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