From 829e569ccda40d803a48c8f9ae8940fb10e0d880 Mon Sep 17 00:00:00 2001 From: tapframe Date: Wed, 15 Oct 2025 21:54:02 +0530 Subject: [PATCH] ui changes --- android/app/build.gradle | 33 ++-- android/gradle.properties | 2 +- app/Streams.tsx | 1 + ios/Nuvio.xcodeproj/project.pbxproj | 6 +- ios/Podfile.lock | 10 +- package-lock.json | 164 +++++++++--------- package.json | 2 +- .../loading/MetadataLoadingScreen.tsx | 62 +++++-- src/components/metadata/HeroSection.tsx | 43 ++++- src/screens/MetadataScreen.tsx | 42 +++-- 10 files changed, 221 insertions(+), 144 deletions(-) create mode 100644 app/Streams.tsx diff --git a/android/app/build.gradle b/android/app/build.gradle index 002dd38..f9ed83b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -81,7 +81,7 @@ def enableMinifyInReleaseBuilds = (findProperty('android.enableMinifyInReleaseBu */ def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+' -apply from: new File(["node", "--print", "require('path').dirname(require.resolve('@sentry/react-native/package.json'))"].execute().text.trim(), "sentry.gradle") +// apply from: new File(["node", "--print", "require('path').dirname(require.resolve('@sentry/react-native/package.json'))"].execute().text.trim(), "sentry.gradle") android { ndkVersion rootProject.ext.ndkVersion @@ -100,41 +100,32 @@ android { buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\"" } - // Split APKs by architecture and density for smaller downloads + // Split APKs by architecture only for smaller downloads splits { abi { enable true reset() - include "arm64-v8a", "armeabi-v7a", "x86", "x86_64" - universalApk true // Generate universal APK as well + include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' + universalApk true } density { - enable true - reset() - include "ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi" - universalApk true // Generate universal APK as well + enable false } } // Generate unique version codes for each split APK def abiVersionCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2, 'x86': 3, 'x86_64': 4] - def densityVersionCodes = ['ldpi': 1, 'mdpi': 2, 'hdpi': 3, 'xhdpi': 4, 'xxhdpi': 5, 'xxxhdpi': 6] - android.applicationVariants.all { variant -> + applicationVariants.all { variant -> variant.outputs.each { output -> - def baseVersionCode = 19 // Current versionCode 20from defaultConfig + def baseVersionCode = 20 // Current versionCode from defaultConfig def abiName = output.getFilter(com.android.build.OutputFile.ABI) - def densityName = output.getFilter(com.android.build.OutputFile.DENSITY) - - def versionCode 20= baseVersionCode * 100 // Base multiplier - + + def versionCode = baseVersionCode * 100 // Base multiplier + if (abiName != null) { - versionCode 20+= abiVersionCodes.get(abiName) * 10 + versionCode += abiVersionCodes.get(abiName) } - - if (densityName != null) { - versionCode 20+= densityVersionCodes.get(densityName) - } - + output.versionCodeOverride = versionCode } } diff --git a/android/gradle.properties b/android/gradle.properties index 8e39f82..bc4cf84 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -10,7 +10,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m -org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m +org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/app/Streams.tsx b/app/Streams.tsx new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/app/Streams.tsx @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ios/Nuvio.xcodeproj/project.pbxproj b/ios/Nuvio.xcodeproj/project.pbxproj index 084418f..4bf304a 100644 --- a/ios/Nuvio.xcodeproj/project.pbxproj +++ b/ios/Nuvio.xcodeproj/project.pbxproj @@ -461,7 +461,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.app; - PRODUCT_NAME = Nuvio; + PRODUCT_NAME = "Nuvio"; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -492,8 +492,8 @@ "-lc++", ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; - PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.app; - PRODUCT_NAME = Nuvio; + PRODUCT_BUNDLE_IDENTIFIER = "com.nuvio.app"; + PRODUCT_NAME = "Nuvio"; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ada4a4a..19eafe7 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2506,7 +2506,7 @@ PODS: - ReactCommon/turbomodule/core - ReactNativeDependencies - Yoga - - RNSentry (7.2.0): + - RNSentry (7.3.0): - hermes-engine - RCTRequired - RCTTypeSafety @@ -2528,7 +2528,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - ReactNativeDependencies - - Sentry/HybridSDK (= 8.56.1) + - Sentry/HybridSDK (= 8.56.2) - Yoga - RNSVG (15.12.1): - hermes-engine @@ -2677,7 +2677,7 @@ PODS: - SDWebImageWebPCoder (0.14.6): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.17) - - Sentry/HybridSDK (8.56.1) + - Sentry/HybridSDK (8.56.2) - SwiftUIIntrospect (1.3.0) - Yoga (0.0.0) @@ -3225,14 +3225,14 @@ SPEC CHECKSUMS: RNGestureHandler: 2914750df066d89bf9d8f48a10ad5f0051108ac3 RNReanimated: 3895a29fdf77bbe2a627e1ed599a5e5d1df76c29 RNScreens: d8d6f1792f6e7ac12b0190d33d8d390efc0c1845 - RNSentry: 41979b419908128847ef662cc130a400b7576fa9 + RNSentry: 7726bf35e00ab799f50c4618df6f5417553678a0 RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34 RNVectorIcons: 4351544f100d4f12cac156a7c13399e60bab3e26 RNWorklets: 54d8dffb7f645873a58484658ddfd4bd1a9a0bc1 SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 - Sentry: b3ec44d01708fce73f99b544beb57e890eca4406 + Sentry: b53951377b78e21a734f5dc8318e333dbfc682d7 SwiftUIIntrospect: fee9aa07293ee280373a591e1824e8ddc869ba5d Yoga: 051f086b5ccf465ff2ed38a2cf5a558ae01aaaa1 diff --git a/package-lock.json b/package-lock.json index f78d571..0e9a36b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.10", "@react-navigation/stack": "^7.2.10", - "@sentry/react-native": "~7.2.0", + "@sentry/react-native": "~7.3.0", "@shopify/flash-list": "2.0.2", "@supabase/supabase-js": "^2.54.0", "@types/lodash": "^4.17.16", @@ -3284,50 +3284,50 @@ } }, "node_modules/@sentry-internal/browser-utils": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.12.0.tgz", - "integrity": "sha512-dozbx389jhKynj0d657FsgbBVOar7pX3mb6GjqCxslXF0VKpZH2Xks0U32RgDY/nK27O+o095IWz7YvjVmPkDw==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.18.0.tgz", + "integrity": "sha512-6Y5VkNcj5ecIFsKdL8/7hrLt7pCuWR4BRLsKOHAmhdCnXtobf7v6DeBow2Hk5yEYO0AwjP5mqvoBAewbS+h3GA==", "license": "MIT", "dependencies": { - "@sentry/core": "10.12.0" + "@sentry/core": "10.18.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.12.0.tgz", - "integrity": "sha512-0+7ceO6yQPPqfxRc9ue/xoPHKcnB917ezPaehGQNfAFNQB9PNTG1y55+8mRu0Fw+ANbZeCt/HyoCmXuRdxmkpg==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.18.0.tgz", + "integrity": "sha512-uuupIivGPCpRStMU1I3sYPgD+pl8PqNV1DSVgVS5LF99h8tqjmRGS1xkCrUaUhVhVmsnxzbnvXb1hsOaCXX7DA==", "license": "MIT", "dependencies": { - "@sentry/core": "10.12.0" + "@sentry/core": "10.18.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.12.0.tgz", - "integrity": "sha512-/1093gSNGN5KlOBsuyAl33JkzGiG38kCnxswQLZWpPpR6LBbR1Ddb18HjhDpoQNNEZybJBgJC3a5NKl43C2TSQ==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.18.0.tgz", + "integrity": "sha512-ixr3K19q4oTRgM0xANi+8ThDUbxV5iixUIgvJrT7c1L6yyidovIwO0D82ZY3phUfMkgE+mX3cxX46gXTRTglKQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "10.12.0", - "@sentry/core": "10.12.0" + "@sentry-internal/browser-utils": "10.18.0", + "@sentry/core": "10.18.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.12.0.tgz", - "integrity": "sha512-W/z1/+69i3INNfPjD1KuinSNaRQaApjzwb37IFmiyF440F93hxmEYgXHk3poOlYYaigl2JMYbysGPWOiXnqUXA==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.18.0.tgz", + "integrity": "sha512-asp1biXA+F5HAKl7RvPbf5s087bg1bpxMB9E69xWc1ECUfFMPrFRNS7mAJ5A8DTd1K74E9cFsLl6zO29HpH4+w==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "10.12.0", - "@sentry/core": "10.12.0" + "@sentry-internal/replay": "10.18.0", + "@sentry/core": "10.18.0" }, "engines": { "node": ">=18" @@ -3343,25 +3343,25 @@ } }, "node_modules/@sentry/browser": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.12.0.tgz", - "integrity": "sha512-lKyaB2NFmr7SxPjmMTLLhQ7xfxaY3kdkMhpzuRI5qwOngtKt4+FtvNYHRuz+PTtEFv4OaHhNNbRn6r91gWguQg==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.18.0.tgz", + "integrity": "sha512-JrPfxjCsuVYUe16U4fo4W2Fn0f9BwRev3G28a4ZIkwKwJo+qSnIk1mT8Eam8nwNCU8MZjB4KNE9w2p0kaoQxvQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "10.12.0", - "@sentry-internal/feedback": "10.12.0", - "@sentry-internal/replay": "10.12.0", - "@sentry-internal/replay-canvas": "10.12.0", - "@sentry/core": "10.12.0" + "@sentry-internal/browser-utils": "10.18.0", + "@sentry-internal/feedback": "10.18.0", + "@sentry-internal/replay": "10.18.0", + "@sentry-internal/replay-canvas": "10.18.0", + "@sentry/core": "10.18.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/cli": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.55.0.tgz", - "integrity": "sha512-cynvcIM2xL8ddwELyFRSpZQw4UtFZzoM2rId2l9vg7+wDREPDocMJB9lEQpBIo3eqhp9JswqUT037yjO6iJ5Sw==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.56.0.tgz", + "integrity": "sha512-br6+1nTPUV5EG1oaxLzxv31kREFKr49Y1+3jutfMUz9Nl8VyVP7o9YwakB/YWl+0Vi0NXg5vq7qsd/OOuV5j8w==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -3378,20 +3378,20 @@ "node": ">= 10" }, "optionalDependencies": { - "@sentry/cli-darwin": "2.55.0", - "@sentry/cli-linux-arm": "2.55.0", - "@sentry/cli-linux-arm64": "2.55.0", - "@sentry/cli-linux-i686": "2.55.0", - "@sentry/cli-linux-x64": "2.55.0", - "@sentry/cli-win32-arm64": "2.55.0", - "@sentry/cli-win32-i686": "2.55.0", - "@sentry/cli-win32-x64": "2.55.0" + "@sentry/cli-darwin": "2.56.0", + "@sentry/cli-linux-arm": "2.56.0", + "@sentry/cli-linux-arm64": "2.56.0", + "@sentry/cli-linux-i686": "2.56.0", + "@sentry/cli-linux-x64": "2.56.0", + "@sentry/cli-win32-arm64": "2.56.0", + "@sentry/cli-win32-i686": "2.56.0", + "@sentry/cli-win32-x64": "2.56.0" } }, "node_modules/@sentry/cli-darwin": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.55.0.tgz", - "integrity": "sha512-jGHE7SHHzqXUmnsmRLgorVH6nmMmTjQQXdPZbSL5tRtH8d3OIYrVNr5D72DSgD26XAPBDMV0ibqOQ9NKoiSpfA==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.56.0.tgz", + "integrity": "sha512-CzXFWbv3GrjU0gFlUM9jt0fvJmyo5ktty4HGxRFfS/eMC6xW58Gg/sEeMVEkdvk5osKooX/YEgfLBdo4zvuWDA==", "license": "BSD-3-Clause", "optional": true, "os": [ @@ -3402,9 +3402,9 @@ } }, "node_modules/@sentry/cli-linux-arm": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.55.0.tgz", - "integrity": "sha512-ATjU0PsiWADSPLF/kZroLZ7FPKd5W9TDWHVkKNwIUNTei702LFgTjNeRwOIzTgSvG3yTmVEqtwFQfFN/7hnVXQ==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.56.0.tgz", + "integrity": "sha512-vQCCMhZLugPmr25XBoP94dpQsFa110qK5SBUVJcRpJKyzMZd+6ueeHNslq2mB0OF4BwL1qd/ZDIa4nxa1+0rjQ==", "cpu": [ "arm" ], @@ -3420,9 +3420,9 @@ } }, "node_modules/@sentry/cli-linux-arm64": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.55.0.tgz", - "integrity": "sha512-jNB/0/gFcOuDCaY/TqeuEpsy/k52dwyk1SOV3s1ku4DUsln6govTppeAGRewY3T1Rj9B2vgIWTrnB8KVh9+Rgg==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.56.0.tgz", + "integrity": "sha512-91d5ZlC989j/t+TXor/glPyx6SnLFS/SlJ9fIrHIQohdGKyWWSFb4VKUan8Ok3GYu9SUzKTMByryIOoYEmeGVw==", "cpu": [ "arm64" ], @@ -3438,9 +3438,9 @@ } }, "node_modules/@sentry/cli-linux-i686": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.55.0.tgz", - "integrity": "sha512-8LZjo6PncTM6bWdaggscNOi5r7F/fqRREsCwvd51dcjGj7Kp1plqo9feEzYQ+jq+KUzVCiWfHrUjddFmYyZJrg==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.56.0.tgz", + "integrity": "sha512-MZzXuq1Q/TktN81DUs6XSBU752pG3XWSJdZR+NCStIg3l8s3O/Pwh6OcDHTYqgwsYJaGBpA0fP2Afl5XeSAUNg==", "cpu": [ "x86", "ia32" @@ -3457,9 +3457,9 @@ } }, "node_modules/@sentry/cli-linux-x64": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.55.0.tgz", - "integrity": "sha512-5LUVvq74Yj2cZZy5g5o/54dcWEaX4rf3myTHy73AKhRj1PABtOkfexOLbF9xSrZy95WXWaXyeH+k5n5z/vtHfA==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.56.0.tgz", + "integrity": "sha512-INOO2OQ90Y3UzYgHRdrHdKC/0es3YSHLv0iNNgQwllL0YZihSVNYSSrZqcPq8oSDllEy9Vt9oOm/7qEnUP2Kfw==", "cpu": [ "x64" ], @@ -3475,9 +3475,9 @@ } }, "node_modules/@sentry/cli-win32-arm64": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.55.0.tgz", - "integrity": "sha512-cWIQdzm1pfLwPARsV6dUb8TVd6Y3V1A2VWxjTons3Ift6GvtVmiAe0OWL8t2Yt95i8v61kTD/6Tq21OAaogqzA==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.56.0.tgz", + "integrity": "sha512-eUvkVk9KK01q6/qyugQPh7dAxqFPbgOa62QAoSwo11WQFYc3NPgJLilFWLQo+nahHGYKh6PKuCJ5tcqnQq5Hkg==", "cpu": [ "arm64" ], @@ -3491,9 +3491,9 @@ } }, "node_modules/@sentry/cli-win32-i686": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.55.0.tgz", - "integrity": "sha512-ldepCn2t9r4I0wvgk7NRaA7coJyy4rTQAzM66u9j5nTEsUldf66xym6esd5ZZRAaJUjffqvHqUIr/lrieTIrVg==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.56.0.tgz", + "integrity": "sha512-mpCA8hKXuvT17bl1H/54KOa5i+02VBBHVlOiP3ltyBuQUqfvX/30Zl/86Spy+ikodovZWAHv5e5FpyXbY1/mPw==", "cpu": [ "x86", "ia32" @@ -3508,9 +3508,9 @@ } }, "node_modules/@sentry/cli-win32-x64": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.55.0.tgz", - "integrity": "sha512-4hPc/I/9tXx+HLTdTGwlagtAfDSIa2AoTUP30tl32NAYQhx9a6niUbPAemK2qfxesiufJ7D2djX83rCw6WnJVA==", + "version": "2.56.0", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.56.0.tgz", + "integrity": "sha512-UV0pXNls+/ViAU/3XsHLLNEHCsRYaGEwJdY3HyGIufSlglxrX6BVApkV9ziGi4WAxcJWLjQdfcEs6V5B+wBy0A==", "cpu": [ "x64" ], @@ -3524,22 +3524,22 @@ } }, "node_modules/@sentry/core": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.12.0.tgz", - "integrity": "sha512-Jrf0Yo7DvmI/ZQcvBnA0xKNAFkJlVC/fMlvcin+5IrFNRcqOToZ2vtF+XqTgjRZymXQNE8s1QTD7IomPHk0TAw==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.18.0.tgz", + "integrity": "sha512-zlhAlzc/Qpza8f/CMUb7zg/9FOhWouKAm9zyV9jZlx9lL6WceVbUEwQ3rq8ncGgM+LMwlASCOjsz5a728vAhCw==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.12.0.tgz", - "integrity": "sha512-TpqgdoYbkf5JynmmW2oQhHQ/h5w+XPYk0cEb/UrsGlvJvnBSR+5tgh0AqxCSi3gvtp82rAXI5w1TyRPBbhLDBw==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.18.0.tgz", + "integrity": "sha512-mLVJzF/+VFTNkqVqApU9QLrTAahASLKLaPreJ5LUXhEbCEiBUTQNZIn8Js+tDisHwbdy9k94XC1/OLxld3Calg==", "license": "MIT", "dependencies": { - "@sentry/browser": "10.12.0", - "@sentry/core": "10.12.0", + "@sentry/browser": "10.18.0", + "@sentry/core": "10.18.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -3550,17 +3550,17 @@ } }, "node_modules/@sentry/react-native": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-7.2.0.tgz", - "integrity": "sha512-rjqYgEjntPz1sPysud78wi4B9ui7LBVPsG6qr8s/htLMYho9GPGFA5dF+eqsQWqMX8NDReAxNkLTC4+gCNklLQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-7.3.0.tgz", + "integrity": "sha512-VrvHK062zq+zuwFffloUjJ2K/+I+IO+tmtgwQMW8t1GkjdtVmrKm3QfZQVzfsXW53sehqkK9CgIHawj4p7DKjQ==", "license": "MIT", "dependencies": { "@sentry/babel-plugin-component-annotate": "4.3.0", - "@sentry/browser": "10.12.0", - "@sentry/cli": "2.55.0", - "@sentry/core": "10.12.0", - "@sentry/react": "10.12.0", - "@sentry/types": "10.12.0" + "@sentry/browser": "10.18.0", + "@sentry/cli": "2.56.0", + "@sentry/core": "10.18.0", + "@sentry/react": "10.18.0", + "@sentry/types": "10.18.0" }, "bin": { "sentry-expo-upload-sourcemaps": "scripts/expo-upload-sourcemaps.js" @@ -3577,12 +3577,12 @@ } }, "node_modules/@sentry/types": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-10.12.0.tgz", - "integrity": "sha512-sKGj3l3V8ZKISh2Tu88bHfnm5ztkRtSLdmpZ6TmCeJdSM9pV+RRd6CMJ0RnSEXmYHselPNUod521t2NQFd4W1w==", + "version": "10.18.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-10.18.0.tgz", + "integrity": "sha512-AVUL63Lotvd7cujtch1A7Rax5syleB7jAP/I5sdCs6UvDc5VqmuTNsrg5DfjBNOOPPoGGfbSBaMBQAimvtNFaA==", "license": "MIT", "dependencies": { - "@sentry/core": "10.12.0" + "@sentry/core": "10.18.0" }, "engines": { "node": ">=18" diff --git a/package.json b/package.json index 48f7fc8..7f3d492 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.10", "@react-navigation/stack": "^7.2.10", - "@sentry/react-native": "~7.2.0", + "@sentry/react-native": "~7.3.0", "@shopify/flash-list": "2.0.2", "@supabase/supabase-js": "^2.54.0", "@types/lodash": "^4.17.16", diff --git a/src/components/loading/MetadataLoadingScreen.tsx b/src/components/loading/MetadataLoadingScreen.tsx index 74186d2..d44acc0 100644 --- a/src/components/loading/MetadataLoadingScreen.tsx +++ b/src/components/loading/MetadataLoadingScreen.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, forwardRef, useImperativeHandle } from 'react'; import { View, Text, @@ -16,11 +16,17 @@ const { width, height } = Dimensions.get('window'); interface MetadataLoadingScreenProps { type?: 'movie' | 'series'; + onExitComplete?: () => void; } -export const MetadataLoadingScreen: React.FC = ({ - type = 'movie' -}) => { +export interface MetadataLoadingScreenRef { + exit: () => void; +} + +export const MetadataLoadingScreen = forwardRef(({ + type = 'movie', + onExitComplete +}, ref) => { const { currentTheme } = useTheme(); // Animation values - removed fadeAnim since parent handles transitions @@ -32,6 +38,39 @@ export const MetadataLoadingScreen: React.FC = ({ const sceneScale = useRef(new Animated.Value(0.95)).current; const sceneTranslateY = useRef(new Animated.Value(8)).current; + // Exit animation function + const exit = () => { + const exitAnimation = Animated.parallel([ + Animated.timing(sceneOpacity, { + toValue: 0, + duration: 200, + easing: Easing.bezier(0.25, 0.1, 0.25, 1.0), + useNativeDriver: true, + }), + Animated.timing(sceneScale, { + toValue: 0.95, + duration: 200, + easing: Easing.bezier(0.25, 0.1, 0.25, 1.0), + useNativeDriver: true, + }), + Animated.timing(sceneTranslateY, { + toValue: 8, + duration: 200, + easing: Easing.bezier(0.25, 0.1, 0.25, 1.0), + useNativeDriver: true, + }), + ]); + + exitAnimation.start(() => { + onExitComplete?.(); + }); + }; + + // Expose exit method through ref + useImperativeHandle(ref, () => ({ + exit, + })); + useEffect(() => { // Scene entrance animation (matching tab navigator) const sceneAnimation = Animated.parallel([ @@ -61,13 +100,15 @@ export const MetadataLoadingScreen: React.FC = ({ const pulseAnimation = Animated.loop( Animated.sequence([ Animated.timing(pulseAnim, { - toValue: 1, - duration: 1200, + toValue: 0.8, + duration: 2500, + easing: Easing.bezier(0.4, 0, 0.2, 1), useNativeDriver: true, }), Animated.timing(pulseAnim, { - toValue: 0.3, - duration: 1200, + toValue: 0.4, + duration: 2500, + easing: Easing.bezier(0.4, 0, 0.2, 1), useNativeDriver: true, }), ]) @@ -77,7 +118,8 @@ export const MetadataLoadingScreen: React.FC = ({ const shimmerAnimation = Animated.loop( Animated.timing(shimmerAnim, { toValue: 1, - duration: 1500, + duration: 2500, + easing: Easing.inOut(Easing.ease), useNativeDriver: true, }) ); @@ -264,7 +306,7 @@ export const MetadataLoadingScreen: React.FC = ({ ); -}; +}); const styles = StyleSheet.create({ container: { diff --git a/src/components/metadata/HeroSection.tsx b/src/components/metadata/HeroSection.tsx index e7fb6f8..6e425e2 100644 --- a/src/components/metadata/HeroSection.tsx +++ b/src/components/metadata/HeroSection.tsx @@ -67,7 +67,6 @@ interface HeroSectionProps { metadata: any; bannerImage: string | null; loadingBanner: boolean; - logoLoadError: boolean; scrollY: SharedValue; heroHeight: SharedValue; heroOpacity: SharedValue; @@ -93,7 +92,6 @@ interface HeroSectionProps { navigation: any; getPlayButtonText: () => string; setBannerImage: (bannerImage: string | null) => void; - setLogoLoadError: (error: boolean) => void; groupedEpisodes?: { [seasonNumber: number]: any[] }; dynamicBackgroundColor?: string; handleBack: () => void; @@ -772,7 +770,6 @@ const HeroSection: React.FC = memo(({ metadata, bannerImage, loadingBanner, - logoLoadError, scrollY, heroHeight, heroOpacity, @@ -790,7 +787,6 @@ const HeroSection: React.FC = memo(({ navigation, getPlayButtonText, setBannerImage, - setLogoLoadError, groupedEpisodes, dynamicBackgroundColor, handleBack, @@ -942,6 +938,36 @@ const HeroSection: React.FC = memo(({ const logoUri = useMemo(() => { return metadata?.logo as string | undefined; }, [metadata?.logo]); + + // Stable logo state management - prevent flickering between logo and text + const [stableLogoUri, setStableLogoUri] = useState(null); + const [logoHasLoadedSuccessfully, setLogoHasLoadedSuccessfully] = useState(false); + + // Update stable logo URI when metadata logo changes + useEffect(() => { + if (metadata?.logo && metadata.logo !== stableLogoUri) { + setStableLogoUri(metadata.logo); + setLogoHasLoadedSuccessfully(false); // Reset for new logo + } else if (!metadata?.logo && stableLogoUri) { + // Clear logo if metadata no longer has one + setStableLogoUri(null); + setLogoHasLoadedSuccessfully(false); + } + }, [metadata?.logo, stableLogoUri]); + + // Handle logo load success - once loaded successfully, keep it stable + const handleLogoLoad = useCallback(() => { + setLogoHasLoadedSuccessfully(true); + }, []); + + // Handle logo load error - only set error if logo hasn't loaded successfully before + const handleLogoError = useCallback(() => { + if (!logoHasLoadedSuccessfully) { + // Only remove logo if it never loaded successfully + setStableLogoUri(null); + } + // If logo loaded successfully before, keep showing it even if it fails later + }, [logoHasLoadedSuccessfully]); // Performance optimization: Lazy loading setup useEffect(() => { @@ -1548,14 +1574,13 @@ const HeroSection: React.FC = memo(({ {/* Optimized Title/Logo - Show logo immediately when available */} - {logoUri && !logoLoadError ? ( + {stableLogoUri ? ( { - runOnJS(setLogoLoadError)(true); - }} + onLoad={handleLogoLoad} + onError={handleLogoError} /> ) : ( diff --git a/src/screens/MetadataScreen.tsx b/src/screens/MetadataScreen.tsx index 71b712e..b598c5b 100644 --- a/src/screens/MetadataScreen.tsx +++ b/src/screens/MetadataScreen.tsx @@ -43,7 +43,7 @@ import { RouteProp } from '@react-navigation/native'; import { NavigationProp } from '@react-navigation/native'; import { RootStackParamList } from '../navigation/AppNavigator'; import { useSettings } from '../hooks/useSettings'; -import { MetadataLoadingScreen } from '../components/loading/MetadataLoadingScreen'; +import { MetadataLoadingScreen, MetadataLoadingScreenRef } from '../components/loading/MetadataLoadingScreen'; import { useTrailer } from '../contexts/TrailerContext'; import FastImage from '@d11/react-native-fast-image'; @@ -103,6 +103,8 @@ const MetadataScreen: React.FC = () => { const [commentBottomSheetVisible, setCommentBottomSheetVisible] = useState(false); const [selectedComment, setSelectedComment] = useState(null); const [revealedSpoilers, setRevealedSpoilers] = useState>(new Set()); + const loadingScreenRef = useRef(null); + const [loadingScreenExited, setLoadingScreenExited] = useState(false); // Debug state changes @@ -157,24 +159,26 @@ const MetadataScreen: React.FC = () => { // Animate network section when data becomes available (for series) useEffect(() => { const hasNetworks = metadata?.networks && metadata.networks.length > 0; + const hasDescription = !!metadata?.description; const isSeries = Object.keys(groupedEpisodes).length > 0; - const shouldShow = shouldLoadSecondaryData && hasNetworks && isSeries; + const shouldShow = shouldLoadSecondaryData && hasNetworks && hasDescription && isSeries; if (shouldShow && networkSectionOpacity.value === 0) { networkSectionOpacity.value = withTiming(1, { duration: 400 }); } - }, [metadata?.networks, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, networkSectionOpacity]); + }, [metadata?.networks, metadata?.description, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, networkSectionOpacity]); // Animate production section when data becomes available (for movies) useEffect(() => { const hasNetworks = metadata?.networks && metadata.networks.length > 0; + const hasDescription = !!metadata?.description; const isMovie = Object.keys(groupedEpisodes).length === 0; - const shouldShow = shouldLoadSecondaryData && hasNetworks && isMovie; + const shouldShow = shouldLoadSecondaryData && hasNetworks && hasDescription && isMovie; if (shouldShow && productionSectionOpacity.value === 0) { productionSectionOpacity.value = withTiming(1, { duration: 400 }); } - }, [metadata?.networks, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, productionSectionOpacity]); + }, [metadata?.networks, metadata?.description, Object.keys(groupedEpisodes).length, shouldLoadSecondaryData, productionSectionOpacity]); // Optimized hooks with memoization and conditional loading const watchProgressData = useWatchProgress(id, Object.keys(groupedEpisodes).length > 0 ? 'series' : type as 'movie' | 'series', episodeId, episodes); @@ -471,9 +475,17 @@ const MetadataScreen: React.FC = () => { } else if (!isReady && isContentReady) { setIsContentReady(false); transitionOpacity.value = 0; + setLoadingScreenExited(false); // Reset for next load } }, [isReady, isContentReady, isScreenFocused]); + // Trigger loading screen exit animation when content is ready + useEffect(() => { + if (isReady && isContentReady && !loadingScreenExited && loadingScreenRef.current) { + loadingScreenRef.current.exit(); + } + }, [isReady, isContentReady, loadingScreenExited]); + // Optimized callback functions with reduced dependencies and haptics throttling const handleToggleLibrary = useCallback(() => { if (isScreenFocused) { @@ -802,15 +814,22 @@ const MetadataScreen: React.FC = () => { return ErrorComponent; } - // Show loading screen if metadata is not yet available - if (loading || !isContentReady) { + // Show loading screen if metadata is not yet available or exit animation hasn't completed + if (loading || !isContentReady || !loadingScreenExited) { console.log('🔍 [MetadataScreen] Showing loading screen:', { isLoading: loading, isContentReady, + loadingScreenExited, hasMetadata: !!metadata, errorMessage: metadataError }); - return 0 ? 'series' : type as 'movie' | 'series'} />; + return ( + 0 ? 'series' : type as 'movie' | 'series'} + onExitComplete={() => setLoadingScreenExited(true)} + /> + ); } return ( @@ -853,7 +872,6 @@ const MetadataScreen: React.FC = () => { metadata={metadata} bannerImage={assetData.bannerImage} loadingBanner={assetData.loadingBanner} - logoLoadError={assetData.logoLoadError} scrollY={animations.scrollY} heroHeight={animations.heroHeight} heroOpacity={animations.heroOpacity} @@ -872,7 +890,6 @@ const MetadataScreen: React.FC = () => { navigation={navigation} getPlayButtonText={watchProgressData.getPlayButtonText} setBannerImage={assetData.setBannerImage} - setLogoLoadError={assetData.setLogoLoadError} groupedEpisodes={groupedEpisodes} dynamicBackgroundColor={dynamicBackgroundColor} handleBack={handleBack} @@ -893,7 +910,7 @@ const MetadataScreen: React.FC = () => { /> {/* Production info row — shown below description and above cast for series */} - {shouldLoadSecondaryData && Object.keys(groupedEpisodes).length > 0 && metadata?.networks && metadata.networks.length > 0 && ( + {shouldLoadSecondaryData && Object.keys(groupedEpisodes).length > 0 && metadata?.networks && metadata.networks.length > 0 && metadata?.description && ( Network @@ -928,7 +945,8 @@ const MetadataScreen: React.FC = () => { {shouldLoadSecondaryData && Object.keys(groupedEpisodes).length === 0 && metadata?.networks && Array.isArray(metadata.networks) && - metadata.networks.some((n: any) => !!n?.logo) && ( + metadata.networks.some((n: any) => !!n?.logo) && + metadata?.description && ( Production