diff --git a/.copr/Makefile b/.copr/Makefile new file mode 120000 index 0000000000..ec3c90dfd9 --- /dev/null +++ b/.copr/Makefile @@ -0,0 +1 @@ +../fedora/Makefile \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index 81eba8ccc9..92cf9dc590 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,3 +7,6 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true end_of_line = lf + +[json] +indent_size = 2 diff --git a/.eslintignore b/.eslintignore index 52369be1e3..8e3aee83fb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,5 @@ -libraries/ +node_modules +dist +.idea +.vscode +src/libraries diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000000..6a01fe5bf7 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,190 @@ +module.exports = { + root: true, + plugins: [ + 'promise', + 'import', + 'eslint-comments' + ], + env: { + node: true, + es6: true, + es2017: true, + es2020: true + }, + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module', + ecmaFeatures: { + impliedStrict: true + } + }, + extends: [ + 'eslint:recommended', + // 'plugin:promise/recommended', + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:eslint-comments/recommended', + 'plugin:compat/recommended' + ], + rules: { + 'block-spacing': ["error"], + 'brace-style': ["error"], + 'comma-dangle': ["error", "never"], + 'comma-spacing': ["error"], + 'eol-last': ["error"], + 'indent': ["error", 4, { "SwitchCase": 1 }], + 'keyword-spacing': ["error"], + 'max-statements-per-line': ["error"], + 'no-floating-decimal': ["error"], + 'no-multi-spaces': ["error"], + 'no-multiple-empty-lines': ["error", { "max": 1 }], + 'no-trailing-spaces': ["error"], + 'one-var': ["error", "never"], + 'semi': ["error"], + 'space-before-blocks': ["error"] + }, + overrides: [ + { + files: [ + './src/**/*.js' + ], + env: { + node: false, + amd: true, + browser: true, + es6: true, + es2017: true, + es2020: true + }, + globals: { + // Browser globals + 'MediaMetadata': 'readonly', + // Tizen globals + 'tizen': 'readonly', + 'webapis': 'readonly', + // WebOS globals + 'webOS': 'readonly', + // Dependency globals + '$': 'readonly', + 'jQuery': 'readonly', + 'requirejs': 'readonly', + // Jellyfin globals + 'ApiClient': 'writable', + 'AppInfo': 'writable', + 'chrome': 'writable', + 'ConnectionManager': 'writable', + 'DlnaProfilePage': 'writable', + 'Dashboard': 'writable', + 'DashboardPage': 'writable', + 'Emby': 'readonly', + 'Events': 'writable', + 'getParameterByName': 'writable', + 'getWindowLocationSearch': 'writable', + 'Globalize': 'writable', + 'Hls': 'writable', + 'dfnshelper': 'writable', + 'LibraryMenu': 'writable', + 'LinkParser': 'writable', + 'LiveTvHelpers': 'writable', + 'MetadataEditor': 'writable', + 'pageClassOn': 'writable', + 'pageIdOn': 'writable', + 'PlaylistViewer': 'writable', + 'UserParentalControlPage': 'writable', + 'Windows': 'readonly' + }, + rules: { + // TODO: Fix warnings and remove these rules + 'no-redeclare': ["warn"], + 'no-unused-vars': ["warn"], + 'no-useless-escape': ["warn"], + // TODO: Remove after ES6 migration is complete + 'import/no-unresolved': ["off"] + }, + settings: { + polyfills: [ + // Native Promises Only + 'Promise', + // whatwg-fetch + 'fetch', + // document-register-element + 'document.registerElement', + // resize-observer-polyfill + 'ResizeObserver', + // fast-text-encoding + 'TextEncoder', + // intersection-observer + 'IntersectionObserver', + // Core-js + 'Object.assign', + 'Object.is', + 'Object.setPrototypeOf', + 'Object.toString', + 'Object.freeze', + 'Object.seal', + 'Object.preventExtensions', + 'Object.isFrozen', + 'Object.isSealed', + 'Object.isExtensible', + 'Object.getOwnPropertyDescriptor', + 'Object.getPrototypeOf', + 'Object.keys', + 'Object.getOwnPropertyNames', + 'Function.name', + 'Function.hasInstance', + 'Array.from', + 'Array.arrayOf', + 'Array.copyWithin', + 'Array.fill', + 'Array.find', + 'Array.findIndex', + 'Array.iterator', + 'String.fromCodePoint', + 'String.raw', + 'String.iterator', + 'String.codePointAt', + 'String.endsWith', + 'String.includes', + 'String.repeat', + 'String.startsWith', + 'String.trim', + 'String.anchor', + 'String.big', + 'String.blink', + 'String.bold', + 'String.fixed', + 'String.fontcolor', + 'String.fontsize', + 'String.italics', + 'String.link', + 'String.small', + 'String.strike', + 'String.sub', + 'String.sup', + 'RegExp', + 'Number', + 'Math', + 'Date', + 'async', + 'Symbol', + 'Map', + 'Set', + 'WeakMap', + 'WeakSet', + 'ArrayBuffer', + 'DataView', + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array', + 'Reflect' + ] + } + } + ] +} diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 0b92c0c9b0..0000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,171 +0,0 @@ -env: - amd: true - browser: true - es6: true - es2017: true - es2020: true - -parserOptions: - ecmaVersion: 2020 - sourceType: module - ecmaFeatures: - impliedStrict: true - -plugins: - - promise - - import - - eslint-comments - -extends: - - eslint:recommended - - plugin:promise/recommended - - plugin:import/errors - - plugin:import/warnings - - plugin:eslint-comments/recommended - - plugin:compat/recommended - -globals: - # Browser globals - MediaMetadata: readonly - # Tizen globals - tizen: readonly - webapis: readonly - # WebOS globals - webOS: readonly - # Dependency globals - $: readonly - jQuery: readonly - requirejs: readonly - # Jellyfin globals - ApiClient: writable - AppInfo: writable - chrome: writable - ConnectionManager: writable - DlnaProfilePage: writable - Dashboard: writable - DashboardPage: writable - Emby: readonly - Events: writable - getParameterByName: writable - getWindowLocationSearch: writable - Globalize: writable - Hls: writable - dfnshelper: writable - LibraryMenu: writable - LinkParser: writable - LiveTvHelpers: writable - MetadataEditor: writable - pageClassOn: writable - pageIdOn: writable - PlaylistViewer: writable - UserParentalControlPage: writable - Windows: readonly - -rules: - block-spacing: ["error"] - brace-style: ["error"] - comma-dangle: ["error", "never"] - comma-spacing: ["error"] - eol-last: ["error"] - indent: ["error", 4, { "SwitchCase": 1 }] - keyword-spacing: ["error"] - max-statements-per-line: ["error"] - no-floating-decimal: ["error"] - no-multi-spaces: ["error"] - no-multiple-empty-lines: ["error", { "max": 1 }] - no-trailing-spaces: ["error"] - one-var: ["error", "never"] - semi: ["error"] - space-before-blocks: ["error"] - # TODO: Fix warnings and remove these rules - no-redeclare: ["warn"] - no-unused-vars: ["warn"] - no-useless-escape: ["warn"] - promise/catch-or-return: ["warn"] - promise/always-return: ["warn"] - promise/no-return-wrap: ["warn"] - # TODO: Remove after ES6 migration is complete - import/no-unresolved: ["warn"] - -settings: - polyfills: - # Native Promises Only - - Promise - # whatwg-fetch - - fetch - # document-register-element - - document.registerElement - # resize-observer-polyfill - - ResizeObserver - # fast-text-encoding - - TextEncoder - # intersection-observer - - IntersectionObserver - # Core-js - - Object.assign - - Object.is - - Object.setPrototypeOf - - Object.toString - - Object.freeze - - Object.seal - - Object.preventExtensions - - Object.isFrozen - - Object.isSealed - - Object.isExtensible - - Object.getOwnPropertyDescriptor - - Object.getPrototypeOf - - Object.keys - - Object.getOwnPropertyNames - - Function.name - - Function.hasInstance - - Array.from - - Array.arrayOf - - Array.copyWithin - - Array.fill - - Array.find - - Array.findIndex - - Array.iterator - - String.fromCodePoint - - String.raw - - String.iterator - - String.codePointAt - - String.endsWith - - String.includes - - String.repeat - - String.startsWith - - String.trim - - String.anchor - - String.big - - String.blink - - String.bold - - String.fixed - - String.fontcolor - - String.fontsize - - String.italics - - String.link - - String.small - - String.strike - - String.sub - - String.sup - - RegExp - - Number - - Math - - Date - - async - - Symbol - - Map - - Set - - WeakMap - - WeakSet - - ArrayBuffer - - DataView - - Int8Array - - Uint8Array - - Uint8ClampedArray - - Int16Array - - Uint16Array - - Int32Array - - Uint32Array - - Float32Array - - Float64Array - - Reflect diff --git a/.gitattributes b/.gitattributes index 80f9bc36ed..9e495a4df0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,35 @@ -/CONTRIBUTORS.md merge=union +* text=auto + +CONTRIBUTORS.md merge=union +README.md text +LICENSE text + +*.css text +*.eot binary +*.gif binary +*.html text diff=html +*.ico binary +*.*ignore text +*.jpg binary +*.js text +*.json text +*.lock text -diff +*.map text -diff +*.md text +*.otf binary +*.png binary +*.py text diff=python +*.svg binary +*.ts text +*.ttf binary +*.sass text +*.vue text +*.webp binary +*.woff binary +*.woff2 binary + +.editorconfig text +.gitattributes export-ignore +.gitignore export-ignore + +*.gitattributes linguist-language=gitattributes diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..a35eb9981f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +.ci @dkanada @EraYaN +.github @jellyfin/core +build.sh @joshuaboniface +deployment @joshuaboniface diff --git a/.gitignore b/.gitignore index 2bb5bc64d3..4adf9558bf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,9 @@ config.json # npm dist +web node_modules # ide .idea -.vscode +.vscode \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000000..9f5fa60229 --- /dev/null +++ b/build.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +# build.sh - Build Jellyfin binary packages +# Part of the Jellyfin Project + +set -o errexit +set -o pipefail + +usage() { + echo -e "build.sh - Build Jellyfin binary packages" + echo -e "Usage:" + echo -e " $0 -t/--type -p/--platform [-k/--keep-artifacts] [-l/--list-platforms]" + echo -e "Notes:" + echo -e " * BUILD_TYPE can be one of: [native, docker] and must be specified" + echo -e " * native: Build using the build script in the host OS" + echo -e " * docker: Build using the build script in a standardized Docker container" + echo -e " * PLATFORM can be any platform shown by -l/--list-platforms and must be specified" + echo -e " * If -k/--keep-artifacts is specified, transient artifacts (e.g. Docker containers) will be" + echo -e " retained after the build is finished; the source directory will still be cleaned" + echo -e " * If -l/--list-platforms is specified, all other arguments are ignored; the script will print" + echo -e " the list of supported platforms and exit" +} + +list_platforms() { + declare -a platforms + platforms=( + $( find deployment -maxdepth 1 -mindepth 1 -name "build.*" | awk -F'.' '{ $1=""; printf $2; if ($3 != ""){ printf "." $3; }; if ($4 != ""){ printf "." $4; }; print ""; }' | sort ) + ) + echo -e "Valid platforms:" + echo + for platform in ${platforms[@]}; do + echo -e "* ${platform} : $( grep '^#=' deployment/build.${platform} | sed 's/^#= //' )" + done +} + +do_build_native() { + export IS_DOCKER=NO + deployment/build.${PLATFORM} +} + +do_build_docker() { + if ! dpkg --print-architecture | grep -q 'amd64'; then + echo "Docker-based builds only support amd64-based cross-building; use a 'native' build instead." + exit 1 + fi + if [[ ! -f deployment/Dockerfile.${PLATFORM} ]]; then + echo "Missing Dockerfile for platform ${PLATFORM}" + exit 1 + fi + if [[ ${KEEP_ARTIFACTS} == YES ]]; then + docker_args="" + else + docker_args="--rm" + fi + + docker build . -t "jellyfin-builder.${PLATFORM}" -f deployment/Dockerfile.${PLATFORM} + mkdir -p ${ARTIFACT_DIR} + docker run $docker_args -v "${SOURCE_DIR}:/jellyfin" -v "${ARTIFACT_DIR}:/dist" "jellyfin-builder.${PLATFORM}" +} + +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -t|--type) + BUILD_TYPE="$2" + shift + shift + ;; + -p|--platform) + PLATFORM="$2" + shift + shift + ;; + -k|--keep-artifacts) + KEEP_ARTIFACTS=YES + shift + ;; + -l|--list-platforms) + list_platforms + exit 0 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown option $1" + usage + exit 1 + ;; + esac +done + +if [[ -z ${BUILD_TYPE} || -z ${PLATFORM} ]]; then + usage + exit 1 +fi + +export SOURCE_DIR="$( pwd )" +export ARTIFACT_DIR="${SOURCE_DIR}/../bin/${PLATFORM}" + +# Determine build type +case ${BUILD_TYPE} in + native) + do_build_native + ;; + docker) + do_build_docker + ;; +esac diff --git a/build.yaml b/build.yaml new file mode 100644 index 0000000000..fe1633faec --- /dev/null +++ b/build.yaml @@ -0,0 +1,9 @@ +--- +# We just wrap `build` so this is really it +name: "jellyfin-web" +version: "10.6.0" +packages: + - debian.all + - fedora.all + - centos.all + - portable diff --git a/bump_version b/bump_version new file mode 100755 index 0000000000..bc8288b829 --- /dev/null +++ b/bump_version @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +# bump_version - increase the shared version and generate changelogs + +set -o errexit +set -o pipefail + +usage() { + echo -e "bump_version - increase the shared version and generate changelogs" + echo -e "" + echo -e "Usage:" + echo -e " $ bump_version " +} + +if [[ -z $1 ]]; then + usage + exit 1 +fi + +shared_version_file="src/components/apphost.js" +build_file="./build.yaml" + +new_version="$1" + +# Parse the version from shared version file +old_version="$( + grep "appVersion" ${shared_version_file} | head -1 \ + | sed -E 's/var appVersion = "([0-9\.]+)";/\1/' +)" +echo "Old version in appHost is: $old_version" + +# Set the shared version to the specified new_version +old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars +new_version_sed="$( cut -f1 -d'-' <<<"${new_version}" )" +sed -i "s/${old_version_sed}/${new_version_sed}/g" ${shared_version_file} + +old_version="$( + grep "version:" ${build_file} \ + | sed -E 's/version: "([0-9\.]+[-a-z0-9]*)"/\1/' +)" +echo "Old version in ${build_file}: $old_version`" + +# Set the build.yaml version to the specified new_version +old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars +sed -i "s/${old_version_sed}/${new_version}/g" ${build_file} + +if [[ ${new_version} == *"-"* ]]; then + new_version_deb="$( sed 's/-/~/g' <<<"${new_version}" )" +else + new_version_deb="${new_version}-1" +fi + +# Write out a temporary Debian changelog with our new stuff appended and some templated formatting +debian_changelog_file="debian/changelog" +debian_changelog_temp="$( mktemp )" +# Create new temp file with our changelog +echo -e "jellyfin (${new_version_deb}) unstable; urgency=medium + + * New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v${new_version} + + -- Jellyfin Packaging Team $( date --rfc-2822 ) +" >> ${debian_changelog_temp} +cat ${debian_changelog_file} >> ${debian_changelog_temp} +# Move into place +mv ${debian_changelog_temp} ${debian_changelog_file} + +# Write out a temporary Yum changelog with our new stuff prepended and some templated formatting +fedora_spec_file="fedora/jellyfin.spec" +fedora_changelog_temp="$( mktemp )" +fedora_spec_temp_dir="$( mktemp -d )" +fedora_spec_temp="${fedora_spec_temp_dir}/jellyfin.spec.tmp" +# Make a copy of our spec file for hacking +cp ${fedora_spec_file} ${fedora_spec_temp_dir}/ +pushd ${fedora_spec_temp_dir} +# Split out the stuff before and after changelog +csplit jellyfin.spec "/^%changelog/" # produces xx00 xx01 +# Update the version in xx00 +sed -i "s/${old_version_sed}/${new_version_sed}/g" xx00 +# Remove the header from xx01 +sed -i '/^%changelog/d' xx01 +# Create new temp file with our changelog +echo -e "%changelog +* $( LANG=C date '+%a %b %d %Y' ) Jellyfin Packaging Team +- New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v${new_version}" >> ${fedora_changelog_temp} +cat xx01 >> ${fedora_changelog_temp} +# Reassembble +cat xx00 ${fedora_changelog_temp} > ${fedora_spec_temp} +popd +# Move into place +mv ${fedora_spec_temp} ${fedora_spec_file} +# Clean up +rm -rf ${fedora_changelog_temp} ${fedora_spec_temp_dir} + +# Stage the changed files for commit +git add ${shared_version_file} ${build_file} ${debian_changelog_file} ${fedora_spec_file} Dockerfile* +git status diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000000..50966c3a01 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +jellyfin-web (10.6.0-1) unstable; urgency=medium + + * New upstream version 10.6.0; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.0 + + -- Jellyfin Packaging Team Mon, 16 Mar 2020 11:15:00 -0400 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000000..45a4fb75db --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000000..ce7b130efc --- /dev/null +++ b/debian/control @@ -0,0 +1,16 @@ +Source: jellyfin-web +Section: misc +Priority: optional +Maintainer: Jellyfin Team +Build-Depends: debhelper (>= 9), + npm | nodejs +Standards-Version: 3.9.4 +Homepage: https://jellyfin.org/ +Vcs-Git: https://github.org/jellyfin/jellyfin-web.git +Vcs-Browser: https://github.org/jellyfin/jellyfin-web + +Package: jellyfin-web +Recommends: jellyfin-server +Architecture: all +Description: Jellyfin is the Free Software Media System. + This package provides the Jellyfin web client. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000000..85548075eb --- /dev/null +++ b/debian/copyright @@ -0,0 +1,28 @@ +Format: http://dep.debian.net/deps/dep5 +Upstream-Name: jellyfin-web +Source: https://github.com/jellyfin/jellyfin-web + +Files: * +Copyright: 2018-2020 Jellyfin Team +License: GPL-3.0 + +Files: debian/* +Copyright: 2020 Joshua Boniface +License: GPL-3.0 + +License: GPL-3.0 + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000000..60b3d28723 --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,6 @@ +[DEFAULT] +pristine-tar = False +cleaner = fakeroot debian/rules clean + +[import-orig] +filter = [ ".git*", ".hg*", ".vs*", ".vscode*" ] diff --git a/debian/install b/debian/install new file mode 100644 index 0000000000..584fe06a11 --- /dev/null +++ b/debian/install @@ -0,0 +1 @@ +web usr/share/jellyfin/ diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in new file mode 100644 index 0000000000..cef83a3407 --- /dev/null +++ b/debian/po/POTFILES.in @@ -0,0 +1 @@ +[type: gettext/rfc822deb] templates diff --git a/debian/po/templates.pot b/debian/po/templates.pot new file mode 100644 index 0000000000..2cdcae4173 --- /dev/null +++ b/debian/po/templates.pot @@ -0,0 +1,57 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: jellyfin-server\n" +"Report-Msgid-Bugs-To: jellyfin-server@packages.debian.org\n" +"POT-Creation-Date: 2015-06-12 20:51-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../templates:1001 +msgid "Jellyfin permission info:" +msgstr "" + +#. Type: note +#. Description +#: ../templates:1001 +msgid "" +"Jellyfin by default runs under a user named \"jellyfin\". Please ensure that the " +"user jellyfin has read and write access to any folders you wish to add to your " +"library. Otherwise please run jellyfin under a different user." +msgstr "" + +#. Type: string +#. Description +#: ../templates:2001 +msgid "Username to run Jellyfin as:" +msgstr "" + +#. Type: string +#. Description +#: ../templates:2001 +msgid "The user that jellyfin will run as." +msgstr "" + +#. Type: note +#. Description +#: ../templates:3001 +msgid "Jellyfin still running" +msgstr "" + +#. Type: note +#. Description +#: ../templates:3001 +msgid "Jellyfin is currently running. Please close it and try again." +msgstr "" diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000000..f3e568225c --- /dev/null +++ b/debian/rules @@ -0,0 +1,20 @@ +#! /usr/bin/make -f +export DH_VERBOSE=1 + +%: + dh $@ + +# disable "make check" +override_dh_auto_test: + +# disable stripping debugging symbols +override_dh_clistrip: + +override_dh_auto_build: + npx yarn install + mv $(CURDIR)/dist $(CURDIR)/web + +override_dh_auto_clean: + test -d $(CURDIR)/dist && rm -rf '$(CURDIR)/dist' || true + test -d $(CURDIR)/web && rm -rf '$(CURDIR)/web' || true + test -d $(CURDIR)/node_modules && rm -rf '$(CURDIR)/node_modules' || true diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000000..d3827e75a5 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +1.0 diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 0000000000..b7adf56c67 --- /dev/null +++ b/debian/source/options @@ -0,0 +1,7 @@ +tar-ignore='.git*' +tar-ignore='**/.git' +tar-ignore='**/.hg' +tar-ignore='**/.vs' +tar-ignore='**/.vscode' +tar-ignore='deployment' +tar-ignore='*.deb' diff --git a/deployment/Dockerfile.centos.all b/deployment/Dockerfile.centos.all new file mode 100644 index 0000000000..93bf8d6988 --- /dev/null +++ b/deployment/Dockerfile.centos.all @@ -0,0 +1,27 @@ +FROM centos:7 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV IS_DOCKER=YES + +# Prepare CentOS environment +RUN yum update -y \ + && yum install -y epel-release \ + && yum install -y @buildsys-build rpmdevtools git yum-plugins-core nodejs-yarn autoconf automake glibc-devel + +# Install recent NodeJS and Yarn +RUN curl -fSsLo /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo \ + && rpm -i https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm \ + && yum install -y yarn + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.centos.all /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.debian.all b/deployment/Dockerfile.debian.all new file mode 100644 index 0000000000..54281a5eb4 --- /dev/null +++ b/deployment/Dockerfile.debian.all @@ -0,0 +1,25 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y debhelper mmv npm git + +# Prepare Yarn +RUN npm install -g yarn + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.all /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.fedora.all b/deployment/Dockerfile.fedora.all new file mode 100644 index 0000000000..d47f4ff4da --- /dev/null +++ b/deployment/Dockerfile.fedora.all @@ -0,0 +1,21 @@ +FROM fedora:31 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV IS_DOCKER=YES + +# Prepare Fedora environment +RUN dnf update -y \ + && dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core nodejs-yarn autoconf automake glibc-devel + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.fedora.all /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.portable b/deployment/Dockerfile.portable new file mode 100644 index 0000000000..e0d1f45265 --- /dev/null +++ b/deployment/Dockerfile.portable @@ -0,0 +1,25 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y mmv npm git + +# Prepare Yarn +RUN npm install -g yarn + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.portable /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/build.centos.all b/deployment/build.centos.all new file mode 100755 index 0000000000..8c2cec6d33 --- /dev/null +++ b/deployment/build.centos.all @@ -0,0 +1,27 @@ +#!/bin/bash + +#= CentOS 7 all .rpm + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +cp -a yarn.lock /tmp/yarn.lock + +# Build RPM +make -f fedora/Makefile srpm outdir=/root/rpmbuild/SRPMS +rpmbuild --rebuild -bb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm + +# Move the artifacts out +mv /root/rpmbuild/RPMS/noarch/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +rm -f fedora/jellyfin*.tar.gz +cp -a /tmp/yarn.lock yarn.lock + +popd diff --git a/deployment/build.debian.all b/deployment/build.debian.all new file mode 100755 index 0000000000..8d617a288e --- /dev/null +++ b/deployment/build.debian.all @@ -0,0 +1,25 @@ +#!/bin/bash + +#= Debian/Ubuntu all .deb + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +cp -a yarn.lock /tmp/yarn.lock + +# Build DEB +dpkg-buildpackage -us -uc --pre-clean --post-clean + +mkdir -p ${ARTIFACT_DIR}/ +mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}/ + +cp -a /tmp/yarn.lock yarn.lock + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/deployment/build.fedora.all b/deployment/build.fedora.all new file mode 100755 index 0000000000..4ba12f35ea --- /dev/null +++ b/deployment/build.fedora.all @@ -0,0 +1,27 @@ +#!/bin/bash + +#= Fedora 29+ all .rpm + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +cp -a yarn.lock /tmp/yarn.lock + +# Build RPM +make -f fedora/Makefile srpm outdir=/root/rpmbuild/SRPMS +rpmbuild -rb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm + +# Move the artifacts out +mv /root/rpmbuild/RPMS/noarch/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +rm -f fedora/jellyfin*.tar.gz +cp -a /tmp/yarn.lock yarn.lock + +popd diff --git a/deployment/build.portable b/deployment/build.portable new file mode 100755 index 0000000000..c4cbe927e4 --- /dev/null +++ b/deployment/build.portable @@ -0,0 +1,28 @@ +#!/bin/bash + +#= Portable .NET DLL .tar.gz + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build archives +npx yarn install +mv dist/ jellyfin-web_${version} +tar -czf jellyfin-web_${version}_portable.tar.gz jellyfin-web_${version} +rm -rf dist/ + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/fedora/Makefile b/fedora/Makefile new file mode 100644 index 0000000000..1d3e39ac8b --- /dev/null +++ b/fedora/Makefile @@ -0,0 +1,21 @@ +VERSION := $(shell sed -ne '/^Version:/s/.* *//p' fedora/jellyfin-web.spec) + +srpm: + cd fedora/; \ + SOURCE_DIR=.. \ + WORKDIR="$${PWD}"; \ + tar \ + --transform "s,^\.,jellyfin-web-$(VERSION)," \ + --exclude='.git*' \ + --exclude='**/.git' \ + --exclude='**/.hg' \ + --exclude='deployment' \ + --exclude='*.deb' \ + --exclude='*.rpm' \ + --exclude='jellyfin-web-$(VERSION).tar.gz' \ + -czf "jellyfin-web-$(VERSION).tar.gz" \ + -C $${SOURCE_DIR} ./ + cd fedora/; \ + rpmbuild -bs jellyfin-web.spec \ + --define "_sourcedir $$PWD/" \ + --define "_srcrpmdir $(outdir)" diff --git a/fedora/jellyfin-web.spec b/fedora/jellyfin-web.spec new file mode 100644 index 0000000000..dbc0bd0efa --- /dev/null +++ b/fedora/jellyfin-web.spec @@ -0,0 +1,43 @@ +%global debug_package %{nil} + +Name: jellyfin-web +Version: 10.6.0 +Release: 1%{?dist} +Summary: The Free Software Media System web client +License: GPLv3 +URL: https://jellyfin.org +# Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` +Source0: jellyfin-web-%{version}.tar.gz + +%if 0%{?centos} +BuildRequires: yarn +%else +BuildRequires nodejs-yarn +%endif +BuildArch: noarch + +# Disable Automatic Dependency Processing +AutoReqProv: no + +%description +Jellyfin is a free software media system that puts you in control of managing and streaming your media. + + +%prep +%autosetup -n jellyfin-web-%{version} -b 0 + +%build + +%install +yarn install +%{__mkdir} -p %{buildroot}%{_datadir} +mv dist %{buildroot}%{_datadir}/jellyfin-web +%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/jellyfin/LICENSE + +%files +%attr(755,root,root) %{_datadir}/jellyfin-web +%{_datadir}/licenses/jellyfin/LICENSE + +%changelog +* Mon Mar 23 2020 Jellyfin Packaging Team +- Forthcoming stable release diff --git a/gulpfile.js b/gulpfile.js index 973c400263..0e97324553 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,5 +1,3 @@ -'use strict'; - const { src, dest, series, parallel, watch } = require('gulp'); const browserSync = require('browser-sync').create(); const del = require('del'); @@ -183,6 +181,12 @@ function copy(query) { .pipe(browserSync.stream()); } +function copyIndex() { + return src(options.injectBundle.query, { base: './src/' }) + .pipe(dest('dist/')) + .pipe(browserSync.stream()); +} + function injectBundle() { return src(options.injectBundle.query, { base: './src/' }) .pipe(inject( @@ -193,9 +197,9 @@ function injectBundle() { } function build(standalone) { - return series(clean, parallel(javascript, apploader(standalone), webpack, css, html, images, copy), injectBundle); + return series(clean, parallel(javascript, apploader(standalone), webpack, css, html, images, copy)); } -exports.default = build(false); -exports.standalone = build(true); +exports.default = series(build(false), copyIndex); +exports.standalone = series(build(true), injectBundle); exports.serve = series(exports.standalone, serve); diff --git a/package.json b/package.json index 693dac2e7c..57c1207c74 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@babel/plugin-transform-modules-amd": "^7.8.3", "@babel/polyfill": "^7.8.7", "@babel/preset-env": "^7.8.6", - "autoprefixer": "^9.7.4", + "autoprefixer": "^9.7.6", "babel-loader": "^8.0.6", "browser-sync": "^2.26.7", "clean-webpack-plugin": "^3.0.0", @@ -61,11 +61,12 @@ "document-register-element": "^1.14.3", "fast-text-encoding": "^1.0.1", "flv.js": "^1.5.0", + "headroom.js": "^0.11.0", "hls.js": "^0.13.1", "howler": "^2.1.3", "intersection-observer": "^0.7.0", "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", - "jquery": "^3.4.1", + "jquery": "^3.5.0", "jstree": "^3.3.7", "libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf-cordova", "material-design-icons-iconfont": "^5.0.1", @@ -73,9 +74,10 @@ "page": "^1.11.5", "query-string": "^6.11.1", "resize-observer-polyfill": "^1.5.1", + "screenfull": "^5.0.2", "shaka-player": "^2.5.10", "sortablejs": "^1.10.2", - "swiper": "^5.3.1", + "swiper": "^5.3.7", "webcomponents.js": "^0.7.24", "whatwg-fetch": "^3.0.0" }, @@ -88,19 +90,19 @@ "test": [ "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", - "src/components/dom.js", "src/components/filedownloader.js", - "src/components/filesystem.js", - "src/components/input/keyboardnavigation.js", "src/components/playback/mediasession.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", + "src/scripts/dfnshelper.js", + "src/scripts/dom.js", + "src/scripts/filesystem.js", + "src/scripts/imagehelper.js", + "src/scripts/inputManager.js", + "src/scripts/keyboardnavigation.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", - "src/scripts/settings/webSettings.js", - "src/scripts/dfnshelper.js", - "src/scripts/imagehelper.js", - "src/scripts/inputManager.js" + "src/scripts/settings/webSettings.js" ], "plugins": [ "@babel/plugin-transform-modules-amd" @@ -129,7 +131,7 @@ "build:development": "gulp --development", "build:production": "gulp --production", "build:standalone": "gulp standalone --development", - "lint": "eslint \"src\"", + "lint": "eslint \".\"", "stylelint": "stylelint \"src/**/*.css\"" } } diff --git a/postcss.config.js b/postcss.config.js index 23159fd295..9ce2e16af6 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,11 +1,13 @@ const postcssPresetEnv = require('postcss-preset-env'); +const autoprefixer = require('autoprefixer'); const cssnano = require('cssnano'); const config = () => ({ - plugins: [ - postcssPresetEnv(), - cssnano() - ] + plugins: [ + postcssPresetEnv(), + autoprefixer(), + cssnano() + ] }); -module.exports = config +module.exports = config; diff --git a/src/addplugin.html b/src/addplugin.html index 83640033bb..30e42a2c5c 100644 --- a/src/addplugin.html +++ b/src/addplugin.html @@ -8,9 +8,8 @@ ${Help} -

-

-

+

+

@@ -28,7 +27,6 @@
${ServerRestartNeededAfterPluginInstall}
-

@@ -37,9 +35,6 @@ diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 2b78d356dc..f7a1160469 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -24,6 +24,10 @@ padding-top: 7em !important; } +.layout-mobile .libraryPage { + padding-top: 4em !important; +} + .itemDetailPage { padding-top: 0 !important; } @@ -115,7 +119,7 @@ display: -webkit-inline-box; display: -webkit-inline-flex; display: inline-flex; - margin: 0.3em 0 0 0.5em; + margin: 0 0 0 0.5em; height: 1.7em; -webkit-box-align: center; -webkit-align-items: center; @@ -268,12 +272,6 @@ } } -@media all and (max-width: 60em) { - .libraryDocument .mainDrawerButton { - display: none; - } -} - @media all and (max-width: 84em) { .withSectionTabs .headerTop { padding-bottom: 0.55em; @@ -519,6 +517,13 @@ .itemName { margin: 0.5em 0; + font-weight: 600; +} + +.nameContainer { + display: flex; + flex-direction: column; + flex-wrap: wrap; } .itemMiscInfo { @@ -536,7 +541,6 @@ .layout-mobile .itemName, .layout-mobile .itemMiscInfo, .layout-mobile .mainDetailButtons { - display: flex; align-items: center; justify-content: center; text-align: center; @@ -578,7 +582,6 @@ .infoText { white-space: nowrap; - overflow: hidden; text-overflow: ellipsis; text-align: left; } @@ -1103,3 +1106,50 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards { .itemsViewSettingsContainer > .button-flat { margin: 0; } + +.layout-mobile #myPreferencesMenuPage { + padding-top: 3.75em; +} + +.itemDetailsGroup { + margin-bottom: 1.5em; +} + +.trackSelections { + max-width: 44em; +} + +.detailsGroupItem, +.trackSelections .selectContainer { + display: flex; + max-width: 44em; + margin: 0 0 0.5em !important; +} + +.trackSelections .selectContainer { + margin: 0 0 0.3em !important; +} + +.detailsGroupItem .label, +.trackSelections .selectContainer .selectLabel { + cursor: default; + flex-grow: 0; + flex-shrink: 0; + flex-basis: 6.25em; + margin: 0 0.6em 0 0; +} + +.trackSelections .selectContainer .selectLabel { + margin: 0 0.2em 0 0; +} + +.trackSelections .selectContainer .detailTrackSelect { + font-size: inherit; + padding: 0; + overflow: hidden; +} + +.trackSelections .selectContainer .selectArrowContainer .selectArrow { + margin-top: 0; + font-size: 1.4em; +} diff --git a/src/assets/css/site.css b/src/assets/css/site.css index 67416663e7..e59b639f45 100644 --- a/src/assets/css/site.css +++ b/src/assets/css/site.css @@ -96,3 +96,16 @@ div[data-role=page] { margin-right: auto; width: 85%; } + +.headroom { + will-change: transform; + transition: transform 200ms linear; +} + +.headroom--pinned { + transform: translateY(0%); +} + +.headroom--unpinned { + transform: translateY(-100%); +} diff --git a/src/bundle.js b/src/bundle.js index cf4822deb6..8a829103fa 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -135,7 +135,20 @@ _define("fast-text-encoding", function () { return fast_text_encoding; }); +// intersection-observer var intersection_observer = require("intersection-observer"); _define("intersection-observer", function () { return intersection_observer; }); + +// screenfull +var screenfull = require("screenfull"); +_define("screenfull", function () { + return screenfull; +}); + +// headroom.js +var headroom = require("headroom.js/dist/headroom"); +_define("headroom", function () { + return headroom; +}); diff --git a/src/components/accessschedule/accessschedule.js b/src/components/accessschedule/accessschedule.js index 2f4be8b2a7..28b09b893b 100644 --- a/src/components/accessschedule/accessschedule.js +++ b/src/components/accessschedule/accessschedule.js @@ -1,4 +1,4 @@ -define(["dialogHelper", "datetime", "emby-select", "paper-icon-button-light", "formDialogStyle"], function (dialogHelper, datetime) { +define(["dialogHelper", "datetime", "globalize", "emby-select", "paper-icon-button-light", "formDialogStyle"], function (dialogHelper, datetime, globalize) { "use strict"; function getDisplayTime(hours) { @@ -38,7 +38,7 @@ define(["dialogHelper", "datetime", "emby-select", "paper-icon-button-light", "f }; if (parseFloat(updatedSchedule.StartHour) >= parseFloat(updatedSchedule.EndHour)) { - return void alert(Globalize.translate("ErrorMessageStartHourGreaterThanEnd")); + return void alert(globalize.translate("ErrorMessageStartHourGreaterThanEnd")); } context.submitted = true; @@ -60,7 +60,7 @@ define(["dialogHelper", "datetime", "emby-select", "paper-icon-button-light", "f }); dlg.classList.add("formDialog"); var html = ""; - html += Globalize.translateDocument(template); + html += globalize.translateDocument(template); dlg.innerHTML = html; populateHours(dlg); loadSchedule(dlg, options.schedule); diff --git a/src/components/appRouter.js b/src/components/appRouter.js index a602d6dce8..17b51b376d 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -200,7 +200,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM var apiClient = this; - if (data.status === 401) { + if (data.status === 403) { if (data.errorCode === "ParentalControl") { var isCurrentAllowed = currentRouteInfo ? (currentRouteInfo.route.anonymous || currentRouteInfo.route.startup) : true; diff --git a/src/components/apphost.js b/src/components/apphost.js index 56e9c93521..e5f48ac42e 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -1,4 +1,4 @@ -define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], function (appSettings, browser, events, htmlMediaHelper, webSettings) { +define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings", "globalize"], function (appSettings, browser, events, htmlMediaHelper, webSettings, globalize) { "use strict"; function getBaseProfileOptions(item) { @@ -46,20 +46,9 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f if (window.NativeShell) { profile = window.NativeShell.AppHost.getDeviceProfile(profileBuilder); } else { - profile = profileBuilder(getBaseProfileOptions(item)); - - if (item && !options.isRetry && "allcomplexformats" !== appSettings.get("subtitleburnin")) { - if (!browser.orsay && !browser.tizen) { - profile.SubtitleProfiles.push({ - Format: "ass", - Method: "External" - }); - profile.SubtitleProfiles.push({ - Format: "ssa", - Method: "External" - }); - } - } + var builderOpts = getBaseProfileOptions(item); + builderOpts.enableSsaRender = (item && !options.isRetry && "allcomplexformats" !== appSettings.get("subtitleburnin")); + profile = profileBuilder(builderOpts); } resolve(profile); @@ -237,10 +226,6 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f features.push("voiceinput"); } - if (!browser.tv && !browser.xboxOne) { - browser.ps4; - } - if (supportsHtmlMediaAutoplay()) { features.push("htmlaudioautoplay"); features.push("htmlvideoautoplay"); @@ -332,10 +317,10 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f require(["actionsheet"], function (actionsheet) { exitPromise = actionsheet.show({ - title: Globalize.translate("MessageConfirmAppExit"), + title: globalize.translate("MessageConfirmAppExit"), items: [ - {id: "yes", name: Globalize.translate("Yes")}, - {id: "no", name: Globalize.translate("No")} + {id: "yes", name: globalize.translate("Yes")}, + {id: "no", name: globalize.translate("No")} ] }).then(function (value) { if (value === "yes") { @@ -350,7 +335,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f var deviceId; var deviceName; var appName = "Jellyfin Web"; - var appVersion = "10.5.0"; + var appVersion = "10.6.0"; var appHost = { getWindowState: function () { diff --git a/src/components/chromecast/chromecastplayer.js b/src/components/chromecast/chromecastplayer.js index 18103e433f..71058cf01b 100644 --- a/src/components/chromecast/chromecastplayer.js +++ b/src/components/chromecast/chromecastplayer.js @@ -5,7 +5,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' var currentResolve; var currentReject; - var PlayerName = 'Chromecast'; + var PlayerName = 'Google Cast'; function sendConnectionResult(isOk) { diff --git a/src/components/directorybrowser/directorybrowser.js b/src/components/directorybrowser/directorybrowser.js index fc976068e7..65fe34df12 100644 --- a/src/components/directorybrowser/directorybrowser.js +++ b/src/components/directorybrowser/directorybrowser.js @@ -1,4 +1,4 @@ -define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-icon-button-light', 'css!./directorybrowser', 'formDialogStyle', 'emby-button'], function(loading, dialogHelper, dom) { +define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-input', 'paper-icon-button-light', 'css!./directorybrowser', 'formDialogStyle', 'emby-button'], function(loading, dialogHelper, dom, globalize) { 'use strict'; function getSystemInfo() { @@ -53,7 +53,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- } if (!path) { - html += getItem("lnkPath lnkDirectory", "", "Network", Globalize.translate("ButtonNetwork")); + html += getItem("lnkPath lnkDirectory", "", "Network", globalize.translate("ButtonNetwork")); } page.querySelector(".results").innerHTML = html; @@ -89,16 +89,16 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- var instruction = options.instruction ? options.instruction + "

" : ""; html += '
'; html += instruction; - html += Globalize.translate("MessageDirectoryPickerInstruction", "\\\\server", "\\\\192.168.1.101"); + html += globalize.translate("MessageDirectoryPickerInstruction", "\\\\server", "\\\\192.168.1.101"); if ("bsd" === systemInfo.OperatingSystem.toLowerCase()) { html += "
"; html += "
"; - html += Globalize.translate("MessageDirectoryPickerBSDInstruction"); + html += globalize.translate("MessageDirectoryPickerBSDInstruction"); html += "
"; } else if ("linux" === systemInfo.OperatingSystem.toLowerCase()) { html += "
"; html += "
"; - html += Globalize.translate("MessageDirectoryPickerLinuxInstruction"); + html += globalize.translate("MessageDirectoryPickerLinuxInstruction"); html += "
"; } html += "
"; @@ -113,10 +113,10 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- labelKey = "LabelPath"; } var readOnlyAttribute = options.pathReadOnly ? " readonly" : ""; - html += ''; + html += ''; html += ""; if (!readOnlyAttribute) { - html += ''; + html += ''; } html += ""; if (!readOnlyAttribute) { @@ -124,14 +124,14 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- } if (options.enableNetworkSharePath) { html += '
'; - html += ''; + html += ''; html += '
'; - html += Globalize.translate("LabelOptionalNetworkPathHelp"); + html += globalize.translate("LabelOptionalNetworkPathHelp"); html += "
"; html += "
"; } html += '
'; - html += '"; + html += '"; html += "
"; html += ""; html += ""; @@ -164,14 +164,14 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- }).catch(function(response) { if (response) { if (response.status === 404) { - alertText(Globalize.translate("PathNotFound")); + alertText(globalize.translate("PathNotFound")); return Promise.reject(); } if (response.status === 500) { if (validateWriteable) { - alertText(Globalize.translate("WriteAccessRequired")); + alertText(globalize.translate("WriteAccessRequired")); } else { - alertText(Globalize.translate("PathNotFound")); + alertText(globalize.translate("PathNotFound")); } return Promise.reject(); } @@ -266,7 +266,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper- html += '
'; html += ''; html += '

'; - html += options.header || Globalize.translate("HeaderSelectPath"); + html += options.header || globalize.translate("HeaderSelectPath"); html += "

"; html += "
"; html += getEditorHtml(options, systemInfo); diff --git a/src/components/filterdialog/filterdialog.js b/src/components/filterdialog/filterdialog.js index cbbb1919b0..c534ba4745 100644 --- a/src/components/filterdialog/filterdialog.js +++ b/src/components/filterdialog/filterdialog.js @@ -24,9 +24,6 @@ define(["dom", "dialogHelper", "globalize", "connectionManager", "events", "brow } function renderFilters(context, result, query) { - if (result.Tags) { - result.Tags.length = Math.min(result.Tags.length, 50); - } renderOptions(context, ".genreFilters", "chkGenreFilter", result.Genres, function (i) { var delimeter = "|"; return (delimeter + (query.Genres || "") + delimeter).indexOf(delimeter + i + delimeter) != -1; diff --git a/src/components/fullscreenManager.js b/src/components/fullscreenManager.js deleted file mode 100644 index 8ae31073a2..0000000000 --- a/src/components/fullscreenManager.js +++ /dev/null @@ -1,103 +0,0 @@ -define(['events', 'dom', 'apphost', 'browser'], function (events, dom, appHost, browser) { - 'use strict'; - - function fullscreenManager() { - - } - - fullscreenManager.prototype.requestFullscreen = function (element) { - - element = element || document.documentElement; - - if (element.requestFullscreen) { - element.requestFullscreen(); - return; - } else if (element.mozRequestFullScreen) { - element.mozRequestFullScreen(); - return; - } else if (element.webkitRequestFullscreen) { - element.webkitRequestFullscreen(); - return; - } else if (element.msRequestFullscreen) { - element.msRequestFullscreen(); - return; - } - - // Hack - This is only available for video elements in ios safari - if (element.tagName !== 'VIDEO') { - element = document.querySelector('video') || element; - } - if (element.webkitEnterFullscreen) { - element.webkitEnterFullscreen(); - } - }; - - fullscreenManager.prototype.exitFullscreen = function () { - - if (!this.isFullScreen()) { - return; - } - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen(); - } else if (document.webkitCancelFullscreen) { - document.webkitCancelFullscreen(); - } else if (document.msExitFullscreen) { - document.msExitFullscreen(); - } - }; - - // TODO: use screenfull.js - fullscreenManager.prototype.isFullScreen = function () { - return document.fullscreen || - document.mozFullScreen || - document.webkitIsFullScreen || - document.msFullscreenElement || /* IE/Edge syntax */ - document.fullscreenElement || /* Standard syntax */ - document.webkitFullscreenElement || /* Chrome, Safari and Opera syntax */ - document.mozFullScreenElement; /* Firefox syntax */ - }; - - var manager = new fullscreenManager(); - - function onFullScreenChange() { - events.trigger(manager, 'fullscreenchange'); - } - - dom.addEventListener(document, 'fullscreenchange', onFullScreenChange, { - passive: true - }); - - dom.addEventListener(document, 'webkitfullscreenchange', onFullScreenChange, { - passive: true - }); - - dom.addEventListener(document, 'mozfullscreenchange', onFullScreenChange, { - passive: true - }); - - function isTargetValid(target) { - return !dom.parentWithTag(target, ['BUTTON', 'INPUT', 'TEXTAREA']); - } - if (appHost.supports("fullscreenchange") && (browser.edgeUwp || -1 !== navigator.userAgent.toLowerCase().indexOf("electron"))) { - - dom.addEventListener(window, 'dblclick', function (e) { - - if (isTargetValid(e.target)) { - if (manager.isFullScreen()) { - manager.exitFullscreen(); - } else { - manager.requestFullscreen(); - } - } - - }, { - passive: true - }); - } - - return manager; -}); diff --git a/src/components/headroom/headroom.css b/src/components/headroom/headroom.css deleted file mode 100644 index df985892ff..0000000000 --- a/src/components/headroom/headroom.css +++ /dev/null @@ -1,11 +0,0 @@ -.headroom { - transition: transform 140ms linear; -} - -.headroom--pinned { - transform: none; -} - -.headroom--unpinned:not(.headroomDisabled) { - transform: translateY(-100%); -} diff --git a/src/components/headroom/headroom.js b/src/components/headroom/headroom.js deleted file mode 100644 index 3c0ada3ce9..0000000000 --- a/src/components/headroom/headroom.js +++ /dev/null @@ -1,343 +0,0 @@ -/*! - * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it - * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js - * License: MIT - */ - -define(['dom', 'layoutManager', 'browser', 'css!./headroom'], function (dom, layoutManager, browser) { - - 'use strict'; - - /* exported features */ - - var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; - - /** - * Handles debouncing of events via requestAnimationFrame - * @see http://www.html5rocks.com/en/tutorials/speed/animations/ - * @param {Function} callback The callback to handle whichever event - */ - function Debouncer(callback) { - this.callback = callback; - this.ticking = false; - } - Debouncer.prototype = { - constructor: Debouncer, - - /** - * dispatches the event to the supplied callback - * @private - */ - update: function () { - if (this.callback) { - this.callback(); - } - this.ticking = false; - }, - - /** - * Attach this as the event listeners - */ - handleEvent: function () { - if (!this.ticking) { - requestAnimationFrame(this.rafCallback || (this.rafCallback = this.update.bind(this))); - this.ticking = true; - } - } - }; - - function onHeadroomClearedExternally() { - this.state = null; - } - - /** - * UI enhancement for fixed headers. - * Hides header when scrolling down - * Shows header when scrolling up - * @constructor - * @param {DOMElement} elem the header element - * @param {Object} options options for the widget - */ - function Headroom(elems, options) { - options = Object.assign(Headroom.options, options || {}); - - this.lastKnownScrollY = 0; - this.elems = elems; - - this.scroller = options.scroller; - - this.debouncer = onScroll.bind(this); - this.offset = options.offset; - this.initialised = false; - - this.initialClass = options.initialClass; - this.unPinnedClass = options.unPinnedClass; - this.pinnedClass = options.pinnedClass; - - this.state = 'clear'; - - this.options = { - offset: 0, - scroller: window, - initialClass: 'headroom', - unPinnedClass: 'headroom--unpinned', - pinnedClass: 'headroom--pinned' - }; - - this.add = function (elem) { - - if (browser.supportsCssAnimation()) { - elem.classList.add(this.initialClass); - elem.addEventListener('clearheadroom', onHeadroomClearedExternally.bind(this)); - this.elems.push(elem); - } - }; - - this.remove = function (elem) { - - elem.classList.remove(this.unPinnedClass); - elem.classList.remove(this.initialClass); - elem.classList.remove(this.pinnedClass); - - var i = this.elems.indexOf(elem); - if (i !== -1) { - this.elems.splice(i, 1); - } - }; - - this.pause = function () { - this.paused = true; - }; - - this.resume = function () { - this.paused = false; - }; - - /** - * Unattaches events and removes any classes that were added - */ - this.destroy = function () { - - this.initialised = false; - - for (var i = 0, length = this.elems.length; i < length; i++) { - - var classList = this.elems[i].classList; - - classList.remove(this.unPinnedClass); - classList.remove(this.initialClass); - classList.remove(this.pinnedClass); - } - - var scrollEventName = this.scroller.getScrollEventName ? this.scroller.getScrollEventName() : 'scroll'; - - dom.removeEventListener(this.scroller, scrollEventName, this.debouncer, { - capture: false, - passive: true - }); - }; - - /** - * Attaches the scroll event - * @private - */ - this.attachEvent = function () { - if (!this.initialised) { - this.lastKnownScrollY = this.getScrollY(); - this.initialised = true; - - var scrollEventName = this.scroller.getScrollEventName ? this.scroller.getScrollEventName() : 'scroll'; - - dom.addEventListener(this.scroller, scrollEventName, this.debouncer, { - capture: false, - passive: true - }); - - this.update(); - } - }; - - /** - * Unpins the header if it's currently pinned - */ - this.clear = function () { - - if (this.state === 'clear') { - return; - } - - this.state = 'clear'; - - var unpinnedClass = this.unPinnedClass; - var pinnedClass = this.pinnedClass; - - for (var i = 0, length = this.elems.length; i < length; i++) { - var classList = this.elems[i].classList; - - classList.remove(unpinnedClass); - //classList.remove(pinnedClass); - } - }; - - /** - * Unpins the header if it's currently pinned - */ - this.pin = function () { - - if (this.state === 'pin') { - return; - } - - this.state = 'pin'; - - var unpinnedClass = this.unPinnedClass; - var pinnedClass = this.pinnedClass; - - for (var i = 0, length = this.elems.length; i < length; i++) { - var classList = this.elems[i].classList; - - classList.remove(unpinnedClass); - classList.add(pinnedClass); - } - }; - - /** - * Unpins the header if it's currently pinned - */ - this.unpin = function () { - - if (this.state === 'unpin') { - return; - } - - this.state = 'unpin'; - - var unpinnedClass = this.unPinnedClass; - var pinnedClass = this.pinnedClass; - - for (var i = 0, length = this.elems.length; i < length; i++) { - var classList = this.elems[i].classList; - - classList.add(unpinnedClass); - //classList.remove(pinnedClass); - } - }; - - /** - * Gets the Y scroll position - * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY - * @return {Number} pixels the page has scrolled along the Y-axis - */ - this.getScrollY = function () { - - var scroller = this.scroller; - - if (scroller.getScrollPosition) { - return scroller.getScrollPosition(); - } - - var pageYOffset = scroller.pageYOffset; - if (pageYOffset !== undefined) { - return pageYOffset; - } - - var scrollTop = scroller.scrollTop; - if (scrollTop !== undefined) { - return scrollTop; - } - - return (document.documentElement || document.body).scrollTop; - }; - - /** - * determine if it is appropriate to unpin - * @param {int} currentScrollY the current y scroll position - * @return {bool} true if should unpin, false otherwise - */ - this.shouldUnpin = function (currentScrollY) { - var scrollingDown = currentScrollY > this.lastKnownScrollY; - var pastOffset = currentScrollY >= this.offset; - - return scrollingDown && pastOffset; - }; - - /** - * determine if it is appropriate to pin - * @param {int} currentScrollY the current y scroll position - * @return {bool} true if should pin, false otherwise - */ - this.shouldPin = function (currentScrollY) { - var scrollingUp = currentScrollY < this.lastKnownScrollY; - var pastOffset = currentScrollY <= this.offset; - - return scrollingUp || pastOffset; - }; - - /** - * Handles updating the state of the widget - */ - this.update = function () { - - if (this.paused) { - return; - } - - var currentScrollY = this.getScrollY(); - - var lastKnownScrollY = this.lastKnownScrollY; - - var isTv = layoutManager.tv; - - if (currentScrollY <= (isTv ? 120 : 10)) { - this.clear(); - } else if (this.shouldUnpin(currentScrollY)) { - this.unpin(); - } else if (this.shouldPin(currentScrollY)) { - - var toleranceExceeded = Math.abs(currentScrollY - lastKnownScrollY) >= 14; - - if (currentScrollY && isTv) { - this.unpin(); - } else if (toleranceExceeded) { - this.clear(); - } - } else if (isTv) { - //this.clear(); - } - - this.lastKnownScrollY = currentScrollY; - }; - - if (browser.supportsCssAnimation()) { - for (var i = 0, length = this.elems.length; i < length; i++) { - this.elems[i].classList.add(this.initialClass); - this.elems[i].addEventListener('clearheadroom', onHeadroomClearedExternally.bind(this)); - } - - this.attachEvent(); - } - } - - function onScroll() { - - if (this.paused) { - return; - } - - requestAnimationFrame(this.rafCallback || (this.rafCallback = this.update.bind(this))); - } - - /** - * Default options - * @type {Object} - */ - Headroom.options = { - offset: 0, - scroller: window, - initialClass: 'headroom', - unPinnedClass: 'headroom--unpinned', - pinnedClass: 'headroom--pinned' - }; - - return Headroom; -}); diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index cb4866a1cc..894cf0bdb9 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -64,13 +64,13 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } else { var noLibDescription; if (user['Policy'] && user['Policy']['IsAdministrator']) { - noLibDescription = Globalize.translate("NoCreatedLibraries", '', ''); + noLibDescription = globalize.translate("NoCreatedLibraries", '
', ''); } else { - noLibDescription = Globalize.translate("AskAdminToCreateLibrary"); + noLibDescription = globalize.translate("AskAdminToCreateLibrary"); } html += '
'; - html += '

' + Globalize.translate("MessageNothingHere") + '

'; + html += '

' + globalize.translate("MessageNothingHere") + '

'; html += '

' + noLibDescription + '

'; html += '
'; elem.innerHTML = html; @@ -243,9 +243,9 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la return function (items) { var cardLayout = false; var shape; - if (itemType === 'Channel' || viewType === 'movies' || viewType === 'books') { + if (itemType === 'Channel' || viewType === 'movies' || viewType === 'books' || viewType === 'tvshows') { shape = getPortraitShape(); - } else if (viewType === 'music') { + } else if (viewType === 'music' || viewType === 'homevideos') { shape = getSquareShape(); } else { shape = getThumbShape(); diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 7df38a6c87..8026110e21 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -162,7 +162,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function seekOnPlaybackStart(instance, element, ticks) { + function seekOnPlaybackStart(instance, element, ticks, onMediaReady) { var seconds = (ticks || 0) / 10000000; @@ -175,6 +175,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve if (element.duration >= seconds) { // media is ready, seek immediately setCurrentTimeIfNeeded(element, seconds); + if (onMediaReady) onMediaReady(); } else { // update video player position when media is ready to be sought var events = ["durationchange", "loadeddata", "play", "loadedmetadata"]; @@ -189,6 +190,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve events.map(function(name) { element.removeEventListener(name, onMediaChange); }); + if (onMediaReady) onMediaReady(); } }; events.map(function (name) { diff --git a/src/components/htmlvideoplayer/plugin.js b/src/components/htmlvideoplayer/plugin.js index bcd3a72ba9..d3e3b3640f 100644 --- a/src/components/htmlvideoplayer/plugin.js +++ b/src/components/htmlvideoplayer/plugin.js @@ -1,4 +1,4 @@ -define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'fullscreenManager', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, fullscreenManager, globalize) { +define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'screenfull', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, screenfull, globalize) { "use strict"; /* globals cast */ @@ -795,7 +795,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa dlg.parentNode.removeChild(dlg); } - fullscreenManager.exitFullscreen(); + if (screenfull.isEnabled) { + screenfull.exit(); + } }; function onEnded() { @@ -857,7 +859,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa loading.hide(); - htmlMediaHelper.seekOnPlaybackStart(self, e.target, self._currentPlayOptions.playerStartPositionTicks); + htmlMediaHelper.seekOnPlaybackStart(self, e.target, self._currentPlayOptions.playerStartPositionTicks, function () { + if (currentSubtitlesOctopus) currentSubtitlesOctopus.resize(); + }); if (self._currentPlayOptions.fullscreen) { diff --git a/src/components/itemcontextmenu.js b/src/components/itemcontextmenu.js index 185d94405d..eec46899a7 100644 --- a/src/components/itemcontextmenu.js +++ b/src/components/itemcontextmenu.js @@ -90,7 +90,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", }); } - if (itemHelper.supportsAddingToPlaylist(item)) { + if (itemHelper.supportsAddingToPlaylist(item) && options.playlist !== false) { commands.push({ name: globalize.translate("AddToPlaylist"), id: "addtoplaylist", @@ -218,7 +218,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", if (item.Type === "Program" && options.record !== false) { if (item.TimerId) { commands.push({ - name: Globalize.translate("ManageRecording"), + name: globalize.translate("ManageRecording"), id: "record", icon: "fiber_manual_record" }); @@ -228,7 +228,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", if (item.Type === "Program" && options.record !== false) { if (!item.TimerId) { commands.push({ - name: Globalize.translate("Record"), + name: globalize.translate("Record"), id: "record", icon: "fiber_manual_record" }); @@ -283,7 +283,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", if (options.openAlbum !== false && item.AlbumId && item.MediaType !== "Photo") { commands.push({ - name: Globalize.translate("ViewAlbum"), + name: globalize.translate("ViewAlbum"), id: "album", icon: "album" }); @@ -291,7 +291,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", if (options.openArtist !== false && item.ArtistItems && item.ArtistItems.length) { commands.push({ - name: Globalize.translate("ViewArtist"), + name: globalize.translate("ViewArtist"), id: "artist", icon: "person" }); diff --git a/src/components/layoutManager.js b/src/components/layoutManager.js index 21bcdf5933..1428f3468d 100644 --- a/src/components/layoutManager.js +++ b/src/components/layoutManager.js @@ -45,7 +45,7 @@ define(['browser', 'appSettings', 'events'], function (browser, appSettings, eve // Take a guess at initial layout. The consuming app can override if (browser.mobile) { this.setLayout('mobile', false); - } else if (browser.tv || browser.xboxOne) { + } else if (browser.tv || browser.xboxOne || browser.ps4) { this.setLayout('tv', false); } else { this.setLayout(this.defaultLayout || 'tv', false); diff --git a/src/components/maintabsmanager.js b/src/components/maintabsmanager.js index 2571470015..e1c5434363 100644 --- a/src/components/maintabsmanager.js +++ b/src/components/maintabsmanager.js @@ -166,6 +166,7 @@ define(['dom', 'browser', 'events', 'emby-tabs', 'emby-button'], function (dom, }).join('') + ''; tabsContainerElem.innerHTML = tabsHtml; + window.CustomElements.upgradeSubtree(tabsContainerElem); document.body.classList.add('withSectionTabs'); tabOwnerView = view; diff --git a/src/components/medialibrarycreator/medialibrarycreator.js b/src/components/medialibrarycreator/medialibrarycreator.js index 0a8741387f..1665efe273 100644 --- a/src/components/medialibrarycreator/medialibrarycreator.js +++ b/src/components/medialibrarycreator/medialibrarycreator.js @@ -1,4 +1,4 @@ -define(["loading", "dialogHelper", "dom", "jQuery", "components/libraryoptionseditor/libraryoptionseditor", "emby-toggle", "emby-input", "emby-select", "paper-icon-button-light", "listViewStyle", "formDialogStyle", "emby-button", "flexStyles"], function (loading, dialogHelper, dom, $, libraryoptionseditor) { +define(["loading", "dialogHelper", "dom", "jQuery", "components/libraryoptionseditor/libraryoptionseditor", "globalize", "emby-toggle", "emby-input", "emby-select", "paper-icon-button-light", "listViewStyle", "formDialogStyle", "emby-button", "flexStyles"], function (loading, dialogHelper, dom, $, libraryoptionseditor, globalize) { "use strict"; function onAddLibrary() { @@ -9,7 +9,7 @@ define(["loading", "dialogHelper", "dom", "jQuery", "components/libraryoptionsed if (pathInfos.length == 0) { require(["alert"], function (alert) { alert({ - text: Globalize.translate("PleaseAddAtLeastOneFolder"), + text: globalize.translate("PleaseAddAtLeastOneFolder"), type: "error" }); }); @@ -36,7 +36,7 @@ define(["loading", "dialogHelper", "dom", "jQuery", "components/libraryoptionsed dialogHelper.close(dlg); }, function () { require(["toast"], function (toast) { - toast(Globalize.translate("ErrorAddingMediaPathToVirtualFolder")); + toast(globalize.translate("ErrorAddingMediaPathToVirtualFolder")); }); isCreating = false; @@ -196,7 +196,7 @@ define(["loading", "dialogHelper", "dom", "jQuery", "components/libraryoptionsed dlg.classList.add("background-theme-a"); dlg.classList.add("dlg-librarycreator"); dlg.classList.add("formDialog"); - dlg.innerHTML = Globalize.translateDocument(template); + dlg.innerHTML = globalize.translateDocument(template); initEditor(dlg, options.collectionTypeOptions); dlg.addEventListener("close", onDialogClosed); dialogHelper.open(dlg); diff --git a/src/components/medialibraryeditor/medialibraryeditor.js b/src/components/medialibraryeditor/medialibraryeditor.js index 7c5c8d4080..6a0f955b2d 100644 --- a/src/components/medialibraryeditor/medialibraryeditor.js +++ b/src/components/medialibraryeditor/medialibraryeditor.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "dialogHelper", "dom", "components/libraryoptionseditor/libraryoptionseditor", "emby-button", "listViewStyle", "paper-icon-button-light", "formDialogStyle", "emby-toggle", "flexStyles"], function (jQuery, loading, dialogHelper, dom, libraryoptionseditor) { +define(["jQuery", "loading", "dialogHelper", "dom", "components/libraryoptionseditor/libraryoptionseditor", "globalize", "emby-button", "listViewStyle", "paper-icon-button-light", "formDialogStyle", "emby-toggle", "flexStyles"], function (jQuery, loading, dialogHelper, dom, libraryoptionseditor, globalize) { "use strict"; function onEditLibrary() { @@ -31,7 +31,7 @@ define(["jQuery", "loading", "dialogHelper", "dom", "components/libraryoptionsed refreshLibraryFromServer(page); }, function () { require(["toast"], function (toast) { - toast(Globalize.translate("ErrorAddingMediaPathToVirtualFolder")); + toast(globalize.translate("ErrorAddingMediaPathToVirtualFolder")); }); }); } @@ -46,7 +46,7 @@ define(["jQuery", "loading", "dialogHelper", "dom", "components/libraryoptionsed refreshLibraryFromServer(page); }, function () { require(["toast"], function (toast) { - toast(Globalize.translate("ErrorAddingMediaPathToVirtualFolder")); + toast(globalize.translate("ErrorAddingMediaPathToVirtualFolder")); }); }); } @@ -57,9 +57,9 @@ define(["jQuery", "loading", "dialogHelper", "dom", "components/libraryoptionsed require(["confirm"], function (confirm) { confirm({ - title: Globalize.translate("HeaderRemoveMediaLocation"), - text: Globalize.translate("MessageConfirmRemoveMediaLocation"), - confirmText: Globalize.translate("ButtonDelete"), + title: globalize.translate("HeaderRemoveMediaLocation"), + text: globalize.translate("MessageConfirmRemoveMediaLocation"), + confirmText: globalize.translate("ButtonDelete"), primary: "delete" }).then(function () { var refreshAfterChange = currentOptions.refresh; @@ -68,7 +68,7 @@ define(["jQuery", "loading", "dialogHelper", "dom", "components/libraryoptionsed refreshLibraryFromServer(dom.parentWithClass(button, "dlg-libraryeditor")); }, function () { require(["toast"], function (toast) { - toast(Globalize.translate("DefaultErrorMessage")); + toast(globalize.translate("DefaultErrorMessage")); }); }); }); @@ -213,7 +213,7 @@ define(["jQuery", "loading", "dialogHelper", "dom", "components/libraryoptionsed dlg.classList.add("ui-body-a"); dlg.classList.add("background-theme-a"); dlg.classList.add("formDialog"); - dlg.innerHTML = Globalize.translateDocument(template); + dlg.innerHTML = globalize.translateDocument(template); dlg.querySelector(".formDialogHeaderTitle").innerHTML = options.library.Name; initEditor(dlg, options); dlg.addEventListener("close", onDialogClosed); diff --git a/src/components/multiselect/multiselect.js b/src/components/multiselect/multiselect.js index b4fa87c8a0..57a358d620 100644 --- a/src/components/multiselect/multiselect.js +++ b/src/components/multiselect/multiselect.js @@ -212,7 +212,7 @@ define(["browser", "appStorage", "apphost", "loading", "connectionManager", "glo if (user.Policy.EnableContentDownloading && appHost.supports("filedownload")) { menuItems.push({ - name: Globalize.translate("ButtonDownload"), + name: globalize.translate("ButtonDownload"), id: "download", icon: "file_download" }); diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 8ba870613b..4b00171aee 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -5,7 +5,8 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir document.removeEventListener('click', onOneDocumentClick); document.removeEventListener('keydown', onOneDocumentClick); - if (window.Notification) { + // don't request notification permissions if they're already granted or denied + if (window.Notification && window.Notification.permission === "default") { /* eslint-disable-next-line compat/compat */ Notification.requestPermission(); } diff --git a/src/components/nowplayingbar/nowplayingbar.js b/src/components/nowplayingbar/nowplayingbar.js index 8205211b4f..a3839a9342 100644 --- a/src/components/nowplayingbar/nowplayingbar.js +++ b/src/components/nowplayingbar/nowplayingbar.js @@ -1,4 +1,4 @@ -define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', 'layoutManager', 'playbackManager', 'nowPlayingHelper', 'apphost', 'dom', 'connectionManager', 'paper-icon-button-light', 'emby-ratingbutton'], function (require, datetime, itemHelper, events, browser, imageLoader, layoutManager, playbackManager, nowPlayingHelper, appHost, dom, connectionManager) { +define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', 'layoutManager', 'playbackManager', 'nowPlayingHelper', 'apphost', 'dom', 'connectionManager', 'itemContextMenu', 'paper-icon-button-light', 'emby-ratingbutton'], function (require, datetime, itemHelper, events, browser, imageLoader, layoutManager, playbackManager, nowPlayingHelper, appHost, dom, connectionManager, itemContextMenu) { 'use strict'; var currentPlayer; @@ -66,7 +66,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', html += ''; html += ''; - html += ''; + html += ''; html += ''; html += ''; @@ -155,8 +155,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } }); - elem.querySelector('.remoteControlButton').addEventListener('click', showRemoteControl); - toggleRepeatButton = elem.querySelector('.toggleRepeatButton'); toggleRepeatButton.addEventListener('click', function () { @@ -187,29 +185,15 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', volumeSliderContainer.classList.remove('hide'); } - var volumeSliderTimer; - function setVolume() { - clearTimeout(volumeSliderTimer); - volumeSliderTimer = null; - if (currentPlayer) { currentPlayer.setVolume(this.value); } } - function setVolumeDelayed() { - if (!volumeSliderTimer) { - var that = this; - volumeSliderTimer = setTimeout(function () { - setVolume.call(that); - }, 700); - } - } - volumeSlider.addEventListener('change', setVolume); - volumeSlider.addEventListener('mousemove', setVolumeDelayed); - volumeSlider.addEventListener('touchmove', setVolumeDelayed); + volumeSlider.addEventListener('mousemove', setVolume); + volumeSlider.addEventListener('touchmove', setVolume); positionSlider = elem.querySelector('.nowPlayingBarPositionSlider'); positionSlider.addEventListener('change', function () { @@ -240,7 +224,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', elem.addEventListener('click', function (e) { - if (!dom.parentWithTag(e.target, ['BUTTON', 'INPUT', 'A'])) { + if (!dom.parentWithTag(e.target, ['BUTTON', 'INPUT'])) { showRemoteControl(); } }); @@ -449,17 +433,13 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } } - function getTextActionButton(item, text, serverId) { + function getTextActionButton(item, text) { if (!text) { text = itemHelper.getDisplayName(item); } - var html = ''; - - return html; + return `${text}`; } function seriesImageUrl(item, options) { @@ -537,16 +517,16 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (textLines.length > 1) { textLines[1].secondary = true; } - var serverId = nowPlayingItem ? nowPlayingItem.ServerId : null; nowPlayingTextElement.innerHTML = textLines.map(function (nowPlayingName) { var cssClass = nowPlayingName.secondary ? ' class="nowPlayingBarSecondaryText"' : ''; if (nowPlayingName.item) { - return '' + getTextActionButton(nowPlayingName.item, nowPlayingName.text, serverId) + ''; + var nowPlayingText = getTextActionButton(nowPlayingName.item, nowPlayingName.text); + return `
${nowPlayingText}
`; } - return '' + nowPlayingName.text + ''; + return `
${nowPlayingText}
`; }).join(''); @@ -575,15 +555,25 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (isRefreshing) { var apiClient = connectionManager.getApiClient(nowPlayingItem.ServerId); - apiClient.getItem(apiClient.getCurrentUserId(), nowPlayingItem.Id).then(function (item) { - var userData = item.UserData || {}; var likes = userData.Likes == null ? '' : userData.Likes; - + var contextButton = document.querySelector('.btnToggleContextMenu'); + var options = { + play: false, + queue: false, + positionTo: contextButton + }; nowPlayingUserData.innerHTML = ''; + apiClient.getCurrentUser().then(function(user) { + contextButton.addEventListener('click', function () { + itemContextMenu.show(Object.assign({ + item: item, + user: user + }, options )); + }); + }); }); - } } else { nowPlayingUserData.innerHTML = ''; diff --git a/src/components/playback/experimentalwarnings.js b/src/components/playback/experimentalwarnings.js index 2d1ef53c19..02a7b82caf 100644 --- a/src/components/playback/experimentalwarnings.js +++ b/src/components/playback/experimentalwarnings.js @@ -44,24 +44,15 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function ( } function showBlurayMessage() { - - var message = - 'Playback of Bluray folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native Bluray folder support.'; - return showMessage(message, 'blurayexpirementalinfo', 'nativeblurayplayback'); + return showMessage(globalize.translate("UnsupportedPlayback"), 'blurayexpirementalinfo', 'nativeblurayplayback'); } function showDvdMessage() { - - var message = - 'Playback of Dvd folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native Dvd folder support.'; - return showMessage(message, 'dvdexpirementalinfo', 'nativedvdplayback'); + return showMessage(globalize.translate("UnsupportedPlayback"), 'dvdexpirementalinfo', 'nativedvdplayback'); } function showIsoMessage() { - - var message = - 'Playback of ISO files in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native ISO support.'; - return showMessage(message, 'isoexpirementalinfo', 'nativeisoplayback'); + return showMessage(globalize.translate("UnsupportedPlayback"), 'isoexpirementalinfo', 'nativeisoplayback'); } function ExpirementalPlaybackWarnings() { diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 2ea4c67cfb..0312312858 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1,6 +1,9 @@ -define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'fullscreenManager'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, fullscreenManager) { +define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) { 'use strict'; + /** Delay time in ms for reportPlayback logging */ + const reportPlaybackLogDelay = 1e3; + function enableLocalPlaylistManagement(player) { if (player.getPlaylist) { @@ -17,9 +20,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function bindToFullscreenChange(player) { - events.on(fullscreenManager, 'fullscreenchange', function () { - events.trigger(player, 'fullscreenchange'); - }); + if (screenfull.isEnabled) { + screenfull.on('change', function () { + events.trigger(player, 'fullscreenchange'); + }); + } } function triggerPlayerChange(playbackManagerInstance, newPlayer, newTarget, previousPlayer, previousTargetInfo) { @@ -38,6 +43,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]); } + /** Last invoked method */ + let reportPlaybackLastMethod; + + /** Last invoke time of method */ + let reportPlaybackLastTime; + function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) { if (!serverId) { @@ -57,7 +68,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId); } - console.debug(method + '-' + JSON.stringify(info)); + const now = (new Date).getTime(); + + if (method !== reportPlaybackLastMethod || now - (reportPlaybackLastTime || 0) >= reportPlaybackLogDelay) { + console.debug(method + '-' + JSON.stringify(info)); + reportPlaybackLastMethod = method; + reportPlaybackLastTime = now; + } + var apiClient = connectionManager.getApiClient(serverId); apiClient[method](info); } @@ -1518,7 +1536,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.isFullscreen(); } - return fullscreenManager.isFullScreen(); + return screenfull.isFullscreen; }; self.toggleFullscreen = function (player) { @@ -1528,10 +1546,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.toggleFulscreen(); } - if (fullscreenManager.isFullScreen()) { - fullscreenManager.exitFullscreen(); - } else { - fullscreenManager.requestFullscreen(); + if (screenfull.isEnabled) { + screenfull.toggle(); } }; @@ -3378,7 +3394,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla pluginManager.ofType('mediaplayer').map(initMediaPlayer); function sendProgressUpdate(player, progressEventName, reportPlaylist) { - if (!player) { throw new Error('player cannot be null'); } diff --git a/src/components/polyfills/objectassign.js b/src/components/polyfills/objectassign.js deleted file mode 100644 index 85f55aa144..0000000000 --- a/src/components/polyfills/objectassign.js +++ /dev/null @@ -1,24 +0,0 @@ -if (typeof Object.assign != 'function') { - (function () { - Object.assign = function (target) { - 'use strict'; - if (target === undefined || target === null) { - throw new TypeError('Cannot convert undefined or null to object'); - } - - var output = Object(target); - for (var index = 1; index < arguments.length; index++) { - var source = arguments[index]; - if (source !== undefined && source !== null) { - for (var nextKey in source) { - // eslint-disable-next-line no-prototype-builtins - if (source.hasOwnProperty(nextKey)) { - output[nextKey] = source[nextKey]; - } - } - } - } - return output; - }; - })(); -} diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 83a1c48e5f..9cdfcde151 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -1,3 +1,7 @@ +.nowPlayingPage { + padding: 5em 0 0 0 !important; +} + .nowPlayingInfoContainer { display: -webkit-box; display: -webkit-flex; @@ -36,8 +40,30 @@ margin: 0 0 0.5em 0.5em; } +.nowPlayingAlbum a, +.nowPlayingArtist a { + font-weight: normal; + text-align: left !important; + color: inherit !important; +} + +.nowPlayingButtonsContainer { + display: flex; +} + +.nowPlayingInfoContainerMedia { + text-align: left; + margin-bottom: 1em; +} + +.nowPlayingPositionSlider { + width: stretch; +} + .nowPlayingPositionSliderContainer { - margin: 0.7em 0 0.7em 1em; + margin: 0.2em 1em 0.2em 1em; + width: 100%; + z-index: 0; } .nowPlayingInfoButtons { @@ -59,17 +85,32 @@ } .nowPlayingPageImageContainer { - width: 20%; - margin-right: 0.25em; + width: 16%; + margin-right: 1em; position: relative; -webkit-flex-shrink: 0; flex-shrink: 0; } -@media all and (min-width: 50em) { - .nowPlayingPageImageContainer { - width: 16%; - } +.nowPlayingPageImageContainerNoAlbum { + width: 100%; + position: relative; +} + +.nowPlayingPageImageContainerNoAlbum button { + cursor: default; +} + +.nowPlayingPageImageContainerNoAlbum::after { + content: ""; + display: block; + padding-bottom: 100%; +} + +.btnPlayPause { + font-size: xx-large; + padding: 0; + margin: 0; } .nowPlayingInfoControls { @@ -87,14 +128,15 @@ } .nowPlayingPageImage { + display: block; bottom: 0; left: 0; right: 0; + margin: 0 auto; width: 100%; -webkit-box-shadow: 0 0 1.9vh #000; box-shadow: 0 0 1.9vh #000; border: 0.1em solid #222; - user-drag: none; user-select: none; -moz-user-select: none; -webkit-user-drag: none; @@ -102,60 +144,16 @@ -ms-user-select: none; } -@media all and (orientation: portrait) and (max-width: 50em) { - .nowPlayingInfoContainer { - -webkit-box-orient: vertical !important; - -webkit-box-direction: normal !important; - -webkit-flex-direction: column !important; - flex-direction: column !important; - -webkit-box-align: center; - -webkit-align-items: center; - align-items: center; - } - - .nowPlayingPageTitle { - text-align: center; - margin: 0.5em 0 0.75em; - } - - .nowPlayingPositionSliderContainer { - margin: 0.7em 1em; - } - - .nowPlayingInfoButtons { - -webkit-box-pack: center; - -webkit-justify-content: center; - justify-content: center; - } - - .nowPlayingPageImageContainer { - width: auto; - margin-right: 0; - } - - .nowPlayingInfoControls { - margin-top: 1em; - max-width: 100%; - } - - .nowPlayingPageImage { - width: auto; - height: 36vh; - } +.contextMenuList { + padding: 1.5em 0; } -@media all and (orientation: portrait) and (max-width: 40em) { - .nowPlayingPageImage { - height: 30vh; - } +.contextMenuList a { + color: inherit !important; } -.nowPlayingTime { - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - align-items: center; - margin: 0 1em; +.contextMenuList i.listItemIcon { + font-size: x-large; } .nowPlayingSecondaryButtons { @@ -167,12 +165,17 @@ align-items: center; -webkit-flex-wrap: wrap; flex-wrap: wrap; - -webkit-box-pack: center; - -webkit-justify-content: center; - justify-content: center; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + z-index: 0; } -@media all and (min-width: 50em) { +@media all and (min-width: 63em) { + .nowPlayingPage { + padding: 8em 0 0 0 !important; + } + .nowPlayingSecondaryButtons { -webkit-box-flex: 1; -webkit-flex-grow: 1; @@ -181,6 +184,16 @@ -webkit-justify-content: flex-end; justify-content: flex-end; } + + .nowPlayingPageUserDataButtonsTitle { + display: none !important; + } + + .playlistSectionButton, + .nowPlayingPlaylist, + .nowPlayingContextMenu { + background: unset !important; + } } @media all and (min-width: 80em) { @@ -189,6 +202,414 @@ } } +@media all and (orientation: portrait) and (max-width: 47em) { + .remoteControlContent { + padding-left: 7.3% !important; + padding-right: 7.3% !important; + display: flex; + height: 100%; + flex-direction: column; + } + + .nowPlayingInfoContainer { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -webkit-flex-direction: column !important; + flex-direction: column !important; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; + width: 100%; + height: calc(100% - 4.2em); + } + + .nowPlayingPageTitle { + /* text-align: center; */ + margin: 0; + } + + .nowPlayingAlbum, + .nowPlayingArtist { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .nowPlayingInfoContainerMedia { + text-align: left !important; + width: 80%; + } + + .nowPlayingPositionSliderContainer { + margin: 0.2em 1em 0.2em 1em; + } + + .nowPlayingInfoButtons { + /* margin: 1.5em 0 0 0; */ + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; + font-size: x-large; + height: 100%; + } + + .nowPlayingPageImageContainer { + width: 100%; + margin: auto auto 0.5em; + } + + .nowPlayingPageImageContainerNoAlbum .cardImageContainer .cardImageIcon { + font-size: 15em; + color: inherit; + } + + .nowPlayingInfoControls { + margin: 0.5em 0 1em 0; + width: 100%; + -webkit-box-pack: start !important; + -webkit-justify-content: start !important; + justify-content: start !important; + } + + .nowPlayingSecondaryButtons { + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; + } + + .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { + width: 20%; + font-size: large; + } + + .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button { + padding-top: 0; + padding-right: 0; + margin-right: 0; + float: right; + border-radius: 0; + } + + .nowPlayingInfoButtons .btnRewind { + position: absolute; + left: 0; + margin-left: 0; + padding-left: 7.3%; + font-size: smaller; + } + + .nowPlayingInfoButtons .btnFastForward { + position: absolute; + right: 0; + margin-right: 0; + padding-right: 7.3%; + font-size: smaller; + } + + .paper-icon-button-light:hover { + color: #fff !important; + background-color: transparent !important; + } + + .btnPlayPause { + padding: 0; + margin: 0; + font-size: 1.7em; + } + + .btnPlayPause:hover { + background-color: transparent !important; + } + + .nowPlayingPageImage { + /* width: inherit; */ + overflow-y: hidden; + overflow: hidden; + margin: 0 auto; + } + + .nowPlayingPageImage.nowPlayingPageImageAudio { + width: 100%; + } + + .nowPlayingPageImageContainer.nowPlayingPageImagePoster { + height: 50%; + overflow: hidden; + } + + .nowPlayingPageImageContainer.nowPlayingPageImagePoster img { + height: 100%; + width: auto; + } + + #nowPlayingPage .playlistSection .playlist, + #nowPlayingPage .playlistSection .contextMenu { + position: absolute; + top: 12.2em; + bottom: 4.2em; + overflow: scroll; + padding: 0 1em; + display: inline-block; + left: 0; + right: 0; + z-index: 1000; + } + + .playlistSectionButton { + position: fixed; + bottom: 0; + left: 0; + height: 4.2em; + right: 0; + padding-left: 7.3%; + padding-right: 7.3%; + } + + .playlistSectionButton .btnTogglePlaylist { + font-size: larger; + margin: 0; + padding-left: 0; + } + + .playlistSectionButton .btnSavePlaylist { + margin: 0; + padding-right: 0; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + border-radius: 0; + } + + .playlistSectionButton .btnToggleContextMenu { + font-size: larger; + margin: 0; + padding-right: 0; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + border-radius: 0; + } + + .playlistSectionButton .volumecontrol { + width: 100%; + } + + .remoteControlSection { + margin: 0; + padding: 0 0 4.2em 0; + } + + .nowPlayingButtonsContainer { + display: flex; + height: 100%; + flex-direction: column; + } +} + +@media all and (orientation: landscape) and (max-width: 63em) { + .remoteControlContent { + padding-left: 4.3% !important; + padding-right: 4.3% !important; + display: flex; + height: 100%; + flex-direction: column; + } + + .nowPlayingInfoContainer { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -webkit-flex-direction: row !important; + flex-direction: row !important; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; + width: 100%; + height: calc(100% - 4.2em); + } + + .nowPlayingPageTitle { + /* text-align: center; */ + margin: 0; + } + + .nowPlayingInfoContainerMedia { + text-align: left !important; + width: 80%; + } + + .nowPlayingPositionSliderContainer { + margin: 0.2em 1em 0.2em 1em; + } + + .nowPlayingInfoButtons { + /* margin: 1.5em 0 0 0; */ + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; + font-size: x-large; + height: 100%; + } + + .nowPlayingPageImageContainer { + width: 30%; + margin: auto 1em auto auto; + } + + .nowPlayingPageImageContainerNoAlbum .cardImageContainer .cardImageIcon { + font-size: 12em; + color: inherit; + } + + .nowPlayingInfoControls { + margin: 0.5em 0 1em 0; + width: 100%; + -webkit-box-pack: start !important; + -webkit-justify-content: start !important; + justify-content: start !important; + } + + .nowPlayingSecondaryButtons { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; + } + + .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { + width: 20%; + font-size: large; + } + + .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button { + padding-top: 0; + padding-right: 0; + margin-right: 0; + float: right; + border-radius: 0; + } + + .paper-icon-button-light:hover { + color: #fff !important; + background-color: transparent !important; + } + + .btnPlayPause { + padding: 0; + margin: 0; + font-size: 1.7em; + } + + .btnPlayPause:hover { + background-color: transparent !important; + } + + .nowPlayingPageImage { + /* width: inherit; */ + overflow-y: hidden; + overflow: hidden; + margin: 0 auto; + } + + .nowPlayingPageImage.nowPlayingPageImageAudio { + width: 100%; + } + + .nowPlayingPageImageContainer.nowPlayingPageImagePoster { + height: 100%; + overflow: hidden; + } + + .nowPlayingPageImageContainer.nowPlayingPageImagePoster img { + height: 100%; + width: auto; + } + + #nowPlayingPage .playlistSection .playlist, + #nowPlayingPage .playlistSection .contextMenu { + position: absolute; + top: 7.2em; + bottom: 4.2em; + overflow: scroll; + padding: 0 1em; + display: inline-block; + left: 0; + right: 0; + z-index: 1000; + } + + .playlistSectionButton { + position: fixed; + bottom: 0; + left: 0; + height: 4.2em; + right: 0; + padding-left: 4.3%; + padding-right: 4.3%; + } + + .playlistSectionButton .btnTogglePlaylist { + font-size: larger; + margin: 0; + padding-left: 0; + } + + .playlistSectionButton .btnSavePlaylist { + margin: 0; + padding-right: 0; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + border-radius: 0; + } + + .playlistSectionButton .btnToggleContextMenu { + font-size: larger; + margin: 0; + padding-right: 0; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + border-radius: 0; + } + + .playlistSectionButton .volumecontrol { + width: 100%; + } + + .remoteControlSection { + margin: 4.2em 0 0 0; + padding: 0 0 4.2em 0; + } + + .nowPlayingButtonsContainer { + display: flex; + height: 100%; + flex-direction: column; + } +} + +.nowPlayingTime { + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; + margin: 0 1em; +} + .nowPlayingNavButtonContainer { width: 30em; } @@ -214,8 +635,11 @@ width: 9em; } -@media all and (max-width: 50em) { - .nowPlayingInfoButtons .nowPlayingPageUserDataButtons { +@media all and (max-width: 63em) { + .nowPlayingSecondaryButtons .nowPlayingPageUserDataButtons, + .nowPlayingSecondaryButtons .repeatToggleButton, + .nowPlayingInfoButtons .playlist .listItemMediaInfo, + .nowPlayingInfoButtons .btnStop { display: none !important; } @@ -223,17 +647,3 @@ font-size: 4em; } } - -@media all and (max-width: 47em) { - .nowPlayingInfoButtons .repeatToggleButton { - display: none !important; - } -} - -@media all and (max-width: 34em) { - .nowPlayingInfoButtons .btnNowPlayingFastForward, - .nowPlayingInfoButtons .btnNowPlayingRewind, - .nowPlayingInfoButtons .playlist .listItemMediaInfo { - display: none !important; - } -} diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 7b620d536a..327cd1dcf3 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,4 +1,4 @@ -define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageLoader", "playbackManager", "nowPlayingHelper", "events", "connectionManager", "apphost", "globalize", "layoutManager", "userSettings", "cardStyle", "emby-itemscontainer", "css!./remotecontrol.css", "emby-ratingbutton"], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings) { +define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageLoader", "playbackManager", "nowPlayingHelper", "events", "connectionManager", "apphost", "globalize", "layoutManager", "userSettings", "cardBuilder", "cardStyle", "emby-itemscontainer", "css!./remotecontrol.css", "emby-ratingbutton"], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder) { "use strict"; function showAudioMenu(context, player, button, item) { @@ -110,49 +110,93 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL return null; } - function updateNowPlayingInfo(context, state) { + function updateNowPlayingInfo(context, state, serverId) { var item = state.NowPlayingItem; var displayName = item ? getNowPlayingNameHtml(item).replace("
", " - ") : ""; - context.querySelector(".nowPlayingPageTitle").innerHTML = displayName; + if (typeof item !== 'undefined') { + var nowPlayingServerId = (item.ServerId || serverId); + if (item.Type == "Audio" || item.MediaStreams[0].Type == "Audio") { + var songName = item.Name; + if (item.Album != null && item.Artists != null) { + var albumName = item.Album; + var artistName; + if (item.ArtistItems != null) { + artistName = item.ArtistItems[0].Name; + context.querySelector(".nowPlayingAlbum").innerHTML = '${albumName}`; + context.querySelector(".nowPlayingArtist").innerHTML = '${artistName}`; + context.querySelector(".contextMenuAlbum").innerHTML = ' ` + globalize.translate("ViewAlbum") + ''; + context.querySelector(".contextMenuArtist").innerHTML = ' ` + globalize.translate("ViewArtist") + ''; + } else { + artistName = item.Artists; + context.querySelector(".nowPlayingAlbum").innerHTML = albumName; + context.querySelector(".nowPlayingArtist").innerHTML = artistName; + } + } + context.querySelector(".nowPlayingSongName").innerHTML = songName; + } else if (item.Type == "Episode") { + if (item.SeasonName != null) { + var seasonName = item.SeasonName; + context.querySelector(".nowPlayingSeason").innerHTML = '${seasonName}`; + } + if (item.SeriesName != null) { + var seriesName = item.SeriesName; + if (item.SeriesId !=null) { + context.querySelector(".nowPlayingSerie").innerHTML = '${seriesName}`; + } else { + context.querySelector(".nowPlayingSerie").innerHTML = seriesName; + } + } + context.querySelector(".nowPlayingEpisode").innerHTML = item.Name; + } else { + context.querySelector(".nowPlayingPageTitle").innerHTML = displayName; + } - if (displayName.length > 0) { - context.querySelector(".nowPlayingPageTitle").classList.remove("hide"); - } else { - context.querySelector(".nowPlayingPageTitle").classList.add("hide"); - } + if (displayName.length > 0 && item.Type != "Audio" && item.Type != "Episode") { + context.querySelector(".nowPlayingPageTitle").classList.remove("hide"); + } else { + context.querySelector(".nowPlayingPageTitle").classList.add("hide"); + } - var url = item ? seriesImageUrl(item, { - maxHeight: 300 * 2 - }) || imageUrl(item, { - maxHeight: 300 * 2 - }) : null; + var url = item ? seriesImageUrl(item, { + maxHeight: 300 * 2 + }) || imageUrl(item, { + maxHeight: 300 * 2 + }) : null; - console.debug("updateNowPlayingInfo"); - setImageUrl(context, url); - if (item) { - backdrop.setBackdrops([item]); - var apiClient = connectionManager.getApiClient(item.ServerId); - apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) { - var userData = fullItem.UserData || {}; - var likes = null == userData.Likes ? "" : userData.Likes; - context.querySelector(".nowPlayingPageUserDataButtons").innerHTML = ''; - }); - } else { - backdrop.clear(); - context.querySelector(".nowPlayingPageUserDataButtons").innerHTML = ""; + console.debug("updateNowPlayingInfo"); + setImageUrl(context, state, url); + if (item) { + backdrop.setBackdrops([item]); + var apiClient = connectionManager.getApiClient(item.ServerId); + apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) { + var userData = fullItem.UserData || {}; + var likes = null == userData.Likes ? "" : userData.Likes; + context.querySelector(".nowPlayingPageUserDataButtonsTitle").innerHTML = ''; + context.querySelector(".nowPlayingPageUserDataButtons").innerHTML = ''; + }); + } else { + backdrop.clear(); + context.querySelector(".nowPlayingPageUserDataButtons").innerHTML = ""; + } } } - function setImageUrl(context, url) { + function setImageUrl(context, state, url) { currentImgUrl = url; + var item = state.NowPlayingItem; var imgContainer = context.querySelector(".nowPlayingPageImageContainer"); if (url) { imgContainer.innerHTML = ''; - imgContainer.classList.remove("hide"); + if (item.Type == "Audio") { + context.querySelector(".nowPlayingPageImage").classList.add("nowPlayingPageImageAudio"); + context.querySelector(".nowPlayingPageImageContainer").classList.remove("nowPlayingPageImageAudio"); + } else { + context.querySelector(".nowPlayingPageImageContainer").classList.add("nowPlayingPageImagePoster"); + context.querySelector(".nowPlayingPageImage").classList.remove("nowPlayingPageImageAudio"); + } } else { - imgContainer.classList.add("hide"); - imgContainer.innerHTML = ""; + imgContainer.innerHTML = '
'; } } @@ -199,28 +243,35 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL var supportedCommands = playerInfo.supportedCommands; currentPlayerSupportedCommands = supportedCommands; var playState = state.PlayState || {}; - buttonVisible(context.querySelector(".btnToggleFullscreen"), item && "Video" == item.MediaType && -1 != supportedCommands.indexOf("ToggleFullscreen")); + var isSupportedCommands = supportedCommands.includes("DisplayMessage") || supportedCommands.includes("SendString") || supportedCommands.includes("Select"); + buttonVisible(context.querySelector(".btnToggleFullscreen"), item && "Video" == item.MediaType && supportedCommands.includes("ToggleFullscreen")); updateAudioTracksDisplay(player, context); updateSubtitleTracksDisplay(player, context); - if (-1 != supportedCommands.indexOf("DisplayMessage") && !currentPlayer.isLocalPlayer) { + if (supportedCommands.includes("DisplayMessage") && !currentPlayer.isLocalPlayer) { context.querySelector(".sendMessageSection").classList.remove("hide"); } else { context.querySelector(".sendMessageSection").classList.add("hide"); } - if (-1 != supportedCommands.indexOf("SendString") && !currentPlayer.isLocalPlayer) { + if (supportedCommands.includes("SendString") && !currentPlayer.isLocalPlayer) { context.querySelector(".sendTextSection").classList.remove("hide"); } else { context.querySelector(".sendTextSection").classList.add("hide"); } - if (-1 != supportedCommands.indexOf("Select") && !currentPlayer.isLocalPlayer) { + if (supportedCommands.includes("Select") && !currentPlayer.isLocalPlayer) { context.querySelector(".navigationSection").classList.remove("hide"); } else { context.querySelector(".navigationSection").classList.add("hide"); } + if (isSupportedCommands && !currentPlayer.isLocalPlayer) { + context.querySelector(".remoteControlSection").classList.remove("hide"); + } else { + context.querySelector(".remoteControlSection").classList.add("hide"); + } + buttonVisible(context.querySelector(".btnStop"), null != item); buttonVisible(context.querySelector(".btnNextTrack"), null != item); buttonVisible(context.querySelector(".btnPreviousTrack"), null != item); @@ -331,7 +382,7 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL function updatePlayPauseState(isPaused, isActive) { var context = dlg; var btnPlayPause = context.querySelector(".btnPlayPause"); - btnPlayPause.querySelector("i").innerHTML = isPaused ? "" : "pause"; + btnPlayPause.querySelector("i").innerHTML = isPaused ? "" : ""; buttonVisible(btnPlayPause, isActive); } @@ -374,9 +425,9 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL }); if (items.length) { - context.querySelector(".playlistSection").classList.remove("hide"); + context.querySelector(".btnTogglePlaylist").classList.remove("hide"); } else { - context.querySelector(".playlistSection").classList.add("hide"); + context.querySelector(".btnTogglePlaylist").classList.add("hide"); } var itemsContainer = context.querySelector(".playlist"); @@ -393,6 +444,9 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL } imageLoader.lazyChildren(itemsContainer); + context.querySelector(".playlist").classList.add("hide"); + context.querySelector(".contextMenu").classList.add("hide"); + context.querySelector(".btnSavePlaylist").classList.add("hide"); }); } @@ -614,27 +668,13 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL return datetime.getDisplayRunningTime(ticks); }; - var volumeSliderTimer; - function setVolume() { - clearTimeout(volumeSliderTimer); - volumeSliderTimer = null; - playbackManager.setVolume(this.value, currentPlayer); } - function setVolumeDelayed() { - if (!volumeSliderTimer) { - var that = this; - volumeSliderTimer = setTimeout(function () { - setVolume.call(that); - }, 700); - } - } - context.querySelector(".nowPlayingVolumeSlider").addEventListener("change", setVolume); - context.querySelector(".nowPlayingVolumeSlider").addEventListener("mousemove", setVolumeDelayed); - context.querySelector(".nowPlayingVolumeSlider").addEventListener("touchmove", setVolumeDelayed); + context.querySelector(".nowPlayingVolumeSlider").addEventListener("mousemove", setVolume); + context.querySelector(".nowPlayingVolumeSlider").addEventListener("touchmove", setVolume); context.querySelector(".buttonMute").addEventListener("click", function () { playbackManager.toggleMute(currentPlayer); }); @@ -648,6 +688,27 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL playbackManager.movePlaylistItem(playlistItemId, newIndex, currentPlayer); }); context.querySelector(".btnSavePlaylist").addEventListener("click", savePlaylist); + context.querySelector(".btnTogglePlaylist").addEventListener("click", function () { + if (context.querySelector(".playlist").classList.contains("hide")) { + context.querySelector(".playlist").classList.remove("hide"); + context.querySelector(".btnSavePlaylist").classList.remove("hide"); + context.querySelector(".contextMenu").classList.add("hide"); + context.querySelector(".volumecontrol").classList.add("hide"); + } else { + context.querySelector(".playlist").classList.add("hide"); + context.querySelector(".btnSavePlaylist").classList.add("hide"); + context.querySelector(".volumecontrol").classList.remove("hide"); + } + }); + context.querySelector(".btnToggleContextMenu").addEventListener("click", function () { + if (context.querySelector(".contextMenu").classList.contains("hide")) { + context.querySelector(".contextMenu").classList.remove("hide"); + context.querySelector(".btnSavePlaylist").classList.add("hide"); + context.querySelector(".playlist").classList.add("hide"); + } else { + context.querySelector(".contextMenu").classList.add("hide"); + } + }); } function onPlayerChange() { @@ -694,6 +755,18 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL } function init(ownerView, context) { + let contextmenuHtml = ``; + let volumecontrolHtml = '
'; + volumecontrolHtml += ``; + volumecontrolHtml += '
'; + volumecontrolHtml += '
'; + if (!layoutManager.mobile) { + context.querySelector('.nowPlayingSecondaryButtons').innerHTML += volumecontrolHtml; + context.querySelector('.playlistSectionButton').innerHTML += contextmenuHtml; + } else { + context.querySelector('.playlistSectionButton').innerHTML += volumecontrolHtml + contextmenuHtml; + } + bindEvents(context); context.querySelector(".sendMessageForm").addEventListener("submit", onMessageSubmit); context.querySelector(".typeTextForm").addEventListener("submit", onSendStringSubmit); diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index d2bf1bb727..48ccee21c8 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -258,6 +258,11 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f direction: 'horizontal', // Loop is disabled due to the virtual slides option not supporting it. loop: false, + zoom: { + minRatio: 1, + toggle: true, + containerClass: 'slider-zoom-container' + }, autoplay: !options.interactive, keyboard: { enabled: true diff --git a/src/components/slideshow/style.css b/src/components/slideshow/style.css index 2bea7c9696..fc747cf371 100644 --- a/src/components/slideshow/style.css +++ b/src/components/slideshow/style.css @@ -41,17 +41,12 @@ } .swiper-slide-img { - width: auto; - height: auto; - max-width: 100%; - max-height: 100%; - -ms-transform: translate(-50%, -50%); - -webkit-transform: translate(-50%, -50%); - -moz-transform: translate(-50%, -50%); - transform: translate(-50%, -50%); - position: absolute; - left: 50%; - top: 50%; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + text-align: center; } .slideshowButtonIcon { @@ -138,3 +133,12 @@ .slideSubtitle { color: #ccc; } + +.swiper-slide { + display: flex; + flex-direction: column; +} + +.slider-zoom-container { + margin: auto; +} diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 1ff30712f6..123b4ba201 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -397,7 +397,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', var items = []; items.push({ - name: Globalize.translate('Download'), + name: globalize.translate('Download'), id: 'download' }); diff --git a/src/components/tvproviders/schedulesdirect.js b/src/components/tvproviders/schedulesdirect.js index cf11e5736d..649ac5017b 100644 --- a/src/components/tvproviders/schedulesdirect.js +++ b/src/components/tvproviders/schedulesdirect.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "emby-select", "emby-button", "flexStyles"], function ($, loading) { +define(["jQuery", "loading", "globalize", "emby-checkbox", "listViewStyle", "emby-input", "emby-select", "emby-button", "flexStyles"], function ($, loading, globalize) { "use strict"; return function (page, providerId, options) { @@ -69,7 +69,7 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em $(page.querySelector(".txtZipCode")).trigger("change"); }, function () { // ApiClient.getJSON() error handler Dashboard.alert({ - message: Globalize.translate("ErrorGettingTvLineups") + message: globalize.translate("ErrorGettingTvLineups") }); }); loading.hide(); @@ -130,7 +130,7 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em reload(); }, function () { Dashboard.alert({ // ApiClient.ajax() error handler - message: Globalize.translate("ErrorSavingTvProvider") + message: globalize.translate("ErrorSavingTvProvider") }); }); }); @@ -141,7 +141,7 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em if (!selectedListingsId) { return void Dashboard.alert({ - message: Globalize.translate("ErrorPleaseSelectLineup") + message: globalize.translate("ErrorPleaseSelectLineup") }); } @@ -178,7 +178,7 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em }, function () { loading.hide(); Dashboard.alert({ - message: Globalize.translate("ErrorAddingListingsToSchedulesDirect") + message: globalize.translate("ErrorAddingListingsToSchedulesDirect") }); }); }); @@ -210,7 +210,7 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em loading.hide(); }, function (result) { Dashboard.alert({ - message: Globalize.translate("ErrorGettingTvLineups") + message: globalize.translate("ErrorGettingTvLineups") }); refreshListings(""); loading.hide(); @@ -290,7 +290,7 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em page.querySelector(".selectTunersSection").classList.remove("hide"); } }); - $(".createAccountHelp", page).html(Globalize.translate("MessageCreateAccountAt", 'http://www.schedulesdirect.org')); + $(".createAccountHelp", page).html(globalize.translate("MessageCreateAccountAt", 'http://www.schedulesdirect.org')); reload(); }; }; diff --git a/src/components/tvproviders/xmltv.js b/src/components/tvproviders/xmltv.js index 7e7d381f09..991ed49a49 100644 --- a/src/components/tvproviders/xmltv.js +++ b/src/components/tvproviders/xmltv.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "emby-checkbox", "emby-input", "listViewStyle", "paper-icon-button-light"], function ($, loading) { +define(["jQuery", "loading", "globalize", "emby-checkbox", "emby-input", "listViewStyle", "paper-icon-button-light"], function ($, loading, globalize) { "use strict"; return function (page, providerId, options) { @@ -92,7 +92,7 @@ define(["jQuery", "loading", "emby-checkbox", "emby-input", "listViewStyle", "pa }, function () { loading.hide(); Dashboard.alert({ - message: Globalize.translate("ErrorAddingXmlTvFile") + message: globalize.translate("ErrorAddingXmlTvFile") }); }); }); diff --git a/src/controllers/auth/addserver.js b/src/controllers/auth/addserver.js index a55ba3066c..8cead5abfd 100644 --- a/src/controllers/auth/addserver.js +++ b/src/controllers/auth/addserver.js @@ -1,4 +1,4 @@ -define(["appSettings", "loading", "browser", "emby-button"], function(appSettings, loading, browser) { +define(["appSettings", "loading", "browser", "globalize", "emby-button"], function(appSettings, loading, browser, globalize) { "use strict"; function handleConnectionResult(page, result) { @@ -17,13 +17,13 @@ define(["appSettings", "loading", "browser", "emby-button"], function(appSetting break; case "ServerUpdateNeeded": Dashboard.alert({ - message: Globalize.translate("ServerUpdateNeeded", 'https://github.com/jellyfin/jellyfin') + message: globalize.translate("ServerUpdateNeeded", 'https://github.com/jellyfin/jellyfin') }); break; case "Unavailable": Dashboard.alert({ - message: Globalize.translate("MessageUnableToConnectToServer"), - title: Globalize.translate("HeaderConnectionFailure") + message: globalize.translate("MessageUnableToConnectToServer"), + title: globalize.translate("HeaderConnectionFailure") }); } } diff --git a/src/controllers/auth/forgotpassword.js b/src/controllers/auth/forgotpassword.js index e0f8ea4ef8..32052d1f77 100644 --- a/src/controllers/auth/forgotpassword.js +++ b/src/controllers/auth/forgotpassword.js @@ -1,23 +1,23 @@ -define([], function () { +define(["globalize"], function (globalize) { "use strict"; function processForgotPasswordResult(result) { if ("ContactAdmin" == result.Action) { return void Dashboard.alert({ - message: Globalize.translate("MessageContactAdminToResetPassword"), - title: Globalize.translate("HeaderForgotPassword") + message: globalize.translate("MessageContactAdminToResetPassword"), + title: globalize.translate("HeaderForgotPassword") }); } if ("InNetworkRequired" == result.Action) { return void Dashboard.alert({ - message: Globalize.translate("MessageForgotPasswordInNetworkRequired"), - title: Globalize.translate("HeaderForgotPassword") + message: globalize.translate("MessageForgotPasswordInNetworkRequired"), + title: globalize.translate("HeaderForgotPassword") }); } if ("PinCode" == result.Action) { - var msg = Globalize.translate("MessageForgotPasswordFileCreated"); + var msg = globalize.translate("MessageForgotPasswordFileCreated"); msg += "
"; msg += "
"; msg += "Enter PIN here to finish Password Reset
"; @@ -26,7 +26,7 @@ define([], function () { msg += "
"; return void Dashboard.alert({ message: msg, - title: Globalize.translate("HeaderForgotPassword"), + title: globalize.translate("HeaderForgotPassword"), callback: function () { Dashboard.navigate("forgotpasswordpin.html"); } diff --git a/src/controllers/auth/forgotpasswordpin.js b/src/controllers/auth/forgotpasswordpin.js index 47b1c899b9..f88f57ad77 100644 --- a/src/controllers/auth/forgotpasswordpin.js +++ b/src/controllers/auth/forgotpasswordpin.js @@ -1,15 +1,15 @@ -define([], function () { +define(["globalize"], function (globalize) { "use strict"; function processForgotPasswordResult(result) { if (result.Success) { - var msg = Globalize.translate("MessagePasswordResetForUsers"); + var msg = globalize.translate("MessagePasswordResetForUsers"); msg += "
"; msg += "
"; msg += result.UsersReset.join("
"); return void Dashboard.alert({ message: msg, - title: Globalize.translate("HeaderPasswordReset"), + title: globalize.translate("HeaderPasswordReset"), callback: function () { window.location.href = "index.html"; } @@ -17,8 +17,8 @@ define([], function () { } Dashboard.alert({ - message: Globalize.translate("MessageInvalidForgotPasswordPin"), - title: Globalize.translate("HeaderPasswordReset") + message: globalize.translate("MessageInvalidForgotPasswordPin"), + title: globalize.translate("HeaderPasswordReset") }); } diff --git a/src/controllers/auth/login.js b/src/controllers/auth/login.js index 4296b8bfb3..05075efe52 100644 --- a/src/controllers/auth/login.js +++ b/src/controllers/auth/login.js @@ -1,4 +1,4 @@ -define(["apphost", "appSettings", "dom", "connectionManager", "loading", "layoutManager", "browser", "cardStyle", "emby-checkbox"], function (appHost, appSettings, dom, connectionManager, loading, layoutManager, browser) { +define(["apphost", "appSettings", "dom", "connectionManager", "loading", "layoutManager", "browser", "globalize", "cardStyle", "emby-checkbox"], function (appHost, appSettings, dom, connectionManager, loading, layoutManager, browser, globalize) { "use strict"; var enableFocusTransform = !browser.slow && !browser.edge; @@ -24,14 +24,16 @@ define(["apphost", "appSettings", "dom", "connectionManager", "loading", "layout page.querySelector("#txtManualPassword").value = ""; loading.hide(); - if (response.status === 401) { + const UnauthorizedOrForbidden = [401, 403]; + if (UnauthorizedOrForbidden.includes(response.status)) { require(["toast"], function (toast) { - toast(Globalize.translate("MessageInvalidUser")); + const messageKey = response.status === 401 ? "MessageInvalidUser" : "MessageUnauthorizedUser"; + toast(globalize.translate(messageKey)); }); } else { Dashboard.alert({ - message: Globalize.translate("MessageUnableToConnectToServer"), - title: Globalize.translate("HeaderConnectionFailure") + message: globalize.translate("MessageUnableToConnectToServer"), + title: globalize.translate("HeaderConnectionFailure") }); } }); diff --git a/src/controllers/apikeys.js b/src/controllers/dashboard/apikeys.js similarity index 100% rename from src/controllers/apikeys.js rename to src/controllers/dashboard/apikeys.js diff --git a/src/controllers/device.js b/src/controllers/dashboard/devices/device.js similarity index 100% rename from src/controllers/device.js rename to src/controllers/dashboard/devices/device.js diff --git a/src/controllers/devices.js b/src/controllers/dashboard/devices/devices.js similarity index 100% rename from src/controllers/devices.js rename to src/controllers/dashboard/devices/devices.js diff --git a/src/controllers/dlnaprofile.js b/src/controllers/dashboard/dlna/dlnaprofile.js similarity index 96% rename from src/controllers/dlnaprofile.js rename to src/controllers/dashboard/dlna/dlnaprofile.js index ca0d3afdb1..f4d5704a27 100644 --- a/src/controllers/dlnaprofile.js +++ b/src/controllers/dashboard/dlna/dlnaprofile.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-input", "emby-checkbox", "listViewStyle", "emby-button"], function ($, loading) { +define(["jQuery", "loading", "globalize", "fnchecked", "emby-select", "emby-button", "emby-input", "emby-checkbox", "listViewStyle", "emby-button"], function ($, loading, globalize) { "use strict"; function loadProfile(page) { @@ -258,14 +258,14 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += "
"; html += ''; - html += "

" + Globalize.translate("ValueContainer", profile.Container || allText) + "

"; + html += "

" + globalize.translate("ValueContainer", profile.Container || allText) + "

"; if ("Video" == profile.Type) { - html += "

" + Globalize.translate("ValueVideoCodec", profile.VideoCodec || allText) + "

"; - html += "

" + Globalize.translate("ValueAudioCodec", profile.AudioCodec || allText) + "

"; + html += "

" + globalize.translate("ValueVideoCodec", profile.VideoCodec || allText) + "

"; + html += "

" + globalize.translate("ValueAudioCodec", profile.AudioCodec || allText) + "

"; } else { if ("Audio" == profile.Type) { - html += "

" + Globalize.translate("ValueCodec", profile.AudioCodec || allText) + "

"; + html += "

" + globalize.translate("ValueCodec", profile.AudioCodec || allText) + "

"; } } @@ -319,14 +319,14 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += "
"; html += ''; html += "

Protocol: " + (profile.Protocol || "Http") + "

"; - html += "

" + Globalize.translate("ValueContainer", profile.Container || allText) + "

"; + html += "

" + globalize.translate("ValueContainer", profile.Container || allText) + "

"; if ("Video" == profile.Type) { - html += "

" + Globalize.translate("ValueVideoCodec", profile.VideoCodec || allText) + "

"; - html += "

" + Globalize.translate("ValueAudioCodec", profile.AudioCodec || allText) + "

"; + html += "

" + globalize.translate("ValueVideoCodec", profile.VideoCodec || allText) + "

"; + html += "

" + globalize.translate("ValueAudioCodec", profile.AudioCodec || allText) + "

"; } else { if ("Audio" == profile.Type) { - html += "

" + Globalize.translate("ValueCodec", profile.AudioCodec || allText) + "

"; + html += "

" + globalize.translate("ValueCodec", profile.AudioCodec || allText) + "

"; } } @@ -404,11 +404,11 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += "
"; html += ''; - html += "

" + Globalize.translate("ValueContainer", profile.Container || allText) + "

"; + html += "

" + globalize.translate("ValueContainer", profile.Container || allText) + "

"; if (profile.Conditions && profile.Conditions.length) { html += "

"; - html += Globalize.translate("ValueConditions", profile.Conditions.map(function (c) { + html += globalize.translate("ValueConditions", profile.Conditions.map(function (c) { return c.Property; }).join(", ")); html += "

"; @@ -476,11 +476,11 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += "
"; html += ''; - html += "

" + Globalize.translate("ValueCodec", profile.Codec || allText) + "

"; + html += "

" + globalize.translate("ValueCodec", profile.Codec || allText) + "

"; if (profile.Conditions && profile.Conditions.length) { html += "

"; - html += Globalize.translate("ValueConditions", profile.Conditions.map(function (c) { + html += globalize.translate("ValueConditions", profile.Conditions.map(function (c) { return c.Property; }).join(", ")); html += "

"; @@ -547,20 +547,20 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in html += "
"; html += ''; - html += "

" + Globalize.translate("ValueContainer", profile.Container || allText) + "

"; + html += "

" + globalize.translate("ValueContainer", profile.Container || allText) + "

"; if ("Video" == profile.Type) { - html += "

" + Globalize.translate("ValueVideoCodec", profile.VideoCodec || allText) + "

"; - html += "

" + Globalize.translate("ValueAudioCodec", profile.AudioCodec || allText) + "

"; + html += "

" + globalize.translate("ValueVideoCodec", profile.VideoCodec || allText) + "

"; + html += "

" + globalize.translate("ValueAudioCodec", profile.AudioCodec || allText) + "

"; } else { if ("Audio" == profile.Type) { - html += "

" + Globalize.translate("ValueCodec", profile.AudioCodec || allText) + "

"; + html += "

" + globalize.translate("ValueCodec", profile.AudioCodec || allText) + "

"; } } if (profile.Conditions && profile.Conditions.length) { html += "

"; - html += Globalize.translate("ValueConditions", profile.Conditions.map(function (c) { + html += globalize.translate("ValueConditions", profile.Conditions.map(function (c) { return c.Property; }).join(", ")); html += "

"; @@ -690,7 +690,7 @@ define(["jQuery", "loading", "fnchecked", "emby-select", "emby-button", "emby-in var currentProfile; var currentSubProfile; var isSubProfileNew; - var allText = Globalize.translate("LabelAll"); + var allText = globalize.translate("LabelAll"); $(document).on("pageinit", "#dlnaProfilePage", function () { var page = this; diff --git a/src/controllers/dlnaprofiles.js b/src/controllers/dashboard/dlna/dlnaprofiles.js similarity index 100% rename from src/controllers/dlnaprofiles.js rename to src/controllers/dashboard/dlna/dlnaprofiles.js diff --git a/src/controllers/dlnasettings.js b/src/controllers/dashboard/dlna/dlnasettings.js similarity index 91% rename from src/controllers/dlnasettings.js rename to src/controllers/dashboard/dlna/dlnasettings.js index fbb3af1205..dd71b9ed1a 100644 --- a/src/controllers/dlnasettings.js +++ b/src/controllers/dashboard/dlna/dlnasettings.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "globalize", "fnchecked"], function ($, loading, libraryMenu, globalize) { "use strict"; function loadPage(page, config, users) { @@ -34,10 +34,10 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, function getTabs() { return [{ href: "dlnasettings.html", - name: Globalize.translate("TabSettings") + name: globalize.translate("TabSettings") }, { href: "dlnaprofiles.html", - name: Globalize.translate("TabProfiles") + name: globalize.translate("TabProfiles") }]; } diff --git a/src/controllers/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js similarity index 98% rename from src/controllers/encodingsettings.js rename to src/controllers/dashboard/encodingsettings.js index 1b27188665..9820d7401f 100644 --- a/src/controllers/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -116,13 +116,13 @@ define(["jQuery", "loading", "globalize", "dom", "libraryMenu"], function ($, lo function getTabs() { return [{ href: "encodingsettings.html", - name: Globalize.translate("Transcoding") + name: globalize.translate("Transcoding") }, { href: "playbackconfiguration.html", - name: Globalize.translate("TabResumeSettings") + name: globalize.translate("TabResumeSettings") }, { href: "streamingsettings.html", - name: Globalize.translate("TabStreaming") + name: globalize.translate("TabStreaming") }]; } diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index a434e46241..68d72d4322 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "fnchecked", "emby-checkbox", "emby-textarea", "emby-input", "emby-select", "emby-button"], function ($, loading) { +define(["jQuery", "loading", "globalize", "fnchecked", "emby-checkbox", "emby-textarea", "emby-input", "emby-select", "emby-button"], function ($, loading, globalize) { "use strict"; function loadPage(page, config, languageOptions, systemInfo) { @@ -58,7 +58,7 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox", "emby-textarea", "emb }); }, function () { require(["alert"], function (alert) { - alert(Globalize.translate("DefaultErrorMessage")); + alert(globalize.translate("DefaultErrorMessage")); }); Dashboard.processServerConfigurationUpdateResult(); @@ -83,8 +83,8 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox", "emby-textarea", "emb picker.close(); }, validateWriteable: true, - header: Globalize.translate("HeaderSelectServerCachePath"), - instruction: Globalize.translate("HeaderSelectServerCachePathHelp") + header: globalize.translate("HeaderSelectServerCachePath"), + instruction: globalize.translate("HeaderSelectServerCachePathHelp") }); }); }); @@ -106,8 +106,8 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox", "emby-textarea", "emb picker.close(); }, validateWriteable: true, - header: Globalize.translate("HeaderSelectMetadataPath"), - instruction: Globalize.translate("HeaderSelectMetadataPathHelp"), + header: globalize.translate("HeaderSelectMetadataPath"), + instruction: globalize.translate("HeaderSelectMetadataPathHelp"), enableNetworkSharePath: true }); }); diff --git a/src/controllers/librarydisplay.js b/src/controllers/dashboard/librarydisplay.js similarity index 93% rename from src/controllers/librarydisplay.js rename to src/controllers/dashboard/librarydisplay.js index 78294f4407..603ab1ee67 100644 --- a/src/controllers/librarydisplay.js +++ b/src/controllers/dashboard/librarydisplay.js @@ -4,16 +4,16 @@ define(["globalize", "loading", "libraryMenu", "emby-checkbox", "emby-button", " function getTabs() { return [{ href: "library.html", - name: Globalize.translate("HeaderLibraries") + name: globalize.translate("HeaderLibraries") }, { href: "librarydisplay.html", - name: Globalize.translate("TabDisplay") + name: globalize.translate("TabDisplay") }, { href: "metadataimages.html", - name: Globalize.translate("TabMetadata") + name: globalize.translate("TabMetadata") }, { href: "metadatanfo.html", - name: Globalize.translate("TabNfoSettings") + name: globalize.translate("TabNfoSettings") }]; } diff --git a/src/controllers/medialibrarypage.js b/src/controllers/dashboard/medialibrarypage.js similarity index 100% rename from src/controllers/medialibrarypage.js rename to src/controllers/dashboard/medialibrarypage.js diff --git a/src/controllers/metadataimagespage.js b/src/controllers/dashboard/metadataimagespage.js similarity index 87% rename from src/controllers/metadataimagespage.js rename to src/controllers/dashboard/metadataimagespage.js index 39b4ca6fef..42d751a248 100644 --- a/src/controllers/metadataimagespage.js +++ b/src/controllers/dashboard/metadataimagespage.js @@ -1,4 +1,4 @@ -define(["jQuery", "dom", "loading", "libraryMenu", "listViewStyle"], function($, dom, loading, libraryMenu) { +define(["jQuery", "dom", "loading", "libraryMenu", "globalize", "listViewStyle"], function($, dom, loading, libraryMenu, globalize) { "use strict"; function populateLanguages(select) { @@ -43,16 +43,16 @@ define(["jQuery", "dom", "loading", "libraryMenu", "listViewStyle"], function($, function getTabs() { return [{ href: "library.html", - name: Globalize.translate("HeaderLibraries") + name: globalize.translate("HeaderLibraries") }, { href: "librarydisplay.html", - name: Globalize.translate("TabDisplay") + name: globalize.translate("TabDisplay") }, { href: "metadataimages.html", - name: Globalize.translate("TabMetadata") + name: globalize.translate("TabMetadata") }, { href: "metadatanfo.html", - name: Globalize.translate("TabNfoSettings") + name: globalize.translate("TabNfoSettings") }]; } diff --git a/src/controllers/metadatanfo.js b/src/controllers/dashboard/metadatanfo.js similarity index 85% rename from src/controllers/metadatanfo.js rename to src/controllers/dashboard/metadatanfo.js index 20049837dd..586663218a 100644 --- a/src/controllers/metadatanfo.js +++ b/src/controllers/dashboard/metadatanfo.js @@ -1,8 +1,8 @@ -define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "globalize"], function ($, loading, libraryMenu, globalize) { "use strict"; function loadPage(page, config, users) { - var html = '"; + var html = '"; html += users.map(function (user) { return '"; }).join(""); @@ -33,7 +33,7 @@ define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) function showConfirmMessage(config) { var msg = []; - msg.push(Globalize.translate("MetadataSettingChangeHelp")); + msg.push(globalize.translate("MetadataSettingChangeHelp")); require(["alert"], function (alert) { alert({ @@ -45,16 +45,16 @@ define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) function getTabs() { return [{ href: "library.html", - name: Globalize.translate("HeaderLibraries") + name: globalize.translate("HeaderLibraries") }, { href: "librarydisplay.html", - name: Globalize.translate("TabDisplay") + name: globalize.translate("TabDisplay") }, { href: "metadataimages.html", - name: Globalize.translate("TabMetadata") + name: globalize.translate("TabMetadata") }, { href: "metadatanfo.html", - name: Globalize.translate("TabNfoSettings") + name: globalize.translate("TabNfoSettings") }]; } diff --git a/src/controllers/playbackconfiguration.js b/src/controllers/dashboard/playbackconfiguration.js similarity index 84% rename from src/controllers/playbackconfiguration.js rename to src/controllers/dashboard/playbackconfiguration.js index cd2136cea9..a4ba6bb625 100644 --- a/src/controllers/playbackconfiguration.js +++ b/src/controllers/dashboard/playbackconfiguration.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "globalize"], function ($, loading, libraryMenu, globalize) { "use strict"; function loadPage(page, config) { @@ -25,13 +25,13 @@ define(["jQuery", "loading", "libraryMenu"], function ($, loading, libraryMenu) function getTabs() { return [{ href: "encodingsettings.html", - name: Globalize.translate("Transcoding") + name: globalize.translate("Transcoding") }, { href: "playbackconfiguration.html", - name: Globalize.translate("TabResumeSettings") + name: globalize.translate("TabResumeSettings") }, { href: "streamingsettings.html", - name: Globalize.translate("TabStreaming") + name: globalize.translate("TabStreaming") }]; } diff --git a/src/controllers/dashboard/plugins/add.js b/src/controllers/dashboard/plugins/add.js index a05cac461b..3b2bf9e765 100644 --- a/src/controllers/dashboard/plugins/add.js +++ b/src/controllers/dashboard/plugins/add.js @@ -7,8 +7,8 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e for (var i = 0; i < length; i++) { var version = packageInfo.versions[i]; - html += '

' + version.versionStr + " (" + version.classification + ")

"; - html += '
' + version.description + "
"; + html += '

' + version.version + "

"; + html += '
' + version.changelog + "
"; } $("#revisionHistory", page).html(html); @@ -19,7 +19,7 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e for (var i = 0; i < packageInfo.versions.length; i++) { var version = packageInfo.versions[i]; - html += '"; + html += '"; } var selectmenu = $("#selectVersion", page).html(html); @@ -28,16 +28,9 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e $("#pCurrentVersion", page).hide().html(""); } - var packageVersion = packageInfo.versions.filter(function (current) { - return "Release" == current.classification; - })[0]; - packageVersion = packageVersion || packageInfo.versions.filter(function (current) { - return "Beta" == current.classification; - })[0]; - + var packageVersion = packageInfo.versions[0]; if (packageVersion) { - var val = packageVersion.versionStr + "|" + packageVersion.classification; - selectmenu.val(val); + selectmenu.val(packageVersion.version); } } @@ -45,44 +38,23 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e var installedPlugin = installedPlugins.filter(function (ip) { return ip.Name == pkg.name; })[0]; + populateVersions(pkg, page, installedPlugin); populateHistory(pkg, page); + $(".pluginName", page).html(pkg.name); + $("#btnInstallDiv", page).removeClass("hide"); + $("#pSelectVersion", page).removeClass("hide"); - if ("Server" == pkg.targetSystem) { - $("#btnInstallDiv", page).removeClass("hide"); - $("#nonServerMsg", page).hide(); - $("#pSelectVersion", page).removeClass("hide"); + if (pkg.overview) { + $("#overview", page).show().html(pkg.overview); } else { - $("#btnInstallDiv", page).addClass("hide"); - $("#pSelectVersion", page).addClass("hide"); - var msg = globalize.translate("MessageInstallPluginFromApp"); - $("#nonServerMsg", page).html(msg).show(); + $("#overview", page).hide(); } - if (pkg.shortDescription) { - $("#tagline", page).show().html(pkg.shortDescription); - } else { - $("#tagline", page).hide(); - } - - $("#overview", page).html(pkg.overview || ""); + $("#description", page).html(pkg.description); $("#developer", page).html(pkg.owner); - if (pkg.richDescUrl) { - $("#pViewWebsite", page).show(); - $("#pViewWebsite a", page).attr("href", pkg.richDescUrl); - } else { - $("#pViewWebsite", page).hide(); - } - - if (pkg.previewImage || pkg.thumbImage) { - var img = pkg.previewImage ? pkg.previewImage : pkg.thumbImage; - $("#pPreviewImage", page).show().html(""); - } else { - $("#pPreviewImage", page).hide().html(""); - } - if (installedPlugin) { var currentVersionText = globalize.translate("MessageYouHaveVersionInstalled", "" + installedPlugin.Version + ""); $("#pCurrentVersion", page).show().html(currentVersionText); diff --git a/src/controllers/dashboard/plugins/available.js b/src/controllers/dashboard/plugins/available.js index adccfa3935..aff9b89ed5 100644 --- a/src/controllers/dashboard/plugins/available.js +++ b/src/controllers/dashboard/plugins/available.js @@ -98,21 +98,14 @@ define(["loading", "libraryMenu", "globalize", "cardStyle", "emby-button", "emby html += '
"; html += '
'; html += "
"; html += plugin.name; html += "
"; - var installedPlugin = plugin.isApp ? null : installedPlugins.filter(function (ip) { + var installedPlugin = installedPlugins.filter(function (ip) { return ip.Id == plugin.guid; })[0]; html += "
"; diff --git a/src/controllers/dashboard/plugins/installed.js b/src/controllers/dashboard/plugins/installed.js index c381b2409e..68a163c38c 100644 --- a/src/controllers/dashboard/plugins/installed.js +++ b/src/controllers/dashboard/plugins/installed.js @@ -42,14 +42,7 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" html += '"; html += '
'; @@ -57,7 +50,7 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" html += ''; html += "
"; html += "
"; - html += configPage ? configPage.DisplayName || plugin.Name : plugin.Name; + html += configPage.DisplayName || plugin.Name; html += "
"; html += "
"; html += plugin.Version; diff --git a/src/controllers/serveractivity.js b/src/controllers/dashboard/serveractivity.js similarity index 100% rename from src/controllers/serveractivity.js rename to src/controllers/dashboard/serveractivity.js diff --git a/src/controllers/streamingsettings.js b/src/controllers/dashboard/streamingsettings.js similarity index 82% rename from src/controllers/streamingsettings.js rename to src/controllers/dashboard/streamingsettings.js index 14e5e028a8..dcd0dcba16 100644 --- a/src/controllers/streamingsettings.js +++ b/src/controllers/dashboard/streamingsettings.js @@ -1,4 +1,4 @@ -define(["jQuery", "libraryMenu", "loading"], function ($, libraryMenu, loading) { +define(["jQuery", "libraryMenu", "loading", "globalize"], function ($, libraryMenu, loading, globalize) { "use strict"; function loadPage(page, config) { @@ -20,13 +20,13 @@ define(["jQuery", "libraryMenu", "loading"], function ($, libraryMenu, loading) function getTabs() { return [{ href: "encodingsettings.html", - name: Globalize.translate("Transcoding") + name: globalize.translate("Transcoding") }, { href: "playbackconfiguration.html", - name: Globalize.translate("TabResumeSettings") + name: globalize.translate("TabResumeSettings") }, { href: "streamingsettings.html", - name: Globalize.translate("TabStreaming") + name: globalize.translate("TabStreaming") }]; } diff --git a/src/controllers/itemdetailpage.js b/src/controllers/itemdetailpage.js index 178419e284..5c33210c35 100644 --- a/src/controllers/itemdetailpage.js +++ b/src/controllers/itemdetailpage.js @@ -336,7 +336,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti return html = html.join(" / "); } - function renderName(item, container, isStatic, context) { var parentRoute; var parentNameHtml = []; @@ -401,14 +400,25 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti } else if (item.Album) { parentNameHtml.push(item.Album); } - + // FIXME: This whole section needs some refactoring, so it becames easier to scale across all form factors. See GH #1022 var html = ""; + var tvShowHtml = parentNameHtml[0]; + var tvSeasonHtml = parentNameHtml[1]; if (parentNameHtml.length) { if (parentNameLast) { - html = '

' + parentNameHtml.join(" - ") + "

"; + // Music + if (layoutManager.mobile) { + html = '

' + parentNameHtml.join("
") + "

"; + } else { + html = '

' + parentNameHtml.join(" - ") + "

"; + } } else { - html = '

' + parentNameHtml.join(" - ") + "

"; + if (layoutManager.mobile) { + html = '

' + parentNameHtml.join("
") + "

"; + } else { + html = '

' + tvShowHtml + "

"; + } } } @@ -418,13 +428,17 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti var offset = parentNameLast ? ".25em" : ".5em"; if (html && !parentNameLast) { - html += '

' + name + '

'; + if (!layoutManager.mobile && tvSeasonHtml) { + html += '

' + tvSeasonHtml + ' - ' + name + '

'; + } else { + html += '

' + name + '

'; + } } else { html = '

' + name + "

" + html; } if (item.OriginalTitle && item.OriginalTitle != item.Name) { - html += '

' + item.OriginalTitle + '

'; + html += '

' + item.OriginalTitle + '

'; } container.innerHTML = html; @@ -540,7 +554,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti renderTimerEditor(page, item, apiClient, user); renderImage(page, item, apiClient, user); renderLogo(page, item, apiClient); - setTitle(item, apiClient); + Emby.Page.setTitle(''); setInitialCollapsibleState(page, item, apiClient, context, user); renderDetails(page, item, apiClient, context); renderTrackSelections(page, instance, item); @@ -652,19 +666,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti return null; } - function setTitle(item, apiClient) { - var url = logoImageUrl(item, apiClient, {}); - - if (url != null) { - var pageTitle = document.querySelector(".pageTitle"); - pageTitle.style.backgroundImage = "url('" + url + "')"; - pageTitle.classList.add("pageTitleWithLogo"); - pageTitle.innerHTML = ""; - } else { - Emby.Page.setTitle(""); - } - } - function renderLogo(page, item, apiClient) { var url = logoImageUrl(item, apiClient, { maxWidth: 400 @@ -2102,7 +2103,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti if (e.detail.isRestored) { if (currentItem) { - setTitle(currentItem, connectionManager.getApiClient(currentItem.ServerId)); + Emby.Page.setTitle(''); renderTrackSelections(page, self, currentItem, true); } } else { diff --git a/src/controllers/livetvguideprovider.js b/src/controllers/livetvguideprovider.js index a58917f22d..b58000adc5 100644 --- a/src/controllers/livetvguideprovider.js +++ b/src/controllers/livetvguideprovider.js @@ -1,4 +1,4 @@ -define(["events", "loading"], function (events, loading) { +define(["events", "loading", "globalize"], function (events, loading, globalize) { "use strict"; function onListingsSubmitted() { @@ -17,7 +17,7 @@ define(["events", "loading"], function (events, loading) { function loadTemplate(page, type, providerId) { require(["text!./components/tvproviders/" + type + ".template.html"], function (html) { - page.querySelector(".providerTemplate").innerHTML = Globalize.translateDocument(html); + page.querySelector(".providerTemplate").innerHTML = globalize.translateDocument(html); init(page, type, providerId); }); } diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 2b11071c75..e86f08ca6c 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "fnchecked", "emby-button"], function ($, loading) { +define(["jQuery", "loading", "globalize", "fnchecked", "emby-button"], function ($, loading, globalize) { "use strict"; function loadPage(page, config) { @@ -44,7 +44,7 @@ define(["jQuery", "loading", "fnchecked", "emby-button"], function ($, loading) var msg = ""; if (recordingPathChanged) { - msg += Globalize.translate("RecordingPathChangeMessage"); + msg += globalize.translate("RecordingPathChangeMessage"); } if (msg) { diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js index 84ceec6a10..4dfe23e7a6 100644 --- a/src/controllers/movies/moviecollections.js +++ b/src/controllers/movies/moviecollections.js @@ -1,4 +1,4 @@ -define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings) { +define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "userSettings", "globalize", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings, globalize) { "use strict"; return function (view, params, tabContent) { @@ -171,7 +171,7 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB } if (!result.Items.length) { - html = '

' + Globalize.translate("MessageNoCollectionsAvailable") + "

"; + html = '

' + globalize.translate("MessageNoCollectionsAvailable") + "

"; } var itemsContainer = tabContent.querySelector(".itemsContainer"); @@ -199,19 +199,19 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB tabContent.querySelector(".btnSort").addEventListener("click", function (e) { libraryBrowser.showSortMenu({ items: [{ - name: Globalize.translate("OptionNameSort"), + name: globalize.translate("OptionNameSort"), id: "SortName" }, { - name: Globalize.translate("OptionImdbRating"), + name: globalize.translate("OptionImdbRating"), id: "CommunityRating,SortName" }, { - name: Globalize.translate("OptionDateAdded"), + name: globalize.translate("OptionDateAdded"), id: "DateCreated,SortName" }, { - name: Globalize.translate("OptionParentalRating"), + name: globalize.translate("OptionParentalRating"), id: "OfficialRating,SortName" }, { - name: Globalize.translate("OptionReleaseDate"), + name: globalize.translate("OptionReleaseDate"), id: "PremiereDate,SortName" }], callback: function () { diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js index 38985fb4dd..9748da62dd 100644 --- a/src/controllers/movies/movies.js +++ b/src/controllers/movies/movies.js @@ -1,4 +1,4 @@ -define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", "alphaPicker", "listView", "cardBuilder", "emby-itemscontainer"], function (loading, layoutManager, userSettings, events, libraryBrowser, alphaPicker, listView, cardBuilder) { +define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", "alphaPicker", "listView", "cardBuilder", "globalize", "emby-itemscontainer"], function (loading, layoutManager, userSettings, events, libraryBrowser, alphaPicker, listView, cardBuilder, globalize) { "use strict"; return function (view, params, tabContent, options) { @@ -191,31 +191,31 @@ define(["loading", "layoutManager", "userSettings", "events", "libraryBrowser", btnSort.addEventListener("click", function (e) { libraryBrowser.showSortMenu({ items: [{ - name: Globalize.translate("OptionNameSort"), + name: globalize.translate("OptionNameSort"), id: "SortName,ProductionYear" }, { - name: Globalize.translate("OptionImdbRating"), + name: globalize.translate("OptionImdbRating"), id: "CommunityRating,SortName,ProductionYear" }, { - name: Globalize.translate("OptionCriticRating"), + name: globalize.translate("OptionCriticRating"), id: "CriticRating,SortName,ProductionYear" }, { - name: Globalize.translate("OptionDateAdded"), + name: globalize.translate("OptionDateAdded"), id: "DateCreated,SortName,ProductionYear" }, { - name: Globalize.translate("OptionDatePlayed"), + name: globalize.translate("OptionDatePlayed"), id: "DatePlayed,SortName,ProductionYear" }, { - name: Globalize.translate("OptionParentalRating"), + name: globalize.translate("OptionParentalRating"), id: "OfficialRating,SortName,ProductionYear" }, { - name: Globalize.translate("OptionPlayCount"), + name: globalize.translate("OptionPlayCount"), id: "PlayCount,SortName,ProductionYear" }, { - name: Globalize.translate("OptionReleaseDate"), + name: globalize.translate("OptionReleaseDate"), id: "PremiereDate,SortName,ProductionYear" }, { - name: Globalize.translate("OptionRuntime"), + name: globalize.translate("OptionRuntime"), id: "Runtime,SortName,ProductionYear" }], callback: function () { diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index 98e0871479..5f341d3e3a 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -1,4 +1,4 @@ -define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "cardBuilder", "dom", "imageLoader", "playbackManager", "emby-scroller", "emby-itemscontainer", "emby-tabs", "emby-button"], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager) { +define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "cardBuilder", "dom", "imageLoader", "playbackManager", "globalize", "emby-scroller", "emby-itemscontainer", "emby-tabs", "emby-button"], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager, globalize) { "use strict"; function enableScrollX() { @@ -91,21 +91,21 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu" switch (recommendation.RecommendationType) { case "SimilarToRecentlyPlayed": - title = Globalize.translate("RecommendationBecauseYouWatched", recommendation.BaselineItemName); + title = globalize.translate("RecommendationBecauseYouWatched", recommendation.BaselineItemName); break; case "SimilarToLikedItem": - title = Globalize.translate("RecommendationBecauseYouLike", recommendation.BaselineItemName); + title = globalize.translate("RecommendationBecauseYouLike", recommendation.BaselineItemName); break; case "HasDirectorFromRecentlyPlayed": case "HasLikedDirector": - title = Globalize.translate("RecommendationDirectedBy", recommendation.BaselineItemName); + title = globalize.translate("RecommendationDirectedBy", recommendation.BaselineItemName); break; case "HasActorFromRecentlyPlayed": case "HasLikedActor": - title = Globalize.translate("RecommendationStarring", recommendation.BaselineItemName); + title = globalize.translate("RecommendationStarring", recommendation.BaselineItemName); break; } @@ -211,19 +211,19 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu" function getTabs() { return [{ - name: Globalize.translate("Movies") + name: globalize.translate("Movies") }, { - name: Globalize.translate("TabSuggestions") + name: globalize.translate("TabSuggestions") }, { - name: Globalize.translate("TabTrailers") + name: globalize.translate("TabTrailers") }, { - name: Globalize.translate("TabFavorites") + name: globalize.translate("TabFavorites") }, { - name: Globalize.translate("TabCollections") + name: globalize.translate("TabCollections") }, { - name: Globalize.translate("TabGenres") + name: globalize.translate("TabGenres") }, { - name: Globalize.translate("ButtonSearch"), + name: globalize.translate("ButtonSearch"), cssClass: "searchTabButton" }]; } @@ -398,8 +398,8 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu" libraryMenu.setTitle(item.Name); }); } else { - view.setAttribute("data-title", Globalize.translate("TabMovies")); - libraryMenu.setTitle(Globalize.translate("TabMovies")); + view.setAttribute("data-title", globalize.translate("TabMovies")); + libraryMenu.setTitle(globalize.translate("TabMovies")); } } diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js index e839d29b1f..590b204b22 100644 --- a/src/controllers/movies/movietrailers.js +++ b/src/controllers/movies/movietrailers.js @@ -1,4 +1,4 @@ -define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings) { +define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "userSettings", "globalize", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings, globalize) { "use strict"; return function (view, params, tabContent) { @@ -158,7 +158,7 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", " } if (!result.Items.length) { - html = '

' + Globalize.translate("MessageNoTrailersFound") + "

"; + html = '

' + globalize.translate("MessageNoTrailersFound") + "

"; } var itemsContainer = tabContent.querySelector(".itemsContainer"); @@ -223,25 +223,25 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", " tabContent.querySelector(".btnSort").addEventListener("click", function (e) { libraryBrowser.showSortMenu({ items: [{ - name: Globalize.translate("OptionNameSort"), + name: globalize.translate("OptionNameSort"), id: "SortName" }, { - name: Globalize.translate("OptionImdbRating"), + name: globalize.translate("OptionImdbRating"), id: "CommunityRating,SortName" }, { - name: Globalize.translate("OptionDateAdded"), + name: globalize.translate("OptionDateAdded"), id: "DateCreated,SortName" }, { - name: Globalize.translate("OptionDatePlayed"), + name: globalize.translate("OptionDatePlayed"), id: "DatePlayed,SortName" }, { - name: Globalize.translate("OptionParentalRating"), + name: globalize.translate("OptionParentalRating"), id: "OfficialRating,SortName" }, { - name: Globalize.translate("OptionPlayCount"), + name: globalize.translate("OptionPlayCount"), id: "PlayCount,SortName" }, { - name: Globalize.translate("OptionReleaseDate"), + name: globalize.translate("OptionReleaseDate"), id: "PremiereDate,SortName" }], callback: function () { diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js index a3c362d359..580f30bce9 100644 --- a/src/controllers/music/musicalbums.js +++ b/src/controllers/music/musicalbums.js @@ -1,4 +1,4 @@ -define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings) { +define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser", "imageLoader", "alphaPicker", "listView", "cardBuilder", "userSettings", "globalize", "emby-itemscontainer"], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings, globalize) { "use strict"; return function (view, params, tabContent) { @@ -230,25 +230,25 @@ define(["layoutManager", "playbackManager", "loading", "events", "libraryBrowser tabContent.querySelector(".btnSort").addEventListener("click", function (e) { libraryBrowser.showSortMenu({ items: [{ - name: Globalize.translate("OptionNameSort"), + name: globalize.translate("OptionNameSort"), id: "SortName" }, { - name: Globalize.translate("OptionAlbumArtist"), + name: globalize.translate("OptionAlbumArtist"), id: "AlbumArtist,SortName" }, { - name: Globalize.translate("OptionCommunityRating"), + name: globalize.translate("OptionCommunityRating"), id: "CommunityRating,SortName" }, { - name: Globalize.translate("OptionCriticRating"), + name: globalize.translate("OptionCriticRating"), id: "CriticRating,SortName" }, { - name: Globalize.translate("OptionDateAdded"), + name: globalize.translate("OptionDateAdded"), id: "DateCreated,SortName" }, { - name: Globalize.translate("OptionReleaseDate"), + name: globalize.translate("OptionReleaseDate"), id: "ProductionYear,PremiereDate,SortName" }, { - name: Globalize.translate("OptionRandom"), + name: globalize.translate("OptionRandom"), id: "Random,SortName" }], callback: function () { diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 8b87dff265..14a231a344 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -1,4 +1,4 @@ -define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "cardBuilder", "dom", "apphost", "imageLoader", "libraryMenu", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-tabs", "emby-button", "flexStyles"], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager) { +define(["browser", "layoutManager", "userSettings", "inputManager", "loading", "cardBuilder", "dom", "apphost", "imageLoader", "libraryMenu", "playbackManager", "mainTabsManager", "globalize", "scrollStyles", "emby-itemscontainer", "emby-tabs", "emby-button", "flexStyles"], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager, globalize) { "use strict"; function itemsPerRow() { @@ -167,21 +167,21 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", " function getTabs() { return [{ - name: Globalize.translate("TabSuggestions") + name: globalize.translate("TabSuggestions") }, { - name: Globalize.translate("TabAlbums") + name: globalize.translate("TabAlbums") }, { - name: Globalize.translate("TabAlbumArtists") + name: globalize.translate("TabAlbumArtists") }, { - name: Globalize.translate("TabArtists") + name: globalize.translate("TabArtists") }, { - name: Globalize.translate("TabPlaylists") + name: globalize.translate("TabPlaylists") }, { - name: Globalize.translate("TabSongs") + name: globalize.translate("TabSongs") }, { - name: Globalize.translate("TabGenres") + name: globalize.translate("TabGenres") }, { - name: Globalize.translate("ButtonSearch"), + name: globalize.translate("ButtonSearch"), cssClass: "searchTabButton" }]; } @@ -388,8 +388,8 @@ define(["browser", "layoutManager", "userSettings", "inputManager", "loading", " libraryMenu.setTitle(item.Name); }); } else { - view.setAttribute("data-title", Globalize.translate("TabMusic")); - libraryMenu.setTitle(Globalize.translate("TabMusic")); + view.setAttribute("data-title", globalize.translate("TabMusic")); + libraryMenu.setTitle(globalize.translate("TabMusic")); } } diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js index aaa71395e4..29d21b0774 100644 --- a/src/controllers/music/songs.js +++ b/src/controllers/music/songs.js @@ -1,4 +1,4 @@ -define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "userSettings", "emby-itemscontainer"], function (events, libraryBrowser, imageLoader, listView, loading, userSettings) { +define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "userSettings", "globalize", "emby-itemscontainer"], function (events, libraryBrowser, imageLoader, listView, loading, userSettings, globalize) { "use strict"; return function (view, params, tabContent) { @@ -149,31 +149,31 @@ define(["events", "libraryBrowser", "imageLoader", "listView", "loading", "userS tabContent.querySelector(".btnSort").addEventListener("click", function (e) { libraryBrowser.showSortMenu({ items: [{ - name: Globalize.translate("OptionTrackName"), + name: globalize.translate("OptionTrackName"), id: "Name" }, { - name: Globalize.translate("OptionAlbum"), + name: globalize.translate("OptionAlbum"), id: "Album,SortName" }, { - name: Globalize.translate("OptionAlbumArtist"), + name: globalize.translate("OptionAlbumArtist"), id: "AlbumArtist,Album,SortName" }, { - name: Globalize.translate("OptionArtist"), + name: globalize.translate("OptionArtist"), id: "Artist,Album,SortName" }, { - name: Globalize.translate("OptionDateAdded"), + name: globalize.translate("OptionDateAdded"), id: "DateCreated,SortName" }, { - name: Globalize.translate("OptionDatePlayed"), + name: globalize.translate("OptionDatePlayed"), id: "DatePlayed,SortName" }, { - name: Globalize.translate("OptionPlayCount"), + name: globalize.translate("OptionPlayCount"), id: "PlayCount,SortName" }, { - name: Globalize.translate("OptionReleaseDate"), + name: globalize.translate("OptionReleaseDate"), id: "PremiereDate,AlbumArtist,Album,SortName" }, { - name: Globalize.translate("OptionRuntime"), + name: globalize.translate("OptionRuntime"), id: "Runtime,AlbumArtist,Album,SortName" }], callback: function () { diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index f71eb0e095..390c3a616d 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -45,23 +45,6 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med return null; } - function logoImageUrl(item, apiClient, options) { - options = options || {}; - options.type = "Logo"; - - if (item.ImageTags && item.ImageTags.Logo) { - options.tag = item.ImageTags.Logo; - return apiClient.getScaledImageUrl(item.Id, options); - } - - if (item.ParentLogoImageTag) { - options.tag = item.ParentLogoImageTag; - return apiClient.getScaledImageUrl(item.ParentLogoItemId, options); - } - - return null; - } - return function (view, params) { function onVerticalSwipe(e, elem, data) { var player = currentPlayer; @@ -309,18 +292,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med } function setTitle(item, parentName) { - var url = logoImageUrl(item, connectionManager.getApiClient(item.ServerId), {}); - - if (url) { - Emby.Page.setTitle(""); - var pageTitle = document.querySelector(".pageTitle"); - pageTitle.style.backgroundImage = "url('" + url + "')"; - pageTitle.classList.add("pageTitleWithLogo"); - pageTitle.classList.remove("pageTitleWithDefaultLogo"); - pageTitle.innerHTML = ""; - } else { - Emby.Page.setTitle(parentName || ""); - } + Emby.Page.setTitle(parentName || ''); var documentTitle = parentName || (item ? item.Name : null); @@ -1272,7 +1244,6 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med var programEndDateMs = 0; var playbackStartTimeTicks = 0; var subtitleSyncOverlay; - var volumeSliderTimer; var nowPlayingVolumeSlider = view.querySelector(".osdVolumeSlider"); var nowPlayingVolumeSliderContainer = view.querySelector(".osdVolumeSliderContainer"); var nowPlayingPositionSlider = view.querySelector(".osdPositionSlider"); @@ -1423,27 +1394,15 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med } function setVolume() { - clearTimeout(volumeSliderTimer); - volumeSliderTimer = null; - playbackManager.setVolume(this.value, currentPlayer); } - function setVolumeDelayed() { - if (!volumeSliderTimer) { - var that = this; - volumeSliderTimer = setTimeout(function () { - setVolume.call(that); - }, 700); - } - } - view.querySelector(".buttonMute").addEventListener("click", function () { playbackManager.toggleMute(currentPlayer); }); nowPlayingVolumeSlider.addEventListener("change", setVolume); - nowPlayingVolumeSlider.addEventListener("mousemove", setVolumeDelayed); - nowPlayingVolumeSlider.addEventListener("touchmove", setVolumeDelayed); + nowPlayingVolumeSlider.addEventListener("mousemove", setVolume); + nowPlayingVolumeSlider.addEventListener("touchmove", setVolume); nowPlayingPositionSlider.addEventListener("change", function () { var player = currentPlayer; diff --git a/src/controllers/shows/episodes.js b/src/controllers/shows/episodes.js index 792eab88a1..bd7823d401 100644 --- a/src/controllers/shows/episodes.js +++ b/src/controllers/shows/episodes.js @@ -1,4 +1,4 @@ -define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "userSettings", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings) { +define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "userSettings", "globalize", "emby-itemscontainer"], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings, globalize) { "use strict"; return function (view, params, tabContent) { @@ -188,28 +188,28 @@ define(["loading", "events", "libraryBrowser", "imageLoader", "listView", "cardB tabContent.querySelector(".btnSort").addEventListener("click", function (e) { libraryBrowser.showSortMenu({ items: [{ - name: Globalize.translate("OptionNameSort"), + name: globalize.translate("OptionNameSort"), id: "SeriesSortName,SortName" }, { - name: Globalize.translate("OptionTvdbRating"), + name: globalize.translate("OptionTvdbRating"), id: "CommunityRating,SeriesSortName,SortName" }, { - name: Globalize.translate("OptionDateAdded"), + name: globalize.translate("OptionDateAdded"), id: "DateCreated,SeriesSortName,SortName" }, { - name: Globalize.translate("OptionPremiereDate"), + name: globalize.translate("OptionPremiereDate"), id: "PremiereDate,SeriesSortName,SortName" }, { - name: Globalize.translate("OptionDatePlayed"), + name: globalize.translate("OptionDatePlayed"), id: "DatePlayed,SeriesSortName,SortName" }, { - name: Globalize.translate("OptionParentalRating"), + name: globalize.translate("OptionParentalRating"), id: "OfficialRating,SeriesSortName,SortName" }, { - name: Globalize.translate("OptionPlayCount"), + name: globalize.translate("OptionPlayCount"), id: "PlayCount,SeriesSortName,SortName" }, { - name: Globalize.translate("OptionRuntime"), + name: globalize.translate("OptionRuntime"), id: "Runtime,SeriesSortName,SortName" }], callback: function () { diff --git a/src/controllers/shows/tvgenres.js b/src/controllers/shows/tvgenres.js index 9a0823a6b9..80e2f646b6 100644 --- a/src/controllers/shows/tvgenres.js +++ b/src/controllers/shows/tvgenres.js @@ -113,6 +113,9 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader itemsContainer: elem, shape: getPortraitShape(), scalable: true, + showTitle: true, + centerText: true, + showYear: true, overlayMoreButton: true, allowBottomPadding: false }); diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js index d1adb04342..4427d3fa72 100644 --- a/src/controllers/shows/tvrecommended.js +++ b/src/controllers/shows/tvrecommended.js @@ -1,23 +1,23 @@ -define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-button"], function (events, inputManager, libraryMenu, layoutManager, loading, dom, userSettings, cardBuilder, playbackManager, mainTabsManager) { +define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "globalize", "scrollStyles", "emby-itemscontainer", "emby-button"], function (events, inputManager, libraryMenu, layoutManager, loading, dom, userSettings, cardBuilder, playbackManager, mainTabsManager, globalize) { "use strict"; function getTabs() { return [{ - name: Globalize.translate("TabShows") + name: globalize.translate("TabShows") }, { - name: Globalize.translate("TabSuggestions") + name: globalize.translate("TabSuggestions") }, { - name: Globalize.translate("TabLatest") + name: globalize.translate("TabLatest") }, { - name: Globalize.translate("TabUpcoming") + name: globalize.translate("TabUpcoming") }, { - name: Globalize.translate("TabGenres") + name: globalize.translate("TabGenres") }, { - name: Globalize.translate("TabNetworks") + name: globalize.translate("TabNetworks") }, { - name: Globalize.translate("TabEpisodes") + name: globalize.translate("TabEpisodes") }, { - name: Globalize.translate("ButtonSearch"), + name: globalize.translate("ButtonSearch"), cssClass: "searchTabButton" }]; } @@ -314,8 +314,8 @@ define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "do libraryMenu.setTitle(item.Name); }); } else { - view.setAttribute("data-title", Globalize.translate("TabShows")); - libraryMenu.setTitle(Globalize.translate("TabShows")); + view.setAttribute("data-title", globalize.translate("TabShows")); + libraryMenu.setTitle(globalize.translate("TabShows")); } } diff --git a/src/controllers/shows/tvshows.js b/src/controllers/shows/tvshows.js index 95d027d770..0f992fe8d6 100644 --- a/src/controllers/shows/tvshows.js +++ b/src/controllers/shows/tvshows.js @@ -1,4 +1,4 @@ -define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "userSettings", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker, userSettings) { +define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", "listView", "cardBuilder", "alphaPicker", "userSettings", "globalize", "emby-itemscontainer"], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker, userSettings, globalize) { "use strict"; return function (view, params, tabContent) { @@ -241,22 +241,22 @@ define(["layoutManager", "loading", "events", "libraryBrowser", "imageLoader", " tabContent.querySelector(".btnSort").addEventListener("click", function (e) { libraryBrowser.showSortMenu({ items: [{ - name: Globalize.translate("OptionNameSort"), + name: globalize.translate("OptionNameSort"), id: "SortName" }, { - name: Globalize.translate("OptionImdbRating"), + name: globalize.translate("OptionImdbRating"), id: "CommunityRating,SortName" }, { - name: Globalize.translate("OptionDateAdded"), + name: globalize.translate("OptionDateAdded"), id: "DateCreated,SortName" }, { - name: Globalize.translate("OptionDatePlayed"), + name: globalize.translate("OptionDatePlayed"), id: "DatePlayed,SortName" }, { - name: Globalize.translate("OptionParentalRating"), + name: globalize.translate("OptionParentalRating"), id: "OfficialRating,SortName" }, { - name: Globalize.translate("OptionReleaseDate"), + name: globalize.translate("OptionReleaseDate"), id: "PremiereDate,SortName" }], callback: function () { diff --git a/src/controllers/shows/tvupcoming.js b/src/controllers/shows/tvupcoming.js index 249d932d39..816717edf8 100644 --- a/src/controllers/shows/tvupcoming.js +++ b/src/controllers/shows/tvupcoming.js @@ -1,4 +1,4 @@ -define(["layoutManager", "loading", "datetime", "libraryBrowser", "cardBuilder", "apphost", "imageLoader", "scrollStyles", "emby-itemscontainer"], function (layoutManager, loading, datetime, libraryBrowser, cardBuilder, appHost, imageLoader) { +define(["layoutManager", "loading", "datetime", "libraryBrowser", "cardBuilder", "apphost", "imageLoader", "globalize", "scrollStyles", "emby-itemscontainer"], function (layoutManager, loading, datetime, libraryBrowser, cardBuilder, appHost, imageLoader, globalize) { "use strict"; function getUpcomingPromise(context, params) { @@ -52,7 +52,7 @@ define(["layoutManager", "loading", "datetime", "libraryBrowser", "cardBuilder", if (item.PremiereDate) { try { var premiereDate = datetime.parseISO8601Date(item.PremiereDate, true); - dateText = datetime.isRelativeDay(premiereDate, -1) ? Globalize.translate("Yesterday") : datetime.toLocaleDateString(premiereDate, { + dateText = datetime.isRelativeDay(premiereDate, -1) ? globalize.translate("Yesterday") : datetime.toLocaleDateString(premiereDate, { weekday: "long", month: "short", day: "numeric" diff --git a/src/controllers/user/profile.js b/src/controllers/user/profile.js index 3b85cb1d8c..d0ff4edd00 100644 --- a/src/controllers/user/profile.js +++ b/src/controllers/user/profile.js @@ -1,4 +1,4 @@ -define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "emby-button"], function (UserPasswordPage, loading, libraryMenu, appHost) { +define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "globalize", "emby-button"], function (UserPasswordPage, loading, libraryMenu, appHost, globalize) { "use strict"; function reloadUser(page) { @@ -37,7 +37,7 @@ define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "em switch (evt.target.error.code) { case evt.target.error.NOT_FOUND_ERR: require(["toast"], function (toast) { - toast(Globalize.translate("FileNotFound")); + toast(globalize.translate("FileNotFound")); }); break; case evt.target.error.ABORT_ERR: @@ -46,7 +46,7 @@ define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "em case evt.target.error.NOT_READABLE_ERR: default: require(["toast"], function (toast) { - toast(Globalize.translate("FileReadError")); + toast(globalize.translate("FileReadError")); }); } } @@ -54,7 +54,7 @@ define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "em function onFileReaderAbort(evt) { loading.hide(); require(["toast"], function (toast) { - toast(Globalize.translate("FileReadCancelled")); + toast(globalize.translate("FileReadCancelled")); }); } @@ -86,7 +86,7 @@ define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "em new UserPasswordPage(view, params); view.querySelector("#btnDeleteImage").addEventListener("click", function () { require(["confirm"], function (confirm) { - confirm(Globalize.translate("DeleteImageConfirmation"), Globalize.translate("DeleteImage")).then(function () { + confirm(globalize.translate("DeleteImageConfirmation"), globalize.translate("DeleteImage")).then(function () { loading.show(); var userId = getParameterByName("userId"); ApiClient.deleteUserImage(userId, "primary").then(function () { diff --git a/src/controllers/useredit.js b/src/controllers/useredit.js index f6a5aaf000..45a8798e4f 100644 --- a/src/controllers/useredit.js +++ b/src/controllers/useredit.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "globalize", "fnchecked"], function ($, loading, libraryMenu, globalize) { "use strict"; function loadDeleteFolders(page, user, mediaFolders) { @@ -112,7 +112,7 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, loading.hide(); require(["toast"], function (toast) { - toast(Globalize.translate("SettingsSaved")); + toast(globalize.translate("SettingsSaved")); }); } @@ -176,7 +176,7 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, var currentUser; $(document).on("pageinit", "#editUserPage", function () { $(".editUserProfileForm").off("submit", onSubmit).on("submit", onSubmit); - this.querySelector(".sharingHelp").innerHTML = Globalize.translate("OptionAllowLinkSharingHelp", 30); + this.querySelector(".sharingHelp").innerHTML = globalize.translate("OptionAllowLinkSharingHelp", 30); var page = this; $("#chkEnableDeleteAllFolders", this).on("change", function () { if (this.checked) { diff --git a/src/controllers/userlibraryaccess.js b/src/controllers/userlibraryaccess.js index 38418f5190..0965e9189b 100644 --- a/src/controllers/userlibraryaccess.js +++ b/src/controllers/userlibraryaccess.js @@ -1,4 +1,4 @@ -define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, libraryMenu) { +define(["jQuery", "loading", "libraryMenu", "globalize", "fnchecked"], function ($, loading, libraryMenu, globalize) { "use strict"; function triggerChange(select) { @@ -9,7 +9,7 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, function loadMediaFolders(page, user, mediaFolders) { var html = ""; - html += '

' + Globalize.translate("HeaderLibraries") + "

"; + html += '

' + globalize.translate("HeaderLibraries") + "

"; html += '
'; for (var i = 0, length = mediaFolders.length; i < length; i++) { @@ -28,7 +28,7 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, function loadChannels(page, user, channels) { var html = ""; - html += '

' + Globalize.translate("HeaderChannels") + "

"; + html += '

' + globalize.translate("HeaderChannels") + "

"; html += '
'; for (var i = 0, length = channels.length; i < length; i++) { @@ -52,7 +52,7 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, function loadDevices(page, user, devices) { var html = ""; - html += '

' + Globalize.translate("HeaderDevices") + "

"; + html += '

' + globalize.translate("HeaderDevices") + "

"; html += '
'; for (var i = 0, length = devices.length; i < length; i++) { @@ -85,7 +85,7 @@ define(["jQuery", "loading", "libraryMenu", "fnchecked"], function ($, loading, loading.hide(); require(["toast"], function (toast) { - toast(Globalize.translate("SettingsSaved")); + toast(globalize.translate("SettingsSaved")); }); } diff --git a/src/controllers/usernew.js b/src/controllers/usernew.js index ec80679f8c..b93d1d6626 100644 --- a/src/controllers/usernew.js +++ b/src/controllers/usernew.js @@ -1,9 +1,9 @@ -define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function ($, loading) { +define(["jQuery", "loading", "globalize", "fnchecked", "emby-checkbox"], function ($, loading, globalize) { "use strict"; function loadMediaFolders(page, mediaFolders) { var html = ""; - html += '

' + Globalize.translate("HeaderLibraries") + "

"; + html += '

' + globalize.translate("HeaderLibraries") + "

"; html += '
'; for (var i = 0; i < mediaFolders.length; i++) { @@ -18,7 +18,7 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function ($, loading function loadChannels(page, channels) { var html = ""; - html += '

' + Globalize.translate("HeaderChannels") + "

"; + html += '

' + globalize.translate("HeaderChannels") + "

"; html += '
'; for (var i = 0; i < channels.length; i++) { @@ -85,7 +85,7 @@ define(["jQuery", "loading", "fnchecked", "emby-checkbox"], function ($, loading }); }, function (response) { require(["toast"], function (toast) { - toast(Globalize.translate("DefaultErrorMessage")); + toast(globalize.translate("DefaultErrorMessage")); }); loading.hide(); diff --git a/src/controllers/userparentalcontrol.js b/src/controllers/userparentalcontrol.js index 333c09f266..54f5a8a949 100644 --- a/src/controllers/userparentalcontrol.js +++ b/src/controllers/userparentalcontrol.js @@ -1,4 +1,4 @@ -define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper-icon-button-light"], function ($, datetime, loading, libraryMenu) { +define(["jQuery", "datetime", "loading", "libraryMenu", "globalize", "listViewStyle", "paper-icon-button-light"], function ($, datetime, loading, libraryMenu, globalize) { "use strict"; function populateRatings(allParentalRatings, page) { @@ -35,29 +35,29 @@ define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper- function loadUnratedItems(page, user) { var items = [{ - name: Globalize.translate("OptionBlockBooks"), + name: globalize.translate("OptionBlockBooks"), value: "Book" }, { - name: Globalize.translate("OptionBlockChannelContent"), + name: globalize.translate("OptionBlockChannelContent"), value: "ChannelContent" }, { - name: Globalize.translate("OptionBlockLiveTvChannels"), + name: globalize.translate("OptionBlockLiveTvChannels"), value: "LiveTvChannel" }, { - name: Globalize.translate("OptionBlockMovies"), + name: globalize.translate("OptionBlockMovies"), value: "Movie" }, { - name: Globalize.translate("OptionBlockMusic"), + name: globalize.translate("OptionBlockMusic"), value: "Music" }, { - name: Globalize.translate("OptionBlockTrailers"), + name: globalize.translate("OptionBlockTrailers"), value: "Trailer" }, { - name: Globalize.translate("OptionBlockTvShows"), + name: globalize.translate("OptionBlockTvShows"), value: "Series" }]; var html = ""; - html += '

' + Globalize.translate("HeaderBlockItemsWithNoRating") + "

"; + html += '

' + globalize.translate("HeaderBlockItemsWithNoRating") + "

"; html += '
'; for (var i = 0, length = items.length; i < length; i++) { @@ -139,7 +139,7 @@ define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper- itemHtml += '
'; itemHtml += '
'; itemHtml += '

'; - itemHtml += Globalize.translate("Option" + a.DayOfWeek); + itemHtml += globalize.translate("Option" + a.DayOfWeek); itemHtml += "

"; itemHtml += '
' + getDisplayTime(a.StartHour) + " - " + getDisplayTime(a.EndHour) + "
"; itemHtml += "
"; @@ -159,7 +159,7 @@ define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper- loading.hide(); require(["toast"], function (toast) { - toast(Globalize.translate("SettingsSaved")); + toast(globalize.translate("SettingsSaved")); }); } @@ -226,7 +226,7 @@ define(["jQuery", "datetime", "loading", "libraryMenu", "listViewStyle", "paper- function showBlockedTagPopup(page) { require(["prompt"], function (prompt) { prompt({ - label: Globalize.translate("LabelTag") + label: globalize.translate("LabelTag") }).then(function (value) { var tags = getBlockedTagsFromPage(page); diff --git a/src/controllers/userpasswordpage.js b/src/controllers/userpasswordpage.js index eeb9b25e3e..8ceb46c5e2 100644 --- a/src/controllers/userpasswordpage.js +++ b/src/controllers/userpasswordpage.js @@ -1,4 +1,4 @@ -define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu) { +define(["loading", "libraryMenu", "globalize", "emby-button"], function (loading, libraryMenu, globalize) { "use strict"; function loadUser(page, params) { @@ -79,7 +79,7 @@ define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu loading.hide(); require(["toast"], function (toast) { - toast(Globalize.translate("MessageSettingsSaved")); + toast(globalize.translate("MessageSettingsSaved")); }); loadUser(view, params); @@ -102,15 +102,15 @@ define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu loading.hide(); require(["toast"], function (toast) { - toast(Globalize.translate("PasswordSaved")); + toast(globalize.translate("PasswordSaved")); }); loadUser(view, params); }, function () { loading.hide(); Dashboard.alert({ - title: Globalize.translate("HeaderLoginFailure"), - message: Globalize.translate("MessageInvalidUser") + title: globalize.translate("HeaderLoginFailure"), + message: globalize.translate("MessageInvalidUser") }); }); } @@ -120,7 +120,7 @@ define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu if (form.querySelector("#txtNewPassword").value != form.querySelector("#txtNewPasswordConfirm").value) { require(["toast"], function (toast) { - toast(Globalize.translate("PasswordMatchError")); + toast(globalize.translate("PasswordMatchError")); }); } else { loading.show(); @@ -139,17 +139,17 @@ define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu } function resetPassword() { - var msg = Globalize.translate("PasswordResetConfirmation"); + var msg = globalize.translate("PasswordResetConfirmation"); require(["confirm"], function (confirm) { - confirm(msg, Globalize.translate("PasswordResetHeader")).then(function () { + confirm(msg, globalize.translate("PasswordResetHeader")).then(function () { var userId = params.userId; loading.show(); ApiClient.resetUserPassword(userId).then(function () { loading.hide(); Dashboard.alert({ - message: Globalize.translate("PasswordResetComplete"), - title: Globalize.translate("PasswordResetHeader") + message: globalize.translate("PasswordResetComplete"), + title: globalize.translate("PasswordResetHeader") }); loadUser(view, params); }); @@ -158,17 +158,17 @@ define(["loading", "libraryMenu", "emby-button"], function (loading, libraryMenu } function resetEasyPassword() { - var msg = Globalize.translate("PinCodeResetConfirmation"); + var msg = globalize.translate("PinCodeResetConfirmation"); require(["confirm"], function (confirm) { - confirm(msg, Globalize.translate("HeaderPinCodeReset")).then(function () { + confirm(msg, globalize.translate("HeaderPinCodeReset")).then(function () { var userId = params.userId; loading.show(); ApiClient.resetEasyPassword(userId).then(function () { loading.hide(); Dashboard.alert({ - message: Globalize.translate("PinCodeResetComplete"), - title: Globalize.translate("HeaderPinCodeReset") + message: globalize.translate("PinCodeResetComplete"), + title: globalize.translate("HeaderPinCodeReset") }); loadUser(view, params); }); diff --git a/src/controllers/wizard/user.js b/src/controllers/wizard/user.js index 270953b24e..32f2bf933f 100644 --- a/src/controllers/wizard/user.js +++ b/src/controllers/wizard/user.js @@ -33,7 +33,7 @@ define(["loading", "globalize", "dashboardcss", "emby-input", "emby-button", "em if (form.querySelector("#txtManualPassword").value != form.querySelector("#txtPasswordConfirm").value) { require(["toast"], function (toast) { - toast(Globalize.translate("PasswordMatchError")); + toast(globalize.translate("PasswordMatchError")); }); } else { submit(form); diff --git a/src/elements/emby-button/emby-button.css b/src/elements/emby-button/emby-button.css index a19ce571e2..b3ee4db157 100644 --- a/src/elements/emby-button/emby-button.css +++ b/src/elements/emby-button/emby-button.css @@ -49,6 +49,7 @@ .button-link { background: transparent; + cursor: pointer; margin: 0; padding: 0; vertical-align: initial; diff --git a/src/elements/emby-scroller/emby-scroller.js b/src/elements/emby-scroller/emby-scroller.js index cb5bae818f..3df40fa6c2 100644 --- a/src/elements/emby-scroller/emby-scroller.js +++ b/src/elements/emby-scroller/emby-scroller.js @@ -96,17 +96,6 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro } } - function initHeadroom(elem) { - require(['headroom'], function (Headroom) { - var headroom = new Headroom([], { - scroller: elem - }); - - headroom.add(document.querySelector('.skinHeader')); - elem.headroom = headroom; - }); - } - ScrollerPrototype.attachedCallback = function () { if (this.getAttribute('data-navcommands')) { inputManager.on(this, onInputCommand); @@ -120,8 +109,6 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro slider.style['white-space'] = 'nowrap'; } - var bindHeader = this.getAttribute('data-bindheader') === 'true'; - var scrollFrame = this; var enableScrollButtons = layoutManager.desktop && horizontal && this.getAttribute('data-scrollbuttons') !== 'false'; @@ -137,7 +124,7 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro dragHandle: 1, autoImmediate: true, skipSlideToWhenVisible: this.getAttribute('data-skipfocuswhenvisible') === 'true', - dispatchScrollEvent: enableScrollButtons || bindHeader || this.getAttribute('data-scrollevent') === 'true', + dispatchScrollEvent: enableScrollButtons || this.getAttribute('data-scrollevent') === 'true', hideScrollbar: enableScrollButtons || this.getAttribute('data-hidescrollbar') === 'true', allowNativeSmoothScroll: this.getAttribute('data-allownativesmoothscroll') === 'true' && !enableScrollButtons, allowNativeScroll: !enableScrollButtons, @@ -155,10 +142,6 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro initCenterFocus(this, this.scroller); } - if (bindHeader && layoutManager.mobile) { - initHeadroom(this); - } - if (enableScrollButtons) { loadScrollButtons(this); } diff --git a/src/index.html b/src/index.html index 624be19360..ed63ca1a98 100644 --- a/src/index.html +++ b/src/index.html @@ -92,7 +92,7 @@ left: 0; bottom: 0; z-index: 1; - width: 10px; + width: 0.8em; } diff --git a/src/itemdetails.html b/src/itemdetails.html index 605ff926e3..0520c80d11 100644 --- a/src/itemdetails.html +++ b/src/itemdetails.html @@ -136,7 +136,7 @@
-
+
diff --git a/src/components/polyfills/focusPreventScroll.js b/src/legacy/focusPreventScroll.js similarity index 100% rename from src/components/polyfills/focusPreventScroll.js rename to src/legacy/focusPreventScroll.js diff --git a/src/libraries/apiclient/apiclientcore.js b/src/libraries/apiclient/apiclientcore.js index 557a4e1033..2046cae69b 100644 --- a/src/libraries/apiclient/apiclientcore.js +++ b/src/libraries/apiclient/apiclientcore.js @@ -1,6 +1,12 @@ define(["events", "appStorage"], function(events, appStorage) { "use strict"; + /** Report rate limits in ms for different events */ + const reportRateLimits = { + "timeupdate": 10000, + "volumechange": 3000 + }; + function redetectBitrate(instance) { stopBitrateDetection(instance), instance.accessToken() && !1 !== instance.enableAutomaticBitrateDetection && setTimeout(redetectBitrateInternal.bind(instance), 6e3) } @@ -231,6 +237,11 @@ define(["events", "appStorage"], function(events, appStorage) { } return 0 } + + function cancelReportPlaybackProgressPromise(instance) { + if (typeof instance.reportPlaybackProgressCancel === "function") instance.reportPlaybackProgressCancel(); + } + ApiClient.prototype.appName = function() { return this._appName }, ApiClient.prototype.setRequestHeaders = function(headers) { @@ -1417,6 +1428,7 @@ define(["events", "appStorage"], function(events, appStorage) { }, ApiClient.prototype.reportPlaybackStart = function(options) { if (!options) throw new Error("null options"); this.lastPlaybackProgressReport = 0, this.lastPlaybackProgressReportTicks = null, stopBitrateDetection(this); + cancelReportPlaybackProgressPromise(this); var url = this.getUrl("Sessions/Playing"); return this.ajax({ type: "POST", @@ -1426,25 +1438,74 @@ define(["events", "appStorage"], function(events, appStorage) { }) }, ApiClient.prototype.reportPlaybackProgress = function(options) { if (!options) throw new Error("null options"); - var newPositionTicks = options.PositionTicks; - if ("timeupdate" === (options.EventName || "timeupdate")) { - var now = (new Date).getTime(), - msSinceLastReport = now - (this.lastPlaybackProgressReport || 0); - if (msSinceLastReport <= 1e4) { - if (!newPositionTicks) return Promise.resolve(); - var expectedReportTicks = 1e4 * msSinceLastReport + (this.lastPlaybackProgressReportTicks || 0); - if (Math.abs((newPositionTicks || 0) - expectedReportTicks) < 5e7) return Promise.resolve() - } - this.lastPlaybackProgressReport = now - } else this.lastPlaybackProgressReport = 0; - this.lastPlaybackProgressReportTicks = newPositionTicks; - var url = this.getUrl("Sessions/Playing/Progress"); - return this.ajax({ - type: "POST", - data: JSON.stringify(options), - contentType: "application/json", - url: url - }) + + const eventName = options.EventName || "timeupdate"; + let reportRateLimitTime = reportRateLimits[eventName] || 0; + + const now = (new Date).getTime(); + const msSinceLastReport = now - (this.lastPlaybackProgressReport || 0); + const newPositionTicks = options.PositionTicks; + + if (msSinceLastReport < reportRateLimitTime && eventName === "timeupdate" && newPositionTicks) { + const expectedReportTicks = 1e4 * msSinceLastReport + (this.lastPlaybackProgressReportTicks || 0); + if (Math.abs(newPositionTicks - expectedReportTicks) >= 5e7) reportRateLimitTime = 0; + } + + if (reportRateLimitTime < (this.reportPlaybackProgressTimeout !== undefined ? this.reportPlaybackProgressTimeout : 1e6)) { + cancelReportPlaybackProgressPromise(this); + } + + this.lastPlaybackProgressOptions = options; + + if (this.reportPlaybackProgressPromise) return Promise.resolve(); + + let instance = this; + let promise; + let cancelled = false; + + let resetPromise = function () { + if (instance.reportPlaybackProgressPromise !== promise) return; + + delete instance.lastPlaybackProgressOptions; + delete instance.reportPlaybackProgressTimeout; + delete instance.reportPlaybackProgressPromise; + delete instance.reportPlaybackProgressCancel; + }; + + let sendReport = function (lastOptions) { + resetPromise(); + + if (!lastOptions) throw new Error("null options"); + + instance.lastPlaybackProgressReport = (new Date).getTime(); + instance.lastPlaybackProgressReportTicks = lastOptions.PositionTicks; + + const url = instance.getUrl("Sessions/Playing/Progress"); + return instance.ajax({ + type: "POST", + data: JSON.stringify(lastOptions), + contentType: "application/json", + url: url + }); + }; + + let delay = Math.max(0, reportRateLimitTime - msSinceLastReport); + + promise = new Promise((resolve, reject) => setTimeout(resolve, delay)).then(() => { + if (cancelled) return Promise.resolve(); + return sendReport(instance.lastPlaybackProgressOptions); + }).finally(() => { + resetPromise(); + }); + + this.reportPlaybackProgressTimeout = reportRateLimitTime; + this.reportPlaybackProgressPromise = promise; + this.reportPlaybackProgressCancel = function () { + cancelled = true; + resetPromise(); + }; + + return promise; }, ApiClient.prototype.reportOfflineActions = function(actions) { if (!actions) throw new Error("null actions"); var url = this.getUrl("Sync/OfflineActions"); @@ -1489,6 +1550,7 @@ define(["events", "appStorage"], function(events, appStorage) { }, ApiClient.prototype.reportPlaybackStopped = function(options) { if (!options) throw new Error("null options"); this.lastPlaybackProgressReport = 0, this.lastPlaybackProgressReportTicks = null, redetectBitrate(this); + cancelReportPlaybackProgressPromise(this); var url = this.getUrl("Sessions/Playing/Stopped"); return this.ajax({ type: "POST", diff --git a/src/components/navdrawer/navdrawer.css b/src/libraries/navdrawer/navdrawer.css similarity index 100% rename from src/components/navdrawer/navdrawer.css rename to src/libraries/navdrawer/navdrawer.css diff --git a/src/components/navdrawer/navdrawer.js b/src/libraries/navdrawer/navdrawer.js similarity index 100% rename from src/components/navdrawer/navdrawer.js rename to src/libraries/navdrawer/navdrawer.js diff --git a/src/components/screensavermanager.js b/src/libraries/screensavermanager.js similarity index 100% rename from src/components/screensavermanager.js rename to src/libraries/screensavermanager.js diff --git a/src/components/scroller.js b/src/libraries/scroller.js similarity index 100% rename from src/components/scroller.js rename to src/libraries/scroller.js diff --git a/src/components/visibleinviewport.js b/src/libraries/visibleinviewport.js similarity index 100% rename from src/components/visibleinviewport.js rename to src/libraries/visibleinviewport.js diff --git a/src/nowplaying.html b/src/nowplaying.html index 59b6a4b789..6eaf0252fb 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -1,57 +1,71 @@ -
+
+ +
-

- -
- +
+

+
+
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+ +
+ + + + -
- + - + - - - - - - - - - - - - -
-
-
/
-
+ + + +
+ + + + +
- -
- -
-
+
-
-
@@ -155,21 +161,22 @@
- -
-
-
-

${TabPlaylist}

- +
-
+
+
+
+
+
+
-
-
-
-
diff --git a/src/components/alphanumericshortcuts/alphanumericshortcuts.js b/src/scripts/alphanumericshortcuts.js similarity index 100% rename from src/components/alphanumericshortcuts/alphanumericshortcuts.js rename to src/scripts/alphanumericshortcuts.js diff --git a/src/scripts/apploader.js b/src/scripts/apploader.js index 7001c4c614..1ee74178b1 100644 --- a/src/scripts/apploader.js +++ b/src/scripts/apploader.js @@ -29,6 +29,16 @@ ); } + try { + Promise.resolve(); + } catch (ex) { + // this checks for several cases actually, typical is + // Promise() being missing on some legacy browser, and a funky one + // is Promise() present but buggy on WebOS 2 + window.Promise = undefined; + self.Promise = undefined; + } + if (!self.Promise) { // Load Promise polyfill if they are not natively supported injectScriptElement( diff --git a/src/scripts/browser.js b/src/scripts/browser.js index f89df82c0c..840ef6ac23 100644 --- a/src/scripts/browser.js +++ b/src/scripts/browser.js @@ -22,7 +22,7 @@ define([], function () { return true; } - if (userAgent.indexOf('webos') !== -1) { + if (userAgent.indexOf('web0s') !== -1) { return true; } @@ -77,10 +77,10 @@ define([], function () { var camel = prop.replace(/-([a-z]|[0-9])/ig, function (all, letter) { return (letter + '').toUpperCase(); }); - // Check if the property is supported - var support = (camel in el.style); // Create test element var el = document.createElement('div'); + // Check if the property is supported + var support = (camel in el.style); // Assign the property and value to invoke // the CSS interpreter el.style.cssText = prop + ':' + value; diff --git a/src/scripts/browserdeviceprofile.js b/src/scripts/browserdeviceprofile.js index 570c0d2fa1..a269498dd0 100644 --- a/src/scripts/browserdeviceprofile.js +++ b/src/scripts/browserdeviceprofile.js @@ -887,6 +887,16 @@ define(['browser'], function (browser) { Method: 'External' }); } + if (options.enableSsaRender) { + profile.SubtitleProfiles.push({ + Format: 'ass', + Method: 'External' + }); + profile.SubtitleProfiles.push({ + Format: 'ssa', + Method: 'External' + }); + } profile.ResponseProfiles = []; profile.ResponseProfiles.push({ diff --git a/src/scripts/dfnshelper.js b/src/scripts/dfnshelper.js index 3f82e6ba7c..6ad2ee9709 100644 --- a/src/scripts/dfnshelper.js +++ b/src/scripts/dfnshelper.js @@ -1,62 +1,62 @@ -import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, ja, kk, ko, lt, ms, nb, - nl, pl, ptBR, pt, ro, ru, sk, sl, sv, tr, uk, vi, zhCN, zhTW } from 'date-fns/locale'; -import globalize from 'globalize'; - -const dateLocales = (locale) => ({ - 'ar': ar, - 'be-by': be, - 'bg-bg': bg, - 'ca': ca, - 'cs': cs, - 'da': da, - 'de': de, - 'el': el, - 'en-gb': enGB, - 'en-us': enUS, - 'es': es, - 'es-ar': es, - 'es-mx': es, - 'fa': faIR, - 'fi': fi, - 'fr': fr, - 'fr-ca': frCA, - 'gsw': de, - 'he': he, - 'hi-in': hi, - 'hr': hr, - 'hu': hu, - 'id': id, - 'it': it, - 'ja': ja, - 'kk': kk, - 'ko': ko, - 'lt-lt': lt, - 'ms': ms, - 'nb': nb, - 'nl': nl, - 'pl': pl, - 'pt-br': ptBR, - 'pt-pt': pt, - 'ro': ro, - 'ru': ru, - 'sk': sk, - 'sl-si': sl, - 'sv': sv, - 'tr': tr, - 'uk': uk, - 'vi': vi, - 'zh-cn': zhCN, - 'zh-hk': zhCN, - 'zh-tw': zhTW -})[locale]; - -export function getLocale() { - return dateLocales(globalize.getCurrentLocale()) || enUS; -} - -export const localeWithSuffix = { addSuffix: true, locale: getLocale() }; - -export default { - getLocale: getLocale, - localeWithSuffix: localeWithSuffix -}; +import { ar, be, bg, ca, cs, da, de, el, enGB, enUS, es, faIR, fi, fr, frCA, he, hi, hr, hu, id, it, ja, kk, ko, lt, ms, nb, + nl, pl, ptBR, pt, ro, ru, sk, sl, sv, tr, uk, vi, zhCN, zhTW } from 'date-fns/locale'; +import globalize from 'globalize'; + +const dateLocales = (locale) => ({ + 'ar': ar, + 'be-by': be, + 'bg-bg': bg, + 'ca': ca, + 'cs': cs, + 'da': da, + 'de': de, + 'el': el, + 'en-gb': enGB, + 'en-us': enUS, + 'es': es, + 'es-ar': es, + 'es-mx': es, + 'fa': faIR, + 'fi': fi, + 'fr': fr, + 'fr-ca': frCA, + 'gsw': de, + 'he': he, + 'hi-in': hi, + 'hr': hr, + 'hu': hu, + 'id': id, + 'it': it, + 'ja': ja, + 'kk': kk, + 'ko': ko, + 'lt-lt': lt, + 'ms': ms, + 'nb': nb, + 'nl': nl, + 'pl': pl, + 'pt-br': ptBR, + 'pt-pt': pt, + 'ro': ro, + 'ru': ru, + 'sk': sk, + 'sl-si': sl, + 'sv': sv, + 'tr': tr, + 'uk': uk, + 'vi': vi, + 'zh-cn': zhCN, + 'zh-hk': zhCN, + 'zh-tw': zhTW +})[locale]; + +export function getLocale() { + return dateLocales(globalize.getCurrentLocale()) || enUS; +} + +export const localeWithSuffix = { addSuffix: true, locale: getLocale() }; + +export default { + getLocale: getLocale, + localeWithSuffix: localeWithSuffix +}; diff --git a/src/components/dom.js b/src/scripts/dom.js similarity index 100% rename from src/components/dom.js rename to src/scripts/dom.js diff --git a/src/scripts/editorsidebar.js b/src/scripts/editorsidebar.js index b7cb4b5c57..5f874b3282 100644 --- a/src/scripts/editorsidebar.js +++ b/src/scripts/editorsidebar.js @@ -1,4 +1,4 @@ -define(["datetime", "jQuery", "material-icons"], function (datetime, $) { +define(["datetime", "jQuery", "globalize", "material-icons"], function (datetime, $, globalize) { "use strict"; function getNode(item, folderState, selected) { @@ -70,7 +70,7 @@ define(["datetime", "jQuery", "material-icons"], function (datetime, $) { var nodes = []; nodes.push({ id: "MediaFolders", - text: Globalize.translate("HeaderMediaFolders"), + text: globalize.translate("HeaderMediaFolders"), state: { opened: true }, @@ -83,7 +83,7 @@ define(["datetime", "jQuery", "material-icons"], function (datetime, $) { if (result.TotalRecordCount) { nodes.push({ id: "livetv", - text: Globalize.translate("HeaderLiveTV"), + text: globalize.translate("HeaderLiveTV"), state: { opened: false }, diff --git a/src/components/filesystem.js b/src/scripts/filesystem.js similarity index 100% rename from src/components/filesystem.js rename to src/scripts/filesystem.js diff --git a/src/components/input/gamepadtokey.js b/src/scripts/gamepadtokey.js similarity index 100% rename from src/components/input/gamepadtokey.js rename to src/scripts/gamepadtokey.js diff --git a/src/scripts/imagehelper.js b/src/scripts/imagehelper.js index 790862b223..f1da17bf2b 100644 --- a/src/scripts/imagehelper.js +++ b/src/scripts/imagehelper.js @@ -14,6 +14,7 @@ import browser from 'browser'; case "Kodi": return baseUrl + "kodi.svg"; case "Jellyfin Android": + case "Android TV": return baseUrl + "android.svg"; case "Jellyfin Web": switch (device.Name || device.DeviceName) { diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index cacc6c99a3..d9dcf52d84 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -235,6 +235,9 @@ import appHost from 'apphost'; } } + // Alias for backward compatibility + export const trigger = handleCommand; + dom.addEventListener(document, 'click', notify, { passive: true }); diff --git a/src/scripts/itembynamedetailpage.js b/src/scripts/itembynamedetailpage.js index ea760900ec..5ffacb2209 100644 --- a/src/scripts/itembynamedetailpage.js +++ b/src/scripts/itembynamedetailpage.js @@ -1,4 +1,4 @@ -define(["connectionManager", "listView", "cardBuilder", "imageLoader", "libraryBrowser", "emby-itemscontainer", "emby-button"], function (connectionManager, listView, cardBuilder, imageLoader, libraryBrowser) { +define(["connectionManager", "listView", "cardBuilder", "imageLoader", "libraryBrowser", "globalize", "emby-itemscontainer", "emby-button"], function (connectionManager, listView, cardBuilder, imageLoader, libraryBrowser, globalize) { "use strict"; function renderItems(page, item) { @@ -6,56 +6,56 @@ define(["connectionManager", "listView", "cardBuilder", "imageLoader", "libraryB if (item.ArtistCount) { sections.push({ - name: Globalize.translate("TabArtists"), + name: globalize.translate("TabArtists"), type: "MusicArtist" }); } if (item.ProgramCount && "Person" == item.Type) { sections.push({ - name: Globalize.translate("HeaderUpcomingOnTV"), + name: globalize.translate("HeaderUpcomingOnTV"), type: "Program" }); } if (item.MovieCount) { sections.push({ - name: Globalize.translate("TabMovies"), + name: globalize.translate("TabMovies"), type: "Movie" }); } if (item.SeriesCount) { sections.push({ - name: Globalize.translate("TabShows"), + name: globalize.translate("TabShows"), type: "Series" }); } if (item.EpisodeCount) { sections.push({ - name: Globalize.translate("TabEpisodes"), + name: globalize.translate("TabEpisodes"), type: "Episode" }); } if (item.TrailerCount) { sections.push({ - name: Globalize.translate("TabTrailers"), + name: globalize.translate("TabTrailers"), type: "Trailer" }); } if (item.AlbumCount) { sections.push({ - name: Globalize.translate("TabAlbums"), + name: globalize.translate("TabAlbums"), type: "MusicAlbum" }); } if (item.MusicVideoCount) { sections.push({ - name: Globalize.translate("TabMusicVideos"), + name: globalize.translate("TabMusicVideos"), type: "MusicVideo" }); } @@ -74,7 +74,7 @@ define(["connectionManager", "listView", "cardBuilder", "imageLoader", "libraryB html += '

'; html += section.name; html += "

"; - html += '"; + html += '"; html += "
"; html += '
'; html += "
"; diff --git a/src/components/input/keyboardnavigation.js b/src/scripts/keyboardnavigation.js similarity index 98% rename from src/components/input/keyboardnavigation.js rename to src/scripts/keyboardnavigation.js index 3c80063f4f..a95b750b1e 100644 --- a/src/components/input/keyboardnavigation.js +++ b/src/scripts/keyboardnavigation.js @@ -155,7 +155,7 @@ export function enable() { function attachGamepadScript(e) { console.log("Gamepad connected! Attaching gamepadtokey.js script"); window.removeEventListener("gamepadconnected", attachGamepadScript); - require(["components/input/gamepadtokey"]); + require(["scripts/gamepadtokey"]); } // No need to check for gamepads manually at load time, the eventhandler will be fired for that diff --git a/src/scripts/librarybrowser.js b/src/scripts/librarybrowser.js index bc8908fe6c..9f8ec00ad8 100644 --- a/src/scripts/librarybrowser.js +++ b/src/scripts/librarybrowser.js @@ -1,4 +1,4 @@ -define(["userSettings"], function (userSettings) { +define(["userSettings", "globalize"], function (userSettings, globalize) { "use strict"; var libraryBrowser = { @@ -45,7 +45,7 @@ define(["userSettings"], function (userSettings) { var menuItems = views.map(function (v) { return { - name: Globalize.translate("Option" + v), + name: globalize.translate("Option" + v), id: v, selected: currentLayout == v }; @@ -83,7 +83,7 @@ define(["userSettings"], function (userSettings) { if (html += '
', showControls) { html += ''; - html += Globalize.translate("ListPaging", (totalRecordCount ? startIndex + 1 : 0), recordsEnd, totalRecordCount); + html += globalize.translate("ListPaging", (totalRecordCount ? startIndex + 1 : 0), recordsEnd, totalRecordCount); html += ""; } @@ -96,15 +96,15 @@ define(["userSettings"], function (userSettings) { } if (options.addLayoutButton) { - html += ''; + html += ''; } if (options.sortButton) { - html += ''; + html += ''; } if (options.filterButton) { - html += ''; + html += ''; } html += "
"; @@ -154,7 +154,7 @@ define(["userSettings"], function (userSettings) { var html = ""; html += '
'; html += '

'; - html += Globalize.translate("HeaderSortBy"); + html += globalize.translate("HeaderSortBy"); html += "

"; var i; var length; @@ -169,13 +169,13 @@ define(["userSettings"], function (userSettings) { html += "
"; html += '

'; - html += Globalize.translate("HeaderSortOrder"); + html += globalize.translate("HeaderSortOrder"); html += "

"; html += "
"; isChecked = "Ascending" == options.query.SortOrder ? " checked" : ""; - html += '"; + html += '"; isChecked = "Descending" == options.query.SortOrder ? " checked" : ""; - html += '"; + html += '"; html += "
"; html += "
"; dlg.innerHTML = html; diff --git a/src/scripts/librarymenu.js b/src/scripts/librarymenu.js index 11c89b01da..79c4c09e78 100644 --- a/src/scripts/librarymenu.js +++ b/src/scripts/librarymenu.js @@ -73,7 +73,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " } if (user && user.localUser) { - if (headerHomeButton && !layoutManager.mobile) { + if (headerHomeButton) { headerHomeButton.classList.remove("hide"); } @@ -733,8 +733,8 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", " function initHeadRoom(elem) { require(["headroom"], function (Headroom) { - var headroom = new Headroom([], {}); - headroom.add(elem); + var headroom = new Headroom(elem); + headroom.init(); }); } diff --git a/src/components/input/mouseManager.js b/src/scripts/mouseManager.js similarity index 100% rename from src/components/input/mouseManager.js rename to src/scripts/mouseManager.js diff --git a/src/scripts/routes.js b/src/scripts/routes.js index 9c3db58a7f..72c67e5b71 100644 --- a/src/scripts/routes.js +++ b/src/scripts/routes.js @@ -23,6 +23,35 @@ define([ console.debug("defining core routes"); + defineRoute({ + path: "/addserver.html", + autoFocus: false, + anonymous: true, + startup: true, + controller: "auth/addserver" + }); + defineRoute({ + path: "/selectserver.html", + autoFocus: false, + anonymous: true, + startup: true, + controller: "auth/selectserver", + type: "selectserver" + }); + defineRoute({ + path: "/forgotpassword.html", + anonymous: true, + startup: true, + controller: "auth/forgotpassword" + }); + defineRoute({ + path: "/forgotpasswordpin.html", + autoFocus: false, + anonymous: true, + startup: true, + controller: "auth/forgotpasswordpin" + }); + defineRoute({ path: "/addplugin.html", autoFocus: false, @@ -41,13 +70,6 @@ define([ transition: "fade", controller: "user/profile" }); - defineRoute({ - path: "/addserver.html", - autoFocus: false, - anonymous: true, - startup: true, - controller: "auth/addserver" - }); defineRoute({ path: "/mypreferencesdisplay.html", autoFocus: false, @@ -95,31 +117,31 @@ define([ path: "/devices.html", autoFocus: false, roles: "admin", - controller: "devices" + controller: "dashboard/devices/devices" }); defineRoute({ path: "/device.html", autoFocus: false, roles: "admin", - controller: "device" + controller: "dashboard/devices/device" }); defineRoute({ path: "/dlnaprofile.html", autoFocus: false, roles: "admin", - controller: "dlnaprofile" + controller: "dashboard/dlna/dlnaprofile" }); defineRoute({ path: "/dlnaprofiles.html", autoFocus: false, roles: "admin", - controller: "dlnaprofiles" + controller: "dashboard/dlna/dlnaprofiles" }); defineRoute({ path: "/dlnasettings.html", autoFocus: false, roles: "admin", - controller: "dlnasettings" + controller: "dashboard/dlna/dlnasettings" }); defineRoute({ path: "/edititemmetadata.html", @@ -130,20 +152,7 @@ define([ path: "/encodingsettings.html", autoFocus: false, roles: "admin", - controller: "encodingsettings" - }); - defineRoute({ - path: "/forgotpassword.html", - anonymous: true, - startup: true, - controller: "auth/forgotpassword" - }); - defineRoute({ - path: "/forgotpasswordpin.html", - autoFocus: false, - anonymous: true, - startup: true, - controller: "auth/forgotpasswordpin" + controller: "dashboard/encodingsettings" }); defineRoute({ path: "/home.html", @@ -158,11 +167,6 @@ define([ controller: "list", transition: "fade" }); - defineRoute({ - path: "/index.html", - autoFocus: false, - isDefaultRoute: true - }); defineRoute({ path: "/itemdetails.html", controller: "itemdetailpage", @@ -173,19 +177,13 @@ define([ path: "/library.html", autoFocus: false, roles: "admin", - controller: "medialibrarypage" + controller: "dashboard/medialibrarypage" }); defineRoute({ path: "/librarydisplay.html", autoFocus: false, roles: "admin", - controller: "librarydisplay" - }); - defineRoute({ - path: "/librarysettings.html", - autoFocus: false, - roles: "admin", - controller: "librarysettings" + controller: "dashboard/librarydisplay" }); defineRoute({ path: "/livetv.html", @@ -233,13 +231,13 @@ define([ path: "/metadataimages.html", autoFocus: false, roles: "admin", - controller: "metadataimagespage" + controller: "dashboard/metadataimagespage" }); defineRoute({ path: "/metadatanfo.html", autoFocus: false, roles: "admin", - controller: "metadatanfo" + controller: "dashboard/metadatanfo" }); defineRoute({ path: "/movies.html", @@ -265,20 +263,11 @@ define([ autoFocus: false, roles: "admin" }); - defineRoute({ - path: "/nowplaying.html", - controller: "playback/nowplaying", - autoFocus: false, - transition: "fade", - fullscreen: true, - supportsThemeMedia: true, - enableMediaControl: false - }); defineRoute({ path: "/playbackconfiguration.html", autoFocus: false, roles: "admin", - controller: "playbackconfiguration" + controller: "dashboard/playbackconfiguration" }); defineRoute({ path: "/availableplugins.html", @@ -308,31 +297,23 @@ define([ path: "/search.html", controller: "searchpage" }); - defineRoute({ - path: "/selectserver.html", - autoFocus: false, - anonymous: true, - startup: true, - controller: "auth/selectserver", - type: "selectserver" - }); defineRoute({ path: "/serveractivity.html", autoFocus: false, roles: "admin", - controller: "serveractivity" + controller: "dashboard/serveractivity" }); defineRoute({ path: "/apikeys.html", autoFocus: false, roles: "admin", - controller: "apikeys" + controller: "dashboard/apikeys" }); defineRoute({ path: "/streamingsettings.html", autoFocus: false, roles: "admin", - controller: "streamingsettings" + controller: "dashboard/streamingsettings" }); defineRoute({ path: "/tv.html", @@ -423,6 +404,15 @@ define([ fullscreen: true, enableMediaControl: false }); + defineRoute({ + path: "/nowplaying.html", + controller: "playback/nowplaying", + autoFocus: false, + transition: "fade", + fullscreen: true, + supportsThemeMedia: true, + enableMediaControl: false + }); defineRoute({ path: "/configurationpage", autoFocus: false, @@ -436,4 +426,9 @@ define([ isDefaultRoute: true, autoFocus: false }); + defineRoute({ + path: "/index.html", + autoFocus: false, + isDefaultRoute: true + }); }); diff --git a/src/scripts/settings/appSettings.js b/src/scripts/settings/appSettings.js index 03ceb346a2..6f0975e98c 100644 --- a/src/scripts/settings/appSettings.js +++ b/src/scripts/settings/appSettings.js @@ -12,7 +12,7 @@ import events from 'events'; } export function enableAutoLogin(val) { - if (val != null) { + if (val !== undefined) { this.set('enableAutoLogin', val.toString()); } @@ -20,7 +20,7 @@ import events from 'events'; } export function enableSystemExternalPlayers(val) { - if (val !== null) { + if (val !== undefined) { this.set('enableSystemExternalPlayers', val.toString()); } @@ -29,7 +29,7 @@ import events from 'events'; export function enableAutomaticBitrateDetection(isInNetwork, mediaType, val) { var key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork; - if (val != null) { + if (val !== undefined) { if (isInNetwork && mediaType === 'Audio') { val = true; } @@ -46,7 +46,7 @@ import events from 'events'; export function maxStreamingBitrate(isInNetwork, mediaType, val) { var key = 'maxbitrate-' + mediaType + '-' + isInNetwork; - if (val != null) { + if (val !== undefined) { if (isInNetwork && mediaType === 'Audio') { // nothing to do, this is always a max value } else { @@ -72,7 +72,7 @@ import events from 'events'; } export function maxChromecastBitrate(val) { - if (val != null) { + if (val !== undefined) { this.set('chromecastBitrate1', val); } @@ -81,7 +81,7 @@ import events from 'events'; } export function syncOnlyOnWifi(val) { - if (val != null) { + if (val !== undefined) { this.set('syncOnlyOnWifi', val.toString()); } @@ -89,7 +89,7 @@ import events from 'events'; } export function syncPath(val) { - if (val != null) { + if (val !== undefined) { this.set('syncPath', val); } @@ -97,7 +97,7 @@ import events from 'events'; } export function cameraUploadServers(val) { - if (val != null) { + if (val !== undefined) { this.set('cameraUploadServers', val.join(',')); } @@ -110,7 +110,7 @@ import events from 'events'; } export function runAtStartup(val) { - if (val != null) { + if (val !== undefined) { this.set('runatstartup', val.toString()); } diff --git a/src/scripts/settings/userSettings.js b/src/scripts/settings/userSettings.js index 6f115eeffa..12748eac20 100644 --- a/src/scripts/settings/userSettings.js +++ b/src/scripts/settings/userSettings.js @@ -84,7 +84,7 @@ import events from 'events'; } export function enableCinemaMode(val) { - if (val != null) { + if (val !== undefined) { return this.set('enableCinemaMode', val.toString(), false); } @@ -93,7 +93,7 @@ import events from 'events'; } export function enableNextVideoInfoOverlay(val) { - if (val != null) { + if (val !== undefined) { return this.set('enableNextVideoInfoOverlay', val.toString()); } @@ -102,7 +102,7 @@ import events from 'events'; } export function enableThemeSongs(val) { - if (val != null) { + if (val !== undefined) { return this.set('enableThemeSongs', val.toString(), false); } @@ -111,7 +111,7 @@ import events from 'events'; } export function enableThemeVideos(val) { - if (val != null) { + if (val !== undefined) { return this.set('enableThemeVideos', val.toString(), false); } @@ -120,7 +120,7 @@ import events from 'events'; } export function enableFastFadein(val) { - if (val != null) { + if (val !== undefined) { return this.set('fastFadein', val.toString(), false); } @@ -129,7 +129,7 @@ import events from 'events'; } export function enableBackdrops(val) { - if (val != null) { + if (val !== undefined) { return this.set('enableBackdrops', val.toString(), false); } @@ -138,7 +138,7 @@ import events from 'events'; } export function language(val) { - if (val != null) { + if (val !== undefined) { return this.set('language', val.toString(), false); } @@ -146,7 +146,7 @@ import events from 'events'; } export function dateTimeLocale(val) { - if (val != null) { + if (val !== undefined) { return this.set('datetimelocale', val.toString(), false); } @@ -154,7 +154,7 @@ import events from 'events'; } export function skipBackLength(val) { - if (val != null) { + if (val !== undefined) { return this.set('skipBackLength', val.toString()); } @@ -162,7 +162,7 @@ import events from 'events'; } export function skipForwardLength(val) { - if (val != null) { + if (val !== undefined) { return this.set('skipForwardLength', val.toString()); } @@ -170,7 +170,7 @@ import events from 'events'; } export function dashboardTheme(val) { - if (val != null) { + if (val !== undefined) { return this.set('dashboardTheme', val); } @@ -178,7 +178,7 @@ import events from 'events'; } export function skin(val) { - if (val != null) { + if (val !== undefined) { return this.set('skin', val, false); } @@ -186,7 +186,7 @@ import events from 'events'; } export function theme(val) { - if (val != null) { + if (val !== undefined) { return this.set('appTheme', val, false); } @@ -194,7 +194,7 @@ import events from 'events'; } export function screensaver(val) { - if (val != null) { + if (val !== undefined) { return this.set('screensaver', val, false); } @@ -202,7 +202,7 @@ import events from 'events'; } export function libraryPageSize(val) { - if (val != null) { + if (val !== undefined) { return this.set('libraryPageSize', parseInt(val, 10), false); } @@ -216,7 +216,7 @@ import events from 'events'; } export function soundEffects(val) { - if (val != null) { + if (val !== undefined) { return this.set('soundeffects', val, false); } diff --git a/src/scripts/settings/webSettings.js b/src/scripts/settings/webSettings.js index 4b1b658e9b..8279c162fe 100644 --- a/src/scripts/settings/webSettings.js +++ b/src/scripts/settings/webSettings.js @@ -11,5 +11,8 @@ function getConfig() { export function enableMultiServer() { return getConfig().then(config => { return config.multiserver; + }).catch(error => { + console.log("cannot get web config:", error); + return false; }); } diff --git a/src/scripts/site.js b/src/scripts/site.js index e33cf25d6f..71d7eefcee 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -350,11 +350,6 @@ var AppInfo = {}; return layoutManager; } - function createWindowHeadroom(Headroom) { - var headroom = new Headroom([], {}); - return headroom; - } - function createSharedAppFooter(appFooter) { return new appFooter({}); } @@ -376,8 +371,9 @@ var AppInfo = {}; function initRequireWithBrowser(browser) { var bowerPath = getBowerPath(); var componentsPath = getComponentsPath(); + var scriptsPath = getScriptsPath(); - define("filesystem", [componentsPath + "/filesystem"], returnFirstDependency); + define("filesystem", [scriptsPath + "/filesystem"], returnFirstDependency); if (window.IntersectionObserver && !browser.edge) { define("lazyLoader", [componentsPath + "/lazyloader/lazyloader-intersectionobserver"], returnFirstDependency); @@ -430,9 +426,6 @@ var AppInfo = {}; if (!window.fetch) { promises.push(require(["fetch"])); } - if ("function" != typeof Object.assign) { - promises.push(require(["objectassign"])); - } Promise.all(promises).then(function () { createConnectionManager().then(function () { @@ -570,7 +563,7 @@ var AppInfo = {}; require(["playerSelectionMenu", "components/playback/remotecontrolautoplay"]); } - require(["components/screensavermanager"]); + require(["libraries/screensavermanager"]); if (!appHost.supports("physicalvolumecontrol") || browser.touch) { require(["components/playback/volumeosd"]); @@ -591,7 +584,7 @@ var AppInfo = {}; } } - require(["playerSelectionMenu", "fullscreenManager"]); + require(["playerSelectionMenu"]); var apiClient = window.ConnectionManager && window.ConnectionManager.currentApiClient(); if (apiClient) { @@ -665,7 +658,7 @@ var AppInfo = {}; medialibraryeditor: componentsPath + "/medialibraryeditor/medialibraryeditor", imageoptionseditor: componentsPath + "/imageoptionseditor/imageoptionseditor", apphost: componentsPath + "/apphost", - visibleinviewport: componentsPath + "/visibleinviewport", + visibleinviewport: bowerPath + "/visibleinviewport", qualityoptions: componentsPath + "/qualityoptions", focusManager: componentsPath + "/focusManager", itemHelper: componentsPath + "/itemhelper", @@ -709,7 +702,9 @@ var AppInfo = {}; "polyfill", "fast-text-encoding", "intersection-observer", - "classlist-polyfill" + "classlist-polyfill", + "screenfull", + "headroom" ] }, urlArgs: urlArgs, @@ -717,6 +712,7 @@ var AppInfo = {}; onError: onRequireJsError }); + require(["fetch"]); require(["polyfill"]); require(["fast-text-encoding"]); require(["intersection-observer"]); @@ -768,9 +764,8 @@ var AppInfo = {}; // TODO remove these libraries // all of these have been modified so we need to fix that first - define("headroom", [componentsPath + "/headroom/headroom"], returnFirstDependency); - define("scroller", [componentsPath + "/scroller"], returnFirstDependency); - define("navdrawer", [componentsPath + "/navdrawer/navdrawer"], returnFirstDependency); + define("scroller", [bowerPath + "/scroller"], returnFirstDependency); + define("navdrawer", [bowerPath + "/navdrawer/navdrawer"], returnFirstDependency); define("emby-button", [elementsPath + "/emby-button/emby-button"], returnFirstDependency); define("paper-icon-button-light", [elementsPath + "/emby-button/paper-icon-button-light"], returnFirstDependency); @@ -810,7 +805,7 @@ var AppInfo = {}; define("playerSettingsMenu", [componentsPath + "/playback/playersettingsmenu"], returnFirstDependency); define("playMethodHelper", [componentsPath + "/playback/playmethodhelper"], returnFirstDependency); define("brightnessOsd", [componentsPath + "/playback/brightnessosd"], returnFirstDependency); - define("alphaNumericShortcuts", [componentsPath + "/alphanumericshortcuts/alphanumericshortcuts"], returnFirstDependency); + define("alphaNumericShortcuts", [scriptsPath + "/alphanumericshortcuts"], returnFirstDependency); define("multiSelect", [componentsPath + "/multiselect/multiselect"], returnFirstDependency); define("alphaPicker", [componentsPath + "/alphapicker/alphapicker"], returnFirstDependency); define("tabbedView", [componentsPath + "/tabbedview/tabbedview"], returnFirstDependency); @@ -832,13 +827,11 @@ var AppInfo = {}; define("itemContextMenu", [componentsPath + "/itemcontextmenu"], returnFirstDependency); define("imageEditor", [componentsPath + "/imageeditor/imageeditor"], returnFirstDependency); define("imageDownloader", [componentsPath + "/imagedownloader/imagedownloader"], returnFirstDependency); - define("dom", [componentsPath + "/dom"], returnFirstDependency); + define("dom", [scriptsPath + "/dom"], returnFirstDependency); define("playerStats", [componentsPath + "/playerstats/playerstats"], returnFirstDependency); define("searchFields", [componentsPath + "/search/searchfields"], returnFirstDependency); define("searchResults", [componentsPath + "/search/searchresults"], returnFirstDependency); define("upNextDialog", [componentsPath + "/upnextdialog/upnextdialog"], returnFirstDependency); - define("fullscreen-doubleclick", [componentsPath + "/fullscreen/fullscreen-dc"], returnFirstDependency); - define("fullscreenManager", [componentsPath + "/fullscreenManager", "events"], returnFirstDependency); define("subtitleAppearanceHelper", [componentsPath + "/subtitlesettings/subtitleappearancehelper"], returnFirstDependency); define("subtitleSettings", [componentsPath + "/subtitlesettings/subtitlesettings"], returnFirstDependency); define("displaySettings", [componentsPath + "/displaysettings/displaysettings"], returnFirstDependency); @@ -864,8 +857,7 @@ var AppInfo = {}; return viewManager; }); define("slideshow", [componentsPath + "/slideshow/slideshow"], returnFirstDependency); - define("objectassign", [componentsPath + "/polyfills/objectassign"], returnFirstDependency); - define("focusPreventScroll", [componentsPath + "/polyfills/focusPreventScroll"], returnFirstDependency); + define("focusPreventScroll", ["legacy/focusPreventScroll"], returnFirstDependency); define("userdataButtons", [componentsPath + "/userdatabuttons/userdatabuttons"], returnFirstDependency); define("listView", [componentsPath + "/listview/listview"], returnFirstDependency); define("indicators", [componentsPath + "/indicators/indicators"], returnFirstDependency); @@ -883,8 +875,8 @@ var AppInfo = {}; define("dialogHelper", [componentsPath + "/dialogHelper/dialogHelper"], returnFirstDependency); define("serverNotifications", [componentsPath + "/serverNotifications"], returnFirstDependency); define("skinManager", [componentsPath + "/skinManager"], returnFirstDependency); - define("keyboardnavigation", [componentsPath + "/input/keyboardnavigation"], returnFirstDependency); - define("mouseManager", [componentsPath + "/input/mouseManager"], returnFirstDependency); + define("keyboardnavigation", [scriptsPath + "/keyboardnavigation"], returnFirstDependency); + define("mouseManager", [scriptsPath + "/mouseManager"], returnFirstDependency); define("scrollManager", [componentsPath + "/scrollManager"], returnFirstDependency); define("autoFocuser", [componentsPath + "/autoFocuser"], returnFirstDependency); define("connectionManager", [], function () { diff --git a/src/scripts/taskbutton.js b/src/scripts/taskbutton.js index f9774167c0..6159ad9fe1 100644 --- a/src/scripts/taskbutton.js +++ b/src/scripts/taskbutton.js @@ -1,4 +1,4 @@ -define(["events", "userSettings", "serverNotifications", "connectionManager", "emby-button"], function (events, userSettings, serverNotifications, connectionManager) { +define(["events", "userSettings", "serverNotifications", "connectionManager", "globalize", "emby-button"], function (events, userSettings, serverNotifications, connectionManager, globalize) { "use strict"; return function (options) { @@ -48,11 +48,11 @@ define(["events", "userSettings", "serverNotifications", "connectionManager", "e var lastResult = task.LastExecutionResult ? task.LastExecutionResult.Status : ''; if (lastResult == "Failed") { - options.lastResultElem.html('(' + Globalize.translate('LabelFailed') + ')'); + options.lastResultElem.html('(' + globalize.translate('LabelFailed') + ')'); } else if (lastResult == "Cancelled") { - options.lastResultElem.html('(' + Globalize.translate('LabelCancelled') + ')'); + options.lastResultElem.html('(' + globalize.translate('LabelCancelled') + ')'); } else if (lastResult == "Aborted") { - options.lastResultElem.html('' + Globalize.translate('LabelAbortedByServerShutdown') + ''); + options.lastResultElem.html('' + globalize.translate('LabelAbortedByServerShutdown') + ''); } else { options.lastResultElem.html(lastResult); } diff --git a/src/strings/af.json b/src/strings/af.json index 6ac71790f6..7cbaab20d9 100644 --- a/src/strings/af.json +++ b/src/strings/af.json @@ -40,5 +40,6 @@ "Add": "Voeg by", "Actor": "Akteur", "AccessRestrictedTryAgainLater": "Toegang is beperk. Probeer weer later .", - "Absolute": "Absoluut" + "Absolute": "Absoluut", + "AlbumArtist": "Album Kunstenaar" } diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json index e21176f6ec..8357a9c8dd 100644 --- a/src/strings/bg-bg.json +++ b/src/strings/bg-bg.json @@ -86,17 +86,17 @@ "ChannelAccessHelp": "Изберете каналите, които да споделите с потребителя. Администраторите ще могат да редактират всички канали, използвайки управлението на метаданни.", "Collections": "Колекции", "ColorSpace": "Цветово пространство", - "CommunityRating": "Обществена ощенка", + "CommunityRating": "Рейтинг на общността", "Composer": "Съчинител", "ConfirmDeleteImage": "Изтриване на изображението?", - "ContinueWatching": "Продължаване на гледането", + "ContinueWatching": "Продължи гледането", "Continuing": "Продължаващо", "CriticRating": "Оценка на критиците", "DateAdded": "Дата на добавяне", "DatePlayed": "Дата на пускане", "DeathDateValue": "Починал/а на: {0}", "Default": "По подразбиране", - "Delete": "Изтриване", + "Delete": "Премахване", "DeleteMedia": "Изтриване на медията", "Desktop": "Работен плот", "DeviceAccessHelp": "Това се отнася само за устройства, които могат да бъдат различени и няма да попречи на достъп от мрежов четец. Филтрирането на потребителски устройства ще предотврати използването им докато не бъдат одобрени тук.", @@ -305,7 +305,7 @@ "LabelCustomCertificatePath": "Път към потребителския сертификат:", "LabelCustomCertificatePathHelp": "Път до файл с шифровъчен стандарт №12 (PKCS #12), съдържащ сертификат и частен ключ за поддръжка на протокол TLS на собствен домейн.", "LabelCustomCss": "CSS по избор:", - "LabelCustomCssHelp": "Добавете собствен стил за Уеб-интерфейса.", + "LabelCustomCssHelp": "Добавете собствен стил към уеб-интерфейса.", "LabelCustomDeviceDisplayName": "Показвано име:", "LabelCustomRating": "Оценка по избор:", "LabelDashboardTheme": "Облик на сървърното табло:", @@ -836,7 +836,7 @@ "AddItemToCollectionHelp": "Добавяне към колекция чрез търсенето им и използване на дясно-щракване с мишката или контекстното меню.", "Absolute": "Aбсолютен", "LabelLanNetworks": "Локални мрежи:", - "LabelKodiMetadataSaveImagePathsHelp": "Това е препоръчително ако имате изображения, пътят към които не е съобразен с изискванията на Kodi", + "LabelKodiMetadataSaveImagePathsHelp": "Това е препоръчително, ако наименованието на изображенията не са съобразени с изискванията на Kodi.", "LabelKodiMetadataSaveImagePaths": "Записване на пътеките към изображенията в nfo файловете", "LabelChannels": "Канали:", "DropShadow": "Сянка", @@ -872,5 +872,36 @@ "CancelSeries": "Откажи сериите", "CancelRecording": "Откажи записа", "ButtonSplit": "Раздели", - "ButtonResetEasyPassword": "Нулиране на бързия ПИН код" + "ButtonResetEasyPassword": "Нулиране на бързия ПИН код", + "ButtonRevoke": "Отмени", + "ButtonEditOtherUserPreferences": "Редакция на потребителския профил, изображение и лични предпочитания.", + "BoxRear": "Комплект (стар)", + "BoxSet": "Комплект", + "AuthProviderHelp": "Избор на доставчик на услуга за Автентификация, която ще се използва за автентификация на потребителската парола.", + "AllowedRemoteAddressesHelp": "Списък с IP адреси или IP/маска записи, разделени със запетая, които ще имат отдалечен достъп. Ако полето не е попълнено всички адреси ще имат отдалечен достъп.", + "BurnSubtitlesHelp": "Определя дали сървърът трябва да записва субтитри във видеоклиповете припрекодиране. Избягването на това значително ще подобри производителността. Изберете Auto, за да запишете формати, базирани на изображения (VOBSUB, PGS, SUB, IDX) и някои ASS или SSA субтитри.", + "AllowFfmpegThrottlingHelp": "Когато прекодирането или запазването на видео стигне достатъчно далеч напред от текущата позиция за възпроизвеждане, поставете на пауза процеса, така ще се изразходват по-малко ресурси. Това е най-полезно, когато се гледа, без да се търси често из видеото. Изключете това, ако имате проблеми с възпроизвеждането.", + "AllowOnTheFlySubtitleExtractionHelp": "Вградените субтитри могат да бъдат извлечени от видеоклиповете и прехвърлени към клиентите като обикновен текст, за да се предотврати транскодирането на видеото. В някои системи това може да отнеме много време и да спре възпроизвеждането на видео по време на процеса на извличане. Деактивирайте това, за да има вградени субтитри, записани с видео кодиране, когато те не се поддържат от клиентското устройство.", + "CinemaModeConfigurationHelp": "Режимът на кино носи театрално изживяване направо във вашата всекидневна с възможност за пускане на трейлъри и персонализирани интродукции преди основния филм.", + "ChangingMetadataImageSettingsNewContent": "Промените в настройките за изтегляне на метаданни или изображения ще се прилагат само за ново съдържание, добавено към вашата библиотека. За да приложите промените към съществуващите заглавия, ще трябва да обновите метаданните им ръчно.", + "DefaultMetadataLangaugeDescription": "Това са настройки по подразбиране и могат да се променят на база библиотека.", + "DefaultErrorMessage": "Възникна грешка при изпълнение на заявката. Моля опитайте по-късно.", + "CustomDlnaProfilesHelp": "Създаване на персонализиран профил за целево устройство или заменяне на системния профил.", + "CopyStreamURL": "Копиране URL на стрийма", + "CopyStreamURLError": "Възникна грешка при копиране на URL.", + "CopyStreamURLSuccess": "URL се копира успешно.", + "Connect": "Свързване", + "ConfirmEndPlayerSession": "Искате ли да изключите Jellyfin на {0}?", + "ConfirmDeletion": "Потвърждаване на изтриването", + "ConfirmDeleteItem": "Изтриването на елемента ще го премахне едновременно от файловата система и библиотеката. Сигурни ли сте, че искате да продължите?", + "ConfigureDateAdded": "Конфигурацията на добавянето на датата се определя в панела на Jellyfin сървъра в секцията за настройка на библиотека", + "ConfirmDeleteItems": "Изтриването на елементите ще ги премахне едновременно от файловата система и библиотеката. Сигурни ли сте, че искате да продължите?", + "ColorTransfer": "Предаване на цвета", + "ColorPrimaries": "Основни цветове", + "DeleteUserConfirmation": "Сигурнили сте че искате да премахнете този потребител?", + "DeleteUser": "Премахване на потребител", + "DeleteImageConfirmation": "Сигурнили сте че искате да премахнете това Изображение?", + "DeleteImage": "Премахване на Исображение", + "ButtonTogglePlaylist": "Списък с изпълнения", + "ButtonToggleContextMenu": "Повече" } diff --git a/src/strings/ca.json b/src/strings/ca.json index 80e4b90067..f3cc97ece0 100644 --- a/src/strings/ca.json +++ b/src/strings/ca.json @@ -732,7 +732,7 @@ "XmlTvNewsCategoriesHelp": "Els programes amb aquestes categories es mostraran com a programes de notícies. Separa'n varis emprant '|'.", "XmlTvSportsCategoriesHelp": "Els programes amb aquestes categories es mostraran com a programes esportius. Separa'n varis emprant '|'.", "Books": "Llibres", - "Folders": "Directoris", + "Folders": "Carpetes", "Photos": "Fotos", "Shows": "Programes", "Songs": "Cançons", @@ -741,7 +741,7 @@ "Channels": "Canals", "Collections": "Col·leccions", "Favorites": "Preferits", - "HeaderAlbumArtists": "Artistes dels Àlbums", + "HeaderAlbumArtists": "Artistes del Àlbum", "HeaderFavoriteAlbums": "Àlbums Preferits", "HeaderFavoriteArtists": "Artistes Preferits", "HeaderFavoriteEpisodes": "Episodis Preferits", diff --git a/src/strings/cs.json b/src/strings/cs.json index 4f0745b425..b7f2f7b9d2 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -1575,8 +1575,8 @@ "Track": "Stopa", "Season": "Sezóna", "ReleaseGroup": "Vydavatel", - "PreferEmbeddedEpisodeInfosOverFileNames": "Preferovat vložené informace o epizodě před názvy souborů", - "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Používá se informace o epizodě z vložených metadat, pokud jsou k dispozici.", + "PreferEmbeddedEpisodeInfosOverFileNames": "Preferovat vloženou informaci o epizodě před názvem souboru", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Používat informaci o epizodě z vložených metadat, pokud jsou k dispozici.", "Person": "Osoba", "OtherArtist": "Ostatní interpreti", "Movie": "Film", @@ -1597,10 +1597,12 @@ "PathNotFound": "Cesta nebyla nalezena. Zkontrolujte, zda je platná a zkuste to znovu.", "WeeklyAt": "V {0} v {1}", "LastSeen": "Naposledy zobrazené {0}", - "YadifBob": "Yadif Bob", - "Yadif": "Yadif", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", "LabelLibraryPageSizeHelp": "Určuje počet položek k zobrazení na stránce knihovny. Nastavte na 0 pro vypnutí stránkování.", "LabelLibraryPageSize": "Velikost stránky knihovny:", "LabelDeinterlaceMethod": "Metoda odstranění prokládání:", - "DeinterlaceMethodHelp": "Vyberte metodu odstranění prokládání obrazu při překódování obsahu." + "DeinterlaceMethodHelp": "Vyberte metodu odstranění prokládání obrazu při překódování obsahu.", + "UnsupportedPlayback": "Jellyfin nemůže dešifrovat obsah chráněný technologií DRM, ale pokusí se zobrazit o veškerý obsah, včetně chráněných titulů. Některé soubory se mohou zdát úplně černé kvůli šifrování nebo jiným nepodporovaným funkcím, jako jsou například interaktivní funkce.", + "MessageUnauthorizedUser": "Momentálně nemáte oprávnění k přístupu na server. Další informace získáte od správce serveru." } diff --git a/src/strings/da.json b/src/strings/da.json index a838ec5298..a2b4cb6a4f 100644 --- a/src/strings/da.json +++ b/src/strings/da.json @@ -12,7 +12,7 @@ "AllChannels": "Alle kanaler", "AllEpisodes": "Alle episoder", "AllLibraries": "Alle biblioteker", - "AllowHWTranscodingHelp": "Lader tuneren omkode streams on-the-fly. Dette kan hjælpe med at reducere omkodning der kræves af serveren.", + "AllowHWTranscodingHelp": "Tillader tuneren at omkode streaming on-the-fly. Dette kan hjælpe med at reducere belastning af serveren på grund af yderligere omkodning.", "AllowMediaConversion": "Tillad media konvertering", "AllowMediaConversionHelp": "Giv eller nægt adgang til Konvertér Media featuren.", "AllowOnTheFlySubtitleExtraction": "Tillad udtræk af undertekster on-the-fly", @@ -29,7 +29,7 @@ "BirthDateValue": "Født: {0}", "BirthLocation": "Fødselslokation", "BirthPlaceValue": "Fødselssted: {0}", - "BookLibraryHelp": "Lyd- og tekstbøger er understøttet. Se {0}Jellyfins guide til navngivning af bøger{1}.", + "BookLibraryHelp": "Lyd- og tekstbøger er understøttet. Se {0}bog guide til navngivning af bøger{1}.", "Browse": "Gennemse", "BrowsePluginCatalogMessage": "Gennemse vores plugin-katalog for at se tilgængelige plugins.", "ButtonAdd": "Tilføj", @@ -53,7 +53,7 @@ "ButtonEdit": "Rediger", "ButtonEditImages": "Rediger billeder", "ButtonEditOtherUserPreferences": "Rediger denne brugers profil, billede og personlige indstillinger.", - "ButtonForgotPassword": "Glemt adgangskode", + "ButtonForgotPassword": "Glemt Adgangskode", "ButtonFullscreen": "Fuld skærm", "ButtonGotIt": "Forstået", "ButtonHelp": "Hjælp", @@ -136,30 +136,30 @@ "DoNotRecord": "Optag ikke", "Download": "Hent", "DrmChannelsNotImported": "Kanaler med DRM importeres ikke.", - "EasyPasswordHelp": "Din pinkode bruges til offline adgang til understøttede Jellyfin apps, og kan også bruges til nemt login inden for eget netværk.", + "EasyPasswordHelp": "Din nemme pin-kode bruges til offline adgang på understøttede klienter og kan også bruges til nem login på netværket.", "Edit": "Rediger", "EditImages": "Rediger billeder", "EditSubtitles": "Rediger undertekster", - "EnableCinemaMode": "Aktiver biograftilstand", - "EnableColorCodedBackgrounds": "Aktiver farvekodet baggrunde", + "EnableCinemaMode": "Aktiver Biograftilstand", + "EnableColorCodedBackgrounds": "Aktiver Farvekodet baggrunde", "EnableHardwareEncoding": "Aktiver hardware indkoding", - "EnablePhotos": "Aktiver fotos", - "EnablePhotosHelp": "Fotos bliver opdaget og vist sammen med andre mediefiler.", + "EnablePhotos": "Vis fotoer", + "EnablePhotosHelp": "Billeder registreres og vises sammen med andre mediefiler.", "EnableStreamLooping": "Auto-gentag live streams", "EnableStreamLoopingHelp": "Aktiver dette hvis live streams kun indeholder få sekunders data og skal efterspørgsel hele tiden. Aktivering af dette uden det er nødvendigt kan forårsage problemer.", "Ended": "Færdig", "EndsAtValue": "Slutter {0}", - "ErrorAddingListingsToSchedulesDirect": "Der opstod en fejl under tilføjelse af opstilling til din Schedules Direct-konto. Schedules Direct tillader kun et begrænset antal opstillinger pr. konto. Du bliver muligvis nød til at logge på Schedules Direct-hjemmesiden og fjerne andre lister fra din konto for at fortsætte.", + "ErrorAddingListingsToSchedulesDirect": "Der opstod en fejl ved tilføjelse af lineup til din Schedules Direct-konto. Schedules Direct tillader kun et begrænset antal opstillinger pr. Konto. Det kan være nødvendigt at du logger ind på Schedules Direct-webstedet og fjerner andre lister fra din konto, før du fortsætter.", "ErrorAddingMediaPathToVirtualFolder": "Der opstod en fejl under tilføjelse af mediesti. Kontroller venligst at stien er gyldig og at Jellyfin Server-processen har adgang til denne lokation.", "ErrorAddingTunerDevice": "Der opstod en fejl under tilføjelse af tuner-enhed. Kontroller venligst at den er tilgængelig og prøv igen.", - "ErrorAddingXmlTvFile": "Der opstod en fejl under tilgang til XmlTV-filen. Kontroller venligst at filen findes og prøv igen.", - "ErrorGettingTvLineups": "Der opstod en fejl under download af tv-opstillinger. Kontroller venligst at dine informationer er korrekte og prøv igen.", + "ErrorAddingXmlTvFile": "Der opstod en fejl under tilgang til XMLTV-filen. Kontroller venligst at filen findes og prøv igen.", + "ErrorGettingTvLineups": "Der opstod en fejl under download af TV-opstillinger. Kontroller venligst at dine informationer er korrekte og prøv igen.", "ErrorMessageStartHourGreaterThanEnd": "Slut tid skal være større end start tid.", "ErrorPleaseSelectLineup": "Vælg venligst en opstilling og prøv igen. Hvis ingen opstillinger er tilgængelige, så kontroller venligst at dit brugernavn, adgangskode og postnummer er korrekt.", "ErrorSavingTvProvider": "Der opstod en fejl i forsøget på at gemme udbyder. Kontroller venligst at den er tilgængelig og prøv igen.", "EveryNDays": "Hver {0} dage", "ExitFullscreen": "Afslut fuldskærm", - "ExtractChapterImagesHelp": "Udvinding af kapitelbilleder lader Jellyfin apps vise grafiske menuer for scenevalg. Processen kan være langsom, cpu-intensiv og kræver muligvis adskillige gigabytes af lagerplads. Den køres når videoer opdages og desuden som en planlagt opgave, natligt. Den planlagte opgave kan konfigureres i området for planlagte opgaver. Det anbefales ikke at køre denne opgave under timer med spidsbelastning.", + "ExtractChapterImagesHelp": "Udtrækning af kapitelbilleder giver klienter mulighed for at vise grafiske scenevalgmenuer. Processen kan være langsom, ressourcekrævende og kan kræve flere gigabyte plads. Det kører, når videoer opdages, og også som en planlagt nat opgave. Skemaet kan konfigureres i det planlagte opgaverområde. Det anbefales ikke at køre denne opgave i de mest brugte timer.", "FFmpegSavePathNotFound": "Vi er ikke i stand til at finde FFmpeg via stien du har angivet. FFprobe er også påkrævet og skal findes i samme mappe. Disse komponenter er som regel pakket i den samme download. Kontroller venligst stien og prøv igen.", "FastForward": "Spol fremad", "Favorite": "Favorit", @@ -170,9 +170,9 @@ "FolderTypeBooks": "Bøger", "FolderTypeMovies": "Film", "FolderTypeMusic": "Musik", - "FolderTypeMusicVideos": "Musikvideoer", + "FolderTypeMusicVideos": "Musik Videoer", "FolderTypeTvShows": "TV", - "FolderTypeUnset": "Ikke valgt (blandet indhold)", + "FolderTypeUnset": "Blandet Indhold", "Friday": "Fredag", "Fullscreen": "Fuldskærm", "General": "Generel", @@ -183,7 +183,7 @@ "H264CrfHelp": "Den Konstante Ratefaktor (CRF) er standardindstillingen for X264-koderen. Du kan sætte værdien i mellem 0 og 51, hvor de lavere værdier resulterer i bedre kvalitet (på bekostning af større filstørrelser). Fornuftige værdier er i mellem 18 og 28. Standarden for X264 er 23, så du kan bruge dette som udgangspunkt.", "EncoderPresetHelp": "Vælg en hurtigere værdi for at forbedre ydeevne, eller en langsommere værdi for at forbedre kvalitet.", "HDPrograms": "HD-programmer", - "HardwareAccelerationWarning": "Aktivering af hardwareacceleration kan forårsage ustabilitet i nogle miljøer. Kontroller at dit operativsystem og videodriver er ajourført. Hvis du har problemer med at afspille video efter aktivering af dette, bliver du nød til at skifte tilbage til Auto.", + "HardwareAccelerationWarning": "Aktivering af hardwareacceleration kan forårsage ustabilitet i nogle miljøer. Kontroller at dit operativsystem og videodriver er opdateret. Hvis du har problemer med at afspille video efter aktivering af dette, bliver du nød til at skifte tilbage til Ingen.", "HeaderAccessSchedule": "Adgangsskema", "HeaderAccessScheduleHelp": "Skab et adgangsskema for at begrænse adgangen til bestemte tidsrum.", "HeaderActiveDevices": "Aktive enheder", @@ -197,9 +197,9 @@ "HeaderAdditionalParts": "Andre stier", "HeaderAlert": "Advarsel", "HeaderAllowMediaDeletionFrom": "Tillad Media Sletning Fra", - "HeaderApiKey": "API nøgle", - "HeaderApiKeys": "API nøgler", - "HeaderApiKeysHelp": "Eksterne applikationer skal have en API nøgle for at kunne kommunikere med Jellyfin. Nøgler udstedes ved at logge ind med en Jellyfin konto, eller ved manuelt at tildele applikationen en nøgle.", + "HeaderApiKey": "API Nøgle", + "HeaderApiKeys": "API Nøgler", + "HeaderApiKeysHelp": "Eksterne applikationer skal have en API-nøgle for at kunne kommunikere med Jellyfin. Nøgler udstedes ved at logge ind med en Jellyfin konto, eller ved manuelt at tildele applikationen en nøgle.", "HeaderAudioSettings": "Lydindstillinger", "HeaderAutomaticUpdates": "Automatiske opdateringer", "HeaderBlockItemsWithNoRating": "Klokér titler uden eller med ukendt bedømmelses information:", @@ -266,7 +266,7 @@ "HeaderItems": "Element", "HeaderKeepRecording": "Bevar Optagelse", "HeaderKeepSeries": "Bevar Serie", - "HeaderKodiMetadataHelp": "For at aktivere NFO metadata, rediger et bibliotek i Jellyfin biblioteks redigering og find metadata gemmer sektionen.", + "HeaderKodiMetadataHelp": "For at aktivere eller deaktivere NFO-metadata skal du redigere et bibliotek i Jellyfin-biblioteksopsætningen og finde afsnittet om metadata.", "HeaderLatestEpisodes": "Sidste episoder", "HeaderLatestMedia": "Seneste medier", "HeaderLatestMovies": "Seneste film", @@ -287,7 +287,7 @@ "HeaderMusicVideos": "Musikvideoer", "HeaderMyDevice": "Min Enhed", "HeaderMyMedia": "Mine medier", - "HeaderNewApiKey": "Ny API nøgle", + "HeaderNewApiKey": "Ny API Nøgle", "HeaderNewDevices": "Nye Enheder", "HeaderNextUp": "Næste", "HeaderOnNow": "Vises Nu", @@ -373,7 +373,7 @@ "Images": "Billeder", "ImportFavoriteChannelsHelp": "Hvis aktiveret, importeres der udelukkende kanaler der er markeret som favoritter på tuner-enheden.", "ImportMissingEpisodesHelp": "hvis aktiveret, vil information omkring manglende episoder bliver importeret ind i din Jellyfin-database og blive vist i sæsoner og serier. Dette medfører muligvis længere biblioteksscanninger.", - "InstallingPackage": "Installerer {0}", + "InstallingPackage": "Installerer {0} (version {1})", "InstantMix": "Instant Mix", "ItemCount": "{0} elementer", "Items": "emner", @@ -397,13 +397,13 @@ "LabelAll": "Alle", "LabelAllowHWTranscoding": "Tillad hardware-omkodning", "LabelAllowServerAutoRestart": "Tillad serveren at genstarte automatisk for at påføre opdateringer", - "LabelAllowServerAutoRestartHelp": "Serveren vil kun genstarte i inaktive perioder, når ingen brugere er aktive", + "LabelAllowServerAutoRestartHelp": "Serveren vil kun genstarte i inaktive perioder, når ingen brugere er aktive.", "LabelAllowedRemoteAddresses": "Fjernadgang IP adresse filter:", "LabelAllowedRemoteAddressesMode": "Fjernadgang IP adresse filter mode:", "LabelAppName": "App navn", - "LabelAppNameExample": "F. eks: Sickbeard, NzbDrone", + "LabelAppNameExample": "F. eks: Sickbeard, Sonarr", "LabelArtists": "Artister:", - "LabelArtistsHelp": "Angiv flere ved at sætte mellem dem ;", + "LabelArtistsHelp": "Angiv flere ved at sætte ;", "LabelAudioLanguagePreference": "Foretrukket lydsprog:", "LabelAutomaticallyRefreshInternetMetadataEvery": "Genopfrisk automatisk metadata fra internettet:", "LabelBindToLocalNetworkAddress": "Bind til lokal netværksadresse:", @@ -411,9 +411,9 @@ "LabelBirthDate": "Fødselsdato:", "LabelBirthYear": "Fødselsår:", "LabelBlastMessageInterval": "Interval mellem 'i live' beskeder (sekunder)", - "LabelBlastMessageIntervalHelp": "Angiver intervallet i sekunder mellem serverens 'i live' beskeder.", + "LabelBlastMessageIntervalHelp": "Bestemmer varigheden i sekunder mellem eksplosive levende meddelelser.", "LabelCachePath": "Cachesti:", - "LabelCachePathHelp": "Angiv en brugerdefineret lokation for server cachefiler, så som billeder. Efterlad blankt for at benytte serverens standard.", + "LabelCachePathHelp": "Angiv en brugerdefineret placering for servercache-filer, såsom billeder. Lad være tom for at bruge serverens standard.", "LabelCancelled": "Annulleret", "LabelChannels": "Kanaler:", "LabelCollection": "Samling:", @@ -425,8 +425,8 @@ "LabelCustomCertificatePath": "Brugerdefineret SSL certifikat sti:", "LabelCustomCertificatePathHelp": "Sti til PKCS #12 fil indeholdende et certifikat og privat nøgle for at aktivere TLS understøttelse på et brugerdefineret domæne.", "LabelCustomCss": "Brugerdefineret CSS:", - "LabelCustomCssHelp": "Anvend din egen css til webinterfacet.", - "LabelCustomDeviceDisplayName": "Vist navn:", + "LabelCustomCssHelp": "Anvend din egen stil til webinterfacet.", + "LabelCustomDeviceDisplayName": "Visningsnavn:", "LabelCustomDeviceDisplayNameHelp": "Angiv en brugerdefineret navn. hvis der ikke angives et navn, bruges det navn enheden sender.", "LabelCustomRating": "Brugerdefineret bedømmelse:", "LabelDateAdded": "Dato for tilføjelse:", @@ -444,24 +444,24 @@ "LabelDisplayOrder": "Visningsorden:", "LabelDisplaySpecialsWithinSeasons": "Vis specialepisoder sammen med den sæson de blev sent i", "LabelDownMixAudioScale": "Forøg lydstyrke ved nedmiksning:", - "LabelDownMixAudioScaleHelp": "Forøg lydstyrken når der nedmikses. Sæt værdien til 1 for at beholde den originale lydstyrke.", + "LabelDownMixAudioScaleHelp": "Forøg lydstyrken når der nedmikses. Sæt værdien til en, for at beholde den originale lydstyrke.", "LabelDownloadLanguages": "Hent sprog:", - "LabelDropImageHere": "Smid billede her.", + "LabelDropImageHere": "Drop billede her, eller Tryk for at vælge.", "LabelEasyPinCode": "Pinkode:", "LabelEmbedAlbumArtDidl": "Indsæt album billede i DIDL", "LabelEmbedAlbumArtDidlHelp": "Nogle enheder foretrækker denne metode til overførsel af album billede. Andre kan fejle når dette er aktiveret.", "LabelEnableAutomaticPortMap": "Aktiver automatisk port mapping", - "LabelEnableAutomaticPortMapHelp": "Forsøg at mappe den offentlige port til den lokale port med uPnP. Dette virker ikke med alle routere.", + "LabelEnableAutomaticPortMapHelp": "Forsøg at mappe den offentlige port til den lokale port med uPnP. Dette virker ikke med alle routere. Ændringerne vil først træde i kræft et en server genstart.", "LabelEnableBlastAliveMessages": "Masseudsend 'i live' beskeder", "LabelEnableBlastAliveMessagesHelp": "Aktiver dette hvis UPnP enheder har problemer med forbindelsen til serveren.", "LabelEnableDlnaClientDiscoveryInterval": "Interval for klientsøgning (sekunder)", "LabelEnableDlnaClientDiscoveryIntervalHelp": "angiver intervallet i sekunder mellem Jellyfins SSDP søgninger.", "LabelEnableDlnaDebugLogging": "Aktiver debu logning af DLNA", - "LabelEnableDlnaDebugLoggingHelp": "Dette generer meget store logfiler, og er kun anbefalet at bruge til fejlfindingsformål.", + "LabelEnableDlnaDebugLoggingHelp": "Opret store logfiler og skal kun bruges efter behov til fejlfinding.", "LabelEnableDlnaPlayTo": "Aktiver DLNA \"Afspil Til\"", - "LabelEnableDlnaPlayToHelp": "Jellyfin kan finde enheder i dit netværk og tilbyde at kontrollere dem.", - "LabelEnableDlnaServer": "Aktiver DNLA server", - "LabelEnableDlnaServerHelp": "Tillader UPnP enheder i dit netværk at gennemse og afspille Jellyfins indhold.", + "LabelEnableDlnaPlayToHelp": "Find enheder i dit netværk og tilbyd at fjernstyre dem.", + "LabelEnableDlnaServer": "Aktiver DLNA server", + "LabelEnableDlnaServerHelp": "Tillader UPnP enheder i dit netværk at gennemse og afspille indhold.", "LabelEnableRealtimeMonitor": "Aktiver realtidsovervågning", "LabelEnableRealtimeMonitorHelp": "Ændringer vil blive behandlet øjeblikkeligt på understøttede filsystemer.", "LabelEnableSingleImageInDidlLimit": "Begræns til et enkelt indlejret billede", @@ -471,56 +471,56 @@ "LabelEvent": "Hændelse:", "LabelEveryXMinutes": "Hver:", "LabelExtractChaptersDuringLibraryScan": "Udtræk kapitelbilleder under biblioteksskanning", - "LabelExtractChaptersDuringLibraryScanHelp": "Aktiver dette for at udtrække kapitelbillleder mens videofiler bliver importeret under biblioteksskanningen. Hvi det ikke er aktiveret, bliver de udtrukket når den planlagte opgave kapitelbilleder kører, og lader den almindelige biblioteksskanning afslutte hurtigere.", + "LabelExtractChaptersDuringLibraryScanHelp": "Generere kapitelbillleder mens videofiler bliver importeret under biblioteksskanningen. Alternativt bliver de udtrukket når den planlagte opgave kapitelbilleder kører, hvilket tillader den almindelige biblioteksskanning at afslutte hurtigere.", "LabelFailed": "Fejlet", - "LabelFileOrUrl": "Fil eller url:", + "LabelFileOrUrl": "Fil eller URL:", "LabelFinish": "Afslut", "LabelForgotPasswordUsernameHelp": "Indtast dit brugernavn, hvis du kan huske det.", "LabelFriendlyName": "System venligt navn:", - "LabelServerNameHelp": "Dette navn bruges til at identificere serveren. Hvis det ikke udfyldes, bruges computerens navn.", + "LabelServerNameHelp": "Dette navn bruges til at identificere serveren. Som udgangspunkt anvendes computerens navn.", "LabelGroupMoviesIntoCollections": "Grupper film i samlinger", "LabelGroupMoviesIntoCollectionsHelp": "Film i samlinger vil blive vist som en samlet enhed i filmlister.", "LabelH264Crf": "H264-kodning CRF:", "LabelEncoderPreset": "Forudindstillet H264-kodning:", "LabelHardwareAccelerationType": "Hardwareacceleration:", - "LabelHardwareAccelerationTypeHelp": "Kun tilgængelig for understøttede systemer.", + "LabelHardwareAccelerationTypeHelp": "Hardwareacceleration kræver yderligere konfiguration.", "LabelHttpsPort": "Lokalt HTTPS portnummer:", - "LabelHttpsPortHelp": "Det portnummer Jellyfins https-server bruger.", - "LabelIconMaxHeight": "Max højde på ikoner:", - "LabelIconMaxHeightHelp": "Maksimumopløsningen på ikoner der bliver vist med upnp:icon", - "LabelIconMaxWidth": "Max bredde på ikoner:", - "LabelIconMaxWidthHelp": "Maksimumopløsningen på ikoner der bliver vist med upnp:icon", + "LabelHttpsPortHelp": "Det TCP-portnummer, som Jellyfins HTTPS-server skal benytte.", + "LabelIconMaxHeight": "Maximal højde af ikoner:", + "LabelIconMaxHeightHelp": "Maksimalopløsningen af ikoner, der bliver vist med upnp:icon.", + "LabelIconMaxWidth": "Maximal bredde på ikoner:", + "LabelIconMaxWidthHelp": "Maksimalopløsningen på ikoner der bliver vist med upnp:icon.", "LabelIdentificationFieldHelp": "En case-insensitive substring eller regex ekspression.", "LabelImageFetchersHelp": "Aktiver og ranger dine fortrukne billede-hentere i en prioriteret rækkefølge.", "LabelImageType": "Billedtype:", "LabelImportOnlyFavoriteChannels": "Begræns til kanaler der er markeret som favoritter", "LabelInNetworkSignInWithEasyPassword": "Tillad login inden for eget netværk med pinkode", - "LabelInNetworkSignInWithEasyPasswordHelp": "Aktiver dette for at loge ind i Jellyfin apps med din pinkode inden for dit eget netværk. Din almindelige adgangskode skal du så kun bruge når du ikke er hjemme. Hvis pinkoden er tom, kan du logge ind uden adgangskode inden for dit eget netværk.", + "LabelInNetworkSignInWithEasyPasswordHelp": "Brug den lette pinkode til at logge ind på klienter i dit lokale netværk. Din almindelige adgangskode er kun nødvendig hjemmefra. Hvis pinkoden efterlades tom, behøver du ikke en adgangskode på dit hjemmenetværk.", "LabelKeepUpTo": "Bevar op til:", "LabelKidsCategories": "Børnekategorier:", "LabelKodiMetadataDateFormat": "Format for udgivelsesdato:", - "LabelKodiMetadataDateFormatHelp": "Alle datoer i NFO-filer vil blive læst og skrevet med dette format.", - "LabelKodiMetadataEnableExtraThumbs": "kopier extrafanart til extrathumbs", + "LabelKodiMetadataDateFormatHelp": "Alle datoer i NFO-filer vil blive analyseret med dette format.", + "LabelKodiMetadataEnableExtraThumbs": "Kopier ekstra fanart til extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Ved hentning af billeder, kan de gemmes i både extrafanart og extrathumbs. Dette giver maksimal Kodi skin kompatibilitet.", "LabelKodiMetadataEnablePathSubstitution": "Aktiver stisubstitution", "LabelKodiMetadataEnablePathSubstitutionHelp": "Aktiverer stisubstitution for billedstier med serverens stisubstitutionsindstillinger.", "LabelKodiMetadataSaveImagePaths": "Gem stier til billeder i Nfo-filer", "LabelKodiMetadataSaveImagePathsHelp": "Dette er anbefalet hvis du har billedfiler med navne der ikke lever op til Kodis retningslinjer.", - "LabelKodiMetadataUser": "Gem brugers set data til NFO'er for:", - "LabelKodiMetadataUserHelp": "Aktiver dette for at komme set data til NFO filer som andre programmer kan bruge.", + "LabelKodiMetadataUser": "Gem brugerdata til NFO-filer til:", + "LabelKodiMetadataUserHelp": "Gem overvågningsdata til NFO-filer til andre applikationer.", "LabelLanNetworks": "LAN netwærk:", "LabelLanguage": "Sprog:", "LabelLineup": "Opstilling:", - "LabelLocalHttpServerPortNumber": "Lokalt http portnummer:", - "LabelLocalHttpServerPortNumberHelp": "Det portnummer Jellyfins http-server bruger.", + "LabelLocalHttpServerPortNumber": "Lokalt HTTP-portnummer:", + "LabelLocalHttpServerPortNumberHelp": "Det TCP-portnummer, som Jellyfin's HTTP-server skal binde til.", "LabelLockItemToPreventChanges": "Lås for at undgå fremtidige ændringer", "LabelLoginDisclaimer": "Login ansvarsfraskrivelse:", - "LabelLoginDisclaimerHelp": "Dette bliver vist i bunden af loginsiden.", - "LabelManufacturer": "Producent", - "LabelManufacturerUrl": "Producent url", + "LabelLoginDisclaimerHelp": "En besked, som vises i bunden af loginsiden.", + "LabelManufacturer": "Producent:", + "LabelManufacturerUrl": "Producentens URL", "LabelMaxBackdropsPerItem": "Maksimum antal af bagtæpper per element:", "LabelMaxParentalRating": "Højst tilladte aldersgrænse:", - "LabelMaxResumePercentage": "Maks. fortsæt procentdel:", + "LabelMaxResumePercentage": "Maksimal fortsæt procentdel:", "LabelMaxResumePercentageHelp": "Medier anses som fuldt afspillet, hvis de stoppes efter denne tid.", "LabelMaxScreenshotsPerItem": "Maksimum antal af skærmbilleder per element:", "LabelMaxStreamingBitrate": "Maks. streaming kvalitet:", @@ -538,9 +538,9 @@ "LabelMethod": "Metode:", "LabelMinBackdropDownloadWidth": "Minimum baggrundsbillede bredde:", "LabelMinResumeDuration": "Min. fortsæt tidsrum (sekunder):", - "LabelMinResumeDurationHelp": "Medier med kortere afspilningstid en denne kan ikke fortsættes.", - "LabelMinResumePercentage": "Min. fortsæt procentdel:", - "LabelMinResumePercentageHelp": "Medier anses om ikke afspillet, hvis de stoppes inden denne tid.", + "LabelMinResumeDurationHelp": "Den korteste videolængde i sekunder, der gemmer afspilningsplacering og giver dig mulighed for at genoptage.", + "LabelMinResumePercentage": "Minimal fortsæt procentdel:", + "LabelMinResumePercentageHelp": "Medier anses som ikke afspillede, hvis de stoppes inden denne tid.", "LabelMinScreenshotDownloadWidth": "Minimum skærmbillede bredde:", "LabelModelDescription": "Modelbeskrivelse", "LabelModelName": "Modelnavn", @@ -548,10 +548,10 @@ "LabelMonitorUsers": "Overvåg aktivitet fra:", "LabelMovieCategories": "Filmkategorier:", "LabelMoviePrefix": "Film-præfiks:", - "LabelMoviePrefixHelp": "Angiv venligst her hvis der tilføjes et præfiks til filmtitler, så Jellyfin kan håndtere det korrekt.", + "LabelMoviePrefixHelp": "Angiv venligst her hvis der tilføjes et præfiks til filmtitler, så serveren kan håndtere det korrekt.", "LabelMovieRecordingPath": "Film afspilningssti (valgfri):", "LabelMusicStreamingTranscodingBitrate": "Bitrate for musiktranskodning:", - "LabelMusicStreamingTranscodingBitrateHelp": "Angiv en maksimal bitrate når der streames musik", + "LabelMusicStreamingTranscodingBitrateHelp": "Angiv en maksimal bitrate når der streames musik.", "LabelName": "Navn:", "LabelNewName": "Nyt navn:", "LabelNewPassword": "Ny kode:", @@ -590,10 +590,10 @@ "LabelProtocol": "Protokol:", "LabelProtocolInfo": "Protokolinformation:", "LabelProtocolInfoHelp": "Den værdi der bruges til svar på GetProtocolInfo-forespørgsler fra enheden.", - "LabelPublicHttpPort": "Offentligt http portnummer:", - "LabelPublicHttpPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale http portnummer.", - "LabelPublicHttpsPort": "Offentligt https portnummer:", - "LabelPublicHttpsPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale https portnummer.", + "LabelPublicHttpPort": "Offentligt HTTP-portnummer:", + "LabelPublicHttpPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale HTTP-portnummer.", + "LabelPublicHttpsPort": "Offentligt HTTPS portnummer:", + "LabelPublicHttpsPortHelp": "Det offentlige portnummer som bliver knyttet til det lokale HTTPS portnummer.", "LabelReadHowYouCanContribute": "Lær hvordan du kan bidrage.", "LabelRecord": "Optag:", "LabelRecordingPath": "Standard afspilningssti:", @@ -614,7 +614,7 @@ "LabelSerialNumber": "Serienummer", "LabelSeriesRecordingPath": "Serier afspilningssti (valgfri):", "LabelServerHost": "Vært:", - "LabelServerHostHelp": "F. eks: 192.168.1.100 eller https://myserver.com", + "LabelServerHostHelp": "F. eks: 192.168.1.100:8096 eller https://myserver.com", "LabelSimultaneousConnectionLimit": "samtidige stream begrænsning:", "LabelSkipIfAudioTrackPresent": "Undlad hvis standardlydsporet er det samme sprog", "LabelSkipIfAudioTrackPresentHelp": "Angiv ikke dette for at sikre at alle videoer har undertekster, uanset hvilket sprog lydsporet anvender.", @@ -647,7 +647,7 @@ "LabelTranscodingTempPathHelp": "Definér en bugerdefineret sti til transkodede filer til klienter. Lad den stå tom for at bruge standardmappen i serverens datamappe.", "LabelTranscodingTemporaryFiles": "Midlertidige filer til omkodning:", "LabelTranscodingThreadCount": "Antal af omkodningstråde:", - "LabelTranscodingThreadCountHelp": "Vælg det maksimale antal af tråde der bruges under omkodning. Reduktion af antallet af tråde sænker cpu-forbrug, men resulterer muligvis i at konverteringer ikke foregår hurtigt nok til en jævn afspilning.", + "LabelTranscodingThreadCountHelp": "Vælg det maksimale antal af tråde der bruges under transcoding. Reduktion af antallet af tråde sænker CPU-forbrug, men resulterer muligvis i at konverteringer ikke foregår hurtigt nok til en jævn afspilning.", "LabelTriggerType": "Udløsertype:", "LabelTunerIpAddress": "IP-adresse for Tuner:", "LabelTunerType": "Tunertype:", @@ -707,37 +707,37 @@ "MessageConfirmRemoveMediaLocation": "Er du sikker på du ønsker at fjerne denne lokalisation?", "MessageConfirmRestart": "Er du sikker på du ønsker at genstarte Jellyfin?", "MessageConfirmRevokeApiKey": "Er du sikker på du ønsker at invalidere denne api nøgle? Applikationens forbindelse til Jellyfin vil blive afbrudt øjeblikkeligt.", - "MessageConfirmShutdown": "Er du sikker på du ønsker at lukke Jellyfin?", + "MessageConfirmShutdown": "Er du sikker på du ønsker at slukke for serveren?", "MessageContactAdminToResetPassword": "Kontakt venligst din systemadministrator for at nulstille din adgangskode.", "MessageCreateAccountAt": "Opret en konto hos {0}", "MessageDeleteTaskTrigger": "Er du sikker på du ønsker at slette denne task trigger?", "MessageDirectoryPickerBSDInstruction": "For BSD skal du muligvis konfigurere lager i dit FreeNAS Jail, før Jellyfin kan tilgå det.", "MessageDirectoryPickerInstruction": "Netværksstier kan indtastes manuelt i tilfælde af at netværksknappen ikke kan lokalisere dine enheder. Foreksempel, {0} eller {1}.", - "MessageDirectoryPickerLinuxInstruction": "For Linux på Arch Linux, CentOS, Debian, Fedora, OpenSuse eller Ubuntu skal du give Jellyfin-systembrugeren minimum læseadgang til dine lagerlokationer.", + "MessageDirectoryPickerLinuxInstruction": "For Linux på Arch Linux, CentOS, Debian, Fedora, openSUSE eller Ubuntu, skal du give servicebrugeren mindst læseadgang til dine lagerpladser.", "MessageDownloadQueued": "Download sat i kø.", "MessageEnablingOptionLongerScans": "Aktivering af denne indstilling kan resultere i væsentlig længere biblioteks skan.", "MessageFileReadError": "Der opstod en fejl i forsøget på at læse filen.", "MessageForgotPasswordFileCreated": "Den følgende fil er blevet oprettet på din server og indeholder instruktioner vedrørende hvordan du skal fortsætte:", "MessageForgotPasswordInNetworkRequired": "Prøv igen inde i dit hjemmenetværk for at igangsætte nulstilling af din adgangskode.", - "MessageInstallPluginFromApp": "Dette plugin skal være installeret inde i den app du ønsker at benytte det fra.", + "MessageInstallPluginFromApp": "Dette plugin skal installeres fra den app, du har til hensigt at bruge det i.", "MessageInvalidForgotPasswordPin": "En ugyldig eller udløbet pinkode blev indtastet. Prøv igen.", "MessageInvalidUser": "Ukendt brugernavn eller adgangskode. Prøv igen.", "MessageItemSaved": "Element gemt.", "MessageItemsAdded": "Emne tilføjet.", - "MessageLeaveEmptyToInherit": "Efterlad tom for at arve indstillinger fra en overliggende post eller den globale standardværdi.", + "MessageLeaveEmptyToInherit": "Lad være tom for at arve indstillinger fra et overordnet element eller den globale standardværdi.", "MessageNoAvailablePlugins": "Ingen tilgængelige plugins.", "MessageNoMovieSuggestionsAvailable": "Ingen filmforslag er tilgængelige. Begynd at se og vurder dine film, og kom tilbage for at se dine anbefalinger.", "MessageNoPluginsInstalled": "Du har ingen plugins installeret.", "MessageNoTrailersFound": "Ingen trailere fundet. Installer Trailer kanalen for at tilføje et bibliotek med trailere fra internettet.", "MessageNothingHere": "Her er ingenting.", - "MessagePasswordResetForUsers": "Adgangskoder blev fjernet for følgende brugere. For at logge ind, skal der benyttes en blank adgangskode.", + "MessagePasswordResetForUsers": "Følgende brugere har fået nulstillet deres adgangskoder. De kan nu logge på med de pinkoder, der blev brugt til at udføre nulstillingen.", "MessagePleaseEnsureInternetMetadata": "Sørg venligst for at hentning af metadata fra internettet er aktiveret.", "MessagePleaseWait": "Vent venligst. Dette kan tage et minut.", "MessagePluginConfigurationRequiresLocalAccess": "For at konfigurerer dette plugin log da venligst direkte ind på din lokale server.", "MessagePluginInstallDisclaimer": "Plugins fremstillet af medlemmer fra Jellyfin-fællesskabet er en alle tiders måde at forbedre din oplevelse af Jellyfin med yderligere features og fordele. Før installation, bedes du venligst være opmærksom på de effekter de kan have på din Jellyfin Server; så som lange scantider på biblioteker, yderligere baggrundsbehandling og forringet systemstabilitet.", "MessageReenableUser": "Se nedenfor om genaktivering", "MessageSettingsSaved": "Indstillinger er gemt.", - "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Følgende medielokationer bliver fjernet fra dit Jellyfin-bibliotek:", + "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Følgende medieplaceringer fjernes fra dit bibliotek:", "MessageUnableToConnectToServer": "Vi kan ikke forbinde til den valgte server på nuværende tidspunkt. Sikrer dig venligst at serveren kører og prøv igen.", "MessageUnsetContentHelp": "Indhold vil blive vist som almindelige mapper. For det bedste resultat benyt metadata manageren til at vælge indholdstypen i undermapper.", "MessageYouHaveVersionInstalled": "Du har version {0} installeret.", @@ -747,10 +747,10 @@ "MinutesBefore": "minutter før", "Monday": "Mandag", "MoreFromValue": "Mere fra {0}", - "MoreUsersCanBeAddedLater": "Flere brugere kan tilføjes senere i betjeningspanelet.", + "MoreUsersCanBeAddedLater": "Flere brugere kan tilføjes senere fra dashboardet.", "MoveLeft": "Flyt mod venstre", "MoveRight": "Flyt mod højre", - "MovieLibraryHelp": "Gennemse {0}Jellyfin film navngivningsguiden{1}.", + "MovieLibraryHelp": "Gennemse {0}film navngivningsguiden{1}.", "Movies": "Film", "Mute": "Afbryd lyd", "MySubtitles": "Mine Undertekster", @@ -782,7 +782,7 @@ "OptionAllowMediaPlaybackTranscodingHelp": "At begrænse adgang til omkodning kan forårsage afspilningsfejl i Jellyfin apps på grund af usupporterede medie formater.", "OptionAllowRemoteControlOthers": "Tillad fjernstyring af andre brugere", "OptionAllowRemoteSharedDevices": "Tillad fjernstyring af delte enheder", - "OptionAllowRemoteSharedDevicesHelp": "DLNA-enheder er delte indtil en bruger begynder at bruge den.", + "OptionAllowRemoteSharedDevicesHelp": "DLNA-enheder betragtes som delt, indtil en bruger begynder at kontrollere dem.", "OptionAllowSyncTranscoding": "Tillad medie hentning og synkronisering der kræver omkodning", "OptionAllowUserToManageServer": "Tillad denne bruger at administrere serveren", "OptionAllowVideoPlaybackRemuxing": "Tillad videoafspilning som kræver konvertering uden omkodning", @@ -811,13 +811,13 @@ "OptionDisableUserHelp": "Hvis deaktiveret vil serveren ikke tillade forbindelser fra denne bruger. Eksisterende forbindelser vil blive afbrudt øjeblikkeligt.", "OptionDislikes": "Ikke-Lide", "OptionDisplayFolderView": "Få vist en mappevisning til at se enkle mediemapper", - "OptionDisplayFolderViewHelp": "Hvis aktiveret, vil Jellyfin apps vise en Mappekategori ved siden af dine mediebiblioteker. Dette er brugbart, hvis du vil have vist enkle mappevisninger.", + "OptionDisplayFolderViewHelp": "Vis mapper sammen med dine andre mediebiblioteker. Dette kan være nyttigt, hvis du gerne vil have en almindelig mappevisning.", "OptionDownloadArtImage": "Billede", "OptionDownloadBackImage": "Bagside", "OptionDownloadBoxImage": "Boks", "OptionDownloadDiscImage": "Disk", "OptionDownloadImagesInAdvance": "Download billeder på forhånd", - "OptionDownloadImagesInAdvanceHelp": "Som standard downloades billeder kun når de anmodes af en Jellyfin app. Aktiver denne indstilling for at downloade alle billeder på forhånd, i mens nyt medie importeres. Dette resulterer muligvis i længere scanninger af bibliotek.", + "OptionDownloadImagesInAdvanceHelp": "Som standard downloades de fleste billeder kun, når de anmodes fra en Jellyfin-app. Aktivér denne mulighed for at downloade alle billeder på forhånd, da nye medier importeres. Dette kan forårsage betydeligt længere biblioteksscanninger.", "OptionDownloadPrimaryImage": "Primær", "OptionDownloadThumbImage": "Miniature", "OptionDvd": "DVD", @@ -826,7 +826,7 @@ "OptionEnableAccessToAllChannels": "Tillad adgang til alle kanaler", "OptionEnableAccessToAllLibraries": "Tillad adgang til alle biblioteker", "OptionEnableExternalContentInSuggestions": "Aktiver eksternt indhold i anbefalinger", - "OptionEnableExternalContentInSuggestionsHelp": "Tillad at internet-trailers og live-tv-programmer bliver inkluderet i det anbefalede indhold.", + "OptionEnableExternalContentInSuggestionsHelp": "Tillad at internet-trailers og live TV programmer bliver inkluderet i det anbefalede indhold.", "OptionEnableForAllTuners": "Aktiver for alle tuner-enheder", "OptionEnableM2tsMode": "Aktiver M2ts tilstand", "OptionEnableM2tsModeHelp": "Aktiver M2ts tilstand når der omkodes til mpegts.", @@ -844,8 +844,8 @@ "OptionHasThemeVideo": "Temavideo", "OptionHideUser": "Vis ikke denne bruger på loginsiden", "OptionHideUserFromLoginHelp": "Nyttigt for private kontoer eller skjulte administratorkontoer. Brugeren skal logge ind ved at skive sit brugernavn og adgangskode.", - "OptionHlsSegmentedSubtitles": "Hls segmented undertekster", - "OptionHomeVideos": "Hjemmevideoer og billeder", + "OptionHlsSegmentedSubtitles": "HLS segmenterede undertekster", + "OptionHomeVideos": "Billeder", "OptionIgnoreTranscodeByteRangeRequests": "Ignorer forespørgsler vedrørende transcode byte interval", "OptionIgnoreTranscodeByteRangeRequestsHelp": "Hvis aktiveret vil disse forespørgsler blive efterkommet, men byte range headeren ignoreret.", "OptionImdbRating": "IMDB bedømmelse", @@ -883,7 +883,7 @@ "OptionThursday": "Torsdag", "OptionTrackName": "Nummerets navn", "OptionTuesday": "Tirsdag", - "OptionTvdbRating": "Tvdb bedømmelse", + "OptionTvdbRating": "TVDB bedømmelse", "OptionUnairedEpisode": "Ikke sendte episoder", "OptionUnplayed": "Ikke afspillet", "OptionWakeFromSleep": "Vågner fra dvale", @@ -893,9 +893,9 @@ "OptionWeekly": "Ugentlig", "OriginalAirDateValue": "Originalt sendt: {0}", "Overview": "Overblik", - "PackageInstallCancelled": "{0} installation afbrudt.", - "PackageInstallCompleted": "{0} installation udført.", - "PackageInstallFailed": "{0} installationen mislykkedes.", + "PackageInstallCancelled": "{0} (version {1}) installation annulleret.", + "PackageInstallCompleted": "{0} (version {1}) installation udført.", + "PackageInstallFailed": "{0} (version {1}) installationen mislykkedes.", "ParentalRating": "Parental Rating", "PasswordMatchError": "Adgangskode og bekræft adgangskode skal være ens.", "PasswordResetComplete": "Adgangskoden er blevet nulstillet.", @@ -913,7 +913,7 @@ "Played": "Afspillet", "PleaseAddAtLeastOneFolder": "Tilføj venligst som minimum en enkelt mappe til dette bibliotek ved at klikke på Tilføj-knappen.", "PleaseConfirmPluginInstallation": "Klik venligst OK for at bekræfte at du har læst ovenstående og ønsker at fortsætte med installationen af plugin.", - "PleaseEnterNameOrId": "Indtast venligst et navn eller eksternt Id.", + "PleaseEnterNameOrId": "Indtast venligst et navn eller eksternt ID.", "PleaseRestartServerName": "Genstart venligst Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Vælg venligst mindst to elementer.", "PluginInstalledMessage": "Plugin blev installeret med success. Jellyfin serveren skal genstartes for at aktivere det.", @@ -1025,7 +1025,7 @@ "TabProfiles": "Profiler", "TabRecordings": "Optagelser", "TabResponses": "Svar", - "TabResumeSettings": "Indstillinger for Genoptag", + "TabResumeSettings": "Genoptag", "TabScheduledTasks": "Planlagte opgaver", "TabSeries": "Serier", "TabSettings": "Indstillinger", @@ -1044,13 +1044,13 @@ "TitlePlayback": "Afspilning", "TrackCount": "{0} numre", "Tuesday": "Tirsdag", - "TvLibraryHelp": "Gennemse {0}Jellyfin TV navngivningsguiden{1}.", + "TvLibraryHelp": "Gennemgå {0} TV-navneguiden {1}.", "UninstallPluginConfirmation": "Er du sikker på du vil afinstallere {0}?", "UninstallPluginHeader": "Afinstaller plugin", "Unmute": "Genoptag lyd", "Unrated": "Ingen bedømmelse", - "UserAgentHelp": "Angiv en brugerdefineret user-agent http header, hvis nødvendigt.", - "UserProfilesIntro": "Jellyfin har indbygget understøttelse af brugerprofiler. Dette giver hver bruger sine egne indstillinger for visning, afspilningsstatus og forældrekontrol.", + "UserAgentHelp": "Angiv en brugerdefineret bruger-agent HTTP-header.", + "UserProfilesIntro": "Jellyfin inkluderer support til brugerprofiler med granuleret displayindstillinger, afspilningstilstand og forældrekontrol.", "ValueAlbumCount": "{0} album", "ValueAudioCodec": "Lyd codec: {0}", "ValueConditions": "Forhold: {0}", @@ -1072,13 +1072,13 @@ "ViewPlaybackInfo": "Vis afspilnings information", "Wednesday": "Onsdag", "WelcomeToProject": "Velkommen til Jellyfin!", - "WizardCompleted": "Det er alt vi behøver for nu. Jellyfin er begyndt at indsamle information omkring dit mediebibliotek. Tjek nogle af vores apps og klik derefter på Færdig for at se Server betjeningspanelet.", + "WizardCompleted": "Det er alt, hvad vi har brug for nu. Jellyfin er begyndt at indsamle information om dit mediebibliotek. Se nogle af vores apps, og klik derefter på Udfør for at se Dashboard.", "Writer": "Forfatter", - "XmlDocumentAttributeListHelp": "Disse attributter bliver tilføjet til rodelementet i alle XML svar.", + "XmlDocumentAttributeListHelp": "Disse attributter anvendes til rodelementet i hvert XML-svar.", "XmlTvKidsCategoriesHelp": "Programmer med disse kategorier bliver vist som programmer for børn. Adskil flere med '|'.", "XmlTvMovieCategoriesHelp": "Programmer med disse kategorier bliver vist som film. Adskil flere med '|'.", "XmlTvNewsCategoriesHelp": "Programmer med disse kategorier bliver vist som nyhedsprogrammer. Adskil flere med '|'.", - "XmlTvPathHelp": "En sti til en xml tv-fil. Jellyfin læser denne fil og kontrollerer periodisk for opdateringer. Du er ansvarlig for at oprette og opdatere filen.", + "XmlTvPathHelp": "En sti til en XMLTV fil. Jellyfin læser denne fil og kontrollerer periodisk for opdateringer. Du er ansvarlig for at oprette og opdatere filen.", "XmlTvSportsCategoriesHelp": "Programmer med disse kategorier bliver vist som sportsprogrammer. Adskil flere med '|'.", "Yesterday": "I går", "AirDate": "Luftdata", @@ -1100,7 +1100,7 @@ "Shows": "Serier", "Songs": "Sange", "AndroidUnlockRestoreHelp": "For at gendanne dit tidligere køb skal du sørge for, at du er logget ind på enheden med den samme Google- eller Amazon-konto, som oprindeligt gjorde købet. Sørg for, at app store er aktiveret og ikke begrænset af forældrekontrol, og sørg for, at du har en aktiv internetforbindelse. Du skal kun gøre dette én gang for at gendanne dit tidligere køb.", - "AnyLanguage": "Ethvert sprog", + "AnyLanguage": "Hvilken som helst sprog", "Art": "Kunst", "Ascending": "Stigende", "AudioBitDepthNotSupported": "Lyd bit dybde ikke understøttet", @@ -1121,7 +1121,7 @@ "Blacklist": "Blackliste", "Box": "Boks", "BoxRear": "Boks (bagside)", - "BurnSubtitlesHelp": "Bestemmer om serveren skal brænde underteksterne ind i videoen når den konverterer baseret på undertekstformatet. Det vil øge serverens ydeevne ikke at brænde underteksterne i filen. Vælg Automatisk for at brænde billedbaserede formater (VOBSUB, PGS, SUB/IDX, osv) og nogle ASS/SSA undertekster.", + "BurnSubtitlesHelp": "Bestemmer om serveren skal brænde undertekster, når der afspilles transcoding videoer. Undgå dette vil forbedre ydelsen meget. Vælg Auto for at brænde billedbaserede formater (VOBSUB, PGS, SUB, IDX) og bestemte ASS- eller SSA-undertekster.", "ButtonFilter": "Filter", "ButtonGuide": "Vejledning", "ButtonInfo": "Information", @@ -1174,14 +1174,14 @@ "DisplayInOtherHomeScreenSections": "Visning på hjemmeskærm sektioner som seneste medier og se videre", "DisplayMissingEpisodesWithinSeasons": "Vis manglende afsnit inde i sæsoner", "DisplayMissingEpisodesWithinSeasonsHelp": "Dette skal også være aktiveret for TV biblioteker i serverens indstillinger.", - "DisplayModeHelp": "Vælg skærmtypen du kører Jellyfin på.", + "DisplayModeHelp": "Vælg det ønskede tema for grænsefladen.", "Down": "Ned", "DownloadItemLimitHelp": "Valgfri. Sæt en begrænsning på antallet af ting der vil blive hentet.", "Downloaded": "Hentet", "DownloadingDots": "Henter...", "Downloads": "Hentninger", "DownloadsValue": "{0} hentninger", - "DropShadow": "Drop skygge", + "DropShadow": "Drop Skygge", "DvrFeatureDescription": "Tidsindstil individuelle TV optagelser, serie optagelser, og mere med Jellyfin DVR.", "EditMetadata": "Redigér metadata", "EnableBackdrops": "Baggrundsbilleder", @@ -1201,7 +1201,7 @@ "ErrorAddingJellyfinConnectAccount1": "Der skete en fejl ved tilføjelsen af Jellyfin Connect kontoen. Har du lavet en Jellyfin konto? Registrer dig på {0}.", "ErrorAddingJellyfinConnectAccount2": "Hvis du stadig har et problem, så send venligst en email til {0} fra den email adresse tilknyttet Jellyfin kontoen.", "ErrorDeletingItem": "Der skete en fejl ved sletningen af mediet fra Jellyfin Server. Tjek venligst at Jellyfin Server har skrive adgang til mediemappen og prøv igen.", - "ExtraLarge": "Ekstra stor", + "ExtraLarge": "Ekstra Stor", "Extras": "Bonusmateriale", "Features": "Funktioner", "Filters": "Filtre", @@ -1270,18 +1270,18 @@ "LabelArtist": "Kunstner", "LabelAudio": "Lyd", "LabelBitrateMbps": "Bitrate (Mbps):", - "LabelBlockContentWithTags": "Blokér filer med mærkerne:", + "LabelBlockContentWithTags": "Blokér filer med etiketter:", "LabelBurnSubtitles": "Brænd undertekster:", "LabelCache": "Cache:", "LabelCertificatePassword": "Adgangskode til certifikat:", - "LabelCertificatePasswordHelp": "Hvis dit certifikat kræver en adgangskode, skriv det benligst her.", + "LabelCertificatePasswordHelp": "Hvis dit certifikat kræver en adgangskode, skriv det venligst her.", "LabelConvertTo": "Konvertér til:", "LabelDashboardTheme": "Server dashboard tema:", "LabelDateTimeLocale": "Dato og tid område:", "LabelDefaultScreen": "Standard skærm:", "LabelDisplayLanguage": "Visningssprog:", "LabelDisplayLanguageHelp": "Oversættelse af Jellyfin er et vedvarende projekt.", - "LabelDisplayMode": "Visningsmodus:", + "LabelDisplayMode": "Visningstilstand:", "LabelDropShadow": "Drop skygge:", "LabelDynamicExternalId": "{0} ID:", "LabelEmail": "Email:", @@ -1297,7 +1297,7 @@ "LabelMaxBitrate": "Maks bitrate:", "LabelMaxChromecastBitrate": "Chromecast streaming kvalitet:", "LabelMetadata": "Metadata:", - "LabelModelUrl": "Model link", + "LabelModelUrl": "Model URL", "LabelPreferredSubtitleLanguage": "Foretrukket undertekst sprog:", "LabelProfileCodecs": "Codecs:", "LabelProfileContainer": "Beholder:", @@ -1378,7 +1378,7 @@ "Off": "Fra", "OnlyForcedSubtitles": "Kun tvungne undertekster", "OnlyForcedSubtitlesHelp": "Kun undertekster markeret som tvungne vil blive indlæst.", - "OnlyImageFormats": "Kun billedformater (VOBSUB, PGS, SUB, etc)", + "OnlyImageFormats": "Kun billedformater (VOBSUB, PGS, SUB)", "Option2Player": "2+", "Option3D": "3D", "Option3Player": "3+", @@ -1420,7 +1420,7 @@ "PlayCount": "Afspilninger", "PlayNext": "Afspil næste", "PlayNextEpisodeAutomatically": "Afspil næste afsnit automatisk", - "PlaybackErrorNoCompatibleStream": "Ingen kompatible streams er tilgængelige. Prøv venligst igen senere eller kontakt din system administrator for detaljer.", + "PlaybackErrorNoCompatibleStream": "Denne klient er ikke kompatibel med medierne, og serveren sender ikke et kompatibelt medieformat.", "PlaybackErrorNotAllowed": "Du har ikke adgang til at afspille dette indhold. Kontakt venligst system administratoren for detaljer.", "PlaybackErrorPlaceHolder": "Indlæs venligst disken for at afspille denne video.", "PlaybackSettings": "Afspilningsindstillinger", @@ -1436,7 +1436,7 @@ "RefFramesNotSupported": "Antal af video reference billeder ikke understøttet", "RefreshMetadata": "Genopfrisk metadata", "RepeatAll": "Gentag alle", - "RepeatMode": "Gentagelsesmode", + "RepeatMode": "Gentagelses tilstand", "RepeatOne": "Gentag én", "RestartPleaseWaitMessage": "Vent venligst mens Jellyfin Server lukker og genstarter. Dette kan tage et minut eller to.", "RunAtStartup": "Kør ved opstart", @@ -1444,7 +1444,7 @@ "Schedule": "Tidsplan", "Screenshot": "Skærmbillede", "SecondaryAudioNotSupported": "Lydspor skift ikke understøttet", - "SeriesDisplayOrderHelp": "Sortér afsnit efter sende dato, dvd rækkefølge eller obsolut nummering.", + "SeriesDisplayOrderHelp": "Sortér episoder efter luftdato, DVD-orden eller absolut nummerering.", "ShowTitle": "Vis titel", "ShowYear": "Vis år", "Small": "Lille", @@ -1536,5 +1536,108 @@ "AllowFfmpegThrottlingHelp": "Når en omkodning eller remux kommer langt nok foran den nuværende afspildings position, pauses processen så der bruges færre resurser. Dette er mest brugbart når man ikke springer i filmen. Slå dette fra hvis du har problemer med playback.", "AllowFfmpegThrottling": "Begræns Omkodning", "AlbumArtist": "Album Artist", - "Album": "Album" + "Album": "Album", + "EveryHour": "Hver time", + "EveryXMinutes": "Hvert {0} minut", + "OnWakeFromSleep": "Ved vækning fra dvale", + "WeeklyAt": "{0}s ved {1}", + "DailyAt": "Dagligt kl. {0}", + "LastSeen": "Sidst set {0}", + "PersonRole": "som {0}", + "ListPaging": "{0}-{1} af {2}", + "WriteAccessRequired": "Jellyfin Server kræver skriveadgang til denne mappe. Sørg for skriveadgang, og prøv igen.", + "PathNotFound": "Stien blev ikke fundet. Sørg for, at stien er gyldig, og prøv igen.", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", + "Track": "Spor", + "TabNetworking": "Netværk", + "SubtitleOffset": "Undertekst Offset", + "SelectAdminUsername": "Vælg et brugernavn til administrator kontoen.", + "Season": "Sæson", + "ReleaseGroup": "Release Group", + "Premiere": "Premiere", + "PreferEmbeddedEpisodeInfosOverFileNames": "Foretrækker integreret episode information frem for filnavne", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Dette bruger episode informationen fra de integrerede metadata, hvis den er tilgængelig.", + "PlaybackData": "Afspilningsdata", + "Person": "Person", + "PasswordResetProviderHelp": "Vælg en leverandør af nulstil adgangskode, der skal bruges, når denne bruger anmoder om en nulstilling af adgangskode", + "OtherArtist": "Anden kunstner", + "OptionThumbCard": "Thumb card", + "OptionThumb": "Thumb", + "OptionRandom": "Tilfældig", + "OptionPosterCard": "Plakatkort", + "OptionPoster": "Plakat", + "OptionLoginAttemptsBeforeLockoutHelp": "En værdi på nul betyder at arve standard for tre forsøg for normale brugere og fem for administratorer. Indstilling af dette til -1 vil deaktivere funktionen.", + "OptionLoginAttemptsBeforeLockout": "Bestemmer, hvor mange forkerte loginforsøg, der kan gøres, før lockout finder sted.", + "OptionList": "Liste", + "OptionForceRemoteSourceTranscoding": "Tving transcoding af eksterne mediekilder (som LiveTV)", + "NoCreatedLibraries": "Det ser ud til, at du ikke har oprettet nogen biblioteker endnu. {0} Vil du oprette en nu? {1}", + "MusicVideo": "Musik Video", + "MusicLibraryHelp": "Gennemgå {0} guide til navngivning af musik {1}.", + "MusicArtist": "Musik Artist", + "MusicAlbum": "Musik Album", + "Movie": "Film", + "MoreMediaInfo": "Medieinfo", + "MessageNoServersAvailable": "Der er ikke fundet nogen servere ved hjælp af den automatiske serveropdagelse.", + "MessageNoCollectionsAvailable": "Samlinger tillader dig at nyde personlige grupperinger af Film, Serier og Albums. Klik på + knappen for at skabe en samling.", + "MessageConfirmAppExit": "Vil du afslutte?", + "MediaInfoStreamTypeSubtitle": "Undertekst", + "MediaInfoStreamTypeEmbeddedImage": "Indlejret billede", + "MediaInfoStreamTypeAudio": "Lyd", + "LaunchWebAppOnStartupHelp": "Åben web klienten i den standard web browser når serveren starter første gang. Dette vil ikke ske når restart server funktionen benyttes.", + "LaunchWebAppOnStartup": "Åben webinterfacet når serveren startes", + "LabelWeb": "Web:", + "LabelVideoResolution": "Videoopløsning:", + "LabelVideoBitrate": "Video bitrate:", + "DashboardArchitecture": "Arkitektur: {0}", + "DashboardOperatingSystem": "Styresystem: {0}", + "DashboardServerName": "Server: {0}", + "DashboardVersionNumber": "Version: {0}", + "LabelTranscodingProgress": "Transcoding fremskridt:", + "LabelTranscodingFramerate": "Transcoding framerate:", + "LabelTranscodes": "Transcodes:", + "LabelTranscodePath": "Transcode sti:", + "LabelStreamType": "Stream type:", + "LabelSonyAggregationFlags": "Sony aggregering flag:", + "LabelSize": "Størrelse:", + "EnableFastImageFadeInHelp": "Aktivér hurtigere fade-in-animation til indlæste billeder", + "EnableFastImageFadeIn": "Hurtigt billede indtoning", + "LabelPleaseRestart": "Ændringer vil træde i kraft efter web klienten er blevet genindlæst manuelt.", + "LabelPlayMethod": "Afspilnings metode:", + "LabelPlayerDimensions": "Afspillerdimensioner:", + "LabelPlayer": "Afspiller:", + "LabelPasswordResetProvider": "Udbyder til nulstilling as kodeord:", + "LabelLibraryPageSizeHelp": "Indstiller mængden af genstande, der skal vises på en bibliotekside. Indstil til 0 for at deaktivere.", + "LabelLibraryPageSize": "Biblioteks størrelse:", + "LabelFolder": "Mappe:", + "LabelBaseUrl": "Base URL:", + "LabelBaseUrlHelp": "Du kan tilføje en speciel undermappe her for, at have adgang til serveren fra en mere unik URL.", + "LabelDroppedFrames": "Tabte frames:", + "LabelDeinterlaceMethod": "Konventerings metode:", + "LabelCorruptedFrames": "Korrupte frames:", + "LabelBitrate": "Bitrate:", + "LabelAuthProvider": "Autentificeringsudbyder:", + "LabelAudioSampleRate": "Lydeksempelfrekvens:", + "LabelAudioCodec": "Lyd codec:", + "LabelAudioChannels": "Lyd kanaler:", + "LabelAudioBitrate": "Lyd bitrate:", + "LabelAudioBitDepth": "Lyd bitdybde:", + "HeaderFavoritePeople": "Foretrukne Personer", + "HeaderFavoriteBooks": "Foretrukne Bøger", + "FetchingData": "Henter yderligere data", + "Episode": "Afsnit", + "DeinterlaceMethodHelp": "Vælg hvilken konverteringsmulighed der skal bruges til transkodning af indhold.", + "CopyStreamURLError": "Der skete en fejl med at kopiere URL'en.", + "CopyStreamURLSuccess": "URL er kopiret succesfuldt.", + "CopyStreamURL": "Kopir Stream URL", + "ClientSettings": "Klient Indstillinger", + "ButtonSplit": "Opdel", + "BoxSet": "Box Set", + "AuthProviderHelp": "Vælg en godkendelses udbyder, der kan bruges til at godkende denne brugers adgangskode.", + "AskAdminToCreateLibrary": "Spørg en administrator om at oprette et bibliotek.", + "Artist": "Artist", + "EveryXHours": "Hver {0} time", + "OnApplicationStartup": "Ved programstart", + "UnsupportedPlayback": "Jellyfin kan ikke dekryptere indhold, der er beskyttet af DRM, men alt indhold vil blive forsøgt afspillet uanset, inklusive beskyttede titler. Nogle filer kan eventuelt vises med sort skærm på grund af kryptering eller andre funktioner, der ikke understøttes, såsom interaktive titler.", + "MessageUnauthorizedUser": "Du har ikke tilladelse til at tilgå serveren på dette tidspunkt. Kontakt din serveradministrator for mere information." } diff --git a/src/strings/de.json b/src/strings/de.json index 347d115f76..cf03296503 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -1097,7 +1097,7 @@ "RefreshMetadata": "Aktualisiere Metadaten", "RefreshQueued": "Aktualisierung eingereiht.", "ReleaseDate": "Veröffentlichungsdatum", - "RememberMe": "Erinnere mich", + "RememberMe": "Angemeldet bleiben", "RemoveFromCollection": "Aus Sammlung entfernen", "RemoveFromPlaylist": "Von Wiedergabeliste entfernen", "Repeat": "Wiederholen", @@ -1518,7 +1518,7 @@ "BoxSet": "Box Set", "YadifBob": "YADIF Bob", "Yadif": "YADIF", - "LabelLibraryPageSizeHelp": "Setzt die Anzahl der gezeigten Elemente auf einer Bibliotheksseite. Setze die Anzahl auf 0 um die Auflistung zu deaktivieren.", + "LabelLibraryPageSizeHelp": "Setzt die Anzahl der auf einer Seite angezeigten Objekte. Setze auf 0, um alle Elemente auf einer Seite anzuzeigen.", "LabelLibraryPageSize": "Bibliothek Seiten Größe:", "DeinterlaceMethodHelp": "Wähle die Deinterlacing-Methode zum Transkodieren von Inhalten im Zeilensprungverfahren (Interlace).", "LabelDeinterlaceMethod": "Deinterlacing-Methode:" diff --git a/src/strings/el.json b/src/strings/el.json index 3856480fd0..4804928364 100644 --- a/src/strings/el.json +++ b/src/strings/el.json @@ -10,7 +10,7 @@ "AdditionalNotificationServices": "Περιηγηθείτε στον κατάλογο plugin για να εγκαταστήσετε πρόσθετες υπηρεσίες ειδοποίησης.", "AirDate": "Ημερομηνία προβολής", "Aired": "Προβλήθηκε", - "Albums": "Άλμπουμ", + "Albums": "Άλμπουμς", "All": "Όλα", "AllChannels": "Όλα τα κανάλια", "AllComplexFormats": "Όλες οι σύνθετες μορφές (ASS, SSA, VOBSUB, PGS, SUB / IDX κ.λπ.)", @@ -19,7 +19,7 @@ "AllLibraries": "Όλες οι βιβλιοθήκες", "AllowRemoteAccess": "Να επιτρέπονται οι απομακρυσμένες συνδέσεις σε αυτόν το διακομιστή Jellyfin.", "AllowRemoteAccessHelp": "Εάν δεν επιλεχθεί, όλες οι απομακρυσμένες συνδέσεις θα αποκλειστούν.", - "AlwaysPlaySubtitles": "Πάντα αναπαραγωγή Υποτίτλων", + "AlwaysPlaySubtitles": "Παίξτε πάντα", "AlwaysPlaySubtitlesHelp": "Οι υπότιτλοι που ταιριάζουν με τις προτιμήσεις γλώσσας θα φορτωθούν ανεξάρτητα από τη γλώσσα του ήχου.", "AnyLanguage": "Οποιαδήποτε γλώσσα", "Anytime": "Οποτεδήποτε", @@ -28,7 +28,7 @@ "Artists": "Καλλιτέχνες", "AsManyAsPossible": "Οσο το δυνατον περισσοτερα", "Ascending": "Αύξουσα", - "AspectRatio": "Αρχικός λόγος διαστάσεων", + "AspectRatio": "Αναλογία απεικόνισης", "AttributeNew": "Νέο", "Audio": "Ήχος", "Auto": "Αυτόματο", @@ -1224,6 +1224,14 @@ "LabelServerName": "Όνομα Διακομιστή:", "ButtonAddImage": "Προσθήκη Εικόνας", "BoxRear": "Κουτί(πίσω)", - "BookLibraryHelp": "Ήχος και βιβλία υποστηρίζονται.Ελέγξτε τον {0}ονομαστικό οδηγό βιβλίων{1}.", - "AuthProviderHelp": "Επιλέξτε ένα Πάροχο Επαλήθευσης για να επαληθεύσετε το κωδικό αυτού του χρήστη." + "BookLibraryHelp": "Υποστήριξη ήχου και βιβλίων κειμένου. Εξετάστε τον {0}οδηγό ονομάτων βιβλίου{1}.", + "AuthProviderHelp": "Επιλέξτε ένα Πάροχο Επαλήθευσης για να επαληθεύσετε το κωδικό αυτού του χρήστη.", + "AllowFfmpegThrottling": "Επιτάχυνση Διακωδικοποιησής", + "AlbumArtist": "Άλμπουμ Καλλιτέχνη", + "Album": "Άλμπουμ", + "BoxSet": "Σετ Κουτιού", + "AskAdminToCreateLibrary": "Ζητήστε από έναν διαχειριστή να δημιουργήσει μια βιβλιοθήκη.", + "Artist": "Καλλιτέχνης", + "AllowedRemoteAddressesHelp": "Λίστα διαχωρισμένων διευθύνσεων IP ή καταχωρίσεων IP / netmask για δίκτυα που θα επιτρέπεται η σύνδεση εξ αποστάσεως. Εάν αφεθεί κενό, όλες οι απομακρυσμένες διευθύνσεις θα επιτρέπονται.", + "AllowFfmpegThrottlingHelp": "Όταν ένας διακωδικοποιητής ή remux φτάσει αρκετά μπροστά από την τρέχουσα θέση αναπαραγωγής, διακόψτε τη διαδικασία ώστε να καταναλώσει λιγότερους πόρους. Αυτό είναι πιο χρήσιμο όταν παρακολουθείτε χωρίς να αναζητάτε συχνά. Απενεργοποιήστε το εάν αντιμετωπίζετε προβλήματα αναπαραγωγής." } diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index bca865ff6c..5e57536715 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -385,6 +385,7 @@ "HeaderFavoriteArtists": "Favourite Artists", "HeaderFavoriteSongs": "Favourite Songs", "HeaderFavoriteVideos": "Favourite Videos", + "HeaderFavoritePlaylists": "Favourite Playlists", "HeaderFeatureAccess": "Feature Access", "HeaderFeatures": "Features", "HeaderFetchImages": "Fetch Images:", @@ -527,6 +528,8 @@ "Smart": "Smart", "SimultaneousConnectionLimitHelp": "The maximum number of allowed simultaneous streams. Enter 0 for no limit.", "Shuffle": "Shuffle", + "New": "New", + "Filter": "Filter", "ShowYear": "Show year", "ShowIndicatorsFor": "Show indicators for:", "ShowAdvancedSettings": "Show advanced settings", diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 990145ee95..9895bbc05c 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -137,6 +137,8 @@ "ButtonSplit": "Split", "ButtonSubmit": "Submit", "ButtonSubtitles": "Subtitles", + "ButtonToggleContextMenu": "More", + "ButtonTogglePlaylist": "Playlist", "ButtonTrailer": "Trailer", "ButtonUninstall": "Uninstall", "ButtonUp": "Up", @@ -368,6 +370,7 @@ "HeaderFavoriteArtists": "Favorite Artists", "HeaderFavoriteSongs": "Favorite Songs", "HeaderFavoriteVideos": "Favorite Videos", + "HeaderFavoritePlaylists": "Favorite Playlists", "HeaderFeatureAccess": "Feature Access", "HeaderFeatures": "Features", "HeaderFetchImages": "Fetch Images:", @@ -990,6 +993,7 @@ "MessageInstallPluginFromApp": "This plugin must be installed from within the app you intend to use it in.", "MessageInvalidForgotPasswordPin": "An invalid or expired pin code was entered. Please try again.", "MessageInvalidUser": "Invalid username or password. Please try again.", + "MessageUnauthorizedUser": "You are not authorized to access the server at this time. Please contact your server administrator for more information.", "MessageItemSaved": "Item saved.", "MessageItemsAdded": "Items added.", "MessageLeaveEmptyToInherit": "Leave empty to inherit settings from a parent item or the global default value.", @@ -1334,6 +1338,8 @@ "ShowYear": "Show year", "Shows": "Shows", "Shuffle": "Shuffle", + "New": "New", + "Filter": "Filter", "SimultaneousConnectionLimitHelp": "The maximum number of allowed simultaneous streams. Enter 0 for no limit.", "SkipEpisodesAlreadyInMyLibrary": "Don't record episodes that are already in my library", "SkipEpisodesAlreadyInMyLibraryHelp": "Episodes will be compared using season and episode numbers, when available.", @@ -1498,5 +1504,6 @@ "EveryXMinutes": "Every {0} minutes", "EveryHour": "Every hour", "EveryXHours": "Every {0} hours", - "OnApplicationStartup": "On application startup" + "OnApplicationStartup": "On application startup", + "UnsupportedPlayback": "Jellyfin cannot decrypt content protected by DRM but all content will be attempted regardless, including protected titles. Some files may appear completely black due to encryption or other unsupported features, such as interactive titles." } diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 90e5283c0c..69c571a57a 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -429,7 +429,7 @@ "HeaderApp": "Aplicación", "HeaderApiKeysHelp": "Las aplicaciones externas requieren una llave API para poder comunicarse con el servidor Jellyfin. Las llaves se emiten iniciando sesión con una cuenta Jellyfin u otorgando manualmente una clave a la aplicación.", "HeaderApiKeys": "Llaves API", - "HeaderApiKey": "Llave API", + "HeaderApiKey": "Contraseña API", "HeaderAllowMediaDeletionFrom": "Permitir el borrado de medios desde", "HeaderAlert": "Alerta", "HeaderAlbums": "Albumes", @@ -476,5 +476,29 @@ "HeaderCastAndCrew": "Reparto", "HeaderCancelSeries": "Cancelar serie", "H264CrfHelp": "El Factor de velocidad constante (CRF) es la configuración de calidad predeterminada para el codificador x264. Puede establecer los valores entre 0 y 51, donde valores más bajos resultarían en una mejor calidad (a expensas de tamaños de archivo más altos). Los valores correctos están entre 18 y 28. El valor predeterminado para x264 es 23, por lo que puede usar esto como punto de partida.", - "DeinterlaceMethodHelp": "Seleccione el método de desentrelazado que se usará al transcodificar contenido entrelazado." + "DeinterlaceMethodHelp": "Seleccione el método de desentrelazado que se usará al transcodificar contenido entrelazado.", + "HeaderFavoriteVideos": "Videos favoritos", + "HeaderFavoritePeople": "Gente favorita", + "HeaderFavoriteMovies": "Películas Favoritas", + "HeaderFavoriteBooks": "Libros favoritos", + "HeaderExternalIds": "IDs externos:", + "HeaderError": "Error", + "HeaderEpisodes": "Episodios", + "HeaderEnabledFields": "Campos habilitados", + "HeaderEditImages": "Editar imágenes", + "HeaderEasyPinCode": "Pin sencillo", + "HeaderDownloadSync": "Descargar y sincronizar", + "HeaderDisplay": "Pantalla", + "HeaderDirectPlayProfile": "Perfil Direct Play", + "HeaderDevices": "Dispositivos", + "HeaderDeviceAccess": "Acceso al dispositivo", + "HeaderDeveloperInfo": "Información para desarrolladores", + "HeaderDetectMyDevices": "Detectar mis dispositivos", + "HeaderDeleteTaskTrigger": "Elminar disparador de acciones", + "HeaderDeleteProvider": "Eliminar proveedor", + "HeaderDeleteItems": "Eliminar ítems", + "HeaderDeleteItem": "Eliminar ítem", + "HeaderDeleteDevice": "Eliminar dispositivo", + "HeaderDefaultRecordingSettings": "Ajustes de grabación por defecto", + "UnsupportedPlayback": "Jellyfin no puede descifrar contenido protegido por DRM pero a pesar de esto lo intentará con todo el contenido, incluyendo títulos protegidos. Algunos archivos pueden aparecer completamente en negro por estar cifrados o por otras características no soportadas, como títulos interactivos." } diff --git a/src/strings/es.json b/src/strings/es.json index 1bb9a76537..4b090997d6 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1248,7 +1248,7 @@ "Descending": "Descendiente", "DirectStreamHelp1": "El tipo de archivo (H.264, AC3, etc.) y la resolución son compatibles con el dispositivo, pero no el contenedor (mkv, avi, wmv, etc.). El vídeo será re-empaquetado al vuelo antes de transmitirlo al dispositivo.", "DirectStreamHelp2": "La transmisión directa del archivo usa muy poco procesamiento sin ninguna pérdida de calidad en el vídeo.", - "Director": "Dirección", + "Director": "Dirección de", "Directors": "Directores", "Display": "Mostrar", "DisplayInMyMedia": "Mostrar en la pantalla de inicio", @@ -1504,5 +1504,11 @@ "LabelDeinterlaceMethod": "Metodo de desentrelazar:", "DeinterlaceMethodHelp": "Seleccione el método de desentrelazar para el transcodificar de contenido entrelazado.", "LabelLibraryPageSize": "Tamaño de la página de la biblioteca:", - "LabelLibraryPageSizeHelp": "Establece la cantidad de artículos a mostrar en una página de la biblioteca. Ponlo en 0 para desactivar la paginación." + "LabelLibraryPageSizeHelp": "Establece la cantidad de artículos a mostrar en una página de la biblioteca. Ponlo en 0 para desactivar la paginación.", + "UnsupportedPlayback": "No es posible desencriptar contenido protegido mediante DRM; sin embargo se intentará su reproducción. Algunos archivos pueden aparecer completamente negros debido a encriptación u otras características no soportadas, como títulos interactivos.", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", + "MessageUnauthorizedUser": "No tiene autorización para acceder al servidor en este momento. Póngase en contacto con el administrador del servidor para obtener más información.", + "ButtonTogglePlaylist": "Lista de reproducción", + "ButtonToggleContextMenu": "Más" } diff --git a/src/strings/fa.json b/src/strings/fa.json index 1e227b0e80..f244a25872 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -106,7 +106,7 @@ "TabProfiles": "پروفایل ها", "TabShows": "سریال ها", "TabSongs": "آهنگ ها", - "TabSuggestions": "پیشنهادات", + "TabSuggestions": "پیشنهادها", "TabUpcoming": "بزودی", "TellUsAboutYourself": "در مورد خودتان به ما بگویید", "ThisWizardWillGuideYou": "این عمل برای انجام تنظیمات به شما کمک می‌کند. برای شروع، لطفا زبان مورد نظر خود را انتخاب کنید.", @@ -127,7 +127,7 @@ "HeaderFavoriteAlbums": "آلبوم‌های مورد علاقه", "HeaderFavoriteArtists": "هنرمندان مورد علاقه", "HeaderFavoriteSongs": "آهنگ‌های مورد علاقه", - "HeaderLiveTV": "تلویزیون زنده", + "HeaderLiveTV": "پخش زنده", "Movies": "فیلم‌ها", "Photos": "عکس‌ها", "Playlists": "لیست‌های پخش", @@ -163,7 +163,7 @@ "ButtonNextTrack": "ترانه پسین", "ButtonPreviousTrack": "ترانه پیشین", "ButtonPause": "مکث", - "ButtonParentalControl": "کنترل والدین", + "ButtonParentalControl": "رتبه بندی والدین", "ButtonOpen": "باز", "ButtonOff": "خاموش", "ButtonNetwork": "شبکه", @@ -239,7 +239,7 @@ "EnableHardwareEncoding": "فعال سازی رمزگذاری سخت افزاری", "EnableExternalVideoPlayersHelp": "یک منوی پخش کننده ویدیوی خارجی، زمانی که شروع به پخش ویدیو می‌شود نمایش داده خواهد شد.", "EnableExternalVideoPlayers": "پخش کننده ویدیوی خارجی", - "EnableDisplayMirroring": "انعکاس نمایش", + "EnableDisplayMirroring": "نمایش آینه", "EnableCinemaMode": "حالت سینما", "EnableBackdrops": "پشت‌زمینه‌ها", "EditSubtitles": "ویرایش زیرنویس‌ها", @@ -602,5 +602,73 @@ "LabelSortOrder": "ترتیب مرتب‌سازی:", "LabelSortBy": "مرتب‌سازی بر اساس:", "LabelSonyAggregationFlags": "پرچم‌های جمع‌آوری سونی:", - "LabelSkipIfGraphicalSubsPresent": "صرف نظر کردن اگر ویدیو پیش از این زیرنویس چسبیده در خود دارد" + "LabelSkipIfGraphicalSubsPresent": "صرف نظر کردن اگر ویدیو پیش از این زیرنویس چسبیده در خود دارد", + "EnableColorCodedBackgrounds": "پشت‌ زمینه‌های کدگذاری شده رنگی", + "DisplayMissingEpisodesWithinSeasonsHelp": "این مورد همچنین باید برای کتابخانه های تلویزیون در پیکربندی سرور فعال شود.", + "DisplayInOtherHomeScreenSections": "در بخش‌های صفحه اصلی مانند آخرین رسانه‌ها و ادامه تماشا نمایش بده", + "Desktop": "دسکتاپ", + "CustomDlnaProfilesHelp": "برای هدف قرار دادن یک دستگاه جدید یا سرپوش گذاشتن روی نمایه سیستم ، یک نمایه سفارشی ایجاد کنید.", + "ConfirmDeleteItems": "حذف این مورد، آن را هم از فایل سیستمی و هم از کتابخانه رسانه شما حذف می کند. آیا اطمینان دارید که می‌خواهید ادامه دهید؟", + "ConfirmDeleteItem": "حذف این مورد، آن را هم از فایل سیستمی و هم از کتابخانه رسانه شما حذف می کند. آیا اطمینان دارید که می‌خواهید ادامه دهید؟", + "AlwaysPlaySubtitlesHelp": "زیرنویس‌های متناسب با توجه به اولویت زبان بدون در نظر گرفتن زبان صوتی ویدیو پخش می شوند.", + "AllowedRemoteAddressesHelp": "لیستی از آدرس های IP یا ورودی‌های IP/‌netmask برای شبکه هایی که به آنها امکان ارتباط از راه دور داده می‌شود ، با کاما از هم جدا شدند. در صورت خالی ماندن ، تمام آدرسهای راه دور مجاز خواهند بود.", + "AllowOnTheFlySubtitleExtractionHelp": "زیرنویس های جاسازی شده را می‌توان از فیلم‌ها استخراج کرد و به منظور جلوگیری از کدگذاری فیلم ، به صورت متن ساده به بازدید کننده ارسال کرد. در بعضی از سیستم‌ها این می‌تواند مدت زیادی طول بکشد و باعث شود پخش فیلم در طول فرآیند استخراج متوقف شود. این گزینه را غیرفعال کنید تا زیرنویس‌های جاسازی شده با استفاده از رمزگذاری ویدیو در حالی که به طور محلی توسط دستگاه بازدیدکننده پشتیبانی نمی‌شوند ارسال شود.", + "AdditionalNotificationServices": "برای نصب سرویس‌های اعلان اضافی، در فروشگاه افزونه‌ها جستجو کنید.", + "OptionThumbCard": "کارت بندانگشتی", + "OptionThumb": "بندانگشتی", + "OptionThursday": "پنجشنبه", + "OptionSunday": "یکشنبه", + "OptionSubstring": "زیررشته", + "OptionSpecialEpisode": "ویژه‌ها", + "OptionSaveMetadataAsHidden": "ذخیره فراداده‌ها و عکس‌ها به عنوان فایل‌های پنهان", + "OptionSaturday": "شنبه", + "OptionRuntime": "زمان اجرا", + "OptionResumable": "قابل از سرگیری", + "OptionResElement": "عنصر res", + "OptionReleaseDate": "تاریخ انتشار", + "OptionRegex": "عبارت منظم", + "OptionRandom": "تصادفی", + "OptionProtocolHttp": "HTTP", + "OptionProtocolHls": "پخش مستقیم HTTP", + "OptionProfileVideoAudio": "صوتی تصویری", + "OptionProfilePhoto": "عکس", + "OptionProfileAudio": "صدا", + "OptionPremiereDate": "تاریخ پخش", + "OptionPosterCard": "کارتِ پوستر", + "OptionPoster": "پوستر", + "OptionPlayCount": "تعداد پخش", + "OptionPlainVideoItems": "نمایش همه فیلم‌ها به عنوان موارد ویدیویی ساده", + "OptionPlainStorageFolders": "نمایش همه پوشه‌ها به عنوان پوشه‌های ذخیره سازی ساده", + "OptionParentalRating": "رتبه بندی والدین", + "OptionOnInterval": "در یک فاصله", + "BookLibraryHelp": "کتاب‌های صوتی و متنی پشتیبانی می‌شوند. {0}راهنمای نامگذاری کتاب{1} را مرور کنید.", + "TabInfo": "اطلاعات", + "TabGuide": "راهنما", + "TabFavorites": "مورد علاقه‌ها", + "TabDisplay": "نمایش", + "TabDirectPlay": "پخش مستقیم", + "TabDevices": "دستگاه‌ها", + "TabDashboard": "داشبورد", + "TabCollections": "مجموعه‌ها", + "TabCodecs": "کدک‌ها", + "TabChannels": "کانال‌ها", + "TabCatalog": "فهرست", + "TV": "تلویزیون", + "Sunday": "یکشنبه", + "TabTranscoding": "کدگذاری", + "TabTrailers": "تریلرها", + "Suggestions": "پیشنهادها", + "Subtitles": "زیرنویس‌ها", + "Studios": "استودیو‌ها", + "StopRecording": "توقف ضبط", + "Sports": "ورزش‌ها", + "SortName": "مرتب سازی نام", + "SortChannelsBy": "مرتب سازی کانال‌ها بر اساس:", + "SortByValue": "مرتب شده بر اساس {0}", + "Sort": "مرتب سازی", + "Smart": "باهوش", + "Smaller": "کوچکتر", + "Small": "کوچک", + "ButtonTogglePlaylist": "لیست پخش", + "ButtonToggleContextMenu": "بیشتر" } diff --git a/src/strings/fi.json b/src/strings/fi.json index b915aefd39..8f3c5fb6e8 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -4,7 +4,7 @@ "ButtonAddUser": "Lisää Käyttäjä", "ButtonCancel": "Peruuta", "ButtonDeleteImage": "Poista Kuva", - "ButtonResetPassword": "Uusi Salasana", + "ButtonResetPassword": "Nollaa salasana", "ButtonSave": "Tallenna", "ButtonSignOut": "Sign out", "Delete": "Poista", @@ -15,16 +15,16 @@ "FileNotFound": "Tiedostoa ei löydy.", "FileReadCancelled": "Tiedoston luku on peruutettu.", "FileReadError": "Virhe tiedoston luvun aikana.", - "FolderTypeTvShows": "TV", + "FolderTypeTvShows": "TV-sarjat", "HeaderCreatePassword": "Luo Salasana:", "HeaderParentalRating": "Parental Rating", - "HeaderSeries": "Jaksot", + "HeaderSeries": "Sarjat", "HeaderYear": "Year:", "LabelAudioLanguagePreference": "Äänen ensisijainen kieli:", "LabelConfigureSettings": "Muuta asetuksia", "LabelCountry": "Maa:", "LabelCurrentPassword": "Tämän hetkinen salsana:", - "LabelDisplayMissingEpisodesWithinSeasons": "Näytä puuttuvat jaksot tuotantokausissa", + "LabelDisplayMissingEpisodesWithinSeasons": "Näytä puuttuvat jaksot kausien sisällä", "LabelDownloadInternetMetadata": "Lataa kuvamateriaali ja metadata internetistä", "LabelFinish": "Valmis", "LabelFolderType": "Kansion tyyppi:", @@ -34,22 +34,22 @@ "LabelNewPasswordConfirm": "Uuden salasanan varmistus:", "LabelNext": "Seuraava", "LabelPrevious": "Edellinen", - "LabelSaveLocalMetadata": "Tallenna kuvamateriaali ja metadata media kansioihin.", + "LabelSaveLocalMetadata": "Tallenna kuvamateriaali mediakansioihin", "LabelSaveLocalMetadataHelp": "Kuvamateriaalin ja metadatan tallentaminen suoraan kansioihin missä niitä on helppo muuttaa.", "LabelSubtitleLanguagePreference": "Tekstityksien ensisijainen kieli:", "LabelUnairedMissingEpisodesWithinSeasons": "Näytä julkaisemattomat jaksot tuotantokausissa", - "LabelYourFirstName": "Sinun ensimmäinen nimi:", - "LabelYoureDone": "Olet valmis!", - "LibraryAccessHelp": "Valitse media kansiot jotka haluat jakaa tämän käyttäjän kanssa. Järjestelmänvalvoja pystyy muokkaamaan kaikkia kansioita käyttäen metadata hallintaa.", - "MaxParentalRatingHelp": "Suuremman arvosanan takia, sisältö tulla piilottamaan käyttäjältä.", - "MoreUsersCanBeAddedLater": "Käyttäjiä voi lisätä lisää myöhemmin Dashboardista", + "LabelYourFirstName": "Etunimesi:", + "LabelYoureDone": "Valmista!", + "LibraryAccessHelp": "Valitse kirjastot, jotka haluat jakaa tämän käyttäjän kanssa. Järjestelmänvalvoja pystyy muokkaamaan kaikkia kansioita käyttäen metadatan hallintatyökalua.", + "MaxParentalRatingHelp": "", + "MoreUsersCanBeAddedLater": "Käyttäjiä voidaan lisätä myöhemmin lisää päänäkymästä.", "NoPluginsInstalledMessage": "Sinulla ei ole mitään lisäosia asennettuna.", "OptionRelease": "Virallinen Julkaisu", - "ParentalRating": "Parental Rating", + "ParentalRating": "", "Password": "Salasana", - "PasswordMatchError": "Salasana ja salasanan vahvistuksen pitää olla samat.", - "PasswordResetComplete": "Salasana on palauttettu.", - "PasswordResetConfirmation": "Oletko varma, että haluat palauttaa salasanan?", + "PasswordMatchError": "Salasanan ja salasanan vahvistuksen on oltava samat.", + "PasswordResetComplete": "Salasana on nollattu.", + "PasswordResetConfirmation": "Haluatko varmasti nollata salasanan?", "PasswordSaved": "Salasana tallennettu.", "Save": "Tallenna", "SettingsSaved": "Asetukset tallennettu.", @@ -59,7 +59,7 @@ "TabProfile": "Profiili", "TabProfiles": "Profiilit", "TellUsAboutYourself": "Kerro meille itsestäsi", - "ThisWizardWillGuideYou": "Tämä työkalu auttaa sinua asennus prosessin aikana. loittaaksesi valitse kieli.", + "ThisWizardWillGuideYou": "Tämä työkalu auttaa sinua asennusprosessin aikana. Valitse kieli aloittaaksesi.", "UninstallPluginConfirmation": "Oletko varma, että haluat poistaa {0}?", "UninstallPluginHeader": "Poista Lisäosa", "Users": "Käyttäjät", @@ -88,7 +88,7 @@ "AddGuideProviderHelp": "Lisää lähde ohjelmaoppaalle.", "AddItemToCollectionHelp": "Lisää nimikkeitä etsimällä niitä ja käyttämällä hiiren oikeaa nappia tai valikkoa lisätäksesi ne kokoelmaan.", "Aired": "Esityspäivä", - "AllowHWTranscodingHelp": "Salli virittimen muuntaa bittivirtaa lennossa. Tämä voi vähentää tarvetta muunnokseen palvelimella.", + "AllowHWTranscodingHelp": "Salli virittimen muuntaa bittivirtaa lennossa. Tämä voi vähentää muunnoksen tarvetta Jellyfin-palvelimella.", "AllowMediaConversion": "Salli median muunto", "AllowMediaConversionHelp": "Salli tai kiellä pääsy median muunnostoimintoon.", "AllowOnTheFlySubtitleExtractionHelp": "Sisäiset tekstitykset voidaan lähettää päätelaitteille ilmitekstinä, jotta videota ei tarvitsisi uudelleenkoodata. Joissain järjestelmissä tämä voi viedä paljon aikaa ja aiheuttaa toiston pysähtymisen purun ajaksi. Poista tämä käytöstä polttaaksesi tekstiykset suoraan videoon, mikäli päätelaite ei tue tekstityksiä.", @@ -101,7 +101,7 @@ "AlwaysPlaySubtitlesHelp": "Oletuskieliasetusta vastaava tekstitys otetaan käyttöön ääniraidan kielestä huolimatta.", "AnamorphicVideoNotSupported": "Anamorfinen video ei ole tuettu", "AndroidUnlockRestoreHelp": "Palauttaaksesi aikaisemman ostoksesi, varmista, että olet kirjautuneena samalla Google (tai Amazon) tunnuksella, jolla teit alkuperäisen oston. Varmista, että sovelluskauppa on päällä eikä sitä ole rajoitettu vanhempien lukolla. Varmista myös, että sinulla on toimiva internet -yhteys. Sinun tarvitsee tehdä taämä vain kerran.", - "AnyLanguage": "Mikä tahansa kieli", + "AnyLanguage": "Mikä tahansa", "Anytime": "Milloin tahansa", "AroundTime": "Noin {0}", "Art": "Taide", @@ -249,13 +249,13 @@ "DisplayInOtherHomeScreenSections": "Näytä kotinäytöllä osastoja kuten viimeisin media ja jatka katselua", "DisplayMissingEpisodesWithinSeasons": "Näytä puuttuvat jaksot tuotantokausissa", "DisplayMissingEpisodesWithinSeasonsHelp": "Tämän pitää aktivoida TV-kirjastoille myös palvelimen asetuksissa.", - "DisplayModeHelp": "Valitse näyttölaitteen tyyppi jolla pyörität Jellyfiniä.", + "DisplayModeHelp": "Valitse ulkonäkö, jonka haluat käyttöliittymälle.", "DoNotRecord": "Älä tallenna", "Down": "Alas", "Download": "Lataa", "DownloadsValue": "{0} latausta", "DrmChannelsNotImported": "Kanavia joissa on tekijänoikeusesto-ohjelmia, ei ladata.", - "DropShadow": "Tiputa varjo", + "DropShadow": "Varjostus", "EasyPasswordHelp": "Sinun helppoa PIN-koodia käytetään offline-käytössä tuetuissa Jellyfin-sovelluksissa, ja voi myös nopeuttaa lan yhteyden kautta kirjautumista.", "Edit": "Muokkaa", "EditImages": "Muokkaa kuvia", @@ -267,7 +267,7 @@ "ButtonAddImage": "Lisää kuva", "Movies": "Elokuvat", "HeaderNextUp": "Seuraavaksi", - "HeaderLiveTV": "Suorat lähetykset", + "HeaderLiveTV": "Live-TV", "HeaderFavoriteSongs": "Lempikappaleet", "HeaderFavoriteShows": "Lempisarjat", "HeaderFavoriteEpisodes": "Lempijaksot", @@ -284,16 +284,16 @@ "ValueSpecialEpisodeName": "Erikois - {0}", "Sync": "Synkronoi", "Songs": "Kappaleet", - "Shows": "Ohjelmat", + "Shows": "Sarjat", "CopyStreamURLSuccess": "Osoite kopioitu onnistuneesti.", - "DeathDateValue": "Kuoli: {0}", - "CustomDlnaProfilesHelp": "Luo mukautettu profiili uutta laitetta varten, tai ohita järjestelmäprofiili.", + "DeathDateValue": "Kuoli: {}", + "CustomDlnaProfilesHelp": "Luo uusi profiili kohdistaaksesi uuteen laitteeseen tai ohittaaksesi järjestelmäprofiilin.", "EnableBackdrops": "Taustat", "ErrorAddingMediaPathToVirtualFolder": "Media-polkua lisätessä ilmeni ongelma. Varmista, että polku on kirjoitettu oikein ja Jellyfin Palvelimella pääsy sijaintiin.", "Episodes": "Jaksot", "EndsAtValue": "Päättyy {0}", "Ended": "Päättynyt", - "EnableThemeSongsHelp": "Soita tunnuslaulut taustalla, selatessasi kirjastoa.", + "EnableThemeSongsHelp": "Soita tunnussäveliä taustalla selatessasi kirjastoa.", "EnableThemeSongs": "Tunnuslaulut", "EnableStreamLoopingHelp": "Laita tämä päälle, jos suoratoistot sisältävät vain muutaman sekuntin verran dataa jota tarvitsee pyytää jatkuvasti. Tämän päälle laittaminen ilman toiminnon tarvetta voi aiheuttaa ongelmia.", "EnablePhotosHelp": "Kuvat tunnistetaan ja näytetään muiden media-tiedostojen ohessa.", @@ -307,11 +307,11 @@ "EnableBackdropsHelp": "Näytä taustat tietyillä sivuilla selatessasi kirjastoa.", "EnableExternalVideoPlayersHelp": "Videota soitettaessa näytetään erillinen valikko.", "Depressed": "Painettu", - "CopyStreamURLError": "Verkko-osoitteen kopioinnissa tapahtui virhe.", + "CopyStreamURLError": "Osoitteen kopioidessa tapahtui virhe.", "ButtonSplit": "jaa", "AskAdminToCreateLibrary": "Pyydä järjestelmän ylläpitäjää luomaan kirjasto.", "EnableStreamLooping": "Auto-toista suoralähetykset", - "EnableNextVideoInfoOverlayHelp": "Videon lopussa, näytä soittolistassa seuraavaksi toistettavan videon tiedot.", + "EnableNextVideoInfoOverlayHelp": "Näytä videon lopussa tietoja seuraavasta videosta soittolistalla.", "ClientSettings": "Pääte-asetukset", "AllowFfmpegThrottlingHelp": "Kun uudelleenkoodaus tai remux ehtii tarpeeksi toiston edelle, keskeytä laskenta jotta laskentaresursseja kuluu vähemmän. Tämä on hyödyllistä jos katselet hyppimättä eri kohtiin. Älä käytä jos toiston kanssa ilmenee ongelmia.", "AllowFfmpegThrottling": "Rajoita uudelleenkoodaus", @@ -319,7 +319,744 @@ "ErrorAddingXmlTvFile": "XMLTV-tiedostoa käyttäessä tapahtui virhe. Varmista, että tiedosto on olemassa ja kokeile uudestaan.", "ErrorAddingTunerDevice": "Viritintä lisätessä ilmeni ongelma. Varmista, että se on kytketty oikein ja kokeile uudestaan.", "EnableThemeVideosHelp": "Soita tunnusvideoita taustalla, selatessasi kirjastoa.", - "EnableThemeVideos": "Teeman videot", + "EnableThemeVideos": "Tunnusvideot", "AlbumArtist": "Albumin Artisti", - "Album": "Albumi" + "Album": "Albumi", + "Played": "Toistetut", + "PlayFromBeginning": "Toista alusta", + "PlayNext": "Toista seuraava", + "Play": "Toista", + "PinCodeResetConfirmation": "Haluatko varmasti nollata PIN-koodin?", + "People": "Ihmiset", + "PasswordResetHeader": "Nollaa salasana", + "OriginalAirDateValue": "Alkuperäinen esityspäivä: {0}", + "OptionWeekly": "Viikottainen", + "OptionWeekends": "Viikonloput", + "OptionWeekdays": "Arkipäivät", + "OptionTvdbRating": "TVDB luokitus", + "OptionTrackName": "Raidan nimi", + "OptionThumbCard": "Pienoiskuvakortti", + "OptionThumb": "Pienoiskuva", + "OptionSubstring": "Substring", + "OptionSpecialEpisode": "Erikoisjaksot", + "OptionSaveMetadataAsHidden": "Tallenna metadata ja kuvat piilotettuina tiedostoina", + "OptionRuntime": "Kesto", + "OptionResumable": "Jatkettavissa oleva", + "OptionResElement": "res element", + "OptionReleaseDate": "Julkaisupäivä", + "OptionRegex": "Regex", + "OptionRandom": "Satunnainen", + "OptionProtocolHttp": "HTTP", + "OptionProtocolHls": "HTTP Suoratoisto", + "OptionProfileVideoAudio": "Video Audio", + "OptionProfileVideo": "Video", + "OptionProfilePhoto": "Kuva", + "OptionProfileAudio": "Audio", + "OptionPremiereDate": "Ensi-iltapäivä", + "OptionPosterCard": "Julistekortti", + "OptionPoster": "Juliste", + "OptionPlayCount": "Toistokerrat", + "OptionPlayed": "Toistettu", + "OptionOnAppStartup": "Käynnistyksen yhteydessä", + "OptionNew": "Uusi...", + "OptionNameSort": "Nimi", + "OptionMonday": "Maanantai", + "OptionMissingEpisode": "Puuttuvat jaksot", + "OptionMax": "Maksimi", + "OptionList": "Lista", + "OptionLikes": "Likes", + "OptionIsSD": "SD", + "OptionIsHD": "HD", + "OptionImdbRating": "IMDb Luokitus", + "OptionHomeVideos": "Kuvat", + "OptionHideUser": "Piilota tämä käyttäjä kirjautumisnäkymästä", + "OptionHasTrailer": "Traileri", + "OptionHasThemeVideo": "Tunnusvideo", + "OptionHasThemeSong": "Tunnuskappale", + "OptionHasSubtitles": "Tekstitykset", + "OptionHasSpecialFeatures": "Erikoisominaisuudet", + "OptionFriday": "Perjantai", + "OptionFavorite": "Suosikit", + "OptionExtractChapterImage": "Ota käyttöön kappalekuvien luonti", + "OptionExternallyDownloaded": "Ulkoinen lataus", + "OptionEveryday": "Joka päivä", + "OptionEnded": "Loppuneet", + "OptionEnableM2tsMode": "Ota käyttöön M2ts tila", + "OptionEnableForAllTuners": "Ota käyttöön kaikille viritinlaitteille", + "OptionEnableAccessToAllLibraries": "Salli pääsy kaikkiin kirjastoihin", + "OptionEnableAccessToAllChannels": "Salli pääsy kaikille kanaville", + "OptionEnableAccessFromAllDevices": "Salli pääsy kaikista laitteista", + "OptionDvd": "DVD", + "OptionDownloadThumbImage": "Pienoiskuva", + "OptionDownloadPrimaryImage": "Ensisijainen", + "OptionDownloadMenuImage": "Valikko", + "OptionDownloadLogoImage": "Logo", + "OptionDownloadImagesInAdvance": "Lataa kuvat etukäteen", + "OptionDislikes": "Disliket", + "OptionCustomUsers": "Mukautettu", + "OptionCriticRating": "Kriitikoiden luokitus", + "OptionContinuing": "Jatkuvat", + "OptionCommunityRating": "Yhteisön luokitus", + "OptionBlockLiveTvChannels": "Live-TV kanavat", + "OptionBanner": "Juliste", + "OnlyForcedSubtitlesHelp": "Vain pakotetuiksi merkityt tekstitykset ladataan.", + "OnlyImageFormats": "Vain kuvaformaatit (VOBSUB, PGS, SUB)", + "OnlyForcedSubtitles": "Vain pakotetut", + "NoSubtitlesHelp": "Tekstityksiä ei ladata oletuksena. Ne voidaan silti kytkeä päälle manuaalisesti toiston aikana.", + "News": "Uutiset", + "Never": "Ei koskaan", + "MessageReenableUser": "Ottaaksesi uudelleen käyttöön, katso alempaa", + "MessagePluginConfigurationRequiresLocalAccess": "Kirjaudu suoraan paikalliselle palvelimellesi muokataksesi tätä liitännäistä.", + "MessagePleaseEnsureInternetMetadata": "Varmista, että metadatan lataus on käytössä.", + "MessageNoServersAvailable": "Automaattisen palvelintunnistuksen avulla ei löydy palvelimia.", + "MessageUnauthorizedUser": "Sinulla ei ole lupaa käyttää palvelinta tällä hetkellä. Ota yhteyttä palvelimen järjestelmänvalvojaan saadaksesi lisätietoja.", + "MessageInvalidForgotPasswordPin": "PIN-koodi on kelpaa tai vanhentunut. Yritä uudelleen.", + "MessageImageTypeNotSelected": "Valitse kuvatyyppi pudotusvalikosta.", + "MessageImageFileTypeAllowed": "Vain JPEG ja PNG tiedostomuotoja tuetaan.", + "MessageContactAdminToResetPassword": "Ota yhteyttä järjestelmänvalvojaan nollataksesi salasanasi.", + "MessageConfirmShutdown": "Haluatko varmasti sammuttaa palvelimen?", + "LabelUserLibrary": "Käyttäjän kirjasto:", + "LabelTranscodingProgress": "Transkoodauksen edistyminen:", + "LabelTranscodingFramerate": "Transkoodauksen ruudunpäivitysnopeus:", + "LabelTranscodes": "Transkoodaukset:", + "LabelTrackNumber": "Raidan numero:", + "LabelTitle": "Nimi:", + "LabelTagline": "Tunnisterivi:", + "LabelSubtitlePlaybackMode": "Tekstitystila:", + "LabelSortOrder": "Lajittelujärjestys:", + "LabelSerialNumber": "Sarjanumero", + "LabelSendNotificationToUsers": "Lähetä ilmoitus:", + "LabelSelectVersionToInstall": "Valitse asennettava versio:", + "LabelPublicHttpsPortHelp": "Paikalliseen HTTPS-porttiin liitettävä julkisen portin numero.", + "LabelPublicHttpPortHelp": "Paikalliseen HTTP-porttiin liitettävä julkisen portin numero.", + "LabelPreferredDisplayLanguage": "Ensisijainen näyttökieli:", + "LabelOriginalTitle": "Alkuperäinen nimi:", + "LabelOriginalAspectRatio": "Alkuperäinen kuvasuhde:", + "LabelEnableAutomaticPortMapHelp": "Yritä automaattisesti yhdistää julkinen ja paikallinen portti UPnP:n kautta. Tämä ei välttämättä toimi kaikkien reitittimien kanssa. Muutokset tulevat voimaan vasta palvelimen uudelleenkäynnistyksen yhteydessä.", + "LabelEnableAutomaticPortMap": "Salli reitittimen porttien automaattinen avaaminen (UPnP)", + "LabelDownloadLanguages": "Latauskielet:", + "LabelDisplaySpecialsWithinSeasons": "Näytä erityiset jaksot kausien sisällä, jolloin ne ilmestyivät", + "LabelDisplayOrder": "Näyttöjärjestys:", + "LabelDisplayName": "Näyttönimi:", + "LabelDisplayMode": "Näyttötila:", + "LabelDateTimeLocale": "Päivämäärä ja aika:", + "LabelCustomRating": "Mukautettu luokitus:", + "LabelCustomDeviceDisplayName": "Näyttönimi:", + "LabelCustomCss": "Mukautettu CSS:", + "LabelCertificatePassword": "Sertifikaatin salasana:", + "LabelAudio": "Audio", + "LabelArtistsHelp": "Erota useita käyttämällä ;", + "LabelAppNameExample": "Esimerkiksi: Sickbeard, Sonarr", + "LabelAppName": "Sovelluksen nimi", + "LabelAllowedRemoteAddressesMode": "Etä-IP-osoitesuodattimen tila:", + "LabelAllowedRemoteAddresses": "Etä-IP-osoitesuodatin:", + "LabelAllowServerAutoRestartHelp": "Palvelin käynnistyy uudelleen vain hiljaisina aikoina, kun yksikään käyttäjä ei ole aktiivinen.", + "LabelAllowServerAutoRestart": "Salli palvelimen automaattinen uudelleenkäynnistys päivitysten asentamiseksi", + "LabelAllowHWTranscoding": "Salli laitteistolla transkoodaus", + "LabelAlbumArtMaxWidth": "Albumin kuvan maksimileveys:", + "LabelAlbumArtMaxHeight": "Albumin kuvan maksimikorkeus:", + "LabelAbortedByServerShutdown": "(Keskeytetty palvelimen sammutuksen takia)", + "Identify": "Tunnista", + "Horizontal": "Horisontaalinen", + "HideWatchedContentFromLatestMedia": "Piilota toistettu sisältö \"uusin media\"-luettelosta", + "HeaderUpcomingOnTV": "Tulossa televisiossa", + "HeaderTypeImageFetchers": "{0} Kuvien hakijat", + "HeaderTranscodingProfile": "Transkoodausprofiili", + "HeaderTracks": "Raidat", + "HeaderThisUserIsCurrentlyDisabled": "Tämä käyttäjä on poistettu käytöstä", + "HeaderSystemDlnaProfiles": "Järjestelmäprofiilit", + "HeaderSubtitleDownloads": "Tekstitysten lataukset", + "HeaderSpecialFeatures": "Lisäominaisuudet", + "HeaderSpecialEpisodeInfo": "Erikoisjakson tiedot", + "HeaderSortOrder": "Lajittelujärjestys", + "HeaderSetupLibrary": "Aseta mediakirjastosi", + "HeaderSeriesStatus": "Sarjan status", + "HeaderSeriesOptions": "Sarjan asetukset", + "HeaderSelectTranscodingPath": "Valitse transkoodauksen väliaikainen polku", + "HeaderSchedule": "Ajastus", + "HeaderScenes": "Kohtaukset", + "HeaderResponseProfile": "Vastausprofiili", + "HeaderRemoveMediaLocation": "Poista mediasijainti", + "HeaderRecordingOptions": "Tallennusasetukset", + "HeaderRecentlyPlayed": "Äskettäin toistetut", + "HeaderProfileServerSettingsHelp": "Nämä arvot mukauttavat sitä, kuinka Jellyfin-palvelin esittää itsensä laitteelle.", + "HeaderProfileInformation": "Profiili-informaatio", + "HeaderPreferredMetadataLanguage": "Ensisijainen metadatan kieli", + "HeaderPinCodeReset": "Nollaa PIN-koodi", + "HeaderPhotoAlbums": "Kuva-albumit", + "HeaderPendingInvitations": "Odottavat kutsut", + "HeaderPaths": "Polut", + "HeaderPasswordReset": "Salasanan nollaus", + "HeaderNextVideoPlayingInValue": "Seuraava video alkaa {0}", + "HeaderNextEpisodePlayingInValue": "Seuraava jakso alkaa {0}", + "HeaderNewDevices": "Uudet laitteet", + "HeaderMyMediaSmall": "Minun mediani (pieni)", + "HeaderMyMedia": "Minun mediani", + "HeaderMyDevice": "Minun laitteeni", + "HeaderLoginFailure": "Kirjautumisvirhe", + "HeaderIdentifyItemHelp": "Anna yksi tai useampi hakukriteeri. Poista kriteerejä lisätäksesi hakutuloksia.", + "HeaderIdentificationCriteriaHelp": "Lisää ainakin yksi tunnistuskriteeri.", + "HeaderFeatures": "Ominaisuudet", + "HeaderFavoriteVideos": "Suosikkivideot", + "HeaderFavoritePeople": "Suosikki-ihmiset", + "HeaderFavoriteMovies": "Suosikkielokuvat", + "HeaderFavoriteBooks": "Suosikkikirjat", + "HeaderExternalIds": "Ulkoiset IDt:", + "HeaderDirectPlayProfile": "Suoratoistoprofiili", + "HeaderEasyPinCode": "Helppo PIN-koodi", + "HeaderDownloadSync": "Lataus ja synkronointi", + "HeaderDeveloperInfo": "Kehittäjäinfo", + "HeaderDetectMyDevices": "Havaitse laitteitani", + "HeaderDeleteProvider": "Poista tarjoaja", + "HeaderDefaultRecordingSettings": "Oletus tallennusasetukset", + "HeaderDateIssued": "Antopäivä", + "HeaderCustomDlnaProfiles": "Mukautetut profiilit", + "HeaderConfirmRevokeApiKey": "Peru API-avain", + "HeaderConfirmProfileDeletion": "Vahvista profiilin poisto", + "HeaderConfirmPluginInstallation": "Vahvista liitännäisen asennus", + "HeaderConfigureRemoteAccess": "Määritä etäkäyttö", + "HeaderChapterImages": "Kappalekuvat", + "HeaderChannels": "Kanavat", + "HeaderApp": "Sovellus", + "HeaderAllowMediaDeletionFrom": "Salli median poisto", + "HeaderAlert": "Hälytys", + "HeaderActivity": "Toiminta", + "HandledByProxy": "Reverse proxyn hoitama", + "HDPrograms": "HD-ohjelmat", + "OptionDownloadArtImage": "Taide", + "OptionDownloadDiscImage": "Levy", + "OptionDownloadBoxImage": "Laatikko", + "OptionDownloadBannerImage": "Juliste", + "OptionDownloadBackImage": "Tausta", + "OptionDisableUser": "Poista tämä käyttäjä käytöstä", + "OptionDescending": "Laskeva", + "OptionDatePlayed": "Toistopäivä", + "OptionDateAddedImportTime": "Käytä kirjastoon skannauspäivää", + "OptionDateAddedFileTime": "Käytä tiedoston luontipäivää", + "OptionDateAdded": "Lisäyspäivä", + "OptionDaily": "Päivittäinen", + "OptionBluray": "Blu-ray", + "TabTrailers": "Trailerit", + "OptionBlockTvShows": "TV-sarjat", + "OptionBlockTrailers": "Trailerit", + "OptionBlockMusic": "Musiikki", + "OptionBlockMovies": "Elokuvat", + "HeaderMovies": "Elokuvat", + "HeaderMoreLikeThis": "Lisää tällaista", + "HeaderMetadataSettings": "Metadata-asetukset", + "MoreMediaInfo": "Mediainfo", + "HeaderMediaInfo": "Mediainfo", + "HeaderMediaFolders": "Mediakansiot", + "HeaderMedia": "Media", + "HeaderLiveTv": "Live-TV", + "HeaderLibraryFolders": "Kirjaston kansiot", + "HeaderLatestMedia": "Uusin media", + "HeaderLatestRecordings": "Uusimmat tallenteet", + "HeaderLatestMusic": "Uusin musiikki", + "HeaderLatestMovies": "Uusimmat elokuvat", + "HeaderLatestEpisodes": "Uusimmat jaksot", + "HeaderInstall": "Asenna", + "HeaderGenres": "Tyylilajit", + "HeaderFrequentlyPlayed": "Usein toistetut", + "HeaderFetcherSettings": "Hakijan asetukset", + "HeaderFetchImages": "Hae kuvia:", + "HeaderFilters": "Suodattimet", + "OptionBlockBooks": "Kirjat", + "Filters": "Suodattimet", + "FastForward": "Hyppää eteenpäin", + "YadifBob": "YADIF Bob", + "MessageInvalidUser": "Väärä käyttäjätunnus tai salasana. Yritä uudelleen.", + "MessageConfirmRestart": "Haluatko varmasti uudelleenkäynnistää Jellyfin-palvelimen?", + "MessageConfirmProfileDeletion": "Haluatko varmasti poistaa tämän profiilin?", + "MessageConfirmDeleteTunerDevice": "Haluatko varmasti poistaa tämän laitteen?", + "MessageConfirmAppExit": "Haluatko poistua?", + "MessageAreYouSureYouWishToRemoveMediaFolder": "Haluatko varmasti poistaa tämän mediakansion?", + "MessageAreYouSureDeleteSubtitles": "Haluatko varmasti poistaa tämän tekstitystiedoston?", + "MessageAlreadyInstalled": "Tämä versio on jo asennettu.", + "Menu": "Valikko", + "MediaInfoStreamTypeVideo": "Video", + "MediaInfoStreamTypeSubtitle": "Tekstitys", + "MediaInfoStreamTypeData": "Data", + "MediaInfoStreamTypeAudio": "Audio", + "MediaInfoSoftware": "Ohjelmisto", + "MediaInfoTimestamp": "Aikaleima", + "MediaInfoResolution": "Resoluutio", + "MediaInfoSize": "Koko", + "MediaInfoProfile": "Profiili", + "MediaInfoLevel": "Taso", + "MediaInfoPath": "Polku", + "MediaInfoLanguage": "Kieli", + "MediaInfoInterlaced": "Lomiteltu", + "MediaInfoFramerate": "Ruudunpäivitysnopeus", + "MediaInfoForced": "Pakotettu", + "MediaInfoDefault": "Oletus", + "MediaInfoExternal": "Ulkoinen", + "MediaInfoChannels": "Kanavat", + "MediaInfoAspectRatio": "Kuvasuhde", + "MarkUnplayed": "Merkitse toistamattomaksi", + "MarkPlayed": "Merkitse toistetuksi", + "ManageRecording": "Hallitse tallennusta", + "ManageLibrary": "Hallitse kirjastoa", + "Logo": "Logo", + "LiveTV": "Live-TV", + "LiveBroadcasts": "Suorat lähetykset", + "Live": "Suora", + "List": "Lista", + "LinksValue": "Linkkejä: {0}", + "LearnHowYouCanContribute": "Katso, miten voit auttaa.", + "Large": "Suuri", + "LabelffmpegPath": "FFmpeg polku:", + "LabelZipCode": "Postinumero:", + "LabelYear": "Vuosi:", + "LabelVideoResolution": "Videon resoluutio:", + "LabelVideo": "Video", + "DashboardArchitecture": "Arkkitehtuuri: {0}", + "DashboardOperatingSystem": "Käyttöjärjestelmä: {0}", + "DashboardServerName": "Palvelin: {0}", + "DashboardVersionNumber": "Versio: {0}", + "LabelVersionInstalled": "{0} asennettu", + "LabelVersion": "Versio:", + "LabelValue": "Arvo:", + "LabelUsername": "Käyttäjätunnus:", + "LabelUser": "Käyttäjä:", + "LabelUseNotificationServices": "Käytä seuraavia palveluita:", + "LabelTypeText": "Teksti", + "LabelTypeMetadataDownloaders": "{0} metadatan lataajat:", + "LabelType": "Tyyppi:", + "LabelTunerType": "Virittimen tyyppi:", + "LabelTunerIpAddress": "Virittimen IP-osoite:", + "LabelTranscodingThreadCountHelp": "Valitse enimmäismäärä säikeitä, joita käytetään transkoodatessa. Säikeiden vähentäminen laskee prosessorin käyttöä, mutta myös lisää riskiä, että uudelleenkoodaus ei tapahdu riittävän nopeasti virheetöntä toistoa varten.", + "LabelTranscodingThreadCount": "Transkoodaus säikeidein lukumäärä:", + "LabelTranscodePath": "Transkoodauksen polku:", + "LabelTimeLimitHours": "Aikaraja (tunteina):", + "LabelTime": "Aika:", + "LabelTheme": "Teema:", + "LabelTextSize": "Tekstin koko:", + "LabelTextColor": "Tekstin väri:", + "LabelTextBackgroundColor": "Tekstin taustaväri:", + "LabelSupportedMediaTypes": "Tuetut mediatyypit:", + "LabelTag": "Tunniste:", + "LabelSubtitles": "Tekstitykset", + "LabelSubtitleFormatHelp": "Esimerkki: srt", + "LabelStatus": "Status:", + "LabelSource": "Lähde:", + "LabelSize": "Koko:", + "LabelServerName": "Palvelimen nimi:", + "LabelServerHostHelp": "192.168.1.100:8096 tai https://myserver.com", + "LabelSelectUsers": "Valitse käyttäjät:", + "LabelSeasonNumber": "Kauden numero:", + "LabelScreensaver": "Näytönsäästäjä:", + "LabelReasonForTranscoding": "Transkoodauksen syy:", + "LabelReadHowYouCanContribute": "Katso, miten voit auttaa.", + "LabelPublicHttpsPort": "Julkinen HTTPS-porttinumero:", + "LabelPublicHttpPort": "Julkinen HTTP-porttinumero:", + "LabelProtocolInfo": "Protokollan info:", + "LabelProtocol": "Protokolla:", + "LabelPreferredSubtitleLanguage": "Ensisijainen tekstityksen kieli:", + "LabelPreferredDisplayLanguageHelp": "Jellyfinin kääntäminen on käynnissä oleva projekti.", + "LabelPlayerDimensions": "Soittimen mitat:", + "LabelPlayer": "Soitin:", + "LabelPlaylist": "Soittolista:", + "LabelPlaceOfBirth": "Synnyinpaikka:", + "LabelPersonRoleHelp": "Esimerkki: Jäätelöauton ajaja", + "LabelPersonRole": "Rooli:", + "LabelPath": "Polku:", + "LabelPasswordRecoveryPinCode": "PIN-koodi:", + "LabelPasswordConfirm": "Salasanan varmistus:", + "LabelPassword": "Salasana:", + "LabelOptionalNetworkPath": "(Valinnainen) Jaettu verkkokansio:", + "LabelNumber": "Numero:", + "LabelNotificationEnabled": "Ota tämä ilmoitus käyttöön", + "LabelNewName": "Uusi nimi:", + "LabelName": "Nimi:", + "LabelMovieCategories": "Elokuvakategoriat:", + "LabelMinScreenshotDownloadWidth": "Pienin kuvakaappauksen latauksen leveys:", + "LabelMinResumePercentageHelp": "Kohteita pidetään toistamattomina, jos toisto keskeytetään ennen tätä aikaa.", + "LabelMinResumeDuration": "Minimi jatkamisen kesto (sekuntia):", + "LabelMinResumePercentage": "Vähimmäisaika jatkoa varten (%):", + "LabelMinResumeDurationHelp": "Kohteiden, joiden toistoaika on tätä lyhyempi, ei voi jatkaa.", + "LabelMethod": "Metodi:", + "LabelMetadataSaversHelp": "Valitse tiedostomuodot, joihin metadata tallennetaan.", + "LabelMetadataSavers": "Metadatan tallentajat:", + "LabelMetadataDownloadLanguage": "Ensisijainen latauskieli:", + "LabelMetadataReaders": "Metadatan lukijat:", + "LabelMetadataPath": "Metadatan polku:", + "LabelMetadata": "Metadata:", + "LabelMessageTitle": "Viestin otsikko:", + "LabelCachePath": "Välimuistin polku:", + "LabelCache": "Välimuisti:", + "LabelBurnSubtitles": "Polta tekstitykset:", + "LabelAutomaticallyRefreshInternetMetadataEvery": "Päivitä metadata automaattisesti:", + "LabelAuthProvider": "Todennuksen tarjoaja:", + "ExtraLarge": "Suurin", + "EveryNDays": "Joka {0} päivä", + "Raised": "Korotettu", + "TabShows": "Sarjat", + "Yesterday": "Eilen", + "Yes": "Kyllä", + "Unplayed": "Toistamattomat", + "Unmute": "Lopeta vaimennus", + "Tuesday": "Tiistai", + "Transcoding": "Transkoodaus", + "Trailers": "Trailerit", + "TitlePlayback": "Toistaminen", + "Thursday": "Torstai", + "TheseSettingsAffectSubtitlesOnThisDevice": "Nämä asetukset vaikuttavat tekstityksiin tällä laitteella", + "ThemeVideos": "Tunnusvideot", + "ThemeSongs": "Tunnuslaulut", + "TagsValue": "Tunnisteet: {0}", + "Tags": "Tunnisteet", + "TabUsers": "Käyttäjät", + "TabUpcoming": "Tulevat", + "TabTranscoding": "Transkoodaus", + "TabSuggestions": "Ehdotukset", + "TabSongs": "Kappaleet", + "TabSettings": "Asetukset", + "TabServer": "Palvelin", + "TabSeries": "Sarjat", + "TabScheduledTasks": "Ajastetut tehtävät", + "TabResumeSettings": "Jatka", + "TabResponses": "Vastaukset", + "TabRecordings": "Tallennukset", + "TabPlugins": "Liitännäiset", + "TabPlaylists": "Soittolistat", + "TabPlaylist": "Soittolista", + "TabPlayback": "Toistaminen", + "TabNfoSettings": "NFO-asetukset", + "TabNetworks": "Verkot", + "TabMyPlugins": "Omat liittännäiseni", + "TabMusicVideos": "Musiikkivideot", + "TabMusic": "Musiikki", + "TabMovies": "Elokuvat", + "TabMetadata": "Metadata", + "TabLogs": "Lokit", + "TabLiveTV": "Live-TV", + "TabLatest": "Uusimmat", + "TabInfo": "Info", + "TabGenres": "Tyylilajit", + "TabFavorites": "Suosikit", + "TabEpisodes": "Jaksot", + "TabDisplay": "Näyttö", + "TabDirectPlay": "Suoratoisto", + "TabDevices": "Laitteet", + "TabDashboard": "Päänäkymä", + "TabCollections": "Kokoelmat", + "TabChannels": "Kanavat", + "TabCatalog": "Luettelo", + "TabArtists": "Artistit", + "TabAlbums": "Albumit", + "TabAlbumArtists": "Albumin artistit", + "TabAdvanced": "Edistynyt", + "TV": "TV", + "Sunday": "Sunnuntai", + "Subtitles": "Tekstitykset", + "Studios": "Studiot", + "StopRecording": "Lopeta tallennus", + "Sort": "Järjestä", + "Smart": "Älykäs", + "SkipEpisodesAlreadyInMyLibrary": "Älä tallenna jaksoja, jotka ovat jo kirjastossani", + "Shuffle": "Sekoita", + "ShowTitle": "Näytä nimi", + "ShowYear": "Näytä vuosi", + "ShowAdvancedSettings": "Näytä edistyneet asetukset", + "Share": "Jaa", + "Settings": "Asetukset", + "ServerRestartNeededAfterPluginInstall": "Jellyfin palvelin täytyy uudelleenkäynnistää liitännäisen asennuksen jälkeen.", + "ServerNameIsShuttingDown": "Jellyfin palvelin - {0} on sammumassa.", + "ServerNameIsRestarting": "Jellyfin palvelin - {0} uudelleenkäynnistyy.", + "Series": "Sarjat", + "SendMessage": "Lähetä viesti", + "SelectAdminUsername": "Valitse käyttäjätunnus järjestelmänvalvojan tilille.", + "SearchForCollectionInternetMetadata": "Etsi kuvamateriaalia ja metadataa internetistä", + "SearchForMissingMetadata": "Etsi puuttuvaa metadataa", + "Season": "Kausi", + "SearchResults": "Tulokset", + "SearchForSubtitles": "Etsi tekstityksiä", + "Search": "Etsi", + "Screenshots": "Kuvakaappaukset", + "Screenshot": "Kuvakaappaus", + "Schedule": "Ajasta", + "ScanLibrary": "Skannaa kirjasto", + "SaveSubtitlesIntoMediaFolders": "Tallenna tekstitykset mediakansioihin", + "Saturday": "Lauantai", + "ResumeAt": "Jatka kohdasta {0}", + "RestartPleaseWaitMessage": "Odota kunnes Jellyfin palvelin sammuu ja käynnistyy uudelleen. Tämä voi kestää hetken aikaa.", + "RequiredForAllRemoteConnections": "Vaadittu kaikille etäyhteyksille", + "ReplaceExistingImages": "Korvaa olemassaolevat kuvat", + "ReplaceAllMetadata": "Korvaa kaikki metadata", + "RepeatEpisodes": "Toista jaksot uudelleen", + "RepeatAll": "Toista kaikki uudelleen", + "Repeat": "Toista uudelleen", + "RemoveFromPlaylist": "Poista soittolistalta", + "RemoveFromCollection": "Poista kokoelmasta", + "RememberMe": "Muista minut", + "ReleaseDate": "Julkaisupäivä", + "RefreshMetadata": "Päivitä metadata", + "RefreshDialogHelp": "Metadata päivitetään asetuksien ja Internet palveluiden perusteella, jotka ovat kytkettynä päälle Jellyfin palvelimen päänäkymässä.", + "Refresh": "Päivitä", + "Recordings": "Tallennukset", + "RecordingScheduled": "Tallennus ajastettu.", + "RecordingCancelled": "Tallennus peruttu.", + "RecordSeries": "Tallenna sarja", + "Record": "Tallenna", + "OptionAutomatic": "Auto", + "OptionAuto": "Auto", + "OptionAscending": "Nouseva", + "OptionArtist": "Artisti", + "OptionAllowVideoPlaybackTranscoding": "Salli transkoodausta vaativan videon toistaminen", + "OptionAllowVideoPlaybackRemuxing": "Salli videon toistaminen, joka vaatii muuntamista ilman koodausta", + "OptionAllowMediaPlaybackTranscodingHelp": "Transkoodauksen estäminen voi aiheuttaa toistovirheitä Jellyfin-sovelluksissa ei-tuettujen mediaformaattien takia.", + "OptionAllowLinkSharingHelp": "Vain mediatietoja sisältävät web-sivut jaetaan. Mediatiedostoja ei koskaan jaeta julkisesti. Jaot ovat määräaikaisia ja päättyvät {0} päivän kuluttua.", + "OptionAllowUserToManageServer": "Salli tämän käyttäjän hallita palvelinta", + "OptionAllowSyncTranscoding": "Salli transkoodausta vaativan median lataaminen ja synkronointi", + "OptionAllowRemoteSharedDevicesHelp": "DLNA-laitteet katsotaan jaetuiksi kunnes käyttäjä alkaa ohjata niitä.", + "OptionAllowRemoteSharedDevices": "Salli jaettujen laitteiden etäohjaaminen", + "OptionAllowRemoteControlOthers": "Salli muiden käyttäjien etäohjaaminen", + "OptionAllowManageLiveTv": "Salli Live-TV tallenteiden hallinta", + "OptionAllowMediaPlayback": "Salli median toisto", + "OptionAllowContentDownloading": "Salli median lataaminen ja synkronointi", + "OptionAllowBrowsingLiveTv": "Salli Live-TV käyttöoikeus", + "HeaderPluginInstallation": "Liitännäisen asennus", + "HeaderPlaybackError": "Toistovirhe", + "HeaderPlayback": "Median toisto", + "HeaderPlayOn": "Toista laitteella", + "OptionAllowLinkSharing": "Salli jakaminen sosiaaliseen mediaan", + "OptionAllowAudioPlaybackTranscoding": "Salli äänen toistaminen joka vaatii uudelleenpakkausta", + "OptionAllUsers": "Kaikki käyttäjät", + "OptionAlbumArtist": "Albumin artisti", + "OptionAlbum": "Albumi", + "OptionAdminUsers": "Järjestelmänvalvojat", + "Option3D": "3D", + "MusicVideo": "Musiikkivideo", + "MoveRight": "Siirry oikealle", + "MoveLeft": "Siirry vasemmalle", + "Mobile": "Mobiili", + "EveryXHours": "Joka {0} tunti", + "EveryXMinutes": "Joka {0} minuutti", + "EveryHour": "Joka tunti", + "LastSeen": "Viimeksi nähty {0}", + "Yadif": "YADIF", + "Writer": "Kirjoittaja", + "WelcomeToProject": "Tervetuloa Jellyfiniin!", + "Wednesday": "Keskiviikko", + "ViewArtist": "Näytä artisti", + "ViewAlbum": "Näytä albumi", + "Vertical": "Vertikaalinen", + "ValueSongCount": "{0} kappaletta", + "ValueSeriesCount": "{0} sarjaa", + "ValueSeconds": "{0} sekuntia", + "ValueOneSong": "1 kappale", + "ValueOneSeries": "1 sarja", + "ValueOneMusicVideo": "1 musiikkivideo", + "ValueOneMovie": "1 elokuva", + "ValueOneEpisode": "1 jakso", + "ValueOneAlbum": "1 albumi", + "ValueMusicVideoCount": "{0} musiikkivideota", + "ValueMovieCount": "{0} elokuvaa", + "ValueMinutes": "{0} min", + "ValueEpisodeCount": "{0} jaksoa", + "ValueDiscNumber": "Levy {0}", + "ValueAlbumCount": "{0} albumia", + "Up": "Ylös", + "OnApplicationStartup": "Käynnistyksen yhteydessä", + "NumLocationsValue": "{0} kansiota", + "NoSubtitleSearchResultsFound": "Ei tuloksia.", + "NoPluginConfigurationMessage": "Tällä liitännäisellä ei ole asetuksia muokattavaksi.", + "NoCreatedLibraries": "Vaikuttaa siltä, ettet ole luonut vielä yhtään kirjastoa. {0} Haluaisitko luoda sellaisen nyt?{1}", + "No": "Ei", + "NextUp": "Seuraavana", + "Next": "Seuraava", + "NewEpisodesOnly": "Vain uudet jaksot", + "NewEpisodes": "Uusia jaksoja", + "NewCollectionNameExample": "Esimerkki: Star Wars Kokoelma", + "NewCollectionHelp": "Kokoelmat mahdollistavat elokuvien ja muun kirjastosisällön personalisoidun ryhmittämisen.", + "NewCollection": "Uusi kokoelma", + "Mute": "Vaimenna", + "Name": "Nimi", + "MySubtitles": "Minun tekstitykseni", + "MusicArtist": "Musiikkiartisti", + "MusicAlbum": "Musiikkialbumi", + "Movie": "Elokuva", + "Monday": "Maanantai", + "MetadataManager": "Metadatan hallintatyökalu", + "Metadata": "Metadata", + "MessageYouHaveVersionInstalled": "Sinulla on versio {0} asennettuna.", + "MessageSettingsSaved": "Asetukset tallennettu.", + "MessagePleaseWait": "Ole hyvä ja odota. Tämä voi kestää hetken.", + "MessageNothingHere": "Täällä ei ole mitään.", + "MessageNoPluginsInstalled": "Sinulla ei ole asennettuna yhtään liitännäistä.", + "MessageNoAvailablePlugins": "Ei saatavilla olevia liitännäisiä.", + "InstallingPackage": "Asennetaan {0} (versio {1})", + "HeaderVideoTypes": "Videotyypit", + "HeaderVideoType": "Videotyyppi", + "HeaderUploadImage": "Lataa kuva", + "HeaderTypeText": "Kirjoita teksti", + "HeaderTunerDevices": "Viritinlaitteet", + "HeaderTuners": "Virittimet", + "HeaderTaskTriggers": "Tehtävän laukaisijat", + "HeaderSubtitleProfilesHelp": "Tekstitysprofiilit kuvaavat tämän laitteen tukemia tekstitysformaatteja.", + "HeaderSubtitleProfiles": "Tekstitysprofiilit", + "HeaderSubtitleProfile": "Tekstitysprofiili", + "HeaderStartNow": "Aloita nyt", + "HeaderSortBy": "Lajittele", + "HeaderSelectServerCachePath": "Valitse palvelimen välimuistin polku", + "HeaderSelectPath": "Valitse polku", + "HeaderSelectCertificatePath": "Valitse sertifikaatin polku", + "HeaderSelectMetadataPath": "Valitse metadatan polku", + "HeaderSecondsValue": "{0} Sekuntia", + "HeaderRunningTasks": "Käynnissä olevat tehtävät", + "HeaderRevisionHistory": "Versiohistoria", + "HeaderRestartingServer": "Uudelleenkäynnistetään palvelinta", + "HeaderRemoveMediaFolder": "Poista mediakansio", + "HeaderRemoteControl": "Etäohjaus", + "HeaderPleaseSignIn": "Ole hyvä ja kirjaudu sisään", + "BoxSet": "Laatikkosarja", + "LabelAccessEnd": "", + "LabelManufacturerUrl": "Valmistajan verkko-osoite", + "LabelManufacturer": "Valmistaja:", + "LabelLogs": "Lokit:", + "LabelLanNetworks": "Lähiverkot:", + "LabelKodiMetadataDateFormat": "Julkaisupäivämäärän muoto:", + "LabelImageType": "Kuvan tyyppi:", + "LabelIconMaxWidth": "Ikonin enimmäisleveys:", + "LabelIconMaxHeight": "Ikonin enimmäiskorkeus:", + "LabelGroupMoviesIntoCollections": "Ryhmitä elokuvat kokoelmiin", + "LabelFormat": "Muoto:", + "LabelFont": "Kirjasinlaji:", + "LabelFolder": "Kansio:", + "LabelEpisodeNumber": "Jaksonumero:", + "LabelDropShadow": "Varjostus:", + "LabelDeathDate": "Kuolinpäivä:", + "LabelDay": "Päivä:", + "LabelDateAdded": "Lisäyspäivämäärä:", + "LabelCollection": "Kokoelma:", + "LabelBirthYear": "Syntymävuosi:", + "LabelBirthDate": "Syntymäaika:", + "LabelArtists": "Artistit:", + "LabelAll": "Kaikki", + "LabelAlbum": "Albumi:", + "LabelAirTime": "Lähetysaika:", + "LabelAccessDay": "Viikonpäivä:", + "Label3DFormat": "3D-formaatti:", + "Kids": "Lapset", + "Images": "Kuvat", + "Hide": "Piilota", + "HeadersFolders": "Kansiot", + "HeaderYears": "Vuodet", + "HeaderVideos": "Videot", + "HeaderVideoQuality": "Kuvanlaatu", + "HeaderUsers": "Käyttäjät", + "HeaderUser": "Käyttäjä", + "HeaderTags": "Tunnisteet", + "HeaderSubtitleAppearance": "Tekstityksen ulkonäkö", + "HeaderStatus": "Tila", + "HeaderShutdown": "Sammuta", + "HeaderServerSettings": "Palvelimen asetukset", + "HeaderSettings": "Asetukset", + "HeaderSendMessage": "Lähetä viesti", + "HeaderSelectServer": "Valitse palvelin", + "HeaderSeasons": "Kaudet", + "HeaderRestart": "Uudelleenkäynnistys", + "HeaderProfile": "Profiili", + "HeaderPlayAll": "Toista kaikki", + "HeaderPeople": "Ihmiset", + "HeaderPassword": "Salasana", + "HeaderNewApiKey": "Uusi API-avain", + "HeaderNavigation": "Navigaatio", + "HeaderMusicVideos": "Musiikkivideot", + "HeaderMusicQuality": "Musiikin laatu", + "HeaderLibraries": "Kirjastot", + "HeaderIdentification": "Tunnistautuminen", + "HeaderForgotPassword": "Unohtuiko salasana", + "HeaderForKids": "Lapsille", + "HeaderError": "Virhe", + "HeaderEpisodes": "Jaksot", + "HeaderEditImages": "Muokkaa kuvia", + "HeaderDisplay": "Näyttö", + "HeaderDevices": "Laitteet", + "HeaderDeleteItems": "Poista valitut", + "HeaderDeleteItem": "Poista valittu", + "HeaderDeleteDevice": "Poista laite", + "HeaderContinueListening": "Jatka kuuntelua", + "HeaderConnectionFailure": "Yhteys epäonnistui", + "HeaderConnectToServer": "Yhdistä palvelimeen", + "HeaderAudioSettings": "Ääniasetukset", + "GroupBySeries": "Ryhmitä sarjan perusteella", + "Fullscreen": "Kokonäyttötila", + "HeaderBooks": "Kirjat", + "HeaderAutomaticUpdates": "Automaattiset päivitykset", + "HeaderAudioBooks": "Äänikirjat", + "HeaderApiKeys": "API-avaimet", + "HeaderApiKey": "API-avain", + "HeaderAdmin": "Ylläpitäjä", + "HeaderAlbums": "Albumit", + "HeaderAddUser": "Lisää käyttäjä", + "HeaderAddUpdateImage": "Lisää/Päivitä kuva", + "HeaderAddToPlaylist": "Lisää soittolistaan", + "HeaderAddToCollection": "Lisää kokoelmaan", + "HeaderActiveDevices": "Aktiiviset laitteet", + "Friday": "Perjantai", + "Premiere": "Ensiesitys", + "Producer": "Tuottaja", + "Quality": "Laatu", + "LabelMessageText": "Viestin sisältö:", + "LabelMaxScreenshotsPerItem": "Kuvakaappausten enimmäismäärä per kohde:", + "LabelLoginDisclaimerHelp": "Viesti, joka näytetään kirjautumissivun alareunassa.", + "LabelLockItemToPreventChanges": "Lukitse tämä kohde estääksesi tulevat muutokset", + "LabelLocalHttpServerPortNumberHelp": "TCP-portin numero, jota Jellyfinin HTTP-palvelimen tulee kuunnella.", + "LabelLocalHttpServerPortNumber": "Paikallisen HTTP-portin numero:", + "LabelKodiMetadataSaveImagePaths": "Tallenna kuvien polut NFO-tiedostojen sisälle", + "LabelKidsCategories": "Lasten kategoriat:", + "LabelHttpsPortHelp": "TCP-portin numero, jota Jellyfinin HTTPS-palvelimen tulee kuunnella.", + "LabelHttpsPort": "Paikallisen HTTPS-portin numero:", + "LabelHardwareAccelerationTypeHelp": "Laitteistokiihdytys vaatii ylimääräistä määritystä.", + "LabelHardwareAccelerationType": "Laitteistokiihdytys:", + "LabelEncoderPreset": "H264 and H265 encoding preset:", + "LabelH264Crf": "H264 encoding CRF:", + "LabelForgotPasswordUsernameHelp": "Anna käyttäjätunnuksesi, jos muistat sen.", + "LabelEveryXMinutes": "Joka:", + "LabelEndDate": "Päättymispäivä:", + "LabelEnableDlnaClientDiscoveryIntervalHelp": "Määrittää, kuinka usein Jellyfin etsii SSDP-protokollaa käyttäviä laitteita.", + "LabelEnableDlnaDebugLoggingHelp": "Luo suuria lokitiedostoja ja tulisi käyttää vain tarvittaessa vianmääritystä varten.", + "LabelEnableDlnaServerHelp": "Sallii verkon UPnP-laitteiden selata ja toistaa sisältöä tältä palvelimelta.", + "LabelEnableDlnaServer": "Ota DLNA-palvelin käyttöön", + "LabelEnableDlnaPlayTo": "Salli DLNA toisto", + "LabelEnableDlnaDebugLogging": "Ota DLNA:n virheenjäljitys käyttöön", + "LabelEnableBlastAliveMessages": "Lähetä hereilläolo -viesti", + "LabelEnableBlastAliveMessagesHelp": "Ota tämä käyttöön, jos muilla verkon UPnP-laitteilla on ongelmia palvelimen havaitsemisessa.", + "LabelEnableDlnaClientDiscoveryInterval": "Asiakaslaitteiden havaintoväli (sekunteina)", + "LabelEasyPinCode": "Helppo PIN-koodi:", + "LabelDynamicExternalId": "{0} Id:", + "LabelDisplayLanguageHelp": "Jellyfinin kääntäminen on käynnissä oleva projekti.", + "LabelDisplayLanguage": "Näytön kieli:", + "LabelDiscNumber": "Levynumero:", + "LabelDeviceDescription": "Laitteen kuvaus", + "LabelDefaultScreen": "Oletusnäyttö:", + "LabelDefaultUser": "Oletuskäyttäjä:", + "LabelDashboardTheme": "Palvelimen päänäkymän teema:", + "LabelCustomCertificatePathHelp": "Polku PKCS # 12-tiedostoon, joka sisältää sertifikaatin ja yksityisen avaimen, jotta TLS-tuki voidaan sallia henkilökohtaiselle verkkotunnukselle.", + "LabelCustomCertificatePath": "Mukautetun SSL-sertifikaatin polku:", + "LabelContentType": "Sisältötyyppi:", + "LabelChannels": "Kanavat:", + "LabelCertificatePasswordHelp": "Jos sertifikaattisi vaatii salasanaa, laita se tähän.", + "OptionWednesday": "Keskiviikko", + "OptionTuesday": "Tiistai", + "OptionThursday": "Torstai", + "OptionSunday": "Sunnuntai", + "OptionSaturday": "Lauantai", + "LabelRuntimeMinutes": "Pituus (minuutteja):", + "LabelReleaseDate": "Julkaisupäivä:", + "Genre": "Tyylilaji", + "FolderTypeBooks": "Kirjat", + "FolderTypeMusicVideos": "Musiikkivideot", + "FolderTypeMusic": "Musiikki", + "FolderTypeMovies": "Elokuvat", + "File": "Tiedosto", + "Favorite": "Suosikki", + "Extras": "Extrat", + "ExitFullscreen": "Poistu kokonäyttötilasta", + "Episode": "Jakso", + "ButtonTogglePlaylist": "Soittolista", + "ButtonToggleContextMenu": "Lisää", + "Artist": "Artisti" } diff --git a/src/strings/fr.json b/src/strings/fr.json index 72ea6f3ed3..3f1d22c75a 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -23,11 +23,11 @@ "AllowMediaConversion": "Autoriser la conversion des médias", "AllowMediaConversionHelp": "Autoriser ou refuser l'accès à la fonctionnalité de conversion des médias.", "AllowOnTheFlySubtitleExtraction": "Autoriser l'extraction des sous-titres à la volée", - "AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux clients au format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil ne les prend pas en charge nativement.", + "AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux clients au format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil client ne les prend pas en charge nativement.", "AllowRemoteAccess": "Autoriser les connexions distantes à ce serveur Jellyfin.", "AllowRemoteAccessHelp": "Si l'option est désactivée, toutes les connexions distantes seront bloquées.", "AllowedRemoteAddressesHelp": "Liste d'adresses IP ou d'IP/masque de sous-réseau séparées par des virgules qui seront autorisées à se connecter à distance. Si la liste est vide, toutes les adresses distantes seront autorisées.", - "AlwaysPlaySubtitles": "Toujours lancer les sous-titres", + "AlwaysPlaySubtitles": "Toujours afficher les sous-titres", "AlwaysPlaySubtitlesHelp": "Les sous-titres correspondant à la préférence linguistique seront chargés indépendamment de la langue de l'audio.", "AnyLanguage": "N'importe quel langage", "Anytime": "N'importe quand", @@ -100,7 +100,7 @@ "ButtonRemove": "Supprimer", "ButtonRename": "Renommer", "ButtonRepeat": "Répéter", - "ButtonResetEasyPassword": "Réinitialiser le code Easy PIN", + "ButtonResetEasyPassword": "Réinitialiser le code easy PIN", "ButtonResetPassword": "Réinitialiser le mot de passe", "ButtonRestart": "Redémarrer", "ButtonResume": "Reprendre", @@ -130,7 +130,7 @@ "CancelRecording": "Annuler l'enregistrement", "CancelSeries": "Annuler la série", "Categories": "Catégories", - "ChangingMetadataImageSettingsNewContent": "Les modifications des réglages de téléchargement des métadonnées et des visuels ne seront appliquées qu'au nouveau contenu ajouté à votre médiathèque. Pour appliquer ces changements aux titres existants, vous devrez actualiser leurs métadonnées manuellement.", + "ChangingMetadataImageSettingsNewContent": "Les modifications des paramètres de téléchargement des métadonnées et des illustrations ne seront appliquées qu'au contenu nouvellement ajouté à votre médiathèque. Pour appliquer ces changements aux titres pré-existants, vous devrez actualiser leurs métadonnées manuellement.", "ChannelAccessHelp": "Sélectionnez les chaînes à partager avec cet utilisateur. Les administrateurs pourront modifier toutes les chaînes en utilisant le gestionnaire de métadonnées.", "ChannelNameOnly": "Seulement la chaîne {0}", "ChannelNumber": "Numéro de chaîne", @@ -199,10 +199,10 @@ "EditMetadata": "Éditer les métadonnées", "EditSubtitles": "Modifier les sous-titres", "EnableBackdrops": "Images d'arrière-plans", - "EnableBackdropsHelp": "Afficher les images d'arrière-plans sur certaines pages pendant la navigation dans la médiathèque.", + "EnableBackdropsHelp": "Afficher des images d'arrière-plans sur certaines pages pendant la navigation dans la médiathèque.", "EnableCinemaMode": "Mode cinéma", "EnableColorCodedBackgrounds": "Fonds avec code couleur", - "EnableDisplayMirroring": "Partage d'écran", + "EnableDisplayMirroring": "Affichage en miroir", "EnableExternalVideoPlayers": "Lecteurs vidéo externes", "EnableExternalVideoPlayersHelp": "Une liste des lecteurs externes sera affichée au lancement de la lecture d'une vidéo.", "EnableHardwareEncoding": "Activer l'encodage matériel", @@ -231,7 +231,7 @@ "EveryNDays": "Tous les {0} jours", "ExitFullscreen": "Sortir du plein écran", "ExtraLarge": "Très Grand", - "ExtractChapterImagesHelp": "L'extraction d'images de chapitre permettra aux applications d'afficher des menus visuels pour la sélection des scènes. Le processus peut être long, consommateur de ressources et peut nécessiter de nombreux gigaoctets de stockage. Il s'exécute lorsque des vidéos sont découvertes et également comme tâche planifiée. La planification peut être modifiée dans les options du planificateur de tâches. Il n'est pas conseillé d'exécuter cette tâche pendant les heures d'usage intensif.", + "ExtractChapterImagesHelp": "L'extraction d'images de chapitre permettra aux applications d'afficher des menus visuels pour la sélection des scènes. Le processus peut être lent, gourmand en ressources et peut nécessiter plusieurs gigaoctets de stockage. Il s'exécute lorsque des vidéos sont découvertes et également comme tâche planifiée. L'horaire est configurable dans les options du planificateur de tâches. Il n'est pas recommandé d'exécuter cette tâche pendant les heures d'usage intensif.", "FFmpegSavePathNotFound": "Nous ne pouvons pas localiser FFmpeg en utilisant le chemin que vous avez saisi. FFprobe est également nécessaire et doit exister dans le même dossier. Ces composants sont généralement regroupés dans le même téléchargement. Veuillez vérifier le chemin et essayer à nouveau.", "FastForward": "Avance rapide", "Favorite": "Favori", @@ -274,7 +274,7 @@ "HeaderAddUser": "Ajouter un utilisateur", "HeaderAdditionalParts": "Parties additionelles", "HeaderAdmin": "Administrateur", - "HeaderAlbumArtists": "Artistes d'album", + "HeaderAlbumArtists": "Artistes de l'album", "HeaderAlert": "Alerte", "HeaderAllowMediaDeletionFrom": "Autoriser la suppression de médias à partir de", "HeaderApiKey": "Clé API", @@ -624,7 +624,7 @@ "LabelKidsCategories": "Catégories jeunesse :", "LabelKodiMetadataDateFormat": "Format de la date de sortie :", "LabelKodiMetadataDateFormatHelp": "Toutes les dates des fichiers NFO seront anlysés en utilisant ce format.", - "LabelKodiMetadataEnableExtraThumbs": "Copier les extrafanart vers le champ extrathumbs", + "LabelKodiMetadataEnableExtraThumbs": "Copier les extrafanart dans les champs extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "Pendant le téléchargement, les images peuvent être enregistrées en tant qu'extrafanart et extrathumbs pour améliorer la compatibilité avec le skin Kodi.", "LabelKodiMetadataEnablePathSubstitution": "Activer la substitution des chemins", "LabelKodiMetadataEnablePathSubstitutionHelp": "Active la substitution du chemin des images en utilisant les paramètres de substitution des chemins du serveur.", @@ -658,7 +658,7 @@ "LabelMetadataDownloadLanguage": "Langue de téléchargement préférée :", "LabelMetadataDownloadersHelp": "Activez et classez vos sources de téléchargement de métadonnées préférées dans l'ordre de priorité. Les plus basses seront utilisées uniquement pour remplir les informations manquantes.", "LabelMetadataPath": "Chemin des métadonnées :", - "LabelMetadataPathHelp": "Veuillez spécifier un emplacement personnalisé pour les images et les métadonnées téléchargées.", + "LabelMetadataPathHelp": "Veuillez spécifier un emplacement personnalisé pour les illustrations et les métadonnées téléchargées.", "LabelMetadataReaders": "Lecteurs de métadonnées :", "LabelMetadataReadersHelp": "Classez vos sources locales de métadonnées préférées dans l'ordre de priorité. Le premier fichier trouvé sera lu.", "LabelMetadataSavers": "Enregistreurs de métadonnées :", @@ -737,8 +737,8 @@ "LabelRemoteClientBitrateLimit": "Limite de débit de streaming Internet (Mbps) :", "LabelRemoteClientBitrateLimitHelp": "Une limite de débit optionnelle par streaming pour les connexions hors du réseau local. Utile pour éviter que les appareils ne demandent un débit supérieur à ce que votre connexion internet peu fournir. Cela peut augmenter la charge du processeur de votre serveur pour transcoder les vidéos à la volée à un débit plus faible.", "LabelRuntimeMinutes": "Durée (minutes) :", - "LabelSaveLocalMetadata": "Enregistrer les images dans les dossiers multimédia", - "LabelSaveLocalMetadataHelp": "L'enregistrement des images dans les dossiers multimédia les placera à un endroit où elles seront facilement modifiables.", + "LabelSaveLocalMetadata": "Enregistrer les illustrations dans les dossiers des médias", + "LabelSaveLocalMetadataHelp": "L'enregistrement des illustrations dans les dossiers des médias les placera à un endroit où elles seront facilement modifiables.", "LabelScheduledTaskLastRan": "Dernière exécution {0}, durée {1}.", "LabelScreensaver": "Économiseur d'écran :", "LabelSeasonNumber": "Numéro de saison :", @@ -1164,7 +1164,7 @@ "Screenshot": "Capture d'écran", "Screenshots": "Captures d'écran", "Search": "Recherche", - "SearchForCollectionInternetMetadata": "Rechercher sur Internet les images et les métadonnées", + "SearchForCollectionInternetMetadata": "Rechercher les illustrations et les métadonnées sur Internet", "SearchForMissingMetadata": "Rechercher les métadonnées manquantes", "SearchForSubtitles": "Rechercher des sous-titres", "SearchResults": "Résultats de la recherche", @@ -1399,7 +1399,7 @@ "AuthProviderHelp": "Sélectionner un fournisseur d'authentification pour authentifier le mot de passe de cet utilisateur.", "PasswordResetProviderHelp": "Choisissez un Fournisseur de réinitialisation de mot de passe à utiliser lorsqu'un utilisateur demande la réinitialisation de son mot de passe", "HeaderHome": "Accueil", - "LabelUserLoginAttemptsBeforeLockout": "Essais manqués restants avant verrouillage utilisateur :", + "LabelUserLoginAttemptsBeforeLockout": "Tentatives de connexion échouées avant que l'utilisateur ne soit verrouillé :", "DashboardOperatingSystem": "Système d'Exploitation: {0}", "DashboardArchitecture": "Architecture : {0}", "LaunchWebAppOnStartup": "Démarrer l'interface web dans mon navigateur quand le serveur est démarré", @@ -1409,7 +1409,7 @@ "MessageNoServersAvailable": "Aucun serveur n'a été trouvé en utilisant la recherche automatique de serveur.", "OptionBanner": "Bannière", "OptionList": "Liste", - "OptionLoginAttemptsBeforeLockout": "Détermine le nombre de tentative de connexion infructueuse avant le blocage d'accès.", + "OptionLoginAttemptsBeforeLockout": "Définis le nombre de tentatives de connexion échouées avant blocage du compte.", "OptionPoster": "Affiche", "OptionPosterCard": "Affichette", "OptionThumb": "Vignette", @@ -1437,10 +1437,10 @@ "LabelVideoBitrate": "Débit vidéo :", "LabelTranscodingProgress": "Progression du transcodage :", "LabelTranscodingFramerate": "Taux de rafraîchissement du transcodage :", - "LabelPleaseRestart": "Les changements prendront effet lors d'un rechargement manuel du client web.", + "LabelPleaseRestart": "Les changements prendront effet après un rechargement manuel du client web.", "LabelPlayMethod": "Méthode de lecture :", "LabelPlayer": "Lecteur :", - "LabelBaseUrl": "Lien d'origine :", + "LabelBaseUrl": "URL de base :", "LabelAudioSampleRate": "Taux d’échantillonnage audio :", "LabelAudioCodec": "Codec audio :", "LabelAudioChannels": "Canaux audio :", @@ -1448,7 +1448,7 @@ "FetchingData": "Récuperer des données suplémentaires", "CopyStreamURLSuccess": "URL copiée avec succès.", "CopyStreamURL": "Copier l'URL du flux", - "LabelBaseUrlHelp": "Vous pouvez ajouter un sous-répertoire personalisé ici pour accéder au serveur depuis une URL plus exclusive.", + "LabelBaseUrlHelp": "Vous pouvez ajouter un sous-répertoire personnalisé ici pour accéder au serveur via un lien unique.", "HeaderFavoritePeople": "Personnes préférées", "OptionRandom": "Aléatoire", "ButtonSplit": "Séparer", @@ -1458,16 +1458,16 @@ "MessageConfirmAppExit": "Voulez-vous quitter ?", "LabelVideoResolution": "Résolution vidéo :", "LabelStreamType": "Type de flux :", - "EnableFastImageFadeInHelp": "Activer un transition plus rapide pour images téléchargées", - "EnableFastImageFadeIn": "Transition d'image rapide", + "EnableFastImageFadeInHelp": "Activer un fondu plus rapide pour l'animation des images chargées", + "EnableFastImageFadeIn": "Fondu d'image rapide", "LabelPlayerDimensions": "Dimension du lecteur :", "LabelDroppedFrames": "Images perdues :", "LabelCorruptedFrames": "Images corrompues :", - "CopyStreamURLError": "Il y a eu une erreur lors de la copie du URL.", + "CopyStreamURLError": "Une erreur est survenue lors de la copie de l'URL.", "AskAdminToCreateLibrary": "Demander à un administrateur de créer une médiathèque.", - "AllowFfmpegThrottlingHelp": "Quand le transcodage ou le remultiplexage est suffisamment loin de la position de lecture, le processus se mettra en pause afin d’économiser des ressources. Plus utile lors d’une lecture continue. À désactiver en cas de problèmes de lecture.", - "AllowFfmpegThrottling": "Adapter la Vitesse du Transcodage", - "NoCreatedLibraries": "Il semblerait que vous n'ayez créé aucune librairie. {0}Voulez-vous en créer une maintenant ?{1}", + "AllowFfmpegThrottlingHelp": "Quand le transcodage ou le remultiplexage est suffisamment en avant de la position de lecture, le processus se mettra en pause afin d’économiser des ressources. Plus utile lors d’une lecture continue. À désactiver en cas de problèmes de lecture.", + "AllowFfmpegThrottling": "Adapter la vitesse du transcodage", + "NoCreatedLibraries": "Il semble que vous n'ayez pas encore créé de bibliothèques. {0}Voulez-vous en créer une maintenant ?{1}", "PlaybackErrorNoCompatibleStream": "Ce client n'est pas compatible avec le média et le serveur n'envoie pas de format compatible.", "PreferEmbeddedEpisodeInfosOverFileNames": "Préférer les informations intégrées aux noms de fichiers", "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Utilise les informations des métadonnées intégrées, si disponible.", @@ -1500,5 +1500,12 @@ "LabelDeinterlaceMethod": "Méthode de désentrelacement :", "DeinterlaceMethodHelp": "Sélectionnes la méthode de désentrelacement à utiliser lors du transcodage de contenu entrelacé.", "LabelLibraryPageSize": "Taille de la page de la médiathèque :", - "LabelLibraryPageSizeHelp": "Définit la quantité d'éléments à afficher sur une page de médiathèque. Définir à 0 afin de désactiver la pagination." + "LabelLibraryPageSizeHelp": "Définit la quantité d'éléments à afficher sur une page de médiathèque. Définir à 0 afin de désactiver la pagination.", + "UnsupportedPlayback": "Jellyfin ne peut pas décoder du contenu protégé par un système de gestion des droits numériques, mais une tentative de lecture sera effectuée sur tout le contenu, y compris les titres protégés. Certains fichiers peuvent apparaître complètement noir, du fait de protections ou de fonctionnalités non supportées, comme les titres interactifs.", + "MessageUnauthorizedUser": "Vous n'êtes pas autorisé à accéder au serveur pour le moment. Veuillez contacter l'administrateur de votre serveur pour plus d'informations.", + "ButtonTogglePlaylist": "Liste de lecture", + "ButtonToggleContextMenu": "Plus", + "Filter": "Filtre", + "New": "Nouveau", + "HeaderFavoritePlaylists": "Listes de lecture favorites" } diff --git a/src/strings/he.json b/src/strings/he.json index 381b9bc181..2015201c79 100644 --- a/src/strings/he.json +++ b/src/strings/he.json @@ -1,14 +1,14 @@ { "Actor": "שחקן", "Add": "הוסף", - "AddToCollection": "להוסיף לאוסף", - "AddToPlayQueue": "הוסף לתור הפעלה", + "AddToCollection": "הוסף לאוסף", + "AddToPlayQueue": "הוסף לרשימת ניגון", "AddToPlaylist": "הוסף לרשימת ניגון", - "AdditionalNotificationServices": "עיין בקטלוג התוספים להתקנת שרותי התראות נוספים", + "AdditionalNotificationServices": "עיין ברשימת התוספים להתקנת שירותי התראות נוספים.", "All": "הכל", "AllChannels": "כל הערוצים", "AllEpisodes": "כל הפרקים", - "AllLibraries": "כל הספרייה", + "AllLibraries": "כל הספריות", "Anytime": "בכל עת", "AroundTime": "בסביבות {0}", "AsManyAsPossible": "כמה שיותר", @@ -52,7 +52,7 @@ "ConfirmDeleteItems": "מחיקת פריטים אלה תמחק אותם הן ממערכת הקבצים והן מספריית המדיה שלך. האם אתה בטוח שברצונך להמשיך?", "ConfirmDeletion": "אשר מחיקה", "Continuing": "ממשיך", - "CustomDlnaProfilesHelp": "צור פרופיל מותאם אישית למכשיר חדש או לעקוף פרופיל מערכת", + "CustomDlnaProfilesHelp": "צור פרופיל מותאם אישית למכשיר חדש או לעקיפת פרופיל מערכת.", "DefaultErrorMessage": "אירעה שגיאה בעיבוד הבקשה. בבקשה נסה שוב מאוחר יותר.", "Delete": "מחק", "DeleteImage": "מחק תמונה", @@ -130,7 +130,7 @@ "HeaderSeries": "סדרה", "HeaderSeriesOptions": "אפשרויות סדרה", "HeaderServerSettings": "הגדרות שרת", - "HeaderSetupLibrary": "הגדר את ספריית המדיה שלך.", + "HeaderSetupLibrary": "הגדר את ספריית המדיה שלך", "HeaderSpecialEpisodeInfo": "פרטי אפיזודות מיוחדות", "HeaderSpecialFeatures": "מאפיינים מיוחדים", "HeaderStatus": "מצב", @@ -164,7 +164,7 @@ "LabelChannels": "ערוצים:", "LabelCollection": "אוספים:", "LabelCommunityRating": "דירוג הקהילה:", - "LabelContentType": "סוג התוכן", + "LabelContentType": "סוג התוכן:", "LabelCountry": "מדינה:", "LabelCriticRating": "דירוג ביקורת:", "LabelCurrentPassword": "סיסמא נוכחית:", @@ -221,7 +221,7 @@ "LabelNext": "הבא", "LabelNotificationEnabled": "אפשר התראה זו", "LabelNumber": "מספר:", - "LabelNumberOfGuideDays": "מספר ימי לוח שידורים להורדה", + "LabelNumberOfGuideDays": "מספר ימים להורדה מלוח השידורים:", "LabelNumberOfGuideDaysHelp": "הורדת יותר ימי לוח שידורים מאפשרת יכולת לתכנן ולראות יותר תוכניות קדימה, אבל גם זמן ההורדה יעלה. מצב אוטומטי ייקבע לפני מספר הערוצים.", "LabelOriginalAspectRatio": "יחס גובה-רוחב מקורי:", "LabelOriginalTitle": "כותרת מקורית:", @@ -234,14 +234,14 @@ "LabelPersonRoleHelp": "דוגמה: נהג משאית גלידה", "LabelPlaceOfBirth": "מקום לידה:", "LabelPlaylist": "רשימת ניגון:", - "LabelPreferredDisplayLanguage": "שפת ממשק מועדפת", - "LabelPreferredDisplayLanguageHelp": "תרגום הממשק של Jellyfin הוא תהליך ממושך", + "LabelPreferredDisplayLanguage": "שפת תצוגה מועדפת:", + "LabelPreferredDisplayLanguageHelp": "תרגום Jellyfin הוא תהליך מתמשך.", "LabelPrevious": "הקודם", - "LabelProfileAudioCodecs": "מקודדי צליל", - "LabelProfileCodecs": "מקודדים", + "LabelProfileAudioCodecs": "מקודדי שמע:", + "LabelProfileCodecs": "מקודדים:", "LabelProfileVideoCodecs": "‮מקודדי וידאו:", "LabelPublicHttpPort": "מספר פורט HTTP פומבי", - "LabelReadHowYouCanContribute": "למד איך תוכל לתרום", + "LabelReadHowYouCanContribute": "למד איך אתה יכול לתרום.", "LabelRecord": "הקלטה:", "LabelRefreshMode": "מצב רענון:", "LabelReleaseDate": "תאריך הוצאה:", @@ -254,17 +254,17 @@ "LabelSortTitle": "מיין כותרת:", "LabelStartWhenPossible": "התחל ברגע שניתן:", "LabelStatus": "סטטוס:", - "LabelStopWhenPossible": "הפסק ברגע שאפשר", + "LabelStopWhenPossible": "הפסק כשיתאפשר:", "LabelTagline": "שורת תיוג:", "LabelTime": "זמן:", - "LabelTimeLimitHours": "הגבלת זמן (בשעות)", + "LabelTimeLimitHours": "מגבלת זמן (שעות):", "LabelTitle": "כותרת:", "LabelTrackNumber": "קטע מספר:", "LabelTriggerType": "סוגר טריגר:", "LabelType": "סוג:", "LabelUseNotificationServices": "השתמש בשירותים הבאים:", "LabelUser": "משתמש:", - "LabelUserLibrary": "ספריית משתמש", + "LabelUserLibrary": "ספריית משתמש:", "LabelYear": "שנה:", "LabelYourFirstName": "שמך הפרטי:", "LabelYoureDone": "סיימת!", @@ -277,12 +277,12 @@ "MaxParentalRatingHelp": "תוכן עם דירוג גובה יותר יוסתר מהמשתמש.", "MessageAreYouSureDeleteSubtitles": "האם אתה בטוח שברצונך למחוק קובץ כתובית זה?", "MessageConfirmRecordingCancellation": "‏האם אתה בטוח שברצונך לבטל הקלטה זו?", - "MessageDownloadQueued": "הורד תור", + "MessageDownloadQueued": "הורדה נוספה לתור.", "MessageItemSaved": "הפריט נשמר.", "MessageItemsAdded": "פריטים נוספו.", - "MessageLeaveEmptyToInherit": "השאר ריק כדי לרשת את ההגדרות מפריט אב, או את ערך ברירת המחדל הגלובלי.", + "MessageLeaveEmptyToInherit": "השאר ריק כדי לרשת את ההגדרות מפריט אב או את ערך ברירת המחדל הגלובלי.", "MessageNothingHere": "אין כאן כלום.", - "MessagePleaseEnsureInternetMetadata": "בבקשה וודא כי הורדת מידע מהאינטרנט מאופשרת", + "MessagePleaseEnsureInternetMetadata": "אנא וודא כי הורדת מטא-דאטה מהאינטרנט מופעלת.", "MinutesAfter": "דקות אחרי", "MinutesBefore": "דקות לפני", "Monday": "שני", @@ -397,7 +397,7 @@ "RecentlyWatched": "נצפה לאחרונה", "Record": "הקלט", "RecordSeries": "הקלט סדרה", - "RecordingCancelled": "בטל הקלטה", + "RecordingCancelled": "הקלטה בוטלה.", "RecordingScheduled": "ההקלטה מתוזמנת.", "Refresh": "רענון", "RefreshDialogHelp": "המטא נתונים מתרעננים על סמך הגדרות ושירותי אינטרנט שמופעלים בלוח המחוונים של מרכז אמבי.", @@ -419,7 +419,7 @@ "SearchForMissingMetadata": "חפש מטא נתונים חסרים", "SearchForSubtitles": "חיפוש של כתוביות", "SearchResults": "תוצאות חיפוש", - "SeriesCancelled": "בטל סדרות", + "SeriesCancelled": "סדרה בוטלה.", "SeriesRecordingScheduled": "הקלטת סדרה מתוזמנת.", "SeriesSettings": "הגדרות סדרה", "SeriesYearToPresent": "{0} - היום", @@ -510,8 +510,8 @@ "Artists": "אומנים", "Books": "ספרים", "Absolute": "מוחלט", - "AccessRestrictedTryAgainLater": "הגישה כרגע מוגבלת. אנא נסה שוב מאוחר יותר.", - "AddedOnValue": "נוסף {0}", + "AccessRestrictedTryAgainLater": "הגישה מוגבלת כרגע, נסה שוב במועד מאוחר יותר.", + "AddedOnValue": "נוספו {0}", "Blacklist": "רשימה שחורה", "Banner": "באנר", "Auto": "אוטומטי", @@ -528,10 +528,10 @@ "Audio": "שמע", "AspectRatio": "יחס גובה-רוחב", "AlwaysPlaySubtitlesHelp": "כתוביות בשפה המועדפת ייטענו ללא קשר לשפת השמע.", - "AlwaysPlaySubtitles": "הפעל כתוביות תמיד", + "AlwaysPlaySubtitles": "הפעל תמיד", "AllowRemoteAccessHelp": "אם לא מסומן, כל החיבורים המרוחקים ייחסמו.", "AllowRemoteAccess": "אפשר חיבור מרוחק לשרת Jellyfin זה.", - "AllowMediaConversionHelp": "אפשר או חסום גישה להמרת מדיה.", + "AllowMediaConversionHelp": "הענק או דחה גישה להמרת מדיה.", "Aired": "שודר", "AirDate": "תאריך שידור", "Yesterday": "אתמול", @@ -548,8 +548,8 @@ "HeaderContinueWatching": "המשך לצפות", "AllowOnTheFlySubtitleExtraction": "אפשר חילוץ כתוביות בזמן אמת", "AllowHWTranscodingHelp": "אפשר למלקט לקודד הזרמות בזמן אמת. זה עשוי לעזור בהפחתת הקידוד שנעשה ע\"י השרת.", - "AllComplexFormats": "כל הפורמטים המורכבים (ASS, SSA, VOBSUB, PGS, SUB\\IDX וכדומה)", - "AddItemToCollectionHelp": "הוסף פריטים לאוספים ע\"י חיפושם ושימוש בלחצן ימני או הקשה על התפריט כדי להוסיף אותם לאוסף.", + "AllComplexFormats": "כל הפורמטים המורכבים (ASS, SSA, VOBSUB, PGS, SUB/IDX)", + "AddItemToCollectionHelp": "הוסף חפצים לאוסף על ידי חיפושם ושימוש בתפריט הלחצן הימני או לחצן התפריט כדי להוסיפם לאוסף.", "Songs": "שירים", "Shows": "סדרות", "DownloadsValue": "{0} הורדות", @@ -741,5 +741,34 @@ "Browse": "עיין", "BoxRear": "מארז (מאחור)", "BookLibraryHelp": "ניתן להוסיף ספרים מוקלטים וספרים כתובים. עיינו {0}במדריך מתן שמות לספרים{1}.", - "Desktop": "שולחן עבודה" + "Desktop": "שולחן עבודה", + "MessageUnauthorizedUser": "אין לך גישה לשרת ברגע זה. אנא צור קשר עם מנהל השרת למידע נוסף.", + "MessageDeleteTaskTrigger": "האם אתה בטוח שברצונך למחוק את מפעיל המשימה הזה?", + "LastSeen": "נראה לאחרונה ב-{0}", + "PersonRole": "כ-{0}", + "ListPaging": "{0}-{1} מתוך {2}", + "EveryXHours": "בכל {0} שעות", + "OnApplicationStartup": "באתחול היישום", + "DeleteUserConfirmation": "האם אתה בטוח שברצונך למחוק את המשתמש?", + "DeleteDeviceConfirmation": "האם אתה בטוח שברצונך למחוק את המכשיר? הוא יופיע שוב בפעם הבאה שמשתמש ייכנס באמצעותו.", + "ColorSpace": "מרחב צבע", + "CinemaModeConfigurationHelp": "מצב קולנוע מביא את חוויית הקולנוע היישר אל הסלון עם האפשרות להפעיל טריילרים וקדימונים מותאמים אישית לפני הסרט.", + "ChannelAccessHelp": "בחר את הערוצים לשיתוף עם משתמש זה. מנהלים יוכלו לערוך את כל הערוצים בעזרת \"מנהל המטא-דאטה\".", + "ButtonResetEasyPassword": "אתחל קוד פין פשוט", + "ButtonOff": "כיבוי", + "ButtonLibraryAccess": "הרשאות גישה לספרייה", + "BurnSubtitlesHelp": "מחליט אם על השרת לצרוב כתוביות בזמן קידוד וידאו. הימנעות מכך תשפר מאוד את הביצועים. בחר \"אוטומטי\" לצריבת כתוביות על בסיס פורמט תמונה (VOBSUB, PGS, SUB, IDX) וכתוביות ASS או SSA מסויימות.", + "Artist": "אמן", + "AllowedRemoteAddressesHelp": "רשימת IP \\ מיסוך רשת המופרדת בפסיקים עבור רשתות שיורשו להתחבר מרחוק. במידה ותישאר ריקה, כל הכתובות יורשו להתחבר.", + "Album": "אלבום", + "AlbumArtist": "אמן האלבום", + "LabelSortOrder": "מיין סדר:", + "ShowYear": "הצג שנה", + "ShowTitle": "הצג כותרת", + "DropShadow": "הפעל צל", + "Playlists": "רשימות הפעלה", + "Raised": "מורם", + "LabelSpecialSeasonsDisplayName": "שם תצוגת \"עונה מיוחדת\":", + "LabelSource": "מקור:", + "LabelSoundEffects": "אפקטי סאונד:" } diff --git a/src/strings/hu.json b/src/strings/hu.json index 92fc370c02..5dc7f02826 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -1473,8 +1473,8 @@ "PlaybackErrorNoCompatibleStream": "Ez a kliens nem kompatibilis ezzel a médiával és a szerver nem tud kompatibilis streamet küldeni az eszközre.", "AllowFfmpegThrottlingHelp": "Ha az átkódolás vagy remux eléggé előtöltődött a jelenlegi lejátszási pozícióhoz képest, ez megállítja a folyamatot, hogy kevesebb erőforrást vegyen igénybe. Ez akkor hasznos, ha ritkán ugrálsz előre a lejátszott videókban. Kapcsold ki, ha lejátszási problémákba ütközöl.", "AllowFfmpegThrottling": "Átkódolás visszafogása", - "PreferEmbeddedEpisodeInfosOverFileNames": "Inkább a beágyazott epizódokra vonatkozó információkat részesítse előnyben a fájlnevekkel szemben", - "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Ez a beágyazott metaadatok epizódinformációit használja, ha rendelkezésre állnak.", + "PreferEmbeddedEpisodeInfosOverFileNames": "Az epizódból elérhető beágyazott információkat használja inkább, fájlnevek helyett", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Ez az epizóddal kapcsolatos beágyazott metaadatokat használja, ha azok elérhetőek.", "OnApplicationStartup": "Az alkalmazás indításakor", "EveryXHours": "{0} óránként", "EveryHour": "Óránként", @@ -1484,7 +1484,7 @@ "DailyAt": "Naponta ekkor: {0}", "LastSeen": "Utoljára elérhető {0}", "PersonRole": "mint {0}", - "ListPaging": "{0}-{1} ennyiből: {2}", + "ListPaging": "{0}-{1} / {2}", "WriteAccessRequired": "A Jellyfin Szerver írási jogosultságot igényel ehhez a könyvtárhoz. Kérjük, ellenőrizd, hogy van-e jogod írni ide, majd próbáld újra.", "PathNotFound": "Az elérési út nem található. Kérjük, ellenőrizd, hogy az elérési út megfelelő-e, majd próbáld újra.", "Track": "Szám", @@ -1494,8 +1494,22 @@ "Movie": "Film", "Episode": "Epizód", "ClientSettings": "Kliens beállítások", - "BoxSet": "Dobozos készlet", + "BoxSet": "Dobozos kiadások", "Artist": "Előadó", "AlbumArtist": "Album előadó", - "Album": "Album" + "Album": "Album", + "LabelLibraryPageSizeHelp": "Az oldalnként megmutatott elemek száma. Nullára állítva a lapozási funkció ki lesz kapcsolva.", + "LabelLibraryPageSize": "Könyvtár oldalméret:", + "LabelDeinterlaceMethod": "Deinterlacing mód:", + "DeinterlaceMethodHelp": "Válassza ki a váltottsorosság megszűntetéséhez használandó módszert a váltottsoros tartalmak transzkódolásakor.", + "UnsupportedPlayback": "Jellyfin nem tud DRM-titkosított tartalmak dekriptálására, ettől függetlenül a lejátszással mindig megpróbálkozik. Néhány fájl emiatt teljesen fekete képernyőt ad, amely vagy a titkosítás miatt van, vagy nem olyan nem támogatott tartalmak miatt, mint az interaktív címek.", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", + "ReleaseGroup": "Kiadócsoport", + "MessageUnauthorizedUser": "Jelenleg nincs jogosultságod a szerverhez való hozzáféréshez. Kérjük, lépj kapcsolatba az adminisztrátorral további információkért!", + "ButtonTogglePlaylist": "Lejátszási listák", + "ButtonToggleContextMenu": "Továbbiak", + "Filter": "Szűrés", + "New": "Új", + "HeaderFavoritePlaylists": "Kedvenc lejátszási listák" } diff --git a/src/strings/it.json b/src/strings/it.json index 120e18d5db..8f54f4b41c 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -1499,5 +1499,9 @@ "Episode": "Episodio", "BoxSet": "Cofanetto", "AlbumArtist": "Artisti dell'Album", - "ReleaseGroup": "Release Group" + "ReleaseGroup": "Release Group", + "UnsupportedPlayback": "Jellyfin non è in grado di decriptare i contenuti protetti da DRM ma tutti i contenuti verranno tentati a prescindere, compresi quelli protetti. Alcuni file potrebbero apparire completamente neri a causa della crittografia o di altre funzionalità non supportate, come i titoli interattivi.", + "MessageUnauthorizedUser": "Non sei autorizzato ad accedere in questo momento al server. Contatta l'amministratore per ulteriori dettagli.", + "ButtonTogglePlaylist": "Playlist", + "ButtonToggleContextMenu": "Altro" } diff --git a/src/strings/ja.json b/src/strings/ja.json index 4a15d798c3..0f90a05c40 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -1139,5 +1139,10 @@ "LabelEnableBlastAliveMessages": "アライブメッセージを配信する", "LabelDateAddedBehaviorHelp": "メタデータある場合、これらのオプションの前にメタデータ使います。", "AskAdminToCreateLibrary": "管理者にライブラリを作成する依頼をしてください。", - "AllowFfmpegThrottling": "トランスコードをスロットルする" + "AllowFfmpegThrottling": "トランスコードをスロットルする", + "Episode": "エピソード", + "ClientSettings": "クライアント設定", + "Artist": "アーティスト", + "AlbumArtist": "アルバム アーティスト", + "Album": "アルバム" } diff --git a/src/strings/kk.json b/src/strings/kk.json index 852e408a3b..a31d2b3758 100644 --- a/src/strings/kk.json +++ b/src/strings/kk.json @@ -15,7 +15,7 @@ "Alerts": "Eskertýler", "All": "Bári", "AllChannels": "Barlyq arnalar", - "AllComplexFormats": "Barlyq kúrdeli pishimderi (ASS, SSA, VOBSUB, PGS, SUB/IDX jáne t.b.)", + "AllComplexFormats": "Barlyq kúrdeli pishimder (ASS, SSA, VOBSUB, PGS, SUB jáne IDX)", "AllEpisodes": "Barlyq bólimder", "AllLanguages": "Barlyq tilder", "AllLibraries": "Barlyq tasyǵyshhanalar", @@ -27,7 +27,7 @@ "AllowRemoteAccess": "Osy Jellyfin Serverine syrtqy qosylymdar úshin ruqsat etý.", "AllowRemoteAccessHelp": "Eger jalaýsha alastalǵan bolsa, baryq syrtqy baılanystar qursaýlanady.", "AllowedRemoteAddressesHelp": "Qashyqtan qosylýǵa ruqsat etiletin jeliler úshin útirlermen bólingen IP-mekenjaılarynyń tizbesi nemese IP/netmask jazbalar Eger bos qaldyrylsa, barlyq qashyqtaǵy mekenjaılarǵa ruqsat etiledi.", - "AlwaysPlaySubtitles": "Sýbtıtrlerdi árqashan oınatý", + "AlwaysPlaySubtitles": "Árqashan oınatý", "AlwaysPlaySubtitlesHelp": "Til teńshelimine sáıkes kelgen sýbtıtrler dybys tiline qatyssyz júkteledi.", "AnamorphicVideoNotSupported": "Anamorftyq beıne úshin qoldaý kórsetilmeıdi", "AndroidUnlockRestoreHelp": "Aldyńǵy satyp alýdy qalpyna keltirý úshin, bastapqyda satyp alý jasalǵan naq sol Google (nemese Amazon) tirkelgisimen qurylǵyǵa kirińiz. Qoldanba dúkeni qosylǵan jáne kezkelgen ata-ana shekteýsiz, jáne belsendi ınternet baılanysy bar ekenine kóz jetkizińiz. Aldyńǵy satyp alý qalpyna keltirý úshin muny tek qana bir ret isteý kerek.", @@ -56,7 +56,7 @@ "BoxRear": "Qorap arty", "Browse": "Sharlaý", "BrowsePluginCatalogMessage": "Qoljetimdi plagındermen tanysý úshin plagın tizimdemesin sholyńyz.", - "BurnSubtitlesHelp": "Sýbtıtrler pishimine baılanysty beıneni túrlendirgen kezde server sýbtıtrlerdi jazyýyn anyqtaıdy. Sýbtıtrler jazýdy qashqaqtaý serverdiń ónimdiligin jaqsartady. Sýretke negizdelgen pishimderdi (VOBSUB, PGS, SUB/IDX j.t.b.) jáne keıbir ASS/SSA sýbtıtrlerin jazý úshin Avtomattyny tańdańyz.", + "BurnSubtitlesHelp": "Beıneni qaıta kodtaǵan kezde server sýbtıtrlerdi jazyýyn anyqtaıdy. Onan qashqaqtaý serverdiń ónimdiligin biraz jaqsartady. Sýretke negizdelgen pishimderdi (VOBSUB, PGS, SUB jáne IDX) jáne keıbir ASS nemese SSA sýbtıtrlerin jazý úshin Avtomattyny tańdańyz.", "ButtonAdd": "Ústeý", "ButtonAddMediaLibrary": "Tasyǵyshhana ústeý", "ButtonAddScheduledTaskTrigger": "Trıger ústeý", @@ -198,7 +198,7 @@ "DisplayInOtherHomeScreenSections": "Basqy ekran bólimderinde beıneleý (mys. Eń sońǵy tasyǵyshderekter jáne Kórýdi jalǵastyrý)", "DisplayMissingEpisodesWithinSeasons": "Joq bólimderdi maýsym ishinde beıneleý", "DisplayMissingEpisodesWithinSeasonsHelp": "Bul sondaı-aq server konfıgýrasýasyndaǵy TD tasyǵyshhanalary úshin qosýlýy qajet.", - "DisplayModeHelp": "Jellyfin iske qosylǵanda ekran túrin tańdańyz.", + "DisplayModeHelp": "Interfeıs úshin laıyqty ornalasý mánerin tańdańyz.", "DoNotRecord": "Jazýǵa bolmaıdy", "Down": "Tómenge", "Download": "Júktep alý", @@ -503,7 +503,7 @@ "Images": "Sýretter", "ImportFavoriteChannelsHelp": "Qosylǵanda, túner qurylǵysyndaǵy tańdaýly retinde belgilengen ǵana arnalar shetten ákelinetin bolady.", "ImportMissingEpisodesHelp": "Qosylǵanda, joq epızodtar týraly aqparat sizdiń Jellyfin derekqorǵa ákelinedi jáne maýsymdar men telehıkaıalar aıasynda paıda bolady. Tasyǵyshhana skanerleýde bul aıtarlyqtaı uzaq ýaqyt alýy múmkin.", - "InstallingPackage": "{0} ornatylýda", + "InstallingPackage": "{0} ({1} nusqasy) ornatylýda", "InstantMix": "Lezdik qospalaý", "ItemCount": "{0} tarmaq", "Items": "Tarmaqtar", @@ -986,16 +986,16 @@ "NoNextUpItemsMessage": "Eshteńe tabylmady. Kórsetimderińizdi qaraı bastańyz!", "NoPluginConfigurationMessage": "Osy plagınde teńsheletin parametrler joq.", "NoSubtitleSearchResultsFound": "Eshqandaı nátıjeler tabylmady.", - "NoSubtitles": "Sýbtıtrlersiz", + "NoSubtitles": "Eshqandaı", "NoSubtitlesHelp": "Ádepkide sýbtıtrler júktelmeıdi. Olardy oınatý kezinde áli de qolmen qosýǵa bolady.", "None": "Eshqandaı", "Normal": "Kádimgi", "NumLocationsValue": "{0} qalta", "Off": "Óshir", "OneChannel": "Bir arnadan", - "OnlyForcedSubtitles": "Tek qana májbúrli sýbtıtrler", + "OnlyForcedSubtitles": "Tek qana májbúrli", "OnlyForcedSubtitlesHelp": "Tek qana májbúrli dep belgilengen sýbtıtrler júkteledi.", - "OnlyImageFormats": "Tek keskin pishimder (VOBSUB, PGS, SUB j.t.b.)", + "OnlyImageFormats": "Tek keskin pishimder (VOBSUB, PGS jáne SUB)", "Open": "Ashý", "OptionActor": "Aktór", "OptionActors": "Aktórler", @@ -1138,9 +1138,9 @@ "OptionWeekly": "Apta saıyn", "OriginalAirDateValue": "Bastapqy efır: {0}", "Overview": "Jalpy sholý", - "PackageInstallCancelled": "{0} ornatylýy boldyrylmady.", - "PackageInstallCompleted": "{0} ornatylýy aıaqtaldy.", - "PackageInstallFailed": "{0} ornatylýy sátsiz.", + "PackageInstallCancelled": "{0} ({1} nusqasy) ornatylýy boldyrylmady.", + "PackageInstallCompleted": "{0} ({1} nusqasy) ornatylýy aıaqtaldy.", + "PackageInstallFailed": "{0} ({1} nusqasy) ornatylýy sátsiz.", "ParentalRating": "Jastas sanaty", "PasswordMatchError": "Paróli men Paróldi rastaý óristeri sáıkes bolý kerek.", "PasswordResetComplete": "Paról ysyryldy.", @@ -1501,6 +1501,35 @@ "ButtonSplit": "Bólý", "AskAdminToCreateLibrary": "Tasýǵyshanany jasaý úshin ákimshiden suraý.", "AllowFfmpegThrottling": "Qaıta kodtaýdy retteý", - "PlaybackErrorNoCompatibleStream": "Klıent profaılyn jasaýda másele oryn aldy jáne server úılesimdi pishiminde tasyǵysh derekterin jibermedi.", - "AllowFfmpegThrottlingHelp": "Qaıta kodtaý nemese qaıta býmalaý aǵymdyq oınatý jaıǵasymynan edáýir alǵa ozǵanda, qor kózderin azdaý tutynatyndaı etip údiristi kidirtedi. Bul jıi izdemeı qaraý kezinde paıdaly. Eger oınatý máseleleri bolsa, ony óshirińiz." + "PlaybackErrorNoCompatibleStream": "Bul klıent tasyǵysh derektermen úılesimsiz jáne server úılesimdi pishiminde tasyǵysh derekterin jibermedi.", + "AllowFfmpegThrottlingHelp": "Qaıta kodtaý nemese qaıta býmalaý aǵymdyq oınatý jaıǵasymynan edáýir alǵa ozǵanda, qor kózderin azdaý tutynatyndaı etip údiristi kidirtedi. Bul jıi izdemeı qaraý kezinde paıdaly. Eger oınatý máseleleri bolsa, ony óshirińiz.", + "Album": "Álbom", + "DeinterlaceMethodHelp": "Jol aralyq jaımaly mazmundy qaıta kodtaý kezinde paıdalaný úshin jol aralyq jaımany joıý ádisin tańdańyz.", + "LabelDeinterlaceMethod": "Jol aralyq jaımany joıý ádisi:", + "YadifBob": "YADIF eki eseleýimen", + "OnApplicationStartup": "Qoldanba iske qosylǵanda", + "EveryXHours": "Ár {0} saǵ", + "EveryHour": "Ár saǵat", + "EveryXMinutes": "Ár {0} mın", + "OnWakeFromSleep": "Uıqylyqtan oıanǵanda", + "WeeklyAt": "{0} {1} kezinde", + "DailyAt": "Kúnde {0} kezinde", + "LastSeen": "Sońǵy kóringeni {0}", + "PersonRole": "- {0}", + "ListPaging": "{0}-{1} {2} ishinen", + "Yadif": "YADIF", + "Track": "Jolshyq", + "Season": "Maýsym", + "ReleaseGroup": "Shyǵarýshy top", + "Person": "Tulǵa", + "OtherArtist": "Basqa oryndaýshy", + "Movie": "Fılm", + "LabelLibraryPageSize": "Tasyǵyshhana betiniń ólshemi:", + "Episode": "Bólim", + "ClientSettings": "Týtynýshy parametrleri", + "ButtonTogglePlaylist": "Oýnatý tizimi", + "ButtonToggleContextMenu": "Kúbirek", + "BoxSet": "Jıyntyq", + "Artist": "Ornatýshy", + "AlbumArtist": "Álbom ornatýshysy" } diff --git a/src/strings/ko.json b/src/strings/ko.json index acd07a336b..9e0bd42604 100644 --- a/src/strings/ko.json +++ b/src/strings/ko.json @@ -976,7 +976,7 @@ "OptionEnableForAllTuners": "모든 튜너 장치 활성화", "OptionBanner": "배너", "Option3D": "3D", - "OnlyImageFormats": "이미지 포맷만 (VOBSUB, PGS, SUB 등)", + "OnlyImageFormats": "이미지 포맷만 (VOBSUB, PGS, SUB)", "Off": "끄기", "NumLocationsValue": "{0} 폴더", "Normal": "보통", @@ -1265,7 +1265,7 @@ "MediaInfoBitDepth": "비트뎁스", "LabelPostProcessor": "후처리 애플리케이션:", "RefreshQueued": "새로 고침 대기 중", - "NoPluginConfigurationMessage": "", + "NoPluginConfigurationMessage": "이 플러그인은 설정할 것이 없습니다.", "OptionExtractChapterImage": "챕터 이미지 추출 활성화", "RestartPleaseWaitMessage": "Jellyfin 서버가 종료되었다가 다시 시작될 때까지 기다리십시오. 1-2분 정도 걸릴 수 있습니다.", "Up": "위", @@ -1378,24 +1378,54 @@ "LabelDefaultScreen": "기본 화면:", "LabelDateTimeLocale": "날짜/시간 로케일:", "XmlTvPathHelp": "XMLTV 파일을 저장할 경로를 설정합니다. Jellyfin은 이 파일을 읽어 주기적으로 변경 사항을 확인합니다. 파일 생성 및 파일 업데이트는 사용자가 수동으로 해야 합니다.", - "MessageTheFollowingLocationWillBeRemovedFromLibrary": "다음 미디어 위치가 라이브러리에서 제거:", + "MessageTheFollowingLocationWillBeRemovedFromLibrary": "다음과 같은 미디어 저장소들을 라이브러리에서 제거합니다:", "MessageReenableUser": "재활성화는 아래를 참조하십시오", "MessagePluginConfigurationRequiresLocalAccess": "이 플러그인을 구성하려면 로컬 서버에 직접 로그인하십시오.", "MessageNoCollectionsAvailable": "컬렉션을 사용하면 영화, 시리즈 및 앨범의 개인화 된 그룹을 즐길 수 있습니다. + 버튼을 클릭하여 컬렉션 만들기를 시작합니다.", - "LabelPlayerDimensions": "플레이어 넓이:", + "LabelPlayerDimensions": "플레이어 화면 크기:", "LabelParentNumber": "부모 번호:", "LabelLineup": "라인업:", - "LabelDroppedFrames": "떨어진 프레임:", + "LabelDroppedFrames": "드롭 프레임:", "LabelDeinterlaceMethod": "디인터레이싱 방법:", - "LabelCustomDeviceDisplayNameHelp": "디바이스에서 보고 한 이름을 사용하려면 사용자 정의 표시 이름을 제공하거나 비워 두십시오.", + "LabelCustomDeviceDisplayNameHelp": "기기에 표시할 이름을 지정하거나 공란으로 두어 등록된 기기 명을 사용합니다.", "Episode": "에피소드", - "EnableColorCodedBackgrounds": "색이 입혀진 배경", + "EnableColorCodedBackgrounds": "컬러코드가 삽입된 배경", "DropShadow": "하단 그림자", - "Depressed": "압축", - "DeinterlaceMethodHelp": "인터레이스 컨텐츠를 트랜스코딩 할 때 사용할 디인터레이싱 방법을 선택하십시오.", + "Depressed": "압축된", + "DeinterlaceMethodHelp": "비월주사식 콘텐츠를 순차주사로 변환할시 사용할 비월제거 방법을 선택하십시오.", "ClientSettings": "클라이언트 설정", "BoxSet": "박스 세트", "Artist": "아티스트", "AlbumArtist": "앨범 아티스트", - "Album": "앨범" + "Album": "앨범", + "NoCreatedLibraries": "라이브러리가 없습니다. {0}지금 생성하겠습니까?{1}", + "NewCollectionHelp": "영화 및 다른 라이브러리 콘텐츠들을 묶어 개인화된 컬렉션을 구성할 수 있습니다.", + "Never": "항상 안 함", + "Movie": "영화", + "MoveRight": "오른쪽으로 이동", + "MoveLeft": "왼쪽으로 이동", + "MoreFromValue": "{0} 에서 더 자세히", + "MetadataSettingChangeHelp": "변경된 메타데이터 설정은 새 콘텐츠에 적용됩니다. 기존의 콘텐츠에 적용하려면 상세 화면에서 새로 고침 버튼을 누르거나 메타데이터 매니저를 통해 일괄적으로 새로 고침을 수행하십시오.", + "MessagePluginInstallDisclaimer": "Jellyfin 커뮤니티에서 만들어진 플러그인은 Jellyfin의 기능과 편의성을 향상시킬 수 있습니다. 다만 이러한 플러그인은 라이브러리 스캔 속도 저하, 추가 백그라운드 프로세싱, 시스템 불안정과 같은 문제를 야기할 수 있다는 것을 유념하시기 바랍니다.", + "LabelLibraryPageSizeHelp": "라이브러리 페이지에 표시될 항목 수를 조절합니다. 0으로 지정 시 페이징을 비활성화합니다.", + "LabelLibraryPageSize": "라이브러리 페이지 크기:", + "LabelEnableBlastAliveMessages": "서버 활성화 메세지", + "OptionEnableExternalContentInSuggestionsHelp": "제안 항목에 인터넷 예고편과 라이브 TV 프로그램이 포함되도록 허용합니다.", + "OptionEnableExternalContentInSuggestions": "제안 항목에 외부 콘텐츠 허용", + "OptionDownloadImagesInAdvanceHelp": "기본적으로 대부분의 이미지는 Jellyfin 앱에서 요청할 때에만 다운로드됩니다. 새 미디어를 추가할 때 모든 이미지를 미리 다운로드하려면 이 옵션을 활성화하십시오. 라이브러리 스캔이 심각하게 지연될 수도 있습니다.", + "OptionDownloadImagesInAdvance": "미리 이미지 다운로드", + "OptionDisplayFolderView": "일반적인 미디어 폴더를 볼 수 있는 폴더 보기를 표시합니다", + "OptionAutomaticallyGroupSeriesHelp": "활성화하면 라이브러리 내의 여러 폴더에 분산된 시리즈를 하나의 시리즈로 병합합니다.", + "OptionAutomaticallyGroupSeries": "여러 폴더에 분산된 시리즈를 자동으로 병합합니다", + "OptionAllowVideoPlaybackRemuxing": "변환이 필요한 비디오를 재인코딩하지 않고 재생하는 것을 허용", + "OptionAllowSyncTranscoding": "트랜스코딩이 필요한 미디어의 다운로드 및 싱크 허용", + "OptionAllowMediaPlaybackTranscodingHelp": "트랜스코딩 접근을 제한하면 Jellyfin 앱에서 지원되지 않는 미디어 형식을 재생할 때 문제가 발생할 수 있습니다.", + "OptionForceRemoteSourceTranscoding": "원격 미디어 소스를 강제 트랜스코딩 (라이브 TV 등)", + "OnlyForcedSubtitlesHelp": "'강제'로 표시된 자막만 불러옵니다.", + "OnlyForcedSubtitles": "강제로 설정한 자막만", + "OneChannel": "단채널", + "NoSubtitlesHelp": "자막을 자동으로 불러오지 않습니다. 재생 중에 수동으로 켤 수 있습니다.", + "MusicLibraryHelp": "{0}음악 이름 지정 규칙{1}을 확인하십시오.", + "MovieLibraryHelp": "{0}영화 이름 지정 규칙{1}을 확인하십시오.", + "MessageUnauthorizedUser": "현재 서버에 접속할 권한이 없습니다. 자세한 정보는 서버 관리자에게 문의하십시오." } diff --git a/src/strings/nb.json b/src/strings/nb.json index 3d863d17e0..1e410c9d2d 100644 --- a/src/strings/nb.json +++ b/src/strings/nb.json @@ -382,7 +382,7 @@ "Images": "Bilder", "ImportFavoriteChannelsHelp": "Hvis aktivert, vil kun kanaler som er markert som favoritt på tuneren bli importert.", "ImportMissingEpisodesHelp": "Hvis aktivert, vil informasjon om manglende episoder importeres til Jellyfin-databasen og de vil vises under sesonger og serier. Dette kan føre til at skanning av biblioteket tar betydelig lengre tid.", - "InstallingPackage": "Installerer {0}", + "InstallingPackage": "Installerer {0} (versjon {1})", "InstantMix": "Direktemiks", "ItemCount": "{0} elementer", "Items": "Elementer", @@ -1129,9 +1129,9 @@ "AllowOnTheFlySubtitleExtractionHelp": "Integrerte undertekster kan hentes ut fra videoer og bli levert til klienter i klartekst for å unngå omkoding av video. På noen systemer kan dette ta lang tid og føre til opphold i avspillingen samtidig som prosessen pågår. Deaktiver innstillingen for å brenne inn underteksten i videoen ved hjelp av omkoding når undertekstformatet ikke er støttet av klienten.", "AllowOnTheFlySubtitleExtraction": "Tillat at undertekster hentes ut fortløpende", "AllLanguages": "Alle språk", - "AllComplexFormats": "Alle avanserte formater (ASS, SSA, VOBSUB, PGS, SUB/IDX, etc.)", + "AllComplexFormats": "Alle avanserte formater (ASS, SSA, VOBSUB, PGS, SUB, IDX)", "AccessRestrictedTryAgainLater": "Tilgang er for øyeblikket begrenset. Vennligst prøv igjen senere.", - "BurnSubtitlesHelp": "Angir om serveren skal brenne inn teksting når videoer konverteres, basert på tekstformatet. Ytelsen på serveren vil forbedres dersom tekstingen ikke brennes inn. Velg Automatisk for å brenne inn bildebaserte formater (VOBSUB, PGS, SUB/IDX, osv.) og enkelte ASS/SSA-undertekster.", + "BurnSubtitlesHelp": "Angir om serveren skal brenne inn teksting når videoer konverteres, basert på tekstformatet. Ytelsen på serveren vil forbedres dersom tekstingen ikke brennes inn. Velg Automatisk for å brenne inn bildebaserte formater (VOBSUB, PGS, SUB, IDX) og enkelte ASS eller SSA-undertekster.", "General": "Generelt", "ChangingMetadataImageSettingsNewContent": "Endringer gjort i innstillinger for metadata eller omslagsbilder vil kun gjelde nytt innhold i biblioteket ditt. For å endre eksisterende innhold, må du oppdatere dets metadata manuelt.", "DefaultSubtitlesHelp": "Undertekster lastes inn basert på flaggene \"standard\" og \"tvungen\" i videoens integrerte metadata. Språkpreferanser tas høyde for dersom flere valg er tilgjengelig.", @@ -1218,7 +1218,7 @@ "Unmute": "Skru på lyd", "OptionIsHD": "HD", "ButtonAddImage": "Legg til bilde", - "DisplayModeHelp": "Velg hvilken slags skjerm du bruker Jellyfin på.", + "DisplayModeHelp": "Velg hvilket brukergrensesnitt oppsett du vil ha.", "DownloadsValue": "{0} nedlastninger", "EnableNextVideoInfoOverlayHelp": "Vis informasjon om den neste videoen i spillelisten ved slutten av en video.", "ExtractChapterImagesHelp": "Uthenting av kapittelbilder vil gjøre det mulig for klienter å vise bilder i menyer for å velge kapitel. Denne prosessen kan være treg, ressurskrevende, og kan kreve flere gigabyte med lagringsplass. Prosessen kjører når videoer oppdages, samt som en daglig planlagt hendelse. Tidsplanen kan endres i innstillinger for planlagte hendelser. Det anbefales ikke at denne prosessen kjøres når det er mange aktive brukere innlogget.", @@ -1467,5 +1467,11 @@ "AskAdminToCreateLibrary": "Spør en administrator om å lage et bibliotek.", "PlaybackErrorNoCompatibleStream": "Det oppstod et problem med klientprofilering, og serveren sender ikke et kompatibelt medieformat.", "AllowFfmpegThrottlingHelp": "Når en omkoding eller ompakking kommer langt nok foran den nåværende avspillingsposisjonen stoppes prosessen slik at den bruker mindre ressurser. Dette er mest nyttig når du sjeldent bytter posisjon i videoen. Slå av dette hvis du opplever problemer med avspilling.", - "AllowFfmpegThrottling": "Begrens hastighet på omkoding" + "AllowFfmpegThrottling": "Begrens hastighet på omkoding", + "Episode": "Episode", + "ClientSettings": "Klientinstillinger", + "BoxSet": "Samleboks", + "Artist": "Artist", + "AlbumArtist": "Albumartist", + "Album": "Album" } diff --git a/src/strings/nl.json b/src/strings/nl.json index 37d2ca34ad..06bd4ca22c 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -26,7 +26,7 @@ "AllowRemoteAccess": "Externe verbindingen met deze Jellyfin Server toestaan.", "AllowRemoteAccessHelp": "Indien niet aangevinkt worden alle externe verbindingen geblokkeerd.", "AllowedRemoteAddressesHelp": "Komma-gescheiden lijst van IP-adressen of IP/netmask adressen voor netwerken die op afstand verbinding mogen maken. Indien blanco, worden alle externe adressen toegestaan.", - "AlwaysPlaySubtitles": "Altijd ondertitels weergeven", + "AlwaysPlaySubtitles": "Altijd afspelen", "AlwaysPlaySubtitlesHelp": "Ondertitels die met de taalvoorkeur overeenkomen worden weergegeven, ongeacht de audiotaal.", "AnyLanguage": "Elke taal", "Anytime": "Op elk moment", @@ -49,7 +49,7 @@ "BoxRear": "Hoes (achterkant)", "Browse": "Bladeren", "BrowsePluginCatalogMessage": "Bekijk de Plugin catalogus voor beschikbare Plug-ins.", - "BurnSubtitlesHelp": "Bepaalt of de server ondertitels moet inbranden wanneer video's op basis van het soort ondertitels geconverteerd moeten worden. Het inbranden van ondertitels heeft een negatief effect op de server performance. Selecteer Automatisch om op afbeelding gebaseerde formaten (VOBSUB, PGS, SUB/IDX etc.) en bepaalde ASS/SSA ondertitels in te branden.", + "BurnSubtitlesHelp": "Bepaalt of de server ondertitels moet branden bij het transcoderen van video's. Als u dit vermijd, worden de prestaties aanzienlijk verbeterd. Selecteer Auto om op afbeeldingen gebaseerde formaten (VOBSUB, PGS, SUB/IDX etc.) en bepaalde ASS/SSA ondertitels te branden.", "ButtonAdd": "Toevoegen", "ButtonAddMediaLibrary": "Voeg Media Bibliotheek toe", "ButtonAddScheduledTaskTrigger": "Trigger Toevoegen", @@ -178,7 +178,7 @@ "DisplayInOtherHomeScreenSections": "In secties van het startscherm weergeven, zoals \"Recente Media\" en \"Verder Kijken\"", "DisplayMissingEpisodesWithinSeasons": "Toon ontbrekende afleveringen binnen een seizoen", "DisplayMissingEpisodesWithinSeasonsHelp": "Dit moet ook worden ingeschakeld voor TV bibliotheken in de server configuratie.", - "DisplayModeHelp": "Selecteer het scherm type waar u Jellyfin op draait", + "DisplayModeHelp": "Selecteer het schermtype waar Jellyfin op draait.", "DoNotRecord": "Niet opnemen", "Down": "Omlaag", "Download": "Downloaden", @@ -195,10 +195,10 @@ "EnableColorCodedBackgrounds": "Kleurgecodeerde achtergronden", "EnableDisplayMirroring": "Beeld spiegelen", "EnableExternalVideoPlayers": "Externe video spelers", - "EnableExternalVideoPlayersHelp": "Een menu voor externe spelers zal worden getoond bij het afspelen van video's", + "EnableExternalVideoPlayersHelp": "Een menu voor externe spelers wordt getoond bij het afspelen van video's.", "EnableHardwareEncoding": "Activeer hardwaredecodering", "EnableNextVideoInfoOverlay": "Toon informatie over de volgende video tijdens het afspelen", - "EnableNextVideoInfoOverlayHelp": "Toon informatie over de volgende video in de afspeellijst aan het einde van de video", + "EnableNextVideoInfoOverlayHelp": "Toon informatie over de volgende video in de afspeellijst aan het einde van de video.", "EnablePhotos": "Foto's weergeven", "EnablePhotosHelp": "Afbeeldingen worden herkend en weergegeven naast andere mediabestanden.", "EnableStreamLooping": "Livestreams automatisch herhalen", @@ -254,7 +254,7 @@ "EncoderPresetHelp": "Kies een hogere waarde om de prestaties, of een tragere waarde om de kwaliteit te verbeteren.", "HDPrograms": "HD Programma's", "HandledByProxy": "Behandeld door reverse proxy", - "HardwareAccelerationWarning": "Hardwareversnelling inschakelen kan instabiliteit veroorzaken in sommige omgevingen. Zorg ervoor dat uw besturingssysteem en videostuurprogramma's volledig up-to-date zijn. Als u problemen ondervindt bij het afspelen van video, nadat u dit hebt ingeschakeld, moet u de instelling terugzetten naar Auto.", + "HardwareAccelerationWarning": "Hardwareversnelling inschakelen kan instabiliteit veroorzaken in sommige omgevingen. Zorg ervoor dat uw besturingssysteem en videostuurprogramma's volledig up-to-date zijn. Als u problemen ondervindt bij het afspelen van video, nadat u dit hebt ingeschakeld, moet u de instelling terugzetten naar geen.", "HeaderAccessSchedule": "Schema Toegang", "HeaderAccessScheduleHelp": "Maak een toegangsschema om de toegang tot bepaalde tijden te beperken.", "HeaderActiveDevices": "Actieve apparaten", @@ -278,7 +278,7 @@ "HeaderAudioBooks": "Luisterboeken", "HeaderAudioSettings": "Audio Instellingen", "HeaderAutomaticUpdates": "Automatische updates", - "HeaderBlockItemsWithNoRating": "Blokkeer items met geen of niet herkende keurinformatie.", + "HeaderBlockItemsWithNoRating": "Blokkeer items met geen of niet herkende beoordelingsinformatie:", "HeaderBooks": "Boeken", "HeaderBranding": "Huisstijl", "HeaderCancelRecording": "Opname Annuleren", @@ -411,7 +411,7 @@ "HeaderSelectTranscodingPath": "Selecteer Tijdelijke Transcodeer Pad", "HeaderSelectTranscodingPathHelp": "Bladeren of voer het pad in om te gebruiken voor het transcoderen van tijdelijke bestanden. De map moet beschrijfbaar zijn.", "HeaderSendMessage": "Stuur bericht", - "HeaderSeries": "Series:", + "HeaderSeries": "Series", "HeaderSeriesOptions": "Series Opties", "HeaderSeriesStatus": "Seriestatus", "HeaderServerSettings": "Server Instellingen", @@ -461,9 +461,9 @@ "Images": "Afbeeldingen", "ImportFavoriteChannelsHelp": "Bij inschakelen zullen alleen kanalen geïmporteerd worden die op de tuner als favoriet aangemerkt zijn.", "ImportMissingEpisodesHelp": "Indien ingeschakeld, wordt informatie over ontbrekende afleveringen in uw Jellyfin de database geïmporteerd en weergegeven in de seizoenen en series. Dit kan aanzienlijk langere bibliotheekscans veroorzaken.", - "InstallingPackage": "Installeren van {0}", + "InstallingPackage": "Installeren van {0} (versie {1})", "Kids": "Kinderen", - "Label3DFormat": "3D formaat", + "Label3DFormat": "3D formaat:", "LabelAbortedByServerShutdown": "(Afgebroken door afsluiten van de server)", "LabelAccessDay": "Dag van de week:", "LabelAccessEnd": "Eind tijd:", @@ -491,7 +491,7 @@ "LabelArtists": "Artiest:", "LabelArtistsHelp": "Scheidt meerdere met een ;", "LabelAudioLanguagePreference": "Voorkeurs audiotaal:", - "LabelAutomaticallyRefreshInternetMetadataEvery": "Vernieuw metagegevens automatisch van het internet", + "LabelAutomaticallyRefreshInternetMetadataEvery": "Vernieuw metagegevens automatisch van het internet:", "LabelBindToLocalNetworkAddress": "Binden aan het lokale netwerk adres:", "LabelBindToLocalNetworkAddressHelp": "Optioneel. Overrule het lokale IP-adres om aan de http-server te binden. Indien leeg gelaten, zal de server binden aan alle beschikbare adressen. Het veranderen van deze waarde vereist herstarten van Jellyfin Server.", "LabelBirthDate": "Geboortedatum:", @@ -506,7 +506,7 @@ "LabelCertificatePassword": "Certificaat paswoord:", "LabelCertificatePasswordHelp": "Als je certificaat een paswoord vereist, vul het dan hier in alstublieft.", "LabelChannels": "Kanalen:", - "LabelCollection": "Collectie", + "LabelCollection": "Collectie:", "LabelCommunityRating": "Beoordeling gemeenschap:", "LabelContentType": "Inhoud type:", "LabelCountry": "Land:", @@ -547,7 +547,7 @@ "LabelEmbedAlbumArtDidl": "Insluiten van albumhoezen in Didl", "LabelEmbedAlbumArtDidlHelp": "Sommige apparaten prefereren deze methode voor het verkrijgen van albumhoezen. Anderen kunnen falen om af te spelen met deze optie ingeschakeld.", "LabelEnableAutomaticPortMap": "Schakel automatisch poort vertalen in", - "LabelEnableAutomaticPortMapHelp": "Probeer om de publieke poort automatisch te vertalen naar de lokale poort via UPnP. Dit werkt niet op alle routers.", + "LabelEnableAutomaticPortMapHelp": "Poging om de publieke poort automatisch om te zetten naar een lokale poort via UPnP. Dit werkt niet op alle routers. De wijzigingen worden pas actief na een herstart van de server.", "LabelEnableBlastAliveMessages": "Alive berichten zenden", "LabelEnableBlastAliveMessagesHelp": "Zet dit aan als de server niet betrouwbaar door andere UPnP-apparaten op uw netwerk wordt gedetecteerd.", "LabelEnableDlnaClientDiscoveryInterval": "Interval voor het zoeken naar clients (seconden)", @@ -563,7 +563,7 @@ "LabelEnableRealtimeMonitorHelp": "Wijzigingen aan bestanden worden op ondersteunde bestandssystemen direct verwerkt.", "LabelEnableSingleImageInDidlLimit": "Beperk tot één enkele ingesloten afbeelding", "LabelEnableSingleImageInDidlLimitHelp": "Sommige apparaten zullen niet goed weergeven als er meerdere afbeeldingen ingesloten zijn in Didl.", - "LabelEndDate": "Eind datum|", + "LabelEndDate": "Eind datum:", "LabelEpisodeNumber": "Afleveringsnummer:", "LabelEvent": "Gebeurtenis:", "LabelEveryXMinutes": "Iedere:", @@ -581,7 +581,7 @@ "LabelGroupMoviesIntoCollectionsHelp": "Bij de weergave van film lijsten, zullen films die tot een collectie behoren worden weergegeven als een gegroepeerd object.", "LabelEncoderPreset": "H264 codering preset:", "LabelHardwareAccelerationType": "Hardware acceleratie:", - "LabelHardwareAccelerationTypeHelp": "Dit is een experimentele functie die alleen beschikbaar is op ondersteunde systemen.", + "LabelHardwareAccelerationTypeHelp": "Hardwarematige versnelling vereist extra configuratie.", "LabelHomeNetworkQuality": "Thuisnetwerk kwaliteit:", "LabelHomeScreenSectionValue": "Beginscherm sectie {0}:", "LabelHttpsPort": "Lokale HTTPS poort nummer:", @@ -673,7 +673,7 @@ "LabelParentNumber": "Bovenliggend nummer:", "LabelParentalRating": "Kijkwijzer classificatie:", "LabelPassword": "Wachtwoord:", - "LabelPasswordConfirm": "Wachtworod (Bevestig)", + "LabelPasswordConfirm": "Wachtwoord (Bevestig):", "LabelPasswordRecoveryPinCode": "Pincode:", "LabelPath": "Pad:", "LabelPersonRole": "Rol:", @@ -681,17 +681,17 @@ "LabelPlaceOfBirth": "Geboorteplaats:", "LabelPlayDefaultAudioTrack": "Standaard audio spoor afspelen ongeacht de taal", "LabelPlaylist": "Afspeellijst:", - "LabelPostProcessor": "Nabewerkings toepassing:", - "LabelPostProcessorArguments": "Nabewerkings command line argumenten:", + "LabelPostProcessor": "Nabewerkings- toepassing:", + "LabelPostProcessorArguments": "Nabewerkings command lijn argumenten:", "LabelPostProcessorArgumentsHelp": "Gebruik {path} als het pad naar het opnamebestand.", - "LabelPreferredDisplayLanguage": "Voorkeurs weergavetaal:", + "LabelPreferredDisplayLanguage": "Voorkeur weergavetaal:", "LabelPreferredDisplayLanguageHelp": "Vertaling van Jellyfin is een voortdurend project.", - "LabelPreferredSubtitleLanguage": "Voorkeurstaal ondertitels:", + "LabelPreferredSubtitleLanguage": "Voorkeurstaal ondertiteling:", "LabelPrevious": "Vorige", "LabelProfileAudioCodecs": "Geluidscodecs:", - "LabelProfileCodecsHelp": "Gescheiden door een komma. Deze kan leeg gelaten worden om te laten gelden voor alle codecs.", - "LabelProfileContainersHelp": "Gescheiden door een komma. Deze kan leeg gelaten worden om te laten gelden voor alle containers.", - "LabelProtocol": "Protokol:", + "LabelProfileCodecsHelp": "Gescheiden door een komma. Dit kan leeg worden gelaten om te laten gelden voor alle codecs.", + "LabelProfileContainersHelp": "Gescheiden door een komma. Dit kan leeg worden gelaten om te laten gelden voor alle containers.", + "LabelProtocol": "Protocol:", "LabelProtocolInfoHelp": "De waarde die wordt gebruikt bij het reageren op GetProtocolInfo verzoeken van het apparaat.", "LabelPublicHttpPort": "Publieke HTTP poort nummer:", "LabelPublicHttpPortHelp": "Het publieke poortnummer dat moet worden toegewezen aan de lokale HTTP poort.", @@ -702,12 +702,12 @@ "LabelRecord": "Opnemen:", "LabelRecordingPath": "Standaard opname pad:", "LabelRecordingPathHelp": "Geef de standaard locatie op om opnamen op te slaan. Indien leeg gelaten, zal de map van de server-programma gegevens worden gebruikt.", - "LabelRefreshMode": "Vernieuw-modus", + "LabelRefreshMode": "Ververs-modus:", "LabelReleaseDate": "Uitgave datum:", "LabelRemoteClientBitrateLimit": "Internet streaming bitrate limiet (Mbps):", - "LabelRemoteClientBitrateLimitHelp": "Een optionele bitrate limiet per stream voor alle apparaten buiten het netwerk. Dit is handig om te voorkomen dat apparaten een hogere bitrate vragen dan je internetverbinding aan kan. Dit kan een verhoogde belasting van de CPU in je server veroorzaken om om videos direct te transcoderen naar een lagere bitrate.", + "LabelRemoteClientBitrateLimitHelp": "Een optionele bitrate per stream limiet voor alle apparaten buiten het netwerk. Dit is handig om te voorkomen dat apparaten een hogere bitrate vragen dan je internetverbinding aan kan. Dit kan een verhoogde belasting van de CPU in je server veroorzaken om videos direct te transcoderen naar een lagere bitrate.", "LabelRuntimeMinutes": "Speelduur (minuten):", - "LabelSaveLocalMetadata": "Afbeeldingen opslaan in de mediamappen", + "LabelSaveLocalMetadata": "Afbeeldingen opslaan in mediamappen", "LabelSaveLocalMetadataHelp": "Door afbeeldingen op te slaan in de mediamappen kunnen ze makkelijker worden aangepast.", "LabelScheduledTaskLastRan": "Laatste keer {0}, duur {1}.", "LabelScreensaver": "Schermbeveiliging:", @@ -722,31 +722,31 @@ "LabelSeriesRecordingPath": "Serieopname pad (optioneel):", "LabelServerHost": "Server:", "LabelServerHostHelp": "192.168.1.100:8096 of https://mijnserver.nl", - "LabelSimultaneousConnectionLimit": "Gelijktijdige streams limiet:", - "LabelSkipBackLength": "Terugspoellengte", - "LabelSkipForwardLength": "Vooruitspoellengte", + "LabelSimultaneousConnectionLimit": "Gelijktijdige stream limiet:", + "LabelSkipBackLength": "Terugspoellengte:", + "LabelSkipForwardLength": "Vooruitspoellengte:", "LabelSkipIfAudioTrackPresent": "Overslaan als het standaard geluidsspoor overeenkomt met de taal van de download", - "LabelSkipIfAudioTrackPresentHelp": "Vink dit uit om ervoor te zorgen dat alle video's ondertiteings krijgen, ongeacht de geluidstaal.", + "LabelSkipIfAudioTrackPresentHelp": "Vink dit uit om ervoor te zorgen dat alle video's ondertitelingen krijgen, ongeacht de geluidstaal.", "LabelSkipIfGraphicalSubsPresent": "Overslaan als de video al ingesloten ondertiteling heeft", "LabelSkipIfGraphicalSubsPresentHelp": "Tekstversies van ondertiteling opslaan zal video's efficiënter overbrengen en de kans op transcodering van video's verkleinen.", "LabelSonyAggregationFlags": "Sony aggregatie vlaggen:", "LabelSonyAggregationFlagsHelp": "Bepaalt de inhoud van het aggregationFlags element in de urn: schemas-sonycom av namespace.", "LabelSortBy": "Sorteren op:", - "LabelSortOrder": "Sorteervolgorde:", + "LabelSortOrder": "Sorteer volgorde:", "LabelSortTitle": "Sorteer titel:", "LabelSoundEffects": "Geluidseffecten:", "LabelSource": "Bron:", - "LabelSpecialSeasonsDisplayName": "De weergavenaam van de speciale seizoen:", + "LabelSpecialSeasonsDisplayName": "De weergavenaam van een speciaal seizoen:", "LabelSportsCategories": "Sport categorieën:", "LabelStartWhenPossible": "Start indien mogelijk:", "LabelStopWhenPossible": "Stop indien mogelijk:", "LabelStopping": "Stoppen", - "LabelSubtitleDownloaders": "Ondertiteldownloaders:", + "LabelSubtitleDownloaders": "Ondertiteling downloaders:", "LabelSubtitleFormatHelp": "Voorbeeld: srt", - "LabelSubtitlePlaybackMode": "Ondertitel mode:", - "LabelSubtitles": "Ondertitels", + "LabelSubtitlePlaybackMode": "Ondertitel modus:", + "LabelSubtitles": "Ondertiteling", "LabelSupportedMediaTypes": "Ondersteunde Media Types:", - "LabelTVHomeScreen": "TV mode begin scherm", + "LabelTVHomeScreen": "TV mode begin scherm:", "LabelTextBackgroundColor": "Tekst achtergrond kleur:", "LabelTextColor": "Tekst kleur:", "LabelTextSize": "Tekst grootte:", @@ -756,9 +756,9 @@ "LabelTitle": "Titel:", "LabelTrackNumber": "Tracknummer:", "LabelTranscodingAudioCodec": "Geluidscodec:", - "LabelTranscodingTempPathHelp": "Specificeer een eigen pad voor de transcode bestanden die geleverd worden aan cliënten. Laat leeg om het server standaard te gebruiken.", - "LabelTranscodingThreadCount": "Aantal transcodeer threads:", - "LabelTranscodingThreadCountHelp": "Selecteer het maximale aantal threads die gebruikt mogen worden om te transcoderen. Bij een lager aantal zal het CPU gebruik lager zijn, maar kan de afspeelkwaliteit minder zijn.", + "LabelTranscodingTempPathHelp": "Specificeer een eigen pad voor de transcode bestanden die geleverd worden aan gebruikers. Laat leeg om de server standaard te gebruiken.", + "LabelTranscodingThreadCount": "Aantal transcodeer draden:", + "LabelTranscodingThreadCountHelp": "Selecteer het maximale aantal draden die gebruikt mogen worden om te kunnen transcoderen. Bij een lager aantal zal het processorgebruik lager zijn, maar kan de afspeelkwaliteit minder zijn voor een vloeiende ervaring.", "LabelTunerIpAddress": "Tuner IP adres:", "LabelTunerType": "Soort Tuner:", "LabelTypeText": "Tekst", @@ -766,8 +766,8 @@ "LabelUser": "Gebruiker:", "LabelUserAgent": "User-agent:", "LabelUserLibrary": "Gebruikers Bibliotheek:", - "LabelUserLibraryHelp": "Selecteer welke gebruikers bibliotheek weergegeven moet worden op het apparaat. Laat leeg standaardinstelling te gebruiken.", - "LabelUserRemoteClientBitrateLimitHelp": "Schrijf de standaard globale waarde gedefineerd in de server afspeel instellingen.", + "LabelUserLibraryHelp": "Selecteer welke gebruikers bibliotheek weergegeven moeten worden op het apparaat. Laat leeg om de standaardinstelling te gebruiken.", + "LabelUserRemoteClientBitrateLimitHelp": "Schrijf de standaard globale waarde gedefinieerd in de server afspeel instellingen.", "LabelUsername": "Gebruikersnaam:", "LabelVaapiDevice": "VA API Apparaat:", "LabelVaapiDeviceHelp": "Dit is de render knooppunt dat wordt gebruikt voor hardwareversnelling.", @@ -792,11 +792,11 @@ "List": "Lijst", "LiveBroadcasts": "Live uitzendingen", "ManageLibrary": "Bibliotheek beheren", - "ManageRecording": "Beheren opnames", + "ManageRecording": "Beheer opnames", "MapChannels": "Map Kanalen", - "MarkPlayed": "Markeren als Afgespeeld", - "MarkUnplayed": "Markeren als Niet Afgespeeld", - "MaxParentalRatingHelp": "Media met een hogere classificatie wordt niet weergegeven", + "MarkPlayed": "Markeren als afgespeeld", + "MarkUnplayed": "Markeren als niet afgespeeld", + "MaxParentalRatingHelp": "Media met een hogere classificatie wordt niet weergegeven voor deze gebruiker.", "MediaInfoAnamorphic": "Anamorf", "MediaInfoAspectRatio": "Beeld verhouding", "MediaInfoBitDepth": "Bitdiepte", @@ -811,48 +811,48 @@ "MediaInfoPixelFormat": "Pixel formaat", "MediaInfoProfile": "Profiel", "MediaInfoResolution": "Resolutie", - "MediaInfoSampleRate": "Samplesnelheid", + "MediaInfoSampleRate": "Bemonsteringsfrequentie", "MediaInfoSize": "Grootte", "MediaInfoTimestamp": "Tijdstempel", - "MediaIsBeingConverted": "De media wordt geconverteerd naar een formaat dat compatible is met het apparaat dat wordt gebruikt om de media af te spelen.", - "MessageAlreadyInstalled": "Deze versie is al geïnstalleerd", - "MessageAreYouSureDeleteSubtitles": "Weet u zeker dat u dit ondertitelbestand wilt verwijderen?", + "MediaIsBeingConverted": "De media wordt geconverteerd naar een formaat dat leesbaar is met het apparaat dat wordt gebruikt om de media af te spelen.", + "MessageAlreadyInstalled": "Deze versie is al geïnstalleerd.", + "MessageAreYouSureDeleteSubtitles": "Weet u zeker dat u dit ondertitelingsbestand wilt verwijderen?", "MessageAreYouSureYouWishToRemoveMediaFolder": "Weet u zeker dat u deze media map wilt verwijderen?", "MessageConfirmDeleteGuideProvider": "Weet u zeker dat u deze gidsprovider wilt verwijderen?", "MessageConfirmDeleteTunerDevice": "Weet u zeker dat u dit apparaat wilt verwijderen?", "MessageConfirmProfileDeletion": "Weet u zeker dat u dit profiel wilt verwijderen?", - "MessageConfirmRecordingCancellation": "Opnemen annuleren?", + "MessageConfirmRecordingCancellation": "Opname annuleren?", "MessageConfirmRemoveMediaLocation": "Weet u zeker dat u deze locatie wilt verwijderen?", "MessageConfirmRestart": "Weet u zeker dat u Jellyfin Server wilt herstarten?", - "MessageConfirmRevokeApiKey": "Weet u zeker dat u deze api key in wilt trekken? De verbinding met Jellyfin Server zal direct verbroken worden.", + "MessageConfirmRevokeApiKey": "Weet u zeker dat u deze api sleutel in wilt trekken? De verbinding met Jellyfin Server zal direct verbroken worden.", "MessageConfirmShutdown": "Weet u zeker dat u de server wilt afsluiten?", "MessageContactAdminToResetPassword": "Neem contact op met de server beheerder om uw wachtwoord te resetten.", "MessageCreateAccountAt": "Maak een account bij {0}", - "MessageDeleteTaskTrigger": "Weet u zeker dat u deze taak trigger wilt verwijderen?", + "MessageDeleteTaskTrigger": "Weet u zeker dat u deze signaal taak wilt verwijderen?", "MessageDirectoryPickerBSDInstruction": "Voor BSD kan het noodzakelijk zijn opslag op uw FreeNAS Jail te configureren voordat Jellyfin het kan benaderen.", - "MessageDirectoryPickerInstruction": "Netwerk paden kunnen handmatig worden ingevoerd in het geval de Netwerk knop faalt om uw apparatuur te lokaliseren . Bijvoorbeeld: {0} of {1}.", + "MessageDirectoryPickerInstruction": "Netwerk paden kunnen handmatig worden ingevoerd in het geval de Netwerk knop faalt om uw apparatuur te lokaliseren. Bijvoorbeeld: {0} of {1}.", "MessageDirectoryPickerLinuxInstruction": "Voor Linux op Arch Linux, CentOS, Debian, Fedora, openSUSE, of Ubuntu, moet u de service-gebruiker ten minste leestoegang tot uw opslaglocaties verlenen.", "MessageDownloadQueued": "Download in de wachtrij geplaatst.", - "MessageEnablingOptionLongerScans": "Inschakelen van deze optie kan leiden tot langere doorlooptijd van bibliotheek scans.", + "MessageEnablingOptionLongerScans": "Het inschakelen van deze optie kan leiden tot langere doorlooptijd van bibliotheek scans.", "MessageFileReadError": "Er is een fout opgetreden bij het lezen van het bestand. Probeer het opnieuw.", - "MessageForgotPasswordFileCreated": "Het volgende bestand met instructies hoe nu verder te gaan is gemaakt:", + "MessageForgotPasswordFileCreated": "Het volgende bestand is gecreëerd op uw server en bevat instructies om verder te gaan:", "MessageForgotPasswordInNetworkRequired": "Probeer de wachtwoord herstel procedure opnieuw vanuit uw thuisnetwerk.", "MessageInstallPluginFromApp": "Deze plugin moet geïnstalleerd worden vanuit de app waarin u het wilt gebruiken.", "MessageInvalidForgotPasswordPin": "Er is een ongeldige of verlopen pincode ingegeven. Probeer opnieuw.", - "MessageInvalidUser": "Foutieve gebruikersnaam of wachtwoord. Probeer opnieuw.", + "MessageInvalidUser": "Incorrecte gebruikersnaam of wachtwoord. Probeer opnieuw.", "MessageItemSaved": "Item opgeslagen.", - "MessageItemsAdded": "Items toegevoegd", + "MessageItemsAdded": "Items toegevoegd.", "MessageLeaveEmptyToInherit": "Leeg laten om instellingen van bovenliggend item of de algemene waarde over te nemen.", "MessageNoAvailablePlugins": "Geen beschikbare Plugins.", "MessageNoMovieSuggestionsAvailable": "Er zijn momenteel geen film suggesties beschikbaar. Begin met het bekijken en waardeer uw films, kom daarna terug om uw aanbevelingen te bekijken.", - "MessageNoPluginsInstalled": "U heeft geen Plugins geïnstalleerd.", - "MessageNoTrailersFound": "Geen trailers gevonden. Installeer het Trailers kanaal en verbeter uw film ervaring door middel van een bibliotheek met internet trailers.", + "MessageNoPluginsInstalled": "U heeft geen plugins geïnstalleerd.", + "MessageNoTrailersFound": "Geen trailers gevonden. Installeer het Trailers kanaal om uw film ervaring te verbeteren door middel van het toevoegen van een bibliotheek met internet trailers.", "MessageNothingHere": "Lijst is leeg.", - "MessagePasswordResetForUsers": "De volgende gebruikers hebben hun wachtwoord laten resetten. Zij kunnen nu inloggen met de pin codes die gebruikt werden om de reset te voltooien.", + "MessagePasswordResetForUsers": "De volgende gebruikers hebben hun wachtwoord laten herstellen. Zij kunnen nu inloggen met de pin codes die gebruikt werden om de herstel te voltooien.", "MessagePlayAccessRestricted": "Afspelen hiervan is op dit moment niet toegestaan. Neem contact op met uw server beheerder voor meer informatie.", "MessagePleaseEnsureInternetMetadata": "Zorg ervoor dat het downloaden van internet-metadata is ingeschakeld.", "MessagePleaseWait": "Even geduld. Dit kan even duren.", - "MessagePluginConfigurationRequiresLocalAccess": "Meld svp. op de lokale server aan om deze plugin te configureren.", + "MessagePluginConfigurationRequiresLocalAccess": "Om deze plugin te configuren moet u zich aanmelden direct op de lokale server.", "MessagePluginInstallDisclaimer": "Plugins ontwikkeld door leden van de Jellyfin gemeenschap zijn een geweldige manier om uw Jellyfin ervaring met extra functies en voordelen te verbeteren. Alvorens te installeren, dient u zich bewust te zijn van de gevolgen die zij kunnen hebben op uw Jellyfin Server, zoals langere bibliotheek scans, extra achtergrondinformatie verwerking, en een verminderde stabiliteit van het systeem.", "MessageReenableUser": "Zie hieronder hoe opnieuw in te schakelen", "MessageSettingsSaved": "Instellingen opgeslagen.", @@ -882,13 +882,13 @@ "NewEpisodesOnly": "Alleen nieuwe afleveringen", "News": "Nieuws", "Next": "Volgende", - "NextUp": "Volgende", + "NextUp": "Hierna", "No": "Nee", "NoNewDevicesFound": "Er zijn geen nieuwe apparaten gevonden. Sluit dit melding en voer handmatig de apparaat gegevens in om een nieuwe tuner toe te voegen.", "NoNextUpItemsMessage": "Niets gevonden. Start met kijken!", "NoPluginConfigurationMessage": "Deze plugin heeft geen instellingen te configureren.", "NoSubtitleSearchResultsFound": "Geen resultaten gevonden.", - "NoSubtitles": "Geen ondertitels", + "NoSubtitles": "Geen ondertiteling", "NoSubtitlesHelp": "Ondertitels worden niet standaard weergegeven. Deze kunnen tijdens het afspelen handmatig worden ingeschakeld.", "None": "Geen", "Normal": "Normaal", @@ -896,14 +896,14 @@ "OneChannel": "Eén kanaal", "OnlyForcedSubtitles": "Alleen geforceerde ondertitels", "OnlyForcedSubtitlesHelp": "Alleen als geforceerd gemarkeerde ondertitels worden geladen.", - "OnlyImageFormats": "Alleen image formaten (VOBSUP, PGS, SUB, etc.)", + "OnlyImageFormats": "Alleen beeld formaten (VOBSUP, PGS, SUB, etc.)", "OptionAdminUsers": "Beheerders", "OptionAlbumArtist": "Albumartiest", "OptionAllUsers": "Alle gebruikers", "OptionAllowAudioPlaybackTranscoding": "Afspelen van geluid via transcoding toestaan", "OptionAllowBrowsingLiveTv": "Live TV toegang toestaan", "OptionAllowContentDownloading": "Media downloaden en synchroniseren toestaan", - "OptionAllowLinkSharing": "Sta social media delen toe", + "OptionAllowLinkSharing": "Sta het delen op social media toe", "OptionAllowLinkSharingHelp": "Alleen webpagina's met media-informatie worden gedeeld. Media-bestanden worden nooit publiekelijk gedeeld. Gedeelde items zijn beperkt in tijd en verlopen na {0} dagen.", "OptionAllowManageLiveTv": "Live TV opname beheer toestaan", "OptionAllowMediaPlayback": "Media afspelen toestaan", @@ -914,7 +914,7 @@ "OptionAllowSyncTranscoding": "Het downloaden en synchroniseren van media via transcoding toestaan", "OptionAllowUserToManageServer": "Deze gebruiker kan de server beheren", "OptionAllowVideoPlaybackRemuxing": "Sta afspelen toe van video die conversie vereist zonder re-encoding", - "OptionAllowVideoPlaybackTranscoding": "Afspelen van video via transcoding toestaan", + "OptionAllowVideoPlaybackTranscoding": "Afspelen van video die transcoderen vereisen toestaan", "OptionArtist": "Artiest", "OptionAscending": "Oplopend", "OptionAutomatic": "Automatisch", @@ -927,8 +927,8 @@ "OptionBlockMusic": "Muziek", "OptionBlockTvShows": "TV Series", "OptionBluray": "Blu-ray", - "OptionCommunityRating": "Gemeenschaps Waardering", - "OptionContinuing": "Wordt vervolgd...", + "OptionCommunityRating": "Algemene Waardering", + "OptionContinuing": "Wordt vervolgd", "OptionCriticRating": "Kritieken", "OptionCustomUsers": "Aangepast", "OptionDaily": "Dagelijks", @@ -937,7 +937,7 @@ "OptionDateAddedImportTime": "Gebruik scan datum", "OptionDatePlayed": "Datum afgespeeld", "OptionDescending": "Aflopend", - "OptionDisableUser": "Dit account uitschakelen", + "OptionDisableUser": "Deze gebruiker uitschakelen", "OptionDisableUserHelp": "Indien uitgeschakeld zal de server geen verbindingen van deze gebruiker toestaan. Bestaande verbindingen zullen abrupt worden beëindigd.", "OptionDislikes": "Niet leuk", "OptionDisplayFolderView": "Toon een mappenweergave als u gewoon Mediamappen wilt weergeven", @@ -956,10 +956,10 @@ "OptionEnableExternalContentInSuggestionsHelp": "Laat internet trailers en live-tv-programma's op te nemen binnen de voorgestelde inhoud.", "OptionEnableForAllTuners": "Inschakelen voor alle tuners", "OptionEnableM2tsMode": "M2ts-modus inschakelen", - "OptionEnableM2tsModeHelp": "m2ts-modus bij het encoderen naar mpegts inschakelen", + "OptionEnableM2tsModeHelp": "M2ts-modus bij het encoderen naar mpegts inschakelen.", "OptionEnded": "Gestopt", "OptionEquals": "Is gelijk aan", - "OptionEstimateContentLength": "Lengte schatten van de inhoud bij het transcoderen", + "OptionEstimateContentLength": "Lengte inschatten van de inhoud bij het transcoderen", "OptionEveryday": "Elke dag", "OptionExternallyDownloaded": "Externe download", "OptionExtractChapterImage": "Inschakelen uitpakken van hoofdstuk afbeeldingen", @@ -967,10 +967,10 @@ "OptionFriday": "Vrijdag", "OptionHasSpecialFeatures": "Extra's", "OptionHasSubtitles": "Ondertiteling", - "OptionHasThemeSong": "Herkenningsmelodie", + "OptionHasThemeSong": "Thema Lied", "OptionHasThemeVideo": "Thema Video", "OptionHideUser": "Verberg deze gebruiker op de aanmeldschermen", - "OptionHideUserFromLoginHelp": "Handig voor pivé of verborgen beheer accounts. De gebruiker zal handmatig m.b.v. gebruikersnaam en wachtwoord aan moeten melden.", + "OptionHideUserFromLoginHelp": "Handig voor pivé of verborgen beheer accounts. De gebruiker zal handmatig moeten inloggen met een gebruikersnaam en wachtwoord.", "OptionHlsSegmentedSubtitles": "HLS gesegmenteerde ondertiteling", "OptionHomeVideos": "Foto's", "OptionIgnoreTranscodeByteRangeRequests": "Transcodeer byte range-aanvragen negeren", @@ -1020,9 +1020,9 @@ "OptionWeekly": "Wekelijks", "OriginalAirDateValue": "Originele uitzenddatum: {0}", "Overview": "Overzicht", - "PackageInstallCancelled": "{0} installatie geannuleerd.", - "PackageInstallCompleted": "{0} installatie voltooid.", - "PackageInstallFailed": "{0} installatie is mislukt.", + "PackageInstallCancelled": "{0} (versie {1}) installatie geannuleerd.", + "PackageInstallCompleted": "{0} (versie {1}) installatie voltooid.", + "PackageInstallFailed": "{0} (versie {1}) installatie is mislukt.", "ParentalRating": "Kijkwijzer classificatie", "PasswordMatchError": "Wachtwoord en wachtwoord bevestiging moeten hetzelfde zijn.", "PasswordResetComplete": "Het wachtwoord is opnieuw ingesteld.", @@ -1064,7 +1064,7 @@ "Raised": "Verhoogd", "Rate": "Waardeer", "RecentlyWatched": "Onlangs bekeken", - "RecommendationBecauseYouLike": "Omdat u {0} leuk vond.", + "RecommendationBecauseYouLike": "Omdat u {0} leuk vond", "RecommendationBecauseYouWatched": "Omdat u keek naar {0}", "RecommendationDirectedBy": "Geregisseerd door {0}", "RecommendationStarring": "In de hoofdrollen {0}", @@ -1072,12 +1072,12 @@ "RecordSeries": "Series Opnemen", "RecordingCancelled": "Opname geannuleerd.", "RecordingPathChangeMessage": "Bij het wijzigen van uw opnamemap zullen bestaande opnamen niet migreren van de oude locatie naar de nieuwe. U moet deze desgewenst handmatig verplaatsen.", - "RecordingScheduled": "Opname schema", + "RecordingScheduled": "Opname schema.", "Recordings": "Opnames", "Refresh": "Vernieuwen", "RefreshDialogHelp": "Metadata wordt vernieuwd op basis van de instellingen en internet diensten die zijn ingeschakeld in het dashboard van de Jellyfin Server.", "RefreshMetadata": "Metadata vernieuwen", - "RefreshQueued": "Vernieuwen wachtrij", + "RefreshQueued": "Verversen wachtrij.", "ReleaseDate": "Uitgave datum", "RememberMe": "Onthoud mij", "RemoveFromCollection": "Verwijder uit collectie", @@ -1085,7 +1085,7 @@ "Repeat": "Herhaling", "RepeatAll": "Alle herhalen", "RepeatEpisodes": "Herhaal afleveringen", - "RepeatMode": "Herhaal mode", + "RepeatMode": "Herhaal modus", "RepeatOne": "Eén herhalen", "ReplaceAllMetadata": "Alle metadata vervangen", "ReplaceExistingImages": "Bestaande afbeeldingen vervangen", @@ -1132,7 +1132,7 @@ "SkipEpisodesAlreadyInMyLibrary": "Neem geen afleveringen op die al in mijn bibliotheek aanwezig zijn", "SkipEpisodesAlreadyInMyLibraryHelp": "Afleveringen zullen worden vergeleken met behulp van seizoen en aflevering nummers, indien beschikbaar.", "Small": "Klein", - "SmallCaps": "Klein Kapitaal", + "SmallCaps": "Kleine letters", "Smaller": "Kleiner", "Smart": "Slim", "SmartSubtitlesHelp": "Ondertitels worden weergegeven in de voorkeurstaal als de audio in een andere taal zijn.", @@ -1201,7 +1201,7 @@ "ThemeSongs": "Themamuziek", "ThemeVideos": "Themavideo's", "TheseSettingsAffectSubtitlesOnThisDevice": "Deze instellingen betreffen ondertitels op dit apparaat", - "ThisWizardWillGuideYou": "Deze wizard helpt u door het setup-proces. Om te beginnen selecteert u eerst de gewenste taal.", + "ThisWizardWillGuideYou": "Deze helper helpt u door het opzet proces heen. Om te beginnen selecteert u eerst de gewenste taal.", "Thumb": "Miniatuur", "Thursday": "Donderdag", "TitleHardwareAcceleration": "Hardware versnelling", @@ -1249,7 +1249,7 @@ "XmlTvKidsCategoriesHelp": "Programma's met deze categorieën wordt weergegeven als programma's voor kinderen. Scheid meerdere met '|'.", "XmlTvMovieCategoriesHelp": "Programma's met deze categorieën wordt weergegeven als films. Scheid meerdere met '|'.", "XmlTvNewsCategoriesHelp": "Programma's met deze categorieën wordt weergegeven als nieuwsprogramma's. Scheid meerdere met '|'.", - "XmlTvPathHelp": "Een pad naar een XML-TV-bestand. Jellyfin zal dit bestand regelmatig lezen en controleren voor updates. U bent verantwoordelijk voor het maken en bijwerken van het bestand.", + "XmlTvPathHelp": "Een pad naar een XML-TV-bestand. Jellyfin zal dit bestand regelmatig lezen en controleren voor updates. U bent verantwoordelijk voor het maken en bijwerken van dit bestand.", "XmlTvSportsCategoriesHelp": "Programma's met deze categorieën wordt weergegeven als sportprogramma's. Scheid meerdere met '|'.", "Yes": "Ja", "Yesterday": "Gisteren", @@ -1271,8 +1271,8 @@ "Genre": "Genre", "Genres": "Genres", "HeaderAlbums": "Albums", - "HeaderCastAndCrew": "Cast & Crew", - "HeaderCastCrew": "Cast & Crew", + "HeaderCastAndCrew": "Acteurs en medewerkers", + "HeaderCastCrew": "Acteurs & medewerkers", "Art": "Afbeeldingen", "HeaderLiveTV": "Live TV", "HeaderDetails": "Details", @@ -1290,7 +1290,7 @@ "HeaderSync": "Synchronisatie", "HeaderTV": "TV", "HeaderTopPlugins": "Top Plugins", - "AuthProviderHelp": "Selecteer een Authenticatie Provider om het wachtwoord van deze gebruiker te verifiëren", + "AuthProviderHelp": "Selecteer een Authenticatie Provider om het wachtwoord van deze gebruiker te verifiëren.", "HeaderFavoriteMovies": "Favoriete Films", "HeaderFavoriteShows": "Favoriete shows", "HeaderFavoriteEpisodes": "Favoriete afleveringen", @@ -1298,7 +1298,7 @@ "HeaderFavoriteArtists": "Favoriete artiesten", "HeaderFavoriteSongs": "Favoriete nummers", "HeaderFavoriteVideos": "Favoriete Films", - "HeaderInstantMix": "Instant Mix", + "HeaderInstantMix": "Directe Mix", "HeaderItems": "Items", "HeaderJellyfinServer": "Jellyfin Server", "HeaderLiveTv": "Live TV", @@ -1322,23 +1322,23 @@ "LabelProfileCodecs": "Codecs:", "LabelProfileContainer": "Container:", "LabelProfileVideoCodecs": "Video codecs:", - "LabelProtocolInfo": "Protocool info:", + "LabelProtocolInfo": "Protocol info:", "LabelServerName": "Server naam:", - "LabelSkin": "Skin:", + "LabelSkin": "Uiterlijk:", "ButtonAddImage": "Voeg afbeelding toe", "LabelSize": "Grootte:", - "CopyStreamURLSuccess": "URL gekopieerd", - "CopyStreamURL": "Kopieer stream URL ", + "CopyStreamURLSuccess": "URL succesvol gekopieerd.", + "CopyStreamURL": "Kopieer Stream URL", "TabLiveTV": "Live TV", "ValueAlbumCount": "{0} albums", "FetchingData": "Meer data op aan het halen", "HeaderFavoriteBooks": "Favoriete Boeken", - "LabelUserLoginAttemptsBeforeLockout": "Mislukte login pogingen voordat de gebruiker buitengesloten wordt:", + "LabelUserLoginAttemptsBeforeLockout": "Mislukte aanmeld pogingen voordat de gebruiker buitengesloten wordt:", "OptionHasTrailer": "Trailer", "OptionMax": "Max", "LabelBaseUrl": "Basis URL:", - "LabelTranscodingProgress": "Transcoding voortgang:", - "LabelTriggerType": "Trigger Type:", + "LabelTranscodingProgress": "Transcoderen voortgang:", + "LabelTriggerType": "Signaal Type:", "LaunchWebAppOnStartup": "Lanceer de web interface wanneer de server start", "MediaInfoBitrate": "Bitrate", "MediaInfoInterlaced": "Interlaced", @@ -1358,13 +1358,13 @@ "SubtitleOffset": "Ondertiteling Compensatie", "LabelXDlnaDoc": "X-DLNA doc:", "LiveTV": "Live TV", - "LabelTag": "Tag:", + "LabelTag": "Label:", "Live": "Live", "OptionDvd": "DVD", "OptionResElement": "res element", "TV": "TV", "HeaderHome": "Thuis", - "MediaInfoStreamTypeEmbeddedImage": "Embedded Afbeelding", + "MediaInfoStreamTypeEmbeddedImage": "Ingeladen Afbeelding", "LabelTypeMetadataDownloaders": "{0} metadata downloaders:", "OptionLoginAttemptsBeforeLockout": "Bepaald hoeveel foutieve login pogingen plaats kunnen vinden voor dat de gebruiker buitengesloten wordt.", "Premiere": "Première", @@ -1372,7 +1372,7 @@ "LabelAudioSampleRate": "Audio sample rate:", "OptionIsHD": "HD", "OptionIsSD": "SD", - "OptionSpecialEpisode": "Specials", + "OptionSpecialEpisode": "Extra's", "TabContainers": "Containers", "TabDashboard": "Dashboard", "TabNetworking": "Netwerken", @@ -1387,7 +1387,7 @@ "OptionThumbCard": "Miniatuur kaart", "PlaybackData": "Afspeel Data", "PasswordResetProviderHelp": "Kies een wachtwoord reset provider om te gebruiken wanneer deze gebruiker een wachtwoord reset aanvraagt", - "Screenshots": "Screenshots", + "Screenshots": "Schermafdruk", "Series": "Series", "TabAlbums": "Albums", "TabGenres": "Genres", @@ -1401,7 +1401,7 @@ "MediaInfoCodec": "Codec", "Menu": "Menu", "OptionThumb": "Miniatuur", - "LabelTranscodingFramerate": "Transcoding framerate:", + "LabelTranscodingFramerate": "Transcoderen beeldverversing:", "LabelType": "Type:", "HeaderFavoritePeople": "Favoriete Mensen", "LabelAudioBitrate": "Audio bitrate:", @@ -1413,13 +1413,13 @@ "LabelLineup": "Lineup:", "LabelPlayer": "Speler:", "LabelPlayMethod": "Afspeel methode:", - "LabelPleaseRestart": "Verandering zullen toegepast worden na het handmatig herladen van de web cliënt.", + "LabelPleaseRestart": "De wijzigingen zullen worden toegepast na het handmatig herladen van de web cliënt.", "LabelStatus": "Status:", - "LabelTagline": "Tagline:", + "LabelTagline": "Label lijn:", "LabelTranscodingContainer": "Container:", - "LabelTranscodePath": "Transcode pad:", - "LabelTranscodes": "Transcodes:", - "DashboardOperatingSystem": "Besturingsysteem: {0}", + "LabelTranscodePath": "Transcodeer pad:", + "LabelTranscodes": "Transcoderen:", + "DashboardOperatingSystem": "Besturingssysteem: {0}", "LabelWeb": "Web:", "LaunchWebAppOnStartupHelp": "Open de web cliënt in uw standaard browser wanneer de server voor de eerste keer start. Dit zal niet voorkomen tijdens gebruik van de server herstart functie.", "LeaveBlankToNotSetAPassword": "U kunt dit veld leeg laten om geen wachtwoord in te stellen.", @@ -1438,17 +1438,17 @@ "Logo": "Logo", "MediaInfoCodecTag": "Codec tag", "MediaInfoContainer": "Container", - "MediaInfoFramerate": "Framerate", - "MediaInfoRefFrames": "Ref frames", + "MediaInfoFramerate": "Beeldverversing", + "MediaInfoRefFrames": "Ref beeld", "MediaInfoSoftware": "Software", - "MessageImageFileTypeAllowed": "Alleen JPEG en PNG bestanden zijn ondersteund.", - "MessageImageTypeNotSelected": "Selecteer alstublieft een afbeelding type van het drop-down menu.", + "MessageImageFileTypeAllowed": "Alleen JPEG en PNG bestanden worden ondersteund.", + "MessageImageTypeNotSelected": "Selecteer een afbeelding type van het menu alstublieft .", "MessageNoCollectionsAvailable": "Collecties staan u toe om te genieten van gepersonaliseerde groeperingen van Films, Series en Albums. Klik de + knop om te beginnen met het maken van collecties.", - "MessageNoServersAvailable": "Geen servers zijn gevonden doormiddel van het automatisch server ontdekken.", + "MessageNoServersAvailable": "Geen servers zijn gevonden door middel van het automatisch ontdekken van een server.", "Metadata": "Metadata", "MetadataManager": "Metadata Beheerder", "MusicAlbum": "Muziek Album", - "NumLocationsValue": "{0} folders", + "NumLocationsValue": "{0} mappen", "OptionBanner": "Banner", "OptionBlockTrailers": "Trailers", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", @@ -1463,5 +1463,55 @@ "OptionAuto": "Auto", "OptionProfileVideo": "Video", "AlbumArtist": "Album Artiest", - "Album": "Album" + "Album": "Album", + "DeinterlaceMethodHelp": "Selecteer de deinterlacingmethode die u wilt gebruiken bij het transcoderen van geïnterlinieerde inhoud.", + "CopyStreamURLError": "Er trad een fout op tijdens het kopieren van de URL.", + "ClientSettings": "Client instellingen", + "ButtonSplit": "Splitsen", + "BoxSet": "Box Set", + "AskAdminToCreateLibrary": "Vraag een beheerder om een bibliotheek te maken.", + "Artist": "Artiest", + "AllowFfmpegThrottlingHelp": "Wanneer een transcode of remux ver genoeg voorloopt op de huidige afspeelpositie, pauzeer het proces, zodat het minder middelen verbruikt. Dit is vooral handig wanneer u kijkt zonder vaak te zoeken. Schakel dit uit als u afspeelproblemen ondervindt.", + "AllowFfmpegThrottling": "Throttle Transcodes", + "EnableFastImageFadeInHelp": "Schakel snellere vervagings-animatie in voor ingeladen afbeeldingen", + "EnableFastImageFadeIn": "Snelle afbeeldingsvervaging", + "LabelPlayerDimensions": "Afspeellengte:", + "LabelLibraryPageSizeHelp": "Kies het aantal artikelen dat wordt weergegeven op een bibliotheekpagina. Kies 0 om dit te verbergen.", + "LabelLibraryPageSize": "Bibliotheekpagina grootte:", + "LabelDroppedFrames": "Vervallen beelden:", + "LabelDeinterlaceMethod": "Deinterlacing methode:", + "LabelCorruptedFrames": "Corrupte beelden:", + "HeaderNavigation": "Navigeren", + "Episode": "Aflevering", + "Season": "Seizoen", + "ReleaseGroup": "Uitgave groep", + "PreferEmbeddedEpisodeInfosOverFileNames": "Verkies ingeladen afleveringsinformatie boven bestandsnaam", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Dit gebruikt de afleveringsinformatie van de ingeladen metadata als deze aanwezig is.", + "PlaybackErrorNoCompatibleStream": "Deze machine is niet leesbaar met de media en de server verstuurd geen leesbare media formaten.", + "Person": "Persoon", + "OtherArtist": "Andere Artiesten", + "OptionForceRemoteSourceTranscoding": "Forceer het transcoderen van op afstand bediende media bronnen (zoals LiveTV)", + "NoCreatedLibraries": "Het lijkt erop dat er geen bibliotheek is gecreëerd. {0}Wilt u er nu een aanmaken?{1}", + "Movie": "Film", + "MessageUnauthorizedUser": "U bent niet gemachtigd om toegang tot de server te krijgen op dit moment. Neem contact op met de server beheerder voor meer informatie.", + "MessageConfirmAppExit": "Wilt u afsluiten?", + "LabelVideoResolution": "Video resolutie:", + "LabelStreamType": "Stream type:", + "UnsupportedPlayback": "Jellyfin kan DRM beschermde inhoud niet ontsleutelen. Alle inhoud zal geprobeerd worden om te ontsleutelen inclusief beschermde titels. Sommige bestanden kunnen volledig zwart zijn vanwege de versleuteling of andere niet ondersteunde functies, zoals interactieve titels.", + "OnApplicationStartup": "Op het opstarten van de applicatie", + "EveryXHours": "Elke {0} uren", + "EveryHour": "Elk uur", + "EveryXMinutes": "Elke {0} minuten", + "OnWakeFromSleep": "Op het wakker worden vanuit slaapstand", + "WeeklyAt": "{0}s op {1}", + "DailyAt": "Dagelijks op {0}", + "LastSeen": "Laatst bekeken {0}", + "PersonRole": "als {0}", + "ListPaging": "{0}-{1} van de {2}", + "WriteAccessRequired": "De Jellyfin Server vereist schrijftoegang tot deze map. Zorg evoor dat Jellyfin schrijftoegang tot de map heeft en probeer opnieuw.", + "PathNotFound": "Het pad kan niet gevonden worden. Zorg ervoor dat het pad correct is en probeer opnieuw.", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", + "Track": "Nummer", + "SelectAdminUsername": "Selecteer een gebruikersnaam voor het beheerder account." } diff --git a/src/strings/pl.json b/src/strings/pl.json index 32e9a97980..431ea3feb9 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -1467,5 +1467,8 @@ "LabelVideoResolution": "Rozdzielczość wideo:", "LabelStreamType": "Typ transmisji:", "EnableFastImageFadeInHelp": "Włącz szybszą animację pojawiania się dla załadowanych obrazów", - "EnableFastImageFadeIn": "Szybkie pojawianie się obrazów" + "EnableFastImageFadeIn": "Szybkie pojawianie się obrazów", + "Artist": "Artysta", + "AlbumArtist": "Album artysty", + "Album": "Album" } diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index 5111966b2e..6a808d090f 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -44,13 +44,13 @@ "BirthDateValue": "Nascimento: {0}", "BirthLocation": "Local de nascimento", "BirthPlaceValue": "Local de nascimento: {0}", - "BookLibraryHelp": "Livros de áudio e texto são suportados. Verifique o {0}guia de nomes de livros{1}.", + "BookLibraryHelp": "Livros de áudio e texto são suportados. Revise o {0}Guia de Nomes de Livros no Jellyfin{1}.", "Books": "Livros", "Box": "Caixa", "BoxRear": "Caixa (traseira)", "Browse": "Navegar", "BrowsePluginCatalogMessage": "Navegue pelo nosso catálogo de plugins para ver os plugins disponíveis.", - "BurnSubtitlesHelp": "Determina se o servidor deveria gravar as legendas no vídeo ao convertê-lo, dependendo do formato da legenda. Evitar a gravação da legenda irá melhorar a performance do servidor. Selecione Auto para gravar formatos de legenda baseados em imagem baseado nos formatos (ex. VOBSUB, PGS, SUB/IDX, etc.) e algumas legendas ASS/SSA.", + "BurnSubtitlesHelp": "Determina se o servidor deveria gravar as legendas no vídeo ao convertê-lo, dependendo do formato da legenda. Evitar a gravação da legenda irá melhorar a performance do servidor. Selecione Auto para gravar legendas baseados em imagem dos tipos (ex. VOBSUB, PGS, SUB/IDX, etc.) e algumas legendas ASS/SSA.", "ButtonAdd": "Adicionar", "ButtonAddMediaLibrary": "Adicionar Biblioteca de Mídia", "ButtonAddScheduledTaskTrigger": "Adicionar Disparador", @@ -218,7 +218,7 @@ "ErrorAddingTunerDevice": "Ocorreu um erro ao adicionar o sintonizador. Por favor, verifique se está acessível e tente novamente.", "ErrorAddingXmlTvFile": "Ocorreu um erro ao acessar o arquivo XmlTV. Por favor, verifique se o arquivo existe e tente novamente.", "ErrorDeletingItem": "Ocorreu um erro ao excluir o item do Servidor Jellyfin. Por favor, verifique se o Servidor Jellyfin possui acesso de gravação na pasta de mídia e tente novamente.", - "ErrorGettingTvLineups": "Ocorreu um erro ao baixar a programação da TV. Por favor, verifique se sua informação está correta e tente novamente.", + "ErrorGettingTvLineups": "Ocorreu um erro ao fazer download da programação de TV. Por favor, certifique-se que sua informação esteja correta e tente novamente.", "ErrorMessageStartHourGreaterThanEnd": "A hora final deve ser maior que a hora inicial.", "ErrorPleaseSelectLineup": "Por favor, selecione a programação e tente novamente. Se não houver programações disponíveis, verifique se o seu nome de usuário, senha e código postal estão corretos.", "ErrorSavingTvProvider": "Um erro ocorreu ao salvar o provedor de TV. Por favor, verifique se está acessível e tente novamente.", @@ -474,7 +474,7 @@ "Images": "Imagens", "ImportFavoriteChannelsHelp": "Se ativado, apenas canais que estão marcados como favoritos no sintonizador serão importados.", "ImportMissingEpisodesHelp": "Se ativado, as informações dos episódios que faltam serão importadas para seu banco de dados do Jellyfin e exibidas dentro das temporadas e séries. Isto pode causar lentidão no rastreamento da biblioteca.", - "InstallingPackage": "Instalando {0}", + "InstallingPackage": "Instalando {0} (versão{1})", "InstantMix": "Mix instântaneo", "ItemCount": "{0} itens", "Items": "itens", @@ -566,7 +566,7 @@ "LabelEmbedAlbumArtDidl": "Arte do álbum incorporada no Didl", "LabelEmbedAlbumArtDidlHelp": "Alguns dispositivos preferem este método para obter a arte do álbum. Outros podem falhar ao reproduzir com esta opção ativada.", "LabelEnableAutomaticPortMap": "Ativar mapeamento automático de portas", - "LabelEnableAutomaticPortMapHelp": "Tentativa de mapear automaticamente a porta pública para a porta local através de UPnP. Isto poderá não funcionar em alguns modelos de roteadores.", + "LabelEnableAutomaticPortMapHelp": "Tentar mapear automaticamente a porta pública para a porta local através de UPnP. Pode não funcionar em alguns modelos de roteadores. As mudanças não serão aplicadas até a reinicialização do servidor.", "LabelEnableBlastAliveMessages": "Mensagens ao vivo", "LabelEnableBlastAliveMessagesHelp": "Ative esta função se o servidor não for detectado por outros dispositivos UPnP em sua rede.", "LabelEnableDlnaClientDiscoveryInterval": "Intervalo para descoberta do cliente (segundos)", @@ -601,7 +601,7 @@ "LabelH264Crf": "CRF de codificação H264:", "LabelEncoderPreset": "Preset de codificação H264:", "LabelHardwareAccelerationType": "Aceleração de hardware:", - "LabelHardwareAccelerationTypeHelp": "Esta é uma função experimental disponível apenas em sistemas suportados.", + "LabelHardwareAccelerationTypeHelp": "Aceleração por hardware requer configurações adicionais.", "LabelHomeNetworkQuality": "Qualidade da rede local:", "LabelHomeScreenSectionValue": "Seção {0} da tela inicial:", "LabelHttpsPort": "Número da porta local de HTTPS:", @@ -637,7 +637,7 @@ "LabelLockItemToPreventChanges": "Bloquear este item para evitar alterações futuras", "LabelLoginDisclaimer": "Aviso legal no login:", "LabelLoginDisclaimerHelp": "Um aviso será exibido na parte inferior da página de login.", - "LabelManufacturer": "Fabricante", + "LabelManufacturer": "Fabricante:", "LabelManufacturerUrl": "URL do fabricante", "LabelMatchType": "Tipo de correspondência:", "LabelMaxBackdropsPerItem": "Número máximo de imagens de fundo por item:", @@ -662,7 +662,7 @@ "LabelMethod": "Método:", "LabelMinBackdropDownloadWidth": "Tamanho mínimo da imagem de fundo para download:", "LabelMinResumeDuration": "Duração mínima para retomar:", - "LabelMinResumeDurationHelp": "A menor duração de vídeo em segundos que salvará o local de reprodução e permitirá que retome.", + "LabelMinResumeDurationHelp": "Tempo mínimo do vídeo em segundos que permitirá continuar a reprodução a partir do ponto que parou.", "LabelMinResumePercentage": "Porcentagem mínima para retomar:", "LabelMinResumePercentageHelp": "Títulos são considerados como não reproduzidos se parados antes deste tempo.", "LabelMinScreenshotDownloadWidth": "Tamanho mínimo da captura de tela para download:", @@ -676,7 +676,7 @@ "LabelMoviePrefixHelp": "Se os títulos dos filmes devem ter um prefixo, digite-o aqui para que o servidor possa usá-lo corretamente.", "LabelMovieRecordingPath": "Local de gravação de filme (opcional):", "LabelMusicStreamingTranscodingBitrate": "Bitrate da transcodificação de músicas:", - "LabelMusicStreamingTranscodingBitrateHelp": "Define o bitrate máximo do streaming de músicas", + "LabelMusicStreamingTranscodingBitrateHelp": "Especifique uma taxa de bits máxima ao transmitir músicas.", "LabelName": "Nome:", "LabelNewName": "Novo nome:", "LabelNewPassword": "Nova senha:", @@ -688,7 +688,7 @@ "LabelNumberOfGuideDays": "Número de dias de dados do guia para baixar:", "LabelNumberOfGuideDaysHelp": "Baixar mais dias do guia da TV permite agendar com maior antecedência e visualizar mais listas, mas também levará mais tempo para baixar. Se selecionar Automático, será escolhido o período baseado no número de canais.", "LabelOptionalNetworkPath": "(Opcional) Pasta compartilhada em rede:", - "LabelOptionalNetworkPathHelp": "Se esta pasta estiver compartilhada em sua rede, fornecendo o local do compartilhamento em rede permitirá que os apps Jellyfin em outros dispositivos acessem arquivos de mídia diretamente.", + "LabelOptionalNetworkPathHelp": "Se esta pasta estiver compartilhada em sua rede, informar o caminho do compartilhamento permitirá que os apps Jellyfin em outros dispositivos acessem arquivos de mídia diretamente.", "LabelOriginalAspectRatio": "Proporção original da tela:", "LabelOriginalTitle": "Título original:", "LabelOverview": "Sinopse:", @@ -725,7 +725,7 @@ "LabelReasonForTranscoding": "Motivo da transcodificação:", "LabelRecord": "Gravar:", "LabelRecordingPath": "Local de gravação padrão:", - "LabelRecordingPathHelp": "Define o local padrão para salvar as gravações. Se deixar em branco, a pasta de dados do programa do servidor será usada.", + "LabelRecordingPathHelp": "Define o local padrão para salvar as gravações. Se deixar não preenchido, a pasta de dados do programa do servidor será usada.", "LabelRefreshMode": "Modo de atualização:", "LabelReleaseDate": "Data do lançamento:", "LabelRemoteClientBitrateLimit": "Limite do bitrate para streaming da internet (Mbps):", @@ -812,7 +812,7 @@ "LabelYoureDone": "Pronto!", "LabelZipCode": "CEP:", "LabelffmpegPath": "Local do FFmpeg:", - "LabelffmpegPathHelp": "O local para o arquivo de aplicação ffmpeg, ou pasta contendo ffmpeg.", + "LabelffmpegPathHelp": "O local para o programa ffmpeg, ou pasta contendo ffmpeg.", "LanNetworksHelp": "Lista separada por vírgula de endereços IP ou entradas IP/máscara de rede para redes que serão consideradas como redes locais ao forçar restrições de banda. Se definida, todos os outros endereços IP serão considerados como estando em uma rede externa e estarão sujeitos a restrições de banda externa. Se deixada em branco, apenas a sub-rede do servidor é considerada como rede local.", "Large": "Grande", "LatestFromLibrary": "Recentes {0}", @@ -867,7 +867,7 @@ "MessageDeleteTaskTrigger": "Deseja realmente excluir este disparador de tarefa?", "MessageDirectoryPickerBSDInstruction": "Para BSD, você precisará configurar o armazenamento dentro de seu Jail do FreeNAS para permitir que o Jellyfin tenha acesso a ele.", "MessageDirectoryPickerInstruction": "Os locais de rede podem ser inseridos manualmente caso o botão de rede falhe em localizar seus dispositivos. Por exemplo, {0} ou {1}.", - "MessageDirectoryPickerLinuxInstruction": "Para Linux no Arch Linux, CentOS, Debian, Fedora, openSUSE ou Ubuntu, você deve permitir que o usuário do serviço tenha ao menos acesso de leitura ao seu armazenamento.", + "MessageDirectoryPickerLinuxInstruction": "Sistemas operacionais Arch Linux, CentOS, Debian, Fedora, openSUSE ou Ubuntu, devem permitir que a conta de serviço tenha ao menos acesso de leitura nos locais de armazenamento.", "MessageDownloadQueued": "Download enfileirado.", "MessageEnablingOptionLongerScans": "Ativar esta opção pode resultar em rastreamentos de biblioteca significativamente mais demorados.", "MessageFileReadError": "Ocorreu um erro ao ler o arquivo. Por favor, tente novamente.", @@ -898,7 +898,7 @@ "MessageYouHaveVersionInstalled": "Você possui a versão {0} instalada.", "Metadata": "Metadados", "MetadataManager": "Gerenciador de Metadados", - "MetadataSettingChangeHelp": "Alterar as configurações dos metadados afetará o novo conteúdo que será adicionado. Para atualizar o conteúdo existente, abra a tela de detalhes e clique no botão de atualizar ou atualize usando o gerenciador de metadados.", + "MetadataSettingChangeHelp": "Alterar as configurações dos metadados afetará o novo conteúdo que será adicionado. Para atualizar o conteúdo existente, abra a tela de detalhes e clique no botão de atualizar, ou atualize usando o gerenciador de metadados.", "MinutesAfter": "minutos após", "MinutesBefore": "minutos antes", "Mobile": "Celular", @@ -924,9 +924,9 @@ "No": "Não", "NoNewDevicesFound": "Nenhum novo dispositivo encontrado. Para adicionar um novo sintonizador, feche esta mensagem e digite as informações do dispositivo manualmente.", "NoNextUpItemsMessage": "Nada encontrado. Comece a assistir suas séries!", - "NoPluginConfigurationMessage": "Este plugin não tem configurações disponíveis.", + "NoPluginConfigurationMessage": "Este plugin não permite alterar configurações.", "NoSubtitleSearchResultsFound": "Nenhum resultado encontrado.", - "NoSubtitles": "Nenhuma legenda", + "NoSubtitles": "Não há legendas", "NoSubtitlesHelp": "Legendas não serão carregadas por padrão. Elas podem ser carregadas manualmente durante a reprodução.", "None": "Nenhum(a)", "NumLocationsValue": "{0} pastas", @@ -949,10 +949,10 @@ "OptionAllowMediaPlaybackTranscodingHelp": "Restringir o acesso à transcodificação pode ocasionar falhas na reprodução nos apps do Jellyfin devido a formatos de mídias não suportados.", "OptionAllowRemoteControlOthers": "Permitir controle remoto de outros usuários", "OptionAllowRemoteSharedDevices": "Permitir controle remoto de dispositivos compartilhados", - "OptionAllowRemoteSharedDevicesHelp": "Dispositivos DLNA são considerados compartilhados até que um usuário comece a controlá-los.", + "OptionAllowRemoteSharedDevicesHelp": "Dispositivos DLNA são autorizados até que um usuário altere as permissões.", "OptionAllowSyncTranscoding": "Permitir download e sincronização de mídia que necessite de transcodificação", "OptionAllowUserToManageServer": "Permitir este usuário administrar o servidor", - "OptionAllowVideoPlaybackRemuxing": "Permitir reprodução de vídeos que requeiram conversão sem re-encodação", + "OptionAllowVideoPlaybackRemuxing": "Permitir reprodução de vídeos que requerem conversão sem recodificar", "OptionAllowVideoPlaybackTranscoding": "Permitir reprodução de vídeo que necessite de transcodificação", "OptionArtist": "Artista", "OptionAscending": "Crescente", @@ -976,15 +976,15 @@ "OptionDescending": "Decrescente", "OptionDisableUser": "Desativar este usuário", "OptionDisableUserHelp": "Se desativado, o servidor não permitirá nenhuma conexão deste usuário. Conexões existentes serão encerradas imediatamente.", - "OptionDislikes": "Não Curtidos", - "OptionDisplayFolderView": "Exibe uma visualização de pasta para exibir pastas de mídias", - "OptionDisplayFolderViewHelp": "Exibe pastas ao lado de suas outras biblioteca de mídia. Isto pode ser útil se quiser uma visualização por pasta.", + "OptionDislikes": "Não gostei", + "OptionDisplayFolderView": "Exibe visualização em pastas para exibir pastas de mídias", + "OptionDisplayFolderViewHelp": "Exibição em pastas ao lado das biblioteca de mídia. Isto pode ser útil para visualizar por pastas.", "OptionDownloadArtImage": "Arte", "OptionDownloadBackImage": "Traseira", "OptionDownloadBoxImage": "Caixa", "OptionDownloadDiscImage": "Disco", "OptionDownloadImagesInAdvance": "Fazer download de imagens antecipadamente", - "OptionDownloadImagesInAdvanceHelp": "Por padrão, a maioria das imagens são baixadas só quando um app Jellyfin solicita. Ativando esta opção, baixará todas as imagens antecipadamente, assim que novas mídias são importadas. Isto pode ocasionar um tempo maior para escanear a biblioteca.", + "OptionDownloadImagesInAdvanceHelp": "Por padrão, a maioria das imagens são baixadas somente quando um app Jellyfin solicita. Ativar esta opção, baixará todas as imagens antecipadamente, ao importar novas mídias. Isto pode ocasionar um tempo maior para escanear a biblioteca.", "OptionDownloadPrimaryImage": "Principal", "OptionDownloadThumbImage": "Miniatura", "OptionDvd": "DVD", @@ -1030,7 +1030,7 @@ "OptionPlainStorageFoldersHelp": "Se ativado, todas as pastas são representadas no DIDL como \"object.container.storageFolder\" ao invés de um tipo mais específico como, por exemplo, \"object.container.person.musicArtist\".", "OptionPlainVideoItems": "Exibir todos os vídeos como itens de vídeo", "OptionPlainVideoItemsHelp": "Se ativado, todos os vídeos são representados no DIDL como \"object.item.videoItem\" ao invés de um tipo mais específico como, por exemplo, \"object.item.videoItem.movie\".", - "OptionPlayCount": "Número de Reproduções", + "OptionPlayCount": "Contagem de Reproduções", "OptionPlayed": "Reproduzido", "OptionPremiereDate": "Data da Estréia", "OptionProfileAudio": "Áudio", @@ -1039,7 +1039,7 @@ "OptionProfileVideoAudio": "Áudio do Vídeo", "OptionReleaseDate": "Data de Lançamento", "OptionReportByteRangeSeekingWhenTranscoding": "Reportar que o servidor suporta busca de byte quando transcodificar", - "OptionReportByteRangeSeekingWhenTranscodingHelp": "Isto é necessário para alguns dispositivos que não buscam o tempo muito bem.", + "OptionReportByteRangeSeekingWhenTranscodingHelp": "Isto é necessário para avançar ou retroceder o tempo em alguns dispositivos.", "OptionRequirePerfectSubtitleMatch": "Fazer download apenas de legendas que correspondam exatamente aos meus arquivos de vídeo", "OptionRequirePerfectSubtitleMatchHelp": "Ao solicitar uma combinação perfeita, filtrará as legendas para incluir somente aquelas que foram testadas e verificadas com o arquivo de vídeo. Ao desmarcar isto, aumentará a quantidade de legendas baixadas, mas aumentará as chances de ter legendas que não estejam sincronizadas.", "OptionResElement": "elemento res", @@ -1063,9 +1063,9 @@ "OptionWeekly": "Semanal", "OriginalAirDateValue": "Data de exibição original: {0}", "Overview": "Sinopse", - "PackageInstallCancelled": "Instalação de {0} cancelada.", - "PackageInstallCompleted": "Instalação de {0} concluída.", - "PackageInstallFailed": "Instalação de {0} falhou.", + "PackageInstallCancelled": "Instalação da versão {0} cancelada.", + "PackageInstallCompleted": "Instalação da versão {0} concluída.", + "PackageInstallFailed": "A Instalação da versão {0} falhou.", "ParentalRating": "Classificação etária", "PasswordMatchError": "A senha e a confirmação da senha devem ser iguais.", "PasswordResetComplete": "A senha foi redefinida.", @@ -1265,7 +1265,7 @@ "Up": "Para cima", "Upload": "Carregar", "UserAgentHelp": "Fornece um cabeçalho HTTP personalizado para o user-agent.", - "UserProfilesIntro": "O Jellyfin inclui suporte para perfis de usuários com configurações precisas de exibição, estado de reprodução e controle dos pais.", + "UserProfilesIntro": "O Jellyfin inclui suporte para perfis de usuário com configurações de exibição granular, estado de reprodução e controle dos pais.", "ValueAlbumCount": "{0} álbuns", "ValueAudioCodec": "Codec de Áudio: {0}", "ValueConditions": "Condições: {0}", @@ -1348,12 +1348,12 @@ "HeaderFavoriteAlbums": "Álbuns Favoritos", "HeaderFavoriteArtists": "Artistas Favoritos", "HeaderFavoriteSongs": "Músicas Favoritas", - "HeaderFavoriteVideos": "Vídeos Favoritos", + "HeaderFavoriteVideos": "Videos favoritos", "HeaderHome": "Inicio", - "HeaderRestartingServer": "Reiniciando Servidor", - "LabelAuthProvider": "Provedor de Autenticação:", + "HeaderRestartingServer": "Reiniciando servidor", + "LabelAuthProvider": "Provedor de autenticação:", "LabelServerName": "Nome do servidor:", - "LabelTranscodePath": "Local de transcodificação:", + "LabelTranscodePath": "Pasta de transcodificação:", "LabelTranscodes": "Transcodificação:", "LabelUserLoginAttemptsBeforeLockout": "Tentativas de login com falha antes que o usuário seja bloqueado:", "DashboardVersionNumber": "Versão: {0}", @@ -1361,7 +1361,7 @@ "DashboardOperatingSystem": "Sistema Operacional: {0}", "DashboardArchitecture": "Arquitetura: {0}", "LabelPasswordResetProvider": "Provedor para Redefinir a Senha:", - "LabelWeb": "Web: ", + "LabelWeb": "Web:", "OptionBluray": "Blu-ray", "LabelProfileContainer": "Formato:", "LabelTranscodingContainer": "Formato:", @@ -1392,7 +1392,7 @@ "OptionIsSD": "SD", "OptionList": "Lista", "OptionLoginAttemptsBeforeLockout": "Determinar quantas tentativas de logins incorretas podem ser feitas antes de ocorrer o bloqueio.", - "OptionLoginAttemptsBeforeLockoutHelp": "Um valor de zero significa herdar o padrão de três tentativas para usuários normais e cinco para administradores. Configurar para -1 desativará o recurso.", + "OptionLoginAttemptsBeforeLockoutHelp": "O valor zero significa herdar o padrão de três tentativas para usuários normais e cinco para administradores. Configurar para -1 desativará o recurso.", "OptionPoster": "Poster", "OptionPosterCard": "Cartaz", "OptionProtocolHls": "Streaming ao Vivo por HTTP", @@ -1463,13 +1463,13 @@ "CopyStreamURLError": "Houve um erro ao copiar a URL.", "ButtonSplit": "Dividir", "AskAdminToCreateLibrary": "Peça a um administrador para criar uma biblioteca.", - "AllowFfmpegThrottling": "Limitar transcodificação", - "PlaybackErrorNoCompatibleStream": "Houve um erro na criação de perfil do cliente e o servidor não está enviando um formato de mídia compatível.", + "AllowFfmpegThrottling": "Transcodes do Acelerador", + "PlaybackErrorNoCompatibleStream": "Este cliente não é compatível com a media e o servidor não está enviando um formato de mídia compatível.", "EnableFastImageFadeInHelp": "Habilitar animações rápidas de aparecimento para imagens carregadas", "LabelDroppedFrames": "Quadros caídos:", "AllowFfmpegThrottlingHelp": "Quando uma transcodificação ou remux estiver suficientemente avançada da posição atual de reprodução, pause o processo para que consuma menos recursos. Isso é mais proveitoso para quando não há avanço ou retrocesso do vídeo com frequência. Desative se tiver problemas de reprodução.", - "PreferEmbeddedEpisodeInfosOverFileNames": "Preferir as informações incorporadas nos arquivos dos episódios ao invés dos nomes", - "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Isso utiliza as informações dos episódios incorporadas nos metadados dos arquivos se estiverem disponíveis.", + "PreferEmbeddedEpisodeInfosOverFileNames": "Preferir informações dos episódios incorporadas nos arquivos ao invés dos nomes", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Esta opção habilita as informações dos episódios incorporadas nos metadados dos arquivos(se estiverem disponíveis).", "ClientSettings": "Configurações do cliente", "OnApplicationStartup": "Na inicialização do aplicativo", "EveryXHours": "A cada {0} horas", @@ -1499,5 +1499,7 @@ "BoxSet": "Coleção", "Artist": "Artista", "AlbumArtist": "Artista do Album", - "Album": "Album" + "Album": "Album", + "UnsupportedPlayback": "O Jellyfin não pode descriptografar conteúdo protegido por DRM, porém mesmo assim fará uma tentativa para todo tipo de conteúdo, incluindo títulos protegidos. A imagem de alguns arquivos pode aparecer completamente preta devido a criptografia ou outros recursos não suportados, como títulos interativos.", + "MessageUnauthorizedUser": "Você não está autorizado a acessar o servidor neste momento. Por favor, contate o administrador do servidor para mais informações." } diff --git a/src/strings/pt.json b/src/strings/pt.json index a288ce5813..4bf5591347 100644 --- a/src/strings/pt.json +++ b/src/strings/pt.json @@ -113,7 +113,7 @@ "Screenshot": "Captura de Ecrã", "Schedule": "Agendamentos", "ScanForNewAndUpdatedFiles": "Procurar ficheiros novos ou actualizados", - "SaveSubtitlesIntoMediaFoldersHelp": "Guardar ficheiros de legendas junto aos ficheiros vídeo facilita a gestão.", + "SaveSubtitlesIntoMediaFoldersHelp": "Salvar arquivos de legendas junto aos arquivos vídeo facilita o gerenciamento.", "SaveSubtitlesIntoMediaFolders": "Guardar legendas nas pastas multimédia", "Save": "Guardar", "Saturday": "Sábado", @@ -270,7 +270,7 @@ "LabelNewPassword": "Nova palavra-passe:", "LabelNewName": "Novo nome:", "LabelName": "Nome:", - "LabelMusicStreamingTranscodingBitrateHelp": "Defina a taxa máxima de transmissão de música", + "LabelMusicStreamingTranscodingBitrateHelp": "Especifique uma taxa de bits máxima ao transmitir músicas.", "LabelMusicStreamingTranscodingBitrate": "Taxa de transcodificação de música:", "LabelMovieRecordingPath": "Caminho para gravação de filmes (opcional):", "LabelMoviePrefixHelp": "Se aplicar um prefixo aos títulos dos filmes, introduza-o aqui para que o servidor consiga tratá-los corretamente.", @@ -307,7 +307,7 @@ "LabelMaxBackdropsPerItem": "Número máximo de imagens de fundo por item:", "LabelMatchType": "Tipo de correspondência:", "LabelManufacturerUrl": "URL do Fabricante", - "LabelManufacturer": "Fabricante", + "LabelManufacturer": "Fabricante:", "LabelLoginDisclaimerHelp": "Este aviso será mostrado na parte inferior da página de login.", "LabelLoginDisclaimer": "Aviso legal de login:", "LabelLockItemToPreventChanges": "Bloquear este item para evitar alterações futuras", @@ -404,12 +404,12 @@ "LabelDeathDate": "Data de falecimento:", "LabelRefreshMode": "Mode de actualização:", "LabelRecord": "Registo:", - "LabelPasswordResetProvider": "Provedor de actualização de palavra-passe", + "LabelPasswordResetProvider": "Provedor de redefinição de senha:", "LabelMetadataSaversHelp": "Escolha os formato em que deseja guardar os seus metadados.", "LabelMetadataReadersHelp": "Ordene as fontes locais de metadados por ordem de prioridade. O primeiro ficheiro a ser encontrado será lido.", "LabelMetadataReaders": "Leirores de metadados", "LabelMetadataDownloadersHelp": "Active e ordene os seus pesquisadores de metadados por ordem de prioridade. Pesquisadores com menor prioridade só serão utilizados para completar informação em falta.", - "LabelLogs": "Registos", + "LabelLogs": "Histórico:", "LabelKodiMetadataUserHelp": "Guardar dados de utilização em NFO para que outras aplicações os utilizem.", "LabelKodiMetadataUser": "Guardar dados de utilização em NFO para:", "LabelImageFetchersHelp": "Activar e ordenar os pesquisadores de imagens por ordem de preferência.", @@ -891,7 +891,7 @@ "EditImages": "Editar imagens", "Edit": "Editar", "EasyPasswordHelp": "O código PIN é utilizado para acesso off-line em clientes suportados e pode ser usado para um acesso fácil dentro da rede.", - "DropShadow": "Sombreado", + "DropShadow": "sombra projetada", "DrmChannelsNotImported": "Canais com proteção DRM não serão importados.", "DownloadsValue": "{0} transferências", "Download": "Transferir", @@ -914,7 +914,7 @@ "DirectPlaying": "Reprodução directa", "DeviceAccessHelp": "Apenas se aplica a dispositivos que podem ser identificados como únicos e que não impedem o acesso ao navegador. Filtrar o acesso a dispositivos a um utilizador, impede-o de utilizar novos dispositivos, até estes serem aprovados aqui.", "DetectingDevices": "Procurando dispositivos", - "Desktop": "Desktop", + "Desktop": "Área de Trabalho", "Descending": "Descendente", "Depressed": "Baixo relevo", "DeleteUserConfirmation": "Tem a certeza que deseja apagar este utilizador?", @@ -1099,12 +1099,12 @@ "AnyLanguage": "Qualquer idioma", "Artists": "Artistas", "AsManyAsPossible": "Tantos quanto possível", - "AllowedRemoteAddressesHelp": "Lista de endereços IP ou IP/Máscara, separados por vírgulas, com permissão para se ligar remotamente. Se deixado em branco, todos os endereços remotos serão permitidos.", - "AllowRemoteAccessHelp": "Se esta opção não for seleccionada, todas as ligações remotas serão bloqueadas.", + "AllowedRemoteAddressesHelp": "Lista separada por vírgula de endereços IP ou entradas de máscara de IP/rede para redes que terão permissão para se conectar remotamente. Se deixado em branco, todos os endereços remotos serão permitidos.", + "AllowRemoteAccessHelp": "Se desmarcada, todas as conexões remotas serão bloqueadas.", "AllowRemoteAccess": "Permitir ligações remotas a este Servidor Jellyfin.", "AllowOnTheFlySubtitleExtractionHelp": "Legendas integradas podem ser extraídas do vídeo e enviadas como texto simples para os clientes para evitar transcodificação. Em certos dispositivos, é uma operação demorada e pode causar paragens de reprodução durante o processo de extracção. Desactive esta opção para que as legendas sejam integradas no vídeo durante a conversão para um formato suportado pelo dispositivo de destino.", - "AllowOnTheFlySubtitleExtraction": "Permitir a extracção de legendas em tempo real", - "AllowHWTranscodingHelp": "Permitir o sintonizador converter emissões em tempo real. Poderá reduzir a necessidade do servidor converter o conteúdo.", + "AllowOnTheFlySubtitleExtraction": "Permitir a extração de legendas em tempo real", + "AllowHWTranscodingHelp": "Permita que o sintonizador transcodifique os fluxos em tempo real. Isso pode ajudar a reduzir a transcodificação exigida pelo servidor.", "AllLibraries": "Todas as bibliotecas", "AllLanguages": "Todos os idiomas", "AllEpisodes": "Todos os episódios", @@ -1119,14 +1119,14 @@ "AddedOnValue": "{0} foi adicionado", "AddToPlaylist": "Adicionar à lista de reprodução", "AddToPlayQueue": "Adicionar à fila de reprodução", - "AddToCollection": "Adicionar à colecção", - "AddItemToCollectionHelp": "Adicione itens às colecções pesquisando-os e utilizando o respetivo menu de toque ou clique direito para os adicionar a uma colecção.", + "AddToCollection": "Adicionar à coleção", + "AddItemToCollectionHelp": "Adicione itens às coleções pesquisando-os e utilizando o respetivo menu de toque ou clique direito para os adicionar a uma coleção.", "Add": "Adicionar", - "Actor": "Actor", - "AccessRestrictedTryAgainLater": "O acesso está actualmente restrito. Por favor, tente mais tarde.", + "Actor": "Ator", + "AccessRestrictedTryAgainLater": "O acesso está atualmente restrito. Por favor, tente mais tarde.", "Absolute": "Absoluto", - "AlwaysPlaySubtitlesHelp": "Legendas correspondentes à língua preferida serão sempre carregadas, independentemente do idioma do áudio.", - "SearchForMissingMetadata": "Procurar metadados em falta", + "AlwaysPlaySubtitlesHelp": "As legendas correspondentes à preferência de idioma serão carregadas, independentemente do idioma do áudio.", + "SearchForMissingMetadata": "Procurar metadados ausentes", "ScanLibrary": "Analisar biblioteca", "HeaderDeleteItem": "Remover item", "HeaderDeleteDevice": "Apagar Dispositivo", @@ -1175,7 +1175,7 @@ "HeaderActiveDevices": "Dispositivos Activos", "HeaderAccessScheduleHelp": "Crie uma restrição horária de acesso para limitar o acesso ao Jellyfin a determinadas horas.", "HeaderAccessSchedule": "Restrição Horária de Acesso", - "HardwareAccelerationWarning": "Activar a aceleração por hardware pode causar instabilidade em alguns ambientes. Garanta que o sistema operativo e os controladores da placa gráfica estão actualizados. Se tiver dificuldades em reproduzir vídeo depois de alterar esta opção, pode ser necessário repor a configuração \\\"None\\\".", + "HardwareAccelerationWarning": "A ativação da aceleração de hardware pode causar instabilidade em alguns ambientes. Verifique se o sistema operacional e os drivers de vídeo estão totalmente atualizados. Se você tiver dificuldade em reproduzir o vídeo depois de ativar isso, precisará alterar a configuração novamente para Nenhum.", "HandledByProxy": "Gerido pelo proxy inverso", "HDPrograms": "Programas HD", "EncoderPresetHelp": "Escolha um valor mais rápido para melhorar o desempenho, ou um valor mais lento para melhorar a qualidade.", @@ -1210,7 +1210,7 @@ "HeaderNavigation": "Navegar", "CopyStreamURLError": "Ocorreu um erro ao copiar o URL.", "ButtonSplit": "Dividir", - "AskAdminToCreateLibrary": "Peça a um administrador para criar a biblioteca.", + "AskAdminToCreateLibrary": "Peça a um administrador para criar uma biblioteca.", "AllowFfmpegThrottling": "Transcodificação com falhas", "DashboardOperatingSystem": "Sistema Operativo", "LabelUserLoginAttemptsBeforeLockout": "Número de tentativas de login falhadas antes do bloqueio do utilizador:", @@ -1227,14 +1227,14 @@ "MoreMediaInfo": "Informações sobre mídia", "MoreFromValue": "Mais de {0}", "MediaInfoRefFrames": "Quadros de referência", - "MediaInfoContainer": "Container", - "MediaInfoAnamorphic": "Anamorphic", + "MediaInfoContainer": "Recipiente", + "MediaInfoAnamorphic": "Anamórfico", "LabelVideoResolution": "Resolução do vídeo:", - "LabelTypeMetadataDownloaders": "{0} metadata downloaders:", + "LabelTypeMetadataDownloaders": "{0} download de metadados:", "LabelTranscodePath": "Caminho da transcodificação:", - "OnlyImageFormats": "Somente formatos de imagem (VOBSUB, PGS, SUB, etc)", + "OnlyImageFormats": "Somente formatos de imagem (VOBSUB, PGS, SUB)", "OnlyForcedSubtitlesHelp": "Apenas as legendas marcadas como forçadas serão carregadas.", - "OnlyForcedSubtitles": "Apenas legendas forçadas", + "OnlyForcedSubtitles": "Somente legendas forçadas", "Off": "Desligar", "NumLocationsValue": "{0} pastas", "Normal": "Normal", @@ -1276,10 +1276,10 @@ "Like": "Gostei", "LeaveBlankToNotSetAPassword": "Você pode deixar esse campo em branco para definir nenhuma senha.", "LearnHowYouCanContribute": "Aprenda como você pode contribuir.", - "LaunchWebAppOnStartupHelp": "Open the web client in your default web browser when the server initially starts. This will not occur when using the restart server function.", + "LaunchWebAppOnStartupHelp": "Abra o cliente da web no seu navegador da web padrão quando o servidor iniciar. Isso não ocorrerá ao usar a função de reinicialização do servidor.", "LaunchWebAppOnStartup": "Inicie a interface da web ao iniciar o servidor", "Large": "Amplo", - "LanNetworksHelp": "Comma separated list of IP addresses or IP/netmask entries for networks that will be considered on local network when enforcing bandwidth restrictions. If set, all other IP addresses will be considered to be on the external network and will be subject to the external bandwidth restrictions. If left blank, only the server's subnet is considered to be on the local network.", + "LanNetworksHelp": "Lista separada por vírgula de endereços IP ou entradas de máscara de rede/IP para redes que serão consideradas na rede local ao impor restrições de largura de banda. Se definido, todos os outros endereços IP serão considerados na rede externa e estarão sujeitos às restrições de largura de banda externa. Se deixado em branco, apenas a sub-rede do servidor é considerada na rede local.", "LabelffmpegPathHelp": "O caminho para o arquivo do aplicativo ffmpeg ou pasta que contém o ffmpeg.", "LabelffmpegPath": "FFmpeg caminho:", "LabelYear": "Ano:", @@ -1295,7 +1295,7 @@ "LabelVersion": "Versão:", "LabelVaapiDeviceHelp": "Este é o nó de renderização usado para aceleração de hardware.", "LabelVaapiDevice": "VA API Dispositivo:", - "LabelUserAgent": "Agente de usuário", + "LabelUserAgent": "Agente de usuário:", "LabelTranscodes": "Transcodificação:", "LabelTranscodingFramerate": "Transcodificação frame por segundo:", "LabelTranscodingProgress": "Progresso da transcodificação:", @@ -1311,9 +1311,9 @@ "LabelSpecialSeasonsDisplayName": "Nome de exibição da temporada especial:", "LabelSoundEffects": "Efeitos sonoros:", "LabelSortTitle": "Classificar título:", - "LabelSortOrder": "Ordem da Ordenação", + "LabelSortOrder": "Ordem de classificação:", "LabelSortBy": "Ordenar por:", - "LabelSkin": "Skin:", + "LabelSkin": "Pele:", "EnableFastImageFadeInHelp": "Habilite uma animação mais rápida para imagens carregadas", "EnableFastImageFadeIn": "Efeito de imagem fade-in rápido", "LabelRemoteClientBitrateLimitHelp": "Um limite opcional de taxa de bits por fluxo para todos os dispositivos fora da rede. Isso é útil para impedir que os dispositivos solicitem uma taxa de bits mais alta do que a sua conexão à Internet pode suportar. Isso pode resultar no aumento da carga da CPU no servidor para transcodificar vídeos em tempo real para uma taxa de bits mais baixa.", @@ -1327,13 +1327,72 @@ "AllowFfmpegThrottlingHelp": "Quando uma transcodificação ou remux se aproximar da posição atual de reprodução, pause o processo para que consuma menos recursos. Isso é mais útil ao assistir sem procurar com frequência. Desative isso se você tiver problemas de reprodução.", "MySubtitles": "Minhas legendas", "Name": "Nome", - "Never": "", - "Artist": "", - "LabelDeinterlaceMethod": "", - "DeinterlaceMethodHelp": "", - "Movie": "", - "LabelLibraryPageSize": "", - "Album": "", - "LabelLibraryPageSizeHelp": "", - "Episode": "" + "Never": "Nunca", + "Artist": "Artista", + "LabelDeinterlaceMethod": "Método de desentrelaçamento:", + "DeinterlaceMethodHelp": "Selecione o método de desentrelaçamento para converter conteúdo entrelaçado.", + "Movie": "Filme", + "LabelLibraryPageSize": "Tamanho da página da biblioteca:", + "Album": "Álbum", + "LabelLibraryPageSizeHelp": "Escolher a quantidade itens a exibir numa página de biblioteca. Escolha \"0\" para desabilitar a exibição em páginas.", + "Episode": "Episódio", + "OptionRequirePerfectSubtitleMatch": "Baixar apenas legendas que correspondem corretamente aos arquivos de vídeo", + "OptionRandom": "Aleatório", + "OptionPoster": "Encarte", + "OptionLoginAttemptsBeforeLockout": "Determinar a quantidade de tentativas de login incorretas até que ocorra bloqueio.", + "OptionList": "Listar", + "OptionIsSD": "Definição padrão", + "OptionIsHD": "Alta definição", + "OptionHomeVideos": "Fotos", + "OptionHasTrailer": "Trailer", + "OptionEnableExternalContentInSuggestions": "Habilitar sugestão de conteúdo externo", + "OptionDownloadMenuImage": "Menu", + "OptionDownloadLogoImage": "Logotipo", + "OptionDownloadBannerImage": "Encarte", + "OptionDisplayFolderViewHelp": "Exiba pastas ao lado de outras bibliotecas de mídia. Isso pode ser útil se você quiser ter uma visualização simples de pastas.", + "OptionDisplayFolderView": "Exibir uma exibição de pasta para mostrar pastas de mídia simples", + "OptionBluray": "Bluray", + "OptionBanner": "Poster", + "OptionAuto": "Automático", + "OptionAllowVideoPlaybackRemuxing": "Permitir execução de vídeo que requer conversão sem recodificar", + "OptionAllowLinkSharingHelp": "Somente páginas da web que contêm informações sobre mídia são compartilhadas. Os arquivos de mídia nunca são compartilhados publicamente. O tempo de compartilhamento é limitado e expira após {0} dias.", + "Option3D": "3D", + "NextUp": "Próximo", + "Next": "Próximo", + "NewEpisodesOnly": "apenas novos episódios", + "NewEpisodes": "Novos episódios", + "NewCollectionHelp": "Coleções permitem criar agrupamentos personalizados de filmes ou de outros conteúdos da biblioteca.", + "BoxSet": "Coleção", + "AlbumArtist": "Álbum do Artista", + "Quality": "Qualidade", + "Previous": "Anterior", + "PreferredNotRequired": "Preferível, mas não obrigatório", + "PictureInPicture": "vídeo destacado", + "OptionThumb": "Miniatura", + "OptionRequirePerfectSubtitleMatchHelp": "Solicitar a \"correspondência perfeita\" filtrará as legendas incluindo apenas aquelas que foram testadas com o arquivo de vídeo. Desmarcar isto aumentará a probabilidade de baixar legendas, mas poderá obter legendas incorretas ou não sincronizadas.", + "StopRecording": "Parar gravação", + "ShowYear": "Exibir ano", + "ShowTitle": "Exibir título", + "SettingsWarning": "Mudar estes valores pode causar instabilidade ou falhas de conexão. Se tiver problemas, recomendamos restaurar os valores originais.", + "ServerNameIsShuttingDown": "Servidor Jellyfin - {0} está desligando.", + "ServerNameIsRestarting": "Servidor Jellyfin - {0} está reiniciando.", + "SeriesYearToPresent": "{0} - Atualmente", + "SeriesCancelled": "Série cancelada.", + "SelectAdminUsername": "Por favor, selecione um usuário para a conta de administrador.", + "Season": "Temporada", + "RepeatEpisodes": "Repetir episódios", + "RepeatAll": "Repetir todos", + "RemoveFromCollection": "Remover da coleção", + "RememberMe": "Lembrar-me", + "ReleaseDate": "Data do lançamento", + "RefreshMetadata": "Atualizar metadados", + "RecentlyWatched": "Visto recentemente", + "OptionEnableForAllTuners": "Ativar para todos os dispositivos sintonizadores", + "OptionCaptionInfoExSamsung": "Informações da legenda (Samsung)", + "OptionBlockTrailers": "trechos de um filme", + "OptionAutomaticallyGroupSeriesHelp": "Se ativada, as séries espalhadas por várias pastas nesta biblioteca serão automaticamente mescladas em uma única série.", + "OptionAutomaticallyGroupSeries": "Mesclar automaticamente séries que estão espalhadas por várias pastas", + "OptionAllowSyncTranscoding": "Permitir download e sincronização de mídia que requeiram transcodificação", + "OptionForceRemoteSourceTranscoding": "Forçar a transcodificação de fontes de mídia remota (como LiveTV)", + "MessageUnauthorizedUser": "Você não está autorizado a acessar o servidor no momento. Entre em contato com o administrador do servidor para obter mais informações." } diff --git a/src/strings/ro.json b/src/strings/ro.json index fd4927f4a1..c27996ec45 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -1470,8 +1470,8 @@ "Track": "Cale", "Season": "Sezon", "ReleaseGroup": "Gruparea lansării", - "PreferEmbeddedEpisodeInfosOverFileNames": "Preferați informațiile despre episod încorporate în fișier decât numele fișierelor", - "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Aceasta folosește informațiile despre episod din metadatele încorporate, dacă sunt disponibile.", + "PreferEmbeddedEpisodeInfosOverFileNames": "Preferați informația despre episod încorporată în fișier decât numele fișierelor", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Aceasta folosește informația despre episod din metadatele încorporate, dacă sunt disponibile.", "Person": "Persoană", "OtherArtist": "Alt artist", "Movie": "Film", @@ -1493,8 +1493,14 @@ "ListPaging": "{0}-{1} din {2}", "WriteAccessRequired": "Jellyfin Server necesită acces de scriere la acest folder. Vă rugăm să vă asigurați accesul la scriere și încercați din nou.", "PathNotFound": "Calea nu a fost găsită. Vă rugăm să vă asigurați de validitatea căii și încercați din nou.", - "YadifBob": "Yadif Bob", - "Yadif": "Yadif", + "YadifBob": "YADIF Bob", + "Yadif": "YADIF", "LabelDeinterlaceMethod": "Metoda de intercalare:", - "DeinterlaceMethodHelp": "Selectați metoda de intercalat pe care să o utilizați la transcodarea conținutului intercalat." + "DeinterlaceMethodHelp": "Selectați metoda de intercalat pe care să o utilizați la transcodarea conținutului intercalat.", + "UnsupportedPlayback": "Jellyfin nu poate decripta conținut protejat de DRM, dar tot conținutul va fi încercat indiferent de titlurile protejate. Unele fișiere pot părea complet negre din cauza criptării sau a altor funcții neacceptate, cum ar fi titluri interactive.", + "LabelLibraryPageSizeHelp": "Setează cantitatea de elemente de afișat pe o pagină a bibliotecii. Setați la 0 pentru a dezactiva paginarea.", + "LabelLibraryPageSize": "Mărimea paginii Bibliotecă:", + "MessageUnauthorizedUser": "Nu sunteți autorizat să accesați serverul în acest moment. Vă rugăm să contactați administratorul serverului pentru mai multe informații.", + "ButtonTogglePlaylist": "Listă de redare", + "ButtonToggleContextMenu": "Mai mult" } diff --git a/src/strings/ru.json b/src/strings/ru.json index d50bcaccaa..1611572754 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -3,19 +3,19 @@ "AccessRestrictedTryAgainLater": "В настоящее время доступ запрещён. Повторите попытку позже.", "Actor": "Актёр", "Add": "Добавить", - "AddItemToCollectionHelp": "Добавляйте элементы в коллекции проведя их поиск, и с помощью правого щелчка по ним или по касанию меню, чтобы присоединить ко коллекции.", + "AddItemToCollectionHelp": "Добавляйте элементы в коллекции, выполняя их поиск, и с помощью правой кнопки мыши или касания меню присоедините их к коллекции.", "AddToCollection": "Добавить в коллекцию", "AddToPlayQueue": "Добавить в очередь воспроизведения", "AddToPlaylist": "Добавить в плей-лист", "AddedOnValue": "Добавлено {0}", - "AdditionalNotificationServices": "Просмотрите каталог плагинов, чтобы установить дополнительные услуги для уведомлений.", + "AdditionalNotificationServices": "Просмотрите каталог плагинов, чтобы установить дополнительные сервисы уведомлений.", "AirDate": "Дата эфира", "Aired": "Эфирный", "Albums": "Альбомы", "Alerts": "Оповещения", "All": "Все", "AllChannels": "Все каналы", - "AllComplexFormats": "Все комлексные форматы (ASS, SSA, VOBSUB, PGS, SUB/IDX и т.д.)", + "AllComplexFormats": "Все комплексные форматы (ASS, SSA, VOBSUB, PGS, SUB и IDX)", "AllEpisodes": "Все эпизоды", "AllLanguages": "Все языки", "AllLibraries": "Все медиатеки", @@ -23,11 +23,11 @@ "AllowMediaConversion": "Разрешить преобразование медиаданных", "AllowMediaConversionHelp": "Предоставить или запретить доступ к компоненте преобразования медиаданных.", "AllowOnTheFlySubtitleExtraction": "Разрешить динамическое извлечение субтитров", - "AllowOnTheFlySubtitleExtractionHelp": "Внедрённые субтитры возможно извлекать из видео и доставлять клиентам в виде обычного текста, в целях предотвращения перекодировки видео. На некоторых системах это может занять продолжительное время и вызывать задержки воспроизведения видео в процессе извлечения. Отключите это, для прошивки внедрённых субтитров во время перекодировки видео, при отсутствии встроенной поддержки их в клиентском устройстве.", - "AllowRemoteAccess": "Разрешение удалённого доступа к данному серверу Jellyfin Server.", + "AllowOnTheFlySubtitleExtractionHelp": "Встроенные субтитры могут быть извлечены из видео и доставлены клиентам в виде обычного текста, в целях предотвращения перекодировки видео. На некоторых системах это может занять продолжительное время и вызвать задержки воспроизведения видео в процессе извлечения. Отключите этот параметр, чтобы встроенные субтитры записывались при перекодировании видео, если они изначально не поддерживаются клиентским устройством.", + "AllowRemoteAccess": "Разрешить удалённый доступ к данному серверу Jellyfin Server.", "AllowRemoteAccessHelp": "Если флажок снят, то все удалённые подключения будут заблокированы.", - "AllowedRemoteAddressesHelp": "Список разделённых запятыми IP-адресов или записей IP/netmask для сетей, которым разрешено удалённое соединение. Если не заполнять, то будут использованы все внешние адреса.", - "AlwaysPlaySubtitles": "Всегда воспроизводить с субтитрами", + "AllowedRemoteAddressesHelp": "Список разделённых запятыми IP-адресов или записей IP/netmask сетей, которым разрешено удалённое соединение. Если оставить это поле пустым, то будут разрешены все удаленные адреса.", + "AlwaysPlaySubtitles": "Воспроизводить всегда", "AlwaysPlaySubtitlesHelp": "Субтитры, соответствующие настройке языка, будут загружаться независимо от языка аудио.", "AnyLanguage": "Любой язык", "Anytime": "В любое время", @@ -36,25 +36,25 @@ "Artists": "Исполнители", "AsManyAsPossible": "Как можно больше", "Ascending": "По возрастанию", - "AspectRatio": "Соот-ие сторон", + "AspectRatio": "Соотношение сторон", "AttributeNew": "Новинка", "Audio": "Аудио", "Auto": "Авто", "AutoBasedOnLanguageSetting": "Авто (на основе настройки языка)", - "Backdrop": "Задник", - "Backdrops": "Задники", + "Backdrop": "Фон", + "Backdrops": "Фоны", "Banner": "Баннер", "BirthDateValue": "Дата рождения: {0}", "BirthLocation": "Место рождения", "BirthPlaceValue": "Место рождения: {0}", "Blacklist": "Чёрный список", - "BookLibraryHelp": "Поддерживаются аудио и текстовые книги. Просмотрите {0}руководство по именованию книг{1}.", + "BookLibraryHelp": "Поддерживаются аудио и текстовые книги. Просмотрите {0}руководство по именованию книг{1}.", "Books": "Книги", "Box": "Коробка", - "BoxRear": "Спинка коробки", + "BoxRear": "Коробка (задняя часть)", "Browse": "Навигация", "BrowsePluginCatalogMessage": "Просмотрите каталог плагинов, чтобы ознакомиться с имеющимися плагинами.", - "BurnSubtitlesHelp": "Определяется, должен ли сервер внедрять субтитры при преобразовании видео в зависимости от формата субтитров. Избегание внедрения субтитров улучшит производительность сервера. Выберите «Авто» для записи основанных на графике форматов (VOBSUB, PGS, SUB/IDX и т.п.) и некоторых субтитров ASS/SSA.", + "BurnSubtitlesHelp": "Определяется, должен ли сервер внедрять субтитры при перекодировании. Избежание этого значительно улучшит производительность. Выберите «Авто» для записи основанных на графике форматов (VOBSUB, PGS, SUB и IDX) и некоторых субтитров ASS или SSA.", "ButtonAdd": "Добавить", "ButtonAddMediaLibrary": "Добавить медиатеку", "ButtonAddScheduledTaskTrigger": "Добавить триггер", @@ -70,12 +70,12 @@ "ButtonChangeServer": "Сменить сервер", "ButtonConnect": "Подсоединиться", "ButtonDelete": "Удалить", - "ButtonDeleteImage": "Удалить рисунок", + "ButtonDeleteImage": "Удалить изображение", "ButtonDown": "Вниз", "ButtonDownload": "Загрузить", "ButtonEdit": "Править", - "ButtonEditImages": "Править рисунки", - "ButtonEditOtherUserPreferences": "Править профиль, рисунок и личные настройки этого пользователя.", + "ButtonEditImages": "Править изображения", + "ButtonEditOtherUserPreferences": "Править профиль, изображение и персональные настройки этого пользователя.", "ButtonFilter": "Фильтр", "ButtonForgotPassword": "Напомнить пароль", "ButtonFullscreen": "Полный экран", @@ -83,21 +83,21 @@ "ButtonGuide": "Телегид", "ButtonHelp": "Справка", "ButtonHome": "Главное", - "ButtonInfo": "Инфо...", + "ButtonInfo": "Инфо", "ButtonLearnMore": "Подробнее", "ButtonLibraryAccess": "Доступ к медиатеке", "ButtonManualLogin": "Войти вручную", "ButtonMore": "Ещё", "ButtonNetwork": "Сеть", "ButtonNew": "Новое", - "ButtonNextTrack": "След. дорожка", + "ButtonNextTrack": "Следующая дорожка", "ButtonOff": "Откл", "ButtonOk": "Ок", "ButtonOpen": "Открыть", - "ButtonParentalControl": "Управлять содержанием", + "ButtonParentalControl": "Родительский контроль", "ButtonPause": "Пауза", - "ButtonPlay": "Воспр.", - "ButtonPreviousTrack": "Пред. дорожка", + "ButtonPlay": "Воспроизведение", + "ButtonPreviousTrack": "Предыдущая дорожка", "ButtonProfile": "Профиль", "ButtonQuickStartGuide": "Руководство по запуску", "ButtonRefresh": "Обновить", @@ -127,6 +127,8 @@ "ButtonStop": "Остановить", "ButtonSubmit": "Подтвердить", "ButtonSubtitles": "Субтитры", + "ButtonToggleContextMenu": "Ещё", + "ButtonTogglePlaylist": "Плей-лист", "ButtonTrailer": "Трейлер", "ButtonUninstall": "Удалить", "ButtonUp": "Вверх", @@ -147,27 +149,27 @@ "CommunityRating": "Общественная оценка", "Composer": "Композитор", "ConfigureDateAdded": "Как конфигурировать дату добавления определяется в Панели Jellyfin Server в параметрах Медиатеки", - "ConfirmDeleteImage": "Удалить рисунок?", + "ConfirmDeleteImage": "Удалить изображение?", "ConfirmDeleteItem": "При удалении данного элемента, он удалится и из файловой системы, и из медиатеки. Вы действительно хотите продолжить?", "ConfirmDeleteItems": "При удалении данных элементов, он удалится и из файловой системы, и из медиатеки. Вы действительно хотите продолжить?", "ConfirmDeletion": "Подтверждение удаления", "ConfirmEndPlayerSession": "Вы хотите завершить работу Jellyfin на {0}?", - "Connect": "Подсоединиться", + "Connect": "Соединиться", "ContinueWatching": "Продолжение просмотра", "Continuing": "Продолжающееся", "CriticRating": "Оценка критиков", "CustomDlnaProfilesHelp": "Создайте настраиваемый профиль, назначаемый для нового устройства или переопределите системный профиль.", "DateAdded": "Дата добавления", "DatePlayed": "Дата воспроизведения", - "DeathDateValue": "Кончина: {0}", - "Default": "Умолчание", + "DeathDateValue": "Дата смерти: {0}", + "Default": "По умолчанию", "DefaultErrorMessage": "Произошла ошибка при обработке запроса. Повторите попытку позже.", "DefaultMetadataLangaugeDescription": "Они являются значениями по умолчанию и могут быть подстроены индивидуально для каждой медиатеки.", "DefaultSubtitlesHelp": "Загрузки субтитров определяются флагами \"По умолчанию\" и \"Форсированные\" во внедрённых метаданных. Языковые настройки учитываются при наличии нескольких опций.", "Delete": "Удалить", "DeleteDeviceConfirmation": "Вы действительно хотите удалить данное устройство? Оно появится снова в следующий раз, когда пользователь войдёт с него.", - "DeleteImage": "Удалить рисунок", - "DeleteImageConfirmation": "Вы действительно хотите удалить данный рисунок?", + "DeleteImage": "Удалить изображение", + "DeleteImageConfirmation": "Вы действительно хотите удалить данное изображение?", "DeleteMedia": "Удалить медиаданные", "DeleteUser": "Удалить пользователя", "DeleteUserConfirmation": "Вы действительно хотите удалить этого пользователя?", @@ -191,7 +193,7 @@ "DisplayInOtherHomeScreenSections": "Показывать в разделах главного экрана (нпр., новейшие медиаданные, продолжение просмотра и т.п.)", "DisplayMissingEpisodesWithinSeasons": "Отображать отсутствующие эпизоды в пределах сезонов", "DisplayMissingEpisodesWithinSeasonsHelp": "Это также должно быть включено для ТВ-медиатек в конфигурации сервера.", - "DisplayModeHelp": "Выберите тип экрана, где запущен Jellyfin.", + "DisplayModeHelp": "Выберите желательный стиль разметки для интерфейса.", "DoNotRecord": "Не записывать", "Down": "Вниз", "Download": "Загрузить", @@ -200,11 +202,11 @@ "DropShadow": "Теневая", "EasyPasswordHelp": "Простой PIN-код используется для автономного доступа на поддерживаемых клиентах и может также использоваться для удобного внутрисетевого входа.", "Edit": "Правка", - "EditImages": "Править рисунки", + "EditImages": "Править изображения", "EditMetadata": "Править метаданные", "EditSubtitles": "Править субтитры", - "EnableBackdrops": "Задники", - "EnableBackdropsHelp": "Задники будут отображаются фоном на некоторых страницах при просмотре медиатеки.", + "EnableBackdrops": "Фоны", + "EnableBackdropsHelp": "Фоны будут отображаются на заднем плане на некоторых страницах при просмотре медиатеки.", "EnableCinemaMode": "Режим кинозала", "EnableColorCodedBackgrounds": "Обозначеннные цветом фоны", "EnableDisplayMirroring": "Дублирование отображения", @@ -214,8 +216,8 @@ "EnableNextVideoInfoOverlay": "Показывать сведения о следующем видео во время воспроизведения", "EnableNextVideoInfoOverlayHelp": "В конце видео отображать информацию о последующем видео в текущем плей-листе.", "EnablePhotos": "Отображать фотографии", - "EnablePhotosHelp": "Рисунки будут обнаруживаться и отображаться наряду с другими медиафайлами.", - "EnableStreamLooping": "Автоциклирование трансляций", + "EnablePhotosHelp": "Изображения будут обнаруживаться и отображаться наряду с другими медиафайлами.", + "EnableStreamLooping": "Зацикливание трансляций", "EnableStreamLoopingHelp": "Включайте, если трансляции содержат данные только на несколько секунд и необходимо непрерывно их запрашивать. Включение этого без необходимости может породить проблемы.", "EnableThemeSongs": "Тематические композиции", "EnableThemeSongsHelp": "Воспроизведение тематических композиций в фоновом режиме при навигации по медиатеке.", @@ -236,7 +238,7 @@ "EveryNDays": "Каждые {0} дней", "ExitFullscreen": "Выход с полного экрана", "ExtraLarge": "Очень крупный", - "ExtractChapterImagesHelp": "Извлечение рисунков сцен предоставляет возможности клиентам для отображения графических меню выбора сцены. Данный процесс может быть медленным, потребляет ресурсы, и могут понадобиться несколько гигабайт пространства. Он работает при обнаружении видеофайлов, а также, как задача, назначенная на ночь. Расписание возможно перенастроить в области Назначенных задач. Не рекомендуется запускать данную задачу в часы пик.", + "ExtractChapterImagesHelp": "Извлечение изображений сцен предоставляет возможности клиентам для отображения графических меню выбора сцены. Данный процесс может быть медленным, потребляет ресурсы, и могут понадобиться несколько гигабайт пространства. Он работает при обнаружении видеофайлов, а также, как задача, назначенная на ночь. Расписание возможно перенастроить в области Назначенных задач. Не рекомендуется запускать данную задачу в часы пик.", "Extras": "Допматериалы", "FFmpegSavePathNotFound": "Мы не смогли обнаружить FFmpeg по введённому вами пути. FFprobe также необходим и должен быть в той же самой папке. Эти компоненты обычно поставляются вместе в одном загрузочном пакете. Проверьте путь и повторите попытку.", "FastForward": "Быстро вперёд", @@ -263,11 +265,11 @@ "Genres": "Жанры", "GroupBySeries": "Группирование по сериалам", "GroupVersions": "Сгруппировать версии", - "GuestStar": "Пригл. актёр", + "GuestStar": "Приглашенный актёр", "Guide": "Телегид", "GuideProviderLogin": "Вход", "GuideProviderSelectListings": "Выбор перечней", - "H264CrfHelp": "Постоянное значение оценки (Constant Rate Factor, CRF) - параметр качества по умолчанию для кодёра x264. Возможно задавать значения от 0 до 51, где меньшие значения привели бы к улучшению качества (за счёт бо́льших размеров файлов). Разумными являются значения от 18 до 28. Стандартно для x264 - 23, так что вы можете использовать это в качестве отправной точки.", + "H264CrfHelp": "Постоянное значение оценки (Constant Rate Factor, CRF) - параметр качества по умолчанию для кодёра x264. Возможно задавать значения от 0 до 51, где меньшие значения привели бы к улучшению качества (за счёт увеличения размеров файлов). Приемлемыми являются значения от 18 до 28. Стандартно для x264 - 23, так что вы можете использовать это в качестве отправной точки.", "EncoderPresetHelp": "Выберите значение быстрее для улучшения производительности, или значение медленнее для улучшения качества.", "HDPrograms": "HD-передачи", "HandledByProxy": "Обрабатывается обратным прокси", @@ -280,7 +282,7 @@ "HeaderAddScheduledTaskTrigger": "Добавление триггера", "HeaderAddToCollection": "Добавить в коллекцию", "HeaderAddToPlaylist": "Добавление в плей-лист", - "HeaderAddUpdateImage": "Добавление/Обновление рисунка", + "HeaderAddUpdateImage": "Добавление/Обновление изображения", "HeaderAddUser": "Добавить пользователя", "HeaderAdditionalParts": "Дополнительные части", "HeaderAdmin": "Администрирование", @@ -305,7 +307,7 @@ "HeaderCastCrew": "Снимались и снимали", "HeaderChannelAccess": "Доступ ко каналам", "HeaderChannels": "Каналы", - "HeaderChapterImages": "Рисунки сцен", + "HeaderChapterImages": "Изображения сцен", "HeaderCodecProfile": "Профиль кодеков", "HeaderCodecProfileHelp": "Профили кодеков обозначают ограничения устройства при воспроизведении с определёнными кодеками. Если применяется ограничение, то медиаданные перекодируются, даже если кодек настроен для прямого воспроизведения.", "HeaderConfigureRemoteAccess": "Конфигурирование удалённого доступа", @@ -335,7 +337,7 @@ "HeaderDisplay": "Отображение", "HeaderDownloadSync": "Загрузка и синхро", "HeaderEasyPinCode": "Простой PIN-код", - "HeaderEditImages": "Править рисунки", + "HeaderEditImages": "Править изображения", "HeaderEnabledFields": "Включённые поля", "HeaderEnabledFieldsHelp": "Снимите флажок, чтобы зафиксировать поле и защитить его данные от изменнений.", "HeaderEpisodes": "Эпизоды", @@ -343,7 +345,7 @@ "HeaderExternalIds": "Внешние идентификаторы:", "HeaderFeatureAccess": "Доступ к компонентам", "HeaderFeatures": "Материалы", - "HeaderFetchImages": "Отборка рисунков:", + "HeaderFetchImages": "Отборка изображений:", "HeaderFetcherSettings": "Параметры отборщика", "HeaderFilters": "Фильтры", "HeaderForKids": "Детям", @@ -356,8 +358,8 @@ "HeaderIdentificationCriteriaHelp": "Введите хотя бы одно условие распознания.", "HeaderIdentificationHeader": "Заголовок для распознания", "HeaderIdentifyItemHelp": "Введите одно или несколько условий поиска. Изымите условие, чтобы прирастить найденные результаты.", - "HeaderImageOptions": "Опции рисунка", - "HeaderImageSettings": "Параметры рисунков", + "HeaderImageOptions": "Параметры изображения", + "HeaderImageSettings": "Настройки изображения", "HeaderInstall": "Установка", "HeaderInstantMix": "Автомикс", "HeaderItems": "Элементы", @@ -404,7 +406,7 @@ "HeaderPeople": "Люди", "HeaderPhotoAlbums": "Фотоальбомы", "HeaderPinCodeReset": "Сброс PIN-кода", - "HeaderPlayAll": "Воспр. все", + "HeaderPlayAll": "Воспроизвести все", "HeaderPlayOn": "Воспроизведение", "HeaderPlayback": "Воспроизведение медиаданных", "HeaderPlaybackError": "Ошибка воспроизведения", @@ -467,10 +469,10 @@ "HeaderTranscodingProfileHelp": "Добавьте профили перекодировки, чтобы указать, какие форматы следует использовать, когда требуется перекодировка.", "HeaderTunerDevices": "Тюнерные устройства", "HeaderTuners": "Тюнеры", - "HeaderTypeImageFetchers": "{0} отборщики рисунков", + "HeaderTypeImageFetchers": "{0} отборщики изображений", "HeaderTypeText": "Ввод текста", "HeaderUpcomingOnTV": "Ожидаемое на ТВ", - "HeaderUploadImage": "Выкладка рисунка", + "HeaderUploadImage": "Загрузка изображения", "HeaderUser": "Пользователь", "HeaderUsers": "Пользователи", "HeaderVideoQuality": "Качество видео", @@ -489,10 +491,10 @@ "Horizontal": "Горизонтально", "HttpsRequiresCert": "Чтобы включить HTTPS для внешних подключений, вам нужно будет предоставить доверенный SSL-cертификат, например, Let's Encrypt. Предоставьте сертификат или отключите защищенные соединения.", "Identify": "Распознать", - "Images": "Рисунки", + "Images": "Изображения", "ImportFavoriteChannelsHelp": "При включении, будут импортированы только каналы, которые обозначены как избранное на тюнерном устройстве.", "ImportMissingEpisodesHelp": "При включении, информация об отсутствующих эпизодах будет импортирована в вашу базу данных Jellyfin и отображаться в пределах сезонов и сериалов. Это может увеличить время сканирования медиатеки.", - "InstallingPackage": "Устанавливается {0}", + "InstallingPackage": "Устанавливается {0} (версия {1})", "InstantMix": "Автомикс", "ItemCount": "{0} элемент(а/ов)", "Items": "Элементы", @@ -508,7 +510,7 @@ "LabelAirsBeforeEpisode": "Эпизод airs_before:", "LabelAirsBeforeSeason": "Сезон airs_before:", "LabelAlbum": "Альбом:", - "LabelAlbumArtHelp": "PN используемое для альбомных обложек, внутри атрибута dlna:profileID при upnp:albumArtURI. Некоторым устройствам требуется специфическое значение, вне зависимости от размера рисунка.", + "LabelAlbumArtHelp": "PN используемое для альбомных обложек, внутри атрибута dlna:profileID при upnp:albumArtURI. Некоторым устройствам требуется специфическое значение, вне зависимости от размера изображения.", "LabelAlbumArtMaxHeight": "Макс. высота облома альбома:", "LabelAlbumArtMaxHeightHelp": "Максимальное разрешение обложек альбома, представляемых с помощью upnp:albumArtURI.", "LabelAlbumArtMaxWidth": "Макс. ширина обложки альбома:", @@ -538,7 +540,7 @@ "LabelBurnSubtitles": "Внедрение субтитров:", "LabelCache": "Кэш:", "LabelCachePath": "Путь к кешу:", - "LabelCachePathHelp": "Укажите произвольное расположение для файлов серверного кэша, например, рисунков. Оставьте поле незаполненным, чтобы использовать значение по умолчанию.", + "LabelCachePathHelp": "Укажите произвольное расположение для файлов серверного кэша, например, изображений. Оставьте поле незаполненным, чтобы использовать значение по умолчанию.", "LabelCancelled": "Отменено", "LabelCertificatePassword": "Пароль сертификата:", "LabelCertificatePasswordHelp": "Если для вашего сертификата требуется пароль, то введите его здесь.", @@ -579,7 +581,7 @@ "LabelDownMixAudioScale": "Коэффициент усиления при понижающем микшировании:", "LabelDownMixAudioScaleHelp": "Коэффициент компенсирующего усиления звука при понижающем до стерео микшировании. Значение 1 сохраняет исходный уровень.", "LabelDownloadLanguages": "Загружаемые языки:", - "LabelDropImageHere": "Перетащите рисунок сюда или щёлкните для навигации.", + "LabelDropImageHere": "Перетащите изображение сюда или щёлкните для навигации.", "LabelDropShadow": "Окантовка:", "LabelEasyPinCode": "Простой PIN-код:", "LabelEmbedAlbumArtDidl": "Внедрять альбомные обложки в DIDL", @@ -599,14 +601,14 @@ "LabelEnableHardwareDecodingFor": "Включить аппаратное декодирование для:", "LabelEnableRealtimeMonitor": "Включить отслеживание в реальном времени", "LabelEnableRealtimeMonitorHelp": "В поддерживаемых файловых системах правки файлов будут обрабатываться незамедлительно.", - "LabelEnableSingleImageInDidlLimit": "Лимитировать до единственного внедрённого рисунка", - "LabelEnableSingleImageInDidlLimitHelp": "На некоторых устройствах не отрисовывается нормально, если внедрены несколько рисунков внутри DIDL.", + "LabelEnableSingleImageInDidlLimit": "Ограничить единственным встроенным изображением", + "LabelEnableSingleImageInDidlLimitHelp": "На некоторых устройствах не отрисовывается нормально, если встроено несколько изображений внутри DIDL.", "LabelEndDate": "Конечная дата:", "LabelEpisodeNumber": "Номер эпизода:", "LabelEvent": "Событие:", "LabelEveryXMinutes": "Каждые:", - "LabelExtractChaptersDuringLibraryScan": "Извлекать рисунки сцен в процессе сканирования медиатеки", - "LabelExtractChaptersDuringLibraryScanHelp": "Генерируются рисунки сцен при импорте видео в процессе сканирования медиатеки. В противном случае, они будут извлечены в процессе назначенной задачи «Рисунки сцен», позволяя регулярному сканированию медиатеки завершаться быстрее.", + "LabelExtractChaptersDuringLibraryScan": "Извлекать изображения сцен в процессе сканирования медиатеки", + "LabelExtractChaptersDuringLibraryScanHelp": "Генерируются изображения сцен при импорте видео в процессе сканирования медиатеки. В противном случае, они будут извлечены в процессе назначенной задачи «Изображения сцен», позволяя регулярному сканированию медиатеки завершаться быстрее.", "LabelFailed": "Неудачно", "LabelFileOrUrl": "Файл или URL:", "LabelFinish": "Завершить", @@ -630,8 +632,8 @@ "LabelIconMaxWidth": "Макс. ширина значка:", "LabelIconMaxWidthHelp": "Максимальное разрешение значков представляемых с помощью upnp:icon.", "LabelIdentificationFieldHelp": "Подстрока без учёта регистра, либо регулярное выражение.", - "LabelImageFetchersHelp": "Включите и ранжируйте предпочитаемые отборщики рисунков в порядке приоритета.", - "LabelImageType": "Тип рисунка:", + "LabelImageFetchersHelp": "Включите и ранжируйте предпочитаемые отборщики изображений в порядке приоритета.", + "LabelImageType": "Тип изображения:", "LabelImportOnlyFavoriteChannels": "Ограничиваться каналами обозначенными как избранное", "LabelInNetworkSignInWithEasyPassword": "Включить внутрисетевой вход со своим простым PIN-кодом", "LabelInNetworkSignInWithEasyPasswordHelp": "Используется простой PIN-код для входа в клиенты внутри своей локальной сети. Ваш обычный пароль будет необходим только вне дома. Если PIN-код не заполнен, то внутри своей домашней сети не потребуется пароль.", @@ -641,11 +643,11 @@ "LabelKodiMetadataDateFormat": "Формат даты выпуска:", "LabelKodiMetadataDateFormatHelp": "Все даты в пределах NFO-файлов будут разбираться по данному формату.", "LabelKodiMetadataEnableExtraThumbs": "Копировать extrafanart в поле extrathumbs", - "LabelKodiMetadataEnableExtraThumbsHelp": "При загрузке рисунков, их возможно сохранять внутрь extrafanart и extrathumbs для максимальной совместимости с оболочкой Kodi.", + "LabelKodiMetadataEnableExtraThumbsHelp": "Загружаемые изображения могут быть сохранены внутри полей extrafanart и extrathumbs для максимальной совместимости с оболочкой Kodi.", "LabelKodiMetadataEnablePathSubstitution": "Включить подстановки путей", - "LabelKodiMetadataEnablePathSubstitutionHelp": "Включаются подстановки путей к рисункам с помощью параметров подстановки путей сервера.", - "LabelKodiMetadataSaveImagePaths": "Сохранять пути рисунков в пределах NFO-файлов", - "LabelKodiMetadataSaveImagePathsHelp": "Рекомендуется, если имена файлов рисунков не соответствуют руководящим принципам Kodi.", + "LabelKodiMetadataEnablePathSubstitutionHelp": "Включаются подстановки путей к изображениям с помощью параметров подстановки путей сервера.", + "LabelKodiMetadataSaveImagePaths": "Сохранять пути изображений в пределах NFO-файлов", + "LabelKodiMetadataSaveImagePathsHelp": "Рекомендуется, если имена файлов изображений не соответствуют руководящим принципам Kodi.", "LabelKodiMetadataUser": "Сохранение в NFO-файле данных о просмотре пользователем:", "LabelKodiMetadataUserHelp": "Сохраняет данные о просмотрах в NFO-файлах для использования в других приложениях.", "LabelLanNetworks": "Домашние сети:", @@ -660,7 +662,7 @@ "LabelManufacturer": "Производитель:", "LabelManufacturerUrl": "URL производителя", "LabelMatchType": "Тип соответствия:", - "LabelMaxBackdropsPerItem": "Макс. число задников на элемент:", + "LabelMaxBackdropsPerItem": "Максимальное число фонов на элемент:", "LabelMaxChromecastBitrate": "Качество трансляции Chromecast:", "LabelMaxParentalRating": "Макс. допустимая возрастная категория:", "LabelMaxResumePercentage": "Макс. доля для возобновления, %:", @@ -680,12 +682,12 @@ "LabelMetadataSavers": "Хранители метаданных:", "LabelMetadataSaversHelp": "Выберите форматы файлов, куда будут сохраняться метаданные.", "LabelMethod": "Метод:", - "LabelMinBackdropDownloadWidth": "Мин. ширина загружаемого задника:", - "LabelMinResumeDuration": "Мин. длительность для возобновления:", + "LabelMinBackdropDownloadWidth": "Минимальная ширина загружаемого фона:", + "LabelMinResumeDuration": "Минимальная длительность для возобновления:", "LabelMinResumeDurationHelp": "Наименьшая длительность видео в секундах, при которой сохраняется позиция воспроизведения и позволяется возобновление.", - "LabelMinResumePercentage": "Мин. доля для возобновления, %:", + "LabelMinResumePercentage": "Минимальная доля для возобновления, %:", "LabelMinResumePercentageHelp": "Произведения предполагаются не воспроизведёнными, при остановке до данного момента.", - "LabelMinScreenshotDownloadWidth": "Мин. ширина загружаемого снимка экрана:", + "LabelMinScreenshotDownloadWidth": "Минимальная ширина загружаемого снимка экрана:", "LabelModelDescription": "Описание модели", "LabelModelName": "Наименование модели", "LabelModelNumber": "Номер модели", @@ -709,7 +711,7 @@ "LabelNumberOfGuideDaysHelp": "Больше дней загрузки данных телегида обеспечивает возможность заблаговременно назначать расписание и просматривать больше перечней, однако это займёт больше времени для загрузки. При значении «Авто» выбор определяется числом каналов.", "LabelOptionalNetworkPath": "(Необязательно) Общедоступная сетевая папка:", "LabelOptionalNetworkPathHelp": "Если данная папка общедоступна в своей сети, предоставление пути к сетевой папке может позволить Jellyfin-приложениям на других устройствах получить прямой доступ к медиафайлам.", - "LabelOriginalAspectRatio": "Исходное соот-ие сторон:", + "LabelOriginalAspectRatio": "Исходное соотношение сторон:", "LabelOriginalTitle": "Оригинальное название:", "LabelOverview": "Обзор:", "LabelParentNumber": "Родительский номер:", @@ -833,7 +835,7 @@ "LabelVideo": "Видео", "LabelXDlnaCap": "Свойства X-Dlna:", "LabelXDlnaCapHelp": "Определяется содержание из элемента X_DLNACAP во пространстве имён urn:schemas-dlna-org:device-1-0.", - "LabelXDlnaDoc": "Схема X-Dlna:", + "LabelXDlnaDoc": "Схема X-DLNA:", "LabelXDlnaDocHelp": "Определяется содержание из элемента X_DLNADOC во пространстве имён urn:schemas-dlna-org:device-1-0.", "LabelYear": "Год:", "LabelYourFirstName": "Ваше имя:", @@ -856,18 +858,18 @@ "ManageLibrary": "Управление медиатекой", "ManageRecording": "Управлять записью", "MapChannels": "Сопоставить каналы", - "MarkPlayed": "Отметить как воспр-ое", - "MarkUnplayed": "Отметить как невоспр-ое", + "MarkPlayed": "Отметить как воспроизведенное", + "MarkUnplayed": "Отметить как невоспроизведенное", "MaxParentalRatingHelp": "Содержание с более высокой возр. категорией будет скрыто от этого пользователя.", "MediaInfoAnamorphic": "Анаморфность", - "MediaInfoAspectRatio": "Соот-ие сторон", + "MediaInfoAspectRatio": "Соотношение сторон", "MediaInfoBitDepth": "Глубина цвета", "MediaInfoBitrate": "Поток. ск-ть", "MediaInfoChannels": "Каналы", "MediaInfoCodec": "Кодек", "MediaInfoCodecTag": "Тег кодека", "MediaInfoContainer": "Контейнер", - "MediaInfoDefault": "Умолчание", + "MediaInfoDefault": "По умолчанию", "MediaInfoExternal": "Внешние", "MediaInfoForced": "Форсир-ые", "MediaInfoFramerate": "Ч-та кадров", @@ -880,7 +882,7 @@ "MediaInfoProfile": "Профиль", "MediaInfoRefFrames": "Опорные кадры", "MediaInfoResolution": "Разрешение", - "MediaInfoSampleRate": "Ч-та дискр-ии", + "MediaInfoSampleRate": "Частота дискретизации", "MediaInfoSize": "Размер", "MediaInfoTimestamp": "Метка времени", "MediaIsBeingConverted": "Медиаданные преобразуются в формат, совместимый с устройством, которое воспроизводит эти медиаданные.", @@ -961,16 +963,16 @@ "NoNextUpItemsMessage": "Ничего не найдено. Начните смотреть свои ТВ-передачи!", "NoPluginConfigurationMessage": "В данном плагине нет параметров конфигурирования.", "NoSubtitleSearchResultsFound": "Результатов не найдено.", - "NoSubtitles": "Без субтитров", + "NoSubtitles": "Ничего", "NoSubtitlesHelp": "По умолчанию, субтитры не будут загружаться. Они могут быть все ещё включены вручную во время воспроизведения.", "None": "Ничего", "Normal": "Обычный", "NumLocationsValue": "{0} пап(ки/ок)", "Off": "Выкл", "OneChannel": "Один канал", - "OnlyForcedSubtitles": "Только форсированные субтитры", + "OnlyForcedSubtitles": "Только форсированные", "OnlyForcedSubtitlesHelp": "Загружены будут только форсированные субтитры.", - "OnlyImageFormats": "Только графические форматы (VOBSUB, PGS, SUB и т.д.)", + "OnlyImageFormats": "Только графические форматы (VOBSUB, PGS и SUB)", "OptionAdminUsers": "Администраторы", "OptionAlbum": "Альбом", "OptionAlbumArtist": "Исп. альбома", @@ -1003,7 +1005,7 @@ "OptionBlockMusic": "Музыка", "OptionBlockTrailers": "Трейлеры", "OptionBlockTvShows": "ТВ-передачи", - "OptionBluray": "BluRay", + "OptionBluray": "Blu-ray", "OptionCommunityRating": "Пользовательский рейтинг", "OptionContinuing": "Продолжающееся", "OptionCriticRating": "Оценка критиков", @@ -1020,12 +1022,12 @@ "OptionDisplayFolderView": "Отображать аспект Папки для просмотра обычных медиапапок", "OptionDisplayFolderViewHelp": "Отображение аспекта \"Папки\" рядом с другими вашими медиатеками. Это может быть полезно, если вы хотите вид обычных папок.", "OptionDownloadArtImage": "Виньетка", - "OptionDownloadBackImage": "Задник", + "OptionDownloadBackImage": "Фон", "OptionDownloadBannerImage": "Баннер", "OptionDownloadBoxImage": "DVD-бокс", "OptionDownloadDiscImage": "Диск", - "OptionDownloadImagesInAdvance": "Загружать рисунки заблаговременно", - "OptionDownloadImagesInAdvanceHelp": "По умолчанию, большинство рисунков загружаются только при запросе от Jellyfin-приложения. Включите данную опцию, чтобы загружать все рисунки заблаговременно, при импорте новых медиаданных. Это может привести к существенно длительным сканированиям медиатеки.", + "OptionDownloadImagesInAdvance": "Загружать изображения заблаговременно", + "OptionDownloadImagesInAdvanceHelp": "По умолчанию, большинство изображений загружаются только при запросе от Jellyfin-приложения. Включите данную опцию, чтобы загружать все изображения заблаговременно, при импорте новых медиаданных. Это может привести к существенно длительным сканированиям медиатеки.", "OptionDownloadLogoImage": "Логотип", "OptionDownloadMenuImage": "Меню", "OptionDownloadPrimaryImage": "Основной", @@ -1045,7 +1047,7 @@ "OptionEstimateContentLength": "Рассчитывать длину содержимого при перекодировке", "OptionEveryday": "Ежедневно", "OptionExternallyDownloaded": "Внешние загружаемые", - "OptionExtractChapterImage": "Включить извлечение рисунков сцен", + "OptionExtractChapterImage": "Включить извлечение изображений сцен", "OptionFavorite": "Избранное", "OptionFriday": "пятница", "OptionHasSpecialFeatures": "Доп. материалы", @@ -1092,7 +1094,7 @@ "OptionResumable": "Возможно возобновление", "OptionRuntime": "Длительность", "OptionSaturday": "суббота", - "OptionSaveMetadataAsHidden": "Сохранять метаданные и рисунки в виде скрытых файлов", + "OptionSaveMetadataAsHidden": "Сохранять метаданные и изображения в виде скрытых файлов", "OptionSaveMetadataAsHiddenHelp": "Это изменение будет применено к новым метаданным сохраняемым в будущем. Существующие файлы метаданных будут обновлены в следующий раз, когда они будут сохраняться на Jellyfin Server.", "OptionSpecialEpisode": "Спецэпизоды", "OptionSubstring": "Подстрока", @@ -1110,10 +1112,10 @@ "OptionWeekly": "Еженедельно", "OriginalAirDateValue": "Дата исходного эфира: {0}", "Overview": "Обзор", - "PackageInstallCancelled": "Установка {0} отменена.", - "PackageInstallCompleted": "Установка {0} завершена.", - "PackageInstallFailed": "Установка {0} неудачна.", - "ParentalRating": "Возр. кат-ия", + "PackageInstallCancelled": "Установка {0} (версия {1}) отменена.", + "PackageInstallCompleted": "Установка {0} (версия {1}) завершена.", + "PackageInstallFailed": "Установка {0} (версия {1}) неудачна.", + "ParentalRating": "Возрастная категория", "PasswordMatchError": "Пароль и подтверждение пароля должны совпадать.", "PasswordResetComplete": "Пароль был сброшен.", "PasswordResetConfirmation": "Вы действительно хотите сбросить пароль?", @@ -1126,10 +1128,10 @@ "PinCodeResetComplete": "PIN-код был сброшен.", "PinCodeResetConfirmation": "Вы действительно хотите сбросить PIN-код?", "PlaceFavoriteChannelsAtBeginning": "Разместить избранные каналы в начале", - "Play": "Воспр.", - "PlayAllFromHere": "Воспр. все отсюда", + "Play": "Воспроизведение", + "PlayAllFromHere": "Воспроизвести все отсюда", "PlayCount": "Кол. воспроизведений", - "PlayFromBeginning": "Воспр. с начала", + "PlayFromBeginning": "Воспроизвести с начала", "PlayNext": "Воспроизвести следующее", "PlayNextEpisodeAutomatically": "Воспроизводить последующий эпизод автоматически", "Played": "Воспроизведено", @@ -1179,7 +1181,7 @@ "RepeatMode": "Режим повтора", "RepeatOne": "Повторить раз", "ReplaceAllMetadata": "Замена всех метаданных", - "ReplaceExistingImages": "Замена имеющихся рисунков", + "ReplaceExistingImages": "Замена имеющихся изображений", "RequiredForAllRemoteConnections": "Требуется для всех внешних подключений", "RestartPleaseWaitMessage": "Подождите, пока Jellyfin Server выключится и перезапустится. Это может занять минуту или две.", "ResumeAt": "Возобновить с {0}", @@ -1221,6 +1223,8 @@ "ShowYear": "Отображать год", "Shows": "Передачи", "Shuffle": "Перемешать", + "New": "Новинка", + "Filter": "Фильтр", "SimultaneousConnectionLimitHelp": "Максимальное количество разрешённых одновременных потоков. Введите 0, чтобы снять ограничения.", "SkipEpisodesAlreadyInMyLibrary": "Не записывать эпизоды, которые уже находятся в моей медиатеке", "SkipEpisodesAlreadyInMyLibraryHelp": "Эпизоды будут сравниваться с помощью номеров сезонов и эпизодов, когда они имеются.", @@ -1243,7 +1247,7 @@ "Subtitles": "Субтитры", "Suggestions": "Предлагаемое", "Sunday": "воскресенье", - "Sync": "Синхро", + "Sync": "Синхронизация", "SystemDlnaProfilesHelp": "Системные профили доступны только для чтения. Правки системного профиля будут сохранены в новом настраиваемом профиле.", "TV": "ТВ", "TabAccess": "Доступ", @@ -1258,7 +1262,7 @@ "TabContainers": "Контейнеры", "TabDashboard": "Панель", "TabDevices": "Устройства", - "TabDirectPlay": "Прямое воспр-ие", + "TabDirectPlay": "Прямое воспроизведение", "TabDisplay": "Отображение", "TabEpisodes": "Эпизоды", "TabFavorites": "Избранное", @@ -1346,7 +1350,7 @@ "ValueSeconds": "{0} сек", "ValueSeriesCount": "{0} сериал(а/ов)", "ValueSongCount": "{0} композици(и/й)", - "ValueSpecialEpisodeName": "Спецэпизод - {0}", + "ValueSpecialEpisodeName": "Специальный эпизод - {0}", "ValueTimeLimitMultiHour": "Временной лимит: {0} час(а/ов)", "ValueTimeLimitSingleHour": "Временной лимит: 1 час", "ValueVideoCodec": "Видео кодек: {0}", @@ -1373,7 +1377,7 @@ "LabelDynamicExternalId": "{0} Ид:", "LeaveBlankToNotSetAPassword": "Оставьте пустым, чтобы не назначать пароль.", "MessageImageFileTypeAllowed": "Поддерживаются только файлы JPEG и PNG.", - "MessageImageTypeNotSelected": "Выберите тип рисунка из выпадающего меню.", + "MessageImageTypeNotSelected": "Выберите тип изображения из выпадающего меню.", "OptionResElement": "res-элемент", "AuthProviderHelp": "Выберите поставщика аутентификации, который будет использоваться для аутентификации пароля этого пользователя.", "HeaderFavoriteMovies": "Избранные фильмы", @@ -1401,7 +1405,7 @@ "MediaInfoSoftware": "ПО", "MediaInfoStreamTypeAudio": "Аудио", "MediaInfoStreamTypeData": "Данные", - "MediaInfoStreamTypeEmbeddedImage": "Внедрённый рисунок", + "MediaInfoStreamTypeEmbeddedImage": "Встроенное изображение", "MediaInfoStreamTypeSubtitle": "Субтитры", "MediaInfoStreamTypeVideo": "Видео", "MessageNoCollectionsAvailable": "Коллекции позволяют вам наслаждаться персонализированными группами фильмов, сериалов и альбомов. Нажмите кнопку +, чтобы начать создавать коллекции.", @@ -1419,8 +1423,8 @@ "OptionLoginAttemptsBeforeLockoutHelp": "При значении 0 наследуются по умолчанию три попытки для обычных пользователей и пять для администратора. При установке этого значения в -1 функция отключается.", "OptionPoster": "Постер", "OptionPosterCard": "Постер-карта", - "OptionThumb": "Бегунок", - "OptionThumbCard": "Бегунок-карта", + "OptionThumb": "Эскиз", + "OptionThumbCard": "Эскиз-карта", "PasswordResetProviderHelp": "Выберите поставщика сброса пароля, который будет использоваться, когда этот пользователь запрашивает сброс пароля", "PlaybackData": "Данные воспроизведения", "SubtitleOffset": "Сдвиг субтитров", @@ -1436,7 +1440,7 @@ "LabelPlayMethod": "Метод воспроизведения:", "LabelFolder": "Папка:", "LabelBaseUrl": "Базовый URL:", - "LabelBitrate": "Поток. ск-ть:", + "LabelBitrate": "Битрейт:", "LabelAudioSampleRate": "Частота дискретизации аудио:", "LabelAudioCodec": "Аудио кодек:", "LabelAudioChannels": "Аудио каналы:", @@ -1445,10 +1449,10 @@ "HeaderFavoriteBooks": "Избранные книги", "CopyStreamURL": "Копировать URL потока", "LabelPleaseRestart": "Изменения вступят в силу после перезагрузки веб-клиента вручную.", - "CopyStreamURLSuccess": "URL скопирован успешно.", + "CopyStreamURLSuccess": "URL скопирован успешно.", "MusicLibraryHelp": "Просмотрите {0}руководство по именованию музыки{1}.", "FetchingData": "Выборка дополнительных данных", - "ButtonAddImage": "Добавить рисунок", + "ButtonAddImage": "Добавить изображение", "HeaderFavoritePeople": "Избранные люди", "OptionRandom": "Случайный", "ButtonSplit": "Разделить", @@ -1456,8 +1460,8 @@ "HeaderNavigation": "Навигация", "LabelVideoResolution": "Разрешение видео:", "LabelStreamType": "Тип потока:", - "EnableFastImageFadeInHelp": "Включить быстрое появление анимации для загруженных рисунков", - "EnableFastImageFadeIn": "Быстрое появление рисунка", + "EnableFastImageFadeInHelp": "Включить быстрое появление анимации для загруженных изображений", + "EnableFastImageFadeIn": "Быстрое появление изображения", "LabelPlayerDimensions": "Размеры проигрывателя:", "LabelDroppedFrames": "Пропущенные кадры:", "LabelCorruptedFrames": "Испорченные кадры:", @@ -1466,6 +1470,40 @@ "NoCreatedLibraries": "Похоже, вы еще не создали ни одной медиатеки. {0}Желаете создать её сейчас?{1}", "AskAdminToCreateLibrary": "Попросите администратора создать медиатеку.", "AllowFfmpegThrottling": "Притормаживать перекодировку", - "PlaybackErrorNoCompatibleStream": "Возникла проблема с профилем клиента, и сервер не отправляет совместимый формат мультимедиа.", - "AllowFfmpegThrottlingHelp": "Когда перекодирование или переупаковка достаточно далеко опережают текущую позицию воспроизведения, процесс приостанавливается, так что он использует меньше ресурсов. Это наиболее полезно, когда вы редко меняете позиции в видео. Выключите это, если у вас возникли проблемы с воспроизведением." + "PlaybackErrorNoCompatibleStream": "Этот клиент несовместим с медиаданными, а сервер не отправляет медиаданные в совместимом формате.", + "AllowFfmpegThrottlingHelp": "Когда перекодирование или переупаковка достаточно далеко опережают текущую позицию воспроизведения, процесс приостанавливается, так что он использует меньше ресурсов. Это наиболее полезно, когда вы редко меняете позиции в видео. Выключите это, если у вас возникли проблемы с воспроизведением.", + "OnWakeFromSleep": "При пробуждении ото сна", + "YadifBob": "YADIF с удвоением", + "OnApplicationStartup": "При запуске приложения", + "EveryXHours": "Каждые {0} часов", + "EveryHour": "Каждый час", + "EveryXMinutes": "Каждые {0} мин", + "WeeklyAt": "{0} в {1}", + "DailyAt": "Ежедневно в {0}", + "PersonRole": "как {0}", + "ListPaging": "{0}-{1} из {2}", + "Yadif": "YADIF", + "Track": "Дорожка", + "Season": "Сезон", + "Person": "Персона", + "OtherArtist": "Другой исполнитель", + "Movie": "Фильм", + "LabelLibraryPageSize": "Размер страницы медиатеки:", + "Episode": "Эпизод", + "ClientSettings": "Параметры клиента", + "BoxSet": "Коллекция", + "Artist": "Исполнитель", + "AlbumArtist": "Исполнитель альбома", + "Album": "Альбом", + "LastSeen": "Последний раз был {0}", + "WriteAccessRequired": "Jellyfin Server требуются права на запись в эту папку. Обеспечьте доступ для записи и попробуйте снова.", + "PathNotFound": "Путь не может быть найден. Убедитесь, что путь правильный и попробуйте снова.", + "ReleaseGroup": "Релиз-группа", + "PreferEmbeddedEpisodeInfosOverFileNames": "Предпочитать встроенную информацию эпизода вместо имён файлов", + "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Используется информация об эпизоде из встроенных метаданных, если они доступны.", + "LabelLibraryPageSizeHelp": "Устанавливается количество элементов для отображения на странице медиатеки. Установите 0 для отключения нумерации страниц.", + "LabelDeinterlaceMethod": "Метод устранения гребёнки:", + "DeinterlaceMethodHelp": "Выберите метод устранения гребёнки, который будет использоваться при перекодировании чересстрочного содержания.", + "UnsupportedPlayback": "Jellyfin не может расшифровать содержимое, защищенное DRM, но в любом случае будет предпринята попытка расшифровки всего содержимого, включая защищенные заголовки. Некоторые файлы могут выглядеть полностью черными из-за шифрования или других неподдерживаемых функций, таких как интерактивные заголовки.", + "MessageUnauthorizedUser": "В настоящее время у вас нет доступа к серверу. Пожалуйста, свяжитесь с администратором сервера для получения дополнительной информации." } diff --git a/src/strings/sv.json b/src/strings/sv.json index 7f6e1abc68..d932221993 100644 --- a/src/strings/sv.json +++ b/src/strings/sv.json @@ -2,7 +2,7 @@ "AccessRestrictedTryAgainLater": "För närvarande är åtkomsten begränsad. Försök igen senare.", "Actor": "Skådespelare", "Add": "Lägg till", - "AddItemToCollectionHelp": "Lägg till objekt till samlingar genom att söka efter dem och använda deras högerklick- eller knack/tryck-meny för att lägga till dem.", + "AddItemToCollectionHelp": "Lägg till objekt i samlingar genom att söka efter dem och använda deras högerklick- eller knackmeny", "AddToCollection": "Lägg till i samling", "AddToPlayQueue": "Lägg till i spelkö", "AddToPlaylist": "Lägg till i spellista", @@ -22,7 +22,7 @@ "AllowOnTheFlySubtitleExtractionHelp": "Inbäddade undertexter kan extraheras ur videor och skickas till klienter i textformat för att förhindra omkodning. I vissa system kan detta ta en lång tid och stoppa videouppspelningen under extraheringsprocessen. Avaktivera detta för att bränna in inbäddade undertexter genom omkodning när de inte stöds av klienten.", "AllowRemoteAccess": "Tillåt fjärranslutningar till denna Jellyfin-server.", "AllowRemoteAccessHelp": "Om avaktiverat så blockeras alla fjärranslutningar.", - "AlwaysPlaySubtitles": "Visa alltid undertexter", + "AlwaysPlaySubtitles": "Visa alltid", "AlwaysPlaySubtitlesHelp": "Undertexter på det önskade språket kommer att laddas oavsett ljudspårets språk.", "AnyLanguage": "Alla språk", "Anytime": "När som helst", @@ -1489,5 +1489,8 @@ "Episode": "Avsnitt", "ClientSettings": "Klientinställningar", "BoxSet": "Samlingsbox", - "Artist": "Artist" + "Artist": "Artist", + "ButtonTogglePlaylist": "Spellista", + "ButtonToggleContextMenu": "Mer", + "AlbumArtist": "Albumartist" } diff --git a/src/strings/tr.json b/src/strings/tr.json index 509c9be86d..d69391ce9a 100644 --- a/src/strings/tr.json +++ b/src/strings/tr.json @@ -317,7 +317,7 @@ "Director": "Yönetmen", "Directors": "Yöneticiler", "Disabled": "Deaktif", - "DisplayModeHelp": "Jellyfin’i çalıştırdığınız ekran türünü seçin.", + "DisplayModeHelp": "Arayüz için kullanılmasını istediğiniz şablonu seçin.", "DoNotRecord": "Kaydetme", "Down": "Aşağı", "Download": "İndir", @@ -365,7 +365,7 @@ "DisplayInMyMedia": "Ana ekranda görüntüleme", "DisplayInOtherHomeScreenSections": "En son medya gibi ana ekran bölümlerinde görüntüleyin ve izlemeye devam edin", "EnableBackdrops": "Arka planında", - "BurnSubtitlesHelp": "Altyazı formatına bağlı olarak video dönüştürülürken sunucunun altyazılarda yazıp yazmayacağını belirler. Altyazılarda yanmaktan kaçınmak, sunucu performansını iyileştirir. Görüntü tabanlı biçimleri (VOBSUB, PGS, SUB / IDX, vb.) Ve bazı ASS / SSA altyazılarını yazmak için Otomatik'i seçin.", + "BurnSubtitlesHelp": "Sunucunun video işlendiği esnada, altyazının görüntüye gömülmesini sağlar. Performansı çok düşürür, zorunda kalmadıkça bu özelliği seçmeyin. Görüntü tabanlı biçimleri (VOBSUB, PGS, SUB / IDX, vb.) Ve bazı ASS / SSA altyazıların görüntüye gömülmesi için Otomatik'i seçin.", "ConfirmDeleteItem": "Bu öğeyi silmek, onu hem dosya sisteminden hem de medya kütüphanenizden siler. Devam etmek istediğinize emin misiniz?", "ValueSpecialEpisodeName": "Özel - {0}", "DeviceAccessHelp": "Bu, yalnızca benzersiz şekilde tanımlanabilen ve tarayıcı erişimini engellemeyen cihazlar için geçerlidir. Kullanıcı cihazlarına erişimin filtrelenmesi, burada onaylanana kadar yeni cihazları kullanmalarını önler.", @@ -663,7 +663,7 @@ "Label3DFormat": "3D Formatı:", "Kids": "Çocuklar", "ItemCount": "{0} nesne", - "InstallingPackage": "Yükleniyor {0}", + "InstallingPackage": "Yükleniyor {0} (versiyon {1})", "Images": "Resimler", "Identify": "Tanımla", "Horizontal": "Yatay", @@ -672,12 +672,12 @@ "HeaderYears": "Yıl", "HeaderXmlSettings": "Xml Ayarları", "HeaderXmlDocumentAttributes": "Xml Döküman Öznitelikleri", - "HeaderXmlDocumentAttribute": "Xml Dökümanı Öznitelik", + "HeaderXmlDocumentAttribute": "Xml Döküman Özniteliği", "HeaderUser": "Kullanıcı", "HeaderUploadImage": "Resim Yükle", "HeaderUpcomingOnTV": "TV'de Yaklaşan", "HeaderTypeText": "Metin Gir", - "HeaderTunerDevices": "Tuner Cihazları", + "HeaderTunerDevices": "Alıcı Cihazları", "HeaderThisUserIsCurrentlyDisabled": "Bu kullanıcı şu anda pasif", "HeaderTags": "Etiketler", "HeaderSubtitleProfiles": "Altyazı Profilleri", @@ -712,5 +712,31 @@ "HeaderNavigation": "Navigasyon", "AllowFfmpegThrottling": "Video Kodlamasını Limitle", "Artist": "Oyuncu", - "Album": "Albüm" + "Album": "Albüm", + "EveryXMinutes": "Her {0} dakika", + "OnWakeFromSleep": "Uyku modundan çıkılarak uyanıldığında", + "DailyAt": "Her gün {0} 'de", + "LastSeen": "Son görülme {0}", + "WriteAccessRequired": "Jellyfin Sunucusu bu dizine yazma iznine ihtiyaç duymakta. Lütfen yazma izin ayarlarını kontrol edip tekrar deneyiniz.", + "PathNotFound": "Gösterilen yol bulunamadı. Lütfen gösterdiğiniz yolun doğru olduğundan emin olun ve tekrar deneyin.", + "EveryHour": "Her saat", + "EveryXHours": "Her {0} saatte bir", + "OnApplicationStartup": "Uygulama başladığında", + "HttpsRequiresCert": "Güvenli bağlantı kurulabilmesi için, Let's Encrypt gibi güvenilir bir sertifika sağlayıcısından edinilmiş sertifikayı tanıtmanız gerekmektedir. Lütfen bir sertifika tanımlayın ya da güvenli bağlantı seçeneğini devre dışı bırakın.", + "Home": "Anasayfa", + "HideWatchedContentFromLatestMedia": "İzlenmiş içeriği En Son Eklenenler klasöründe gösterme", + "HeaderTypeImageFetchers": "Görüntü İndirici", + "HeaderTracks": "Parçalar", + "HeaderSeriesStatus": "Dizi Durumu", + "HeaderSeriesOptions": "Dizi Seçenekleri", + "Episode": "Bölüm", + "DeinterlaceMethodHelp": "Tarama tipi görüntülerde titreşimi yok etmek için kullanılmasını istediğiniz metodu seçin.", + "ClientSettings": "Kullanıcı Ayarları", + "BoxSet": "Seri Filmler", + "AskAdminToCreateLibrary": "Kütüphane oluşturmak için yöneticiden izin iste.", + "AllowFfmpegThrottlingHelp": "Video dönüşüm işlemleri yeterince ilerlediyse kaynak tüketimini azaltmak için durdur. İleri/geri sarma işlemlerinin az yapıldığı durumlarda çok kullanışlıdır. Oynatım sorunları ile karşılaşırsanız bu özelliği kapatın.", + "AlbumArtist": "Sanatçı", + "HeaderTuners": "Alıcılar", + "HeaderTranscodingProfileHelp": "Kodlama gerekince hangi formatın kullanılacağını belirtmek için kodlama profili ekle.", + "ButtonTogglePlaylist": "Liste" } diff --git a/src/strings/vi.json b/src/strings/vi.json index e32272bdaf..6d7fa3a9f1 100644 --- a/src/strings/vi.json +++ b/src/strings/vi.json @@ -30,7 +30,7 @@ "HeaderLatestEpisodes": "Các tập phim mới nhất", "HeaderLatestMovies": "Phim mới nhất", "HeaderRecentlyPlayed": "Phát gần đây", - "HeaderSeries": "Series:", + "HeaderSeries": "Series", "HeaderStatus": "Trạng thái", "HeaderSystemDlnaProfiles": "Hồ sơ hệ thống", "HeaderUsers": "dùng", @@ -42,7 +42,7 @@ "LabelEnableDlnaPlayTo": "Cho phép DLNA chạy để", "LabelEvent": "Sự kiện:", "LabelFinish": "Kết thúc", - "LabelLanguage": "Ngôn ngữ", + "LabelLanguage": "Ngôn ngữ:", "LabelName": "Tên:", "LabelNewPassword": "Mật khẩu mới:", "LabelNewPasswordConfirm": "Xác nhận mật khẩu mới:", @@ -51,7 +51,7 @@ "LabelSaveLocalMetadata": "Lưu các ảnh nghệ thuật và metadata vào trong các thư mục media", "LabelSaveLocalMetadataHelp": "Lưu các ảnh nghệ thuật và metadata vào trong các thư mục media, sẽ đưa chúng vào một nơi bạn có thể chỉnh sửa dễ dàng hơn.", "LabelTime": "Thời gian:", - "LabelYourFirstName": "Tên của Bạn", + "LabelYourFirstName": "Tên của bạn:", "LabelYoureDone": "Bạn đã hoàn thành!", "MaxParentalRatingHelp": "Nội dung với đánh giá cao hơn sẽ được ẩn đi từ người dùng này.", "MessageNothingHere": "Không có gì ở đây.", @@ -87,7 +87,7 @@ "OptionTrackName": "Tên bài", "ParentalRating": "Parental Rating", "PasswordMatchError": "Mật khẩu và mật khẩu xác nhận cần phải khớp nhau .", - "PasswordResetComplete": "Mật khẩu đã được reset", + "PasswordResetComplete": "Mật khẩu đã được cài đặt lại.", "PasswordResetConfirmation": "Bạn có chắc muốn reset mật khẩu?", "PasswordSaved": "Mật khẩu đã được lưu.", "Saturday": "Thứ Bảy", @@ -116,7 +116,7 @@ "ThisWizardWillGuideYou": "Thủ thuật này sẽ hướng dẫn quá trình cài đặt cho bạn. Để bắt đầu, vui lòng lựa chọn ngôn ngữ bạn ưa thích.", "UninstallPluginConfirmation": "Bạn có chắc muốn gỡ bỏ{0}?", "UninstallPluginHeader": "Gỡ bỏ Plugin", - "AccessRestrictedTryAgainLater": "Truy cập hiện đang hạn chế. Hãy thử lại sau.", + "AccessRestrictedTryAgainLater": "Truy cập hiện đang bị hạn chế. Hãy thử lại sau.", "AddToCollection": "Thêm vào bộ sưu tập", "Actor": "Diễn viên", "ButtonRevoke": "Thu hồi", @@ -149,7 +149,7 @@ "ButtonFullscreen": "Toàn màn hình", "ButtonForgotPassword": "Quên mật khẩu", "ButtonFilter": "Lọc", - "ButtonEditOtherUserPreferences": "Chỉnh sửa hồ sơ, hình ảnh và sở thích cá nhân.", + "ButtonEditOtherUserPreferences": "Chỉnh sửa thông tin, hình ảnh và sở thích cá nhân.", "ButtonEditImages": "Sửa hình ảnh", "ButtonEdit": "Sửa", "ButtonDownload": "Tải", @@ -167,7 +167,7 @@ "ButtonAddScheduledTaskTrigger": "Thêm kích hoạt", "ButtonAddMediaLibrary": "Thêm thư viện Media", "ButtonAddImage": "Thêm hình ảnh", - "BurnSubtitlesHelp": "Xác định xem máy chủ có ghi phụ đề khi chuyển đổi video hay không tùy thuộc vào định dạng phụ đề. Tránh ghi trong phụ đề sẽ cải thiện hiệu suất máy chủ. Chọn Tự động để ghi hình ảnh dựa trên các định dạng (VOBSUB, PGS, SUB / IDX, v.v.) và phụ đề ASS/SSA nhất định.", + "BurnSubtitlesHelp": "Xác định xem máy chủ có nên ghi phụ đề khi chuyển đổi video hay không. Tránh thực hiện việc này sẽ cải thiện hiệu suất máy chủ đáng kể. Chọn Tự động để ghi các phụ đề có định dạng dựa trên hình ảnh (VOBSUB, PGS, SUB, IDX) và một vài phụ đề ASS/SSA nhất định.", "Browse": "Duyệt", "BoxRear": "Hộp (mặt sau)", "Books": "Sách", @@ -188,9 +188,9 @@ "Ascending": "Tăng dần", "AsManyAsPossible": "Càng nhiều càng tốt", "Artists": "Nghệ Sĩ", - "AroundTime": "Xunh quanh {0}", + "AroundTime": "Khoảng {0}", "Anytime": "Bất cứ lúc nào", - "AnyLanguage": "Bất kỳ ngôn ngữ", + "AnyLanguage": "Ngôn Ngữ Bất Kỳ", "AlwaysPlaySubtitlesHelp": "Phụ đề phù hợp với sở thích ngôn ngữ sẽ được tải bất kể ngôn ngữ âm thanh.", "AlwaysPlaySubtitles": "Luôn hiển thị phụ đề", "AllowedRemoteAddressesHelp": "Danh sách địa chỉ IP được phân tách bằng dấu phẩy hoặc các mục IP/netmask cho các mạng sẽ được phép kết nối từ xa. Nếu để trống, tất cả các địa chỉ sẽ được cho phép.", @@ -204,7 +204,7 @@ "AllLibraries": "Tất cả các thư viện", "AllLanguages": "Tất cả các ngôn ngữ", "AllEpisodes": "Tất cả các tập phim", - "AllComplexFormats": "Tất cả các định dạng phức tạp (ASS, SSA, VOBSUB, PGS, SUB / IDX, v.v.)", + "AllComplexFormats": "Tất cả các định dạng phức tạp (ASS, SSA, VOBSUB, PGS, SUB, IDX)", "AllChannels": "Tất cả các kênh", "Alerts": "Cảnh Báo", "Albums": "Albums", @@ -215,7 +215,7 @@ "AddToPlaylist": "Thêm vào danh sách phát", "AddToPlayQueue": "Thêm vào hàng đợi", "AddItemToCollectionHelp": "Thêm các mục vào bộ sưu tập bằng cách tìm kiếm và nhấp chuột phải hoặc nhấn vào menu để thêm chúng vào bộ sưu tập.", - "Absolute": "Tuyệt Đối", + "Absolute": "Tuyệt đối", "ButtonSend": "Gửi", "ButtonSelectView": "Chọn chế độ xem", "ButtonSelectServer": "Chọn máy chủ", @@ -236,5 +236,91 @@ "ButtonStart": "Bắt đầu", "ButtonSignIn": "Đăng nhập", "ButtonShutdown": "Tắt", - "ButtonSettings": "Cài đặt" + "ButtonSettings": "Cài đặt", + "DefaultErrorMessage": "Có lỗi xảy ra trong lúc xử lý yêu cầu của bạn. Xin hãy thử lại sau.", + "Default": "Mặc định", + "DeathDateValue": "Không hoạt động: {0}", + "DatePlayed": "Ngày phát", + "DateAdded": "Ngày thêm vào", + "CustomDlnaProfilesHelp": "Tạo một bộ thiết lập tuỳ chọn dành cho một thiết bị mới hoặc thay thế một thiết lập hệ thống.", + "CriticRating": "Đánh giá phê bình", + "CopyStreamURLError": "Có lỗi xảy ra lúc sao chép URL.", + "CopyStreamURLSuccess": "URL đã được sao chép.", + "CopyStreamURL": "Sao Chép URL Phát Sóng", + "Continuing": "Tiếp tục", + "ContinueWatching": "Tiếp tục xem", + "Connect": "Kết nối", + "ConfirmEndPlayerSession": "Bạn có muốn tắt máy chủ Jellyfin trên {0}?", + "ConfirmDeletion": "Xác Nhận Xoá", + "ConfirmDeleteItems": "Xoá những mục này sẽ xoá chúng khỏi ổ cứng và thư viện của bạn. Bạn có chắc chắn muốn tiếp tục?", + "ConfirmDeleteItem": "Xoá mục này sẽ xoá nó khỏi ổ cứng và thư viện của bạn. Bạn có chắc chắn muốn tiếp tục?", + "ConfirmDeleteImage": "Bạn có chắc chắn xoá ảnh này?", + "ConfigureDateAdded": "Thiết lập cách xác định \"ngày thêm vào\" trong mục cài đặt Thư Viện của phần quản lý máy chủ Jellyfin", + "Composer": "Tác giả", + "CommunityRating": "Đánh giá của cộng đồng", + "ColorTransfer": "Chuyển đổi màu", + "ColorSpace": "Bộ mã màu", + "ColorPrimaries": "Những màu chủ đạo", + "Collections": "Bộ sưu tập", + "ClientSettings": "Cài đặt thiết bị phát", + "CinemaModeConfigurationHelp": "Chế độ Cinema giúp bạn mang lại trải nghiệm rạp chiếu phim ngay tại phòng khách với khả năng phát trailers và những đoạn mở đầu tuỳ chọn trước phần chính của bộ phim.", + "ChannelNumber": "Kênh số", + "Channels": "Kênh", + "ChannelNameOnly": "Chỉ kênh {0}", + "ChannelAccessHelp": "Chọn những kênh để chia vẻ với người dùng này. Người quản lý sẽ có thể thay đổi toàn bộ kênh bằng cách sử dụng bộ quản lý thông tin.", + "ChangingMetadataImageSettingsNewContent": "Thay đổi về thiết lập của việc tải thông tin hoặc hình ảnh sẽ chỉ có tác dụng với những nội dung mới được thêm vào thư viện. Để những thiết lập mới có tác dụng với nội dung đã có sẵn, bạn sẽ phải cập nhật lại thông tin của chúng.", + "CancelSeries": "Ngưng series", + "ButtonTogglePlaylist": "Danh sách phát", + "ButtonToggleContextMenu": "Thêm", + "BoxSet": "Tuyển tập", + "Box": "Hộp", + "Banner": "Ảnh bìa", + "Art": "Nghệ thuật", + "Artist": "Nghệ Sĩ", + "AllowFfmpegThrottlingHelp": "Tạm dừng quá trình chuyển mã hoặc chuyển đổi định dạng để tiết kiệm tài nguyên máy chủ khi việc này đã đủ để phát so với vị trí hiện tại. Điều này hữu hiệu khi không tua nhanh thường xuyên lúc nghe nhạc hoặc xem phim. Hãy tắt tính năng này nếu có hiện tượng giật lag khi nghe nhạc hoặc xem phim.", + "AllowFfmpegThrottling": "Điều tiết sự chuyển mã", + "AlbumArtist": "Nghệ sĩ Album", + "Album": "Album", + "DisplayMissingEpisodesWithinSeasonsHelp": "Thiết lập này cũng phải được kích hoạt trong thiết lập máy chủ dành cho thư viện phim bộ.", + "DisplayMissingEpisodesWithinSeasons": "Hiển thị những tập phim bị thiếu trong mỗi phần", + "DisplayInOtherHomeScreenSections": "Những phần hiển thị trên trang chính như là nội dung mới nhất và nội dung tiếp theo", + "DisplayInMyMedia": "Hiển thị trên trang chính", + "Display": "Hiển thị", + "Dislike": "Không thích", + "Disconnect": "Ngắt kết nối", + "Disc": "Đĩa", + "Disabled": "Đã vô hiệu hoá", + "Directors": "Đạo Diễn", + "Director": "Đạo Diễn", + "DirectStreaming": "Phát trực tuyến", + "DirectStreamHelp2": "Phát trực tuyến sử dụng rất ít tài nguyên máy chủ mà không giảm chất lượng video.", + "DirectStreamHelp1": "Nội dung này tương thích với thiết bị về độ phân giải và dạng mã hoá (H.264, AC3, v.v.), nhưng lại không tương tích định dạng (mkv, avi, wmv, v.v.). Video sẽ được chuyển đổi định dạng trực tiếp ngay trước khi phát trên thiết bị.", + "DirectPlaying": "Phát trực tiếp", + "DeviceAccessHelp": "Thiết lập này chỉ áp dụng cho những thiết bị có thể định danh và sẽ không chặn được truy cập từ trình duyệt. Chọn lọc thiết bị người dùng sẽ chặn người dùng này truy cập từ những thiết bị mới cho đến khi được duyệt.", + "DetectingDevices": "Đang tìm kiếm thiết bị", + "Desktop": "Máy tính", + "Descending": "Giảm dần", + "Depressed": "Hạ xuống", + "DeleteUserConfirmation": "Bạn có chắc chắn muốn xoá người dùng này?", + "DeleteMedia": "Xoá nội dung", + "DeleteDeviceConfirmation": "Bạn có chắc chắn muốn xoá thiết bị này? Nó sẽ xuất hiện lại khi người dùng đăng nhập bằng thiết bị đó.", + "DeinterlaceMethodHelp": "Chọn phương pháp khử xen kẽ khi chuyển mã những nội dung sử dụng phương pháp quét xen kẽ.", + "DefaultSubtitlesHelp": "Phụ đề được sử dụng dựa vào thiết lập mặc định (default) và bắt buộc (forced) trong phần thông tin bổ trợ. Tuỳ chọn ưu tiên ngôn ngữ sẽ có tác dụng khi có nhiều phụ đề khác nhau.", + "DefaultMetadataLangaugeDescription": "Đây là thiết lập mặc định chung, bạn có thể tuỳ chỉnh thiết lập riêng cho từng thư viện.", + "DisplayModeHelp": "Chọn kiểu bố trí giao diện mà bạn muốn.", + "Download": "Tải xuống", + "Down": "Xuống", + "DoNotRecord": "Không ghi lại", + "EnableCinemaMode": "Chế độ rạp phim", + "EnableBackdropsHelp": "Hiển thị phông nền phía sau một số trang khi xem thư viện.", + "EnableBackdrops": "Phông nền", + "EditSubtitles": "Chỉnh sửa phụ đề", + "EditMetadata": "Chỉnh sửa thông tin", + "EditImages": "Chỉnh sửa hình ảnh", + "Edit": "Chỉnh sửa", + "EasyPasswordHelp": "Mã PIN tiện lợi được sử dụng cho việc truy cập offline trên những thiết bị được hỗ trợ và cũng có thể sử dụng dành cho truy cập dễ dàng trong nội mạng.", + "DropShadow": "Đổ Bóng", + "DrmChannelsNotImported": "Những kênh được bảo vệ bản quyền sẽ không được nhập vào.", + "DownloadsValue": "{0} đã tải xuống", + "EnableColorCodedBackgrounds": "Màu nền theo loại kênh" } diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index 671c183a1d..fd0afb77ab 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -449,7 +449,7 @@ "Hide": "隐藏", "HideWatchedContentFromLatestMedia": "从最新媒体中隐藏已观看的内容", "Home": "首页", - "HttpsRequiresCert": "要启用安全连接, 您需要提供一个受信任的 SSL 证书, 如 \"允许加密\"。请提供证书或禁用安全连接。", + "HttpsRequiresCert": "要启用安全连接, 您需要提供一个受信任的 SSL 证书, 例如 Let's Encrypt 。请提供证书或禁用安全连接。", "Identify": "识别", "Images": "图片", "ImportFavoriteChannelsHelp": "如果启用,只有在协调器设备中被标记为我的最爱的频道才会被导入。", @@ -1504,5 +1504,7 @@ "LabelDeinterlaceMethod": "反交错方法:", "DeinterlaceMethodHelp": "选择对隔行扫描内容进行转码时所用的反交错方法。", "LabelLibraryPageSize": "媒体库分页阈值:", - "LabelLibraryPageSizeHelp": "设置媒体库页面每页要显示的最多媒体个数。设置为 0 以禁用分页。" + "LabelLibraryPageSizeHelp": "设置媒体库页面每页要显示的最多媒体个数。设置为 0 以禁用分页。", + "UnsupportedPlayback": "Jellyfin无法解密被DRM保护的内容,但仍然会尝试播放包括受保护内容在内的所有内容。某些文件由于被加密或包含不受支持的特性(如互动标题),在播放时可能显示为黑屏。", + "MessageUnauthorizedUser": "您目前无权访问服务器。更多有关信息,请与服务器管理员联系。" } diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index ca2dd5b936..f5020837f8 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -45,7 +45,7 @@ "Edit": "編輯", "EditImages": "編輯圖片", "Ended": "完結", - "EndsAtValue": "完結於{0}", + "EndsAtValue": "於 {0} 結束", "Favorite": "加到最愛", "File": "檔案", "FileNotFound": "未找到檔案。", @@ -67,13 +67,13 @@ "HeaderDeleteItem": "刪除項目", "HeaderEasyPinCode": "簡易 PIN 碼", "HeaderFeatureAccess": "可以使用的功能", - "HeaderFetchImages": "抓取圖像:", + "HeaderFetchImages": "擷取圖像:", "HeaderForgotPassword": "忘記密碼", "HeaderFrequentlyPlayed": "經常播放", "HeaderGuideProviders": "節目表提供者", "HeaderImageSettings": "圖像設置", "HeaderInstantMix": "瞬時混播", - "HeaderLatestEpisodes": "最新節目單元", + "HeaderLatestEpisodes": "最新劇集", "HeaderLatestMovies": "最新電影", "HeaderLatestRecordings": "最新錄影的節目", "HeaderLatestSongs": "最新歌曲", @@ -106,7 +106,7 @@ "LabelAllowServerAutoRestart": "允許伺服器自動重新啟動去安裝更新資料", "LabelAllowServerAutoRestartHelp": "伺服器只會在沒有使用者在使用時重新啟動。", "LabelAudioLanguagePreference": "音頻語言偏好選項:", - "LabelCachePath": "緩存路徑:", + "LabelCachePath": "快取路徑:", "LabelCollection": "收藏櫃:", "LabelContentType": "內容類型:", "LabelCountry": "國家:", @@ -116,7 +116,7 @@ "LabelEnableDlnaClientDiscoveryInterval": "尋找客戶端時間間隔(秒)", "LabelEnableDlnaDebugLogging": "記錄 DLNA 除錯資料到日誌", "LabelEnableDlnaDebugLoggingHelp": "將會建立非常大的日誌檔案,建議在進行故障排除時啟用。", - "LabelEnableDlnaPlayTo": "播放到DLNA設備", + "LabelEnableDlnaPlayTo": "播放到 DLNA 設備", "LabelEnableRealtimeMonitor": "啟用實時監控", "LabelEnableRealtimeMonitorHelp": "支持的檔案系統上的更改,將會立即處理。", "LabelEvent": "事件:", @@ -149,15 +149,15 @@ "LabelTime": "時間:", "LabelTriggerType": "觸發類型:", "LabelUser": "使用者:", - "LabelYourFirstName": "你的名字:", - "LabelYoureDone": "完成!", + "LabelYourFirstName": "您的名字:", + "LabelYoureDone": "完成,耶!", "LibraryAccessHelp": "選擇媒體資料夾與此使用者共享。管理員將可以使用中繼資料管理器編輯所有的媒體資料夾。", "Like": "喜歡", "MaxParentalRatingHelp": "具有較高的家長評級內容將從這使用者被隱藏。", "MessageAreYouSureDeleteSubtitles": "您真的要刪除這個字幕檔嗎?", "MessageDownloadQueued": "下載已排程。", "MessageItemsAdded": "已新增項目。", - "MessageNoMovieSuggestionsAvailable": "目前並沒有推薦的電影。開始觀看並對您的電影評分後,我們就會為您推薦您可能會喜歡的內容。", + "MessageNoMovieSuggestionsAvailable": "目前並沒有推薦的電影,開始觀看並對您的電影評分後,我們就會為您推薦您可能會喜歡的內容。", "MessageNothingHere": "這裡沒有什麼。", "MessagePasswordResetForUsers": "下列使用者的密碼已被重新設置。該使用者現在可以使用在密碼重置時所使用之 PIN 代碼進行登入。", "MessagePleaseEnsureInternetMetadata": "請確保已啟用從互聯網下載媒體資料。", @@ -181,7 +181,7 @@ "OptionBluray": "藍光", "OptionCommunityRating": "社區評分", "OptionContinuing": "持續", - "OptionCriticRating": "評論家評價", + "OptionCriticRating": "影評人評價", "OptionDaily": "每日", "OptionDateAdded": "新增日期", "OptionDatePlayed": "播放日期", @@ -235,7 +235,7 @@ "OptionWeekly": "每週", "OriginalAirDateValue": "原始播出日期:{0}", "ParentalRating": "Parental Rating", - "PasswordMatchError": "密碼和密碼確認必須一致。", + "PasswordMatchError": "兩個密碼必須一致。", "PasswordResetComplete": "密碼已重設。", "PasswordResetConfirmation": "你確定要重設密碼?", "PasswordSaved": "密碼已保存。", @@ -245,8 +245,8 @@ "RecordingCancelled": "已取消排程錄製。", "RecordingScheduled": "已排程錄製。", "Refresh": "重新整理", - "RefreshDialogHelp": "詳細資料的更新方式會依據Jellyfin的設定及已經啟用的網路服務來進行。", - "ReplaceAllMetadata": "取代所有詳細資料", + "RefreshDialogHelp": "詳細資料的更新方式會依據 Jellyfin 的設定及已經啟用的網路服務來進行。", + "ReplaceAllMetadata": "取代所有中繼資料", "ReplaceExistingImages": "取代現有圖片", "Saturday": "星期六", "Save": "保存", @@ -291,19 +291,19 @@ "TabTrailers": "預告", "TabTranscoding": "轉碼中", "TabUpcoming": "接下來", - "TellUsAboutYourself": "請自我介紹一下你自己", - "ThisWizardWillGuideYou": "此精靈將帶你完成安裝過程。開始之前,請選擇您慣用的語言。", + "TellUsAboutYourself": "介紹一下自己", + "ThisWizardWillGuideYou": "此精靈將帶你完成安裝過程,開始之前,請選擇您慣用的語言。", "Thursday": "星期四", - "TrackCount": "{0}個曲目", + "TrackCount": "{0} 個曲目", "Tuesday": "星期二", - "UninstallPluginConfirmation": "你確定要卸載{0}?", - "UninstallPluginHeader": "卸載插件", + "UninstallPluginConfirmation": "你確定要解除安裝 {0}?", + "UninstallPluginHeader": "解除安裝插件", "UserProfilesIntro": "Jellyfin 可單獨對使用者進行設定,所有使用者擁有自己的顯示設置,播放狀態和家長控制。", "Users": "使用者", "VersionNumber": "版本 {0}", "Wednesday": "星期三", "WelcomeToProject": "歡迎使用 Jellyfin!", - "WizardCompleted": "這就是我們所需的全部資訊,Jellyfin 現在正在收集你的媒體櫃的資料,在這段時間內,不妨參考我們推出的應用程式。按一下完成進入伺服器總覽頁。", + "WizardCompleted": "這就是我們所需的全部資訊,Jellyfin 現在正在收集你的媒體櫃的資料,在這段時間內,不妨參考我們推出的應用程式。按一下完成進入控制台。", "Actor": "演員", "AddToPlayQueue": "加入播放清單", "AddToPlaylist": "加入播放列表", @@ -367,7 +367,7 @@ "ButtonConnect": "連結", "ButtonDown": "下", "ButtonDownload": "下載", - "ButtonEditOtherUserPreferences": "編輯此使用者的內容,大頭貼和個人設定。", + "ButtonEditOtherUserPreferences": "編輯此使用者的內容、大頭貼和個人設定。", "ButtonFullscreen": "全螢幕", "ButtonHelp": "幫助", "ButtonInfo": "詳細資料", @@ -418,7 +418,7 @@ "CloudSyncFeatureDescription": "將您的媒體備份到雲端當作簡單的備份,收藏和轉檔。", "Collections": "合輯", "Composer": "作曲家", - "ConfigureDateAdded": "調整伺服器怎麼判定媒體褲的「新增日期」", + "ConfigureDateAdded": "調整伺服器怎麼判定媒體庫的「新增日期」", "ConfirmDeleteImage": "刪除圖片?", "ConfirmDeleteItems": "刪除這些項目會將檔案從系統和媒體庫中刪除。你真的要繼續嗎?", "ConfirmEndPlayerSession": "您要在 {0} 秒後將 Jellyfin關機嗎?", @@ -462,7 +462,7 @@ "DisplayInOtherHomeScreenSections": "在“最新媒體”和“繼續觀看“等主畫面區塊中顯示", "DisplayMissingEpisodesWithinSeasons": "顯示每季缺少的劇集", "DisplayMissingEpisodesWithinSeasonsHelp": "必須在 Jellyfin 伺服器的電視媒體庫設定中啟用該功能。", - "DisplayModeHelp": "選擇您正在運行Jellyfin的螢幕類型。", + "DisplayModeHelp": "選擇您想要的界面樣式。", "DoNotRecord": "不要錄", "Down": "下", "DownloadItemLimitHelp": "非必要。 設置要下載的項目數限制。", @@ -498,7 +498,7 @@ "EnterFFmpegLocation": "輸入 FFmpeg 路徑", "Episodes": "劇集", "Error": "錯誤", - "ErrorAddingListingsToSchedulesDirect": "在將電視節目時間表添加到您的Schedules Direct賬號時出現錯誤。每個Schedules Direct賬號只允許有限的時間表。您在繼續前可能需要登入Schedules Direct網站并刪除賬號中的其它列表。", + "ErrorAddingListingsToSchedulesDirect": "在將電視節目時間表新增到您的 Schedules Direct 帳號時出現錯誤。每個 Schedules Direct 帳號只允許有限的時間表。您在繼續前可能需要登入 Schedules Direct 網站並刪除帳號中的其它列表。", "ErrorAddingGuestAccount1": "新增Jellyfin Connect時發生錯誤。你的賓客有建立Jellyfin帳號嗎?他們可以在 {0} 創建帳號。", "ErrorAddingGuestAccount2": "若你還是遇到問題,請發送email至 {0} 並附上你和他們的email帳號。", "ErrorAddingJellyfinConnectAccount1": "新增Jellyfin Connect時發生錯誤。您有建立Jellyfin帳號嗎?您可以在 {0} 創建帳號。", @@ -506,17 +506,17 @@ "ErrorAddingJellyfinConnectAccount3": "這個 Jellyfin 帳號已經被連接至一個本地帳號。一個 Jellyfin帳號 只能同時被連接到一個本機帳號。", "ErrorAddingMediaPathToVirtualFolder": "新增媒體路徑時發生錯誤,請確認路徑是否有效,且你的 Jellyfin 伺服器有對該位置的存取權。", "ErrorAddingTunerDevice": "新增調諧器設備時發生錯誤,請確認它是否可被存取後再試一次。", - "ErrorAddingXmlTvFile": "存取 XMLTV 文件時發生錯誤。請確認該檔案是否存在後再試一次。", + "ErrorAddingXmlTvFile": "存取 XMLTV 檔案時發生錯誤,請確認該檔案是否存在後再試一次。", "ErrorConnectServerUnreachable": "處理請求時發生錯誤。您的伺服器無法與我們位於 {0} 的 Jellyfin Connect伺服器溝通。請確認你的伺服器有網路連結且防火牆或其他安全性程式允許這個程式對外溝通。", - "ErrorDeletingItem": "從Jellyfin伺服器刪除項目時發生錯誤。請確認伺服器有那個磁碟的寫入權限並再試一次。", - "ErrorGettingTvLineups": "下載電視節目表時發生錯誤,請確認你的資訊是正確的然後再試一次。", + "ErrorDeletingItem": "從 Jellyfin 伺服器刪除項目時發生錯誤,請確認伺服器對該磁碟有寫入權限並再試一次。", + "ErrorGettingTvLineups": "下載電視節目表時發生錯誤,請確認你的資訊是否正確並重試。", "ErrorMessagePasswordNotMatchConfirm": "密碼和密碼確認必須吻合。", "ErrorMessageStartHourGreaterThanEnd": "結束時間必須在開始時間後。", "ErrorMessageUsernameInUse": "用戶名已存在。請重新選個名稱再試。", "ErrorPleaseSelectLineup": "請選擇節目表,然後再試一次。如果沒有可用的節目表,請檢查您的使用者名稱、密碼和郵遞區號是否正確。", "ErrorReachingJellyfinConnect": "連接 Jellyfin Connect 伺服器時發生錯誤。請確認你的網絡狀態是否穩定後再試一次。", "ErrorRemovingJellyfinConnectAccount": "移除 Jellyfin Connect 帳號時發生錯誤。請確認你的網絡狀態是否穩定後再試一次。", - "ErrorSavingTvProvider": "儲存電視供應商時發生錯誤。請確認它是可存取後再試一次。", + "ErrorSavingTvProvider": "儲存電視供應商時發生錯誤,請確認是否可存取並重試。", "EveryNDays": "每 {0} 天", "ExitFullscreen": "結束全螢幕", "ExtraLarge": "特大", @@ -542,15 +542,15 @@ "Genres": "風格", "GroupBySeries": "按系列分組", "GroupVersions": "按版本分組", - "GuestStar": "特邀明星", + "GuestStar": "客串", "GuestUserNotFound": "未找到用戶。請確保用戶名稱正確後重試,或者嘗試輸入他們的電子郵件地址。", "Guide": "指南", "GuideProviderSelectListings": "選擇列表", - "H264CrfHelp": "The Constant Rate Factor (CRF) 是 x264 編碼器的默認畫質設置。此方法允許編碼器自動分配位元速率來試著達到一定輸出品質。讓每個畫格得到它需要的位元數來保持所需的品質等級。CRF 會得到最佳的位元速率分配結果。", + "H264CrfHelp": "CRF 是 x264 編碼器的預設畫質設置。此方法允許編碼器自動分配位元速率來試著達到一定輸出品質。讓每個畫格得到它需要的位元數來保持所需的品質等級。CRF 會得到最佳的位元速率分配結果。", "EncoderPresetHelp": "速度越慢則會得到更好的壓縮編碼效率。", - "HDPrograms": "HD節目", + "HDPrograms": "HD 節目", "HandledByProxy": "由反向代理處理", - "HardwareAccelerationWarning": "啟動硬體加速可能在某些環境下導致系統不穩定。請確認你的作業系統和影片驅動程式是最新的。如果你在開啟此項後播放影片產生困難,那麼你需要將此選項設回”無“。", + "HardwareAccelerationWarning": "啟動硬體加速可能在某些環境下導致系統不穩定。請確認你的作業系統和影片驅動程式是最新的。如果你在開啟此項後難以播放影片,那麼你需要將此選項設回「無」。", "HeaderAccessSchedule": "存取時程", "HeaderAccessScheduleHelp": "建立一個存取時程以限制可存取的時段。", "HeaderActiveDevices": "運行中裝置", @@ -570,7 +570,7 @@ "HeaderAllowMediaDeletionFrom": "允許從中刪除媒體", "HeaderApiKey": "API 金鑰", "HeaderApiKeys": "API 金鑰", - "HeaderApiKeysHelp": "外部應用程式需要有一個 API 金鑰以用於和 Jellyfin 伺服器溝通。金鑰將在通過 Jellyfin 帳戶登入時自動發行,或者你可以手動為應用程式產生一個金鑰。", + "HeaderApiKeysHelp": "外部應用程式需要有一個 API 金鑰以用於和 Jellyfin 伺服器溝通。金鑰會在 Jellyfin 使用者登入時自動發行,或者你可以手動為應用程式產生一個金鑰。", "HeaderApp": "應用程式", "HeaderAppearsOn": "同時出現於", "HeaderAudio": "音訊", @@ -606,12 +606,12 @@ "HeaderConfirmRecordingCancellation": "確認取消錄製", "HeaderConfirmRecordingDeletion": "確認刪除錄影", "HeaderConfirmRemoveUser": "移除用戶", - "HeaderConfirmRevokeApiKey": "撤銷 API 金鑰", + "HeaderConfirmRevokeApiKey": "重置 API 金鑰", "HeaderConfirmSeriesCancellation": "確認系列取消", "HeaderConfirmation": "確認", "HeaderConnectToServer": "連結至伺服器", "HeaderConnectionFailure": "連結失敗", - "HeaderContainerProfile": "影片容器設定檔", + "HeaderContainerProfile": "影片載體設定", "HeaderContainerProfileHelp": "影片容器的設定檔標明了設備播放特定媒體格式時的限制。如果在限制之內則媒體將被轉碼,否則媒體格式將被設定為直接播放。", "HeaderContinueListening": "繼續聆聽", "HeaderContinueWatching": "繼續觀賞", @@ -628,7 +628,7 @@ "HeaderDeleteTaskTrigger": "刪除任務觸發條件", "HeaderDestination": "目的地", "HeaderDetectMyDevices": "偵測我的設備", - "HeaderDeveloperInfo": "開發者訊息", + "HeaderDeveloperInfo": "開發者資訊", "HeaderDevice": "裝置", "HeaderDeviceAccess": "允許裝置存取", "HeaderDevices": "裝置", @@ -651,7 +651,7 @@ "HeaderFavoriteAlbums": "最愛專輯", "HeaderFavoriteArtists": "最愛演出者", "HeaderFavoriteCollections": "最愛收藏", - "HeaderFavoriteEpisodes": "最愛級數", + "HeaderFavoriteEpisodes": "最愛影集", "HeaderFavoriteMovies": "最愛電影", "HeaderFavoritePlaylists": "最愛播放列表", "HeaderFavoriteShows": "最愛節目", @@ -668,7 +668,7 @@ "HeaderHomePage": "主畫面", "HeaderHomeScreen": "主畫面", "HeaderHomeScreenSettings": "主畫面設定", - "HeaderHttpHeaders": "Http 標頭", + "HeaderHttpHeaders": "HTTP 標頭", "HeaderIdentification": "身份識別", "HeaderIdentificationCriteriaHelp": "至少輸入一個識別標準。", "HeaderIdentificationHeader": "身份識別標題", @@ -871,9 +871,9 @@ "HeaderVideoType": "影片類型", "HeaderVideoTypes": "影片類型", "HeaderVideos": "影片", - "HeaderXmlDocumentAttribute": "XML檔案屬性", - "HeaderXmlDocumentAttributes": "XML檔案屬性", - "HeaderXmlSettings": "XML設置", + "HeaderXmlDocumentAttribute": "XML 檔案屬性", + "HeaderXmlDocumentAttributes": "XML 檔案屬性", + "HeaderXmlSettings": "XML 設置", "HeaderYears": "年份", "HeadersFolders": "資料夾", "Hide": "隱藏", @@ -883,14 +883,14 @@ "HttpsRequiresCert": "要啟用安全連線,您需要提供受信任的SSL證書,如 Let's Encrypt。 請提供證書,或停用安全連線。", "Identify": "識別", "Images": "圖片", - "ImportFavoriteChannelsHelp": "如果啟用,只有在調諧器設備中被標記為我的最愛的頻道才會被導入。", - "ImportMissingEpisodesHelp": "如果啟用,有關缺失劇集的數據導入您的Jellyfin媒體庫,並在季節和系列中顯示。 這可能會導致媒體庫掃描延長。", - "InstallingPackage": "正在安装 {0} (版本 {1})", + "ImportFavoriteChannelsHelp": "若啟用,只有在調諧器設備中被標記為我的最愛的頻道才會被導入。", + "ImportMissingEpisodesHelp": "若啟用,有關缺失劇集的數據導入您的 Jellyfin 媒體庫,並在季節和系列中顯示。 這可能會導致媒體庫掃描延長。", + "InstallingPackage": "正在安装 {0}(版本 {1})", "InstantMix": "即時混音", "Items": "項目", "Kids": "兒童", - "Label3DFormat": "3D格式:", - "LabelAbortedByServerShutdown": "(因為伺服器關閉被中止)", + "Label3DFormat": "3D 格式:", + "LabelAbortedByServerShutdown": "(因為伺服器關閉被中止)", "LabelAccessDay": "一周中的何時:", "LabelAccessEnd": "結束時間:", "LabelAccessStart": "開始時間:", @@ -904,24 +904,24 @@ "LabelAlbumArtMaxHeight": "專輯封面最大高度:", "LabelAlbumArtMaxHeightHelp": "通過 upnp:albumArtURI 顯示的專輯封面超鏈接的最大分辨率。", "LabelAlbumArtMaxWidth": "專輯封面最大寬度:", - "LabelAlbumArtMaxWidthHelp": "通過upnp:albumArtURI顯示的專輯封面超鏈接的最大分辨率。", - "LabelAlbumArtPN": "專輯封面PN :", + "LabelAlbumArtMaxWidthHelp": "通過 upnp:albumArtURI 顯示的專輯封面超鏈接的最大解析度。", + "LabelAlbumArtPN": "專輯封面 PN :", "LabelAlbumArtists": "專輯作家:", "LabelAll": "所有", "LabelAllowHWTranscoding": "允許硬體轉碼", - "LabelAllowedRemoteAddresses": "遠端IP地址過濾:", - "LabelAllowedRemoteAddressesMode": "遠端IP地址過濾模式:", - "LabelAppName": "APP名稱", - "LabelAppNameExample": "例如: Sickbeard, Sonarr", + "LabelAllowedRemoteAddresses": "遠端 IP 過濾:", + "LabelAllowedRemoteAddressesMode": "遠端 IP 過濾模式:", + "LabelAppName": "APP 名稱", + "LabelAppNameExample": "例如:可愛蹦蹦主機、小安的 Jellyfin", "LabelArtists": "藝人:", "LabelArtistsHelp": "分開多重使用 ;", "LabelAudio": "音頻", "LabelAuthProvider": "認證提供者:", "LabelAutomaticallyRefreshInternetMetadataEvery": "從網路自動刷新數據:", "LabelBindToLocalNetworkAddress": "聯結本地網絡地址:", - "LabelBindToLocalNetworkAddressHelp": "(可選的)覆蓋 HTTP 服務器綁定的本地 IP 地址。如果留空,服務器將會監聽所有可用的地址。改變這個值需要重啟 Jellyfin 伺服器\n。", + "LabelBindToLocalNetworkAddressHelp": "(選用)覆蓋 HTTP 服務器綁定的本地 IP 地址。如果留空,服務器將會監聽所有可用的地址。改變這個值需要重啟 Jellyfin 伺服器。", "LabelBirthDate": "出生日期:", - "LabelBirthYear": "出生年份:", + "LabelBirthYear": "出生年:", "LabelBlastMessageInterval": "活動信號的時間間隔(秒)", "LabelBlastMessageIntervalHelp": "確定伺服器活動消息之間的持續時間(秒)。", "LabelBlockContentWithTags": "通過標籤鎖定內容:", @@ -940,17 +940,17 @@ "LabelCustomCssHelp": "於 Web 介面套用您的自訂樣式。", "LabelCustomDeviceDisplayName": "顯示名稱:", "Depressed": "凹陷", - "HeaderHome": "主頁", + "HeaderHome": "首頁", "HeaderSelectMetadataPathHelp": "瀏覽或者輸入路徑以用於保存中繼資料,請確保資料夾可以寫入。", "HeaderSelectServerCachePathHelp": "瀏覽或者輸入路徑以用於伺服器快取檔案。請確保該資料夾可以被寫入。", "LabelCustomDeviceDisplayNameHelp": "指定自訂的顯示名稱,或者留空以使用設備自己報告的名稱。", "LabelCustomRating": "自訂分級:", - "LabelDashboardTheme": "儀表板佈景主題:", + "LabelDashboardTheme": "控制台佈景主題:", "LabelDateAdded": "新增日期:", "LabelDateAddedBehavior": "新内容加入的日期應使用:", "LabelDateTimeLocale": "設定時區:", "LabelDeathDate": "死亡時間:", - "LabelDefaultScreen": "預設螢幕:", + "LabelDefaultScreen": "預設分頁:", "LabelDefaultUser": "預設使用者:", "LabelDeviceDescription": "裝置說明", "LabelDidlMode": "DIDL 模式:", @@ -966,13 +966,13 @@ "OptionMax": "最大", "LabelAudioBitDepth": "音訊位元深度:", "LabelBaseUrl": "根路徑:", - "LabelIconMaxHeight": "Icon 最高高度:", + "LabelIconMaxHeight": "圖示最高高度:", "LabelHttpsPortHelp": "Jellyfin 的 HTTPS 伺服器應綁定的 TCP 端口。", "LabelIconMaxHeightHelp": "通過 upnp:icon 的圖標最大解析度。", "CopyStreamURL": "複製串流連結", "MediaInfoDefault": "預設", "MediaInfoStreamTypeAudio": "音訊", - "LabelDateAddedBehaviorHelp": "如果原本就有中繼資料,則將始終在這些選項之一之前使用它。", + "LabelDateAddedBehaviorHelp": "如果原本就有中繼資料,將會優先使用其數據。", "LabelScreensaver": "螢幕保護程式:", "LabelSeasonNumber": "季:", "LabelDropImageHere": "拖移圖片到這裡,或是點擊來選取。", @@ -1010,7 +1010,7 @@ "ValueCodec": "編碼:{0}", "ValueSongCount": "{0} 首歌", "LabelFileOrUrl": "檔案或路徑:", - "LabelKodiMetadataSaveImagePaths": "在 nfo 檔案中儲存圖片路徑", + "LabelKodiMetadataSaveImagePaths": "在 NFO 檔案中儲存圖片路徑", "LabelLanNetworks": "區域網路:", "LabelMetadataPathHelp": "指定自訂路徑來儲存下載的圖片與中繼資料。", "LabelZipCode": "郵遞區號:", @@ -1024,7 +1024,7 @@ "ShowAdvancedSettings": "顯示進階選項", "ShowTitle": "顯示標題", "ShowYear": "顯示年份", - "Shuffle": "隨ㄔㄧ", + "Shuffle": "隨機播放", "Smart": "智慧", "HeaderFavoriteBooks": "最愛的書籍", "LabelAudioBitrate": "音訊比特率:", @@ -1130,7 +1130,7 @@ "ManageRecording": "管理錄影", "MessageAlreadyInstalled": "已安裝此版本。", "MessageConfirmRestart": "您確定要重新啟動嗎?", - "Metadata": "ˊ中繼資料", + "Metadata": "中繼資料", "OptionAllUsers": "所有使用者", "OptionHomeVideos": "圖片", "OptionPoster": "海報", @@ -1144,7 +1144,7 @@ "TV": "電視", "TabUsers": "使用者", "Trailers": "預告", - "LabelImageFetchersHelp": "按優先級啟用並排列您喜歡的圖片抓取器。", + "LabelImageFetchersHelp": "啟用並按優先順序排序您的首選圖片擷取器。", "LabelDownMixAudioScale": "縮混時的音訊增強:", "LabelDownMixAudioScaleHelp": "縮混時增強音訊。其中一個音軌將保持原始音量。", "LabelDownloadLanguages": "下載語言:", @@ -1162,7 +1162,7 @@ "LabelSelectUsers": "選擇使用者:", "LabelSelectVersionToInstall": "選擇要安裝的版本:", "LabelSendNotificationToUsers": "傳送通知給:", - "LabelSortBy": "排序依:", + "LabelSortBy": "排序按照:", "LabelVideoBitrate": "影片比特率:", "MediaInfoSize": "大小", "MediaInfoTimestamp": "時間戳", @@ -1295,7 +1295,7 @@ "Up": "上", "ValueOneSeries": "1 劇集", "Writer": "編劇", - "XmlTvMovieCategoriesHelp": "有這些類別的節目會被當作電影。用「|」分隔多個。", + "XmlTvMovieCategoriesHelp": "有這些類別的節目會被當作電影,以「|」來分隔多個項目。", "ValueSeriesCount": "{0} 劇集", "LabelHardwareAccelerationTypeHelp": "硬件加速需要額外的配置。", "LabelHomeNetworkQuality": "區域網路畫質:", @@ -1317,7 +1317,7 @@ "OptionEstimateContentLength": "轉檔時,估計內容長度", "OptionExternallyDownloaded": "外部下載", "OptionHlsSegmentedSubtitles": "HLS 分段字幕", - "OptionLoginAttemptsBeforeLockout": "確定在被封鎖之前可以登入失敗幾次。", + "OptionLoginAttemptsBeforeLockout": "在被封鎖之前可以登入失敗幾次。", "OptionRequirePerfectSubtitleMatch": "只下載與我的影片檔案完美匹配的字幕", "PlayCount": "播放次數", "Series": "電視劇", @@ -1342,7 +1342,7 @@ "LabelMoviePrefixHelp": "若前綴套用到電影標題,請在此處輸入它來方便伺服器能夠正確處理。", "LabelMovieRecordingPath": "電影錄製路徑(選用):", "LabelNotificationEnabled": "啟用這個通知", - "LabelProfileContainersHelp": "以逗號分隔。留空則適用於所有影片容器。", + "LabelProfileContainersHelp": "以逗號分隔,留空則適用於所有影片容器。", "LabelSelectFolderGroupsHelp": "未選中的資料夾將在其自己的檢視中顯示。", "LabelSerialNumber": "序號", "LabelSeriesRecordingPath": "電視劇錄影路徑(選用):", @@ -1398,7 +1398,7 @@ "MessageDirectoryPickerLinuxInstruction": "使用 Linux on Arch Linux、CentOS、Debian、Fedora、openSUSE 或 Ubuntu 作業系統,您必須授權使用者至少讀取權限來存取您的儲存路徑。", "MessageEnablingOptionLongerScans": "啟用這個選項可能會延長媒體庫的掃描時間。", "MessageFileReadError": "讀取檔案時發生錯誤。", - "MessageForgotPasswordInNetworkRequired": "請檢查您的區域網路後再試一次來開始密碼重置流程。", + "MessageForgotPasswordInNetworkRequired": "請檢查您的區域網路後再開始密碼重置流程。", "MessageForgotPasswordFileCreated": "已在伺服器上建立了以下檔案,並包含有關後續步驟說明:", "MessageNoAvailablePlugins": "沒有可用的模組。", "MessageNoServersAvailable": "無法自動偵測伺服器。", @@ -1474,7 +1474,7 @@ "Uniform": "輪廓", "Unmute": "取消靜音", "Unplayed": "尚未播放", - "TvLibraryHelp": "查看{0}電視命名指南{1}。", + "TvLibraryHelp": "查看 {0} 電視命名指南 {1} 。", "LabelMonitorUsers": "監控活動:", "LabelPleaseRestart": "改動將在手動重啟用戶端後生效。", "LabelProfileCodecsHelp": "以逗號分隔。留空則適用於所有編解碼器。", @@ -1482,7 +1482,7 @@ "LabelInNetworkSignInWithEasyPasswordHelp": "你可以在你的家庭網路中使用你的簡易 PIN 碼登錄 Jellyfin 應用程式,僅在你使用外部網路時才需要輸入密碼,如果 PIN 碼留空,那麼在你的區域網路中便不需輸入密碼。", "LabelReleaseDate": "釋出日期:", "LabelRemoteClientBitrateLimit": "網際網路串流傳輸位元率限制(Mbps):", - "LanNetworksHelp": "在强制頻寬限制時,認作本地網路上的 IP 地址或 IP/網路掩碼條目的逗號分隔列表。如果設置此項,所有其它 IP 地址將被視作在外部網路上,并且將受到外部頻寬限制。如果保留爲空,則只將服務器的子網視作本地網路。", + "LanNetworksHelp": "在強制頻寬限制時,認作本地網路上的 IP 地址或 IP/子網域遮罩項目的逗號分隔列表。若設置此項,所有其它 IP 地址將被視作在外部網路上,并且將受到外部頻寬限制。如果保留爲空,則只將服務器的子網域遮罩作本地網路。", "OptionIgnoreTranscodeByteRangeRequests": "忽略轉檔位元組範圍請求", "OptionIgnoreTranscodeByteRangeRequestsHelp": "如果啟用,這些請求會被兌現,但會忽略的位元組範圍標頭。", "OptionLoginAttemptsBeforeLockoutHelp": "若值為 0,則表示將允許普通使用者嘗試三次、管理員嘗試五次的預設值,設定為 -1 來停用此功能。", @@ -1507,7 +1507,7 @@ "SystemDlnaProfilesHelp": "系統設定檔案是唯讀的,更改系統設定檔案將被儲存到自訂的新設定檔案。", "LabelNumber": "編號:", "LabelNumberOfGuideDays": "下載電視指南日數:", - "OnlyForcedSubtitlesHelp": "只有標記為「強制」的字幕會被載入。", + "OnlyForcedSubtitlesHelp": "僅被標記為「強制」的字幕會被載入。", "PackageInstallCompleted": "{0} (版本 {1}) 安裝完成。", "OptionDisplayFolderViewHelp": "在其他媒體庫旁邊顯示資料夾,對想要一個普通的資料夾檢視很有用。", "LabelReasonForTranscoding": "轉檔原因:", @@ -1534,7 +1534,7 @@ "LabelSportsCategories": "體育分類:", "LabelStartWhenPossible": "當可能時自動開始:", "LabelVaapiDevice": "VA API 裝置:", - "DashboardArchitecture": "結構:{0}", + "DashboardArchitecture": "架構:{0}", "MediaInfoSampleRate": "採樣率", "MessageContactAdminToResetPassword": "請聯繫您的管理員來重置密碼。", "MessageUnsetContentHelp": "內容將顯示為純資料夾,建議使用中繼資料管理器設置子資料夾的內容類型。", @@ -1542,7 +1542,7 @@ "OptionCustomUsers": "自訂", "OptionDateAddedFileTime": "使用檔案建立日期", "OptionReportByteRangeSeekingWhenTranscodingHelp": "這對一些時間跳轉緩慢的裝置是必要的。", - "XmlTvNewsCategoriesHelp": "有這些類別的節目會被當作新聞節目。用「|」分隔多個。", + "XmlTvNewsCategoriesHelp": "有這些類別的節目會被當作新聞節目,以「|」來分隔多個項目。", "LabelKodiMetadataEnableExtraThumbsHelp": "為了相容 Kodi 主題,下載的圖片將被同時儲存在 extrafanart 和 extrathumbs 資料夾中。", "LabelInternetQuality": "網路畫質:", "LabelKodiMetadataEnablePathSubstitutionHelp": "允許將圖片的路徑以伺服器路徑來替換。", @@ -1575,16 +1575,16 @@ "LabelPostProcessorArguments": "處理器後命令行參數:", "LabelPostProcessorArgumentsHelp": "使用 {path} 作為錄製檔案的路徑。", "LabelPreferredDisplayLanguage": "首選語言:", - "LabelPreferredDisplayLanguageHelp": "翻譯 Jellyfin 是一個進行中的項目。", + "LabelPreferredDisplayLanguageHelp": "歡迎一起翻譯 Jellyfin!", "LabelPreferredSubtitleLanguage": "字幕語言偏好:", - "LabelProtocol": "協議:", + "LabelProtocol": "協議:", "LabelProtocolInfo": "協議資訊:", "LabelPublicHttpPort": "公開 HTTP 端口:", "LabelPublicHttpsPort": "公開 HTTPS 端口:", "LabelProtocolInfoHelp": "當響應來自裝置的 GetProtocolInfo(獲取協議訊息)請求時,該值將被使用。", "LabelPublicHttpPortHelp": "公開連接埠應映射到本地 HTTP 連接埠。", "LabelPublicHttpsPortHelp": "公開連接埠應映射到本地 HTTPS 連接埠。", - "LabelReadHowYouCanContribute": "了解如何作出貢獻。", + "LabelReadHowYouCanContribute": "瞭解如何一同貢獻。", "LabelSelectFolderGroups": "自動將以下資料夾中的內容分組到視圖中,例如電影、音樂和電視:", "LabelStatus": "狀態:", "LiveBroadcasts": "直播", @@ -1603,13 +1603,13 @@ "Vertical": "垂直", "VideoRange": "影片範圍", "ViewPlaybackInfo": "查看播放訊息", - "XmlTvSportsCategoriesHelp": "有這些類別的節目會被當作體育節目。用「|」分隔多個。", + "XmlTvSportsCategoriesHelp": "有這些類別的節目會被當作體育節目,以「|」來分隔多個項目。", "XmlTvPathHelp": "XML 電視檔案的路徑,Jellyfin 將讀取該檔案並定期檢查其更新,您負責建立和更新檔案。", "MessageInvalidForgotPasswordPin": "簡易代碼錯誤或已過期,請再試一次。", "OptionAllowVideoPlaybackTranscoding": "允許播放需要轉檔的影片", "Small": "小", "Smaller": "更小", - "XmlTvKidsCategoriesHelp": "有這些類別的節目會被當作兒童節目。用「|」分隔多個。", + "XmlTvKidsCategoriesHelp": "有這些類別的節目會被當作兒童節目,以「|」來分隔多個項目。", "TabResponses": "響應", "LabelDisplaySpecialsWithinSeasons": "顯示劇集季度中的特集", "LabelNumberOfGuideDaysHelp": "下載更多電視指南資料會提供更好時間表查看能力,但將需要更長的下載時間。自動基於頻道數目來選擇。", @@ -1628,7 +1628,7 @@ "SelectAdminUsername": "請為管理員賬戶選擇一個用戶名。", "CopyStreamURLError": "複製網址的時候發生錯誤.", "OptionSaveMetadataAsHiddenHelp": "更改此項將應用於以後保存的元數據。現有元數據文件將在下一次 Jellyfin 伺服器保存它們時被更新。", - "OptionAllowRemoteSharedDevicesHelp": "DLNA 設備在用戶對它們進行控制前都被視作共享的。", + "OptionAllowRemoteSharedDevicesHelp": "DLNA裝置將被視為共享中,直至有使用者控制。", "OptionForceRemoteSourceTranscoding": "强制遠端轉碼(像電視直播一樣)", "MessageConfirmAppExit": "您要退出嗎?", "LaunchWebAppOnStartupHelp": "伺服器啓動時在默認游覽器中打開網頁端。使用重啓伺服器功能時此項不生效。", @@ -1646,10 +1646,37 @@ "AllowFfmpegThrottlingHelp": "當轉檔或重組進度大量超前目前播放進度時,將暫停轉檔節省消耗的資源。在不常跳播的時候最有效。如果遇到播放問題,請關閉此功能。", "AllowFfmpegThrottling": "限制轉檔", "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "這將會使用內建劇集資料。", - "PlaybackErrorNoCompatibleStream": "用戶端偵測出了問題,伺服器也未傳送相容的媒體格式。", + "PlaybackErrorNoCompatibleStream": "用戶端與該媒體不相容,伺服器也未傳送相容的媒體格式。", "PreferEmbeddedEpisodeInfosOverFileNames": "優先使用內建劇集資訊而不是檔案名稱", "OtherArtist": "其他歌手", "Artist": "歌手", "AlbumArtist": "專輯歌手", - "Album": "專輯" + "Album": "專輯", + "YadifBob": "YADIF Bob", + "WriteAccessRequired": "Jellyfin 伺服器需要此資料夾的寫入權限,請確認是否擁有寫入權限並重試。", + "PathNotFound": "無法找到此路徑,請確認路徑可用並重試。", + "Track": "音軌", + "Yadif": "YADIF", + "ListPaging": "{2} 的 {0}-{1}", + "PersonRole": "作為 {0}", + "LastSeen": "上次觀看 {0}", + "DailyAt": "每日的 {0}", + "WeeklyAt": "每週第 {0} 天的 {1}", + "OnWakeFromSleep": "當從睡眠中喚醒時", + "EveryXMinutes": "每 {0} 分鐘", + "EveryHour": "每小時", + "EveryXHours": "每 {0} 小時", + "OnApplicationStartup": "當應用程式啟動時", + "Season": "季", + "ReleaseGroup": "發行組織", + "Person": "人物", + "Movie": "電影", + "LabelLibraryPageSizeHelp": "設置媒體庫頁面每頁要顯示的最多媒體個數。設置為 0 來停用分頁。", + "LabelLibraryPageSize": "媒體庫分頁大小:", + "LabelDeinterlaceMethod": "反交錯方法:", + "Episode": "劇集", + "DeinterlaceMethodHelp": "選擇對隔行掃描內容進行轉碼時所用的反交錯方法。", + "BoxSet": "套裝", + "UnsupportedPlayback": "Jellyfin 無法解密受 DRM 保護的內容,但仍然會嘗試播放所有內容。某些檔案由於被加密或包含如互動標題等不受支援的內容,在播放時可能會沒有畫面。", + "MessageUnauthorizedUser": "您目前無權存取伺服器,請與您的伺服器管理員聯繫以獲取更多訊息。" } diff --git a/src/themes/appletv/theme.css b/src/themes/appletv/theme.css index 5ca517bea5..760038ad72 100644 --- a/src/themes/appletv/theme.css +++ b/src/themes/appletv/theme.css @@ -43,7 +43,9 @@ html { } .backgroundContainer, -.dialog { +.dialog, +.nowPlayingPlaylist, +.nowPlayingContextMenu { background: #d5e9f2; -webkit-background-size: 100% 100%; background-size: 100% 100%; @@ -186,7 +188,8 @@ html { } .appfooter, -.formDialogFooter:not(.formDialogFooter-clear) { +.formDialogFooter:not(.formDialogFooter-clear), +.playlistSectionButton { color: rgba(0, 0, 0, 0.7); background: #303030; background: -webkit-gradient(linear, left top, right top, from(#bcbcbc), color-stop(#a7b4b7), color-stop(#beb5a5), color-stop(#adbec2), to(#b9c7cb)); diff --git a/src/themes/blueradiance/theme.css b/src/themes/blueradiance/theme.css index b929c2a296..3e86782f37 100644 --- a/src/themes/blueradiance/theme.css +++ b/src/themes/blueradiance/theme.css @@ -42,6 +42,8 @@ html { } .dialog, +.nowPlayingPlaylist, +.nowPlayingContextMenu, html { background-color: #033361; } @@ -179,7 +181,8 @@ html { color: rgba(255, 255, 255, 0.87); } -.appfooter { +.appfooter, +.playlistSectionButton { background: #033664; color: #ccc; color: rgba(255, 255, 255, 0.78); diff --git a/src/themes/dark/theme.css b/src/themes/dark/theme.css index 4363be991b..f9163d82f5 100644 --- a/src/themes/dark/theme.css +++ b/src/themes/dark/theme.css @@ -36,6 +36,8 @@ html { .backgroundContainer, .dialog, +.nowPlayingPlaylist, +.nowPlayingContextMenu, html { background-color: #101010; } @@ -161,7 +163,8 @@ html { color: rgba(255, 255, 255, 0.87); } -.appfooter { +.appfooter, +.playlistSectionButton { background: #202020; color: #ccc; color: rgba(255, 255, 255, 0.78); diff --git a/src/themes/light/theme.css b/src/themes/light/theme.css index d84a1c3b67..114ef7c3b1 100644 --- a/src/themes/light/theme.css +++ b/src/themes/light/theme.css @@ -51,7 +51,9 @@ html { background-color: rgba(255, 255, 255, 0.8); } -.dialog { +.dialog, +.nowPlayingPlaylist, +.nowPlayingContextMenu { background-color: #f0f0f0; } @@ -183,7 +185,8 @@ html { color: rgba(255, 255, 255, 0.87); } -.appfooter { +.appfooter, +.playlistSectionButton { background: #282828; color: #ccc; color: rgba(255, 255, 255, 0.78); diff --git a/src/themes/purplehaze/theme.css b/src/themes/purplehaze/theme.css index 45f43abc2f..82b774a736 100644 --- a/src/themes/purplehaze/theme.css +++ b/src/themes/purplehaze/theme.css @@ -37,6 +37,8 @@ html { } .dialog, +.nowPlayingPlaylist, +.nowPlayingContextMenu, html { background-color: #230c33; } @@ -269,7 +271,8 @@ a[data-role=button] { color: rgba(255, 255, 255, 0.87); } -.appfooter { +.appfooter, +.playlistSectionButton { background: #06256f; color: #ccc; color: rgba(255, 255, 255, 0.78); diff --git a/src/themes/wmc/theme.css b/src/themes/wmc/theme.css index 6143b7fe2c..e7d4c0371b 100644 --- a/src/themes/wmc/theme.css +++ b/src/themes/wmc/theme.css @@ -48,7 +48,9 @@ html { } .backgroundContainer, -.dialog { +.dialog, +.nowPlayingPlaylist, +.nowPlayingContextMenu { background: -webkit-gradient(linear, left top, left bottom, from(#0f3562), color-stop(#1162a4), to(#03215f)); background: -webkit-linear-gradient(top, #0f3562, #1162a4, #03215f); background: -o-linear-gradient(top, #0f3562, #1162a4, #03215f); @@ -172,7 +174,8 @@ html { } .appfooter, -.formDialogFooter:not(.formDialogFooter-clear) { +.formDialogFooter:not(.formDialogFooter-clear), +.playlistSectionButton { background: #0c2450; background: -webkit-gradient(linear, left bottom, left top, from(#0c2450), to(#081b3b)); background: -webkit-linear-gradient(bottom, #0c2450, #081b3b); diff --git a/webpack.dev.js b/webpack.dev.js index beca8ea4fb..d0a8c69b8f 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -14,7 +14,7 @@ module.exports = merge(common, { rules: [ { test: /\.js$/, - exclude: /node_modules[\\/](?!query-string)/, + exclude: /node_modules[\\/](?!query-string|split-on-first|strict-uri-encode)/, loader: "babel-loader" }, { @@ -28,7 +28,7 @@ module.exports = merge(common, { { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ - 'file-loader', + 'file-loader' ] } ] diff --git a/webpack.prod.js b/webpack.prod.js index 80d40f3450..4405f8f164 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -7,7 +7,7 @@ module.exports = merge(common, { rules: [ { test: /\.js$/, - exclude: /node_modules[\\/](?!query-string)/, + exclude: /node_modules[\\/](?!query-string|split-on-first|strict-uri-encode)/, loader: "babel-loader" }, { @@ -21,7 +21,7 @@ module.exports = merge(common, { { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ - 'file-loader', + 'file-loader' ] } ] diff --git a/yarn.lock b/yarn.lock index 03437af39b..8cfc660aa3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1553,6 +1553,19 @@ autoprefixer@^9.0.0, autoprefixer@^9.6.1, autoprefixer@^9.7.4: postcss "^7.0.27" postcss-value-parser "^4.0.3" +autoprefixer@^9.7.6: + version "9.7.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.6.tgz#63ac5bbc0ce7934e6997207d5bb00d68fa8293a4" + integrity sha512-F7cYpbN7uVVhACZTeeIeealwdGM6wMtfWARVLTy5xmKtgVdBNJvbDRoCK3YO1orcs7gv/KwYlb3iXwu9Ug9BkQ== + dependencies: + browserslist "^4.11.1" + caniuse-lite "^1.0.30001039" + chalk "^2.4.2" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.27" + postcss-value-parser "^4.0.3" + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -1970,6 +1983,16 @@ browserslist@^4.0.0, browserslist@^4.11.0, browserslist@^4.6.4, browserslist@^4. node-releases "^1.1.52" pkg-up "^3.1.0" +browserslist@^4.11.1: + version "4.12.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d" + integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg== + dependencies: + caniuse-lite "^1.0.30001043" + electron-to-chromium "^1.3.413" + node-releases "^1.1.53" + pkg-up "^2.0.0" + browserslist@^4.8.2: version "4.11.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b" @@ -2240,6 +2263,11 @@ caniuse-lite@^1.0.30001038: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz#b3814a1c38ffeb23567f8323500c09526a577bbe" integrity sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q== +caniuse-lite@^1.0.30001039, caniuse-lite@^1.0.30001043: + version "1.0.30001046" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001046.tgz#7a06d3e8fd8aa7f4d21c9a2e313f35f2d06b013e" + integrity sha512-CsGjBRYWG6FvgbyGy+hBbaezpwiqIOLkxQPY4A4Ea49g1eNsnQuESB+n4QM0BKii1j80MyJ26Ir5ywTQkbRE4g== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -3667,6 +3695,11 @@ electron-to-chromium@^1.3.390: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.397.tgz#db640c2e67b08d590a504c20b56904537aa2bafa" integrity sha512-zcUd1p/7yzTSdWkCTrqGvbnEOASy96d0RJL/lc5BDJoO23Z3G/VHd0yIPbguDU9n8QNUTCigLO7oEdtOb7fp2A== +electron-to-chromium@^1.3.413: + version "1.3.418" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.418.tgz#840021191f466b803a873e154113620c9f53cec6" + integrity sha512-i2QrQtHes5fK/F9QGG5XacM5WKEuR322fxTYF9e8O9Gu0mc0WmjjwGpV8c7Htso6Zf2Di18lc3SIPxmMeRFBug== + elliptic@^6.0.0: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" @@ -5527,6 +5560,11 @@ he@1.2.x, he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +headroom.js@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/headroom.js/-/headroom.js-0.11.0.tgz#26547a932025e4243abf8ace001b4ce5e110ed20" + integrity sha512-yI4ciZRD1WH22wa5uJDg2kMtRvhJwUJWo2l41Eby0BoAD+lzXL98lf5jDFxP4Q5W3HmlrpfItSfmqc3jCtasbw== + hex-color-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" @@ -6508,10 +6546,10 @@ isurl@^1.0.0-alpha5: version "1.0.2" resolved "https://github.com/jellyfin/jellyfin-noto#a441b179c833288fc372cadb408d32a76c5479f1" -jquery@>=1.9.1, jquery@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" - integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== +jquery@>=1.9.1, jquery@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9" + integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ== js-base64@^2.1.8, js-base64@^2.1.9: version "2.5.2" @@ -10216,6 +10254,11 @@ schema-utils@^2.6.0, schema-utils@^2.6.4, schema-utils@^2.6.5: ajv "^6.12.0" ajv-keywords "^3.4.1" +screenfull@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.0.2.tgz#b9acdcf1ec676a948674df5cd0ff66b902b0bed7" + integrity sha512-cCF2b+L/mnEiORLN5xSAz6H3t18i2oHh9BA8+CQlAh5DRw2+NFAGQJOSYbcGw8B2k04g/lVvFcfZ83b3ysH5UQ== + scss-tokenizer@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" @@ -11312,10 +11355,10 @@ svgo@^1.0.0, svgo@^1.3.2: unquote "~1.1.1" util.promisify "~1.0.0" -swiper@^5.3.1: - version "5.3.6" - resolved "https://registry.yarnpkg.com/swiper/-/swiper-5.3.6.tgz#102b7f8145d734ec4c30e04602160382356b5948" - integrity sha512-FUz50g6RuvGAuXQWmR5lRPoA129leRUZ/p57ckr8+P5kR7VktElVQ47JGmWD86mOJCFfvMhUf0hinyC5UFL5iw== +swiper@^5.3.7: + version "5.3.7" + resolved "https://registry.yarnpkg.com/swiper/-/swiper-5.3.7.tgz#1349c055730e9247e4482b72631166119b83f409" + integrity sha512-BFpXllmUNj1k/Uz6FRW7ykZfUfeCpfqUZxOxeTFZKYy3gv/kOWULHjwy0xlQIJdsiVGF5nZgRG2VbVl6XWy3gw== dependencies: dom7 "^2.1.3" ssr-window "^1.0.1"