diff --git a/.copr/Makefile b/.copr/Makefile new file mode 120000 index 000000000..ec3c90dfd --- /dev/null +++ b/.copr/Makefile @@ -0,0 +1 @@ +../fedora/Makefile \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index 81eba8ccc..92cf9dc59 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 52369be1e..8e3aee83f 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 000000000..6a01fe5bf --- /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 0b92c0c9b..000000000 --- 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 80f9bc36e..9e495a4df 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 000000000..a35eb9981 --- /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 2bb5bc64d..4adf9558b 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 000000000..9f5fa6022 --- /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 000000000..fe1633fae --- /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 000000000..bc8288b82 --- /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 000000000..50966c3a0 --- /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 000000000..45a4fb75d --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..ce7b130ef --- /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 000000000..85548075e --- /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 000000000..60b3d2872 --- /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 000000000..584fe06a1 --- /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 000000000..cef83a340 --- /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 000000000..2cdcae417 --- /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 000000000..f3e568225 --- /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 000000000..d3827e75a --- /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 000000000..b7adf56c6 --- /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 000000000..93bf8d698 --- /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 000000000..54281a5eb --- /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 000000000..d47f4ff4d --- /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 000000000..e0d1f4526 --- /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 000000000..8c2cec6d3 --- /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 000000000..8d617a288 --- /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 000000000..4ba12f35e --- /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 000000000..c4cbe927e --- /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 000000000..1d3e39ac8 --- /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 000000000..dbc0bd0ef --- /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 4556e71bc..0e9732455 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'); diff --git a/package.json b/package.json index 7e8969556..e75734423 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", @@ -66,7 +66,7 @@ "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", @@ -90,17 +90,17 @@ "test": [ "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", - "src/components/dom.js", "src/components/filedownloader.js", - "src/components/filesystem.js", "src/components/images/imageLoader.js", - "src/components/input/keyboardnavigation.js", "src/components/lazyloader/lazyloader-intersectionobserver.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" @@ -132,7 +132,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 23159fd29..9ce2e16af 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 83640033b..30e42a2c5 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/components/accessschedule/accessschedule.js b/src/components/accessschedule/accessschedule.js index 2f4be8b2a..28b09b893 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/apphost.js b/src/components/apphost.js index 6d7e857c3..e5f48ac42 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); @@ -328,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") { @@ -346,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/directorybrowser/directorybrowser.js b/src/components/directorybrowser/directorybrowser.js index fc976068e..65fe34df1 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 cbbb1919b..c534ba474 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/homesections/homesections.js b/src/components/homesections/homesections.js index cb4866a1c..894cf0bdb 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/htmlvideoplayer/plugin.js b/src/components/htmlvideoplayer/plugin.js index fa0c02237..d3e3b3640 100644 --- a/src/components/htmlvideoplayer/plugin.js +++ b/src/components/htmlvideoplayer/plugin.js @@ -795,7 +795,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa dlg.parentNode.removeChild(dlg); } - screenfull.exit(); + if (screenfull.isEnabled) { + screenfull.exit(); + } }; function onEnded() { diff --git a/src/components/itemcontextmenu.js b/src/components/itemcontextmenu.js index 5f95714d3..eec46899a 100644 --- a/src/components/itemcontextmenu.js +++ b/src/components/itemcontextmenu.js @@ -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/maintabsmanager.js b/src/components/maintabsmanager.js index 257147001..e1c543436 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 0a8741387..1665efe27 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 7c5c8d408..6a0f955b2 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 b4fa87c8a..57a358d62 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 8ba870613..4b00171ae 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/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index f323d3609..031231285 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -20,9 +20,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function bindToFullscreenChange(player) { - screenfull.on('change', function () { - events.trigger(player, 'fullscreenchange'); - }); + if (screenfull.isEnabled) { + screenfull.on('change', function () { + events.trigger(player, 'fullscreenchange'); + }); + } } function triggerPlayerChange(playbackManagerInstance, newPlayer, newTarget, previousPlayer, previousTargetInfo) { diff --git a/src/components/polyfills/objectassign.js b/src/components/polyfills/objectassign.js deleted file mode 100644 index 85f55aa14..000000000 --- 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.js b/src/components/remotecontrol/remotecontrol.js index 8e2a382d1..327cd1dcf 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -672,18 +672,6 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL playbackManager.setVolume(this.value, currentPlayer); } - var contextmenuHtml = ''; - var volumecontrolHtml = '
'; - volumecontrolHtml += ''; - volumecontrolHtml += '
'; - volumecontrolHtml += '
'; - if (!layoutManager.mobile) { - context.querySelector(".nowPlayingSecondaryButtons").innerHTML += volumecontrolHtml; - context.querySelector(".playlistSectionButton").innerHTML += contextmenuHtml; - } else { - context.querySelector(".playlistSectionButton").innerHTML += volumecontrolHtml + contextmenuHtml; - } - context.querySelector(".nowPlayingVolumeSlider").addEventListener("change", setVolume); context.querySelector(".nowPlayingVolumeSlider").addEventListener("mousemove", setVolume); context.querySelector(".nowPlayingVolumeSlider").addEventListener("touchmove", setVolume); @@ -767,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/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 1ff30712f..123b4ba20 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 cf11e5736..649ac5017 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 7e7d381f0..991ed49a4 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 a55ba3066..8cead5abf 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 e0f8ea4ef..32052d1f7 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 47b1c899b..f88f57ad7 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 4b679bbbd..05075efe5 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; @@ -28,12 +28,12 @@ define(["apphost", "appSettings", "dom", "connectionManager", "loading", "layout if (UnauthorizedOrForbidden.includes(response.status)) { require(["toast"], function (toast) { const messageKey = response.status === 401 ? "MessageInvalidUser" : "MessageUnauthorizedUser"; - toast(Globalize.translate(messageKey)); + 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 ca0d3afdb..f4d5704a2 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 fbb3af120..dd71b9ed1 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 1b2718866..9820d7401 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 a434e4624..68d72d432 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 78294f440..603ab1ee6 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 39b4ca6fe..42d751a24 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 20049837d..586663218 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 cd2136cea..a4ba6bb62 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 a05cac461..3b2bf9e76 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 adccfa393..aff9b89ed 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 c381b2409..68a163c38 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 14e5e028a..dcd0dcba1 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 4343baac4..4d692f9ae 100644 --- a/src/controllers/itemdetailpage.js +++ b/src/controllers/itemdetailpage.js @@ -554,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); @@ -666,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 @@ -2116,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 a58917f22..b58000adc 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 2b11071c7..e86f08ca6 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 84ceec6a1..4dfe23e7a 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 38985fb4d..9748da62d 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 98e087147..5f341d3e3 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 e839d29b1..590b204b2 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 a3c362d35..580f30bce 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 8b87dff26..14a231a34 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 aaa71395e..29d21b077 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 555e34c5b..390c3a616 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); diff --git a/src/controllers/shows/episodes.js b/src/controllers/shows/episodes.js index 792eab88a..bd7823d40 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/tvrecommended.js b/src/controllers/shows/tvrecommended.js index d1adb0434..4427d3fa7 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 95d027d77..0f992fe8d 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 249d932d3..816717edf 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 3b85cb1d8..d0ff4edd0 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 f6a5aaf00..45a8798e4 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 38418f519..0965e9189 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 ec80679f8..b93d1d662 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 333c09f26..54f5a8a94 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 eeb9b25e3..8ceb46c5e 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 270953b24..32f2bf933 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 a19ce571e..b3ee4db15 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/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/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 0f34e5ba3..6eaf0252f 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -26,9 +26,9 @@
-
+
-
+
"; + 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 3c80063f4..a95b750b1 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 bc8908fe6..9f8ec00ad 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/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 9c3db58a7..72c67e5b7 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 03ceb346a..6f0975e98 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 d757dd808..072e3f306 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 4b1b658e9..8279c162f 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 337c2f140..5d5062c39 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -371,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); define("lazyLoader", [componentsPath + "/lazyloader/lazyloader-intersectionobserver"], returnFirstDependency); define("shell", [componentsPath + "/shell"], returnFirstDependency); @@ -416,9 +417,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 () { @@ -556,7 +554,7 @@ var AppInfo = {}; require(["playerSelectionMenu", "components/playback/remotecontrolautoplay"]); } - require(["components/screensavermanager"]); + require(["libraries/screensavermanager"]); if (!appHost.supports("physicalvolumecontrol") || browser.touch) { require(["components/playback/volumeosd"]); @@ -648,7 +646,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", @@ -702,6 +700,7 @@ var AppInfo = {}; onError: onRequireJsError }); + require(["fetch"]); require(["polyfill"]); require(["fast-text-encoding"]); require(["intersection-observer"]); @@ -753,8 +752,8 @@ var AppInfo = {}; // TODO remove these libraries // all of these have been modified so we need to fix that first - 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); @@ -794,7 +793,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); @@ -816,7 +815,7 @@ 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); @@ -846,8 +845,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); @@ -865,8 +863,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 f9774167c..6159ad9fe 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 6ac71790f..7cbaab20d 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 ab4cfcb93..8357a9c8d 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": "Сянка", @@ -878,5 +878,30 @@ "BoxRear": "Комплект (стар)", "BoxSet": "Комплект", "AuthProviderHelp": "Избор на доставчик на услуга за Автентификация, която ще се използва за автентификация на потребителската парола.", - "AllowedRemoteAddressesHelp": "Списък с IP адреси или IP/маска записи, разделени със запетая, които ще имат отдалечен достъп. Ако полето не е попълнено всички адреси ще имат отдалечен достъп." + "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/cs.json b/src/strings/cs.json index fc6abce2e..b7f2f7b9d 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -1603,5 +1603,6 @@ "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.", - "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." + "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 3b8f4f13d..a2b4cb6a4 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", @@ -1539,7 +1539,7 @@ "Album": "Album", "EveryHour": "Hver time", "EveryXMinutes": "Hvert {0} minut", - "OnWakeFromSleep": "Når du vågner fra søvn", + "OnWakeFromSleep": "Ved vækning fra dvale", "WeeklyAt": "{0}s ved {1}", "DailyAt": "Dagligt kl. {0}", "LastSeen": "Sidst set {0}", @@ -1585,7 +1585,7 @@ "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", + "LaunchWebAppOnStartup": "Åben webinterfacet når serveren startes", "LabelWeb": "Web:", "LabelVideoResolution": "Videoopløsning:", "LabelVideoBitrate": "Video bitrate:", @@ -1633,9 +1633,11 @@ "ClientSettings": "Klient Indstillinger", "ButtonSplit": "Opdel", "BoxSet": "Box Set", - "AuthProviderHelp": "Vælg en godkendelse udbyder, der skal bruges til at godkende denne brugers adgangskode.", + "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" + "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/el.json b/src/strings/el.json index 3856480fd..480492836 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 bca865ff6..5e5753671 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 a44dece13..9895bbc05 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:", @@ -1335,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.", diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 44ddbbf30..69c571a57 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -499,5 +499,6 @@ "HeaderDeleteItems": "Eliminar ítems", "HeaderDeleteItem": "Eliminar ítem", "HeaderDeleteDevice": "Eliminar dispositivo", - "HeaderDefaultRecordingSettings": "Ajustes de grabación por defecto" + "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 5a2ad1ea9..4b090997d 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1508,5 +1508,7 @@ "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." + "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 cf2ef80be..f244a2587 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -106,7 +106,7 @@ "TabProfiles": "پروفایل ها", "TabShows": "سریال ها", "TabSongs": "آهنگ ها", - "TabSuggestions": "پیشنهادات", + "TabSuggestions": "پیشنهادها", "TabUpcoming": "بزودی", "TellUsAboutYourself": "در مورد خودتان به ما بگویید", "ThisWizardWillGuideYou": "این عمل برای انجام تنظیمات به شما کمک می‌کند. برای شروع، لطفا زبان مورد نظر خود را انتخاب کنید.", @@ -163,7 +163,7 @@ "ButtonNextTrack": "ترانه پسین", "ButtonPreviousTrack": "ترانه پیشین", "ButtonPause": "مکث", - "ButtonParentalControl": "کنترل والدین", + "ButtonParentalControl": "رتبه بندی والدین", "ButtonOpen": "باز", "ButtonOff": "خاموش", "ButtonNetwork": "شبکه", @@ -613,5 +613,62 @@ "AlwaysPlaySubtitlesHelp": "زیرنویس‌های متناسب با توجه به اولویت زبان بدون در نظر گرفتن زبان صوتی ویدیو پخش می شوند.", "AllowedRemoteAddressesHelp": "لیستی از آدرس های IP یا ورودی‌های IP/‌netmask برای شبکه هایی که به آنها امکان ارتباط از راه دور داده می‌شود ، با کاما از هم جدا شدند. در صورت خالی ماندن ، تمام آدرسهای راه دور مجاز خواهند بود.", "AllowOnTheFlySubtitleExtractionHelp": "زیرنویس های جاسازی شده را می‌توان از فیلم‌ها استخراج کرد و به منظور جلوگیری از کدگذاری فیلم ، به صورت متن ساده به بازدید کننده ارسال کرد. در بعضی از سیستم‌ها این می‌تواند مدت زیادی طول بکشد و باعث شود پخش فیلم در طول فرآیند استخراج متوقف شود. این گزینه را غیرفعال کنید تا زیرنویس‌های جاسازی شده با استفاده از رمزگذاری ویدیو در حالی که به طور محلی توسط دستگاه بازدیدکننده پشتیبانی نمی‌شوند ارسال شود.", - "AdditionalNotificationServices": "برای نصب سرویس‌های اعلان اضافی، در فروشگاه افزونه‌ها جستجو کنید." + "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 b915aefd3..8f3c5fb6e 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 87ad75526..3f1d22c75 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", @@ -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": "Tentatives de connexion échouées avant que l'utilisateur ne soit verrouillé:", + "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é", @@ -1465,8 +1465,8 @@ "LabelCorruptedFrames": "Images corrompues :", "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", + "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", @@ -1502,5 +1502,10 @@ "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.", "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." + "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 0eafd988f..2015201c7 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": "סיימת!", @@ -282,7 +282,7 @@ "MessageItemsAdded": "פריטים נוספו.", "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": "אוטומטי", @@ -531,7 +531,7 @@ "AlwaysPlaySubtitles": "הפעל תמיד", "AllowRemoteAccessHelp": "אם לא מסומן, כל החיבורים המרוחקים ייחסמו.", "AllowRemoteAccess": "אפשר חיבור מרוחק לשרת Jellyfin זה.", - "AllowMediaConversionHelp": "אפשר או חסום גישה להמרת מדיה.", + "AllowMediaConversionHelp": "הענק או דחה גישה להמרת מדיה.", "Aired": "שודר", "AirDate": "תאריך שידור", "Yesterday": "אתמול", @@ -549,7 +549,7 @@ "AllowOnTheFlySubtitleExtraction": "אפשר חילוץ כתוביות בזמן אמת", "AllowHWTranscodingHelp": "אפשר למלקט לקודד הזרמות בזמן אמת. זה עשוי לעזור בהפחתת הקידוד שנעשה ע\"י השרת.", "AllComplexFormats": "כל הפורמטים המורכבים (ASS, SSA, VOBSUB, PGS, SUB/IDX)", - "AddItemToCollectionHelp": "הוסף חפצים לאוסף על ידי חיפוש שלהם ולחיצה על כפתור ימני בעכבר או כפתור התפריט כדי להוסיף לאוסף.", + "AddItemToCollectionHelp": "הוסף חפצים לאוסף על ידי חיפושם ושימוש בתפריט הלחצן הימני או לחצן התפריט כדי להוסיפם לאוסף.", "Songs": "שירים", "Shows": "סדרות", "DownloadsValue": "{0} הורדות", @@ -761,5 +761,14 @@ "Artist": "אמן", "AllowedRemoteAddressesHelp": "רשימת IP \\ מיסוך רשת המופרדת בפסיקים עבור רשתות שיורשו להתחבר מרחוק. במידה ותישאר ריקה, כל הכתובות יורשו להתחבר.", "Album": "אלבום", - "AlbumArtist": "אמן האלבום" + "AlbumArtist": "אמן האלבום", + "LabelSortOrder": "מיין סדר:", + "ShowYear": "הצג שנה", + "ShowTitle": "הצג כותרת", + "DropShadow": "הפעל צל", + "Playlists": "רשימות הפעלה", + "Raised": "מורם", + "LabelSpecialSeasonsDisplayName": "שם תצוגת \"עונה מיוחדת\":", + "LabelSource": "מקור:", + "LabelSoundEffects": "אפקטי סאונד:" } diff --git a/src/strings/hu.json b/src/strings/hu.json index a8f35831a..5dc7f0282 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -1506,5 +1506,10 @@ "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!" + "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 0f9cee571..8f54f4b41 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -1501,5 +1501,7 @@ "AlbumArtist": "Artisti dell'Album", "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." + "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 4a15d798c..0f90a05c4 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 144fb007b..a31d2b375 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,7 +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.", + "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": "" + "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 7e6f36b84..9e0bd4260 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": "보통", @@ -1378,7 +1378,7 @@ "LabelDefaultScreen": "기본 화면:", "LabelDateTimeLocale": "날짜/시간 로케일:", "XmlTvPathHelp": "XMLTV 파일을 저장할 경로를 설정합니다. Jellyfin은 이 파일을 읽어 주기적으로 변경 사항을 확인합니다. 파일 생성 및 파일 업데이트는 사용자가 수동으로 해야 합니다.", - "MessageTheFollowingLocationWillBeRemovedFromLibrary": "다음과 같은 미디어 장소들을 라이브러리에서 제거합니다:", + "MessageTheFollowingLocationWillBeRemovedFromLibrary": "다음과 같은 미디어 저장소들을 라이브러리에서 제거합니다:", "MessageReenableUser": "재활성화는 아래를 참조하십시오", "MessagePluginConfigurationRequiresLocalAccess": "이 플러그인을 구성하려면 로컬 서버에 직접 로그인하십시오.", "MessageNoCollectionsAvailable": "컬렉션을 사용하면 영화, 시리즈 및 앨범의 개인화 된 그룹을 즐길 수 있습니다. + 버튼을 클릭하여 컬렉션 만들기를 시작합니다.", @@ -1398,16 +1398,34 @@ "Artist": "아티스트", "AlbumArtist": "앨범 아티스트", "Album": "앨범", - "NoCreatedLibraries": "라이브러리가 없는 것 같습니다. {0}지금 당장 하나 만드시겠습니까?{1}", - "NewCollectionHelp": "컬렉션을 통해 사용자 정의로 영화와 같은 콘텐츠들을 묶어놓을 수 있습니다.", - "Never": "절대 아님", + "NoCreatedLibraries": "라이브러리가 없습니다. {0}지금 생성하겠습니까?{1}", + "NewCollectionHelp": "영화 및 다른 라이브러리 콘텐츠들을 묶어 개인화된 컬렉션을 구성할 수 있습니다.", + "Never": "항상 안 함", "Movie": "영화", "MoveRight": "오른쪽으로 이동", "MoveLeft": "왼쪽으로 이동", - "MoreFromValue": "{0} 에서", - "MetadataSettingChangeHelp": "변환된 메타데이터 설정은 새롭게 들어오는 콘텐츠에 적용이 됩니다. 기존의 콘텐츠에도 적용을 하려면 상세 스크린을 열어 새로 고침 버튼을 누르거나 메타데이터 메니저를 통해 대량으로 새로 고침을 하면 됩니다.", - "MessagePluginInstallDisclaimer": "Jellyfin 커뮤니티에서 만들어진 플러그인들은 Jellyfin의 기능들과 편리성을 향상시켜줄 수 있습니다. 하지만 설치하기 전에 이런 플러그인들은 라이브러리 스켄 속도 저하, 추가된 백그라운드 프로세싱 그리고 시스템의 불안정성같은 문제점들을 Jellyfin 서버에 일으킬 수도 있다는 것을 유념하시기 바람니다.", - "LabelLibraryPageSizeHelp": "라이브러리 페이지에 표시될 아이템들의 수를 조절합니다. 0 으로 지정시 페이징을 비활성화 합니다.", + "MoreFromValue": "{0} 에서 더 자세히", + "MetadataSettingChangeHelp": "변경된 메타데이터 설정은 새 콘텐츠에 적용됩니다. 기존의 콘텐츠에 적용하려면 상세 화면에서 새로 고침 버튼을 누르거나 메타데이터 매니저를 통해 일괄적으로 새로 고침을 수행하십시오.", + "MessagePluginInstallDisclaimer": "Jellyfin 커뮤니티에서 만들어진 플러그인은 Jellyfin의 기능과 편의성을 향상시킬 수 있습니다. 다만 이러한 플러그인은 라이브러리 스캔 속도 저하, 추가 백그라운드 프로세싱, 시스템 불안정과 같은 문제를 야기할 수 있다는 것을 유념하시기 바랍니다.", + "LabelLibraryPageSizeHelp": "라이브러리 페이지에 표시될 항목 수를 조절합니다. 0으로 지정 시 페이징을 비활성화합니다.", "LabelLibraryPageSize": "라이브러리 페이지 크기:", - "LabelEnableBlastAliveMessages": "서버 활성화 메세지" + "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/nl.json b/src/strings/nl.json index 234cab9f0..06bd4ca22 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -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:", @@ -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:", @@ -673,7 +673,7 @@ "LabelParentNumber": "Bovenliggend nummer:", "LabelParentalRating": "Kijkwijzer classificatie:", "LabelPassword": "Wachtwoord:", - "LabelPasswordConfirm": "Wachtworod (Bevestig)", + "LabelPasswordConfirm": "Wachtwoord (Bevestig):", "LabelPasswordRecoveryPinCode": "Pincode:", "LabelPath": "Pad:", "LabelPersonRole": "Rol:", @@ -682,7 +682,7 @@ "LabelPlayDefaultAudioTrack": "Standaard audio spoor afspelen ongeacht de taal", "LabelPlaylist": "Afspeellijst:", "LabelPostProcessor": "Nabewerkings- toepassing:", - "LabelPostProcessorArguments": "Nabewerkings command line argumenten:", + "LabelPostProcessorArguments": "Nabewerkings command lijn argumenten:", "LabelPostProcessorArgumentsHelp": "Gebruik {path} als het pad naar het opnamebestand.", "LabelPreferredDisplayLanguage": "Voorkeur weergavetaal:", "LabelPreferredDisplayLanguageHelp": "Vertaling van Jellyfin is een voortdurend project.", @@ -702,7 +702,7 @@ "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": "Ververs-modus", + "LabelRefreshMode": "Ververs-modus:", "LabelReleaseDate": "Uitgave datum:", "LabelRemoteClientBitrateLimit": "Internet streaming bitrate limiet (Mbps):", "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.", @@ -746,7 +746,7 @@ "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:", @@ -828,7 +828,7 @@ "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}.", "MessageDirectoryPickerLinuxInstruction": "Voor Linux op Arch Linux, CentOS, Debian, Fedora, openSUSE, of Ubuntu, moet u de service-gebruiker ten minste leestoegang tot uw opslaglocaties verlenen.", @@ -888,7 +888,7 @@ "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", @@ -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", @@ -1327,8 +1327,8 @@ "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", @@ -1442,7 +1442,7 @@ "MediaInfoRefFrames": "Ref beeld", "MediaInfoSoftware": "Software", "MessageImageFileTypeAllowed": "Alleen JPEG en PNG bestanden worden ondersteund.", - "MessageImageTypeNotSelected": "Selecteer alstublieft een afbeelding type van het menu.", + "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 door middel van het automatisch ontdekken van een server.", "Metadata": "Metadata", @@ -1496,5 +1496,22 @@ "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:" + "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 32e9a9798..431ea3feb 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 5e307b653..6a808d090 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -1463,7 +1463,7 @@ "CopyStreamURLError": "Houve um erro ao copiar a URL.", "ButtonSplit": "Dividir", "AskAdminToCreateLibrary": "Peça a um administrador para criar uma biblioteca.", - "AllowFfmpegThrottling": "Ajuste de transcodificação", + "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:", diff --git a/src/strings/pt.json b/src/strings/pt.json index 290bb1524..4bf559134 100644 --- a/src/strings/pt.json +++ b/src/strings/pt.json @@ -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,13 +1119,13 @@ "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.", + "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", @@ -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.", @@ -1332,7 +1332,7 @@ "LabelDeinterlaceMethod": "Método de desentrelaçamento:", "DeinterlaceMethodHelp": "Selecione o método de desentrelaçamento para converter conteúdo entrelaçado.", "Movie": "Filme", - "LabelLibraryPageSize": "", + "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", @@ -1349,21 +1349,21 @@ "OptionDownloadMenuImage": "Menu", "OptionDownloadLogoImage": "Logotipo", "OptionDownloadBannerImage": "Encarte", - "OptionDisplayFolderViewHelp": "Exibir de pastas ao lado das bibliotecas. Isto pode ser útil para visualização em pasta simples.", - "OptionDisplayFolderView": "Exibir em pastas", + "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": "acima", + "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": "Artista do Álbum", + "AlbumArtist": "Álbum do Artista", "Quality": "Qualidade", "Previous": "Anterior", "PreferredNotRequired": "Preferível, mas não obrigatório", @@ -1386,5 +1386,13 @@ "RememberMe": "Lembrar-me", "ReleaseDate": "Data do lançamento", "RefreshMetadata": "Atualizar metadados", - "RecentlyWatched": "Visto recentemente" + "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 4da3ddde4..c27996ec4 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -1499,5 +1499,8 @@ "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ă:" + "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 6d88e3ea8..161157275 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -83,7 +83,7 @@ "ButtonGuide": "Телегид", "ButtonHelp": "Справка", "ButtonHome": "Главное", - "ButtonInfo": "Инфо...", + "ButtonInfo": "Инфо", "ButtonLearnMore": "Подробнее", "ButtonLibraryAccess": "Доступ к медиатеке", "ButtonManualLogin": "Войти вручную", @@ -96,7 +96,7 @@ "ButtonOpen": "Открыть", "ButtonParentalControl": "Родительский контроль", "ButtonPause": "Пауза", - "ButtonPlay": "Воспр.", + "ButtonPlay": "Воспроизведение", "ButtonPreviousTrack": "Предыдущая дорожка", "ButtonProfile": "Профиль", "ButtonQuickStartGuide": "Руководство по запуску", @@ -127,6 +127,8 @@ "ButtonStop": "Остановить", "ButtonSubmit": "Подтвердить", "ButtonSubtitles": "Субтитры", + "ButtonToggleContextMenu": "Ещё", + "ButtonTogglePlaylist": "Плей-лист", "ButtonTrailer": "Трейлер", "ButtonUninstall": "Удалить", "ButtonUp": "Вверх", @@ -203,8 +205,8 @@ "EditImages": "Править изображения", "EditMetadata": "Править метаданные", "EditSubtitles": "Править субтитры", - "EnableBackdrops": "Задники", - "EnableBackdropsHelp": "Задники будут отображаются фоном на некоторых страницах при просмотре медиатеки.", + "EnableBackdrops": "Фоны", + "EnableBackdropsHelp": "Фоны будут отображаются на заднем плане на некоторых страницах при просмотре медиатеки.", "EnableCinemaMode": "Режим кинозала", "EnableColorCodedBackgrounds": "Обозначеннные цветом фоны", "EnableDisplayMirroring": "Дублирование отображения", @@ -215,7 +217,7 @@ "EnableNextVideoInfoOverlayHelp": "В конце видео отображать информацию о последующем видео в текущем плей-листе.", "EnablePhotos": "Отображать фотографии", "EnablePhotosHelp": "Изображения будут обнаруживаться и отображаться наряду с другими медиафайлами.", - "EnableStreamLooping": "Автоциклирование трансляций", + "EnableStreamLooping": "Зацикливание трансляций", "EnableStreamLoopingHelp": "Включайте, если трансляции содержат данные только на несколько секунд и необходимо непрерывно их запрашивать. Включение этого без необходимости может породить проблемы.", "EnableThemeSongs": "Тематические композиции", "EnableThemeSongsHelp": "Воспроизведение тематических композиций в фоновом режиме при навигации по медиатеке.", @@ -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": "Обрабатывается обратным прокси", @@ -404,7 +406,7 @@ "HeaderPeople": "Люди", "HeaderPhotoAlbums": "Фотоальбомы", "HeaderPinCodeReset": "Сброс PIN-кода", - "HeaderPlayAll": "Воспр. все", + "HeaderPlayAll": "Воспроизвести все", "HeaderPlayOn": "Воспроизведение", "HeaderPlayback": "Воспроизведение медиаданных", "HeaderPlaybackError": "Ошибка воспроизведения", @@ -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,11 +858,11 @@ "ManageLibrary": "Управление медиатекой", "ManageRecording": "Управлять записью", "MapChannels": "Сопоставить каналы", - "MarkPlayed": "Отметить как воспр-ое", - "MarkUnplayed": "Отметить как невоспр-ое", + "MarkPlayed": "Отметить как воспроизведенное", + "MarkUnplayed": "Отметить как невоспроизведенное", "MaxParentalRatingHelp": "Содержание с более высокой возр. категорией будет скрыто от этого пользователя.", "MediaInfoAnamorphic": "Анаморфность", - "MediaInfoAspectRatio": "Соот-ие сторон", + "MediaInfoAspectRatio": "Соотношение сторон", "MediaInfoBitDepth": "Глубина цвета", "MediaInfoBitrate": "Поток. ск-ть", "MediaInfoChannels": "Каналы", @@ -880,7 +882,7 @@ "MediaInfoProfile": "Профиль", "MediaInfoRefFrames": "Опорные кадры", "MediaInfoResolution": "Разрешение", - "MediaInfoSampleRate": "Ч-та дискр-ии", + "MediaInfoSampleRate": "Частота дискретизации", "MediaInfoSize": "Размер", "MediaInfoTimestamp": "Метка времени", "MediaIsBeingConverted": "Медиаданные преобразуются в формат, совместимый с устройством, которое воспроизводит эти медиаданные.", @@ -1003,7 +1005,7 @@ "OptionBlockMusic": "Музыка", "OptionBlockTrailers": "Трейлеры", "OptionBlockTvShows": "ТВ-передачи", - "OptionBluray": "BluRay", + "OptionBluray": "Blu-ray", "OptionCommunityRating": "Пользовательский рейтинг", "OptionContinuing": "Продолжающееся", "OptionCriticRating": "Оценка критиков", @@ -1020,7 +1022,7 @@ "OptionDisplayFolderView": "Отображать аспект Папки для просмотра обычных медиапапок", "OptionDisplayFolderViewHelp": "Отображение аспекта \"Папки\" рядом с другими вашими медиатеками. Это может быть полезно, если вы хотите вид обычных папок.", "OptionDownloadArtImage": "Виньетка", - "OptionDownloadBackImage": "Задник", + "OptionDownloadBackImage": "Фон", "OptionDownloadBannerImage": "Баннер", "OptionDownloadBoxImage": "DVD-бокс", "OptionDownloadDiscImage": "Диск", @@ -1113,7 +1115,7 @@ "PackageInstallCancelled": "Установка {0} (версия {1}) отменена.", "PackageInstallCompleted": "Установка {0} (версия {1}) завершена.", "PackageInstallFailed": "Установка {0} (версия {1}) неудачна.", - "ParentalRating": "Возр. кат-ия", + "ParentalRating": "Возрастная категория", "PasswordMatchError": "Пароль и подтверждение пароля должны совпадать.", "PasswordResetComplete": "Пароль был сброшен.", "PasswordResetConfirmation": "Вы действительно хотите сбросить пароль?", @@ -1126,10 +1128,10 @@ "PinCodeResetComplete": "PIN-код был сброшен.", "PinCodeResetConfirmation": "Вы действительно хотите сбросить PIN-код?", "PlaceFavoriteChannelsAtBeginning": "Разместить избранные каналы в начале", - "Play": "Воспр.", - "PlayAllFromHere": "Воспр. все отсюда", + "Play": "Воспроизведение", + "PlayAllFromHere": "Воспроизвести все отсюда", "PlayCount": "Кол. воспроизведений", - "PlayFromBeginning": "Воспр. с начала", + "PlayFromBeginning": "Воспроизвести с начала", "PlayNext": "Воспроизвести следующее", "PlayNextEpisodeAutomatically": "Воспроизводить последующий эпизод автоматически", "Played": "Воспроизведено", @@ -1221,6 +1223,8 @@ "ShowYear": "Отображать год", "Shows": "Передачи", "Shuffle": "Перемешать", + "New": "Новинка", + "Filter": "Фильтр", "SimultaneousConnectionLimitHelp": "Максимальное количество разрешённых одновременных потоков. Введите 0, чтобы снять ограничения.", "SkipEpisodesAlreadyInMyLibrary": "Не записывать эпизоды, которые уже находятся в моей медиатеке", "SkipEpisodesAlreadyInMyLibraryHelp": "Эпизоды будут сравниваться с помощью номеров сезонов и эпизодов, когда они имеются.", @@ -1258,7 +1262,7 @@ "TabContainers": "Контейнеры", "TabDashboard": "Панель", "TabDevices": "Устройства", - "TabDirectPlay": "Прямое воспр-ие", + "TabDirectPlay": "Прямое воспроизведение", "TabDisplay": "Отображение", "TabEpisodes": "Эпизоды", "TabFavorites": "Избранное", @@ -1436,7 +1440,7 @@ "LabelPlayMethod": "Метод воспроизведения:", "LabelFolder": "Папка:", "LabelBaseUrl": "Базовый URL:", - "LabelBitrate": "Поток. ск-ть:", + "LabelBitrate": "Битрейт:", "LabelAudioSampleRate": "Частота дискретизации аудио:", "LabelAudioCodec": "Аудио кодек:", "LabelAudioChannels": "Аудио каналы:", @@ -1469,7 +1473,7 @@ "PlaybackErrorNoCompatibleStream": "Этот клиент несовместим с медиаданными, а сервер не отправляет медиаданные в совместимом формате.", "AllowFfmpegThrottlingHelp": "Когда перекодирование или переупаковка достаточно далеко опережают текущую позицию воспроизведения, процесс приостанавливается, так что он использует меньше ресурсов. Это наиболее полезно, когда вы редко меняете позиции в видео. Выключите это, если у вас возникли проблемы с воспроизведением.", "OnWakeFromSleep": "При пробуждении ото сна", - "YadifBob": "YADIF Bob", + "YadifBob": "YADIF с удвоением", "OnApplicationStartup": "При запуске приложения", "EveryXHours": "Каждые {0} часов", "EveryHour": "Каждый час", @@ -1491,7 +1495,7 @@ "Artist": "Исполнитель", "AlbumArtist": "Исполнитель альбома", "Album": "Альбом", - "LastSeen": "Последнимй раз был {0}", + "LastSeen": "Последний раз был {0}", "WriteAccessRequired": "Jellyfin Server требуются права на запись в эту папку. Обеспечьте доступ для записи и попробуйте снова.", "PathNotFound": "Путь не может быть найден. Убедитесь, что путь правильный и попробуйте снова.", "ReleaseGroup": "Релиз-группа", @@ -1500,5 +1504,6 @@ "LabelLibraryPageSizeHelp": "Устанавливается количество элементов для отображения на странице медиатеки. Установите 0 для отключения нумерации страниц.", "LabelDeinterlaceMethod": "Метод устранения гребёнки:", "DeinterlaceMethodHelp": "Выберите метод устранения гребёнки, который будет использоваться при перекодировании чересстрочного содержания.", - "UnsupportedPlayback": "Jellyfin не может расшифровать содержимое, защищенное DRM, но в любом случае будет предпринята попытка расшифровки всего содержимого, включая защищенные заголовки. Некоторые файлы могут выглядеть полностью черными из-за шифрования или других неподдерживаемых функций, таких как интерактивные заголовки." + "UnsupportedPlayback": "Jellyfin не может расшифровать содержимое, защищенное DRM, но в любом случае будет предпринята попытка расшифровки всего содержимого, включая защищенные заголовки. Некоторые файлы могут выглядеть полностью черными из-за шифрования или других неподдерживаемых функций, таких как интерактивные заголовки.", + "MessageUnauthorizedUser": "В настоящее время у вас нет доступа к серверу. Пожалуйста, свяжитесь с администратором сервера для получения дополнительной информации." } diff --git a/src/strings/sv.json b/src/strings/sv.json index 7f6e1abc6..d93222199 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 5d6772b75..d69391ce9 100644 --- a/src/strings/tr.json +++ b/src/strings/tr.json @@ -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", @@ -735,5 +735,8 @@ "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çı" + "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 e32272bda..6d7fa3a9f 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 034871138..fd0afb77a 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1505,5 +1505,6 @@ "DeinterlaceMethodHelp": "选择对隔行扫描内容进行转码时所用的反交错方法。", "LabelLibraryPageSize": "媒体库分页阈值:", "LabelLibraryPageSizeHelp": "设置媒体库页面每页要显示的最多媒体个数。设置为 0 以禁用分页。", - "UnsupportedPlayback": "Jellyfin无法解密被DRM保护的内容,但仍然会尝试播放包括受保护内容在内的所有内容。某些文件由于被加密或包含不受支持的特性(如互动标题),在播放时可能显示为黑屏。" + "UnsupportedPlayback": "Jellyfin无法解密被DRM保护的内容,但仍然会尝试播放包括受保护内容在内的所有内容。某些文件由于被加密或包含不受支持的特性(如互动标题),在播放时可能显示为黑屏。", + "MessageUnauthorizedUser": "您目前无权访问服务器。更多有关信息,请与服务器管理员联系。" } diff --git a/webpack.dev.js b/webpack.dev.js index beca8ea4f..d0a8c69b8 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 80d40f345..4405f8f16 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 55d6a104d..8cfc660aa 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" @@ -6513,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"