Compare commits

..

12 Commits

Author SHA1 Message Date
lance chant
7f68506ceb Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-08 14:47:39 +02:00
lance chant
ac41fa7863 Merge branch 'develop' into fix/android-tv-issues 2026-06-08 13:54:36 +02:00
Gauvain
8f82ac481a chore: enforce LF line endings repo-wide via .gitattributes (#1643) 2026-06-08 13:33:54 +02:00
Gauvain
a242ff69fd chore(i18n): sentence-case and polish the en.json source (#1663) 2026-06-08 12:10:43 +02:00
Chris
b0c9dc114c Revise bug report template for clarity and specificity
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
🏗️ Build Apps / 🍎 Build tvOS IPA (push) Has been cancelled
🏗️ Build Apps / 🍎 Build tvOS IPA (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
🚦 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
Updated issue report template to specify improvements for Streamyfin and enhanced placeholder text for clarity.
2026-06-05 17:54:07 +02:00
Chris
89190b5054 Revise issue report template for clarity and accuracy
Updated placeholders and descriptions for device and server information in issue report template.
2026-06-05 17:51:10 +02:00
Chris
394262af5a Update Streamyfin version options in issue template
Add new version options for Streamyfin in issue report template.
2026-06-05 17:37:35 +02:00
Gauvain
3dbe5bb64c ci(issues): detect likely-duplicate issues on open (#1645)
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
🏗️ Build Apps / 🍎 Build tvOS IPA (push) Has been cancelled
🏗️ Build Apps / 🍎 Build tvOS IPA (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
🚦 Security & Quality Gate / 📝 Validate PR Title (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Vulnerable Dependencies (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 / 🚑 Expo Doctor Check (push) Has been cancelled
🚦 Security & Quality Gate / 🔍 Lint & Test (typecheck) (push) Has been cancelled
2026-06-05 14:21:12 +02:00
lance chant
cd5300e4ba Merge branch 'develop' into fix/android-tv-issues 2026-06-05 13:26:15 +02:00
Gauvain
801ab275ab fix(icon): downsize the icon and make them appropriate (#1660) 2026-06-05 11:29:38 +02:00
Lance Chant
326956dfda fix: search page crash on android
Ensured the search module is only apple specific to stop android
crashing

Signed-off-by: Lance Chant <13349722+lancechant@users.noreply.github.com>
2026-06-05 08:24:40 +02:00
Lance Chant
7528274249 fix: the home recommendations
there was an issue where the home recommendations was deleted and then
not shown again because of google TV policies

Signed-off-by: Lance Chant <13349722+lancechant@users.noreply.github.com>
2026-06-05 08:08:03 +02:00
73 changed files with 1313 additions and 1097 deletions

29
.gitattributes vendored
View File

@@ -1 +1,28 @@
.modules/vlc-player/Frameworks/*.xcframework filter=lfs diff=lfs merge=lfs -text # Normalise line endings to LF for everyone. Files are stored as LF in git and
# checked out as LF on every OS, so Windows clones stop producing CRLF churn
# (no more "LF will be replaced by CRLF" warnings) regardless of core.autocrlf.
* text=auto eol=lf
# Windows-only scripts must stay CRLF
*.bat text eol=crlf
*.cmd text eol=crlf
# Binary assets — never touched / never normalised
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.webp binary
*.ico binary
*.icns binary
*.ttf binary
*.otf binary
*.woff binary
*.woff2 binary
*.mp3 binary
*.mp4 binary
*.mov binary
*.pdf binary
*.keystore binary
*.jks binary
*.p12 binary

View File

@@ -1,5 +1,5 @@
name: "🐛 Bug Report" name: "🐛 Bug Report"
description: Create a report to help us improve description: Create a report to help Streamyfin improve
title: "[Bug]: " title: "[Bug]: "
labels: labels:
- "🐛 bug" - "🐛 bug"
@@ -36,7 +36,7 @@ body:
attributes: attributes:
label: What happened? label: What happened?
description: A clear and concise description of what the bug is. description: A clear and concise description of what the bug is.
placeholder: Describe what happened in detail. placeholder: Describe what happened in detail, the more precise the better.
validations: validations:
required: true required: true
@@ -67,7 +67,7 @@ body:
attributes: attributes:
label: Which device and operating system are you using? label: Which device and operating system are you using?
description: Please provide your device model and OS version description: Please provide your device model and OS version
placeholder: e.g. iPhone 15 Pro, iOS 18.1.1 or Samsung Galaxy S24, Android 14 placeholder: e.g. iPhone 17 Pro / iOS 26.5.1, Samsung Galaxy S25 / Android 16, Apple TV / tvOS 26.5
validations: validations:
required: true required: true
@@ -75,11 +75,11 @@ body:
id: version id: version
attributes: attributes:
label: Streamyfin Version label: Streamyfin Version
description: What version of Streamyfin are you running? description: What version of Streamyfin are you using?
options: options:
- 0.47.1 - 0.54.1
- 0.30.2 - 0.51.0
- older - Older
- TestFlight/Development build - TestFlight/Development build
validations: validations:
required: true required: true
@@ -90,9 +90,9 @@ body:
label: Jellyfin Server Information label: Jellyfin Server Information
description: Please provide details about your Jellyfin server description: Please provide details about your Jellyfin server
placeholder: | placeholder: |
- Jellyfin Server Version: e.g. 10.10.7 - Jellyfin Server Version: e.g. 10.11.10
- Server OS: e.g. Ubuntu 22.04, Windows 11, Docker - Server OS: e.g. Ubuntu 26.04, Windows 11, Docker, Proxmox
- Connection: e.g. Local network, Remote via domain, VPN - Connection: e.g. Local network, remote via domain, VPN
- type: textarea - type: textarea
id: screenshots id: screenshots
@@ -104,7 +104,7 @@ body:
id: logs id: logs
attributes: attributes:
label: Relevant logs (if available) label: Relevant logs (if available)
description: If you have access to app logs or crash reports, please include them here. **Remember to remove any personal information like server URLs or usernames.** description: If you have access to app logs or crash reports, please include them here. **Remember to remove any personal information like server URL, API keys or usernames.**
render: shell render: shell
- type: textarea - type: textarea

38
.github/workflows/detect-duplicate.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: 🔁 Detect Duplicate Issues
on:
issues:
types: [opened]
permissions:
contents: read
concurrency:
group: detect-duplicate-${{ github.event.issue.number }}
cancel-in-progress: true
jobs:
detect:
name: 🔍 Find similar issues
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-24.04
permissions:
issues: write
contents: read
steps:
- name: 📥 Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: 🍞 Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: latest
- name: 🔍 Detect duplicate issues
run: bun scripts/detect-duplicate-issue.mjs
env:
GH_TOKEN: ${{ github.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}

11
.gitignore vendored
View File

@@ -1,6 +1,5 @@
# Dependencies and Package Managers # Dependencies and Package Managers
node_modules/ node_modules/
bun.lock
bun.lockb bun.lockb
package-lock.json package-lock.json
@@ -21,10 +20,8 @@ web-build/
# Gradle caches (top-level + per-module native projects) # Gradle caches (top-level + per-module native projects)
**/.gradle/ **/.gradle/
# Module-specific Builds # Native module build outputs (any module)
modules/mpv-player/android/build modules/*/android/build/
modules/player/android
modules/hls-downloader/android/build
# Generated Applications # Generated Applications
Streamyfin.app Streamyfin.app
@@ -69,10 +66,6 @@ certs/
# Version and Backup Files # Version and Backup Files
/version-backup-* /version-backup-*
/modules/sf-player/android/build
/modules/music-controls/android/build
modules/background-downloader/android/build/*
/modules/mpv-player/android/build
# ios:unsigned-build Artifacts # ios:unsigned-build Artifacts
build/ build/

View File

@@ -161,9 +161,7 @@ export default function FavoritesSeeAllScreen() {
/> />
{!itemType ? ( {!itemType ? (
<View className='flex-1 items-center justify-center px-6'> <View className='flex-1 items-center justify-center px-6'>
<Text className='text-neutral-500'> <Text className='text-neutral-500'>{t("favorites.noData")}</Text>
{t("favorites.noData", { defaultValue: "No items found." })}
</Text>
</View> </View>
) : isLoading ? ( ) : isLoading ? (
<View className='justify-center items-center h-full'> <View className='justify-center items-center h-full'>
@@ -194,7 +192,7 @@ export default function FavoritesSeeAllScreen() {
ListEmptyComponent={ ListEmptyComponent={
<View className='flex flex-col items-center justify-center h-full py-12'> <View className='flex flex-col items-center justify-center h-full py-12'>
<Text className='font-bold text-xl text-neutral-500'> <Text className='font-bold text-xl text-neutral-500'>
{t("home.no_items", { defaultValue: "No items" })} {t("home.no_items")}
</Text> </Text>
</View> </View>
} }

View File

@@ -137,12 +137,12 @@ export default function DownloadsPage() {
deleteFileByType("Episode") deleteFileByType("Episode")
.then(() => .then(() =>
toast.success( toast.success(
t("home.downloads.toasts.deleted_all_tvseries_successfully"), t("home.downloads.toasts.deleted_all_series_successfully"),
), ),
) )
.catch((reason) => { .catch((reason) => {
writeToLog("ERROR", reason); writeToLog("ERROR", reason);
toast.error(t("home.downloads.toasts.failed_to_delete_all_tvseries")); toast.error(t("home.downloads.toasts.failed_to_delete_all_series"));
}); });
const deleteOtherMedia = () => const deleteOtherMedia = () =>
Promise.all( Promise.all(
@@ -207,7 +207,7 @@ export default function DownloadsPage() {
<View className='mb-4'> <View className='mb-4'>
<View className='flex flex-row items-center justify-between mb-2 px-4'> <View className='flex flex-row items-center justify-between mb-2 px-4'>
<Text className='text-lg font-bold'> <Text className='text-lg font-bold'>
{t("home.downloads.tvseries")} {t("home.downloads.series")}
</Text> </Text>
<View className='bg-purple-600 rounded-full h-6 w-6 flex items-center justify-center'> <View className='bg-purple-600 rounded-full h-6 w-6 flex items-center justify-center'>
<Text className='text-xs font-bold'> <Text className='text-xs font-bold'>
@@ -288,7 +288,7 @@ export default function DownloadsPage() {
{t("home.downloads.delete_all_movies_button")} {t("home.downloads.delete_all_movies_button")}
</Button> </Button>
<Button color='purple' onPress={deleteShows}> <Button color='purple' onPress={deleteShows}>
{t("home.downloads.delete_all_tvseries_button")} {t("home.downloads.delete_all_series_button")}
</Button> </Button>
{otherMedia.length > 0 && ( {otherMedia.length > 0 && (
<Button color='purple' onPress={deleteOtherMedia}> <Button color='purple' onPress={deleteOtherMedia}>

View File

@@ -179,18 +179,15 @@ export default function SettingsTV() {
// Handle clearing all cache in the entire app // Handle clearing all cache in the entire app
const handleClearCache = async () => { const handleClearCache = async () => {
Alert.alert( Alert.alert(
t("home.settings.storage.clear_all_cache_confirm", "Clear All Cache?"), t("home.settings.storage.clear_all_cache_confirm"),
t( t("home.settings.storage.clear_all_cache_confirm_desc"),
"home.settings.storage.clear_all_cache_confirm_desc",
"Are you sure you want to clear all cached data? This will clear all cached images, music files, subtitles, and query caches. Your settings and login session will be kept.",
),
[ [
{ {
text: t("common.cancel", "Cancel"), text: t("common.cancel"),
style: "cancel", style: "cancel",
}, },
{ {
text: t("common.ok", "OK"), text: t("common.ok"),
onPress: async () => { onPress: async () => {
try { try {
// 1. Clear React Query Cache (memory & MMKV) // 1. Clear React Query Cache (memory & MMKV)
@@ -243,11 +240,8 @@ export default function SettingsTV() {
} catch (error) { } catch (error) {
console.error("Failed to clear cache:", error); console.error("Failed to clear cache:", error);
Alert.alert( Alert.alert(
t("home.settings.toasts.error_deleting_files", "Error"), t("home.settings.toasts.error_deleting_files"),
t( t("home.settings.storage.clear_all_cache_error_desc"),
"home.settings.storage.clear_all_cache_error_desc",
"An error occurred while clearing the cache.",
),
); );
} }
}, },

View File

@@ -102,8 +102,8 @@ export default function TabLayout() {
!settings?.streamyStatsServerUrl || settings?.hideWatchlistsTab, !settings?.streamyStatsServerUrl || settings?.hideWatchlistsTab,
tabBarIcon: tabBarIcon:
Platform.OS === "android" Platform.OS === "android"
? (_e) => require("@/assets/icons/list.png") ? (_e) => require("@/assets/icons/list.star.png")
: (_e) => ({ sfSymbol: "list.bullet.rectangle" }), : (_e) => ({ sfSymbol: "list.star" }),
}} }}
/> />
<NativeTabs.Screen <NativeTabs.Screen
@@ -112,7 +112,7 @@ export default function TabLayout() {
title: t("tabs.library"), title: t("tabs.library"),
tabBarIcon: tabBarIcon:
Platform.OS === "android" Platform.OS === "android"
? (_e) => require("@/assets/icons/server.rack.png") ? (_e) => require("@/assets/icons/rectangle.stack.fill.png")
: (_e) => ({ sfSymbol: "rectangle.stack.fill" }), : (_e) => ({ sfSymbol: "rectangle.stack.fill" }),
}} }}
/> />
@@ -123,8 +123,8 @@ export default function TabLayout() {
tabBarItemHidden: !settings?.showCustomMenuLinks, tabBarItemHidden: !settings?.showCustomMenuLinks,
tabBarIcon: tabBarIcon:
Platform.OS === "android" Platform.OS === "android"
? (_e) => require("@/assets/icons/list.png") ? (_e) => require("@/assets/icons/link.png")
: (_e) => ({ sfSymbol: "list.dash.fill" }), : (_e) => ({ sfSymbol: "link" }),
}} }}
/> />
<NativeTabs.Screen <NativeTabs.Screen
@@ -134,7 +134,7 @@ export default function TabLayout() {
tabBarItemHidden: !Platform.isTV, tabBarItemHidden: !Platform.isTV,
tabBarIcon: tabBarIcon:
Platform.OS === "android" Platform.OS === "android"
? (_e) => require("@/assets/icons/gear.png") //Should maybe use other libraries to have it uniform ? (_e) => require("@/assets/icons/gearshape.fill.png")
: (_e) => ({ sfSymbol: "gearshape.fill" }), : (_e) => ({ sfSymbol: "gearshape.fill" }),
}} }}
/> />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 22 KiB

BIN
assets/icons/link.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

BIN
assets/icons/list.star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" fill="none" viewBox="0 0 96 96"><path fill="url(#paint0_linear)" fill-rule="evenodd" d="M48 96C74.5097 96 96 74.5097 96 48C96 21.4903 74.5097 0 48 0C21.4903 0 0 21.4903 0 48C0 74.5097 21.4903 96 48 96ZM80.0001 52C80.0001 67.464 67.4641 80 52.0001 80C36.5361 80 24.0001 67.464 24.0001 52C24.0001 49.1303 24.4318 46.3615 25.2338 43.7548C27.4288 48.6165 32.3194 52 38.0001 52C45.7321 52 52.0001 45.732 52.0001 38C52.0001 32.3192 48.6166 27.4287 43.755 25.2337C46.3616 24.4317 49.1304 24 52.0001 24C67.4641 24 80.0001 36.536 80.0001 52Z" clip-rule="evenodd"/><path fill="#131928" fill-rule="evenodd" d="M80.0002 52C80.0002 67.464 67.4642 80 52.0002 80C36.864 80 24.5329 67.9897 24.017 52.9791C24.0057 53.318 24 53.6583 24 54C24 70.5685 37.4315 84 54 84C70.5685 84 84 70.5685 84 54C84 37.4315 70.5685 24 54 24C53.6597 24 53.3207 24.0057 52.9831 24.0169C67.9919 24.5347 80.0002 36.865 80.0002 52Z" clip-rule="evenodd" opacity=".2"/><path fill="url(#paint1_linear)" fill-rule="evenodd" d="M48 12C28.1177 12 12 28.1177 12 48C12 50.2091 10.2091 52 8 52C5.79086 52 4 50.2091 4 48C4 23.6995 23.6995 4 48 4C50.2091 4 52 5.79086 52 8C52 10.2091 50.2091 12 48 12Z" clip-rule="evenodd"/><defs><linearGradient id="paint0_linear" x1="48" x2="117.5" y1="0" y2="69.5" gradientUnits="userSpaceOnUse"><stop stop-color="#C395FC"/><stop offset="1" stop-color="#4F65F5"/></linearGradient><linearGradient id="paint1_linear" x1="28" x2="28" y1="8" y2="48" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" stop-opacity=".4"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient></defs></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,65 +0,0 @@
<svg
type="certified"
viewBox="0 0 80 80"
preserveAspectRatio="xMidYMid"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<g transform="translate(2.29, 0)">
<path
d="M42.1942857,18.8022857 C44.3794286,18.608 49.1565714,18.7177143 51.4902857,21.0057143 C51.6297143,21.1451429 51.5085714,21.4605714 51.3097143,21.408 C47.8902857,20.4868571 42.5577143,25.0217143 39.1017143,22.0891429 C39.008,22.9485714 38.2331429,27.0857143 32.3314286,26.4731429 C32.192,26.4594286 32.1371429,26.304 32.24,26.2171429 C33.1542857,25.44 34.2765714,23.2891429 33.3142857,21.9154286 C30.3108571,23.9085714 28.7565714,23.9954286 23.2182857,21.5954286 C23.0377143,21.5177143 23.1451429,21.2228571 23.3577143,21.1748571 C24.5074286,20.9165714 27.2434286,19.9222857 29.696,19.4582857 C30.1645714,19.3691429 30.624,19.3165714 31.0674286,19.312 C28.528,18.7062857 27.4217143,18.1805714 25.7485714,18.1874286 C25.5657143,18.1897143 25.4742857,17.9611429 25.6068571,17.8354286 C28.224,15.3188571 32.9691429,15.1885714 35.2548571,17.0628571 L33.2068571,12.7862857 L35.696,12.4114286 C35.696,12.4114286 36.3451429,14.6925714 36.9257143,16.7428571 C39.5177143,13.904 43.5268571,14.192 44.8777143,16.672 C44.9577143,16.8182857 44.8251429,16.992 44.6605714,16.9622857 C43.3005714,16.7314286 42.3702857,17.8628571 42.1737143,18.7977143 L42.1942857,18.8022857"
id="Fill-2"
fill="#00912D"
></path>
<mask id="mask-2" fill="white">
<polygon
points="0.137142857 0.921142857 75.0534777 0.921142857 75.0534777 79.8628571 0.137142857 79.8628571"
></polygon>
</mask>
<path
d="M13.0491429,59.1817143 C9.90628571,55.3554286 7.86971429,50.576 7.51771429,44.9622857 C6.912,35.2342857 10.2354286,26.0845714 23.1794286,21.4834286 C23.1908571,21.5245714 23.1725714,21.5748571 23.2182857,21.5954286 C23.0377143,21.5177143 23.1451429,21.2228571 23.3577143,21.1748571 C24.5074286,20.9165714 27.2434286,19.92 29.696,19.4582857 C30.1645714,19.3691429 30.624,19.3165714 31.0674286,19.3097143 C28.528,18.7062857 27.4217143,18.1805714 25.7485714,18.1874286 C25.5657143,18.1897143 25.4742857,17.9611429 25.6068571,17.8331429 C28.224,15.3165714 32.9691429,15.1885714 35.2548571,17.0628571 L33.2068571,12.784 L35.696,12.4114286 C35.696,12.4114286 36.3451429,14.6902857 36.9257143,16.7428571 C39.5177143,13.904 43.5268571,14.192 44.8777143,16.672 C44.9577143,16.8182857 44.8251429,16.992 44.6605714,16.9622857 C43.3005714,16.7314286 42.3702857,17.8628571 42.1737143,18.7977143 L42.1942857,18.8022857 C44.3794286,18.608 49.1565714,18.7177143 51.4902857,21.0057143 C51.328,20.8502857 51.1337143,20.7245714 50.9508571,20.5874286 C60.2765714,23.504 66.7474286,30.1531429 67.44,41.2251429 C67.8811429,48.2948571 65.5702857,54.3885714 61.568,59.1154286 C62.784,59.2891429 63.9931429,59.4925714 65.2045714,59.6937143 C70.304,53.4537143 73.2502857,45.5428571 73.2502857,37.056 C73.2502857,17.7165714 57.5337143,2.56685714 37.472,2.56685714 C17.4102857,2.56685714 1.69371429,17.7165714 1.69371429,37.056 C1.69371429,45.5565714 4.64,53.472 9.744,59.7097143 C10.8434286,59.5268571 11.9451429,59.3462857 13.0491429,59.1817143"
fill="#FFD700"
mask="url(#mask-2)"
></path>
<path
d="M9.744,59.7097143 C4.64,53.472 1.69371429,45.5565714 1.69371429,37.056 C1.69371429,17.7165714 17.4102857,2.56685714 37.472,2.56685714 C57.5337143,2.56685714 73.2502857,17.7165714 73.2502857,37.056 C73.2502857,45.5428571 70.304,53.4537143 65.2045714,59.6937143 C65.8125714,59.7942857 66.4205714,59.8742857 67.0285714,59.984 C71.9497143,53.6457143 74.8937143,45.6982857 74.8937143,37.056 C74.8937143,16.3862857 58.1394286,0.921142857 37.472,0.921142857 C16.8022857,0.921142857 0.048,16.3862857 0.048,37.056 C0.048,45.7074286 2.99885714,53.6594286 7.92914286,59.9977143 C8.53257143,59.8902857 9.13828571,59.8102857 9.744,59.7097143"
fill="#FA6E0F"
mask="url(#mask-2)"
></path>
<path
d="M58.2857143,74.9394286 C62.3748571,75.1954286 65.7874286,77.2137143 67.8468571,79.9474286 C67.9131429,80.0182857 68.0114286,80.016 68.0411429,79.9382857 C68.7451429,77.0971429 68.9394286,74.0662857 68.5851429,71.0125714 C68.5874286,70.9805714 68.6125714,70.9577143 68.6537143,70.9485714 C70.576,70.3428571 72.7017143,70.0137143 74.9645714,70.0457143 C75.0857143,70.0594286 75.0834286,69.9405714 74.9554286,69.8194286 C72.5577143,67.4994286 69.6297143,65.6914286 66.416,64.5417143 C65.3051429,67.68 64.2217143,70.816 63.1565714,73.9634286 C63.136,74.0228571 63.0514286,74.0594286 62.9645714,74.0434286 L58.2857143,74.9394286"
fill="#0AC855"
mask="url(#mask-2)"
></path>
<path
d="M62.9645714,74.0434286 L58.2857143,74.9394286 C58.2857143,74.9394286 58.3451429,74.512 58.528,73.3325714 C60.9417143,73.6754286 62.9645714,74.0434286 62.9645714,74.0434286"
fill="#0B4902"
></path>
<g transform="translate(0, 20.57)">
<mask id="mask-4" fill="white">
<polygon
points="0.137142857 0.016 67.4935952 0.016 67.4935952 59.2914286 0.137142857 59.2914286"
></polygon>
</mask>
<path
d="M13.0765714,38.6057143 C29.1177143,36.2605714 45.5222857,36.2354286 61.568,38.544 C65.5702857,33.8171429 67.8811429,27.7234286 67.44,20.6537143 C66.7474286,9.58171429 60.2765714,2.93257143 50.9508571,0.016 C51.1337143,0.153142857 51.328,0.278857143 51.4902857,0.434285714 C51.6297143,0.573714286 51.5085714,0.889142857 51.3097143,0.836571429 C47.8902857,-0.0845714286 42.5577143,4.45028571 39.1017143,1.51771429 C39.008,2.37485714 38.2331429,6.51428571 32.3314286,5.90171429 C32.192,5.888 32.1371429,5.73257143 32.24,5.64571429 C33.1542857,4.86857143 34.2765714,2.71542857 33.3142857,1.344 C30.3108571,3.33714286 28.7565714,3.424 23.2182857,1.024 C23.1725714,1.00342857 23.1908571,0.953142857 23.1794286,0.912 C10.2354286,5.51314286 6.912,14.6628571 7.51771429,24.3908571 C7.86971429,30.0091429 9.93142857,34.7748571 13.0765714,38.6057143"
fill="#FA3200"
mask="url(#mask-4)"
></path>
<path
d="M12.0868571,53.472 C12,53.488 11.9154286,53.4514286 11.8948571,53.392 C10.8274286,50.2445714 9.73485714,47.0971429 8.62171429,43.9611429 C5.41028571,45.1108571 2.49371429,46.9302857 0.0982857143,49.248 C-0.0297142857,49.3691429 -0.032,49.488 0.0891428571,49.4742857 C2.352,49.4422857 4.47771429,49.7714286 6.4,50.3771429 C6.44114286,50.3862857 6.46628571,50.4091429 6.46857143,50.4411429 C6.11428571,53.4948571 6.30857143,56.5257143 7.01257143,59.3668571 C7.04228571,59.4445714 7.14057143,59.4468571 7.20685714,59.376 C9.26628571,56.6422857 12.6742857,54.624 16.7657143,54.368 L12.0868571,53.472"
fill="#0AC855"
mask="url(#mask-4)"
></path>
</g>
<path
d="M62.9645714,74.0434286 C46.192,71.104 28.8571429,71.104 12.0868571,74.0434286 C12,74.0594286 11.9154286,74.0228571 11.8948571,73.9634286 C10.3428571,69.3851429 8.74285714,64.8182857 7.09257143,60.2628571 C7.06971429,60.1988571 7.14057143,60.1257143 7.248,60.1074286 C27.1885714,56.464 47.8605714,56.464 67.8034286,60.1074286 C67.9108571,60.1257143 67.9817143,60.1988571 67.9565714,60.2628571 C66.3085714,64.8182857 64.7085714,69.3851429 63.1565714,73.9634286 C63.136,74.0228571 63.0514286,74.0594286 62.9645714,74.0434286"
fill="#00912D"
></path>
<path
d="M12.0868571,74.0434286 L16.7657143,74.9394286 C16.7657143,74.9394286 16.704,74.512 16.5211429,73.3325714 C14.1074286,73.6754286 12.0868571,74.0434286 12.0868571,74.0434286"
fill="#0B4902"
></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 560 560" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M370.57 474.214l23.466-237.956c14.93-4.796 29.498-11.15 40.23-20.262L404.16 446.278c-6.748 10.248-19.863 20.86-33.59 27.936zm-78.197 21.631l2.947-244.528c20.894-.599 47.933-3.43 70.97-8.346l-19.07 241.17c-22.724 7.518-35.934 9.848-54.847 11.704zm-99.694-252.874c23.038 4.916 50.077 7.747 70.971 8.346l2.948 244.528c-18.914-1.856-32.123-4.186-54.847-11.705l-19.072-241.17zm-67.974-26.975c10.732 9.112 25.3 15.466 40.23 20.262l23.464 237.956c-13.726-7.075-26.84-17.688-33.59-27.936l-30.104-230.282z"/><path fill="gold" d="M118.905 157.445c1.357 28.827 72.771 51.677 160.578 51.176 76.687-.438 140.659-18.546 156.329-42.336a22.976 22.976 0 00-14.058-7.426c.06-.7.098-1.406.095-2.122-.065-11.4-8.429-20.788-19.327-22.54.287-1.474.438-2.999.43-4.559-.072-12.696-10.426-22.928-23.124-22.856-.287.001-.568.036-.853.049a22.911 22.911 0 001.254-7.56c-.074-12.697-10.425-22.93-23.123-22.858a22.914 22.914 0 00-8.247 1.6c-3.632-6.835-10.606-11.6-18.737-12.149-1.416-11.4-11.157-20.195-22.93-20.129-7.41.042-13.963 3.6-18.136 9.065-4.233-4.605-10.3-7.494-17.047-7.456-12.698.072-22.932 10.424-22.86 23.118a22.983 22.983 0 001.115 6.946 22.918 22.918 0 00-13.07 7.459c-2.644-9.847-11.637-17.084-22.314-17.024-9.975.057-18.406 6.47-21.537 15.366-8.474 3.426-14.439 11.738-14.383 21.433.012 2.154.342 4.227.907 6.202a22.876 22.876 0 00-9.328-1.932c-10.012.058-18.47 6.516-21.574 15.465a22.83 22.83 0 00-9.788-2.149c-12.698.072-22.934 10.422-22.86 23.118a22.833 22.833 0 003.159 11.463c-.202.203-.379.426-.571.636"/><path fill="#FA320A" d="M404.161 446.278c-6.749 10.248-19.864 20.86-33.59 27.936l23.465-237.956c14.93-4.796 29.498-11.15 40.23-20.262L404.16 446.278zM347.22 484.14c-22.723 7.519-35.934 9.85-54.847 11.705l2.947-244.528c20.894-.599 47.933-3.43 70.973-8.346L347.22 484.14zm-135.47 0l-19.07-241.17c23.037 4.917 50.076 7.748 70.97 8.347l2.948 244.528c-18.914-1.856-32.123-4.186-54.847-11.705zm-56.94-37.862l-30.105-230.282c10.732 9.112 25.3 15.466 40.23 20.262l23.464 237.956c-13.726-7.075-26.84-17.688-33.588-27.936zm247.668-321.143c.298 1.453.465 2.955.473 4.498a23.018 23.018 0 01-.43 4.56c10.9 1.749 19.263 11.137 19.328 22.54a23.59 23.59 0 01-.095 2.12 22.976 22.976 0 0114.058 7.425c-15.669 23.792-79.642 41.9-156.327 42.34-87.807.502-159.221-22.346-160.58-51.175.192-.208.37-.433.57-.634-1.355-2.311-2.29-4.887-2.773-7.62-8.408 7.979-13.495 14.412-12.6 23.78.085 1.251 37.196 266.911 37.196 266.911 4.282 42.075 65.391 75.703 138.187 76.12 72.796-.417 133.907-34.045 138.187-76.12 0 0 37.11-265.66 37.197-266.912 1.777-18.736-20.15-35.745-52.39-47.833z"/></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 560 560" xmlns="http://www.w3.org/2000/svg"><g transform="translate(33 140)"><path d="m43.802 267.32l237.94 23.482c4.7937 14.937 11.149 29.517 20.259 40.256l-230.27-30.125c-10.248-6.7519-20.861-19.877-27.936-33.612zm222.88-75.298c0.60053 20.906 3.4316 47.964 8.3462 71.017l-241.15-19.083c-7.518-22.739-9.8466-35.959-11.704-54.885l244.51 2.951zm8.3462-102.71c-4.9146 23.053-7.7456 50.111-8.3462 71.017l-244.51 2.951c1.8576-18.926 4.1862-32.146 11.704-54.885l241.15-19.083zm26.973-68.019c-9.1095 10.74-15.465 25.318-20.259 40.257l-237.94 23.48c7.0751-13.735 17.689-26.859 27.936-33.612l230.27-30.125z" fill="#fff"/><path d="m303.57 264.67c3.155-7.8209 14.337-12.586 22.367-12.028 8.5825 0.59581 17.699 9.6258 19.292 18.507 0.29589-0.32244 0.60578-0.62735 0.92093-0.92701 2.7558-2.6356 6.2084-4.3845 9.9867-4.8664-0.57777-2.562-0.71609-5.3045-0.3204-8.1188 1.3954-9.901 9.3336-17.326 18.422-17.252 5.8652 0.047314 11.011 3.0509 14.364 7.6649 0.29939-0.37501 0.6303-0.71848 0.95245-1.069 3.8343-19.991 6.2644-42.578 6.8177-66.547 1.8996-82.42-18.993-149.75-46.663-150.39-27.672-0.63962-51.644 65.656-53.544 148.08 0 0-1.4654 30.062 7.4042 86.951" fill="#00641E"/><path d="m490.91 354.8c1.6353-2.732 2.5492-6.0072 2.4862-9.4874 0.5305-11.245-7.1819-21.439-17.913-20.31 0.3099-1.2862 0.51299-2.6233 0.59178-4.0024 0.64255-11.264-7.1188-20.972-17.337-21.682-0.2241-0.014019-0.44471-0.021029-0.66706-0.028039 1.0627-2.795 1.5897-5.916 1.4024-9.2228-0.52875-9.3717-6.9858-17.268-15.386-18.822-3.0342-0.56076-5.9773-0.28213-8.6718 0.65188-2.5457-6.277-7.8909-10.933-14.393-11.916-0.51474-10.192-7.8699-18.58-17.34-19.238-5.9545-0.41356-11.426 2.3237-15.085 6.9061-3.3528-4.614-8.4985-7.6158-14.364-7.6632-9.0885-0.075352-17.027 7.3495-18.422 17.252-0.39569 2.8126-0.25737 5.555 0.3204 8.1188-3.7783 0.48015-7.2309 2.2308-9.9867 4.8646-0.31515 0.29966-0.62504 0.60457-0.92093 0.92701-1.5932-8.8811-10.71-17.909-19.292-18.507-8.0293-0.55726-19.357 4.3249-22.367 12.028 1.3201 13.434 9.71 50.053 40.055 82.903l0.26963 0.019276c2.9256 2.6496 6.7459 4.1093 10.818 3.7466 2.5247-0.22606 4.8498-1.1303 6.8527-2.5252l0.48848 0.033295c2.67 1.8558 5.8793 2.8266 9.2706 2.5252 1.2956-0.11566 2.5317-0.42758 3.7065-0.87269 2.9064 6.0142 9.3879 9.901 16.622 9.2631 5.6026-0.49417 10.365-3.5959 13.164-7.9611l0.90692 0.063086c2.7961 2.774 6.513 4.3897 10.522 4.2688 3.3143 5.0188 9.4019 8.1065 16.12 7.516 2.5299-0.22255 4.8918-0.95505 6.998-2.0643 3.5139 4.3266 9.2811 6.8991 15.609 6.3419 6.2557-0.5485 11.54-4.02 14.414-8.8197 2.8241 2.2693 6.3625 3.4872 10.12 3.1525 3.6452-0.32594 6.8842-2.0485 9.3179-4.6543l0.40619 0.028038c0.55326-0.80259 1.026-1.6245 1.4654-2.4533 0.010505-0.015772 0.019259-0.033296 0.028014-0.049067 0.059527-0.1104 0.13306-0.21905 0.18909-0.3312" fill="#FFD700"/><path d="m281.75 61.547l-237.94 23.48c7.0751-13.735 17.689-26.859 27.936-33.612l230.27-30.125c-9.1095 10.74-15.465 25.318-20.259 40.257zm20.259 269.51l-230.27-30.125c-10.248-6.7519-20.861-19.877-27.936-33.611l237.94 23.48c4.7937 14.937 11.149 29.517 20.259 40.256zm-268.13-87.102c-7.518-22.739-9.8466-35.957-11.704-54.885l244.51 2.951c0.60053 20.906 3.4316 47.964 8.3462 71.017l-241.15-19.083zm0-135.56l241.15-19.083c-4.9146 23.053-7.7456 50.111-8.3462 71.019l-244.51 2.9493c1.8576-18.926 4.1862-32.146 11.704-54.885zm344.72-82.679c-15.255-17.778-26.206-26.124-35.587-25.04-1.7491 0.22255-266.89 37.222-266.89 37.222-42.074 4.2828-75.7 65.432-76.117 138.28 0.4167 72.843 34.043 133.99 76.117 138.28 0 0 265.64 37.135 266.89 37.221 2.2183-0.014019 4.4086-0.31192 6.5673-0.86568-2.101-0.6256-4.0391-1.7208-5.6867-3.2139l-0.26963-0.019276c-30.345-32.848-38.735-69.47-40.055-82.903 0.003501-0.010514 0.010505-0.019276 0.014006-0.02979-0.003501 0.010514-0.010505 0.019276-0.014006 0.02979-8.8697-56.889-7.4042-86.951-7.4042-86.951 1.8996-82.42 25.872-148.72 53.544-148.08 27.67 0.63962 48.562 67.973 46.663 150.39-0.55326 23.969-2.9834 46.556-6.8177 66.547 3.9393-4.3512 9.2233-6.1842 14.133-5.8372 0.90342 0.064838 1.7823 0.2173 2.6437 0.41531 16.804-92.03-0.81238-181.89-27.729-215.44z" fill="#04A53C"/></g></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 560 560" xmlns="http://www.w3.org/2000/svg"><path d="m478.29 296.98c-3.99-63.966-36.52-111.82-85.468-138.58 0.278 1.56-1.109 3.508-2.688 2.818-32.016-14.006-86.328 31.32-124.28 7.584 0.285 8.519-1.378 50.072-59.914 52.483-1.382 0.056-2.142-1.355-1.268-2.354 7.828-8.929 15.732-31.535 4.367-43.586-24.338 21.81-38.472 30.017-85.138 19.186-29.878 31.241-46.809 74-43.485 127.26 6.78 108.74 108.63 170.89 211.19 164.49 102.56-6.395 193.47-80.572 186.68-189.31" fill="#FA320A"/><path d="M291.375 132.293c21.075-5.023 81.693-.49 101.114 25.274 1.166 1.545-.475 4.468-2.355 3.648-32.016-14.006-86.328 31.32-124.282 7.584.285 8.519-1.378 50.072-59.914 52.483-1.382.056-2.142-1.355-1.268-2.354 7.828-8.929 15.73-31.535 4.367-43.586-26.512 23.758-40.884 31.392-98.426 15.838-1.883-.508-1.241-3.535.762-4.298 10.876-4.157 35.515-22.361 58.824-30.385 4.438-1.526 8.862-2.71 13.18-3.4-25.665-2.293-37.235-5.862-53.559-3.4-1.789.27-3.004-1.813-1.895-3.241 21.995-28.332 62.513-36.888 87.512-21.837-15.41-19.094-27.48-34.321-27.48-34.321l28.601-16.246s11.817 26.4 20.414 45.614c21.275-31.435 60.86-34.336 77.585-12.033.992 1.326-.045 3.21-1.702 3.171-13.612-.331-21.107 12.05-21.675 21.466l.197.023" fill="#00912D"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 560 560" xmlns="http://www.w3.org/2000/svg"><path d="M445.185 444.684c-79.369 4.167-95.587-86.652-126.726-86.006-13.268.279-23.726 14.151-19.133 30.32 2.525 8.888 9.53 21.923 13.944 30.011 15.57 28.544-7.447 60.845-34.383 63.577-44.76 4.54-63.433-21.426-62.278-48.007 1.3-29.84 26.6-60.331.65-73.305-27.194-13.597-49.301 39.572-75.325 51.439-23.553 10.741-56.248 2.413-67.872-23.741-8.164-18.379-6.68-53.768 29.67-67.27 22.706-8.433 73.305 11.029 75.9-13.623 2.992-28.416-53.155-30.812-70.06-37.626-29.912-12.055-47.567-37.85-33.734-65.522 10.378-20.757 40.915-29.203 64.223-20.11 27.922 10.892 32.404 39.853 46.71 51.897 12.324 10.38 29.19 11.68 40.22 4.543 8.135-5.265 10.843-16.828 7.774-27.39-4.07-14.023-14.875-22.773-25.415-31.346-18.758-15.249-45.24-28.36-29.222-69.983 13.13-34.11 51.642-35.34 51.642-35.34 15.3-1.72 29.002 2.9 40.167 12.875 14.927 13.335 17.834 31.16 15.336 50.176-2.283 17.358-8.426 32.56-11.63 49.759-3.717 19.966 6.954 40.086 27.249 40.869 26.694 1.031 34.698-19.486 37.964-32.492 4.782-19.028 11.058-36.694 28.718-47.82 25.346-15.97 60.552-12.47 76.886 18.222 12.92 24.284 8.772 57.715-11.047 75.97-8.892 8.188-19.584 11.075-31.148 11.156-16.585.117-33.162-.29-48.556 7.471-10.48 5.281-15.047 13.888-15.045 25.423 0 11.242 5.853 18.585 15.336 23.363 17.86 9.003 37.577 10.843 56.871 14.222 27.98 4.9 52.581 14.755 68.375 40.72.142.228.28.458.415.69 18.139 30.741-.831 75.005-36.476 76.878" fill="#0AC855"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 190.24 81.52"><defs><linearGradient id="a" y1="40.76" x2="190.24" y2="40.76" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#90cea1"/><stop offset=".56" stop-color="#3cbec9"/><stop offset="1" stop-color="#00b3e5"/></linearGradient></defs><path d="M105.67 36.06h66.9a17.67 17.67 0 0017.67-17.66A17.67 17.67 0 00172.57.73h-66.9A17.67 17.67 0 0088 18.4a17.67 17.67 0 0017.67 17.66zm-88 45h76.9a17.67 17.67 0 0017.67-17.66 17.67 17.67 0 00-17.67-17.67h-76.9A17.67 17.67 0 000 63.4a17.67 17.67 0 0017.67 17.66zm-7.26-45.64h7.8V6.92h10.1V0h-28v6.9h10.1zm28.1 0h7.8V8.25h.1l9 27.15h6l9.3-27.15h.1V35.4h7.8V0H66.76l-8.2 23.1h-.1L50.31 0h-11.8zm113.92 20.25a15.07 15.07 0 00-4.52-5.52 18.57 18.57 0 00-6.68-3.08 33.54 33.54 0 00-8.07-1h-11.7v35.4h12.75a24.58 24.58 0 007.55-1.15 19.34 19.34 0 006.35-3.32 16.27 16.27 0 004.37-5.5 16.91 16.91 0 001.63-7.58 18.5 18.5 0 00-1.68-8.25zM145 68.6a8.8 8.8 0 01-2.64 3.4 10.7 10.7 0 01-4 1.82 21.57 21.57 0 01-5 .55h-4.05v-21h4.6a17 17 0 014.67.63 11.66 11.66 0 013.88 1.87A9.14 9.14 0 01145 59a9.87 9.87 0 011 4.52 11.89 11.89 0 01-1 5.08zm44.63-.13a8 8 0 00-1.58-2.62 8.38 8.38 0 00-2.42-1.85 10.31 10.31 0 00-3.17-1v-.1a9.22 9.22 0 004.42-2.82 7.43 7.43 0 001.68-5 8.42 8.42 0 00-1.15-4.65 8.09 8.09 0 00-3-2.72 12.56 12.56 0 00-4.18-1.3 32.84 32.84 0 00-4.62-.33h-13.2v35.4h14.5a22.41 22.41 0 004.72-.5 13.53 13.53 0 004.28-1.65 9.42 9.42 0 003.1-3 8.52 8.52 0 001.2-4.68 9.39 9.39 0 00-.55-3.18zm-19.42-15.75h5.3a10 10 0 011.85.18 6.18 6.18 0 011.7.57 3.39 3.39 0 011.22 1.13 3.22 3.22 0 01.48 1.82 3.63 3.63 0 01-.43 1.8 3.4 3.4 0 01-1.12 1.2 4.92 4.92 0 01-1.58.65 7.51 7.51 0 01-1.77.2h-5.65zm11.72 20a3.9 3.9 0 01-1.22 1.3 4.64 4.64 0 01-1.68.7 8.18 8.18 0 01-1.82.2h-7v-8h5.9a15.35 15.35 0 012 .15 8.47 8.47 0 012.05.55 4 4 0 011.57 1.18 3.11 3.11 0 01.63 2 3.71 3.71 0 01-.43 1.92z" fill="url(#a)"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -89,14 +89,14 @@ export const IntroSheet = forwardRef<IntroSheetRef>((_, ref) => {
</Text> </Text>
<View className='flex flex-row items-center mt-4'> <View className='flex flex-row items-center mt-4'>
<Image <Image
source={require("@/assets/icons/jellyseerr-logo.svg")} source={require("@/assets/icons/seerr-logo.svg")}
style={{ style={{
width: 50, width: 50,
height: 50, height: 50,
}} }}
/> />
<View className='shrink ml-2'> <View className='shrink ml-2'>
<Text className='font-bold mb-1'>Jellyseerr</Text> <Text className='font-bold mb-1'>Seerr</Text>
<Text className='shrink text-xs'> <Text className='shrink text-xs'>
{t("home.intro.jellyseerr_feature_description")} {t("home.intro.jellyseerr_feature_description")}
</Text> </Text>

View File

@@ -40,8 +40,8 @@ export const Ratings: React.FC<Props> = ({ item, ...props }) => {
<Image <Image
source={ source={
item.CriticRating < 60 item.CriticRating < 60
? require("@/assets/images/rotten-tomatoes.png") ? require("@/assets/images/rt_rotten.svg")
: require("@/assets/images/not-rotten-tomatoes.svg") : require("@/assets/images/rt_fresh.svg")
} }
style={{ style={{
width: 14, width: 14,
@@ -89,8 +89,8 @@ export const JellyserrRatings: React.FC<{
className='mr-1' className='mr-1'
source={ source={
data?.criticsRating === "Rotten" data?.criticsRating === "Rotten"
? require("@/utils/jellyseerr/src/assets/rt_rotten.svg") ? require("@/assets/images/rt_rotten.svg")
: require("@/utils/jellyseerr/src/assets/rt_fresh.svg") : require("@/assets/images/rt_fresh.svg")
} }
style={{ style={{
width: 14, width: 14,
@@ -109,8 +109,8 @@ export const JellyserrRatings: React.FC<{
className='mr-1' className='mr-1'
source={ source={
data?.audienceRating === "Spilled" data?.audienceRating === "Spilled"
? require("@/utils/jellyseerr/src/assets/rt_aud_rotten.svg") ? require("@/assets/images/rt_aud_rotten.svg")
: require("@/utils/jellyseerr/src/assets/rt_aud_fresh.svg") : require("@/assets/images/rt_aud_fresh.svg")
} }
style={{ style={{
width: 14, width: 14,
@@ -127,7 +127,7 @@ export const JellyserrRatings: React.FC<{
iconLeft={ iconLeft={
<Image <Image
className='mr-1' className='mr-1'
source={require("@/utils/jellyseerr/src/assets/tmdb_logo.svg")} source={require("@/assets/images/tmdb_logo.svg")}
style={{ style={{
width: 14, width: 14,
height: 14, height: 14,

View File

@@ -63,7 +63,7 @@ export const TrackSheet: React.FC<Props> = ({
<Text numberOfLines={1}> <Text numberOfLines={1}>
{selected === -1 && streamType === "Subtitle" {selected === -1 && streamType === "Subtitle"
? t("common.none") ? t("common.none")
: selectedSteam?.DisplayTitle || t("common.select", "Select")} : selectedSteam?.DisplayTitle || t("common.select")}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>

View File

@@ -2,7 +2,7 @@ import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { useMemo } from "react"; import { useMemo } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ScrollView, View } from "react-native"; import { Platform, ScrollView, TextInput, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Text } from "@/components/common/Text"; import { Text } from "@/components/common/Text";
import { TVDiscover } from "@/components/jellyseerr/discover/TVDiscover"; import { TVDiscover } from "@/components/jellyseerr/discover/TVDiscover";
@@ -231,26 +231,48 @@ export const TVSearchPage: React.FC<TVSearchPageProps> = ({
paddingTop: insets.top + TOP_PADDING, paddingTop: insets.top + TOP_PADDING,
}} }}
> >
{/* Native tvOS search field (SwiftUI `.searchable`, our `tv-search` {/* Search bar: native tvOS SwiftUI `.searchable` on Apple TV, standard
module). It renders the native search bar + grid keyboard and TextInput fallback on Android TV (the native module is Apple-only). */}
forwards typed text into the existing query pipeline via setSearch; {Platform.OS === "ios" ? (
our own results grid renders below. */} <View
{/* No horizontal margin here: the native tvOS search bar centers itself style={{
and renders a trailing "Hold to Dictate in <Language>" hint. Extra marginBottom: 24,
margins squeeze the bar's width and clip that trailing hint, so let height: SEARCH_AREA_HEIGHT,
the native view span the full width and own its own insets. */} }}
<View >
style={{ {/* No horizontal margin here: the native tvOS search bar centers
marginBottom: 24, itself and renders a trailing "Hold to Dictate" hint. */}
height: SEARCH_AREA_HEIGHT, <TvSearchView
}} style={{ width: "100%", height: "100%" }}
> placeholder={t("search.search")}
<TvSearchView onChangeText={(e) => setSearch(e.nativeEvent.text)}
style={{ width: "100%", height: "100%" }} />
placeholder={t("search.search")} </View>
onChangeText={(e) => setSearch(e.nativeEvent.text)} ) : (
/> <View
</View> style={{
marginHorizontal: HORIZONTAL_PADDING,
marginBottom: 24,
}}
>
<TextInput
style={{
height: 56,
width: "100%",
backgroundColor: "#262626",
borderRadius: 12,
paddingHorizontal: 20,
fontSize: 28,
color: "#fff",
}}
placeholder={t("search.search")}
placeholderTextColor='rgba(255,255,255,0.4)'
onChangeText={setSearch}
defaultValue=''
autoFocus={false}
/>
</View>
)}
</View> </View>
<ScrollView <ScrollView

View File

@@ -1,10 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application> <application>
<receiver <receiver android:name=".TvRecommendationsReceiver" android:exported="true">
android:name=".TvRecommendationsReceiver"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" /> <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
</application> </application>

View File

@@ -61,31 +61,61 @@ internal object TvRecommendationsPublisher {
fun clear(context: Context): Boolean { fun clear(context: Context): Boolean {
val prefs = preferences(context) val prefs = preferences(context)
val channelId = prefs.getLong(KEY_CHANNEL_ID, -1L)
val programIds = prefs.getString(KEY_PROGRAM_IDS, null)?.let(::JSONObject)
val contentResolver = context.contentResolver val contentResolver = context.contentResolver
if (programIds != null) { // KEY_PROGRAM_IDS is now { channelId: "{ providerId: programId }" }
val allProgramIds = prefs.getString(KEY_PROGRAM_IDS, null)?.let(::JSONObject)
if (allProgramIds != null) {
var deletedPrograms = 0 var deletedPrograms = 0
val keys = programIds.keys() val channelKeys = allProgramIds.keys()
while (keys.hasNext()) { while (channelKeys.hasNext()) {
val key = keys.next() val channelIdStr = channelKeys.next()
val programId = programIds.optLong(key, -1L) val programIdsJson = allProgramIds.optString(channelIdStr)
if (programId > 0L) { if (programIdsJson.isBlank()) continue
contentResolver.delete(
TvContractCompat.buildPreviewProgramUri(programId), try {
null, val programIds = JSONObject(programIdsJson)
null val keys = programIds.keys()
) while (keys.hasNext()) {
deletedPrograms += 1 val providerId = keys.next()
val programId = programIds.optLong(providerId, -1L)
if (programId > 0L) {
deletePreviewProgram(contentResolver, programId)
deletedPrograms += 1
}
}
} catch (e: Exception) {
Log.w(TAG, "clear(): failed to parse programIds for channel $channelIdStr", e)
} }
// Notify the channel
val channelId = channelIdStr.toLongOrNull() ?: -1L
if (channelId > 0L) {
try {
contentResolver.notifyChange(TvContractCompat.buildChannelUri(channelId), null)
} catch (e: SecurityException) {
Log.w(TAG, "clear(): lost provider permission, cannot notify channel $channelId", e)
}
}
// Remove per-channel pref
prefs.edit().remove("programIds_$channelIdStr").apply()
} }
Log.d(TAG, "clear(): deleted $deletedPrograms preview program(s)") Log.d(TAG, "clear(): deleted $deletedPrograms preview program(s)")
} }
if (channelId > 0L) { // Also handle legacy format (flat { providerId: programId }) for migration
contentResolver.notifyChange(TvContractCompat.buildChannelUri(channelId), null) val legacyProgramIds = prefs.getString("legacy_" + KEY_PROGRAM_IDS, null)?.let(::JSONObject)
Log.d(TAG, "clear(): notified channel $channelId") if (legacyProgramIds != null) {
val keys = legacyProgramIds.keys()
while (keys.hasNext()) {
val key = keys.next()
val programId = legacyProgramIds.optLong(key, -1L)
if (programId > 0L) {
deletePreviewProgram(contentResolver, programId)
}
}
prefs.edit().remove("legacy_" + KEY_PROGRAM_IDS).apply()
} }
prefs.edit() prefs.edit()
@@ -96,126 +126,262 @@ internal object TvRecommendationsPublisher {
return true return true
} }
/**
* Delete a single preview program from the TvProvider.
* Called by clear(), synchronize() (stale programs), and TvRecommendationsReceiver (user removed).
*/
fun deletePreviewProgram(context: Context, programId: Long) {
try {
context.contentResolver.delete(
TvContractCompat.buildPreviewProgramUri(programId),
null,
null
)
Log.d(TAG, "deletePreviewProgram(): deleted programId=$programId")
// Also remove from stored programIds prefs
removeProgramFromPrefs(context, programId)
} catch (e: SecurityException) {
Log.w(TAG, "deletePreviewProgram(): lost provider permission for programId=$programId", e)
}
}
private fun deletePreviewProgram(contentResolver: android.content.ContentResolver, programId: Long) {
try {
contentResolver.delete(
TvContractCompat.buildPreviewProgramUri(programId),
null,
null
)
} catch (e: SecurityException) {
Log.w(TAG, "deletePreviewProgram(): lost provider permission for programId=$programId", e)
}
}
private fun removeProgramFromPrefs(context: Context, programId: Long) {
val prefs = preferences(context)
val programIdsJson = prefs.getString(KEY_PROGRAM_IDS, null) ?: return
try {
val programIds = JSONObject(programIdsJson)
val keys = programIds.keys()
while (keys.hasNext()) {
val key = keys.next()
if (programIds.optLong(key, -1L) == programId) {
programIds.remove(key)
break
}
}
prefs.edit().putString(KEY_PROGRAM_IDS, programIds.toString()).apply()
} catch (e: Exception) {
Log.w(TAG, "removeProgramFromPrefs(): failed to update prefs for programId=$programId", e)
}
}
private fun synchronize(context: Context, payload: JSONObject): Boolean { private fun synchronize(context: Context, payload: JSONObject): Boolean {
val sections = payload.optJSONArray("sections") ?: JSONArray() val sections = payload.optJSONArray("sections") ?: JSONArray()
val firstSection = if (sections.length() > 0) sections.optJSONObject(0) else null if (sections.length() == 0) {
val sectionTitle = firstSection?.optString("title")?.takeIf { it.isNotBlank() } ?: DEFAULT_CHANNEL_NAME Log.w(TAG, "synchronize(): no sections in payload")
val items = firstSection?.optJSONArray("items") ?: JSONArray()
Log.d(
TAG,
"synchronize(): using section \"$sectionTitle\" with ${items.length()} item(s)"
)
val channelId = getOrCreateChannel(context, sectionTitle)
if (channelId <= 0L) {
Log.w(TAG, "synchronize(): failed to get or create preview channel")
return false return false
} }
Log.d(TAG, "synchronize(): publishing into channelId=$channelId") val prefs = preferences(context)
val allNextProgramIds = JSONObject()
var totalActive = 0
var totalDeleted = 0
val previousProgramIds = preferences(context) for (sectionIndex in 0 until sections.length()) {
.getString(KEY_PROGRAM_IDS, null) val section = sections.optJSONObject(sectionIndex) ?: continue
?.let(::JSONObject) val sectionTitle = section.optString("title")?.takeIf { it.isNotBlank() } ?: DEFAULT_CHANNEL_NAME
?: JSONObject() val items = section.optJSONArray("items") ?: JSONArray()
val nextProgramIds = JSONObject()
val activeProviderIds = mutableSetOf<String>()
for (index in 0 until items.length()) { Log.d(
val item = items.optJSONObject(index) ?: continue TAG,
val providerId = item.optString("id") "synchronize(): section \"$sectionTitle\" ($sectionIndex/${sections.length()}) with ${items.length()} item(s)"
if (providerId.isBlank()) continue
val programId = upsertPreviewProgram(
context = context,
channelId = channelId,
item = item,
previousProgramId = previousProgramIds.optLong(providerId, -1L),
weight = index
) )
if (programId > 0L) { val channelId = getOrCreateChannel(context, sectionTitle)
activeProviderIds += providerId if (channelId <= 0L) {
nextProgramIds.put(providerId, programId) Log.w(TAG, "synchronize(): failed to get or create channel for \"$sectionTitle\"")
Log.d(TAG, "synchronize(): upserted program for item=$providerId programId=$programId") continue
} }
}
var deletedPrograms = 0 // Per Android docs: check channel.isBrowsable() and request if needed.
val previousKeys = previousProgramIds.keys() if (!isChannelBrowsable(context, channelId)) {
while (previousKeys.hasNext()) { Log.d(TAG, "synchronize(): channel $channelId not browsable, requesting browsable")
val providerId = previousKeys.next() TvContractCompat.requestChannelBrowsable(context, channelId)
if (activeProviderIds.contains(providerId)) continue }
val programId = previousProgramIds.optLong(providerId, -1L) val prefKey = "programIds_$channelId"
if (programId > 0L) { val previousProgramIds = prefs.getString(prefKey, null)
context.contentResolver.delete( ?.let(::JSONObject)
TvContractCompat.buildPreviewProgramUri(programId), ?: JSONObject()
null, val nextProgramIds = JSONObject()
null val activeProviderIds = mutableSetOf<String>()
for (index in 0 until items.length()) {
val item = items.optJSONObject(index) ?: continue
val providerId = item.optString("id")
if (providerId.isBlank()) continue
val programId = upsertPreviewProgram(
context = context,
channelId = channelId,
item = item,
previousProgramId = previousProgramIds.optLong(providerId, -1L),
weight = index
) )
deletedPrograms += 1
Log.d(TAG, "synchronize(): deleted stale programId=$programId for item=$providerId") if (programId > 0L) {
activeProviderIds += providerId
nextProgramIds.put(providerId, programId)
Log.d(TAG, "synchronize(): upserted program for item=$providerId programId=$programId")
}
} }
var deletedPrograms = 0
val previousKeys = previousProgramIds.keys()
while (previousKeys.hasNext()) {
val providerId = previousKeys.next()
if (activeProviderIds.contains(providerId)) continue
val programId = previousProgramIds.optLong(providerId, -1L)
if (programId > 0L) {
deletePreviewProgram(context, programId)
deletedPrograms += 1
Log.d(TAG, "synchronize(): deleted stale programId=$programId for item=$providerId")
}
}
allNextProgramIds.put(channelId.toString(), nextProgramIds.toString())
prefs.edit().putString(prefKey, nextProgramIds.toString()).apply()
totalActive += activeProviderIds.size
totalDeleted += deletedPrograms
logProviderState(context, channelId)
} }
preferences(context) // Store all channel program IDs for clear() to use
.edit() prefs.edit().putString(KEY_PROGRAM_IDS, allNextProgramIds.toString()).apply()
.putLong(KEY_CHANNEL_ID, channelId)
.putString(KEY_PROGRAM_IDS, nextProgramIds.toString())
.apply()
logProviderState(context, channelId)
Log.d( Log.d(
TAG, TAG,
"synchronize(): completed with ${activeProviderIds.size} active program(s), deleted $deletedPrograms stale program(s)" "synchronize(): completed across ${sections.length()} section(s), $totalActive active program(s), deleted $totalDeleted stale program(s)"
) )
return true return true
} }
/**
* Query provider to check if a channel is browsable.
* Per Android docs: "check channel.isBrowsable() before updating programs."
*/
private fun isChannelBrowsable(context: Context, channelId: Long): Boolean {
return try {
context.contentResolver.query(
TvContractCompat.buildChannelUri(channelId),
null,
null,
null,
null
)?.use { cursor ->
if (cursor.moveToFirst()) {
val browsableIndex = cursor.getColumnIndex(TvContractCompat.Channels.COLUMN_BROWSABLE)
if (browsableIndex >= 0) cursor.getInt(browsableIndex) == 1 else true
} else {
false
}
} ?: false
} catch (e: SecurityException) {
Log.w(TAG, "isChannelBrowsable(): lost provider permission for channelId=$channelId", e)
true // Assume browsable if we can't check, to avoid blocking updates
}
}
/**
* Query provider to verify a channel actually exists.
* Prevents the channel-delete-recreate bug: if update() returns 0 rows
* we must first check whether the channel was deleted by the system
* or if the update simply failed for another reason.
*/
private fun channelExistsInProvider(context: Context, channelId: Long): Boolean {
return try {
context.contentResolver.query(
TvContractCompat.buildChannelUri(channelId),
null,
null,
null,
null
)?.use { cursor ->
cursor.moveToFirst()
} ?: false
} catch (e: SecurityException) {
Log.w(TAG, "channelExistsInProvider(): lost provider permission for channelId=$channelId", e)
false
}
}
private fun getOrCreateChannel(context: Context, displayName: String): Long { private fun getOrCreateChannel(context: Context, displayName: String): Long {
val prefs = preferences(context) val prefs = preferences(context)
val existingChannelId = prefs.getLong(KEY_CHANNEL_ID, -1L) val existingChannelId = prefs.getLong(KEY_CHANNEL_ID, -1L)
val contentResolver = context.contentResolver val contentResolver = context.contentResolver
if (existingChannelId > 0L) { if (existingChannelId > 0L) {
val updated = Channel.Builder() // Query provider first to verify channel actually exists (prevents recreate bug)
.setType(TvContractCompat.Channels.TYPE_PREVIEW) val exists = channelExistsInProvider(context, existingChannelId)
.setDisplayName(displayName)
.setAppLinkIntentUri(buildIntentUri(context, "streamyfin://"))
.build()
val updatedRows = contentResolver.update( if (exists) {
TvContractCompat.buildChannelUri(existingChannelId), // Channel exists — update it in place, never recreate
updated.toContentValues(), val updated = Channel.Builder()
null, .setType(TvContractCompat.Channels.TYPE_PREVIEW)
null .setDisplayName(displayName)
) .setAppLinkIntentUri(buildIntentUri(context, "streamyfin://"))
.build()
if (updatedRows > 0) { try {
TvContractCompat.requestChannelBrowsable(context, existingChannelId) val updatedRows = contentResolver.update(
storeChannelLogo(context, existingChannelId) TvContractCompat.buildChannelUri(existingChannelId),
Log.d(TAG, "getOrCreateChannel(): updated existing channelId=$existingChannelId and requested browsable") updated.toContentValues(),
return existingChannelId null,
null
)
if (updatedRows > 0) {
TvContractCompat.requestChannelBrowsable(context, existingChannelId)
storeChannelLogo(context, existingChannelId)
Log.d(TAG, "getOrCreateChannel(): updated existing channelId=$existingChannelId and requested browsable")
return existingChannelId
}
// Update returned 0 rows but channel exists — log and return existing ID, don't recreate
Log.e(TAG, "getOrCreateChannel(): update returned 0 for existing channelId=$existingChannelId but channel exists — not recreating")
return existingChannelId
} catch (e: SecurityException) {
Log.w(TAG, "getOrCreateChannel(): lost provider permission updating channelId=$existingChannelId", e)
return existingChannelId
}
} }
Log.w(TAG, "getOrCreateChannel(): stored channelId=$existingChannelId was stale, recreating") // Channel truly doesn't exist in provider — recreate
Log.w(TAG, "getOrCreateChannel(): channelId=$existingChannelId not in provider, recreating")
prefs.edit().remove(KEY_CHANNEL_ID).apply() prefs.edit().remove(KEY_CHANNEL_ID).apply()
} }
// Create a new channel
val channel = Channel.Builder() val channel = Channel.Builder()
.setType(TvContractCompat.Channels.TYPE_PREVIEW) .setType(TvContractCompat.Channels.TYPE_PREVIEW)
.setDisplayName(displayName) .setDisplayName(displayName)
.setAppLinkIntentUri(buildIntentUri(context, "streamyfin://")) .setAppLinkIntentUri(buildIntentUri(context, "streamyfin://"))
.build() .build()
val channelUri = contentResolver.insert( val channelUri = try {
TvContractCompat.Channels.CONTENT_URI, contentResolver.insert(
channel.toContentValues() TvContractCompat.Channels.CONTENT_URI,
) ?: return -1L channel.toContentValues()
)
} catch (e: SecurityException) {
Log.e(TAG, "getOrCreateChannel(): lost provider permission, cannot create channel", e)
null
} ?: return -1L
val channelId = ContentUris.parseId(channelUri) val channelId = ContentUris.parseId(channelUri)
TvContractCompat.requestChannelBrowsable(context, channelId) TvContractCompat.requestChannelBrowsable(context, channelId)
@@ -249,42 +415,62 @@ internal object TvRecommendationsPublisher {
builder.setDescription(it) builder.setDescription(it)
} }
// Per Android docs: use unique URIs for all images to avoid stale cache
imageUrl.takeIf { it.isNotBlank() }?.let { imageUrl.takeIf { it.isNotBlank() }?.let {
val imageUri = Uri.parse(it) val uniqueImageUrl = appendCacheBuster(it)
val imageUri = Uri.parse(uniqueImageUrl)
builder.setPosterArtUri(imageUri) builder.setPosterArtUri(imageUri)
builder.setThumbnailUri(imageUri) builder.setThumbnailUri(imageUri)
} }
val contentValues = builder.build().toContentValues() val contentValues = builder.build().toContentValues()
val contentResolver = context.contentResolver val contentResolver = context.contentResolver
if (previousProgramId > 0L) { if (previousProgramId > 0L) {
val updatedRows = contentResolver.update( try {
TvContractCompat.buildPreviewProgramUri(previousProgramId), val updatedRows = contentResolver.update(
contentValues, TvContractCompat.buildPreviewProgramUri(previousProgramId),
null, contentValues,
null null,
) null
)
if (updatedRows > 0) { if (updatedRows > 0) {
Log.d(TAG, "upsertPreviewProgram(): updated existing programId=$previousProgramId") Log.d(TAG, "upsertPreviewProgram(): updated existing programId=$previousProgramId")
return previousProgramId return previousProgramId
}
Log.w(TAG, "upsertPreviewProgram(): existing programId=$previousProgramId was stale, inserting new row")
} catch (e: SecurityException) {
Log.w(TAG, "upsertPreviewProgram(): lost provider permission for programId=$previousProgramId", e)
} }
Log.w(TAG, "upsertPreviewProgram(): existing programId=$previousProgramId was stale, inserting new row")
} }
val insertedUri = contentResolver.insert( val insertedUri = try {
TvContractCompat.PreviewPrograms.CONTENT_URI, contentResolver.insert(
contentValues TvContractCompat.PreviewPrograms.CONTENT_URI,
) ?: return -1L contentValues
)
} catch (e: SecurityException) {
Log.w(TAG, "upsertPreviewProgram(): lost provider permission, cannot insert program", e)
null
} ?: return -1L
val programId = ContentUris.parseId(insertedUri) val programId = ContentUris.parseId(insertedUri)
Log.d(TAG, "upsertPreviewProgram(): inserted new programId=$programId") Log.d(TAG, "upsertPreviewProgram(): inserted new programId=$programId")
return programId return programId
} }
/**
* Append a cache-busting parameter to ensure unique URIs when images change.
* Per Android docs: "Use unique Uris for all images... the old image will
* continue to appear if you don't change the Uri."
*/
private fun appendCacheBuster(imageUrl: String): String {
val separator = if (imageUrl.contains("?")) "&" else "?"
return "$imageUrl${separator}_t=${System.currentTimeMillis()}"
}
private fun buildIntentUri(context: Context, deepLink: String): Uri { private fun buildIntentUri(context: Context, deepLink: String): Uri {
val intent = Intent(Intent.ACTION_VIEW).apply { val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(deepLink) data = Uri.parse(deepLink)
@@ -306,13 +492,17 @@ internal object TvRecommendationsPublisher {
private fun storeChannelLogo(context: Context, channelId: Long) { private fun storeChannelLogo(context: Context, channelId: Long) {
val bitmap = applicationIconBitmap(context) ?: return val bitmap = applicationIconBitmap(context) ?: return
val outputStream = context.contentResolver.openOutputStream( try {
TvContractCompat.buildChannelLogoUri(channelId) val outputStream = context.contentResolver.openOutputStream(
) ?: return TvContractCompat.buildChannelLogoUri(channelId)
) ?: return
outputStream.use { stream -> outputStream.use { stream ->
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream) bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
stream.flush() stream.flush()
}
} catch (e: SecurityException) {
Log.w(TAG, "storeChannelLogo(): lost provider permission for channelId=$channelId", e)
} }
} }
@@ -341,9 +531,14 @@ internal object TvRecommendationsPublisher {
return bitmap return bitmap
} }
fun getChannelId(context: Context): Long {
return preferences(context).getLong(KEY_CHANNEL_ID, -1L)
}
private fun preferences(context: Context): SharedPreferences { private fun preferences(context: Context): SharedPreferences {
return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
} }
private fun logProviderState(context: Context, channelId: Long) { private fun logProviderState(context: Context, channelId: Long) {
val contentResolver = context.contentResolver val contentResolver = context.contentResolver
@@ -372,8 +567,8 @@ internal object TvRecommendationsPublisher {
Log.w(TAG, "logProviderState(): channelId=$channelId exists=false") Log.w(TAG, "logProviderState(): channelId=$channelId exists=false")
} }
} ?: Log.w(TAG, "logProviderState(): channel query returned null for channelId=$channelId") } ?: Log.w(TAG, "logProviderState(): channel query returned null for channelId=$channelId")
} catch (error: Exception) { } catch (error: SecurityException) {
Log.w(TAG, "logProviderState(): failed to query channelId=$channelId", error) Log.w(TAG, "logProviderState(): lost provider permission for channelId=$channelId", error)
} }
} }
} }

View File

@@ -1,12 +1,19 @@
import { requireNativeView } from "expo"; import { requireNativeView } from "expo";
import * as React from "react"; import * as React from "react";
import type { View } from "react-native"; import type { View } from "react-native";
import { Platform } from "react-native";
import type { TvSearchViewProps } from "./TvSearchView.types"; import type { TvSearchViewProps } from "./TvSearchView.types";
// The native TvSearchModule is Apple-only (tvOS SwiftUI `.searchable`).
// On Android the component is never rendered, but we must avoid calling
// `requireNativeView` at module-scope because it would crash on import.
const NativeView: React.ComponentType< const NativeView: React.ComponentType<
TvSearchViewProps & React.RefAttributes<View> TvSearchViewProps & React.RefAttributes<View>
> = requireNativeView("TvSearchModule"); > =
Platform.OS === "ios"
? requireNativeView("TvSearchModule")
: ((() => null) as any);
/** /**
* Forwards its ref to the underlying native view so it can be used as a * Forwards its ref to the underlying native view so it can be used as a

View File

@@ -1,5 +1,4 @@
import { getSessionApi } from "@jellyfin/sdk/lib/utils/api"; import { getSessionApi } from "@jellyfin/sdk/lib/utils/api";
import { router } from "expo-router";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import { import {
createContext, createContext,
@@ -12,6 +11,7 @@ import {
useState, useState,
} from "react"; } from "react";
import { AppState, type AppStateStatus } from "react-native"; import { AppState, type AppStateStatus } from "react-native";
import useRouter from "@/hooks/useAppRouter";
import { useNetworkAwareQueryClient } from "@/hooks/useNetworkAwareQueryClient"; import { useNetworkAwareQueryClient } from "@/hooks/useNetworkAwareQueryClient";
import { apiAtom, getOrSetDeviceId } from "@/providers/JellyfinProvider"; import { apiAtom, getOrSetDeviceId } from "@/providers/JellyfinProvider";
import { useNetworkStatus } from "@/providers/NetworkStatusProvider"; import { useNetworkStatus } from "@/providers/NetworkStatusProvider";
@@ -28,20 +28,6 @@ const LIBRARY_CHANGE_QUERY_KEYS = [
["episodes"], ["episodes"],
] as const; ] as const;
// Query keys that depend on per-user playback state (resume position, played
// status, favorites) and should be refreshed when the server reports a
// `UserDataChanged`. Scoped to the progression-based sections so finishing an
// episode does not pointlessly refetch "recently added" or suggestions.
const USER_DATA_CHANGE_QUERY_KEYS = [
["home", "continueAndNextUp"],
["home", "resumeItems"],
["home", "nextUp-all"],
["home", "heroItems"],
["resumeItems"],
["nextUp-all"],
["nextUp"],
] as const;
interface WebSocketMessage { interface WebSocketMessage {
MessageType: string; MessageType: string;
Data: any; Data: any;
@@ -52,30 +38,10 @@ interface WebSocketProviderProps {
children: ReactNode; children: ReactNode;
} }
/**
* Handler invoked for every message of a given `MessageType`. Receives the
* message `Data` payload and the full message.
*/
type WebSocketMessageHandler = (data: any, message: WebSocketMessage) => void;
interface WebSocketContextType { interface WebSocketContextType {
ws: WebSocket | null; ws: WebSocket | null;
isConnected: boolean; isConnected: boolean;
/**
* @deprecated Prefer `subscribe`. `lastMessage` only keeps the most recent
* message, so bursts arriving in the same tick are coalesced and lost. Kept
* for `useWebsockets` (GeneralCommand handling) until it is migrated.
*/
lastMessage: WebSocketMessage | null; lastMessage: WebSocketMessage | null;
/**
* Subscribe to a given message type. The handler is called synchronously for
* every matching message (no coalescing, unlike `lastMessage`). Returns an
* unsubscribe function to call on cleanup.
*/
subscribe: (
messageType: string,
handler: WebSocketMessageHandler,
) => () => void;
sendMessage: (message: any) => void; sendMessage: (message: any) => void;
clearLastMessage: () => void; clearLastMessage: () => void;
} }
@@ -88,6 +54,7 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
const [ws, setWs] = useState<WebSocket | null>(null); const [ws, setWs] = useState<WebSocket | null>(null);
const [isConnected, setIsConnected] = useState(false); const [isConnected, setIsConnected] = useState(false);
const [lastMessage, setLastMessage] = useState<WebSocketMessage | null>(null); const [lastMessage, setLastMessage] = useState<WebSocketMessage | null>(null);
const router = useRouter();
const queryClient = useNetworkAwareQueryClient(); const queryClient = useNetworkAwareQueryClient();
const deviceId = useMemo(() => { const deviceId = useMemo(() => {
return getOrSetDeviceId(); return getOrSetDeviceId();
@@ -96,52 +63,6 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
const libraryChangeDebounceRef = useRef<ReturnType<typeof setTimeout> | null>( const libraryChangeDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(
null, null,
); );
const userDataChangeDebounceRef = useRef<ReturnType<
typeof setTimeout
> | null>(null);
// Pub/sub registry: messageType -> set of handlers. Stored in a ref so
// subscribing/dispatching never triggers a re-render.
const listenersRef = useRef<Map<string, Set<WebSocketMessageHandler>>>(
new Map(),
);
const subscribe = useCallback(
(messageType: string, handler: WebSocketMessageHandler) => {
const listeners = listenersRef.current;
let handlers = listeners.get(messageType);
if (!handlers) {
handlers = new Set();
listeners.set(messageType, handlers);
}
handlers.add(handler);
return () => {
handlers?.delete(handler);
if (handlers && handlers.size === 0) {
listeners.delete(messageType);
}
};
},
[],
);
const dispatchMessage = useCallback((message: WebSocketMessage) => {
const handlers = listenersRef.current.get(message.MessageType);
if (!handlers || handlers.size === 0) return;
// Copy to tolerate handlers that unsubscribe during dispatch.
for (const handler of [...handlers]) {
// Isolate each handler so one throwing subscriber can't abort the rest
// (and isn't misreported as a parse failure by the outer onmessage catch).
try {
handler(message.Data, message);
} catch (error) {
console.error(
`Error handling WebSocket message type "${message.MessageType}":`,
error,
);
}
}
}, []);
const connectWebSocket = useCallback(() => { const connectWebSocket = useCallback(() => {
if (!deviceId || !api?.accessToken || !isNetworkConnected) { if (!deviceId || !api?.accessToken || !isNetworkConnected) {
@@ -192,10 +113,7 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
newWebSocket.onmessage = (e) => { newWebSocket.onmessage = (e) => {
try { try {
const message = JSON.parse(e.data); const message = JSON.parse(e.data);
// Legacy single-slot state, still consumed by useWebsockets. setLastMessage(message); // Store the last message in context
setLastMessage(message);
// Pub/sub: deliver to every subscriber without coalescing.
dispatchMessage(message);
} catch (error) { } catch (error) {
console.error("Error parsing WebSocket message:", error); console.error("Error parsing WebSocket message:", error);
} }
@@ -208,7 +126,7 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
} }
newWebSocket.close(); newWebSocket.close();
}; };
}, [api, deviceId, isNetworkConnected, dispatchMessage]); }, [api, deviceId, isNetworkConnected]);
const handleLibraryChanged = useCallback( const handleLibraryChanged = useCallback(
(data: any) => { (data: any) => {
@@ -239,77 +157,47 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
[queryClient], [queryClient],
); );
const handleUserDataChanged = useCallback( useEffect(() => {
(data: any) => { if (!lastMessage) {
// Jellyfin sends UserDataChanged when playback position, played status return;
// or favorites change (e.g. finishing an episode). Only the }
// progression-based home sections care about it. if (lastMessage.MessageType === "Play") {
if (!((data?.UserDataList?.length ?? 0) > 0)) { handlePlayCommand(lastMessage.Data);
return; } else if (lastMessage.MessageType === "LibraryChanged") {
} handleLibraryChanged(lastMessage.Data);
}
// Finishing an item can emit several UserDataChanged messages, so }, [lastMessage, router, handleLibraryChanged]);
// debounce to invalidate the affected sections only once.
if (userDataChangeDebounceRef.current) {
clearTimeout(userDataChangeDebounceRef.current);
}
userDataChangeDebounceRef.current = setTimeout(() => {
for (const queryKey of USER_DATA_CHANGE_QUERY_KEYS) {
queryClient.invalidateQueries({ queryKey: [...queryKey] });
}
}, 800);
},
[queryClient],
);
// Refresh library-dependent queries when the server reports a change.
useEffect(
() => subscribe("LibraryChanged", handleLibraryChanged),
[subscribe, handleLibraryChanged],
);
// Refresh "Continue Watching" / "Next Up" when playback state changes.
useEffect(
() => subscribe("UserDataChanged", handleUserDataChanged),
[subscribe, handleUserDataChanged],
);
useEffect(() => { useEffect(() => {
return () => { return () => {
if (libraryChangeDebounceRef.current) { if (libraryChangeDebounceRef.current) {
clearTimeout(libraryChangeDebounceRef.current); clearTimeout(libraryChangeDebounceRef.current);
} }
if (userDataChangeDebounceRef.current) {
clearTimeout(userDataChangeDebounceRef.current);
}
}; };
}, []); }, []);
const handlePlayCommand = useCallback((data: any) => { const handlePlayCommand = useCallback(
if (!data?.ItemIds?.length) { (data: any) => {
return; if (!data?.ItemIds?.length) {
} return;
}
const itemId = data.ItemIds[0]; const itemId = data.ItemIds[0];
router.push({ router.push({
pathname: "/(auth)/player/direct-player", pathname: "/(auth)/player/direct-player",
params: { params: {
itemId: itemId, itemId: itemId,
playCommand: data.PlayCommand || "PlayNow", playCommand: data.PlayCommand || "PlayNow",
audioIndex: data.AudioStreamIndex?.toString(), audioIndex: data.AudioStreamIndex?.toString(),
subtitleIndex: data.SubtitleStreamIndex?.toString(), subtitleIndex: data.SubtitleStreamIndex?.toString(),
mediaSourceId: data.MediaSourceId || "", mediaSourceId: data.MediaSourceId || "",
bitrateValue: "", bitrateValue: "",
offline: "false", offline: "false",
}, },
}); });
}, []); },
[router],
// Server-initiated "Play me this item" remote command.
useEffect(
() => subscribe("Play", handlePlayCommand),
[subscribe, handlePlayCommand],
); );
useEffect(() => { useEffect(() => {
@@ -379,14 +267,7 @@ export const WebSocketProvider = ({ children }: WebSocketProviderProps) => {
}, []); }, []);
return ( return (
<WebSocketContext.Provider <WebSocketContext.Provider
value={{ value={{ ws, isConnected, lastMessage, sendMessage, clearLastMessage }}
ws,
isConnected,
lastMessage,
subscribe,
sendMessage,
clearLastMessage,
}}
> >
{children} {children}
</WebSocketContext.Provider> </WebSocketContext.Provider>

View File

@@ -0,0 +1,236 @@
#!/usr/bin/env bun
/**
* Flags likely-duplicate issues when a new issue is opened, using lexical similarity
* (Jaccard over word sets of the title and body) — no API key, no embeddings.
*
* On a match it posts ONE comment listing the closest open issues and adds the
* "possible duplicate" label. If nothing is similar enough, it does nothing.
*
* Env:
* GITHUB_REPOSITORY owner/repo
* ISSUE_NUMBER the new issue number
* ISSUE_TITLE the new issue title
* ISSUE_BODY the new issue body
* GH_TOKEN/GITHUB_TOKEN for gh (provided in CI)
* DUP_THRESHOLD similarity threshold 0..1 (default 0.3)
* DUP_MAX max matches to report (default 5)
* DUP_FIXTURE optional path to a JSON array of {number,title,body} (local testing)
* DRY_RUN if set, print results instead of commenting/labelling
*/
import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
// Parse a numeric env var, falling back to `def` only when unset/empty/NaN so an explicit 0 is honoured.
const numEnv = (name, def) => {
const raw = process.env[name];
if (raw === undefined || raw === "") return def;
const n = Number(raw);
return Number.isNaN(n) ? def : n;
};
const REPO = process.env.GITHUB_REPOSITORY || "streamyfin/streamyfin";
const NUMBER = numEnv("ISSUE_NUMBER", Number.NaN);
const TITLE = process.env.ISSUE_TITLE || "";
const BODY = process.env.ISSUE_BODY || "";
const THRESHOLD = numEnv("DUP_THRESHOLD", 0.3);
const MAX = numEnv("DUP_MAX", 5);
const DRY = !!process.env.DRY_RUN;
const LABEL = "possible duplicate";
const MARKER = "<!-- duplicate-detector -->";
// Generic stop words only — keep domain/feature/platform words (android, downloads,
// subtitles…) since those are exactly what makes two reports the same or different.
const STOP = new Set(
(
"a an the and or but if then of to in on at by for with from as is are was were be been being do does did " +
"it its this that these those i you we they me my your our their he she him her " +
"when while where what which who how why so just then than too very can could would should will " +
"not no nor only own same s t don dont im ive please thanks hi hello also still get got use used using " +
"app application streamyfin issue bug"
).split(/\s+/),
);
const stem = (w) => w.replace(/(ing|ed|es|s)$/, "");
const tokens = (s) =>
(s || "")
.toLowerCase()
.replace(/```[\s\S]*?```/g, " ") // drop code blocks
.replace(/<!--[\s\S]*?-->/g, " ") // drop html comments
.replace(/https?:\/\/\S+/g, " ") // drop urls
.replace(/[^a-z0-9\s]/g, " ")
.split(/\s+/)
.filter((w) => w.length > 2 && !STOP.has(w))
.map(stem)
.filter((w) => w.length > 2);
const jaccard = (a, b) => {
const A = new Set(a);
const B = new Set(b);
if (!A.size || !B.size) return 0;
let inter = 0;
for (const x of A) if (B.has(x)) inter++;
return inter / (A.size + B.size - inter);
};
const newTitle = tokens(TITLE);
const newBody = tokens(BODY);
const score = (o) =>
0.6 * jaccard(newTitle, tokens(o.title)) +
0.4 * jaccard(newBody, tokens(o.body));
// fetch open issues (excluding PRs and the new issue itself)
let issues;
if (process.env.DUP_FIXTURE) {
issues = JSON.parse(readFileSync(process.env.DUP_FIXTURE, "utf8"));
} else {
const raw = execFileSync(
"gh",
[
"api",
`repos/${REPO}/issues`,
"--paginate",
"-X",
"GET",
"-f",
"state=open",
"-f",
"per_page=100",
"--jq",
".[] | select(.pull_request | not) | {number, title, body}",
],
{ encoding: "utf8", maxBuffer: 1e8 },
);
issues = raw
.split("\n")
.filter(Boolean)
.map((l) => JSON.parse(l));
}
const matches = issues
.filter((o) => o.number !== NUMBER)
.map((o) => ({ ...o, s: score(o) }))
.filter((o) => o.s >= THRESHOLD)
.sort((a, b) => b.s - a.s)
.slice(0, MAX);
if (!matches.length) {
console.log("No likely duplicates found.");
process.exit(0);
}
// Neutralise other issues' titles before echoing them back: break @mentions and
// strip markdown/HTML control chars so a maliciously-named issue can't ping people
// or inject formatting into our comment. GitHub linkifies "#123" on its own.
const safeTitle = (t) =>
(t || "")
.replace(/@/g, "@")
.replace(/[`<>|*_~[\]]/g, " ")
.replace(/\s+/g, " ")
.trim()
.slice(0, 140);
const list = matches
.map(
(m) =>
`- #${m.number}${safeTitle(m.title)} (≈ ${Math.round(m.s * 100)}% similar)`,
)
.join("\n");
const comment = [
MARKER,
"🔍 **This looks like it might be a duplicate.** Possibly related open issues:",
"",
list,
"",
"If yours is different, ignore this — a maintainer will confirm. Otherwise, please 👍 the existing issue and add any extra details there.",
].join("\n");
console.log(`Found ${matches.length} possible duplicate(s):\n${list}`);
if (DRY) {
console.log("\nDRY_RUN: not commenting/labelling.");
process.exit(0);
}
// Live mode needs a real issue number; refuse rather than POST to /issues/NaN/...
if (!Number.isInteger(NUMBER) || NUMBER <= 0) {
console.error(
`Invalid ISSUE_NUMBER ${JSON.stringify(process.env.ISSUE_NUMBER)} — refusing to comment.`,
);
process.exit(1);
}
// Idempotency: skip if we've already flagged this issue (guards re-runs / future triggers).
const priorComments = execFileSync(
"gh",
[
"api",
`repos/${REPO}/issues/${NUMBER}/comments`,
"--paginate",
"--jq",
".[].body",
],
{ encoding: "utf8", maxBuffer: 1e8 },
);
if (priorComments.includes(MARKER)) {
console.log("Already flagged (marker present); skipping.");
process.exit(0);
}
execFileSync(
"gh",
[
"api",
"-X",
"POST",
`repos/${REPO}/issues/${NUMBER}/comments`,
"-f",
`body=${comment}`,
],
{ stdio: "ignore" },
);
try {
execFileSync(
"gh",
[
"api",
"-X",
"POST",
`repos/${REPO}/issues/${NUMBER}/labels`,
"-f",
`labels[]=${LABEL}`,
],
{ stdio: "ignore" },
);
} catch {
// label may not exist yet — create then add
execFileSync(
"gh",
[
"api",
"-X",
"POST",
`repos/${REPO}/labels`,
"-f",
`name=${LABEL}`,
"-f",
"color=fbca04",
"-f",
"description=Automatically flagged as a possible duplicate",
],
{ stdio: "ignore" },
);
execFileSync(
"gh",
[
"api",
"-X",
"POST",
`repos/${REPO}/issues/${NUMBER}/labels`,
"-f",
`labels[]=${LABEL}`,
],
{ stdio: "ignore" },
);
}
console.log("Commented and labelled.");

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "التنزيلات", "downloads_title": "التنزيلات",
"tvseries": "مسلسلات", "series": "مسلسلات",
"movies": "أفلام", "movies": "أفلام",
"queue": "قائمة الانتظار", "queue": "قائمة الانتظار",
"other_media": "وسائط أخرى", "other_media": "وسائط أخرى",
@@ -524,7 +524,7 @@
"no_items_in_queue": "لا توجد عناصر في قائمة الانتظار", "no_items_in_queue": "لا توجد عناصر في قائمة الانتظار",
"no_downloaded_items": "لا توجد عناصر تم تنزيلها", "no_downloaded_items": "لا توجد عناصر تم تنزيلها",
"delete_all_movies_button": "حذف جميع الأفلام", "delete_all_movies_button": "حذف جميع الأفلام",
"delete_all_tvseries_button": "حذف جميع المسلسلات", "delete_all_series_button": "حذف جميع المسلسلات",
"delete_all_button": "حذف الكل", "delete_all_button": "حذف الكل",
"delete_all_other_media_button": "حذف الوسائط الأخرى", "delete_all_other_media_button": "حذف الوسائط الأخرى",
"active_download": "التنزيل الجاري", "active_download": "التنزيل الجاري",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "غير مسموح لك بتنزيل الملفات.", "you_are_not_allowed_to_download_files": "غير مسموح لك بتنزيل الملفات.",
"deleted_all_movies_successfully": "تم حذف جميع الأفلام بنجاح!", "deleted_all_movies_successfully": "تم حذف جميع الأفلام بنجاح!",
"failed_to_delete_all_movies": "فشل حذف جميع الأفلام", "failed_to_delete_all_movies": "فشل حذف جميع الأفلام",
"deleted_all_tvseries_successfully": "تم حذف جميع المسلسلات بنجاح!", "deleted_all_series_successfully": "تم حذف جميع المسلسلات بنجاح!",
"failed_to_delete_all_tvseries": "فشل حذف جميع المسلسلات", "failed_to_delete_all_series": "فشل حذف جميع المسلسلات",
"deleted_media_successfully": "تم حذف الوسائط الأخرى بنجاح!", "deleted_media_successfully": "تم حذف الوسائط الأخرى بنجاح!",
"failed_to_delete_media": "فشل حذف الوسائط الأخرى", "failed_to_delete_media": "فشل حذف الوسائط الأخرى",
"download_deleted": "تم حذف التنزيل", "download_deleted": "تم حذف التنزيل",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Descàrregues", "downloads_title": "Descàrregues",
"tvseries": "Sèries", "series": "Sèries",
"movies": "Pel·lícules", "movies": "Pel·lícules",
"queue": "Cua", "queue": "Cua",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "No hi ha elements a la cua", "no_items_in_queue": "No hi ha elements a la cua",
"no_downloaded_items": "No hi ha elements descarregats", "no_downloaded_items": "No hi ha elements descarregats",
"delete_all_movies_button": "Suprimeix totes les pel·lícules", "delete_all_movies_button": "Suprimeix totes les pel·lícules",
"delete_all_tvseries_button": "Suprimeix totes les sèries", "delete_all_series_button": "Suprimeix totes les sèries",
"delete_all_button": "Suprimeix-ho tot", "delete_all_button": "Suprimeix-ho tot",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "Descàrrega activa", "active_download": "Descàrrega activa",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "No teniu permís per descarregar fitxers.", "you_are_not_allowed_to_download_files": "No teniu permís per descarregar fitxers.",
"deleted_all_movies_successfully": "S'han suprimit totes les pel·lícules correctament!", "deleted_all_movies_successfully": "S'han suprimit totes les pel·lícules correctament!",
"failed_to_delete_all_movies": "No s'han pogut suprimir totes les pel·lícules", "failed_to_delete_all_movies": "No s'han pogut suprimir totes les pel·lícules",
"deleted_all_tvseries_successfully": "S'han suprimit totes les sèries correctament!", "deleted_all_series_successfully": "S'han suprimit totes les sèries correctament!",
"failed_to_delete_all_tvseries": "No s'han pogut suprimir totes les sèries", "failed_to_delete_all_series": "No s'han pogut suprimir totes les sèries",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Download Deleted", "download_deleted": "Download Deleted",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Stahování", "downloads_title": "Stahování",
"tvseries": "Televizní série", "series": "Televizní série",
"movies": "Filmy", "movies": "Filmy",
"queue": "Fronta", "queue": "Fronta",
"other_media": "Ostatní média", "other_media": "Ostatní média",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Žádné položky ve frontě", "no_items_in_queue": "Žádné položky ve frontě",
"no_downloaded_items": "Žádné stažené položky", "no_downloaded_items": "Žádné stažené položky",
"delete_all_movies_button": "Odstranit všechny filmy", "delete_all_movies_button": "Odstranit všechny filmy",
"delete_all_tvseries_button": "Odstranit všechny TV-série", "delete_all_series_button": "Odstranit všechny TV-série",
"delete_all_button": "Smazat vše", "delete_all_button": "Smazat vše",
"delete_all_other_media_button": "Odstranit ostatní média", "delete_all_other_media_button": "Odstranit ostatní média",
"active_download": "Aktivní stahování", "active_download": "Aktivní stahování",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Nemáte oprávnění stahovat soubory.", "you_are_not_allowed_to_download_files": "Nemáte oprávnění stahovat soubory.",
"deleted_all_movies_successfully": "Všechny filmy byly úspěšně smazány!", "deleted_all_movies_successfully": "Všechny filmy byly úspěšně smazány!",
"failed_to_delete_all_movies": "Nepodařilo se odstranit všechny filmy", "failed_to_delete_all_movies": "Nepodařilo se odstranit všechny filmy",
"deleted_all_tvseries_successfully": "Všechny série televizorů byly úspěšně smazány!", "deleted_all_series_successfully": "Všechny série televizorů byly úspěšně smazány!",
"failed_to_delete_all_tvseries": "Nepodařilo se odstranit všechny TV-série", "failed_to_delete_all_series": "Nepodařilo se odstranit všechny TV-série",
"deleted_media_successfully": "Ostatní média úspěšně smazána!", "deleted_media_successfully": "Ostatní média úspěšně smazána!",
"failed_to_delete_media": "Nepodařilo se odstranit ostatní média", "failed_to_delete_media": "Nepodařilo se odstranit ostatní média",
"download_deleted": "Stahování smazáno", "download_deleted": "Stahování smazáno",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "TV-serier", "series": "TV-serier",
"movies": "Film", "movies": "Film",
"queue": "Kø", "queue": "Kø",
"other_media": "Andre medier", "other_media": "Andre medier",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Ingen elementer i køen", "no_items_in_queue": "Ingen elementer i køen",
"no_downloaded_items": "Ingen downloadede elementer", "no_downloaded_items": "Ingen downloadede elementer",
"delete_all_movies_button": "Slet alle film", "delete_all_movies_button": "Slet alle film",
"delete_all_tvseries_button": "Slet alle TV-serier", "delete_all_series_button": "Slet alle TV-serier",
"delete_all_button": "Slet alle", "delete_all_button": "Slet alle",
"delete_all_other_media_button": "Slet andre medier", "delete_all_other_media_button": "Slet andre medier",
"active_download": "Aktiv download", "active_download": "Aktiv download",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Du har ikke tilladelse til at downloade filer.", "you_are_not_allowed_to_download_files": "Du har ikke tilladelse til at downloade filer.",
"deleted_all_movies_successfully": "Alle film er slettet med succes!", "deleted_all_movies_successfully": "Alle film er slettet med succes!",
"failed_to_delete_all_movies": "Kunne ikke slette alle film", "failed_to_delete_all_movies": "Kunne ikke slette alle film",
"deleted_all_tvseries_successfully": "Alle TV-serier er slettet med succes!", "deleted_all_series_successfully": "Alle TV-serier er slettet med succes!",
"failed_to_delete_all_tvseries": "Kunne ikke slette alle TV-serier", "failed_to_delete_all_series": "Kunne ikke slette alle TV-serier",
"deleted_media_successfully": "Slettede andre medier med succes!", "deleted_media_successfully": "Slettede andre medier med succes!",
"failed_to_delete_media": "Kunne ikke slette andre medier", "failed_to_delete_media": "Kunne ikke slette andre medier",
"download_deleted": "Download Slettet", "download_deleted": "Download Slettet",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "Serien", "series": "Serien",
"movies": "Filme", "movies": "Filme",
"queue": "Warteschlange", "queue": "Warteschlange",
"other_media": "Andere Medien", "other_media": "Andere Medien",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Keine Elemente in der Warteschlange", "no_items_in_queue": "Keine Elemente in der Warteschlange",
"no_downloaded_items": "Keine heruntergeladenen Elemente", "no_downloaded_items": "Keine heruntergeladenen Elemente",
"delete_all_movies_button": "Alle Filme löschen", "delete_all_movies_button": "Alle Filme löschen",
"delete_all_tvseries_button": "Alle Serien löschen", "delete_all_series_button": "Alle Serien löschen",
"delete_all_button": "Alles löschen", "delete_all_button": "Alles löschen",
"delete_all_other_media_button": "Alle anderen Medien löschen", "delete_all_other_media_button": "Alle anderen Medien löschen",
"active_download": "Aktiver Download", "active_download": "Aktiver Download",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Du hast keine Berechtigung, Dateien herunterzuladen", "you_are_not_allowed_to_download_files": "Du hast keine Berechtigung, Dateien herunterzuladen",
"deleted_all_movies_successfully": "Alle Filme erfolgreich gelöscht!", "deleted_all_movies_successfully": "Alle Filme erfolgreich gelöscht!",
"failed_to_delete_all_movies": "Fehler beim Löschen aller Filme", "failed_to_delete_all_movies": "Fehler beim Löschen aller Filme",
"deleted_all_tvseries_successfully": "Alle Serien erfolgreich gelöscht!", "deleted_all_series_successfully": "Alle Serien erfolgreich gelöscht!",
"failed_to_delete_all_tvseries": "Fehler beim Löschen aller Serien", "failed_to_delete_all_series": "Fehler beim Löschen aller Serien",
"deleted_media_successfully": "Andere Medien erfolgreich gelöscht!", "deleted_media_successfully": "Andere Medien erfolgreich gelöscht!",
"failed_to_delete_media": "Fehler beim Löschen anderer Medien", "failed_to_delete_media": "Fehler beim Löschen anderer Medien",
"download_deleted": "Download gelöscht", "download_deleted": "Download gelöscht",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Λήψεις", "downloads_title": "Λήψεις",
"tvseries": "Τηλεόραση-Σειρά", "series": "Τηλεόραση-Σειρά",
"movies": "Ταινίες", "movies": "Ταινίες",
"queue": "Ουρά", "queue": "Ουρά",
"other_media": "Άλλα μέσα", "other_media": "Άλλα μέσα",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Δεν υπάρχουν αντικείμενα στην ουρά", "no_items_in_queue": "Δεν υπάρχουν αντικείμενα στην ουρά",
"no_downloaded_items": "Δεν Έχουν Ληφθεί Αντικείμενα", "no_downloaded_items": "Δεν Έχουν Ληφθεί Αντικείμενα",
"delete_all_movies_button": "Διαγραφή Όλων Των Ταινιών", "delete_all_movies_button": "Διαγραφή Όλων Των Ταινιών",
"delete_all_tvseries_button": "Διαγραφή Όλων Των Τηλεοπτικών Σειρών", "delete_all_series_button": "Διαγραφή Όλων Των Τηλεοπτικών Σειρών",
"delete_all_button": "Διαγραφή Όλων", "delete_all_button": "Διαγραφή Όλων",
"delete_all_other_media_button": "Διαγραφή άλλων μέσων", "delete_all_other_media_button": "Διαγραφή άλλων μέσων",
"active_download": "Ενεργή Λήψη", "active_download": "Ενεργή Λήψη",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Δεν επιτρέπεται να κατεβάσετε αρχεία.", "you_are_not_allowed_to_download_files": "Δεν επιτρέπεται να κατεβάσετε αρχεία.",
"deleted_all_movies_successfully": "Διαγράφηκε Όλες Οι Ταινίες Επιτυχία!", "deleted_all_movies_successfully": "Διαγράφηκε Όλες Οι Ταινίες Επιτυχία!",
"failed_to_delete_all_movies": "Αποτυχία διαγραφής όλων των ταινιών", "failed_to_delete_all_movies": "Αποτυχία διαγραφής όλων των ταινιών",
"deleted_all_tvseries_successfully": "Διαγράφηκε Όλη Η Τηλεόραση-Σειρά Επιτυχία!", "deleted_all_series_successfully": "Διαγράφηκε Όλη Η Τηλεόραση-Σειρά Επιτυχία!",
"failed_to_delete_all_tvseries": "Αποτυχία διαγραφής Όλων των TV-Series", "failed_to_delete_all_series": "Αποτυχία διαγραφής Όλων των TV-Series",
"deleted_media_successfully": "Διαγράφηκε άλλο μέσο επιτυχώς!", "deleted_media_successfully": "Διαγράφηκε άλλο μέσο επιτυχώς!",
"failed_to_delete_media": "Αποτυχία διαγραφής άλλων πολυμέσων", "failed_to_delete_media": "Αποτυχία διαγραφής άλλων πολυμέσων",
"download_deleted": "Η Λήψη Διαγράφηκε", "download_deleted": "Η Λήψη Διαγράφηκε",

File diff suppressed because it is too large Load Diff

View File

@@ -229,14 +229,14 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Elŝutoj", "downloads_title": "Elŝutoj",
"tvseries": "Televidaj serioj", "series": "Televidaj serioj",
"movies": "Filmoj", "movies": "Filmoj",
"queue": "Vico", "queue": "Vico",
"queue_hint": "Vico kaj elŝutoj perdiĝos ĉe aplikaĵa rekomenco", "queue_hint": "Vico kaj elŝutoj perdiĝos ĉe aplikaĵa rekomenco",
"no_items_in_queue": "Neniuj eroj en vico", "no_items_in_queue": "Neniuj eroj en vico",
"no_downloaded_items": "Neniuj elŝutitaj eroj", "no_downloaded_items": "Neniuj elŝutitaj eroj",
"delete_all_movies_button": "Forigi ĉiujn Filmojn", "delete_all_movies_button": "Forigi ĉiujn Filmojn",
"delete_all_tvseries_button": "Forigi ĉiujn Televidajn Seriojn", "delete_all_series_button": "Forigi ĉiujn Televidajn Seriojn",
"delete_all_button": "Forigi ĉion", "delete_all_button": "Forigi ĉion",
"active_download": "Aktiva elŝuto", "active_download": "Aktiva elŝuto",
"no_active_downloads": "Neniuj aktivaj elŝutoj", "no_active_downloads": "Neniuj aktivaj elŝutoj",
@@ -253,8 +253,8 @@
"you_are_not_allowed_to_download_files": "Vi ne rajtas elŝuti dosierojn.", "you_are_not_allowed_to_download_files": "Vi ne rajtas elŝuti dosierojn.",
"deleted_all_movies_successfully": "Sukcese forigis ĉiujn filmojn!", "deleted_all_movies_successfully": "Sukcese forigis ĉiujn filmojn!",
"failed_to_delete_all_movies": "Malsukcesis forigi ĉiujn filmojn", "failed_to_delete_all_movies": "Malsukcesis forigi ĉiujn filmojn",
"deleted_all_tvseries_successfully": "Sukcese forigis ĉiujn Televidajn Seriojn!", "deleted_all_series_successfully": "Sukcese forigis ĉiujn Televidajn Seriojn!",
"failed_to_delete_all_tvseries": "Malsukcesis forigi ĉiujn Televidajn Seriojn", "failed_to_delete_all_series": "Malsukcesis forigi ĉiujn Televidajn Seriojn",
"download_cancelled": "Elŝuto nuligita", "download_cancelled": "Elŝuto nuligita",
"could_not_cancel_download": "Ne povis nuligi elŝuton", "could_not_cancel_download": "Ne povis nuligi elŝuton",
"download_completed": "Elŝuto finita", "download_completed": "Elŝuto finita",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Descargas", "downloads_title": "Descargas",
"tvseries": "Series", "series": "Series",
"movies": "Películas", "movies": "Películas",
"queue": "Cola", "queue": "Cola",
"other_media": "Otros medios", "other_media": "Otros medios",
@@ -524,7 +524,7 @@
"no_items_in_queue": "No hay ítems en la cola", "no_items_in_queue": "No hay ítems en la cola",
"no_downloaded_items": "No hay ítems descargados", "no_downloaded_items": "No hay ítems descargados",
"delete_all_movies_button": "Eliminar todas las películas", "delete_all_movies_button": "Eliminar todas las películas",
"delete_all_tvseries_button": "Eliminar todas las series", "delete_all_series_button": "Eliminar todas las series",
"delete_all_button": "Eliminar todo", "delete_all_button": "Eliminar todo",
"delete_all_other_media_button": "Eliminar otros medios", "delete_all_other_media_button": "Eliminar otros medios",
"active_download": "Descarga activa", "active_download": "Descarga activa",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "No tienes permiso para descargar archivos.", "you_are_not_allowed_to_download_files": "No tienes permiso para descargar archivos.",
"deleted_all_movies_successfully": "¡Todas las películas eliminadas con éxito!", "deleted_all_movies_successfully": "¡Todas las películas eliminadas con éxito!",
"failed_to_delete_all_movies": "Error al eliminar todas las películas", "failed_to_delete_all_movies": "Error al eliminar todas las películas",
"deleted_all_tvseries_successfully": "¡Todas las series eliminadas con éxito!", "deleted_all_series_successfully": "¡Todas las series eliminadas con éxito!",
"failed_to_delete_all_tvseries": "Error al eliminar todas las series", "failed_to_delete_all_series": "Error al eliminar todas las series",
"deleted_media_successfully": "¡Otros medios eliminados con éxito!", "deleted_media_successfully": "¡Otros medios eliminados con éxito!",
"failed_to_delete_media": "Error al eliminar otros medios", "failed_to_delete_media": "Error al eliminar otros medios",
"download_deleted": "Descarga eliminada", "download_deleted": "Descarga eliminada",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Lataukset", "downloads_title": "Lataukset",
"tvseries": "TV-sarjat", "series": "TV-sarjat",
"movies": "Elokuvat", "movies": "Elokuvat",
"queue": "Jonot", "queue": "Jonot",
"other_media": "Muu media", "other_media": "Muu media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Ei kohteita jonossa", "no_items_in_queue": "Ei kohteita jonossa",
"no_downloaded_items": "Ei ladattuja kohteita", "no_downloaded_items": "Ei ladattuja kohteita",
"delete_all_movies_button": "Poista kaikki elokuvat", "delete_all_movies_button": "Poista kaikki elokuvat",
"delete_all_tvseries_button": "Poista kaikki TV-sarjat", "delete_all_series_button": "Poista kaikki TV-sarjat",
"delete_all_button": "Poista kaikki", "delete_all_button": "Poista kaikki",
"delete_all_other_media_button": "Poista muu media", "delete_all_other_media_button": "Poista muu media",
"active_download": "Aktiivinen lataus", "active_download": "Aktiivinen lataus",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Sinulla ei ole lupaa ladata tiedostoja.", "you_are_not_allowed_to_download_files": "Sinulla ei ole lupaa ladata tiedostoja.",
"deleted_all_movies_successfully": "Kaikki elokuvat poistettu onnistuneesti!", "deleted_all_movies_successfully": "Kaikki elokuvat poistettu onnistuneesti!",
"failed_to_delete_all_movies": "Kaikkien elokuvien poistaminen epäonnistui", "failed_to_delete_all_movies": "Kaikkien elokuvien poistaminen epäonnistui",
"deleted_all_tvseries_successfully": "Kaikki TV-sarjat poistettu onnistuneesti!", "deleted_all_series_successfully": "Kaikki TV-sarjat poistettu onnistuneesti!",
"failed_to_delete_all_tvseries": "Kaikkien TV-sarjojen poistaminen epäonnistui", "failed_to_delete_all_series": "Kaikkien TV-sarjojen poistaminen epäonnistui",
"deleted_media_successfully": "Muu media poistettu onnistuneesti!", "deleted_media_successfully": "Muu media poistettu onnistuneesti!",
"failed_to_delete_media": "Muiden medioiden poistaminen epäonnistui", "failed_to_delete_media": "Muiden medioiden poistaminen epäonnistui",
"download_deleted": "Lataus Poistettu", "download_deleted": "Lataus Poistettu",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Téléchargements", "downloads_title": "Téléchargements",
"tvseries": "Séries", "series": "Séries",
"movies": "Films", "movies": "Films",
"queue": "File d'attente", "queue": "File d'attente",
"other_media": "Autres médias", "other_media": "Autres médias",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Aucun téléchargement de média dans la file d'attente", "no_items_in_queue": "Aucun téléchargement de média dans la file d'attente",
"no_downloaded_items": "Aucun média téléchargé", "no_downloaded_items": "Aucun média téléchargé",
"delete_all_movies_button": "Supprimer tous les films", "delete_all_movies_button": "Supprimer tous les films",
"delete_all_tvseries_button": "Supprimer toutes les séries", "delete_all_series_button": "Supprimer toutes les séries",
"delete_all_button": "Supprimer tous les médias", "delete_all_button": "Supprimer tous les médias",
"delete_all_other_media_button": "Supprimer un autre média", "delete_all_other_media_button": "Supprimer un autre média",
"active_download": "Téléchargement actif", "active_download": "Téléchargement actif",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Vous n'êtes pas autorisé à télécharger des fichiers.", "you_are_not_allowed_to_download_files": "Vous n'êtes pas autorisé à télécharger des fichiers.",
"deleted_all_movies_successfully": "Tous les films ont été supprimés avec succès!", "deleted_all_movies_successfully": "Tous les films ont été supprimés avec succès!",
"failed_to_delete_all_movies": "Échec de la suppression de tous les films", "failed_to_delete_all_movies": "Échec de la suppression de tous les films",
"deleted_all_tvseries_successfully": "Toutes les séries ont été supprimées avec succès!", "deleted_all_series_successfully": "Toutes les séries ont été supprimées avec succès!",
"failed_to_delete_all_tvseries": "Échec de la suppression de toutes les séries", "failed_to_delete_all_series": "Échec de la suppression de toutes les séries",
"deleted_media_successfully": "Les autres médias ont été supprimés avec succès !", "deleted_media_successfully": "Les autres médias ont été supprimés avec succès !",
"failed_to_delete_media": "Échec de la suppression d'un autre média", "failed_to_delete_media": "Échec de la suppression d'un autre média",
"download_deleted": "Téléchargement supprimé", "download_deleted": "Téléchargement supprimé",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "הורדות", "downloads_title": "הורדות",
"tvseries": "סדרות", "series": "סדרות",
"movies": "סרטים", "movies": "סרטים",
"queue": "תוֹר", "queue": "תוֹר",
"other_media": "תוכן אחר", "other_media": "תוכן אחר",
@@ -524,7 +524,7 @@
"no_items_in_queue": "אין פרטים בתור", "no_items_in_queue": "אין פרטים בתור",
"no_downloaded_items": "אין פריטים שהורדו", "no_downloaded_items": "אין פריטים שהורדו",
"delete_all_movies_button": "מחק את כל הסרטים", "delete_all_movies_button": "מחק את כל הסרטים",
"delete_all_tvseries_button": "מחק את כל הסדרות", "delete_all_series_button": "מחק את כל הסדרות",
"delete_all_button": "מחק הכל", "delete_all_button": "מחק הכל",
"delete_all_other_media_button": "מחק שאר תוכן", "delete_all_other_media_button": "מחק שאר תוכן",
"active_download": "הורדה פעילה", "active_download": "הורדה פעילה",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "אתה לא מורשה להוריד קבצים.", "you_are_not_allowed_to_download_files": "אתה לא מורשה להוריד קבצים.",
"deleted_all_movies_successfully": "כל הסרטים נמחקו בהצלחה!", "deleted_all_movies_successfully": "כל הסרטים נמחקו בהצלחה!",
"failed_to_delete_all_movies": "נכשל במחיקת כל הסרטים", "failed_to_delete_all_movies": "נכשל במחיקת כל הסרטים",
"deleted_all_tvseries_successfully": "כל הסדרות נמחקו בהצלחה!", "deleted_all_series_successfully": "כל הסדרות נמחקו בהצלחה!",
"failed_to_delete_all_tvseries": "נכשל במחיקת כל הסדרות", "failed_to_delete_all_series": "נכשל במחיקת כל הסדרות",
"deleted_media_successfully": "כל שאר התוכן נמחק בהצלחה!", "deleted_media_successfully": "כל שאר התוכן נמחק בהצלחה!",
"failed_to_delete_media": "נכשל במחיקת שאר התוכן", "failed_to_delete_media": "נכשל במחיקת שאר התוכן",
"download_deleted": "ההורדה נמחקה", "download_deleted": "ההורדה נמחקה",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Letöltések", "downloads_title": "Letöltések",
"tvseries": "Sorozatok", "series": "Sorozatok",
"movies": "Filmek", "movies": "Filmek",
"queue": "Sor", "queue": "Sor",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Nincs Elem a Sorban", "no_items_in_queue": "Nincs Elem a Sorban",
"no_downloaded_items": "Nincsenek Letöltött Elemek", "no_downloaded_items": "Nincsenek Letöltött Elemek",
"delete_all_movies_button": "Összes Film Törlése", "delete_all_movies_button": "Összes Film Törlése",
"delete_all_tvseries_button": "Összes Sorozat Törlése", "delete_all_series_button": "Összes Sorozat Törlése",
"delete_all_button": "Összes Törlése", "delete_all_button": "Összes Törlése",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "Aktív Letöltés", "active_download": "Aktív Letöltés",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Nem engedélyezett a fájlok letöltése.", "you_are_not_allowed_to_download_files": "Nem engedélyezett a fájlok letöltése.",
"deleted_all_movies_successfully": "Az Összes Film Sikeresen Törölve!", "deleted_all_movies_successfully": "Az Összes Film Sikeresen Törölve!",
"failed_to_delete_all_movies": "Nem Sikerült Törölni Az Összes Filmet", "failed_to_delete_all_movies": "Nem Sikerült Törölni Az Összes Filmet",
"deleted_all_tvseries_successfully": "Az Összes Sorozat Sikeresen Törölve!", "deleted_all_series_successfully": "Az Összes Sorozat Sikeresen Törölve!",
"failed_to_delete_all_tvseries": "Nem Sikerült Törölni Az Összes Sorozatot", "failed_to_delete_all_series": "Nem Sikerült Törölni Az Összes Sorozatot",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Letöltés Törölve", "download_deleted": "Letöltés Törölve",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Scaricati", "downloads_title": "Scaricati",
"tvseries": "Serie TV", "series": "Serie TV",
"movies": "Film", "movies": "Film",
"queue": "Coda", "queue": "Coda",
"other_media": "Altri supporti", "other_media": "Altri supporti",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Nessun elemento in coda", "no_items_in_queue": "Nessun elemento in coda",
"no_downloaded_items": "Nessun elemento scaricato", "no_downloaded_items": "Nessun elemento scaricato",
"delete_all_movies_button": "Cancella tutti i film", "delete_all_movies_button": "Cancella tutti i film",
"delete_all_tvseries_button": "Cancella tutte le serie TV", "delete_all_series_button": "Cancella tutte le serie TV",
"delete_all_button": "Cancella tutti", "delete_all_button": "Cancella tutti",
"delete_all_other_media_button": "Elimina altri supporti", "delete_all_other_media_button": "Elimina altri supporti",
"active_download": "Scaricamento in corso", "active_download": "Scaricamento in corso",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Non è consentito scaricare file.", "you_are_not_allowed_to_download_files": "Non è consentito scaricare file.",
"deleted_all_movies_successfully": "Cancellati tutti i film con successo!", "deleted_all_movies_successfully": "Cancellati tutti i film con successo!",
"failed_to_delete_all_movies": "Impossibile eliminare tutti i film", "failed_to_delete_all_movies": "Impossibile eliminare tutti i film",
"deleted_all_tvseries_successfully": "Eliminate tutte le serie TV con successo!", "deleted_all_series_successfully": "Eliminate tutte le serie TV con successo!",
"failed_to_delete_all_tvseries": "Impossibile eliminare tutte le serie TV", "failed_to_delete_all_series": "Impossibile eliminare tutte le serie TV",
"deleted_media_successfully": "Eliminato altri supporti con successo!", "deleted_media_successfully": "Eliminato altri supporti con successo!",
"failed_to_delete_media": "Impossibile eliminare altri media", "failed_to_delete_media": "Impossibile eliminare altri media",
"download_deleted": "Download Eliminato", "download_deleted": "Download Eliminato",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "ダウンロード", "downloads_title": "ダウンロード",
"tvseries": "TVシリーズ", "series": "TVシリーズ",
"movies": "映画", "movies": "映画",
"queue": "キュー", "queue": "キュー",
"other_media": "その他のメディア", "other_media": "その他のメディア",
@@ -524,7 +524,7 @@
"no_items_in_queue": "キューにアイテムがありません", "no_items_in_queue": "キューにアイテムがありません",
"no_downloaded_items": "ダウンロードしたアイテムはありません", "no_downloaded_items": "ダウンロードしたアイテムはありません",
"delete_all_movies_button": "すべての映画を削除", "delete_all_movies_button": "すべての映画を削除",
"delete_all_tvseries_button": "すべてのシリーズを削除", "delete_all_series_button": "すべてのシリーズを削除",
"delete_all_button": "すべて削除", "delete_all_button": "すべて削除",
"delete_all_other_media_button": "他のメディアを削除する", "delete_all_other_media_button": "他のメディアを削除する",
"active_download": "アクティブなダウンロード", "active_download": "アクティブなダウンロード",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "ファイルをダウンロードする権限がありません。", "you_are_not_allowed_to_download_files": "ファイルをダウンロードする権限がありません。",
"deleted_all_movies_successfully": "すべての映画を正常に削除しました!", "deleted_all_movies_successfully": "すべての映画を正常に削除しました!",
"failed_to_delete_all_movies": "すべての映画を削除できませんでした", "failed_to_delete_all_movies": "すべての映画を削除できませんでした",
"deleted_all_tvseries_successfully": "すべてのシリーズを正常に削除しました!", "deleted_all_series_successfully": "すべてのシリーズを正常に削除しました!",
"failed_to_delete_all_tvseries": "すべてのシリーズを削除できませんでした", "failed_to_delete_all_series": "すべてのシリーズを削除できませんでした",
"deleted_media_successfully": "他のメディアを削除しました!", "deleted_media_successfully": "他のメディアを削除しました!",
"failed_to_delete_media": "他のメディアの削除に失敗しました", "failed_to_delete_media": "他のメディアの削除に失敗しました",
"download_deleted": "ダウンロードが削除されました", "download_deleted": "ダウンロードが削除されました",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "TV-Series", "series": "TV-Series",
"movies": "Movies", "movies": "Movies",
"queue": "Queue", "queue": "Queue",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "No Items in Queue", "no_items_in_queue": "No Items in Queue",
"no_downloaded_items": "No Downloaded Items", "no_downloaded_items": "No Downloaded Items",
"delete_all_movies_button": "Delete All Movies", "delete_all_movies_button": "Delete All Movies",
"delete_all_tvseries_button": "Delete All TV-Series", "delete_all_series_button": "Delete All TV-Series",
"delete_all_button": "Delete All", "delete_all_button": "Delete All",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "Active Download", "active_download": "Active Download",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "You are not allowed to download files.", "you_are_not_allowed_to_download_files": "You are not allowed to download files.",
"deleted_all_movies_successfully": "Deleted All Movies Successfully!", "deleted_all_movies_successfully": "Deleted All Movies Successfully!",
"failed_to_delete_all_movies": "Failed to Delete All Movies", "failed_to_delete_all_movies": "Failed to Delete All Movies",
"deleted_all_tvseries_successfully": "Deleted All TV-Series Successfully!", "deleted_all_series_successfully": "Deleted All TV-Series Successfully!",
"failed_to_delete_all_tvseries": "Failed to Delete All TV-Series", "failed_to_delete_all_series": "Failed to Delete All TV-Series",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Download Deleted", "download_deleted": "Download Deleted",

View File

@@ -229,14 +229,14 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Nedlastinger", "downloads_title": "Nedlastinger",
"tvseries": "TV-serier", "series": "TV-serier",
"movies": "Filmer", "movies": "Filmer",
"queue": "Kø", "queue": "Kø",
"queue_hint": "Kø og nedlastinger vil gå tapt ved omstart av appen", "queue_hint": "Kø og nedlastinger vil gå tapt ved omstart av appen",
"no_items_in_queue": "Ingen elementer i køen", "no_items_in_queue": "Ingen elementer i køen",
"no_downloaded_items": "Ingen nedlastede elementer", "no_downloaded_items": "Ingen nedlastede elementer",
"delete_all_movies_button": "Slett alle filmer", "delete_all_movies_button": "Slett alle filmer",
"delete_all_tvseries_button": "Slett alle TV-serier", "delete_all_series_button": "Slett alle TV-serier",
"delete_all_button": "Slett alt", "delete_all_button": "Slett alt",
"active_download": "Aktiv nedlasting", "active_download": "Aktiv nedlasting",
"no_active_downloads": "Ingen aktive nedlastinger", "no_active_downloads": "Ingen aktive nedlastinger",
@@ -253,8 +253,8 @@
"you_are_not_allowed_to_download_files": "Du har ikke tillatelse til å laste ned filer.", "you_are_not_allowed_to_download_files": "Du har ikke tillatelse til å laste ned filer.",
"deleted_all_movies_successfully": "Alle filmer ble slettet!", "deleted_all_movies_successfully": "Alle filmer ble slettet!",
"failed_to_delete_all_movies": "Kunne ikke slette alle filmer", "failed_to_delete_all_movies": "Kunne ikke slette alle filmer",
"deleted_all_tvseries_successfully": "Alle TV-serier ble slettet!", "deleted_all_series_successfully": "Alle TV-serier ble slettet!",
"failed_to_delete_all_tvseries": "Kunne ikke slette alle TV-serier", "failed_to_delete_all_series": "Kunne ikke slette alle TV-serier",
"download_cancelled": "Nedlasting avbrutt", "download_cancelled": "Nedlasting avbrutt",
"could_not_cancel_download": "Kunne ikke avbryte nedlastingen", "could_not_cancel_download": "Kunne ikke avbryte nedlastingen",
"download_completed": "Nedlasting fullført", "download_completed": "Nedlasting fullført",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "Series", "series": "Series",
"movies": "Films", "movies": "Films",
"queue": "Wachtrij", "queue": "Wachtrij",
"other_media": "Andere media", "other_media": "Andere media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Geen items in wachtrij", "no_items_in_queue": "Geen items in wachtrij",
"no_downloaded_items": "Geen gedownloade items", "no_downloaded_items": "Geen gedownloade items",
"delete_all_movies_button": "Verwijder alle films", "delete_all_movies_button": "Verwijder alle films",
"delete_all_tvseries_button": "Verwijder alle Series", "delete_all_series_button": "Verwijder alle Series",
"delete_all_button": "Verwijder alles", "delete_all_button": "Verwijder alles",
"delete_all_other_media_button": "Andere media verwijderen", "delete_all_other_media_button": "Andere media verwijderen",
"active_download": "Actieve download", "active_download": "Actieve download",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Je mag geen bestanden downloaden.", "you_are_not_allowed_to_download_files": "Je mag geen bestanden downloaden.",
"deleted_all_movies_successfully": "Alle films succesvol verwijderd!", "deleted_all_movies_successfully": "Alle films succesvol verwijderd!",
"failed_to_delete_all_movies": "Alle films zijn niet verwijderd", "failed_to_delete_all_movies": "Alle films zijn niet verwijderd",
"deleted_all_tvseries_successfully": "Alle series succesvol verwijderd!", "deleted_all_series_successfully": "Alle series succesvol verwijderd!",
"failed_to_delete_all_tvseries": "Alle series zijn niet verwijderd", "failed_to_delete_all_series": "Alle series zijn niet verwijderd",
"deleted_media_successfully": "Andere media succesvol verwijderd!", "deleted_media_successfully": "Andere media succesvol verwijderd!",
"failed_to_delete_media": "Verwijderen van andere media mislukt", "failed_to_delete_media": "Verwijderen van andere media mislukt",
"download_deleted": "Download verwijderd", "download_deleted": "Download verwijderd",

View File

@@ -229,14 +229,14 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Nedlastingar", "downloads_title": "Nedlastingar",
"tvseries": "TV-seriar", "series": "TV-seriar",
"movies": "Filmar", "movies": "Filmar",
"queue": "Kø", "queue": "Kø",
"queue_hint": "Kø og nedlastingar vil gå tapt ved omstart av appen", "queue_hint": "Kø og nedlastingar vil gå tapt ved omstart av appen",
"no_items_in_queue": "Ingen element i køen", "no_items_in_queue": "Ingen element i køen",
"no_downloaded_items": "Ingen nedlasta element", "no_downloaded_items": "Ingen nedlasta element",
"delete_all_movies_button": "Slett alle filmar", "delete_all_movies_button": "Slett alle filmar",
"delete_all_tvseries_button": "Slett alle TV-seriar", "delete_all_series_button": "Slett alle TV-seriar",
"delete_all_button": "Slett alt", "delete_all_button": "Slett alt",
"active_download": "Aktiv nedlasting", "active_download": "Aktiv nedlasting",
"no_active_downloads": "Ingen aktive nedlastingar", "no_active_downloads": "Ingen aktive nedlastingar",
@@ -253,8 +253,8 @@
"you_are_not_allowed_to_download_files": "Du har ikkje løyve til å lasta ned filer.", "you_are_not_allowed_to_download_files": "Du har ikkje løyve til å lasta ned filer.",
"deleted_all_movies_successfully": "Alle filmar vart sletta!", "deleted_all_movies_successfully": "Alle filmar vart sletta!",
"failed_to_delete_all_movies": "Kunne ikkje sletta alle filmar", "failed_to_delete_all_movies": "Kunne ikkje sletta alle filmar",
"deleted_all_tvseries_successfully": "Alle TV-seriar vart sletta!", "deleted_all_series_successfully": "Alle TV-seriar vart sletta!",
"failed_to_delete_all_tvseries": "Kunne ikkje sletta alle TV-seriar", "failed_to_delete_all_series": "Kunne ikkje sletta alle TV-seriar",
"download_cancelled": "Nedlasting avbroten", "download_cancelled": "Nedlasting avbroten",
"could_not_cancel_download": "Kunne ikkje avbryta nedlastinga", "could_not_cancel_download": "Kunne ikkje avbryta nedlastinga",
"download_completed": "Nedlasting fullført", "download_completed": "Nedlasting fullført",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Nedlastinger", "downloads_title": "Nedlastinger",
"tvseries": "TV-Serier", "series": "TV-Serier",
"movies": "Filmer", "movies": "Filmer",
"queue": "Kø", "queue": "Kø",
"other_media": "Andre medier", "other_media": "Andre medier",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Ingen elementer i køen", "no_items_in_queue": "Ingen elementer i køen",
"no_downloaded_items": "Ingen nedlastede elementer", "no_downloaded_items": "Ingen nedlastede elementer",
"delete_all_movies_button": "Slett alle filmer", "delete_all_movies_button": "Slett alle filmer",
"delete_all_tvseries_button": "Slett alle TV-Serier", "delete_all_series_button": "Slett alle TV-Serier",
"delete_all_button": "Slett alle", "delete_all_button": "Slett alle",
"delete_all_other_media_button": "Slett andre media", "delete_all_other_media_button": "Slett andre media",
"active_download": "Aktiv nedlasting", "active_download": "Aktiv nedlasting",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Du har ikke lov til å laste ned filer.", "you_are_not_allowed_to_download_files": "Du har ikke lov til å laste ned filer.",
"deleted_all_movies_successfully": "Slettet alle filmer vellykket!", "deleted_all_movies_successfully": "Slettet alle filmer vellykket!",
"failed_to_delete_all_movies": "Kunne ikke slette alle filmer", "failed_to_delete_all_movies": "Kunne ikke slette alle filmer",
"deleted_all_tvseries_successfully": "Alle TV-Serier ble slettet!", "deleted_all_series_successfully": "Alle TV-Serier ble slettet!",
"failed_to_delete_all_tvseries": "Kunne ikke slette alle TV-Serier", "failed_to_delete_all_series": "Kunne ikke slette alle TV-Serier",
"deleted_media_successfully": "Slettet andre media vellykket!", "deleted_media_successfully": "Slettet andre media vellykket!",
"failed_to_delete_media": "Kunne ikke slette andre medier", "failed_to_delete_media": "Kunne ikke slette andre medier",
"download_deleted": "Nedlasting slettet", "download_deleted": "Nedlasting slettet",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Pobrane", "downloads_title": "Pobrane",
"tvseries": "Seriale", "series": "Seriale",
"movies": "Filmy", "movies": "Filmy",
"queue": "Kolejka", "queue": "Kolejka",
"other_media": "Inne media", "other_media": "Inne media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Brak elementów w kolejce", "no_items_in_queue": "Brak elementów w kolejce",
"no_downloaded_items": "Brak pobranych elementów", "no_downloaded_items": "Brak pobranych elementów",
"delete_all_movies_button": "Usuń wszystkie filmy", "delete_all_movies_button": "Usuń wszystkie filmy",
"delete_all_tvseries_button": "Usuń wszystkie seriale", "delete_all_series_button": "Usuń wszystkie seriale",
"delete_all_button": "Usuń wszystko", "delete_all_button": "Usuń wszystko",
"delete_all_other_media_button": "Usuń inne media", "delete_all_other_media_button": "Usuń inne media",
"active_download": "Aktywne pobieranie", "active_download": "Aktywne pobieranie",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Nie masz uprawnień do pobierania plików.", "you_are_not_allowed_to_download_files": "Nie masz uprawnień do pobierania plików.",
"deleted_all_movies_successfully": "Wszystkie filmy zostały pomyślnie usunięte!", "deleted_all_movies_successfully": "Wszystkie filmy zostały pomyślnie usunięte!",
"failed_to_delete_all_movies": "Nie udało się usunąć wszystkich filmów", "failed_to_delete_all_movies": "Nie udało się usunąć wszystkich filmów",
"deleted_all_tvseries_successfully": "Wszystkie seriale zostały pomyślnie usunięte!", "deleted_all_series_successfully": "Wszystkie seriale zostały pomyślnie usunięte!",
"failed_to_delete_all_tvseries": "Nie udało się usunąć wszystkich seriali", "failed_to_delete_all_series": "Nie udało się usunąć wszystkich seriali",
"deleted_media_successfully": "Pomyślnie usunięto inne media!", "deleted_media_successfully": "Pomyślnie usunięto inne media!",
"failed_to_delete_media": "Nie udało się usunąć innych mediów", "failed_to_delete_media": "Nie udało się usunąć innych mediów",
"download_deleted": "Pobieranie usunięte", "download_deleted": "Pobieranie usunięte",

View File

@@ -227,14 +227,14 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "TV/Séries", "series": "TV/Séries",
"movies": "Filmes", "movies": "Filmes",
"queue": "Fila", "queue": "Fila",
"queue_hint": "A fila e os downloads serão perdidos ao reiniciar o aplicativo", "queue_hint": "A fila e os downloads serão perdidos ao reiniciar o aplicativo",
"no_items_in_queue": "Nenhum item na fila", "no_items_in_queue": "Nenhum item na fila",
"no_downloaded_items": "Nenhum item baixado", "no_downloaded_items": "Nenhum item baixado",
"delete_all_movies_button": "Remover todos os filmes", "delete_all_movies_button": "Remover todos os filmes",
"delete_all_tvseries_button": "Remover todos as TV/Séries", "delete_all_series_button": "Remover todos as TV/Séries",
"delete_all_button": "Remover tudo", "delete_all_button": "Remover tudo",
"active_download": "Downloads ativos", "active_download": "Downloads ativos",
"no_active_downloads": "Nenhum download ativo", "no_active_downloads": "Nenhum download ativo",
@@ -251,8 +251,8 @@
"you_are_not_allowed_to_download_files": "Você não tem permissão para baixar arquivos.", "you_are_not_allowed_to_download_files": "Você não tem permissão para baixar arquivos.",
"deleted_all_movies_successfully": "Todos os filmes foram removidos com sucesso!", "deleted_all_movies_successfully": "Todos os filmes foram removidos com sucesso!",
"failed_to_delete_all_movies": "Falha ao remover todos os filmes", "failed_to_delete_all_movies": "Falha ao remover todos os filmes",
"deleted_all_tvseries_successfully": "Todos as TV/Séries foram removidos com sucesso!", "deleted_all_series_successfully": "Todos as TV/Séries foram removidos com sucesso!",
"failed_to_delete_all_tvseries": "Falha ao remover todos as TV/Séries", "failed_to_delete_all_series": "Falha ao remover todos as TV/Séries",
"download_cancelled": "Download cancelado", "download_cancelled": "Download cancelado",
"could_not_cancel_download": "Não foi possível cancelar o download", "could_not_cancel_download": "Não foi possível cancelar o download",
"download_completed": "Download completo", "download_completed": "Download completo",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "TV-Séries", "series": "TV-Séries",
"movies": "Filmes", "movies": "Filmes",
"queue": "Fila", "queue": "Fila",
"other_media": "Outras mídias", "other_media": "Outras mídias",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Nenhum item na fila", "no_items_in_queue": "Nenhum item na fila",
"no_downloaded_items": "Nenhum item baixado", "no_downloaded_items": "Nenhum item baixado",
"delete_all_movies_button": "Excluir todos os filmes", "delete_all_movies_button": "Excluir todos os filmes",
"delete_all_tvseries_button": "Excluir todas as séries", "delete_all_series_button": "Excluir todas as séries",
"delete_all_button": "Excluir todos os", "delete_all_button": "Excluir todos os",
"delete_all_other_media_button": "Excluir outras mídias", "delete_all_other_media_button": "Excluir outras mídias",
"active_download": "Download ativo", "active_download": "Download ativo",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Você não tem permissão para baixar arquivos.", "you_are_not_allowed_to_download_files": "Você não tem permissão para baixar arquivos.",
"deleted_all_movies_successfully": "Todos os filmes excluídos com sucesso!", "deleted_all_movies_successfully": "Todos os filmes excluídos com sucesso!",
"failed_to_delete_all_movies": "Falha ao excluir todos os filmes", "failed_to_delete_all_movies": "Falha ao excluir todos os filmes",
"deleted_all_tvseries_successfully": "Todas as TV-Series excluídas com sucesso!", "deleted_all_series_successfully": "Todas as TV-Series excluídas com sucesso!",
"failed_to_delete_all_tvseries": "Falha ao excluir todas as séries", "failed_to_delete_all_series": "Falha ao excluir todas as séries",
"deleted_media_successfully": "Outras mídias excluídas com sucesso!", "deleted_media_successfully": "Outras mídias excluídas com sucesso!",
"failed_to_delete_media": "Falha ao excluir outras mídias", "failed_to_delete_media": "Falha ao excluir outras mídias",
"download_deleted": "Download Excluído", "download_deleted": "Download Excluído",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Descărcări", "downloads_title": "Descărcări",
"tvseries": "Seriale", "series": "Seriale",
"movies": "Filme", "movies": "Filme",
"queue": "Coadă", "queue": "Coadă",
"other_media": "Alte suporturi", "other_media": "Alte suporturi",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Niciun articol în coadă", "no_items_in_queue": "Niciun articol în coadă",
"no_downloaded_items": "Niciun element descărcat", "no_downloaded_items": "Niciun element descărcat",
"delete_all_movies_button": "Șterge toate filmele", "delete_all_movies_button": "Șterge toate filmele",
"delete_all_tvseries_button": "Șterge toate serialele", "delete_all_series_button": "Șterge toate serialele",
"delete_all_button": "Șterge tot", "delete_all_button": "Șterge tot",
"delete_all_other_media_button": "Șterge alte fișiere media", "delete_all_other_media_button": "Șterge alte fișiere media",
"active_download": "Descărcare activă", "active_download": "Descărcare activă",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Nu aveți voie să descărcați fișiere.", "you_are_not_allowed_to_download_files": "Nu aveți voie să descărcați fișiere.",
"deleted_all_movies_successfully": "Toate filmele au fost șterse cu succes!", "deleted_all_movies_successfully": "Toate filmele au fost șterse cu succes!",
"failed_to_delete_all_movies": "Nu s-au putut șterge toate filmele", "failed_to_delete_all_movies": "Nu s-au putut șterge toate filmele",
"deleted_all_tvseries_successfully": "Toate serialele au fost șterse cu succes!", "deleted_all_series_successfully": "Toate serialele au fost șterse cu succes!",
"failed_to_delete_all_tvseries": "Nu s-au putut șterge toate serialele", "failed_to_delete_all_series": "Nu s-au putut șterge toate serialele",
"deleted_media_successfully": "Alte fișiere șterse cu succes!", "deleted_media_successfully": "Alte fișiere șterse cu succes!",
"failed_to_delete_media": "Ștergerea altor fișiere media a eșuat", "failed_to_delete_media": "Ștergerea altor fișiere media a eșuat",
"download_deleted": "Descărcare ştearsă", "download_deleted": "Descărcare ştearsă",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Загрузки", "downloads_title": "Загрузки",
"tvseries": "Сериалы", "series": "Сериалы",
"movies": "Фильмы", "movies": "Фильмы",
"queue": "Очередь", "queue": "Очередь",
"other_media": "Прочие файлы", "other_media": "Прочие файлы",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Нет элементов в очереди", "no_items_in_queue": "Нет элементов в очереди",
"no_downloaded_items": "Нет загруженных файлов", "no_downloaded_items": "Нет загруженных файлов",
"delete_all_movies_button": "Удалить все фильмы", "delete_all_movies_button": "Удалить все фильмы",
"delete_all_tvseries_button": "Удалить все сериалы", "delete_all_series_button": "Удалить все сериалы",
"delete_all_button": "Удалить все", "delete_all_button": "Удалить все",
"delete_all_other_media_button": "Удалить прочие файлы", "delete_all_other_media_button": "Удалить прочие файлы",
"active_download": "Загружается", "active_download": "Загружается",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Нет разрешения на скачивание файлов.", "you_are_not_allowed_to_download_files": "Нет разрешения на скачивание файлов.",
"deleted_all_movies_successfully": "Все фильмы были успешно удалены!", "deleted_all_movies_successfully": "Все фильмы были успешно удалены!",
"failed_to_delete_all_movies": "Возникла ошибка при удалении всех фильмов", "failed_to_delete_all_movies": "Возникла ошибка при удалении всех фильмов",
"deleted_all_tvseries_successfully": "Все сериалы были успешно удалены!", "deleted_all_series_successfully": "Все сериалы были успешно удалены!",
"failed_to_delete_all_tvseries": "Возникла ошибка при удалении всех сериалов", "failed_to_delete_all_series": "Возникла ошибка при удалении всех сериалов",
"deleted_media_successfully": "Остальные медиафайлы успешно удалены!", "deleted_media_successfully": "Остальные медиафайлы успешно удалены!",
"failed_to_delete_media": "Не удалось удалить остальные медиафайлы", "failed_to_delete_media": "Не удалось удалить остальные медиафайлы",
"download_deleted": "Загруженный контент удалён", "download_deleted": "Загруженный контент удалён",

View File

@@ -229,14 +229,14 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Shkarkimet", "downloads_title": "Shkarkimet",
"tvseries": "Seriale TV", "series": "Seriale TV",
"movies": "Filma", "movies": "Filma",
"queue": "Rradhë", "queue": "Rradhë",
"queue_hint": "Rradhat dhe shkarkimet do të humbasin pas genstartit të aplikacionit", "queue_hint": "Rradhat dhe shkarkimet do të humbasin pas genstartit të aplikacionit",
"no_items_in_queue": "Nuk ka elemente në rradhë", "no_items_in_queue": "Nuk ka elemente në rradhë",
"no_downloaded_items": "Nuk ka shkarkime", "no_downloaded_items": "Nuk ka shkarkime",
"delete_all_movies_button": "Fshijë të gjithë filmat", "delete_all_movies_button": "Fshijë të gjithë filmat",
"delete_all_tvseries_button": "Fshijë të gjitha serialet TV", "delete_all_series_button": "Fshijë të gjitha serialet TV",
"delete_all_button": "Fshijë të gjitha", "delete_all_button": "Fshijë të gjitha",
"active_download": "Shkarkim aktiv", "active_download": "Shkarkim aktiv",
"no_active_downloads": "Nuk ka shkarkime aktive", "no_active_downloads": "Nuk ka shkarkime aktive",
@@ -253,8 +253,8 @@
"you_are_not_allowed_to_download_files": "Nuk keni të drejtë të shkarkoni skedarë.", "you_are_not_allowed_to_download_files": "Nuk keni të drejtë të shkarkoni skedarë.",
"deleted_all_movies_successfully": "Të gjithë filmat u fshinë me sukses!", "deleted_all_movies_successfully": "Të gjithë filmat u fshinë me sukses!",
"failed_to_delete_all_movies": "Dështojë fshirja e të gjithë filmave", "failed_to_delete_all_movies": "Dështojë fshirja e të gjithë filmave",
"deleted_all_tvseries_successfully": "Të gjitha serialet TV u fshinë me sukses!", "deleted_all_series_successfully": "Të gjitha serialet TV u fshinë me sukses!",
"failed_to_delete_all_tvseries": "Dështojë fshirja e të gjitha serialeve TV", "failed_to_delete_all_series": "Dështojë fshirja e të gjitha serialeve TV",
"download_cancelled": "Shkarkimi u anulua", "download_cancelled": "Shkarkimi u anulua",
"could_not_cancel_download": "Nuk mundet të anulohet shkarkimi", "could_not_cancel_download": "Nuk mundet të anulohet shkarkimi",
"download_completed": "Shkarkimi u përfundua", "download_completed": "Shkarkimi u përfundua",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Nedladdningar", "downloads_title": "Nedladdningar",
"tvseries": "TV-Serier", "series": "TV-Serier",
"movies": "Filmer", "movies": "Filmer",
"queue": "Kö", "queue": "Kö",
"other_media": "Annan media", "other_media": "Annan media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Inga objekt i Kön", "no_items_in_queue": "Inga objekt i Kön",
"no_downloaded_items": "Inga Nedladdade Objekt", "no_downloaded_items": "Inga Nedladdade Objekt",
"delete_all_movies_button": "Ta Bort Alla Filmer", "delete_all_movies_button": "Ta Bort Alla Filmer",
"delete_all_tvseries_button": "Ta Bort Alla TV-Serier", "delete_all_series_button": "Ta Bort Alla TV-Serier",
"delete_all_button": "Radera Allt", "delete_all_button": "Radera Allt",
"delete_all_other_media_button": "Ta Bort Andra Videor", "delete_all_other_media_button": "Ta Bort Andra Videor",
"active_download": "Aktiv Nedladdning", "active_download": "Aktiv Nedladdning",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Du har inte behörighet att ladda ner filer.", "you_are_not_allowed_to_download_files": "Du har inte behörighet att ladda ner filer.",
"deleted_all_movies_successfully": "Alla Filmer Har Tagits Bort!", "deleted_all_movies_successfully": "Alla Filmer Har Tagits Bort!",
"failed_to_delete_all_movies": "Det Gick Inte Att Ta Bort Alla Filmer", "failed_to_delete_all_movies": "Det Gick Inte Att Ta Bort Alla Filmer",
"deleted_all_tvseries_successfully": "Alla TV-Serier Har Tagits Bort!", "deleted_all_series_successfully": "Alla TV-Serier Har Tagits Bort!",
"failed_to_delete_all_tvseries": "Det Gick Inte Att Ta Bort Alla TV-Serier", "failed_to_delete_all_series": "Det Gick Inte Att Ta Bort Alla TV-Serier",
"deleted_media_successfully": "Andra Medier Har Tagits Bort!", "deleted_media_successfully": "Andra Medier Har Tagits Bort!",
"failed_to_delete_media": "Kunde Inte Ta Bort Andra Medier", "failed_to_delete_media": "Kunde Inte Ta Bort Andra Medier",
"download_deleted": "Nedladdning Borttagen", "download_deleted": "Nedladdning Borttagen",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "TV-Series", "series": "TV-Series",
"movies": "Movies", "movies": "Movies",
"queue": "Queue", "queue": "Queue",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "No Items in Queue", "no_items_in_queue": "No Items in Queue",
"no_downloaded_items": "No Downloaded Items", "no_downloaded_items": "No Downloaded Items",
"delete_all_movies_button": "Delete All Movies", "delete_all_movies_button": "Delete All Movies",
"delete_all_tvseries_button": "Delete All TV-Series", "delete_all_series_button": "Delete All TV-Series",
"delete_all_button": "Delete All", "delete_all_button": "Delete All",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "Active Download", "active_download": "Active Download",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "You are not allowed to download files.", "you_are_not_allowed_to_download_files": "You are not allowed to download files.",
"deleted_all_movies_successfully": "Deleted All Movies Successfully!", "deleted_all_movies_successfully": "Deleted All Movies Successfully!",
"failed_to_delete_all_movies": "Failed to Delete All Movies", "failed_to_delete_all_movies": "Failed to Delete All Movies",
"deleted_all_tvseries_successfully": "Deleted All TV-Series Successfully!", "deleted_all_series_successfully": "Deleted All TV-Series Successfully!",
"failed_to_delete_all_tvseries": "Failed to Delete All TV-Series", "failed_to_delete_all_series": "Failed to Delete All TV-Series",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Download Deleted", "download_deleted": "Download Deleted",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Qaw' Doch", "downloads_title": "Qaw' Doch",
"tvseries": "TV Hem", "series": "TV Hem",
"movies": "DIS", "movies": "DIS",
"queue": "ghom", "queue": "ghom",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "ghom Doch pagh", "no_items_in_queue": "ghom Doch pagh",
"no_downloaded_items": "Qaw' Doch pagh", "no_downloaded_items": "Qaw' Doch pagh",
"delete_all_movies_button": "Hoch DIS yIQaw'", "delete_all_movies_button": "Hoch DIS yIQaw'",
"delete_all_tvseries_button": "Hoch TV Hem yIQaw'", "delete_all_series_button": "Hoch TV Hem yIQaw'",
"delete_all_button": "Hoch yIQaw'", "delete_all_button": "Hoch yIQaw'",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "chu' Qaw'", "active_download": "chu' Qaw'",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Doch Qaw' je'laHbe'.", "you_are_not_allowed_to_download_files": "Doch Qaw' je'laHbe'.",
"deleted_all_movies_successfully": "Hoch DIS Qaw' Qapla'!", "deleted_all_movies_successfully": "Hoch DIS Qaw' Qapla'!",
"failed_to_delete_all_movies": "Hoch DIS Qaw'laHbe'", "failed_to_delete_all_movies": "Hoch DIS Qaw'laHbe'",
"deleted_all_tvseries_successfully": "Hoch TV Hem Qaw' Qapla'!", "deleted_all_series_successfully": "Hoch TV Hem Qaw' Qapla'!",
"failed_to_delete_all_tvseries": "Hoch TV Hem Qaw'laHbe'", "failed_to_delete_all_series": "Hoch TV Hem Qaw'laHbe'",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Download Deleted", "download_deleted": "Download Deleted",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "İndirilenler", "downloads_title": "İndirilenler",
"tvseries": "Diziler", "series": "Diziler",
"movies": "Filmler", "movies": "Filmler",
"queue": "Sıra", "queue": "Sıra",
"other_media": "Diğer medya", "other_media": "Diğer medya",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Sırada öğe yok", "no_items_in_queue": "Sırada öğe yok",
"no_downloaded_items": "İndirilen öğe yok", "no_downloaded_items": "İndirilen öğe yok",
"delete_all_movies_button": "Tüm Filmleri Sil", "delete_all_movies_button": "Tüm Filmleri Sil",
"delete_all_tvseries_button": "Tüm Dizileri Sil", "delete_all_series_button": "Tüm Dizileri Sil",
"delete_all_button": "Tümünü Sil", "delete_all_button": "Tümünü Sil",
"delete_all_other_media_button": "Diğer medyayı sil", "delete_all_other_media_button": "Diğer medyayı sil",
"active_download": "Aktif indirme", "active_download": "Aktif indirme",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Dosyaları indirme izniniz yok.", "you_are_not_allowed_to_download_files": "Dosyaları indirme izniniz yok.",
"deleted_all_movies_successfully": "Tüm filmler başarıyla silindi!", "deleted_all_movies_successfully": "Tüm filmler başarıyla silindi!",
"failed_to_delete_all_movies": "Filmler silinemedi", "failed_to_delete_all_movies": "Filmler silinemedi",
"deleted_all_tvseries_successfully": "Tüm diziler başarıyla silindi!", "deleted_all_series_successfully": "Tüm diziler başarıyla silindi!",
"failed_to_delete_all_tvseries": "Diziler silinemedi", "failed_to_delete_all_series": "Diziler silinemedi",
"deleted_media_successfully": "Diğer medya başarıyla silindi!", "deleted_media_successfully": "Diğer medya başarıyla silindi!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "İndirme silindi", "download_deleted": "İndirme silindi",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Завантаження", "downloads_title": "Завантаження",
"tvseries": "ТБ-Серіали", "series": "ТБ-Серіали",
"movies": "Фільми", "movies": "Фільми",
"queue": "Черга", "queue": "Черга",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Нема елементів в черзі", "no_items_in_queue": "Нема елементів в черзі",
"no_downloaded_items": "Нема завантажених елементів", "no_downloaded_items": "Нема завантажених елементів",
"delete_all_movies_button": "Видалити всі Фільми", "delete_all_movies_button": "Видалити всі Фільми",
"delete_all_tvseries_button": "Видалити всі ТБ-Серіали", "delete_all_series_button": "Видалити всі ТБ-Серіали",
"delete_all_button": "Видалити Все", "delete_all_button": "Видалити Все",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "Активне завантаження", "active_download": "Активне завантаження",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Вам не дозволено завантажувати файли.", "you_are_not_allowed_to_download_files": "Вам не дозволено завантажувати файли.",
"deleted_all_movies_successfully": "Видалення всіх фільмів було успішне!", "deleted_all_movies_successfully": "Видалення всіх фільмів було успішне!",
"failed_to_delete_all_movies": "Не вдалося видалити усі фільми", "failed_to_delete_all_movies": "Не вдалося видалити усі фільми",
"deleted_all_tvseries_successfully": "Успішно видалено всі серіали!", "deleted_all_series_successfully": "Успішно видалено всі серіали!",
"failed_to_delete_all_tvseries": "Не вдалося видалити всі телесеріали", "failed_to_delete_all_series": "Не вдалося видалити всі телесеріали",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Download Deleted", "download_deleted": "Download Deleted",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Tải xuống", "downloads_title": "Tải xuống",
"tvseries": "Chương trình TV", "series": "Chương trình TV",
"movies": "Phim", "movies": "Phim",
"queue": "Hàng đợi", "queue": "Hàng đợi",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "Không có mục trong hàng đợi", "no_items_in_queue": "Không có mục trong hàng đợi",
"no_downloaded_items": "Không có mục đã tải", "no_downloaded_items": "Không có mục đã tải",
"delete_all_movies_button": "Xóa tất cả phim", "delete_all_movies_button": "Xóa tất cả phim",
"delete_all_tvseries_button": "Xóa tất cả chương trình TV", "delete_all_series_button": "Xóa tất cả chương trình TV",
"delete_all_button": "Xóa tất cả", "delete_all_button": "Xóa tất cả",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "Đang tải xuống", "active_download": "Đang tải xuống",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "Bạn không có quyền tải nội dung.", "you_are_not_allowed_to_download_files": "Bạn không có quyền tải nội dung.",
"deleted_all_movies_successfully": "Đã xóa tất cả phim thành công!", "deleted_all_movies_successfully": "Đã xóa tất cả phim thành công!",
"failed_to_delete_all_movies": "Xóa phim thất bại", "failed_to_delete_all_movies": "Xóa phim thất bại",
"deleted_all_tvseries_successfully": "Đã xóa tất cả chương trình TV thành công!", "deleted_all_series_successfully": "Đã xóa tất cả chương trình TV thành công!",
"failed_to_delete_all_tvseries": "Xóa chương trình TV thất bại", "failed_to_delete_all_series": "Xóa chương trình TV thất bại",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Download Deleted", "download_deleted": "Download Deleted",

View File

@@ -224,14 +224,14 @@
}, },
"downloads": { "downloads": {
"downloads_title": "下载", "downloads_title": "下载",
"tvseries": "剧集", "series": "剧集",
"movies": "电影", "movies": "电影",
"queue": "队列", "queue": "队列",
"queue_hint": "应用重启后队列和下载将会丢失", "queue_hint": "应用重启后队列和下载将会丢失",
"no_items_in_queue": "队列中无项目", "no_items_in_queue": "队列中无项目",
"no_downloaded_items": "无已下载项目", "no_downloaded_items": "无已下载项目",
"delete_all_movies_button": "删除所有电影", "delete_all_movies_button": "删除所有电影",
"delete_all_tvseries_button": "删除所有剧集", "delete_all_series_button": "删除所有剧集",
"delete_all_button": "删除全部", "delete_all_button": "删除全部",
"active_download": "活跃下载", "active_download": "活跃下载",
"no_active_downloads": "无活跃下载", "no_active_downloads": "无活跃下载",
@@ -248,8 +248,8 @@
"you_are_not_allowed_to_download_files": "您无权下载文件。", "you_are_not_allowed_to_download_files": "您无权下载文件。",
"deleted_all_movies_successfully": "成功删除所有电影!", "deleted_all_movies_successfully": "成功删除所有电影!",
"failed_to_delete_all_movies": "删除所有电影失败", "failed_to_delete_all_movies": "删除所有电影失败",
"deleted_all_tvseries_successfully": "成功删除所有剧集!", "deleted_all_series_successfully": "成功删除所有剧集!",
"failed_to_delete_all_tvseries": "删除所有剧集失败", "failed_to_delete_all_series": "删除所有剧集失败",
"download_cancelled": "下载已取消", "download_cancelled": "下载已取消",
"could_not_cancel_download": "无法取消下载", "could_not_cancel_download": "无法取消下载",
"download_completed": "下载完成", "download_completed": "下载完成",

View File

@@ -231,14 +231,14 @@
}, },
"downloads": { "downloads": {
"downloads_title": "下載", "downloads_title": "下載",
"tvseries": "電視劇", "series": "電視劇",
"movies": "電影", "movies": "電影",
"queue": "隊列", "queue": "隊列",
"queue_hint": "應用重啟後隊列和下載將會丟失", "queue_hint": "應用重啟後隊列和下載將會丟失",
"no_items_in_queue": "隊列中無項目", "no_items_in_queue": "隊列中無項目",
"no_downloaded_items": "無已下載項目", "no_downloaded_items": "無已下載項目",
"delete_all_movies_button": "刪除所有電影", "delete_all_movies_button": "刪除所有電影",
"delete_all_tvseries_button": "刪除所有電視劇", "delete_all_series_button": "刪除所有電視劇",
"delete_all_button": "刪除全部", "delete_all_button": "刪除全部",
"active_download": "活動下載", "active_download": "活動下載",
"no_active_downloads": "無活動下載", "no_active_downloads": "無活動下載",
@@ -255,8 +255,8 @@
"you_are_not_allowed_to_download_files": "您無權下載文件。", "you_are_not_allowed_to_download_files": "您無權下載文件。",
"deleted_all_movies_successfully": "成功刪除所有電影!", "deleted_all_movies_successfully": "成功刪除所有電影!",
"failed_to_delete_all_movies": "刪除所有電影失敗", "failed_to_delete_all_movies": "刪除所有電影失敗",
"deleted_all_tvseries_successfully": "成功刪除所有電視劇!", "deleted_all_series_successfully": "成功刪除所有電視劇!",
"failed_to_delete_all_tvseries": "刪除所有電視劇失敗", "failed_to_delete_all_series": "刪除所有電視劇失敗",
"download_cancelled": "下載已取消", "download_cancelled": "下載已取消",
"could_not_cancel_download": "無法取消下載", "could_not_cancel_download": "無法取消下載",
"download_completed": "下載完成", "download_completed": "下載完成",

View File

@@ -516,7 +516,7 @@
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
"tvseries": "TV-Series", "series": "TV-Series",
"movies": "Movies", "movies": "Movies",
"queue": "Queue", "queue": "Queue",
"other_media": "Other media", "other_media": "Other media",
@@ -524,7 +524,7 @@
"no_items_in_queue": "No Items in Queue", "no_items_in_queue": "No Items in Queue",
"no_downloaded_items": "No Downloaded Items", "no_downloaded_items": "No Downloaded Items",
"delete_all_movies_button": "Delete All Movies", "delete_all_movies_button": "Delete All Movies",
"delete_all_tvseries_button": "Delete All TV-Series", "delete_all_series_button": "Delete All TV-Series",
"delete_all_button": "Delete All", "delete_all_button": "Delete All",
"delete_all_other_media_button": "Delete other media", "delete_all_other_media_button": "Delete other media",
"active_download": "Active Download", "active_download": "Active Download",
@@ -542,8 +542,8 @@
"you_are_not_allowed_to_download_files": "You are not allowed to download files.", "you_are_not_allowed_to_download_files": "You are not allowed to download files.",
"deleted_all_movies_successfully": "Deleted All Movies Successfully!", "deleted_all_movies_successfully": "Deleted All Movies Successfully!",
"failed_to_delete_all_movies": "Failed to Delete All Movies", "failed_to_delete_all_movies": "Failed to Delete All Movies",
"deleted_all_tvseries_successfully": "Deleted All TV-Series Successfully!", "deleted_all_series_successfully": "Deleted All TV-Series Successfully!",
"failed_to_delete_all_tvseries": "Failed to Delete All TV-Series", "failed_to_delete_all_series": "Failed to Delete All TV-Series",
"deleted_media_successfully": "Deleted other media Successfully!", "deleted_media_successfully": "Deleted other media Successfully!",
"failed_to_delete_media": "Failed to Delete other media", "failed_to_delete_media": "Failed to Delete other media",
"download_deleted": "Download Deleted", "download_deleted": "Download Deleted",