diff --git a/back/src/Kyoo.Authentication/Views/AuthApi.cs b/back/src/Kyoo.Authentication/Views/AuthApi.cs index 6e3548f2..550e1990 100644 --- a/back/src/Kyoo.Authentication/Views/AuthApi.cs +++ b/back/src/Kyoo.Authentication/Views/AuthApi.cs @@ -211,6 +211,12 @@ public class AuthApi( User? user = await users.GetOrDefault( new Filter.Eq(nameof(Abstractions.Models.User.Username), request.Username) ); + if (user != null && user.Password == null) + return Forbid( + new RequestError( + "This account was registerd via oidc. Please login via oidc or add a password to your account in the settings first" + ) + ); if (user == null || !BCryptNet.Verify(request.Password, user.Password)) return Forbid(new RequestError("The user and password does not match.")); diff --git a/front/apps/mobile/app.config.js b/front/apps/mobile/app.config.js deleted file mode 100644 index b0abf42a..00000000 --- a/front/apps/mobile/app.config.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Kyoo - A portable and vast media library solution. - * Copyright (c) Kyoo. - * - * See AUTHORS.md and LICENSE file in the project root for full license information. - * - * Kyoo is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * Kyoo is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Kyoo. If not, see . - */ - -const IS_DEV = process.env.APP_VARIANT === "development"; - -// Defined outside the config because dark splashscreen needs to be platform specific. -const splash = { - image: "./assets/icon.png", - resizeMode: "contain", - backgroundColor: "#eff1f5", - dark: { - image: "./assets/icon.png", - resizeMode: "contain", - backgroundColor: "#1e1e2e", - }, -}; - -const config = { - expo: { - name: IS_DEV ? "Kyoo Development" : "Kyoo", - slug: "kyoo", - scheme: "kyoo", - version: "1.0.0", - orientation: "default", - icon: "./assets/icon.png", - userInterfaceStyle: "automatic", - splash, - assetBundlePatterns: ["**/*"], - ios: { - supportsTablet: true, - }, - android: { - package: IS_DEV ? "dev.zoriya.kyoo.dev" : "dev.zoriya.kyoo", - adaptiveIcon: { - foregroundImage: "./assets/icon.png", - backgroundColor: "#eff1f5", - }, - splash, - }, - updates: { - url: "https://u.expo.dev/55de6b52-c649-4a15-9a45-569ff5ed036c", - fallbackToCacheTimeout: 0, - }, - runtimeVersion: { - policy: "sdkVersion", - }, - extra: { - eas: { - projectId: "55de6b52-c649-4a15-9a45-569ff5ed036c", - }, - }, - plugins: ["expo-build-properties", "expo-localization"], - }, -}; -export default config; diff --git a/front/apps/mobile/app.config.ts b/front/apps/mobile/app.config.ts new file mode 100644 index 00000000..85044c04 --- /dev/null +++ b/front/apps/mobile/app.config.ts @@ -0,0 +1,99 @@ +/* + * Kyoo - A portable and vast media library solution. + * Copyright (c) Kyoo. + * + * See AUTHORS.md and LICENSE file in the project root for full license information. + * + * Kyoo is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * Kyoo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Kyoo. If not, see . + */ + +// import "ts-node/register"; // Add this to import TypeScript files +import type { ExpoConfig } from "expo/config"; +import { withAndroidManifest } from "expo/config-plugins"; + +const IS_DEV = process.env.APP_VARIANT === "development"; + +// Defined outside the config because dark splashscreen needs to be platform specific. +const splash = { + image: "./assets/icon.png", + resizeMode: "contain", + backgroundColor: "#eff1f5", + dark: { + image: "./assets/icon.png", + resizeMode: "contain", + backgroundColor: "#1e1e2e", + }, +} as const; + +const config: ExpoConfig = { + name: IS_DEV ? "Kyoo Development" : "Kyoo", + slug: "kyoo", + scheme: "kyoo", + version: "1.0.0", + orientation: "default", + icon: "./assets/icon.png", + userInterfaceStyle: "automatic", + splash, + assetBundlePatterns: ["**/*"], + ios: { + supportsTablet: true, + }, + android: { + package: IS_DEV ? "dev.zoriya.kyoo.dev" : "dev.zoriya.kyoo", + adaptiveIcon: { + foregroundImage: "./assets/icon.png", + backgroundColor: "#eff1f5", + }, + splash, + permissions: [ + "android.permission.FOREGROUND_SERVICE", + "android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK", + ], + }, + updates: { + url: "https://u.expo.dev/55de6b52-c649-4a15-9a45-569ff5ed036c", + fallbackToCacheTimeout: 0, + }, + runtimeVersion: { + policy: "sdkVersion", + }, + extra: { + eas: { + projectId: "55de6b52-c649-4a15-9a45-569ff5ed036c", + }, + }, + plugins: ["expo-build-properties", "expo-localization"], +}; + +const withForegroundService = (c: ExpoConfig): ExpoConfig => { + return withAndroidManifest(c, async (config) => { + const manifest = config.modResults.manifest; + manifest.application![0].service ??= []; + manifest.application![0].service.push({ + $: { + "android:name": "com.brentvatne.exoplayer.VideoPlaybackService", + "android:exported": "false", + "android:foregroundServiceType": "mediaPlayback", + }, + "intent-filter": [ + { + action: [{ $: { "android:name": "androidx.media3.session.MediaSessionService" } }], + }, + ], + }); + return config; + }); +}; + +export default withForegroundService(config); diff --git a/front/apps/mobile/package.json b/front/apps/mobile/package.json index 370bf2af..dc3cb697 100644 --- a/front/apps/mobile/package.json +++ b/front/apps/mobile/package.json @@ -5,8 +5,8 @@ "sideEffects": false, "scripts": { "dev": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", + "android": "expo run:android", + "ios": "expo run:ios", "web": "expo start --web", "build": "eas build --profile production --platform android --non-interactive --auto-submit", "build:apk": "eas build --profile preview --platform android --non-interactive --json", @@ -23,9 +23,9 @@ "@material-symbols/svg-400": "^0.18.0", "@react-native-community/netinfo": "11.3.1", "@shopify/flash-list": "1.6.4", - "@tanstack/query-sync-storage-persister": "^5.37.1", - "@tanstack/react-query": "^5.37.1", - "@tanstack/react-query-persist-client": "^5.37.1", + "@tanstack/query-sync-storage-persister": "^5.38.0", + "@tanstack/react-query": "^5.39.0", + "@tanstack/react-query-persist-client": "^5.39.0", "array-shuffle": "^3.0.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", "expo": "^51.0.8", @@ -44,14 +44,14 @@ "expo-secure-store": "~13.0.1", "expo-status-bar": "~1.12.1", "expo-updates": "~0.25.14", - "i18next": "^23.11.4", + "i18next": "^23.11.5", "intl-pluralrules": "^2.0.1", "moti": "^0.29.0", "react": "18.2.0", "react-dom": "18.2.0", - "react-i18next": "^14.1.1", + "react-i18next": "^14.1.2", "react-native": "0.74.1", - "react-native-blurhash": "^2.0.2", + "react-native-blurhash": "^2.0.3", "react-native-fast-image": "^8.6.3", "react-native-mmkv": "^2.12.2", "react-native-reanimated": "~3.10.1", @@ -59,11 +59,11 @@ "react-native-screens": "~3.31.1", "react-native-svg": "15.2.0", "react-native-uuid": "^2.0.2", - "react-native-video": "^6.0.0", + "react-native-video": "^6.1.2", "yoshiki": "1.2.14" }, "devDependencies": { - "@babel/core": "^7.24.5", + "@babel/core": "^7.24.6", "react-native-svg-transformer": "^1.4.0", "typescript": "~5.3.3" }, diff --git a/front/apps/web/package.json b/front/apps/web/package.json index 97e71a95..f25fb9bc 100644 --- a/front/apps/web/package.json +++ b/front/apps/web/package.json @@ -19,27 +19,27 @@ "@material-symbols/svg-400": "^0.18.0", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-select": "^2.0.0", - "@tanstack/react-query": "^5.37.1", - "@tanstack/react-query-devtools": "^5.37.1", + "@tanstack/react-query": "^5.39.0", + "@tanstack/react-query-devtools": "^5.39.0", "array-shuffle": "^3.0.0", "expo-image-picker": "~15.0.5", "expo-linear-gradient": "^13.0.2", "expo-modules-core": "^1.12.11", "hls.js": "^1.5.8", - "i18next": "^23.11.4", + "i18next": "^23.11.5", "jassub": "^1.7.15", - "jotai": "^2.8.0", + "jotai": "^2.8.1", "moti": "^0.29.0", "next": "14.2.3", "next-translate": "^2.6.2", "raf": "^3.4.1", "react": "18.3.1", "react-dom": "18.3.1", - "react-i18next": "^14.1.1", + "react-i18next": "^14.1.2", "react-native-reanimated": "3.11.0", "react-native-svg": "15.3.0", - "react-native-video": "^6.0.0", - "react-native-web": "0.19.11", + "react-native-video": "^6.1.2", + "react-native-web": "0.19.12", "react-tooltip": "^5.26.4", "solito": "^4.2.2", "srt-webvtt": "zoriya/srt-webvtt#build", diff --git a/front/packages/primitives/package.json b/front/packages/primitives/package.json index 4f390639..106165a1 100644 --- a/front/packages/primitives/package.json +++ b/front/packages/primitives/package.json @@ -53,13 +53,13 @@ }, "dependencies": { "@expo/html-elements": "^0.10.1", - "@tanstack/react-query": "^5.37.1", + "@tanstack/react-query": "^5.39.0", "solito": "^4.2.2" }, "optionalDependencies": { "@radix-ui/react-select": "^2.0.0", "blurhash": "^2.0.5", - "react-native-blurhash": "^2.0.2", + "react-native-blurhash": "^2.0.3", "react-native-fast-image": "^8.6.3", "react-native-safe-area-context": "4.10.1" } diff --git a/front/packages/primitives/src/skeleton.tsx b/front/packages/primitives/src/skeleton.tsx index 3470a75d..2c29b7e8 100644 --- a/front/packages/primitives/src/skeleton.tsx +++ b/front/packages/primitives/src/skeleton.tsx @@ -19,12 +19,20 @@ */ import { LinearGradient as LG } from "expo-linear-gradient"; -import { MotiView, motify } from "moti"; -import { useState } from "react"; -import { Platform, View, type ViewProps } from "react-native"; +import { memo, useEffect } from "react"; +import { Platform, StyleSheet, View, type ViewProps } from "react-native"; +import Animated, { + SharedValue, + useAnimatedStyle, + useDerivedValue, + useSharedValue, + withDelay, + withRepeat, + withTiming, +} from "react-native-reanimated"; import { em, percent, px, rem, useYoshiki } from "yoshiki/native"; -const LinearGradient = motify(LG)(); +const LinearGradient = Animated.createAnimatedComponent(LG); export const SkeletonCss = () => (