mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-07-15 08:52:59 +01:00
Compare commits
1 Commits
fix/networ
...
I10n_crowd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0dcab949a |
274
app/_layout.tsx
274
app/_layout.tsx
@@ -27,7 +27,6 @@ import { NetworkStatusProvider } from "@/providers/NetworkStatusProvider";
|
||||
import { PlaySettingsProvider } from "@/providers/PlaySettingsProvider";
|
||||
import { ServerUrlProvider } from "@/providers/ServerUrlProvider";
|
||||
import { WebSocketProvider } from "@/providers/WebSocketProvider";
|
||||
import { WifiSsidProvider } from "@/providers/WifiSsidProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import {
|
||||
BACKGROUND_FETCH_TASK,
|
||||
@@ -422,146 +421,143 @@ function Layout() {
|
||||
>
|
||||
<JellyfinProvider>
|
||||
<InactivityProvider>
|
||||
<WifiSsidProvider>
|
||||
<ServerUrlProvider>
|
||||
<NetworkStatusProvider>
|
||||
<PlaySettingsProvider>
|
||||
<LogProvider>
|
||||
<WebSocketProvider>
|
||||
<DownloadProvider>
|
||||
<MusicPlayerProvider>
|
||||
<GlobalModalProvider>
|
||||
<BottomSheetModalProvider>
|
||||
<IntroSheetProvider>
|
||||
<ThemeProvider value={DarkTheme}>
|
||||
<SystemBars style='light' hidden={false} />
|
||||
<Stack initialRouteName='(auth)/(tabs)'>
|
||||
<Stack.Screen
|
||||
name='(auth)/(tabs)'
|
||||
options={{
|
||||
headerShown: false,
|
||||
title: "",
|
||||
header: () => null,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/player'
|
||||
options={{
|
||||
headerShown: false,
|
||||
title: "",
|
||||
header: () => null,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/now-playing'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "modal",
|
||||
gestureEnabled: true,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='login'
|
||||
options={{
|
||||
headerShown: true,
|
||||
title: "",
|
||||
headerTransparent:
|
||||
Platform.OS === "ios",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen name='+not-found' />
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-option-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-subtitle-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-request-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-season-select-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-series-season-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='tv-account-action-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='tv-account-select-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-user-switch-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
<Toaster
|
||||
duration={4000}
|
||||
toastOptions={{
|
||||
style: {
|
||||
backgroundColor: "#262626",
|
||||
borderColor: "#363639",
|
||||
borderWidth: 1,
|
||||
},
|
||||
titleStyle: {
|
||||
color: "white",
|
||||
},
|
||||
<ServerUrlProvider>
|
||||
<NetworkStatusProvider>
|
||||
<PlaySettingsProvider>
|
||||
<LogProvider>
|
||||
<WebSocketProvider>
|
||||
<DownloadProvider>
|
||||
<MusicPlayerProvider>
|
||||
<GlobalModalProvider>
|
||||
<BottomSheetModalProvider>
|
||||
<IntroSheetProvider>
|
||||
<ThemeProvider value={DarkTheme}>
|
||||
<SystemBars style='light' hidden={false} />
|
||||
<Stack initialRouteName='(auth)/(tabs)'>
|
||||
<Stack.Screen
|
||||
name='(auth)/(tabs)'
|
||||
options={{
|
||||
headerShown: false,
|
||||
title: "",
|
||||
header: () => null,
|
||||
}}
|
||||
closeButton
|
||||
/>
|
||||
{!Platform.isTV && <GlobalModal />}
|
||||
</ThemeProvider>
|
||||
</IntroSheetProvider>
|
||||
</BottomSheetModalProvider>
|
||||
</GlobalModalProvider>
|
||||
</MusicPlayerProvider>
|
||||
</DownloadProvider>
|
||||
</WebSocketProvider>
|
||||
</LogProvider>
|
||||
</PlaySettingsProvider>
|
||||
</NetworkStatusProvider>
|
||||
</ServerUrlProvider>
|
||||
</WifiSsidProvider>
|
||||
<Stack.Screen
|
||||
name='(auth)/player'
|
||||
options={{
|
||||
headerShown: false,
|
||||
title: "",
|
||||
header: () => null,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/now-playing'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "modal",
|
||||
gestureEnabled: true,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='login'
|
||||
options={{
|
||||
headerShown: true,
|
||||
title: "",
|
||||
headerTransparent: Platform.OS === "ios",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen name='+not-found' />
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-option-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-subtitle-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-request-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-season-select-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-series-season-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='tv-account-action-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='tv-account-select-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name='(auth)/tv-user-switch-modal'
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "transparentModal",
|
||||
animation: "fade",
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
<Toaster
|
||||
duration={4000}
|
||||
toastOptions={{
|
||||
style: {
|
||||
backgroundColor: "#262626",
|
||||
borderColor: "#363639",
|
||||
borderWidth: 1,
|
||||
},
|
||||
titleStyle: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
closeButton
|
||||
/>
|
||||
{!Platform.isTV && <GlobalModal />}
|
||||
</ThemeProvider>
|
||||
</IntroSheetProvider>
|
||||
</BottomSheetModalProvider>
|
||||
</GlobalModalProvider>
|
||||
</MusicPlayerProvider>
|
||||
</DownloadProvider>
|
||||
</WebSocketProvider>
|
||||
</LogProvider>
|
||||
</PlaySettingsProvider>
|
||||
</NetworkStatusProvider>
|
||||
</ServerUrlProvider>
|
||||
</InactivityProvider>
|
||||
</JellyfinProvider>
|
||||
</PersistQueryClientProvider>
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useTranslation } from "react-i18next";
|
||||
import { Switch, TouchableOpacity, View } from "react-native";
|
||||
import { toast } from "sonner-native";
|
||||
import { useWifiSSID } from "@/hooks/useWifiSSID";
|
||||
import { openLocationSettings } from "@/modules/wifi-ssid";
|
||||
import { useServerUrl } from "@/providers/ServerUrlProvider";
|
||||
import { storage } from "@/utils/mmkv";
|
||||
import {
|
||||
@@ -27,26 +26,16 @@ const DEFAULT_CONFIG: LocalNetworkConfig = {
|
||||
|
||||
interface StatusDisplayProps {
|
||||
currentSSID: string | null;
|
||||
connectedToWifi: boolean;
|
||||
isUsingLocalUrl: boolean;
|
||||
locationBlocked: boolean;
|
||||
onOpenLocationSettings: () => void;
|
||||
t: (key: string) => string;
|
||||
}
|
||||
|
||||
function StatusDisplay({
|
||||
currentSSID,
|
||||
connectedToWifi,
|
||||
isUsingLocalUrl,
|
||||
locationBlocked,
|
||||
onOpenLocationSettings,
|
||||
t,
|
||||
}: StatusDisplayProps): React.ReactElement {
|
||||
const wifiStatus = currentSSID
|
||||
? currentSSID
|
||||
: connectedToWifi
|
||||
? t("home.settings.network.ssid_hidden")
|
||||
: t("home.settings.network.not_connected");
|
||||
const wifiStatus = currentSSID ?? t("home.settings.network.not_connected");
|
||||
const urlType = isUsingLocalUrl
|
||||
? t("home.settings.network.local")
|
||||
: t("home.settings.network.remote");
|
||||
@@ -66,23 +55,6 @@ function StatusDisplay({
|
||||
</Text>
|
||||
<Text className={urlTypeColor}>{urlType}</Text>
|
||||
</View>
|
||||
|
||||
{locationBlocked && (
|
||||
<View className='mt-2 pt-2 border-t border-neutral-800'>
|
||||
<Text className='text-xs text-amber-400'>
|
||||
{t("home.settings.network.location_off_description")}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
onPress={onOpenLocationSettings}
|
||||
className='mt-2 self-start'
|
||||
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
||||
>
|
||||
<Text className='text-xs text-blue-400 font-semibold'>
|
||||
{t("home.settings.network.open_location_settings")}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -90,17 +62,7 @@ function StatusDisplay({
|
||||
export function LocalNetworkSettings(): React.ReactElement | null {
|
||||
const { t } = useTranslation();
|
||||
const { permissionStatus, requestPermission } = useWifiSSID();
|
||||
const { isUsingLocalUrl, currentSSID, connectedToWifi, refreshUrlState } =
|
||||
useServerUrl();
|
||||
|
||||
// Connected to Wi-Fi and have permission, but the OS won't reveal the SSID —
|
||||
// on Android this means device Location services are off.
|
||||
const locationBlocked =
|
||||
permissionStatus === "granted" && connectedToWifi && !currentSSID;
|
||||
|
||||
const handleOpenLocationSettings = useCallback(() => {
|
||||
openLocationSettings();
|
||||
}, []);
|
||||
const { isUsingLocalUrl, currentSSID, refreshUrlState } = useServerUrl();
|
||||
|
||||
const remoteUrl = storage.getString("serverUrl");
|
||||
const [config, setConfig] = useState<LocalNetworkConfig>(DEFAULT_CONFIG);
|
||||
@@ -233,23 +195,18 @@ export function LocalNetworkSettings(): React.ReactElement | null {
|
||||
)}
|
||||
</ListGroup>
|
||||
|
||||
{!locationBlocked && (
|
||||
<View className='py-2'>
|
||||
<Button
|
||||
onPress={handleAddCurrentNetwork}
|
||||
disabled={!currentSSID || permissionStatus !== "granted"}
|
||||
>
|
||||
{addNetworkButtonText}
|
||||
</Button>
|
||||
</View>
|
||||
)}
|
||||
<View className='py-2'>
|
||||
<Button
|
||||
onPress={handleAddCurrentNetwork}
|
||||
disabled={!currentSSID || permissionStatus !== "granted"}
|
||||
>
|
||||
{addNetworkButtonText}
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
<StatusDisplay
|
||||
currentSSID={currentSSID}
|
||||
connectedToWifi={connectedToWifi}
|
||||
isUsingLocalUrl={isUsingLocalUrl}
|
||||
locationBlocked={locationBlocked}
|
||||
onOpenLocationSettings={handleOpenLocationSettings}
|
||||
t={t}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -1,5 +1,125 @@
|
||||
export {
|
||||
type PermissionStatus,
|
||||
type UseWifiSSIDReturn,
|
||||
useWifiSsid as useWifiSSID,
|
||||
} from "@/providers/WifiSsidProvider";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import { getSSID } from "@/modules/wifi-ssid";
|
||||
|
||||
export type PermissionStatus =
|
||||
| "granted"
|
||||
| "denied"
|
||||
| "undetermined"
|
||||
| "unavailable";
|
||||
|
||||
export interface UseWifiSSIDReturn {
|
||||
ssid: string | null;
|
||||
permissionStatus: PermissionStatus;
|
||||
requestPermission: () => Promise<boolean>;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
// WiFi SSID is not available on tvOS
|
||||
if (Platform.isTV) {
|
||||
// Export a stub hook for tvOS
|
||||
module.exports = {
|
||||
useWifiSSID: (): UseWifiSSIDReturn => ({
|
||||
ssid: null,
|
||||
permissionStatus: "unavailable" as PermissionStatus,
|
||||
requestPermission: async () => false,
|
||||
isLoading: false,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
// Only import Location on non-TV platforms
|
||||
const Location = Platform.isTV ? null : require("expo-location");
|
||||
|
||||
function mapLocationStatus(status: number | undefined): PermissionStatus {
|
||||
if (!Location) return "unavailable";
|
||||
switch (status) {
|
||||
case Location.PermissionStatus?.GRANTED:
|
||||
return "granted";
|
||||
case Location.PermissionStatus?.DENIED:
|
||||
return "denied";
|
||||
default:
|
||||
return "undetermined";
|
||||
}
|
||||
}
|
||||
|
||||
export function useWifiSSID(): UseWifiSSIDReturn {
|
||||
const [ssid, setSSID] = useState<string | null>(null);
|
||||
const [permissionStatus, setPermissionStatus] = useState<PermissionStatus>(
|
||||
Platform.isTV ? "unavailable" : "undetermined",
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState(!Platform.isTV);
|
||||
|
||||
const fetchSSID = useCallback(async () => {
|
||||
if (Platform.isTV) return;
|
||||
const result = await getSSID();
|
||||
setSSID(result);
|
||||
}, []);
|
||||
|
||||
const requestPermission = useCallback(async (): Promise<boolean> => {
|
||||
if (Platform.isTV || !Location) {
|
||||
setPermissionStatus("unavailable");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const { status } = await Location.requestForegroundPermissionsAsync();
|
||||
const newStatus = mapLocationStatus(status);
|
||||
setPermissionStatus(newStatus);
|
||||
|
||||
if (newStatus === "granted") {
|
||||
await fetchSSID();
|
||||
}
|
||||
|
||||
return newStatus === "granted";
|
||||
} catch {
|
||||
setPermissionStatus("unavailable");
|
||||
return false;
|
||||
}
|
||||
}, [fetchSSID]);
|
||||
|
||||
useEffect(() => {
|
||||
if (Platform.isTV || !Location) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { status } = await Location.getForegroundPermissionsAsync();
|
||||
const mappedStatus = mapLocationStatus(status);
|
||||
setPermissionStatus(mappedStatus);
|
||||
|
||||
if (mappedStatus === "granted") {
|
||||
await fetchSSID();
|
||||
}
|
||||
} catch {
|
||||
setPermissionStatus("unavailable");
|
||||
}
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
initialize();
|
||||
}, [fetchSSID]);
|
||||
|
||||
// Refresh SSID when permission status changes to granted
|
||||
useEffect(() => {
|
||||
if (Platform.isTV) return;
|
||||
|
||||
if (permissionStatus === "granted") {
|
||||
fetchSSID();
|
||||
|
||||
// Also set up an interval to periodically check SSID
|
||||
const interval = setInterval(fetchSSID, 10000); // Check every 10 seconds
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [permissionStatus, fetchSSID]);
|
||||
|
||||
return {
|
||||
ssid,
|
||||
permissionStatus,
|
||||
requestPermission,
|
||||
isLoading,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
apply plugin: 'expo-module-gradle-plugin'
|
||||
|
||||
group = 'expo.modules.wifissid'
|
||||
version = '1.0.0'
|
||||
|
||||
expoModule {
|
||||
canBePublished false
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "expo.modules.wifissid"
|
||||
defaultConfig {
|
||||
versionCode 1
|
||||
versionName "1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Reading the connected Wi-Fi SSID requires ACCESS_WIFI_STATE, and (since
|
||||
Android 8) ACCESS_FINE_LOCATION granted at runtime. Location is requested
|
||||
at runtime by the app via expo-location; the manifest declares the
|
||||
Wi-Fi/network permissions this module needs directly. -->
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
</manifest>
|
||||
@@ -1,121 +0,0 @@
|
||||
package expo.modules.wifissid
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.wifi.WifiInfo
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import expo.modules.kotlin.modules.Module
|
||||
import expo.modules.kotlin.modules.ModuleDefinition
|
||||
|
||||
class WifiSsidModule : Module() {
|
||||
companion object {
|
||||
private const val TAG = "WifiSsid"
|
||||
private const val UNKNOWN_SSID = "<unknown ssid>"
|
||||
}
|
||||
|
||||
private val context
|
||||
get() = requireNotNull(appContext.reactContext)
|
||||
|
||||
override fun definition() = ModuleDefinition {
|
||||
Name("WifiSsid")
|
||||
|
||||
AsyncFunction("getSSID") {
|
||||
val (ssid, connectedToWifi) = readWifi()
|
||||
mapOf(
|
||||
"ssid" to ssid,
|
||||
"connectedToWifi" to connectedToWifi,
|
||||
)
|
||||
}
|
||||
|
||||
Function("getSSIDSync") {
|
||||
val (ssid, connectedToWifi) = readWifi()
|
||||
mapOf(
|
||||
"ssid" to ssid,
|
||||
"connectedToWifi" to connectedToWifi,
|
||||
)
|
||||
}
|
||||
|
||||
Function("openLocationSettings") {
|
||||
openLocationSettings()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current Wi-Fi SSID (or null when it can't be read) and whether
|
||||
* the device is connected to a Wi-Fi network. When the device is connected but
|
||||
* the SSID is null, the OS is withholding the network name — on Android this
|
||||
* typically means device Location services are off (the SSID is treated as
|
||||
* location-sensitive).
|
||||
*/
|
||||
private fun readWifi(): Pair<String?, Boolean> {
|
||||
val androidContext = context.applicationContext
|
||||
var connectedToWifi = false
|
||||
var ssid: String? = null
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
try {
|
||||
val cm = androidContext.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
|
||||
val caps = cm?.let { manager ->
|
||||
manager.activeNetwork?.let { net -> manager.getNetworkCapabilities(net) }
|
||||
}
|
||||
connectedToWifi = caps?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true
|
||||
if (hasFineLocationPermission()) {
|
||||
ssid = (caps?.transportInfo as? WifiInfo)?.ssid?.sanitize()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error reading Wi-Fi via ConnectivityManager", e)
|
||||
}
|
||||
} else {
|
||||
// Pre-Q (API 26–28): NetworkCapabilities/transportInfo aren't available, so
|
||||
// detect a Wi-Fi connection via the legacy active-network API. Without this,
|
||||
// connectedToWifi stays false on Android 8/9 even when connected, so the
|
||||
// "connected but SSID hidden" state never surfaces there.
|
||||
try {
|
||||
val cm = androidContext.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
|
||||
@Suppress("DEPRECATION")
|
||||
connectedToWifi = cm?.activeNetworkInfo?.type == ConnectivityManager.TYPE_WIFI
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error reading Wi-Fi via ConnectivityManager (legacy)", e)
|
||||
}
|
||||
}
|
||||
|
||||
if (ssid == null && hasFineLocationPermission()) {
|
||||
try {
|
||||
val wm = androidContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
|
||||
@Suppress("DEPRECATION")
|
||||
ssid = wm?.connectionInfo?.ssid?.sanitize()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error reading SSID via WifiManager", e)
|
||||
}
|
||||
}
|
||||
|
||||
return Pair(ssid, connectedToWifi)
|
||||
}
|
||||
|
||||
private fun openLocationSettings() {
|
||||
try {
|
||||
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.applicationContext.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to open Location settings", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasFineLocationPermission(): Boolean =
|
||||
context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) ==
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
|
||||
private fun String.sanitize(): String? {
|
||||
val cleaned = trim('"')
|
||||
return if (cleaned.isBlank() || cleaned == UNKNOWN_SSID) null else cleaned
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
{
|
||||
"name": "wifi-ssid",
|
||||
"version": "1.0.0",
|
||||
"platforms": ["ios", "android"],
|
||||
"platforms": ["ios"],
|
||||
"ios": {
|
||||
"modules": ["WifiSsidModule"]
|
||||
},
|
||||
"android": {
|
||||
"modules": ["expo.modules.wifissid.WifiSsidModule"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,92 +1,44 @@
|
||||
import { Platform, requireNativeModule } from "expo-modules-core";
|
||||
import { Linking } from "react-native";
|
||||
|
||||
export interface WifiSsidResult {
|
||||
ssid: string | null;
|
||||
/**
|
||||
* Whether the device is connected to a Wi-Fi network. When true but `ssid` is
|
||||
* null, the OS is withholding the network name — on Android this happens when
|
||||
* device Location services are off (the SSID is location-sensitive).
|
||||
*/
|
||||
connectedToWifi: boolean;
|
||||
}
|
||||
|
||||
// Load the native module on iOS and Android (not TV/web). Wrapped so a
|
||||
// missing/unlinked module degrades to null instead of crashing the bundle.
|
||||
const WifiSsidModule = (() => {
|
||||
if (Platform.OS !== "ios" && Platform.OS !== "android") return null;
|
||||
try {
|
||||
return requireNativeModule("WifiSsid");
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
// Only load the native module on iOS
|
||||
const WifiSsidModule =
|
||||
Platform.OS === "ios" ? requireNativeModule("WifiSsid") : null;
|
||||
|
||||
/**
|
||||
* Get the current WiFi SSID and whether the device is on a Wi-Fi network.
|
||||
* Get the current WiFi SSID on iOS.
|
||||
* Returns null on Android or if not connected to WiFi.
|
||||
*
|
||||
* iOS requirements:
|
||||
* Requires:
|
||||
* - Location permission granted
|
||||
* - com.apple.developer.networking.wifi-info entitlement
|
||||
*
|
||||
* Android requirements:
|
||||
* - ACCESS_FINE_LOCATION granted at runtime, and device Location services on
|
||||
* - Access WiFi Information capability enabled in Apple Developer Portal
|
||||
*/
|
||||
export async function getSSID(): Promise<WifiSsidResult> {
|
||||
export async function getSSID(): Promise<string | null> {
|
||||
if (!WifiSsidModule) {
|
||||
return { ssid: null, connectedToWifi: false };
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return normalize(await WifiSsidModule.getSSID());
|
||||
const ssid = await WifiSsidModule.getSSID();
|
||||
return ssid ?? null;
|
||||
} catch (error) {
|
||||
console.error("[WifiSsid] Error getting SSID:", error);
|
||||
return { ssid: null, connectedToWifi: false };
|
||||
}
|
||||
}
|
||||
|
||||
/** Synchronous version (uses the older CNCopyCurrentNetworkInfo API on iOS). */
|
||||
export function getSSIDSync(): WifiSsidResult {
|
||||
if (!WifiSsidModule) {
|
||||
return { ssid: null, connectedToWifi: false };
|
||||
}
|
||||
try {
|
||||
return normalize(WifiSsidModule.getSSIDSync());
|
||||
} catch (error) {
|
||||
console.error("[WifiSsid] Error getting SSID (sync):", error);
|
||||
return { ssid: null, connectedToWifi: false };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the system Location settings so the user can enable Location services
|
||||
* (required on Android for the OS to reveal the Wi-Fi SSID). Falls back to the
|
||||
* app's settings page where there is no dedicated native action (e.g. iOS).
|
||||
* Synchronous version - uses older CNCopyCurrentNetworkInfo API
|
||||
*/
|
||||
export function openLocationSettings(): void {
|
||||
try {
|
||||
if (WifiSsidModule?.openLocationSettings) {
|
||||
WifiSsidModule.openLocationSettings();
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[WifiSsid] Error opening location settings:", error);
|
||||
export function getSSIDSync(): string | null {
|
||||
if (!WifiSsidModule) {
|
||||
return null;
|
||||
}
|
||||
Linking.openSettings();
|
||||
}
|
||||
|
||||
// Both native modules return { ssid, connectedToWifi }. The string branch is a
|
||||
// defensive fallback in case a build returns the older plain-string shape.
|
||||
function normalize(result: unknown): WifiSsidResult {
|
||||
if (typeof result === "string") {
|
||||
const ssid = result || null;
|
||||
return { ssid, connectedToWifi: ssid !== null };
|
||||
try {
|
||||
return WifiSsidModule.getSSIDSync() ?? null;
|
||||
} catch (error) {
|
||||
console.error("[WifiSsid] Error getting SSID (sync):", error);
|
||||
return null;
|
||||
}
|
||||
if (result && typeof result === "object") {
|
||||
const obj = result as { ssid?: string | null; connectedToWifi?: boolean };
|
||||
return {
|
||||
ssid: obj.ssid ?? null,
|
||||
connectedToWifi: Boolean(obj.connectedToWifi),
|
||||
};
|
||||
}
|
||||
return { ssid: null, connectedToWifi: false };
|
||||
}
|
||||
|
||||
@@ -1,113 +1,50 @@
|
||||
import ExpoModulesCore
|
||||
#if !os(tvOS)
|
||||
import Network
|
||||
import NetworkExtension
|
||||
import SystemConfiguration.CaptiveNetwork
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
public class WifiSsidModule: Module {
|
||||
#if !os(tvOS)
|
||||
// NWPathMonitor reports whether the active path uses Wi-Fi WITHOUT requiring
|
||||
// the wifi-info entitlement, so we can tell "on Wi-Fi but can't read the SSID"
|
||||
// apart from "not connected to Wi-Fi" even when fetchCurrent returns nil.
|
||||
private let pathMonitor = NWPathMonitor()
|
||||
private let monitorQueue = DispatchQueue(label: "expo.modules.wifissid.pathmonitor")
|
||||
private let lock = NSLock()
|
||||
private var cachedOnWifi = false
|
||||
private var pathMonitorStarted = false
|
||||
|
||||
private var isOnWifi: Bool {
|
||||
lock.lock()
|
||||
defer { lock.unlock() }
|
||||
return cachedOnWifi
|
||||
}
|
||||
|
||||
private func startPathMonitorIfNeeded() {
|
||||
lock.lock()
|
||||
if pathMonitorStarted {
|
||||
lock.unlock()
|
||||
return
|
||||
}
|
||||
pathMonitorStarted = true
|
||||
lock.unlock()
|
||||
|
||||
pathMonitor.pathUpdateHandler = { [weak self] path in
|
||||
guard let self else { return }
|
||||
let onWifi = path.status == .satisfied && path.usesInterfaceType(.wifi)
|
||||
self.lock.lock()
|
||||
self.cachedOnWifi = onWifi
|
||||
self.lock.unlock()
|
||||
}
|
||||
pathMonitor.start(queue: monitorQueue)
|
||||
}
|
||||
|
||||
deinit {
|
||||
pathMonitor.cancel()
|
||||
}
|
||||
#endif
|
||||
|
||||
public func definition() -> ModuleDefinition {
|
||||
Name("WifiSsid")
|
||||
|
||||
AsyncFunction("getSSID") { () -> [String: Any] in
|
||||
// Get current WiFi SSID using NEHotspotNetwork (iOS 14+)
|
||||
// Not available on tvOS
|
||||
AsyncFunction("getSSID") { () -> String? in
|
||||
#if os(tvOS)
|
||||
return ["ssid": NSNull(), "connectedToWifi": false]
|
||||
return nil
|
||||
#else
|
||||
self.startPathMonitorIfNeeded()
|
||||
let ssid = await self.resolveSSID()
|
||||
var result: [String: Any] = ["connectedToWifi": self.isOnWifi]
|
||||
if let ssid = ssid {
|
||||
result["ssid"] = ssid
|
||||
} else {
|
||||
result["ssid"] = NSNull()
|
||||
}
|
||||
return result
|
||||
#endif
|
||||
}
|
||||
|
||||
Function("getSSIDSync") { () -> [String: Any] in
|
||||
#if os(tvOS)
|
||||
return ["ssid": NSNull(), "connectedToWifi": false]
|
||||
#else
|
||||
self.startPathMonitorIfNeeded()
|
||||
let ssid = self.getSSIDViaCNCopy()
|
||||
var result: [String: Any] = ["connectedToWifi": self.isOnWifi]
|
||||
if let ssid = ssid {
|
||||
result["ssid"] = ssid
|
||||
} else {
|
||||
result["ssid"] = NSNull()
|
||||
}
|
||||
return result
|
||||
#endif
|
||||
}
|
||||
|
||||
Function("openLocationSettings") {
|
||||
#if !os(tvOS)
|
||||
DispatchQueue.main.async {
|
||||
if let url = URL(string: UIApplication.openSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
return await withCheckedContinuation { continuation in
|
||||
NEHotspotNetwork.fetchCurrent { network in
|
||||
if let ssid = network?.ssid {
|
||||
print("[WifiSsid] Got SSID via NEHotspotNetwork: \(ssid)")
|
||||
continuation.resume(returning: ssid)
|
||||
} else {
|
||||
// Fallback to CNCopyCurrentNetworkInfo for older iOS
|
||||
print("[WifiSsid] NEHotspotNetwork returned nil, trying CNCopyCurrentNetworkInfo")
|
||||
let ssid = self.getSSIDViaCNCopy()
|
||||
continuation.resume(returning: ssid)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Synchronous version using only CNCopyCurrentNetworkInfo
|
||||
// Not available on tvOS
|
||||
Function("getSSIDSync") { () -> String? in
|
||||
#if os(tvOS)
|
||||
return nil
|
||||
#else
|
||||
return self.getSSIDViaCNCopy()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
private func resolveSSID() async -> String? {
|
||||
await withCheckedContinuation { continuation in
|
||||
NEHotspotNetwork.fetchCurrent { network in
|
||||
if let ssid = network?.ssid {
|
||||
continuation.resume(returning: ssid)
|
||||
} else {
|
||||
continuation.resume(returning: self.getSSIDViaCNCopy())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getSSIDViaCNCopy() -> String? {
|
||||
guard let interfaces = CNCopySupportedInterfaces() as? [String] else {
|
||||
print("[WifiSsid] CNCopySupportedInterfaces returned nil")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -117,10 +54,12 @@ public class WifiSsidModule: Module {
|
||||
}
|
||||
|
||||
if let ssid = networkInfo[kCNNetworkInfoKeySSID as String] as? String {
|
||||
print("[WifiSsid] Got SSID via CNCopyCurrentNetworkInfo: \(ssid)")
|
||||
return ssid
|
||||
}
|
||||
}
|
||||
|
||||
print("[WifiSsid] No SSID found via CNCopyCurrentNetworkInfo")
|
||||
return nil
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
@@ -19,7 +18,6 @@ interface ServerUrlContextValue {
|
||||
effectiveServerUrl: string | null;
|
||||
isUsingLocalUrl: boolean;
|
||||
currentSSID: string | null;
|
||||
connectedToWifi: boolean;
|
||||
refreshUrlState: () => void;
|
||||
}
|
||||
|
||||
@@ -34,7 +32,7 @@ interface Props {
|
||||
export function ServerUrlProvider({ children }: Props): React.ReactElement {
|
||||
const api = useAtomValue(apiAtom);
|
||||
const { switchServerUrl } = useJellyfin();
|
||||
const { ssid, connectedToWifi, permissionStatus } = useWifiSSID();
|
||||
const { ssid, permissionStatus } = useWifiSSID();
|
||||
|
||||
const [isUsingLocalUrl, setIsUsingLocalUrl] = useState(false);
|
||||
const [effectiveServerUrl, setEffectiveServerUrl] = useState<string | null>(
|
||||
@@ -103,25 +101,15 @@ export function ServerUrlProvider({ children }: Props): React.ReactElement {
|
||||
};
|
||||
}, [ssid, permissionStatus, evaluateAndSwitchUrl]);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
effectiveServerUrl,
|
||||
isUsingLocalUrl,
|
||||
currentSSID: ssid,
|
||||
connectedToWifi,
|
||||
refreshUrlState,
|
||||
}),
|
||||
[
|
||||
effectiveServerUrl,
|
||||
isUsingLocalUrl,
|
||||
ssid,
|
||||
connectedToWifi,
|
||||
refreshUrlState,
|
||||
],
|
||||
);
|
||||
|
||||
return (
|
||||
<ServerUrlContext.Provider value={value}>
|
||||
<ServerUrlContext.Provider
|
||||
value={{
|
||||
effectiveServerUrl,
|
||||
isUsingLocalUrl,
|
||||
currentSSID: ssid,
|
||||
refreshUrlState,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ServerUrlContext.Provider>
|
||||
);
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
import type React from "react";
|
||||
import {
|
||||
createContext,
|
||||
type ReactNode,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Platform } from "react-native";
|
||||
import { getSSID } from "@/modules/wifi-ssid";
|
||||
|
||||
export type PermissionStatus =
|
||||
| "granted"
|
||||
| "denied"
|
||||
| "undetermined"
|
||||
| "unavailable";
|
||||
|
||||
export interface UseWifiSSIDReturn {
|
||||
ssid: string | null;
|
||||
connectedToWifi: boolean;
|
||||
permissionStatus: PermissionStatus;
|
||||
requestPermission: () => Promise<boolean>;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const WifiSsidContext = createContext<UseWifiSSIDReturn | null>(null);
|
||||
|
||||
// WiFi SSID is not available on tvOS, and expo-location isn't needed there.
|
||||
const Location = Platform.isTV ? null : require("expo-location");
|
||||
|
||||
const POLL_INTERVAL_MS = 10_000;
|
||||
|
||||
function mapLocationStatus(status: number | undefined): PermissionStatus {
|
||||
if (!Location) return "unavailable";
|
||||
switch (status) {
|
||||
case Location.PermissionStatus?.GRANTED:
|
||||
return "granted";
|
||||
case Location.PermissionStatus?.DENIED:
|
||||
return "denied";
|
||||
default:
|
||||
return "undetermined";
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single source of truth for the current WiFi SSID and the location permission
|
||||
* that gates it. State is shared via context so that granting permission in one
|
||||
* place (e.g. the network settings screen) is reflected everywhere else — most
|
||||
* importantly ServerUrlProvider, which switches between the local and remote
|
||||
* server URLs based on the connected SSID.
|
||||
*
|
||||
* Previously each consumer created its own useWifiSSID instance with independent
|
||||
* state, so the provider never learned that permission had been granted later
|
||||
* in the session and reported "not connected to WiFi" forever.
|
||||
*/
|
||||
export function WifiSsidProvider({ children }: Props): React.ReactElement {
|
||||
const [ssid, setSSID] = useState<string | null>(null);
|
||||
const [connectedToWifi, setConnectedToWifi] = useState(false);
|
||||
const [permissionStatus, setPermissionStatus] = useState<PermissionStatus>(
|
||||
Platform.isTV ? "unavailable" : "undetermined",
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState(!Platform.isTV);
|
||||
|
||||
const fetchSSID = useCallback(async () => {
|
||||
if (Platform.isTV) return;
|
||||
const result = await getSSID();
|
||||
setSSID(result.ssid);
|
||||
setConnectedToWifi(result.connectedToWifi);
|
||||
}, []);
|
||||
|
||||
const requestPermission = useCallback(async (): Promise<boolean> => {
|
||||
if (Platform.isTV || !Location) {
|
||||
setPermissionStatus("unavailable");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const { status } = await Location.requestForegroundPermissionsAsync();
|
||||
const newStatus = mapLocationStatus(status);
|
||||
setPermissionStatus(newStatus);
|
||||
return newStatus === "granted";
|
||||
} catch {
|
||||
setPermissionStatus("unavailable");
|
||||
return false;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Check the location permission once on mount. The poll effect below takes
|
||||
// over fetching the SSID whenever permission becomes "granted".
|
||||
useEffect(() => {
|
||||
if (Platform.isTV || !Location) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
async function initialize() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { status } = await Location.getForegroundPermissionsAsync();
|
||||
if (cancelled) return;
|
||||
setPermissionStatus(mapLocationStatus(status));
|
||||
} catch {
|
||||
if (!cancelled) setPermissionStatus("unavailable");
|
||||
}
|
||||
if (!cancelled) setIsLoading(false);
|
||||
}
|
||||
|
||||
initialize();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Fetch the SSID immediately, then poll, whenever permission is granted.
|
||||
// Because permissionStatus is shared, this also covers the case where
|
||||
// permission was granted later (from another consumer) than this provider's
|
||||
// mount time — the original root cause of the "not connected to WiFi" bug.
|
||||
useEffect(() => {
|
||||
if (Platform.isTV || permissionStatus !== "granted") return;
|
||||
|
||||
fetchSSID();
|
||||
const interval = setInterval(fetchSSID, POLL_INTERVAL_MS);
|
||||
return () => clearInterval(interval);
|
||||
}, [permissionStatus, fetchSSID]);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
ssid,
|
||||
connectedToWifi,
|
||||
permissionStatus,
|
||||
requestPermission,
|
||||
isLoading,
|
||||
}),
|
||||
[ssid, connectedToWifi, permissionStatus, requestPermission, isLoading],
|
||||
);
|
||||
|
||||
return (
|
||||
<WifiSsidContext.Provider value={value}>
|
||||
{children}
|
||||
</WifiSsidContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useWifiSsid(): UseWifiSSIDReturn {
|
||||
const context = useContext(WifiSsidContext);
|
||||
if (!context) {
|
||||
throw new Error("useWifiSsid must be used within WifiSsidProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "حسنًا",
|
||||
"connection_failed": "فشل الاتصال",
|
||||
"could_not_connect_to_server": "تعذر الاتصال بالخادم. يرجى التحقق من الرابط واتصال الشبكة.",
|
||||
"an_unexpected_error_occured": "حدث خطأ غير متوقع",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "تغيير الخادم",
|
||||
"invalid_username_or_password": "اسم المستخدم أو كلمة المرور غير صالحة",
|
||||
"user_does_not_have_permission_to_log_in": "ليس لدى المستخدم صَلاحِيَة تسجيل الدخول",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "يستغرق الخادم وقتًا طويلاً للرد، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"server_received_too_many_requests_try_again_later": "تلقى الخادم عددًا كبيرًا جدًا من الطلبات، يرجى المحاولة مرة أخرى لاحقًا.",
|
||||
"there_is_a_server_error": "هناك خطأ في الخادم",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "حدث خطأ غير متوقع. هل أدخلت رابط الخادم بشكل صحيح؟",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "تم اكتشاف خادم Jellyfin غير مدعوم",
|
||||
"too_old_server_description": "يرجى تحديث Jellyfin إلى أحدث إصدار"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "تفويض الدخول السريع",
|
||||
"enter_the_quick_connect_code": "أدخل رمز الدخول السريع...",
|
||||
"success": "نجاح",
|
||||
"quick_connect_autorized": "تم تفويض الدخول السريع",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "خطأ",
|
||||
"invalid_code": "رمز غير صالح",
|
||||
"authorize": "تفويض"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "إظهار روابط القائمة المخصصة",
|
||||
"show_large_home_carousel": "إظهار شريط العرض الكبير (تجريبي)",
|
||||
"hide_libraries": "إخفاء المكتبات",
|
||||
"select_liraries_you_want_to_hide": "اختر المكتبات التي تريد إخفاءها من تبويب المكتبة وأقسام الصفحة الرئيسية.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "تعطيل ردود الفعل اللمسية",
|
||||
"default_quality": "الجودة الافتراضية",
|
||||
"default_playback_speed": "سرعة التشغيل الافتراضية",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "خطأ",
|
||||
"failed_to_get_stream_url": "فشل في الحصول على رابط البث",
|
||||
"an_error_occured_while_playing_the_video": "حدث خطأ أثناء تشغيل الفيديو. تحقق من السجلات في الإعدادات.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "خطأ في المشغّل",
|
||||
"could_not_create_stream_for_chromecast": "تعذر إنشاء بث لـChromecast",
|
||||
"message_from_server": "رسالة من الخادم: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Entesos",
|
||||
"connection_failed": "Ha fallat la connexió",
|
||||
"could_not_connect_to_server": "No s'ha pogut connectar amb el servidor. Comproveu l'URL i la connexió de xarxa.",
|
||||
"an_unexpected_error_occured": "S'ha produït un error inesperat",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Canvia el servidor",
|
||||
"invalid_username_or_password": "Nom d'usuari o contrasenya incorrectes",
|
||||
"user_does_not_have_permission_to_log_in": "L'usuari no té permís per iniciar sessió",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "El servidor triga massa a respondre, torneu-ho a provar més tard",
|
||||
"server_received_too_many_requests_try_again_later": "El servidor ha rebut massa sol·licituds, torneu-ho a provar més tard.",
|
||||
"there_is_a_server_error": "Error del servidor",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "S'ha produït un error inesperat. Heu introduït correctament l'URL del servidor?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoritza connexió ràpida",
|
||||
"enter_the_quick_connect_code": "Introdueix el codi de connexió ràpida...",
|
||||
"success": "Èxit",
|
||||
"quick_connect_autorized": "Connexió ràpida autoritzada",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Error",
|
||||
"invalid_code": "Codi invàlid",
|
||||
"authorize": "Autoritza"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostrar enllaços del menú personalitzats",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Oculta biblioteques",
|
||||
"select_liraries_you_want_to_hide": "Seleccioneu les biblioteques que voleu ocultar de la pestanya Biblioteca i de les seccions de la pàgina d'inici.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Desactiva la resposta hàptica",
|
||||
"default_quality": "Qualitat per defecte",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "No s'ha pogut obtenir l'URL del flux",
|
||||
"an_error_occured_while_playing_the_video": "S'ha produït un error en reproduir el vídeo. Consulteu els registres a la configuració.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Error del client",
|
||||
"could_not_create_stream_for_chromecast": "No s'ha pogut crear un flux per a Chromecast",
|
||||
"message_from_server": "Missatge del servidor: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Rozumím",
|
||||
"connection_failed": "Připojení se nezdařilo",
|
||||
"could_not_connect_to_server": "Nelze se připojit k serveru. Zkontrolujte adresu URL a síťové připojení.",
|
||||
"an_unexpected_error_occured": "Došlo k neočekávané chybě",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Změnit server",
|
||||
"invalid_username_or_password": "Neplatné uživatelské jméno nebo heslo",
|
||||
"user_does_not_have_permission_to_log_in": "Uživatel nemá oprávnění k přihlášení",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Reakce na server trvá příliš dlouho, zkuste to znovu později",
|
||||
"server_received_too_many_requests_try_again_later": "Server obdržel příliš mnoho požadavků, opakujte akci později.",
|
||||
"there_is_a_server_error": "Došlo k chybě serveru",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Došlo k neočekávané chybě. Vložili jste adresu URL serveru?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Objeven nepodporovaný Jellyfin server",
|
||||
"too_old_server_description": "Prosím aktualizujte Jellyfin na nejnovější verzi"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizovat rychlé připojení",
|
||||
"enter_the_quick_connect_code": "Zadejte kód rychlého připojení...",
|
||||
"success": "Úspěšně",
|
||||
"quick_connect_autorized": "Oprávněné Rychlé připojení",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Chyba",
|
||||
"invalid_code": "Neplatný kód",
|
||||
"authorize": "Autorizovat"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Zobrazit vlastní Menu odkazy",
|
||||
"show_large_home_carousel": "Zobrazit velký přehled (beta)",
|
||||
"hide_libraries": "Skrýt knihovny",
|
||||
"select_liraries_you_want_to_hide": "Vyberte knihovny, které chcete skrýt v záložce Knihovna a v sekcích domovské stránky.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Zakázat Haptickou zpětnou vazbu",
|
||||
"default_quality": "Výchozí kvalita",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Chyba",
|
||||
"failed_to_get_stream_url": "Nepodařilo se získat URL streamu",
|
||||
"an_error_occured_while_playing_the_video": "Při přehrávání videa došlo k chybě. Zkontrolujte logy v nastavení.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Chyba klienta",
|
||||
"could_not_create_stream_for_chromecast": "Nelze vytvořit stream pro Chromecast",
|
||||
"message_from_server": "Zpráva od serveru: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Forstået",
|
||||
"connection_failed": "Forbindelsen mislykkedes",
|
||||
"could_not_connect_to_server": "Kunne ikke oprette forbindelse til serveren. Tjek venligst URL'en og din netværksforbindelse.",
|
||||
"an_unexpected_error_occured": "Der opstod en uventet fejl",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Skift server",
|
||||
"invalid_username_or_password": "Ugyldigt brugernavn eller adgangskode",
|
||||
"user_does_not_have_permission_to_log_in": "Brugeren har ikke tilladelse til at logge ind",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serveren svarer for langsomt, prøv igen senere",
|
||||
"server_received_too_many_requests_try_again_later": "Serveren modtog for mange forespørgsler, prøv igen senere.",
|
||||
"there_is_a_server_error": "Der er en serverfejl",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Der opstod en uventet fejl. Har du indtastet serverens URL korrekt?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Ikke Understøttet Jellyfin Server Opdaget",
|
||||
"too_old_server_description": "Opdater venligst Jellyfin til den seneste version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoriser Hurtigforbindelse",
|
||||
"enter_the_quick_connect_code": "Indtast koden til hurtigforbindelse...",
|
||||
"success": "Succes",
|
||||
"quick_connect_autorized": "Hurtigforbindelse autoriseret",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Fejl",
|
||||
"invalid_code": "Ugyldig kode",
|
||||
"authorize": "Autoriser"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Vis tilpassede menulinks",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Skjul biblioteker",
|
||||
"select_liraries_you_want_to_hide": "Vælg de biblioteker, du ønsker at skjule fra fanen Bibliotek og startside sektionerne.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Deaktiver haptisk feedback",
|
||||
"default_quality": "Standard kvalitet",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fejl",
|
||||
"failed_to_get_stream_url": "Kunne ikke hente stream URL'en",
|
||||
"an_error_occured_while_playing_the_video": "Der opstod en fejl under afspilning af videoen. Tjek logfilerne i indstillinger.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Klientfejl",
|
||||
"could_not_create_stream_for_chromecast": "Kunne ikke oprette en stream til Chromecast",
|
||||
"message_from_server": "Besked fra server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Verstanden",
|
||||
"connection_failed": "Verbindung fehlgeschlagen",
|
||||
"could_not_connect_to_server": "Verbindung zum Server fehlgeschlagen. Bitte überprüf die URL und deine Netzwerkverbindung.",
|
||||
"an_unexpected_error_occured": "Ein unerwarteter Fehler ist aufgetreten",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Server wechseln",
|
||||
"invalid_username_or_password": "Ungültiger Benutzername oder Passwort",
|
||||
"user_does_not_have_permission_to_log_in": "Benutzer hat keine Berechtigung, um sich anzumelden",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Der Server benötigt zu lange, um zu antworten. Bitte versuch es später erneut",
|
||||
"server_received_too_many_requests_try_again_later": "Der Server hat zu viele Anfragen erhalten. Bitte versuch es später erneut.",
|
||||
"there_is_a_server_error": "Es gibt einen Serverfehler",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ein unerwarteter Fehler ist aufgetreten. Hast du die Server-URL korrekt eingegeben?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Nicht unterstützter Jellyfin Server entdeckt",
|
||||
"too_old_server_description": "Bitte aktualisiere Jellyfin auf die neueste Version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Quick Connect autorisieren",
|
||||
"enter_the_quick_connect_code": "Quick Connect-Code eingeben...",
|
||||
"success": "Erfolgreich verbunden",
|
||||
"quick_connect_autorized": "Quick Connect autorisiert",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Fehler",
|
||||
"invalid_code": "Ungültiger Code",
|
||||
"authorize": "Autorisieren"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Benutzerdefinierte Menülinks anzeigen",
|
||||
"show_large_home_carousel": "Zeige große Startseiten-Übersicht (Beta)",
|
||||
"hide_libraries": "Bibliotheken ausblenden",
|
||||
"select_liraries_you_want_to_hide": "Bibliotheken auswählen die aus dem Bibliothekstab und der Startseite ausgeblendet werden sollen.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Haptisches Feedback deaktivieren",
|
||||
"default_quality": "Standardqualität",
|
||||
"default_playback_speed": "Standard-Wiedergabegeschwindigkeit",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fehler",
|
||||
"failed_to_get_stream_url": "Fehler beim Abrufen der Stream-URL",
|
||||
"an_error_occured_while_playing_the_video": "Ein Fehler ist beim Abspielen des Videos aufgetreten. Logs in den Einstellungen überprüfen.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client-Fehler",
|
||||
"could_not_create_stream_for_chromecast": "Konnte keinen Stream für Chromecast erstellen",
|
||||
"message_from_server": "Nachricht vom Server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Το Κατάλαβα",
|
||||
"connection_failed": "Η Σύνδεση Απέτυχε",
|
||||
"could_not_connect_to_server": "Δεν ήταν δυνατή η σύνδεση με τον διακομιστή. Παρακαλώ ελέγξτε τη διεύθυνση URL και τη σύνδεση δικτύου σας.",
|
||||
"an_unexpected_error_occured": "Παρουσιάστηκε Απροσδόκητο Σφάλμα",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Αλλαγή Διακομιστή",
|
||||
"invalid_username_or_password": "Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης",
|
||||
"user_does_not_have_permission_to_log_in": "Ο χρήστης δεν έχει άδεια να συνδεθεί",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Ο διακομιστής καθυστερεί πάρα πολύ για να απαντήσει, δοκιμάστε ξανά αργότερα",
|
||||
"server_received_too_many_requests_try_again_later": "Ο διακομιστής έλαβε πάρα πολλά αιτήματα, δοκιμάστε ξανά αργότερα.",
|
||||
"there_is_a_server_error": "Υπάρχει ένα σφάλμα διακομιστή",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Παρουσιάστηκε μη αναμενόμενο σφάλμα. Εισαγάγετε σωστά το URL του διακομιστή?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Ανακαλύφθηκε Μη Υποστηριζόμενος Εξυπηρετητής Jellyfin",
|
||||
"too_old_server_description": "Παρακαλούμε ενημερώστε το Jellyfin στην τελευταία έκδοση"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Εξουσιοδότηση Γρήγορης Σύνδεσης",
|
||||
"enter_the_quick_connect_code": "Εισάγετε τον κωδικό γρήγορης σύνδεσης...",
|
||||
"success": "Επιτυχία",
|
||||
"quick_connect_autorized": "Γρήγορη Σύνδεση Εξουσιοδοτήθηκε",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Σφάλμα",
|
||||
"invalid_code": "Μη Έγκυρος Κωδικός",
|
||||
"authorize": "Εξουσιοδότηση"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Εμφάνιση Προσαρμοσμένων Συνδέσμων Μενού",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Απόκρυψη Βιβλιοθηκών",
|
||||
"select_liraries_you_want_to_hide": "Επιλέξτε τις βιβλιοθήκες που θέλετε να αποκρύψετε από την καρτέλα της Βιβλιοθήκης και τις ενότητες της αρχικής σελίδας.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Απενεργοποίηση Απτικής Ανατροφοδότησης",
|
||||
"default_quality": "Προεπιλεγμένη Ποιότητα",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Σφάλμα",
|
||||
"failed_to_get_stream_url": "Αποτυχία λήψης του URL ροής",
|
||||
"an_error_occured_while_playing_the_video": "Παρουσιάστηκε σφάλμα κατά την αναπαραγωγή του βίντεο. Ελέγξτε τα αρχεία καταγραφής στις ρυθμίσεις.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Σφάλμα Πελάτη",
|
||||
"could_not_create_stream_for_chromecast": "Αδυναμία δημιουργίας ροής για το Chromecast",
|
||||
"message_from_server": "Μήνυμα από το διακομιστή: {{message}}",
|
||||
|
||||
@@ -174,10 +174,7 @@
|
||||
"network_already_added": "Network already added",
|
||||
"no_wifi_connected": "Not connected to Wi-Fi",
|
||||
"permission_denied": "Location permission denied",
|
||||
"permission_denied_explanation": "Location permission is required to detect the Wi-Fi network for auto-switching. Please enable it in Settings.",
|
||||
"ssid_hidden": "SSID hidden",
|
||||
"location_off_description": "Connected to Wi-Fi, but the network name is hidden. Enable device Location services and grant the app location permission to detect it.",
|
||||
"open_location_settings": "Open Location settings"
|
||||
"permission_denied_explanation": "Location permission is required to detect the Wi-Fi network for auto-switching. Please enable it in Settings."
|
||||
},
|
||||
"user_info": {
|
||||
"user_info_title": "User info",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Entendido",
|
||||
"connection_failed": "Conexión fallida",
|
||||
"could_not_connect_to_server": "No se pudo conectar al servidor. Por favor comprueba la URL y tu conexión de red.",
|
||||
"an_unexpected_error_occured": "Ha ocurrido un error inesperado",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Cambiar servidor",
|
||||
"invalid_username_or_password": "Usuario o contraseña inválidos",
|
||||
"user_does_not_have_permission_to_log_in": "El usuario no tiene permiso para iniciar sesión",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "El servidor está tardando mucho en responder, inténtalo de nuevo más tarde.",
|
||||
"server_received_too_many_requests_try_again_later": "El servidor está recibiendo muchas peticiones, inténtalo de nuevo más tarde.",
|
||||
"there_is_a_server_error": "Hay un error en el servidor",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ha ocurrido un error inesperado. ¿Has introducido la URL correcta?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Servidor Jellyfin no soportado descubierto",
|
||||
"too_old_server_description": "Por favor, actualiza Jellyfin a la última versión"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizar conexión rápida",
|
||||
"enter_the_quick_connect_code": "Introduce el código de conexión rápida...",
|
||||
"success": "Hecho",
|
||||
"quick_connect_autorized": "Conexión rápida autorizada",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Error",
|
||||
"invalid_code": "Código inválido",
|
||||
"authorize": "Autorizar"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostrar enlaces de menú personalizados",
|
||||
"show_large_home_carousel": "Mostrar carrusel del menú principal grande (beta)",
|
||||
"hide_libraries": "Ocultar bibliotecas",
|
||||
"select_liraries_you_want_to_hide": "Selecciona las bibliotecas que quieres ocultar de la pestaña Bibliotecas y de Inicio.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Desactivar feedback háptico",
|
||||
"default_quality": "Calidad por defecto",
|
||||
"default_playback_speed": "Velocidad de reproducción predeterminada",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Error al obtener la URL del Steam",
|
||||
"an_error_occured_while_playing_the_video": "Ha ocurrido un error al reproducir el vídeo. Comprueba los registros en la configuración.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Error del cliente",
|
||||
"could_not_create_stream_for_chromecast": "No se pudo crear el Steam para Chromecast",
|
||||
"message_from_server": "Mensaje del servidor: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Okei",
|
||||
"connection_failed": "Yhteys epäonnistui",
|
||||
"could_not_connect_to_server": "Yhteyttä palvelimeen ei voitu muodostaa. Tarkista URL-osoite ja verkkoyhteytesi.",
|
||||
"an_unexpected_error_occured": "Odottamaton virhe tapahtui",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Vaihda palvelinta",
|
||||
"invalid_username_or_password": "Virheellinen käyttäjätunnus tai salasana",
|
||||
"user_does_not_have_permission_to_log_in": "Käyttäjällä ei ole oikeuksia kirjautua sisään",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Palvelin reagoi liian hitaasti, yritä myöhemmin uudelleen",
|
||||
"server_received_too_many_requests_try_again_later": "Palvelin sai liian monta pyyntöä, yritä myöhemmin uudelleen.",
|
||||
"there_is_a_server_error": "Palvelimessa on virhe",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Odottamaton virhe tapahtui. Syötitkö palvelimen URL-osoitteen oikein?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Ei-tuettu Jellyfin-palvelin löydetty",
|
||||
"too_old_server_description": "Ole hyvä ja päivitä Jellyfin uusimpaan versioon"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Valtuuta pikayhdistys",
|
||||
"enter_the_quick_connect_code": "Syötä nopean yhteyden koodi...",
|
||||
"success": "Onnistui",
|
||||
"quick_connect_autorized": "Pikayhdistys valtuutettu",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Virhe",
|
||||
"invalid_code": "Virheellinen koodi",
|
||||
"authorize": "Valtuuta"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Näytä mukautetut valikkolinkit",
|
||||
"show_large_home_carousel": "Näytä suuri kotikaruselli (beta)",
|
||||
"hide_libraries": "Piilota kirjastot",
|
||||
"select_liraries_you_want_to_hide": "Valitse kirjastot, jotka haluat piilottaa Kirjasto-välilehdeltä ja etusivun osioista.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Poista haptinen palautteet käytöstä",
|
||||
"default_quality": "Oletuslaatu",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Virhe",
|
||||
"failed_to_get_stream_url": "Lähetyksen URL-osoitteen haku epäonnistui",
|
||||
"an_error_occured_while_playing_the_video": "Videon toiston yhteydessä tapahtui virhe. Tarkista lokit asetuksista.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Asiakkaan Virhe",
|
||||
"could_not_create_stream_for_chromecast": "Suoratoistoa ei voitu luoda Chromecastia varten",
|
||||
"message_from_server": "Viesti palvelimelta: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "D'accord",
|
||||
"connection_failed": "La connexion a échoué",
|
||||
"could_not_connect_to_server": "Impossible de se connecter au serveur. Veuillez vérifier l’URL et votre connexion réseau.",
|
||||
"an_unexpected_error_occured": "Une erreur inattendue s'est produite",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Changer de serveur",
|
||||
"invalid_username_or_password": "Nom d'utilisateur ou mot de passe invalide",
|
||||
"user_does_not_have_permission_to_log_in": "L'utilisateur n'a pas la permission de se connecter",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Le serveur prend trop de temps à répondre, réessayez plus tard",
|
||||
"server_received_too_many_requests_try_again_later": "Le serveur a reçu trop de demandes, réessayez plus tard.",
|
||||
"there_is_a_server_error": "Il y a une erreur de serveur",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Une erreur inattendue s’est produite. Avez-vous correctement saisi l’URL du serveur ?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Serveur Jellyfin non pris en charge découvert",
|
||||
"too_old_server_description": "Veuillez mettre à jour Jellyfin vers la dernière version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoriser une connexion rapide",
|
||||
"enter_the_quick_connect_code": "Entrez le code de connexion rapide...",
|
||||
"success": "Succès",
|
||||
"quick_connect_autorized": "Connexion rapide autorisée",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Erreur",
|
||||
"invalid_code": "Code invalide",
|
||||
"authorize": "Autoriser"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Afficher les liens personnalisés",
|
||||
"show_large_home_carousel": "Afficher le grand carrousel d’accueil (bêta)",
|
||||
"hide_libraries": "Masquer les bibliothèques",
|
||||
"select_liraries_you_want_to_hide": "Sélectionnez les bibliothèques que vous souhaitez masquer dans l'onglet Bibliothèque et les sections de la page d'accueil.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Désactiver le retour haptique",
|
||||
"default_quality": "Qualité par défaut",
|
||||
"default_playback_speed": "Vitesse de lecture par défaut",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "Lecteur MPV",
|
||||
"error": "Erreur",
|
||||
"failed_to_get_stream_url": "Échec de l'obtention de l'URL du flux",
|
||||
"an_error_occured_while_playing_the_video": "Une erreur s’est produite lors de la lecture de la vidéo. Vérifiez les journaux dans les paramètres.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Erreur du client",
|
||||
"could_not_create_stream_for_chromecast": "Impossible de créer un flux sur la Chromecast",
|
||||
"message_from_server": "Message du serveur : {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "קיבלתי",
|
||||
"connection_failed": "ההתחברות נכשלה",
|
||||
"could_not_connect_to_server": "לא היה ניתן להתחבר לשרת. אנא בדוק את הקישור ואת חיבור הרשת שלך.",
|
||||
"an_unexpected_error_occured": "קרתה שגיאה לא צפויה",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "החלף שרת",
|
||||
"invalid_username_or_password": "שם משתמש או סיסמה שגויים",
|
||||
"user_does_not_have_permission_to_log_in": "לחשבון זה אין גישה להתחבר",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "השרת לוקח יותר מדי זמן כדי להגיב, נסה שוב מאוחר יותר",
|
||||
"server_received_too_many_requests_try_again_later": "השרת קיבל יותר מדי קריאות, נסה שוב מאוחר יותר",
|
||||
"there_is_a_server_error": "קרתה שגיאה בצד השרת",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "קרתה שגיאה לא צפויה. האם כתובת השרת שהוקלדה נכונה?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "נמצא שרת Jellyfin שלא נתמך",
|
||||
"too_old_server_description": "אנא עדכן את גרסת ה-Jellyfin למעודכנת ביותר"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "אשר התחברות מהירה",
|
||||
"enter_the_quick_connect_code": "הקלד את קוד ההתחברות המהירה...",
|
||||
"success": "הצלחה",
|
||||
"quick_connect_autorized": "חיבור מהיר אושר",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "שגיאה",
|
||||
"invalid_code": "קוד שגוי",
|
||||
"authorize": "אשר"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "הצג קישורים לתפריטים מותאמים אישית",
|
||||
"show_large_home_carousel": "הצג קרוסלה גדולה במסך הבית (בטא)",
|
||||
"hide_libraries": "הסתר ספריות",
|
||||
"select_liraries_you_want_to_hide": "בחר את הספריות שתרצה להסתיר ממסך הספריות וגם ממסך הבית.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "בטל משוב רטט",
|
||||
"default_quality": "איכות ברירת מחדל",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "שגיאה",
|
||||
"failed_to_get_stream_url": "נכשל בהשגת קישור הזרם",
|
||||
"an_error_occured_while_playing_the_video": "קרתה תקלה במהלך הניגון של הקובץ. בדוק את הלוגים בהגדרות.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "שגיאת לקוח",
|
||||
"could_not_create_stream_for_chromecast": "נכשל ביצירת זרם עבור Chromecast",
|
||||
"message_from_server": "הודעה מהשרת: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Értettem",
|
||||
"connection_failed": "Kapcsolódás Sikertelen",
|
||||
"could_not_connect_to_server": "Nem sikerült csatlakozni a szerverhez. Kérjük, ellenőrizd az URL-t és a hálózati kapcsolatot.",
|
||||
"an_unexpected_error_occured": "Váratlan Hiba Történt",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Szerverváltás",
|
||||
"invalid_username_or_password": "Érvénytelen Felhasználónév vagy Jelszó",
|
||||
"user_does_not_have_permission_to_log_in": "A felhasználónak nincs jogosultsága a bejelentkezéshez",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "A szerver túl sokáig válaszol, próbáld újra később",
|
||||
"server_received_too_many_requests_try_again_later": "A szerver túl sok kérést kapott, próbáld újra később.",
|
||||
"there_is_a_server_error": "Szerverhiba történt",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Váratlan hiba történt. Helyesen adtad meg a szerver URL-jét?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Nem Támogatott Jellyfin-szerver",
|
||||
"too_old_server_description": "Frissítsd a Jellyfint a legújabb verzióra"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Gyorscsatlakozás Engedélyezése",
|
||||
"enter_the_quick_connect_code": "Add meg a gyors csatlakozási kódot...",
|
||||
"success": "Siker",
|
||||
"quick_connect_autorized": "Gyorscsatlakozás Engedélyezve",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Hiba",
|
||||
"invalid_code": "Érvénytelen Kód",
|
||||
"authorize": "Engedélyezés"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Egyéni Menülinkek Megjelenítése",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Könyvtárak Elrejtése",
|
||||
"select_liraries_you_want_to_hide": "Válaszd ki azokat a könyvtárakat, amelyeket el szeretnél rejteni a Könyvtár fülön és a kezdőlapon.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Haptikus Visszajelzés Letiltása",
|
||||
"default_quality": "Alapértelmezett Minőség",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Hiba",
|
||||
"failed_to_get_stream_url": "Nem sikerült lekérni a stream URL-t",
|
||||
"an_error_occured_while_playing_the_video": "Hiba történt a videó lejátszása közben. Ellenőrizd a naplókat a beállításokban.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Kliens Hiba",
|
||||
"could_not_create_stream_for_chromecast": "A Chromecast stream létrehozása sikertelen volt",
|
||||
"message_from_server": "Üzenet a szervertől: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Capito",
|
||||
"connection_failed": "Connessione fallita",
|
||||
"could_not_connect_to_server": "Impossibile connettersi al server. Controllare l'URL e la connessione di rete.",
|
||||
"an_unexpected_error_occured": "Si è verificato un errore inaspettato",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Cambiare il server",
|
||||
"invalid_username_or_password": "Nome utente o password non validi",
|
||||
"user_does_not_have_permission_to_log_in": "L'utente non ha il permesso di accedere",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Il server sta impiegando troppo tempo per rispondere, riprovare più tardi",
|
||||
"server_received_too_many_requests_try_again_later": "Il server ha ricevuto troppe richieste, riprovare più tardi.",
|
||||
"there_is_a_server_error": "Si è verificato un errore del server",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Si è verificato un errore imprevisto. L'URL del server è stato inserito correttamente?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Scoperto Server Jellyfin non supportato",
|
||||
"too_old_server_description": "Aggiorna Jellyfin all'ultima versione"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizza Connessione Rapida",
|
||||
"enter_the_quick_connect_code": "Inserisci il codice per la Connessione Rapida...",
|
||||
"success": "Successo",
|
||||
"quick_connect_autorized": "Connessione Rapida autorizzata",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Errore",
|
||||
"invalid_code": "Codice invalido",
|
||||
"authorize": "Autorizza"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostra i link del menu personalizzato",
|
||||
"show_large_home_carousel": "Mostra Carosello Grande nella Home (beta)",
|
||||
"hide_libraries": "Nascondi Librerie",
|
||||
"select_liraries_you_want_to_hide": "Selezionate le librerie che volete nascondere dalla scheda Libreria e dalle sezioni della pagina iniziale.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disabilita il feedback aptico",
|
||||
"default_quality": "Qualità predefinita",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Errore",
|
||||
"failed_to_get_stream_url": "Impossibile ottenere l'URL dello stream",
|
||||
"an_error_occured_while_playing_the_video": "Si è verificato un errore durante la riproduzione del video. Controllare i log nelle impostazioni.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Errore del client",
|
||||
"could_not_create_stream_for_chromecast": "Impossibile creare uno stream per Chromecast",
|
||||
"message_from_server": "Messaggio dal server",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "了解",
|
||||
"connection_failed": "接続に失敗しました",
|
||||
"could_not_connect_to_server": "サーバーに接続できませんでした。URLとネットワーク接続を確認してください。",
|
||||
"an_unexpected_error_occured": "予期しないエラーが発生しました",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "サーバーの変更",
|
||||
"invalid_username_or_password": "ユーザー名またはパスワードが無効です",
|
||||
"user_does_not_have_permission_to_log_in": "ユーザーにログイン権限がありません",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "サーバーの応答に時間がかかりすぎています。しばらくしてからもう一度お試しください。",
|
||||
"server_received_too_many_requests_try_again_later": "サーバーにリクエストが多すぎます。後でもう一度お試しください。",
|
||||
"there_is_a_server_error": "サーバーエラーが発生しました",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "予期しないエラーが発生しました。サーバーのURLを正しく入力しましたか?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "サポートされていないJellyfinサーバー発見",
|
||||
"too_old_server_description": "Jellyfinを最新バージョンにアップデートしてください"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "クイックコネクトを承認する",
|
||||
"enter_the_quick_connect_code": "クイックコネクトコードを入力...",
|
||||
"success": "成功しました",
|
||||
"quick_connect_autorized": "クイックコネクトが承認されました",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "エラー",
|
||||
"invalid_code": "無効なコードです",
|
||||
"authorize": "承認"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "カスタムメニューのリンクを表示",
|
||||
"show_large_home_carousel": "大きなヒーロー(Beta)",
|
||||
"hide_libraries": "ライブラリを非表示",
|
||||
"select_liraries_you_want_to_hide": "ライブラリタブとホームページセクションから非表示にするライブラリを選択します。",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "触覚フィードバックを無効にする",
|
||||
"default_quality": "デフォルトの品質",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "エラー",
|
||||
"failed_to_get_stream_url": "ストリームURLを取得できませんでした",
|
||||
"an_error_occured_while_playing_the_video": "動画の再生中にエラーが発生しました。設定でログを確認してください。",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "クライアントエラー",
|
||||
"could_not_create_stream_for_chromecast": "Chromecastのストリームを作成できませんでした",
|
||||
"message_from_server": "サーバーからのメッセージ",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "성공",
|
||||
"connection_failed": "연결 실패",
|
||||
"could_not_connect_to_server": "서버에 연결되지 않았습니다. URL과 네트워크 상태를 확인하세요.",
|
||||
"an_unexpected_error_occured": "예기치 않은 오류가 발생했습니다",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "서버 변경",
|
||||
"invalid_username_or_password": "잘못된 아이디 혹은 비밀번호입니다",
|
||||
"user_does_not_have_permission_to_log_in": "로그인 하기 위한 권한이 없습니다",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "서버 응답이 너무 느립니다. 나중에 다시 시도하세요",
|
||||
"server_received_too_many_requests_try_again_later": "서버가 너무 많은 요청을 받았습니다. 나중에 다시 시도하세요.",
|
||||
"there_is_a_server_error": "서버 에러",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "예기치 않은 오류가 발생했습니다. 서버 URL을 올바르게 입력하셨습니까?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "퀵 커넥트 승인",
|
||||
"enter_the_quick_connect_code": "퀵 커넥트 코드 입력...",
|
||||
"success": "성공",
|
||||
"quick_connect_autorized": "퀵 커넥트 승인됨",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "오류",
|
||||
"invalid_code": "유효하지 않은 코드",
|
||||
"authorize": "승인"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "사용자 지정 메뉴 링크 표시",
|
||||
"show_large_home_carousel": "대형 홈 슬라이드 배너 표시 (베타)",
|
||||
"hide_libraries": "라이브러리 숨기기",
|
||||
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disable Haptic Feedback",
|
||||
"default_quality": "Default Quality",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Failed to get the stream URL",
|
||||
"an_error_occured_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client Error",
|
||||
"could_not_create_stream_for_chromecast": "Could not create a stream for Chromecast",
|
||||
"message_from_server": "Message from Server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Begrepen",
|
||||
"connection_failed": "Verbinding mislukt",
|
||||
"could_not_connect_to_server": "Kon niet verbinden met de server. Controleer de URL en je netwerkverbinding.",
|
||||
"an_unexpected_error_occured": "Er is een onverwachte fout opgetreden",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Server wijzigen",
|
||||
"invalid_username_or_password": "Onjuiste gebruikersnaam of wachtwoord",
|
||||
"user_does_not_have_permission_to_log_in": "Gebruiker heeft geen rechten om aan te melden",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "De server doet er te lang over om te antwoorden, probeer later opnieuw",
|
||||
"server_received_too_many_requests_try_again_later": "De server heeft te veel aanvragen ontvangen, probeer later opnieuw",
|
||||
"there_is_a_server_error": "Er is een serverfout",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Er is een onverwachte fout opgetreden. Heb je de server URL correct ingegeven?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Niet-ondersteunde Jellyfin Server Ontdekt",
|
||||
"too_old_server_description": "Werk Jellyfin bij naar de laatste versie"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Snel Verbinden toestaan",
|
||||
"enter_the_quick_connect_code": "Vul de Snel Verbinden code in...",
|
||||
"success": "Succes",
|
||||
"quick_connect_autorized": "Snel Verbinden toegestaan",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Fout",
|
||||
"invalid_code": "Ongeldige code",
|
||||
"authorize": "Toestaan"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Aangepaste menulinks tonen",
|
||||
"show_large_home_carousel": "Toon grote carrousel op startpagina (bèta)",
|
||||
"hide_libraries": "Verberg Bibliotheken",
|
||||
"select_liraries_you_want_to_hide": "Selecteer de bibliotheken die je wil verbergen van de Bibliotheektab en hoofdpagina onderdelen.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Haptische feedback uitschakelen",
|
||||
"default_quality": "Standaard kwaliteit",
|
||||
"default_playback_speed": "Standaard Afspeelsnelheid",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fout",
|
||||
"failed_to_get_stream_url": "De stream-URL kon niet worden verkregen",
|
||||
"an_error_occured_while_playing_the_video": "Er is een fout opgetreden tijdens het afspelen van de video. Controleer de logs in de instellingen.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Fout van de client",
|
||||
"could_not_create_stream_for_chromecast": "Kon geen stream maken voor Chromecast",
|
||||
"message_from_server": "Bericht van de server",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Har det",
|
||||
"connection_failed": "Tilkobling mislyktes",
|
||||
"could_not_connect_to_server": "Kunne ikke koble til serveren. Kontroller nettadressen og nettverkstilkoblingen.",
|
||||
"an_unexpected_error_occured": "En uventet feil oppstod",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Endre server",
|
||||
"invalid_username_or_password": "Ugyldig brukernavn eller passord",
|
||||
"user_does_not_have_permission_to_log_in": "Brukeren har ikke tillatelse til å logge inn",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serveren tar for lang tid å svare, prøv igjen senere",
|
||||
"server_received_too_many_requests_try_again_later": "Serveren mottok for mange forespørsler, prøv igjen senere.",
|
||||
"there_is_a_server_error": "Det er en serverfeil",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Det oppstod en uventet feil. Sendte du inn URLen til serveren riktig?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Ustøttet Jellyfin Server oppdaget",
|
||||
"too_old_server_description": "Vennligst oppdater Jellyfin til nyeste versjon"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoriser rask tilkobling",
|
||||
"enter_the_quick_connect_code": "Skriv inn hurtig-tilkobling kode...",
|
||||
"success": "Vellykket",
|
||||
"quick_connect_autorized": "Hurtig tilkobling autorisert",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Feil",
|
||||
"invalid_code": "Ugyldig kode",
|
||||
"authorize": "Autoriser"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Vis tilpassede menylenker",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Skjul biblioteker",
|
||||
"select_liraries_you_want_to_hide": "Velg bibliotekene du vil skjule deg for Biblioteket og avsnittene for hjemmesider.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Deaktiver Haptisk tilbakemelding",
|
||||
"default_quality": "Standard kvalitet",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Feil",
|
||||
"failed_to_get_stream_url": "Kan ikke hente nettadressen for stream",
|
||||
"an_error_occured_while_playing_the_video": "En feil oppstod under video. Sjekk loggene i innstillingene.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Feil med annonsør",
|
||||
"could_not_create_stream_for_chromecast": "Kan ikke opprette en strøm for Chromecast",
|
||||
"message_from_server": "Melding fra tjener: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Rozumiem",
|
||||
"connection_failed": "Połączenie nieudane",
|
||||
"could_not_connect_to_server": "Nie można połączyć się z serwerem. Sprawdź adres URL oraz połączenie sieciowe.",
|
||||
"an_unexpected_error_occured": "Wystąpił nieoczekiwany błąd",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Zmień serwer",
|
||||
"invalid_username_or_password": "Nieprawidłowa nazwa użytkownika lub hasło",
|
||||
"user_does_not_have_permission_to_log_in": "Użytkownik nie ma uprawnień do logowania",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serwer zbyt długo nie odpowiada – spróbuj ponownie później",
|
||||
"server_received_too_many_requests_try_again_later": "Serwer otrzymał zbyt wiele żądań – spróbuj ponownie później.",
|
||||
"there_is_a_server_error": "Wystąpił błąd serwera",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Wystąpił nieoczekiwany błąd. Czy wpisałeś poprawny adres URL?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Wykryto nieobsługiwany serwer Jellyfin",
|
||||
"too_old_server_description": "Proszę zaktualizować Jellyfin do najnowszej wersji"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autoryzuj szybkie połączenie",
|
||||
"enter_the_quick_connect_code": "Wpisz kod szybkiego połączenia...",
|
||||
"success": "Sukces",
|
||||
"quick_connect_autorized": "Szybkie połączenie autoryzowane",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Błąd",
|
||||
"invalid_code": "Nieprawidłowy kod",
|
||||
"authorize": "Autoryzuj"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Pokaż niestandardowe odnośniki w menu",
|
||||
"show_large_home_carousel": "Wyświetl Dużą Karuzelę na ekranie głównym (beta)",
|
||||
"hide_libraries": "Ukryj biblioteki",
|
||||
"select_liraries_you_want_to_hide": "Wybierz biblioteki, które chcesz ukryć na karcie Biblioteka i w sekcjach strony głównej.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Wyłącz wibracje",
|
||||
"default_quality": "Domyślna jakość",
|
||||
"default_playback_speed": "Domyślna prędkość odtwarzania",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Błąd",
|
||||
"failed_to_get_stream_url": "Nie udało się pobrać adresu strumienia",
|
||||
"an_error_occured_while_playing_the_video": "Wystąpił błąd podczas odtwarzania wideo. Sprawdź logi w ustawieniach.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Błąd klienta",
|
||||
"could_not_create_stream_for_chromecast": "Nie udało się utworzyć strumienia dla Chromecasta",
|
||||
"message_from_server": "Wiadomość z serwera: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Tenho isso",
|
||||
"connection_failed": "Falha na conexão",
|
||||
"could_not_connect_to_server": "Não foi possível conectar ao servidor. Verifique a URL e sua conexão de rede.",
|
||||
"an_unexpected_error_occured": "Ocorreu um erro inesperado",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Alterar Servidor",
|
||||
"invalid_username_or_password": "Usuário ou senha inválidos",
|
||||
"user_does_not_have_permission_to_log_in": "Usuário não tem permissão para fazer login",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "O servidor está demorando muito para responder, tente novamente mais tarde",
|
||||
"server_received_too_many_requests_try_again_later": "O servidor recebeu muitos pedidos, tente novamente mais tarde.",
|
||||
"there_is_a_server_error": "Existe um erro no servidor",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ocorreu um erro inesperado. Você inseriu a URL do servidor corretamente?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Servidor Jellyfin Descoberto Não Suportado",
|
||||
"too_old_server_description": "Por favor, atualize o Jellyfin para a versão mais recente"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizar conexão rápida",
|
||||
"enter_the_quick_connect_code": "Insira o código de conexão rápida...",
|
||||
"success": "Sucesso",
|
||||
"quick_connect_autorized": "Acesso Rápido Autorizado",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Erro",
|
||||
"invalid_code": "Código inválido",
|
||||
"authorize": "Autorizar"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Mostrar Links de Menu Personalizado",
|
||||
"show_large_home_carousel": "Mostrar Carrossel Grande (beta)",
|
||||
"hide_libraries": "Ocultar bibliotecas",
|
||||
"select_liraries_you_want_to_hide": "Selecione as bibliotecas que você deseja ocultar da aba Biblioteca e seções da página inicial.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Desativar o retorno tátil",
|
||||
"default_quality": "Qualidade Padrão",
|
||||
"default_playback_speed": "Velocidade padrão de reprodução",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "ERRO",
|
||||
"failed_to_get_stream_url": "Falha ao obter a URL de transmissão",
|
||||
"an_error_occured_while_playing_the_video": "Ocorreu um erro ao reproduzir o vídeo. Verifique os logs nas configurações.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Erro de Cliente",
|
||||
"could_not_create_stream_for_chromecast": "Não foi possível criar um fluxo para o Chromecast",
|
||||
"message_from_server": "Mensagem do Servidor: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Am înţeles",
|
||||
"connection_failed": "Conectare eșuată",
|
||||
"could_not_connect_to_server": "Nu s-a putut conecta la server. Verificați adresa URL și conexiunea la internet.",
|
||||
"an_unexpected_error_occured": "A apărut o eroare neașteptată",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Schimba",
|
||||
"invalid_username_or_password": "Nume de utilizator sau parolă greșită",
|
||||
"user_does_not_have_permission_to_log_in": "Utilizatorul nu are permisiunea de a se conecta",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Serverul răspunde prea greu, încearcă din nou mai târziu.",
|
||||
"server_received_too_many_requests_try_again_later": "Serverul a primit prea multe solicitări, încercați din nou mai târziu.",
|
||||
"there_is_a_server_error": "Eroare de server",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "A apărut o eroare neașteptată. Ați introdus corect adresa URL a serverului?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Serverul Jellyfin Neacceptat Descoperit",
|
||||
"too_old_server_description": "Vă rugăm să actualizați Jellyfin la cea mai recentă versiune"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Autorizare conectare rapidă",
|
||||
"enter_the_quick_connect_code": "Introduceți codul pt. conectare rapidă...",
|
||||
"success": "Succes",
|
||||
"quick_connect_autorized": "Conectare rapidă autorizată",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Eroare",
|
||||
"invalid_code": "Cod invalid.",
|
||||
"authorize": "Autorizează"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Afișează link-uri personalizate în meniu",
|
||||
"show_large_home_carousel": "Arată Caruselul Media Mare (beta)",
|
||||
"hide_libraries": "Ascunde bibliotecile",
|
||||
"select_liraries_you_want_to_hide": "Selectează bibliotecile pe care dorești să le ascunzi din fila Bibliotecă și din secțiunile paginii principale.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Dezactivează vibrațiile tactile",
|
||||
"default_quality": "Calitate implicită",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Eroare",
|
||||
"failed_to_get_stream_url": "Nu s-a putut obține adresa URL a fluxului",
|
||||
"an_error_occured_while_playing_the_video": "A apărut o eroare la redarea videoclipului. Verificați jurnalele în setări.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Eroare client",
|
||||
"could_not_create_stream_for_chromecast": "Nu s-a putut crea un flux pentru Chromecast",
|
||||
"message_from_server": "Mesaj de la server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Принято",
|
||||
"connection_failed": "Соединение не удалось",
|
||||
"could_not_connect_to_server": "Не удалось подключиться к серверу. Пожалуйста, проверьте URL и ваше интернет-соединение.",
|
||||
"an_unexpected_error_occured": "Возникла непредвиденная ошибка",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Поменять сервер",
|
||||
"invalid_username_or_password": "Неправильное имя пользователя или пароль",
|
||||
"user_does_not_have_permission_to_log_in": "Пользователь не имеет прав на вход",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Сервер долго не отвечает, попробуйте позже",
|
||||
"server_received_too_many_requests_try_again_later": "Сервер получил слишком много запросов, попробуйте позже.",
|
||||
"there_is_a_server_error": "Возникла ошибка сервера",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Возникла непредвиденная ошибка. Вы правильно ввели URL?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Обнаружен неподдерживаемый сервер Jellyfin",
|
||||
"too_old_server_description": "Пожалуйста, обновите Jellyfin до последней версии"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Авторизовать через быстрое подключение",
|
||||
"enter_the_quick_connect_code": "Введите код для быстрого подключения...",
|
||||
"success": "Успех",
|
||||
"quick_connect_autorized": "Быстрое подключение авторизовано",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Ошибка",
|
||||
"invalid_code": "Неверный код",
|
||||
"authorize": "Авторизовать"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Показать ссылки пользовательского меню",
|
||||
"show_large_home_carousel": "Показывать большую карусель (beta)",
|
||||
"hide_libraries": "Скрыть библиотеки",
|
||||
"select_liraries_you_want_to_hide": "Выберите Библиотеки, которое хотите спрятать из вкладки Библиотеки и домашней страницы.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Отключить тактильную обратную связь",
|
||||
"default_quality": "Качество по умолчанию",
|
||||
"default_playback_speed": "Скорость воспроизведения по умолчанию",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Ошибка",
|
||||
"failed_to_get_stream_url": "Не удалось получить URL потока",
|
||||
"an_error_occured_while_playing_the_video": "Возникла Неожиданная ошибка во время воспроизведения. Проверьте логи в настройках.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Ошибка клиента",
|
||||
"could_not_create_stream_for_chromecast": "Не удалось создать поток для Chromecast",
|
||||
"message_from_server": "Сообщение от сервера: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Koden har mottagits",
|
||||
"connection_failed": "Anslutningen Misslyckades",
|
||||
"could_not_connect_to_server": "Det gick inte att ansluta till servern. Kontrollera webbadressen och din nätverksanslutning.",
|
||||
"an_unexpected_error_occured": "Ett Oväntat Fel Uppstod",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Byt Server",
|
||||
"invalid_username_or_password": "Ogiltigt användarnamn eller lösenord",
|
||||
"user_does_not_have_permission_to_log_in": "Användaren har inte behörighet att logga in",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Servern svarar för långsamt, försök igen senare",
|
||||
"server_received_too_many_requests_try_again_later": "Servern har fått för många förfrågningar, försök igen senare.",
|
||||
"there_is_a_server_error": "Ett serverfel uppstod",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Ett oväntat fel uppstod. Har du angett serverns URL korrekt?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Jellyfin Servern Stöds Inte",
|
||||
"too_old_server_description": "Var God Uppdatera Jellyfin Till Den Senaste Versionen"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Godkänn snabbanslutning",
|
||||
"enter_the_quick_connect_code": "Ange snabbanslutningskod...",
|
||||
"success": "Snabbanslutning lyckades",
|
||||
"quick_connect_autorized": "Snabbanslutning Godkänd",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Fel",
|
||||
"invalid_code": "Ogiltig kod",
|
||||
"authorize": "Autentisera"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Visa anpassade menylänkar",
|
||||
"show_large_home_carousel": "Visa toppbanner (beta)",
|
||||
"hide_libraries": "Dölj bibliotek",
|
||||
"select_liraries_you_want_to_hide": "Välj de bibliotek du vill dölja på fliken Bibliotek och på startsidan.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Stäng av vibrationer",
|
||||
"default_quality": "Förvald Kvalitet",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Fel",
|
||||
"failed_to_get_stream_url": "Kunde inte hämta stream-URL",
|
||||
"an_error_occured_while_playing_the_video": "Ett fel uppstod vid uppspelning av videon. Kontrollera loggarna i inställningarna.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Klientfel",
|
||||
"could_not_create_stream_for_chromecast": "Kunde inte skapa stream för Chromecast",
|
||||
"message_from_server": "Meddelande från servern: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Got It",
|
||||
"connection_failed": "Connection Failed",
|
||||
"could_not_connect_to_server": "Could not connect to the server. Please check the URL and your network connection.",
|
||||
"an_unexpected_error_occured": "An Unexpected Error Occurred",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Change Server",
|
||||
"invalid_username_or_password": "Invalid Username or Password",
|
||||
"user_does_not_have_permission_to_log_in": "ผู้ใช้ไม่มีสิทธิ์ในการเข้าสู่ระบบ",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Server is taking too long to respond, try again later",
|
||||
"server_received_too_many_requests_try_again_later": "Server received too many requests, try again later.",
|
||||
"there_is_a_server_error": "There is a server error",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Authorize Quick Connect",
|
||||
"enter_the_quick_connect_code": "Enter the quick connect code...",
|
||||
"success": "Success",
|
||||
"quick_connect_autorized": "Quick Connect Authorized",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Error",
|
||||
"invalid_code": "Invalid Code",
|
||||
"authorize": "Authorize"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Show Custom Menu Links",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Hide Libraries",
|
||||
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disable Haptic Feedback",
|
||||
"default_quality": "Default Quality",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Failed to get the stream URL",
|
||||
"an_error_occured_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client Error",
|
||||
"could_not_create_stream_for_chromecast": "Could not create a stream for Chromecast",
|
||||
"message_from_server": "Message from Server: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "jIyaj",
|
||||
"connection_failed": "ngoQlaHbe'",
|
||||
"could_not_connect_to_server": "SeHlaw veS Ho'Do'laHbe'. URL 'ej ret ghun mej.",
|
||||
"an_unexpected_error_occured": "num ghIq Doch",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Ho'Do' veS yIghoS",
|
||||
"invalid_username_or_password": "tlhIngan pagh ngoq De' law'be'",
|
||||
"user_does_not_have_permission_to_log_in": "tlhIngan lut 'el je'laHbe'",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Ho'Do' veS jachrup. pItlh yIHaD",
|
||||
"server_received_too_many_requests_try_again_later": "Ho'Do' veS lutlh ngeb petlh law'. pItlh yIHaD.",
|
||||
"there_is_a_server_error": "Ho'Do' veS ghIq maS",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "num ghIq Doch. URL mej Danej'a'?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "**Jellyfin chu'qu' Dotlh yIchoHmoH**"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "parmaq ngoQ yIje'",
|
||||
"enter_the_quick_connect_code": "parmaq ngoQ De' yI'el...",
|
||||
"success": "Qapla'",
|
||||
"quick_connect_autorized": "parmaq ngoQ je'laH",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "ghIq",
|
||||
"invalid_code": "De' law'be'",
|
||||
"authorize": "yIje'"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "menuDaq ret teqlu' yInej",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "De'wI' bom yIQIj",
|
||||
"select_liraries_you_want_to_hide": "De'wI' bom Danej QIj yIwIv.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Qub quvHa' yIQIj",
|
||||
"default_quality": "wa' luj",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "ghIq",
|
||||
"failed_to_get_stream_url": "tlhol ret URL tu'laHbe'",
|
||||
"an_error_occured_while_playing_the_video": "mu'tlhegh tlholDI' ghIq. menDaq De' qon mej.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "lut 'el ghIq",
|
||||
"could_not_create_stream_for_chromecast": "Chromecast tlhol ret qonlaHbe'",
|
||||
"message_from_server": "Ho'Do' veS jach: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Anlaşıldı",
|
||||
"connection_failed": "Bağlantı başarısız",
|
||||
"could_not_connect_to_server": "Sunucuya bağlanılamadı. Lütfen URL'yi ve ağ bağlantınızı kontrol edin.",
|
||||
"an_unexpected_error_occured": "Beklenmedik bir hata oluştu",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Sunucu değiştir",
|
||||
"invalid_username_or_password": "Geçersiz kullanıcı adı veya şifre",
|
||||
"user_does_not_have_permission_to_log_in": "Kullanıcının giriş yapma izni yok",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Sunucunun yanıt vermesi çok uzun sürüyor, lütfen daha sonra tekrar deneyin",
|
||||
"server_received_too_many_requests_try_again_later": "Sunucu çok fazla istek aldı, lütfen daha sonra tekrar deneyin.",
|
||||
"there_is_a_server_error": "Sunucu hatası var",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Beklenmedik bir hata oluştu. Sunucu URL'sini doğru girdiğinizden emin misiniz?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Desteklenmeyen Jellyfin Sunucu sürümü bulundu.",
|
||||
"too_old_server_description": "Lütfen Jellyfin'i en son sürüme güncelleyin."
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Hızlı Bağlantıyı Yetkilendir",
|
||||
"enter_the_quick_connect_code": "Hızlı bağlantı kodunu girin...",
|
||||
"success": "Başarılı",
|
||||
"quick_connect_autorized": "Hızlı Bağlantı Yetkilendirildi",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Hata",
|
||||
"invalid_code": "Geçersiz kod",
|
||||
"authorize": "Yetkilendir"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Özel Menü Bağlantılarını Göster",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Kütüphaneleri Gizle",
|
||||
"select_liraries_you_want_to_hide": "Kütüphane sekmesinden ve ana sayfa bölümlerinden gizlemek istediğiniz kütüphaneleri seçin.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Dokunsal Geri Bildirimi Devre Dışı Bırak",
|
||||
"default_quality": "Varsayılan kalite",
|
||||
"default_playback_speed": "Varsayılan Oynatma Hızı",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Hata",
|
||||
"failed_to_get_stream_url": "Yayın URL'si alınamadı",
|
||||
"an_error_occured_while_playing_the_video": "Video oynatılırken bir hata oluştu. Ayarlardaki günlüklere bakın.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "İstemci hatası",
|
||||
"could_not_create_stream_for_chromecast": "Chromecast için yayın oluşturulamadı",
|
||||
"message_from_server": "Sunucudan mesaj: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Готово",
|
||||
"connection_failed": "Помилка зʼєднання",
|
||||
"could_not_connect_to_server": "Неможливо підʼєднатися до серверу. Будь ласка перевірте URL і ваше зʼєднання з мережею",
|
||||
"an_unexpected_error_occured": "Сталася несподівана помилка",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Змінити сервер",
|
||||
"invalid_username_or_password": "Неправильні імʼя користувача або пароль",
|
||||
"user_does_not_have_permission_to_log_in": "Користувач не маю дозволу на вхід",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Сервер відповідає занадто довго, будь-ласка спробуйте пізніше",
|
||||
"server_received_too_many_requests_try_again_later": "Сервер отримав забагато запитів, будь ласка спробуйте пізніше.",
|
||||
"there_is_a_server_error": "Відбулася помилка на стороні сервера",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Відбулася несподівана помилка. Чи введений URL сервера правильний?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Авторизуйте Швидке Зʼєднання",
|
||||
"enter_the_quick_connect_code": "Введіть код для швидкого зʼєднання...",
|
||||
"success": "Успіх",
|
||||
"quick_connect_autorized": "Швидке Зʼєднання авторизовано",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Помилка",
|
||||
"invalid_code": "Не правильний код",
|
||||
"authorize": "Авторизувати"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Показати користувацькі посилання меню",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Сховати медіатеки",
|
||||
"select_liraries_you_want_to_hide": "Виберіть медіатеки, що бажаєте приховати з вкладки Медіатека і з секції на головній сторінці.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Вимкнути тактильний зворотний зв'язок",
|
||||
"default_quality": "Якість за замовченням",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Помилка",
|
||||
"failed_to_get_stream_url": "Не вдалося отримати URL-адресу потоку",
|
||||
"an_error_occured_while_playing_the_video": "Під час відтворення відео сталася помилка. Перевірте журнал в налаштуваннях.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Помилка клієнту",
|
||||
"could_not_create_stream_for_chromecast": "Не вдалося створити потік для Chromecast",
|
||||
"message_from_server": "Повідомлення від серверу: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Đã hiểu",
|
||||
"connection_failed": "Kết nối thất bại",
|
||||
"could_not_connect_to_server": "Không thể kết nối tới máy chủ. Vui lòng kiểm tra URL và kết nối mạng.",
|
||||
"an_unexpected_error_occured": "Đã xảy ra lỗi không mong muốn",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Đổi máy chủ",
|
||||
"invalid_username_or_password": "Tên đăng nhập hoặc mật khẩu không đúng",
|
||||
"user_does_not_have_permission_to_log_in": "Người dùng không có quyền đăng nhập",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Máy chủ phản hồi quá lâu, vui lòng thử lại sau",
|
||||
"server_received_too_many_requests_try_again_later": "Máy chủ nhận quá nhiều yêu cầu, vui lòng thử lại sau.",
|
||||
"there_is_a_server_error": "Đã xảy ra lỗi ở máy chủ",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Đã xảy ra lỗi không mong muốn. Bạn có chắc đã nhập đúng URL máy chủ?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Cho phép Kết nối nhanh",
|
||||
"enter_the_quick_connect_code": "Nhập mã kết nối nhanh...",
|
||||
"success": "Thành công",
|
||||
"quick_connect_autorized": "Kết nối nhanh đã được cho phép",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Lỗi",
|
||||
"invalid_code": "Mã không hợp lệ",
|
||||
"authorize": "Cho phép"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Hiện liên kết tùy chỉnh",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Ẩn thư viện",
|
||||
"select_liraries_you_want_to_hide": "Chọn các thư viện muốn ẩn khỏi mục Thư viện và Trang chủ.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Tắt phản hồi rung",
|
||||
"default_quality": "Chất lượng mặc định",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Lỗi",
|
||||
"failed_to_get_stream_url": "Không thể lấy URL phát trực tiếp",
|
||||
"an_error_occured_while_playing_the_video": "Có lỗi khi phát video. Xem nhật ký trong cài đặt.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Lỗi phía máy khách",
|
||||
"could_not_create_stream_for_chromecast": "Không thể tạo luồng cho Chromecast",
|
||||
"message_from_server": "Thông báo từ máy chủ: {{message}}",
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
"got_it": "Got It",
|
||||
"connection_failed": "Connection Failed",
|
||||
"could_not_connect_to_server": "Could not connect to the server. Please check the URL and your network connection.",
|
||||
"an_unexpected_error_occured": "An Unexpected Error Occurred",
|
||||
"an_unexpected_error_occurred": "An unexpected error occurred",
|
||||
"change_server": "Change Server",
|
||||
"invalid_username_or_password": "Invalid Username or Password",
|
||||
"user_does_not_have_permission_to_log_in": "User does not have permission to log in",
|
||||
"server_is_taking_too_long_to_respond_try_again_later": "Server is taking too long to respond, try again later",
|
||||
"server_received_too_many_requests_try_again_later": "Server received too many requests, try again later.",
|
||||
"there_is_a_server_error": "There is a server error",
|
||||
"an_unexpected_error_occured_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"an_unexpected_error_occurred_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?",
|
||||
"too_old_server_text": "Unsupported Jellyfin Server Discovered",
|
||||
"too_old_server_description": "Please update Jellyfin to the latest version"
|
||||
},
|
||||
@@ -188,7 +188,7 @@
|
||||
"authorize_button": "Authorize Quick Connect",
|
||||
"enter_the_quick_connect_code": "Enter the quick connect code...",
|
||||
"success": "Success",
|
||||
"quick_connect_autorized": "Quick Connect Authorized",
|
||||
"quick_connect_authorized": "Quick Connect authorized",
|
||||
"error": "Error",
|
||||
"invalid_code": "Invalid Code",
|
||||
"authorize": "Authorize"
|
||||
@@ -298,7 +298,7 @@
|
||||
"show_custom_menu_links": "Show Custom Menu Links",
|
||||
"show_large_home_carousel": "Show Large Home Carousel (beta)",
|
||||
"hide_libraries": "Hide Libraries",
|
||||
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"select_libraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
|
||||
"disable_haptic_feedback": "Disable Haptic Feedback",
|
||||
"default_quality": "Default Quality",
|
||||
"default_playback_speed": "Default Playback Speed",
|
||||
@@ -598,7 +598,7 @@
|
||||
"mpv_player_title": "MPV Player",
|
||||
"error": "Error",
|
||||
"failed_to_get_stream_url": "Failed to get the stream URL",
|
||||
"an_error_occured_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"an_error_occurred_while_playing_the_video": "An error occurred while playing the video. Check logs in settings.",
|
||||
"client_error": "Client Error",
|
||||
"could_not_create_stream_for_chromecast": "Could not create a stream for Chromecast",
|
||||
"message_from_server": "Message from Server: {{message}}",
|
||||
|
||||
Reference in New Issue
Block a user