Compare commits

..

3 Commits

Author SHA1 Message Date
Uruk
aadb5f9f6d refactor(app): rename default function components
Renames default function components to PascalCase for consistency.

This change improves code readability and adheres to React component naming conventions.
2026-02-24 14:58:45 +01:00
Uruk
bc3e8dd9ed chore: update biome to v2.4.4
updates the biome linter and formatter to the latest version

this ensures that the project benefits from the newest features
and bug fixes in biome.
2026-02-24 14:58:30 +01:00
Gallyam Biktashev
479e23f001 fix(i18n): Update transalation for Russian lang (#1427)
Some checks failed
🏗️ Build Apps / 🤖 Build Android APK (Phone) (push) Has been cancelled
🏗️ Build Apps / 🤖 Build Android APK (TV) (push) Has been cancelled
🏗️ Build Apps / 🍎 Build iOS IPA (Phone) (push) Has been cancelled
🏗️ Build Apps / 🍎 Build iOS IPA (Phone - Unsigned) (push) Has been cancelled
🔒 Lockfile Consistency Check / 🔍 Check bun.lock and package.json consistency (push) Has been cancelled
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (actions) (push) Has been cancelled
🛡️ CodeQL Analysis / 🔎 Analyze with CodeQL (javascript-typescript) (push) Has been cancelled
🏷️🔀Merge Conflict Labeler / 🏷️ Labeling Merge Conflicts (push) Has been cancelled
🌐 Translation Sync / sync-translations (push) Has been cancelled
🚦 Security & Quality Gate / 📝 Validate PR Title (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Vulnerable Dependencies (push) Has been cancelled
🚦 Security & Quality Gate / 🚑 Expo Doctor Check (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (check) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (format) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (lint) (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (typecheck) (push) Has been cancelled
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-21 18:51:01 +01:00
27 changed files with 355 additions and 368 deletions

View File

@@ -16,7 +16,7 @@ export interface MenuLink {
icon: string;
}
export default function menuLinks() {
export default function MenuLinks() {
const [api] = useAtom(apiAtom);
const insets = useSafeAreaInsets();
const [menuLinks, setMenuLinks] = useState<MenuLink[]>([]);

View File

@@ -1,10 +1,9 @@
import { useCallback, useState } from "react";
import { Platform, RefreshControl, ScrollView, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Favorites } from "@/components/home/Favorites";
import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache";
export default function favorites() {
export default function Favorites() {
const invalidateCache = useInvalidatePlaybackProgressCache();
const [loading, setLoading] = useState(false);

View File

@@ -20,7 +20,7 @@ import { OfflineModeProvider } from "@/providers/OfflineModeProvider";
import { queueAtom } from "@/utils/atoms/queue";
import { writeToLog } from "@/utils/log";
export default function page() {
export default function Page() {
const navigation = useNavigation();
const { t } = useTranslation();
const [_queue, _setQueue] = useAtom(queueAtom);

View File

@@ -23,7 +23,7 @@ import { formatBitrate } from "@/utils/bitrate";
import { getPrimaryImageUrl } from "@/utils/jellyfin/image/getPrimaryImageUrl";
import { formatTimeString } from "@/utils/time";
export default function page() {
export default function Page() {
const { sessions, isLoading } = useSessions({} as useSessionsProps);
const { t } = useTranslation();

View File

@@ -14,7 +14,7 @@ import { UserInfo } from "@/components/settings/UserInfo";
import useRouter from "@/hooks/useAppRouter";
import { useJellyfin, userAtom } from "@/providers/JellyfinProvider";
export default function settings() {
export default function Settings() {
const router = useRouter();
const insets = useSafeAreaInsets();
const [_user] = useAtom(userAtom);

View File

@@ -12,7 +12,7 @@ import DisabledSetting from "@/components/settings/DisabledSetting";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
export default function page() {
export default function Page() {
const { settings, updateSettings, pluginSettings } = useSettings();
const user = useAtomValue(userAtom);
const api = useAtomValue(apiAtom);

View File

@@ -11,7 +11,7 @@ import DisabledSetting from "@/components/settings/DisabledSetting";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
export default function page() {
export default function Page() {
const { settings, updateSettings, pluginSettings } = useSettings();
const user = useAtomValue(userAtom);
const api = useAtomValue(apiAtom);

View File

@@ -4,7 +4,7 @@ import DisabledSetting from "@/components/settings/DisabledSetting";
import { JellyseerrSettings } from "@/components/settings/Jellyseerr";
import { useSettings } from "@/utils/atoms/settings";
export default function page() {
export default function Page() {
const { pluginSettings } = useSettings();
const insets = useSafeAreaInsets();

View File

@@ -4,7 +4,7 @@ import DisabledSetting from "@/components/settings/DisabledSetting";
import { KefinTweaksSettings } from "@/components/settings/KefinTweaks";
import { useSettings } from "@/utils/atoms/settings";
export default function page() {
export default function Page() {
const { pluginSettings } = useSettings();
const insets = useSafeAreaInsets();

View File

@@ -18,7 +18,7 @@ import DisabledSetting from "@/components/settings/DisabledSetting";
import { useNetworkAwareQueryClient } from "@/hooks/useNetworkAwareQueryClient";
import { useSettings } from "@/utils/atoms/settings";
export default function page() {
export default function Page() {
const navigation = useNavigation();
const { t } = useTranslation();

View File

@@ -17,7 +17,7 @@ import { ListItem } from "@/components/list/ListItem";
import { useNetworkAwareQueryClient } from "@/hooks/useNetworkAwareQueryClient";
import { useSettings } from "@/utils/atoms/settings";
export default function page() {
export default function Page() {
const { t } = useTranslation();
const navigation = useNavigation();
const insets = useSafeAreaInsets();

View File

@@ -13,7 +13,7 @@ import {
} from "@/utils/jellyseerr/server/models/Search";
import { COMPANY_LOGO_IMAGE_FILTER } from "@/utils/jellyseerr/src/components/Discover/NetworkSlider";
export default function page() {
export default function Page() {
const local = useLocalSearchParams();
const { jellyseerrApi, isJellyseerrMovieOrTvResult } = useJellyseerr();

View File

@@ -9,7 +9,7 @@ import JellyseerrPoster from "@/components/posters/JellyseerrPoster";
import { Endpoints, useJellyseerr } from "@/hooks/useJellyseerr";
import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover";
export default function page() {
export default function Page() {
const local = useLocalSearchParams();
const { jellyseerrApi, isJellyseerrMovieOrTvResult } = useJellyseerr();

View File

@@ -11,7 +11,7 @@ import JellyseerrPoster from "@/components/posters/JellyseerrPoster";
import { useJellyseerr } from "@/hooks/useJellyseerr";
import type { PersonCreditCast } from "@/utils/jellyseerr/server/models/Person";
export default function page() {
export default function Page() {
const local = useLocalSearchParams();
const { t } = useTranslation();

View File

@@ -8,7 +8,7 @@ import { ItemImage } from "@/components/common/ItemImage";
import { Text } from "@/components/common/Text";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
export default function page() {
export default function Page() {
const [api] = useAtom(apiAtom);
const [user] = useAtom(userAtom);
const _insets = useSafeAreaInsets();

View File

@@ -17,7 +17,7 @@ const ITEMS_PER_PAGE = 20;
const MemoizedLiveTVGuideRow = React.memo(LiveTVGuideRow);
export default function page() {
export default function Page() {
const [api] = useAtom(apiAtom);
const [user] = useAtom(userAtom);
const insets = useSafeAreaInsets();

View File

@@ -7,7 +7,7 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
import { ScrollingCollectionList } from "@/components/home/ScrollingCollectionList";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
export default function page() {
export default function Page() {
const [api] = useAtom(apiAtom);
const [user] = useAtom(userAtom);
const insets = useSafeAreaInsets();

View File

@@ -2,7 +2,7 @@ import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { Text } from "@/components/common/Text";
export default function page() {
export default function Page() {
const { t } = useTranslation();
return (
<View className='flex items-center justify-center h-full -mt-12'>

View File

@@ -15,7 +15,7 @@ import { LibraryItemCard } from "@/components/library/LibraryItemCard";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
export default function index() {
export default function Index() {
const [api] = useAtom(apiAtom);
const [user] = useAtom(userAtom);
const queryClient = useQueryClient();

View File

@@ -55,7 +55,7 @@ const exampleSearches = [
"The Mandalorian",
];
export default function search() {
export default function Search() {
const params = useLocalSearchParams();
const insets = useSafeAreaInsets();
const router = useRouter();

View File

@@ -58,7 +58,7 @@ import { writeToLog } from "@/utils/log";
import { generateDeviceProfile } from "@/utils/profiles/native";
import { msToTicks, ticksToSeconds } from "@/utils/time";
export default function page() {
export default function Page() {
const videoRef = useRef<MpvPlayerViewRef>(null);
const user = useAtomValue(userAtom);
const api = useAtomValue(apiAtom);

View File

@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.11/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.4/schema.json",
"files": {
"includes": [
"**/*",

View File

@@ -88,7 +88,7 @@
"react-native-uuid": "^2.0.3",
"react-native-volume-manager": "^2.0.8",
"react-native-web": "^0.21.0",
"react-native-worklets": "0.7.4",
"react-native-worklets": "0.5.1",
"sonner-native": "0.21.2",
"tailwindcss": "3.3.2",
"use-debounce": "^10.0.4",
@@ -96,7 +96,7 @@
},
"devDependencies": {
"@babel/core": "7.28.6",
"@biomejs/biome": "2.3.11",
"@biomejs/biome": "2.4.4",
"@react-native-community/cli": "20.1.1",
"@react-native-tvos/config-tv": "0.1.4",
"@types/jest": "29.5.14",
@@ -258,7 +258,7 @@
"@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
"@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg=="],
"@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
"@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
@@ -308,23 +308,23 @@
"@babel/types": ["@babel/types@7.28.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg=="],
"@biomejs/biome": ["@biomejs/biome@2.3.11", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.11", "@biomejs/cli-darwin-x64": "2.3.11", "@biomejs/cli-linux-arm64": "2.3.11", "@biomejs/cli-linux-arm64-musl": "2.3.11", "@biomejs/cli-linux-x64": "2.3.11", "@biomejs/cli-linux-x64-musl": "2.3.11", "@biomejs/cli-win32-arm64": "2.3.11", "@biomejs/cli-win32-x64": "2.3.11" }, "bin": { "biome": "bin/biome" } }, "sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ=="],
"@biomejs/biome": ["@biomejs/biome@2.4.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.4", "@biomejs/cli-darwin-x64": "2.4.4", "@biomejs/cli-linux-arm64": "2.4.4", "@biomejs/cli-linux-arm64-musl": "2.4.4", "@biomejs/cli-linux-x64": "2.4.4", "@biomejs/cli-linux-x64-musl": "2.4.4", "@biomejs/cli-win32-arm64": "2.4.4", "@biomejs/cli-win32-x64": "2.4.4" }, "bin": { "biome": "bin/biome" } }, "sha512-tigwWS5KfJf0cABVd52NVaXyAVv4qpUXOWJ1rxFL8xF1RVoeS2q/LK+FHgYoKMclJCuRoCWAPy1IXaN9/mS61Q=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA=="],
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-jZ+Xc6qvD6tTH5jM6eKX44dcbyNqJHssfl2nnwT6vma6B1sj7ZLTGIk6N5QwVBs5xGN52r3trk5fgd3sQ9We9A=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg=="],
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dh1a/+W+SUCXhEdL7TiX3ArPTFCQKJTI1mGncZNWfO+6suk+gYA4lNyJcBB+pwvF49uw0pEbUS49BgYOY4hzUg=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g=="],
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-V/NFfbWhsUU6w+m5WYbBenlEAz8eYnSqRMDMAW3K+3v0tYVkNyZn8VU0XPxk/lOqNXLSCCrV7FmV/u3SjCBShg=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg=="],
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+sPAXq3bxmFwhVFJnSwkSF5Rw2ZAJMH3MF6C9IveAEOdSpgajPhoQhbbAK12SehN9j2QrHpk4J/cHsa/HqWaYQ=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.11", "", { "os": "linux", "cpu": "x64" }, "sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg=="],
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-R4+ZCDtG9kHArasyBO+UBD6jr/FcFCTH8QkNTOCu0pRJzCWyWC4EtZa2AmUZB5h3e0jD7bRV2KvrENcf8rndBg=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.11", "", { "os": "linux", "cpu": "x64" }, "sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw=="],
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gGvFTGpOIQDb5CQ2VC0n9Z2UEqlP46c4aNgHmAMytYieTGEcfqhfCFnhs6xjt0S3igE6q5GLuIXtdQt3Izok+g=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw=="],
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-trzCqM7x+Gn832zZHgr28JoYagQNX4CZkUZhMUac2YxvvyDRLJDrb5m9IA7CaZLlX6lTQmADVfLEKP1et1Ma4Q=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.11", "", { "os": "win32", "cpu": "x64" }, "sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg=="],
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.4", "", { "os": "win32", "cpu": "x64" }, "sha512-gnOHKVPFAAPrpoPt2t+Q6FZ7RPry/FDV3GcpU53P3PtLNnQjBmKyN2Vh/JtqXet+H4pme8CC76rScwdjDcT1/A=="],
"@bottom-tabs/react-navigation": ["@bottom-tabs/react-navigation@1.1.0", "", { "dependencies": { "color": "^5.0.0" }, "peerDependencies": { "@react-navigation/native": ">=7", "react": "*", "react-native": "*", "react-native-bottom-tabs": "*" } }, "sha512-+4YppCodABcSNIgJiq95QUQ+3ClVBG+rLG3WmYI0+/nbxqKbCz6luFBep4KFOj98Iplj1JY2Ki6ix8CcOZVQ/Q=="],
@@ -1708,7 +1708,7 @@
"react-native-web": ["react-native-web@0.21.2", "", { "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", "fbjs": "^3.0.4", "inline-style-prefixer": "^7.0.1", "memoize-one": "^6.0.0", "nullthrows": "^1.1.1", "postcss-value-parser": "^4.2.0", "styleq": "^0.1.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg=="],
"react-native-worklets": ["react-native-worklets@0.7.4", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "7.27.1", "@babel/plugin-transform-class-properties": "7.27.1", "@babel/plugin-transform-classes": "7.28.4", "@babel/plugin-transform-nullish-coalescing-operator": "7.27.1", "@babel/plugin-transform-optional-chaining": "7.27.1", "@babel/plugin-transform-shorthand-properties": "7.27.1", "@babel/plugin-transform-template-literals": "7.27.1", "@babel/plugin-transform-unicode-regex": "7.27.1", "@babel/preset-typescript": "7.27.1", "convert-source-map": "2.0.0", "semver": "7.7.3" }, "peerDependencies": { "@babel/core": "*", "react": "*", "react-native": "*" } }, "sha512-NYOdM1MwBb3n+AtMqy1tFy3Mn8DliQtd8sbzAVRf9Gc+uvQ0zRfxN7dS8ZzoyX7t6cyQL5THuGhlnX+iFlQTag=="],
"react-native-worklets": ["react-native-worklets@0.5.1", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", "@babel/plugin-transform-classes": "^7.0.0-0", "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", "@babel/plugin-transform-optional-chaining": "^7.0.0-0", "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", "@babel/plugin-transform-template-literals": "^7.0.0-0", "@babel/plugin-transform-unicode-regex": "^7.0.0-0", "@babel/preset-typescript": "^7.16.7", "convert-source-map": "^2.0.0", "semver": "7.7.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w=="],
"react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="],
@@ -2216,8 +2216,6 @@
"@react-native/babel-preset/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
"@react-native/babel-preset/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
"@react-native/babel-preset/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
"@react-native/codegen/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
@@ -2440,9 +2438,7 @@
"react-native-web/memoize-one": ["memoize-one@6.0.0", "", {}, "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="],
"react-native-worklets/@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="],
"react-native-worklets/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"react-native-worklets/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"readable-web-to-node-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],

View File

@@ -476,7 +476,6 @@ export const Controls: FC<Props> = ({
{/* Technical Info Overlay - rendered outside animated views to stay visible */}
{getTechnicalInfo && (
<TechnicalInfoOverlay
showControls={showControls}
visible={showTechnicalInfo}
getTechnicalInfo={getTechnicalInfo}
playMethod={playMethod}

View File

@@ -14,7 +14,6 @@ import { HEADER_LAYOUT } from "./constants";
type PlayMethod = "DirectPlay" | "DirectStream" | "Transcode";
interface TechnicalInfoOverlayProps {
showControls: boolean;
visible: boolean;
getTechnicalInfo: () => Promise<TechnicalInfo>;
playMethod?: PlayMethod;
@@ -120,13 +119,7 @@ const formatTranscodeReason = (reason: string): string => {
};
export const TechnicalInfoOverlay: FC<TechnicalInfoOverlayProps> = memo(
({
showControls,
visible,
getTechnicalInfo,
playMethod,
transcodeReasons,
}) => {
({ visible, getTechnicalInfo, playMethod, transcodeReasons }) => {
const { settings } = useSettings();
const insets = useSafeAreaInsets();
const [info, setInfo] = useState<TechnicalInfo | null>(null);

View File

@@ -108,7 +108,7 @@
"react-native-uuid": "^2.0.3",
"react-native-volume-manager": "^2.0.8",
"react-native-web": "^0.21.0",
"react-native-worklets": "0.7.4",
"react-native-worklets": "0.5.1",
"sonner-native": "0.21.2",
"tailwindcss": "3.3.2",
"use-debounce": "^10.0.4",
@@ -116,7 +116,7 @@
},
"devDependencies": {
"@babel/core": "7.28.6",
"@biomejs/biome": "2.3.11",
"@biomejs/biome": "2.4.4",
"@react-native-community/cli": "20.1.1",
"@react-native-tvos/config-tv": "0.1.4",
"@types/jest": "29.5.14",

View File

@@ -34,44 +34,44 @@
"search_for_local_servers": "Поиск локальных серверов",
"searching": "Поиск...",
"servers": "Сервера",
"saved": "Saved",
"session_expired": "Session Expired",
"please_login_again": "Your saved session has expired. Please log in again.",
"remove_saved_login": "Remove Saved Login",
"remove_saved_login_description": "This will remove your saved credentials for this server. You'll need to enter your username and password again next time.",
"accounts_count": "{{count}} accounts",
"select_account": "Select Account",
"add_account": "Add Account",
"remove_account_description": "This will remove the saved credentials for {{username}}."
"saved": "Сохранено",
"session_expired": "Сессия истекла",
"please_login_again": "Ваша сессия истекла. Пожалуйста, войдите снова.",
"remove_saved_login": "Удалить сохраненный аккаунт",
"remove_saved_login_description": "Ваши сохранённые данные для входа от этого сервера будут удалены. Вам придётся ввести ваши логин и пароль ещё раз.",
"accounts_count": "{{count}} аккаунтов",
"select_account": "Выбрать аккаунт",
"add_account": "Добавить аккаунт",
"remove_account_description": "Данные для входа {{username}} будут удалены."
},
"save_account": {
"title": "Save Account",
"save_for_later": "Save this account",
"security_option": "Security Option",
"no_protection": "No protection",
"no_protection_desc": "Quick login without authentication",
"pin_code": "PIN code",
"pin_code_desc": "4-digit PIN required when switching",
"password": "Re-enter password",
"password_desc": "Password required when switching",
"save_button": "Save",
"cancel_button": "Cancel"
"title": "Сохранить аккаунт",
"save_for_later": "Сохранить этот аккаунт",
"security_option": "Опции безопасности",
"no_protection": "Без защиты",
"no_protection_desc": "Быстрый вход без ввода данных",
"pin_code": "PIN-код",
"pin_code_desc": "При переключении будет требоваться 4-значный PIN",
"password": "Пароль",
"password_desc": "При переключении будет требоваться пароль",
"save_button": "Сохранить",
"cancel_button": "Отмена"
},
"pin": {
"enter_pin": "Enter PIN",
"enter_pin_for": "Enter PIN for {{username}}",
"enter_4_digits": "Enter 4 digits",
"invalid_pin": "Invalid PIN",
"setup_pin": "Set Up PIN",
"confirm_pin": "Confirm PIN",
"pins_dont_match": "PINs don't match",
"forgot_pin": "Forgot PIN?",
"forgot_pin_desc": "Your saved credentials will be removed"
"enter_pin": "Введите PIN",
"enter_pin_for": "Введите PIN для {{username}}",
"enter_4_digits": "Введите 4 цифры",
"invalid_pin": "Некорректный PIN",
"setup_pin": "Установить PIN",
"confirm_pin": "Подтвердите PIN",
"pins_dont_match": "PIN-коды не совпадают",
"forgot_pin": "Забыли PIN?",
"forgot_pin_desc": "Ваши данные для входа будут удалены"
},
"password": {
"enter_password": "Enter Password",
"enter_password_for": "Enter password for {{username}}",
"invalid_password": "Invalid password"
"enter_password": "Введите пароль",
"enter_password_for": "Введите пароль для {{username}}",
"invalid_password": "Неверный пароль"
},
"home": {
"checking_server_connection": "Проверка соединения с сервером...",
@@ -82,12 +82,12 @@
"go_to_downloads": "В загрузки",
"retry": "Повторить",
"server_unreachable": "Сервер недоступен",
"server_unreachable_message": "Could not reach the server.\nPlease check your network connection.",
"server_unreachable_message": "Не удалось соединиться с сервером.\nПожалуйста, проверьте настройки сети.",
"oops": "Упс!",
"error_message": "Что-то пошло не так.\nПожалуйста выйдите и зайдите снова.",
"continue_watching": "Продолжить просмотр",
"next_up": "Следующее",
"continue_and_next_up": "Continue & Next Up",
"continue_watching": "Продолжить",
"next_up": "Далее",
"continue_and_next_up": "Продолжить и Далее",
"recently_added_in": "Недавно добавлено в {{libraryName}}",
"suggested_movies": "Предложенные фильмы",
"suggested_episodes": "Предложенные серии",
@@ -110,46 +110,46 @@
"settings_title": "Настройки",
"log_out_button": "Выйти",
"categories": {
"title": "Categories"
"title": "Категории"
},
"playback_controls": {
"title": "Playback & Controls"
"title": "Воспроизведение и управление"
},
"audio_subtitles": {
"title": "Audio & Subtitles"
"title": "Аудио и субтитры"
},
"appearance": {
"title": "Appearance",
"merge_next_up_continue_watching": "Merge Continue Watching & Next Up",
"hide_remote_session_button": "Hide Remote Session Button"
"title": "Внешний вид",
"merge_next_up_continue_watching": "Объединить «Продолжить» и «Далее»",
"hide_remote_session_button": "Скрыть кнопку «Удалённый сеанс»"
},
"network": {
"title": "Network",
"local_network": "Local Network",
"auto_switch_enabled": "Auto-switch when at home",
"auto_switch_description": "Automatically switch to local URL when connected to home WiFi",
"local_url": "Local URL",
"local_url_hint": "Enter your local server address (e.g., http://192.168.1.100:8096)",
"title": "Сеть",
"local_network": "Локальная сеть",
"auto_switch_enabled": "Переключаться дома автоматически",
"auto_switch_description": "Автоматически переключаться на локальный URL при присоединении к домашней WiFi сети",
"local_url": "Локальный URL",
"local_url_hint": "Введите локальный URL вашего сервера (e.g., http://192.168.1.100:8096)",
"local_url_placeholder": "http://192.168.1.100:8096",
"home_wifi_networks": "Home WiFi Networks",
"add_current_network": "Add \"{{ssid}}\"",
"not_connected_to_wifi": "Not connected to WiFi",
"no_networks_configured": "No networks configured",
"add_network_hint": "Add your home WiFi network to enable auto-switching",
"current_wifi": "Current WiFi",
"using_url": "Using",
"local": "Local URL",
"remote": "Remote URL",
"not_connected": "Not connected",
"current_server": "Current Server",
"remote_url": "Remote URL",
"active_url": "Active URL",
"not_configured": "Not configured",
"network_added": "Network added",
"network_already_added": "Network already added",
"no_wifi_connected": "Not connected to WiFi",
"permission_denied": "Location permission denied",
"permission_denied_explanation": "Location permission is required to detect WiFi network for auto-switching. Please enable it in Settings."
"home_wifi_networks": "Домашние WiFi сети",
"add_current_network": "Добавить \"{{ssid}}\"",
"not_connected_to_wifi": "Нет WiFi соединения",
"no_networks_configured": "Нет настроенных сетей",
"add_network_hint": "Добавьте вашу домашнюю сеть WiFi для включения автоматического переключения",
"current_wifi": "Текущая WiFi сеть",
"using_url": "Используется",
"local": "Локальный",
"remote": "Внешний",
"not_connected": "Нет соединения",
"current_server": "Текущий сервер",
"remote_url": "Внешний URL",
"active_url": "Активный URL",
"not_configured": "Не настроено",
"network_added": "Сеть добавлена",
"network_already_added": "Сеть уже добавлена",
"no_wifi_connected": "Нет WiFi соединения",
"permission_denied": "Нет доступа к местоположению",
"permission_denied_explanation": "Разрешение на доступ к местоположению обязательно для обнаружения WiFi сети при автоматическом переключении. Пожалуйста, включите его в настройках."
},
"user_info": {
"user_info_title": "Информация о пользователе",
@@ -170,22 +170,22 @@
},
"media_controls": {
"media_controls_title": "Медиа-контроль",
"forward_skip_length": "Длина пропуска вперед",
"rewind_length": "Длина перемотки",
"forward_skip_length": "Шаг перемотки вперёд",
"rewind_length": "Шаг перемотки назад",
"seconds_unit": "c"
},
"gesture_controls": {
"gesture_controls_title": "Управление жестами",
"horizontal_swipe_skip": "Горизонтальный свайп, чтобы пропустить",
"horizontal_swipe_skip": "Горизонтальный свайп для перемотки",
"horizontal_swipe_skip_description": "Проведите влево/вправо, когда элементы управления скрыты, чтобы пропустить",
"left_side_brightness": "Управление яркостью левой стороны",
"left_side_brightness_description": "Смахните вверх/вниз на левой стороне для настройки яркости",
"right_side_volume": "Управление громкостью справа",
"right_side_volume_description": "Свайп вверх/вниз с правой стороны для настройки громкости",
"hide_volume_slider": "Hide Volume Slider",
"hide_volume_slider_description": "Hide the volume slider in the video player",
"hide_brightness_slider": "Hide Brightness Slider",
"hide_brightness_slider_description": "Hide the brightness slider in the video player"
"hide_volume_slider": "Скрыть индикатор громкости",
"hide_volume_slider_description": "Скрывает индикатор громкости в плеере",
"hide_brightness_slider": "Скрыть индикатор яркости",
"hide_brightness_slider_description": "Скрывает индикатор яркости в плеере"
},
"audio": {
"audio_title": "Аудио",
@@ -195,17 +195,17 @@
"none": "Отсутствует",
"language": "Язык",
"transcode_mode": {
"title": "Audio Transcoding",
"description": "Controls how surround audio (7.1, TrueHD, DTS-HD) is handled",
"auto": "Auto",
"stereo": "Force Stereo",
"5_1": "Allow 5.1",
"passthrough": "Passthrough"
"title": "Перекодировка аудио",
"description": "Управляет обработкой пространственного звука (7.1, TrueHD, DTS-HD)",
"auto": "Авто",
"stereo": "Принудительно в стерео",
"5_1": "Разрешить 5.1",
"passthrough": "Ничего не изменять"
}
},
"subtitles": {
"subtitle_title": "Субтитры",
"subtitle_hint": "Настроить субтитры.",
"subtitle_hint": "Настройки отображения субтитров",
"subtitle_language": "Язык субтитров",
"subtitle_mode": "Режим субтитров",
"set_subtitle_track": "Устанавливать субтитры из предыдущего элемента",
@@ -226,24 +226,24 @@
"outline_thickness": "Толщина контура",
"background_opacity": "Прозрачность фона",
"outline_opacity": "Прозрачность контура",
"bold_text": "Bold Text",
"bold_text": "Жирный",
"colors": {
"Black": "Черный",
"Gray": "Серый",
"Silver": "Серебряный",
"Silver": "Серебристый",
"White": "Белый",
"Maroon": "Марун",
"Maroon": "Бордовый",
"Red": "Красный",
"Fuchsia": "Fuchsia",
"Fuchsia": "Пурпурный",
"Yellow": "Жёлтый",
"Olive": "Олив",
"Olive": "Оливковый",
"Green": "Зелёный",
"Teal": "Бирюзовый",
"Lime": "Лаймовый",
"Purple": "Фиолетовый",
"Navy": "Тёмно-синий",
"Blue": "Синий",
"Aqua": "Акваа"
"Aqua": "Голубой"
},
"thickness": {
"None": "Отсутствует",
@@ -251,29 +251,29 @@
"Normal": "Обычный",
"Thick": "Толстый"
},
"subtitle_color": "Subtitle Color",
"subtitle_background_color": "Background Color",
"subtitle_font": "Subtitle Font",
"ksplayer_title": "KSPlayer Settings",
"hardware_decode": "Hardware Decoding",
"hardware_decode_description": "Use hardware acceleration for video decoding. Disable if you experience playback issues."
"subtitle_color": "Цвет субтитров",
"subtitle_background_color": "Цвет фона",
"subtitle_font": "Шрифт субтитров",
"ksplayer_title": "Настройки KSPlayer",
"hardware_decode": "Аппаратное декодирование",
"hardware_decode_description": "Использовать аппаратное ускорение для декодирования видео. Выключите, если наблюдаете проблемы с воспроизведением."
},
"vlc_subtitles": {
"title": "VLC Subtitle Settings",
"hint": "Customize subtitle appearance for VLC player. Changes take effect on next playback.",
"text_color": "Text Color",
"background_color": "Background Color",
"background_opacity": "Background Opacity",
"outline_color": "Outline Color",
"outline_opacity": "Outline Opacity",
"outline_thickness": "Outline Thickness",
"bold": "Bold Text",
"margin": "Bottom Margin"
"title": "Настройки субтитров в VLC",
"hint": "Настройте внешний вид субтитров в VLC плеере. Изменения применятся при следующем воспроизведении.",
"text_color": "Цвет текста",
"background_color": "Цвет фона",
"background_opacity": "Прозрачность фона",
"outline_color": "Цвет контура",
"outline_opacity": "Прозрачность контура",
"outline_thickness": "Толщина контура",
"bold": "Жирный",
"margin": "Отступ снизу"
},
"video_player": {
"title": "Video Player",
"video_player": "Video Player",
"video_player_description": "Choose which video player to use on iOS.",
"title": "Видеоплеер",
"video_player": "Видеоплеер",
"video_player_description": "Выберите видеоплеер в iOS.",
"ksplayer": "KSPlayer",
"vlc": "VLC"
},
@@ -294,19 +294,19 @@
"UNKNOWN": "Неизвестное"
},
"safe_area_in_controls": "Безопасная зона в элементах управления",
"video_player": "Видео прейер",
"video_player": "Видеоплеер",
"video_players": {
"VLC_3": "VLC 3",
"VLC_4": "VLC 4 (Экспериментальный + PiP)"
},
"show_custom_menu_links": "Показать ссылки кастомного меню",
"show_large_home_carousel": "Show Large Home Carousel (beta)",
"show_large_home_carousel": "Показывать большую карусель (beta)",
"hide_libraries": "Скрыть библиотеки",
"select_liraries_you_want_to_hide": "Выберите Библиотеки, которое хотите спрятать из вкладки Библиотеки и домашней страницы.",
"disable_haptic_feedback": "Отключить тактильную обратную связь",
"default_quality": "Качество по умолчанию",
"default_playback_speed": "Default Playback Speed",
"auto_play_next_episode": "Auto-play Next Episode",
"default_playback_speed": "Скорость воспроизведения по умолчанию",
"auto_play_next_episode": "Автоматически воспроизводить следующий эпизод",
"max_auto_play_episode_count": "Максимальное количество автовоспроизведения эпизодов",
"disabled": "Отключено"
},
@@ -314,15 +314,15 @@
"downloads_title": "Загрузки"
},
"music": {
"title": "Music",
"playback_title": "Playback",
"playback_description": "Configure how music is played.",
"prefer_downloaded": "Prefer Downloaded Songs",
"caching_title": "Caching",
"caching_description": "Automatically cache upcoming tracks for smoother playback.",
"lookahead_enabled": "Enable Look-Ahead Caching",
"lookahead_count": "Tracks to Pre-cache",
"max_cache_size": "Max Cache Size"
"title": "Музыка",
"playback_title": "Воспроизведение",
"playback_description": "Настройте воспроизведение музыки.",
"prefer_downloaded": "Предпочитать скачанные песни",
"caching_title": "Кеширование",
"caching_description": "Автоматически предкешировать следующие треки для стабильного воспроизведения.",
"lookahead_enabled": "Включить предкеширование",
"lookahead_count": "Сколько предкешировать",
"max_cache_size": "Максимальное число предкешированных треков"
},
"plugins": {
"plugins_title": "Плагины",
@@ -357,39 +357,39 @@
"save_button": "Сохранить",
"toasts": {
"saved": "Сохранено",
"refreshed": "Settings refreshed from server"
"refreshed": "Настройки обновлены с сервера"
},
"refresh_from_server": "Refresh Settings from Server"
"refresh_from_server": "Обновить настройки с сервера"
},
"streamystats": {
"enable_streamystats": "Enable Streamystats",
"disable_streamystats": "Disable Streamystats",
"enable_search": "Use for Search",
"enable_streamystats": "Включить Streamystats",
"disable_streamystats": "Выключить Streamystats",
"enable_search": "Использовать в поиске",
"url": "URL",
"server_url_placeholder": "http(s)://streamystats.example.com",
"streamystats_search_hint": "Enter the URL for your Streamystats server. The URL should include http or https and optionally the port.",
"read_more_about_streamystats": "Read More About Streamystats.",
"save_button": "Save",
"save": "Save",
"features_title": "Features",
"home_sections_title": "Home Sections",
"enable_movie_recommendations": "Movie Recommendations",
"enable_series_recommendations": "Series Recommendations",
"enable_promoted_watchlists": "Promoted Watchlists",
"hide_watchlists_tab": "Hide Watchlists Tab",
"home_sections_hint": "Show personalized recommendations and promoted watchlists from Streamystats on the home page.",
"recommended_movies": "Recommended Movies",
"recommended_series": "Recommended Series",
"streamystats_search_hint": "Введите URL вашего сервера Streamystats. URL должен включать http/https и порт при необходимости.",
"read_more_about_streamystats": "Узнать больше про Streamystats.",
"save_button": "Сохранить",
"save": "Сохранить",
"features_title": "Функции",
"home_sections_title": "Показывать на главной",
"enable_movie_recommendations": "Рекомендации фильмов",
"enable_series_recommendations": "Рекомендации сериалов",
"enable_promoted_watchlists": "Продвигаемые списки просмотра",
"hide_watchlists_tab": "Скрыть вкладку со списками",
"home_sections_hint": "Показывать персонализированные рекомендации и подходящие списки просмотров из Streamystats на главной странице.",
"recommended_movies": "Рекомендованные фильмы",
"recommended_series": "Рекомендованные сериалы",
"toasts": {
"saved": "Saved",
"refreshed": "Settings refreshed from server",
"disabled": "Streamystats disabled"
"saved": "Сохранено",
"refreshed": "Настройки обновлены с сервера",
"disabled": "Streamystats отключен"
},
"refresh_from_server": "Refresh Settings from Server"
"refresh_from_server": "Обновить настройки с сервера"
},
"kefinTweaks": {
"watchlist_enabler": "Enable our Watchlist integration",
"watchlist_button": "Toggle Watchlist integration"
"watchlist_enabler": "Включить интеграцию со списками просмотра",
"watchlist_button": "Изменить интеграцию со списками просмотра"
}
},
"storage": {
@@ -398,18 +398,18 @@
"device_usage": "Устройство {{availableSpace}}%",
"size_used": "{{used}} из {{total}} использовано",
"delete_all_downloaded_files": "Удалить все загруженные файлы",
"music_cache_title": "Music Cache",
"music_cache_description": "Automatically cache songs as you listen for smoother playback and offline support",
"enable_music_cache": "Enable Music Cache",
"clear_music_cache": "Clear Music Cache",
"music_cache_size": "{{size}} cached",
"music_cache_cleared": "Music cache cleared",
"delete_all_downloaded_songs": "Delete All Downloaded Songs",
"downloaded_songs_size": "{{size}} downloaded",
"downloaded_songs_deleted": "Downloaded songs deleted"
"music_cache_title": "Кеш музыки",
"music_cache_description": "Автоматически прекешировать песни по мере прослушивания для плавного воспроизведения и поддержки отсутствия интернета",
"enable_music_cache": "Кешировать музыку",
"clear_music_cache": "Очистить кеш музыки",
"music_cache_size": "{{size}} кешировано",
"music_cache_cleared": "Кеш музыки очищен",
"delete_all_downloaded_songs": "Удалить все скачанные песни",
"downloaded_songs_size": "{{size}} скачано",
"downloaded_songs_deleted": "Скачанные песни удалены"
},
"intro": {
"title": "Intro",
"title": "Вступление",
"show_intro": "Показать вступление",
"reset_intro": "Сбросить вступление"
},
@@ -441,24 +441,24 @@
"tvseries": "Сериалы",
"movies": "Фильмы",
"queue": "Очередь",
"other_media": "Другие медиа",
"queue_hint": "Очередь и загрузки будут удалены при перезагрузке приложения",
"other_media": "Прочие файлы",
"queue_hint": "Очередь очистится после перезапуска",
"no_items_in_queue": "Нет элементов в очереди",
"no_downloaded_items": "Нет загруженых предметов",
"no_downloaded_items": "Нет загруженных файлов",
"delete_all_movies_button": "Удалить все фильмы",
"delete_all_tvseries_button": "Удалить все сериалы",
"delete_all_button": "Удалить все",
"delete_all_other_media_button": "Удалить другой материал",
"active_download": "Активно загружается",
"delete_all_other_media_button": "Удалить прочие файлы",
"active_download": "Загружается",
"no_active_downloads": "Нет активных загрузок",
"active_downloads": "Активные загрузки",
"active_downloads": "Активные",
"new_app_version_requires_re_download": "Новая версия приложения требует повторной загрузки",
"new_app_version_requires_re_download_description": "Новая версия приложения требует повторной загрузки. Пожалуйста удалите всё и попробуйте заново.",
"back": "Назад",
"delete": "Удалить",
"something_went_wrong": "Что-то пошло не так",
"could_not_get_stream_url_from_jellyfin": "Не удалось получить ссылку трансляции из Jellyfin",
"eta": "ETA {{eta}}",
"eta": "Осталось {{eta}}",
"toasts": {
"you_are_not_allowed_to_download_files": "Нет разрешения на скачивание файлов.",
"deleted_all_movies_successfully": "Все фильмы были успешно удалены!",
@@ -467,64 +467,64 @@
"failed_to_delete_all_tvseries": "Возникла ошибка при удалении всех сериалов",
"deleted_media_successfully": "Другие носители успешно удалены!",
"failed_to_delete_media": "Не удалось удалить другой файл",
"download_deleted": "Загрузка удалена",
"download_deleted": "Удалено",
"download_cancelled": "Загрузка отменена",
"could_not_delete_download": "Не удалось удалить загрузку",
"download_paused": "Загрузка приостановлена",
"download_paused": "На паузе",
"could_not_pause_download": "Не удалось приостановить загрузку",
"download_resumed": "Загрузка возобновлена",
"download_resumed": "Продолжено",
"could_not_resume_download": "Не удалось продолжить загрузку",
"download_completed": "Загрузка завершена",
"download_failed": "Download Failed",
"download_completed": "Завершено",
"download_failed": "Не удалось загрузить",
"download_failed_for_item": "Загрузка {{item}} провалилась с ошибкой: {{error}}",
"download_completed_for_item": "{{item}} успешно загружен",
"download_started_for_item": "Загрузка началась для {{item}}",
"failed_to_start_download": "Не удалось начать загрузку",
"item_already_downloading": "{{item}} is already downloading",
"all_files_deleted": "All Downloads Deleted Successfully",
"files_deleted_by_type": "{{count}} {{type}} deleted",
"item_already_downloading": "{{item}} уже загружается",
"all_files_deleted": "Все загрузки удалены",
"files_deleted_by_type": "{{count}} {{type}} удалён(о)",
"all_files_folders_and_jobs_deleted_successfully": "Все файлы, папки, и задачи были успешно удалены",
"failed_to_clean_cache_directory": "Не удалось очистить директорию кэша",
"could_not_get_download_url_for_item": "Не удалось получить URL загрузки для {{itemName}}",
"go_to_downloads": "В загрузки",
"file_deleted": "{{item}} deleted"
"file_deleted": "{{item}} удалён"
}
}
},
"common": {
"select": "Выбрать",
"no_trailer_available": "Прицеп недоступен",
"no_trailer_available": "Трейлер недоступен",
"video": "Видео",
"audio": "Звук",
"subtitle": "Субтитры",
"play": "Играть",
"none": "None",
"track": "Track",
"cancel": "Cancel",
"delete": "Delete",
"ok": "OK",
"remove": "Remove",
"next": "Next",
"back": "Back",
"continue": "Continue",
"verifying": "Verifying..."
"play": "Воспроизвести",
"none": "Отсутствует",
"track": "Трек",
"cancel": "Отмена",
"delete": "Удалить",
"ok": "ОК",
"remove": "Удалить",
"next": "Вперед",
"back": "Назад",
"continue": "Продолжить",
"verifying": "Проверка..."
},
"search": {
"search": "Поиск...",
"x_items": "{{count}} предметов",
"x_items": "{{count}} элементов",
"library": "Библиотека",
"discover": "Найти новое",
"no_results": "Нет результатов",
"no_results_found_for": "Не было результатов при поиске",
"no_results": "Ничего не найдено",
"no_results_found_for": "Ничего не найдено по запросу",
"movies": "Фильмы",
"series": "Сериалы",
"episodes": "Серии",
"collections": "Коллекции",
"actors": "Актеры",
"artists": "Artists",
"albums": "Albums",
"songs": "Songs",
"playlists": "Playlists",
"artists": "Артисты",
"albums": "Альбомы",
"songs": "Песни",
"playlists": "Плейлисты",
"request_movies": "Запросить фильмы",
"request_series": "Запросить сериалы",
"recently_added": "Недавно добавлено",
@@ -553,7 +553,7 @@
"no_results": "Нет результатов",
"no_libraries_found": "Библиотеки не найдены",
"item_types": {
"movies": "фильмы",
"movies": "Фильмы",
"series": "Сериалы",
"boxsets": "Коллекции",
"items": "элементы"
@@ -571,9 +571,9 @@
"filters": {
"genres": "Жанры",
"years": "Года",
"sort_by": "Сортировать по",
"filter_by": "Filter By",
"sort_order": "Порядок сортировки",
"sort_by": "Сортировка",
"filter_by": "Фильтр",
"sort_order": "Порядок",
"tags": "Тэги"
}
},
@@ -604,14 +604,14 @@
"index": "Индекс:",
"continue_watching": "Продолжить просмотр",
"go_back": "Назад",
"downloaded_file_title": "You have this file downloaded",
"downloaded_file_message": "Do you want to play the downloaded file?",
"downloaded_file_yes": "Yes",
"downloaded_file_no": "No",
"downloaded_file_cancel": "Cancel"
"downloaded_file_title": "Этот файл уже скачан",
"downloaded_file_message": "Хотите воспроизвести скачанный файл?",
"downloaded_file_yes": "Да",
"downloaded_file_no": "Нет",
"downloaded_file_cancel": "Отмена"
},
"item_card": {
"next_up": "Следующее",
"next_up": "Далее",
"no_items_to_display": "Нет элементов для отображения",
"cast_and_crew": "Актеры и съемочная группа",
"series": "Серии",
@@ -644,7 +644,7 @@
}
},
"live_tv": {
"next": "Следующая",
"next": "Далее",
"previous": "Предыдущая",
"coming_soon": "Скоро",
"on_now": "Сейчас в эфире",
@@ -675,7 +675,7 @@
"series_type": "Тип сериала",
"release_dates": "Дата релиза",
"first_air_date": "Первая дата выхода в эфир",
"next_air_date": "Следующая дата выхода в эфир",
"next_air_date": "Ближайшая дата выхода в эфир",
"revenue": "Прибыль",
"budget": "Бюджет",
"original_language": "Оригинальный язык",
@@ -693,10 +693,10 @@
"number_episodes": "{{episode_number}} серий",
"born": "Рожден",
"appearances": "Появления",
"approve": "Approve",
"decline": "Decline",
"requested_by": "Requested by {{user}}",
"unknown_user": "Unknown User",
"approve": "Одобрить",
"decline": "Отклонить",
"requested_by": "Запрошено {{user}}",
"unknown_user": "Неизвестный пользователь",
"toasts": {
"jellyseer_does_not_meet_requirements": "Сервер Jellyseerr не соответствует минимальным требованиям версии! Пожалуйста, обновите до версии не ниже 2.0.0",
"jellyseerr_test_failed": "Тест Jellyseerr не пройден. Попробуйте еще раз.",
@@ -705,141 +705,141 @@
"requested_item": "Запрошено {{item}}!",
"you_dont_have_permission_to_request": "У вас нет разрешения на запрос!",
"something_went_wrong_requesting_media": "Что-то пошло не так при запросе медиафайлов!",
"request_approved": "Request Approved!",
"request_declined": "Request Declined!",
"failed_to_approve_request": "Failed to Approve Request",
"failed_to_decline_request": "Failed to Decline Request"
"request_approved": "Запрос одобрен!",
"request_declined": "Запрос отклонён!",
"failed_to_approve_request": "Не удалось одобрить запрос",
"failed_to_decline_request": "Не удалось отклонить запрос"
}
},
"tabs": {
"home": "Дом",
"home": "Главная",
"search": "Поиск",
"library": "Библиотека",
"custom_links": "Кастомные ссылки",
"custom_links": "Ссылки",
"favorites": "Избранное"
},
"music": {
"title": "Music",
"title": "Музыка",
"tabs": {
"suggestions": "Suggestions",
"albums": "Albums",
"artists": "Artists",
"playlists": "Playlists",
"tracks": "tracks"
"suggestions": "Рекомендации",
"albums": "Альбомы",
"artists": "Исполнители",
"playlists": "Плейлисты",
"tracks": "треки"
},
"filters": {
"all": "All"
"all": "Все"
},
"recently_added": "Recently Added",
"recently_played": "Recently Played",
"frequently_played": "Frequently Played",
"explore": "Explore",
"top_tracks": "Top Tracks",
"play": "Play",
"shuffle": "Shuffle",
"play_top_tracks": "Play Top Tracks",
"no_suggestions": "No suggestions available",
"no_albums": "No albums found",
"no_artists": "No artists found",
"no_playlists": "No playlists found",
"album_not_found": "Album not found",
"artist_not_found": "Artist not found",
"playlist_not_found": "Playlist not found",
"recently_added": "Недавно добавлено",
"recently_played": "Недавно воспроизведено",
"frequently_played": "Часто играет",
"explore": "Найти новое",
"top_tracks": "Топ",
"play": "Воспроизвести",
"shuffle": "Перемешать",
"play_top_tracks": "Воспроизвести топ",
"no_suggestions": "Нет рекомендаций",
"no_albums": "Альбомы не найдены",
"no_artists": "Исполнители не найдены",
"no_playlists": "Плейлисты не найдены",
"album_not_found": "Альбом не найден",
"artist_not_found": "Исполнитель не найден",
"playlist_not_found": "Плейлист не найден",
"track_options": {
"play_next": "Play Next",
"add_to_queue": "Add to Queue",
"add_to_playlist": "Add to Playlist",
"download": "Download",
"downloaded": "Downloaded",
"downloading": "Downloading...",
"cached": "Cached",
"delete_download": "Delete Download",
"delete_cache": "Remove from Cache",
"go_to_artist": "Go to Artist",
"go_to_album": "Go to Album",
"add_to_favorites": "Add to Favorites",
"remove_from_favorites": "Remove from Favorites",
"remove_from_playlist": "Remove from Playlist"
"play_next": "Далее",
"add_to_queue": "Добавить в очередь",
"add_to_playlist": "Добавить в плейлист",
"download": "Скачать",
"downloaded": "Скачано",
"downloading": "Скачивается...",
"cached": "Кешировано",
"delete_download": "Удалить загрузку",
"delete_cache": "Удалить из кеша",
"go_to_artist": "К исполнителю",
"go_to_album": "К альбому",
"add_to_favorites": "В избранное",
"remove_from_favorites": "Удалить из избранного",
"remove_from_playlist": "Удалить из плейлиста"
},
"playlists": {
"create_playlist": "Create Playlist",
"playlist_name": "Playlist Name",
"enter_name": "Enter playlist name",
"create": "Create",
"search_playlists": "Search playlists...",
"added_to": "Added to {{name}}",
"added": "Added to playlist",
"removed_from": "Removed from {{name}}",
"removed": "Removed from playlist",
"created": "Playlist created",
"create_new": "Create New Playlist",
"failed_to_add": "Failed to add to playlist",
"failed_to_remove": "Failed to remove from playlist",
"failed_to_create": "Failed to create playlist",
"delete_playlist": "Delete Playlist",
"delete_confirm": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.",
"deleted": "Playlist deleted",
"failed_to_delete": "Failed to delete playlist"
"create_playlist": "Создать плейлист",
"playlist_name": "Название плейлиста",
"enter_name": "Введите название плейлиста",
"create": "Создать",
"search_playlists": "Поиск плейлистов...",
"added_to": "Добавлено в {{name}}",
"added": "Добавлено в плейлист",
"removed_from": "Удалено из {{name}}",
"removed": "Удалено из плейлиста",
"created": "Плейлист создан",
"create_new": "Добавить новый плейлист",
"failed_to_add": "Не удалось добавить в плейлист",
"failed_to_remove": "Не удалось удалить из плейлиста",
"failed_to_create": "Не удалось создать плейлист",
"delete_playlist": "Удалить плейлист",
"delete_confirm": "Вы уверены, что хотите удалить \"{{name}}\"? Это действие необратимо.",
"deleted": "Плейлист удалён",
"failed_to_delete": "Не удалось удалить плейлист"
},
"sort": {
"title": "Sort By",
"alphabetical": "Alphabetical",
"date_created": "Date Created"
"title": "Сортировка",
"alphabetical": "По алфавиту",
"date_created": "По дате создания"
}
},
"watchlists": {
"title": "Watchlists",
"my_watchlists": "My Watchlists",
"public_watchlists": "Public Watchlists",
"create_title": "Create Watchlist",
"edit_title": "Edit Watchlist",
"create_button": "Create Watchlist",
"save_button": "Save Changes",
"delete_button": "Delete",
"remove_button": "Remove",
"cancel_button": "Cancel",
"name_label": "Name",
"name_placeholder": "Enter watchlist name",
"description_label": "Description",
"description_placeholder": "Enter description (optional)",
"is_public_label": "Public Watchlist",
"is_public_description": "Allow others to view this watchlist",
"allowed_type_label": "Content Type",
"sort_order_label": "Default Sort Order",
"empty_title": "No Watchlists",
"empty_description": "Create your first watchlist to start organizing your media",
"empty_watchlist": "This watchlist is empty",
"empty_watchlist_hint": "Add items from your library to this watchlist",
"not_configured_title": "Streamystats Not Configured",
"not_configured_description": "Configure Streamystats in settings to use watchlists",
"go_to_settings": "Go to Settings",
"add_to_watchlist": "Add to Watchlist",
"remove_from_watchlist": "Remove from Watchlist",
"select_watchlist": "Select Watchlist",
"create_new": "Create New Watchlist",
"item": "item",
"items": "items",
"public": "Public",
"private": "Private",
"you": "You",
"by_owner": "By another user",
"not_found": "Watchlist not found",
"delete_confirm_title": "Delete Watchlist",
"delete_confirm_message": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.",
"remove_item_title": "Remove from Watchlist",
"remove_item_message": "Remove \"{{name}}\" from this watchlist?",
"loading": "Loading watchlists...",
"no_compatible_watchlists": "No compatible watchlists",
"create_one_first": "Create a watchlist that accepts this content type"
"title": "Списки просмотров",
"my_watchlists": "Мои списки",
"public_watchlists": "Публичные списки",
"create_title": "Создать список",
"edit_title": "Редактировать список",
"create_button": "Создать список",
"save_button": "Сохранить изменения",
"delete_button": "Удалить",
"remove_button": "Удалить",
"cancel_button": "Отмена",
"name_label": "Название",
"name_placeholder": "Введите название списка",
"description_label": "Описание",
"description_placeholder": "Введите описание (не обязательно)",
"is_public_label": "Публичный",
"is_public_description": "Разрешить остальным пользователям видеть этот список",
"allowed_type_label": "Тип контента",
"sort_order_label": "Сортировка по умолчанию",
"empty_title": "Нет списков",
"empty_description": "Создайте ваш первый список для управления вашими медиа",
"empty_watchlist": "Этот список пуст",
"empty_watchlist_hint": "Добавляйте элементы из библиотеки в этот список",
"not_configured_title": "Streamystats не настроен",
"not_configured_description": "Настройте Streamystats для использования функционала списков",
"go_to_settings": "В настройки",
"add_to_watchlist": "Добавить в список просмотра",
"remove_from_watchlist": "Удалить из списка просмотра",
"select_watchlist": "Выбрать список",
"create_new": "Создать новый список",
"item": "элемент",
"items": "элементы",
"public": "Публичный",
"private": "Личный",
"you": "Ваш",
"by_owner": "Другим пользователем",
"not_found": "Список не найден",
"delete_confirm_title": "Удалить список",
"delete_confirm_message": "Вы уверены, что хотите удалить список \"{{name}}\"? Это действие необратимо.",
"remove_item_title": "Удалить из списка",
"remove_item_message": "Удалить \"{{name}}\" из списка?",
"loading": "Загрузка списков...",
"no_compatible_watchlists": "Нет совместимых списков",
"create_one_first": "Создайте список просмотра с подходящим типом контента"
},
"playback_speed": {
"title": "Playback Speed",
"apply_to": "Apply To",
"speed": "Speed",
"title": "Скорость воспроизведения",
"apply_to": "Применять к",
"speed": "Скорость",
"scope": {
"media": "This media only",
"show": "This show",
"all": "All media (default)"
"media": "Только в этот раз",
"show": "Ко всему сериалу",
"all": "Ко всем файлам (по умолчанию)"
}
}
}