From 454bccb8f2287aa7fbda24280d3481ec99269db1 Mon Sep 17 00:00:00 2001 From: alichherawalla Date: Mon, 28 Sep 2026 18:29:21 +0530 Subject: [PATCH 001/129] build(mobile): add native video playback dependency [skip ci] --- ios/Podfile.lock | 90 +++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 11 ++++++ package.json | 1 + 3 files changed, 102 insertions(+) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 1bb3fde0a..613f017a5 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2303,6 +2303,92 @@ PODS: - react-native-tcp-socket (6.4.1): - CocoaAsyncSocket - React-Core + - react-native-video (6.19.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - react-native-video/Video (= 6.19.3) + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - react-native-video/Fabric (6.19.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - react-native-video/Video (6.19.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - react-native-video/Fabric + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-voice (3.2.4): - React-Core - react-native-zeroconf (0.14.0): @@ -3554,6 +3640,7 @@ DEPENDENCIES: - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - react-native-tcp-socket (from `../node_modules/react-native-tcp-socket`) + - react-native-video (from `../node_modules/react-native-video`) - "react-native-voice (from `../node_modules/@react-native-voice/voice`)" - react-native-zeroconf (from `../node_modules/react-native-zeroconf`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) @@ -3730,6 +3817,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/slider" react-native-tcp-socket: :path: "../node_modules/react-native-tcp-socket" + react-native-video: + :path: "../node_modules/react-native-video" react-native-voice: :path: "../node_modules/@react-native-voice/voice" react-native-zeroconf: @@ -3897,6 +3986,7 @@ SPEC CHECKSUMS: react-native-safe-area-context: c00143b4823773bba23f2f19f85663ae89ceb460 react-native-slider: 34064ca1a6864d7b263e44dd76a2d794e8d26744 react-native-tcp-socket: 7c7e53a07f122ecf00fb3626684bc0ca82c4f044 + react-native-video: 61841250a61ed594812b0bd4ce3f03549d574efc react-native-voice: 908a0eba96c8c3d643e4f98b7232c6557d0a6f9c react-native-zeroconf: eb2e5584308f20f5fc3eb0cea2ceafbbd345b48b React-NativeModulesApple: a2c3d2cbec893956a5b3e4060322db2984fff75b diff --git a/package-lock.json b/package-lock.json index 23f27de91..e6f614f2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,7 @@ "react-native-tcp-socket": "^6.4.1", "react-native-url-polyfill": "^3.0.0", "react-native-vector-icons": "^10.3.0", + "react-native-video": "^6.19.3", "react-native-vision-camera": "^4.7.3", "react-native-worklets": "^0.7.3", "react-native-zeroconf": "^0.14.0", @@ -15276,6 +15277,16 @@ "node": ">=10" } }, + "node_modules/react-native-video": { + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/react-native-video/-/react-native-video-6.19.3.tgz", + "integrity": "sha512-hI0YhEH6NdkfbFfMoZTZizEmLIm13rLlMf6KyWlGSe0+6If7/gvhapR2j/BMKBEwmlAIZjU4A6ax4Qn7yssjLQ==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-vision-camera": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/react-native-vision-camera/-/react-native-vision-camera-4.7.3.tgz", diff --git a/package.json b/package.json index 864b69f8e..60a459b4d 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "react-native-tcp-socket": "^6.4.1", "react-native-url-polyfill": "^3.0.0", "react-native-vector-icons": "^10.3.0", + "react-native-video": "^6.19.3", "react-native-vision-camera": "^4.7.3", "react-native-worklets": "^0.7.3", "react-native-zeroconf": "^0.14.0", From 50c50468da6ecb35cf20f0b1da08f8140f272c3f Mon Sep 17 00:00:00 2001 From: alichherawalla Date: Mon, 28 Sep 2026 18:29:21 +0530 Subject: [PATCH 002/129] feat(media): store synced videos and update Pro integration [skip ci] --- pro | 2 +- src/stores/appStore.ts | 14 ++++++++++++++ src/types/index.ts | 22 +++++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/pro b/pro index 035e38bd2..7233bbfbb 160000 --- a/pro +++ b/pro @@ -1 +1 @@ -Subproject commit 035e38bd2345569d82377809cd8a582701592cfd +Subproject commit 7233bbfbb64ff058e8cec2e412ed7115a5672044 diff --git a/src/stores/appStore.ts b/src/stores/appStore.ts index 053637864..e675e466b 100644 --- a/src/stores/appStore.ts +++ b/src/stores/appStore.ts @@ -24,6 +24,7 @@ import { INFERENCE_BACKENDS, LiteRTBackend, GeneratedImage, + GeneratedVideo, } from '../types'; import { emitChangedModelSettings, @@ -195,6 +196,10 @@ export interface AppState extends ProAccessSlice { setImageGenerationStatus: (status: string | null) => void; setImagePreviewPath: (path: string | null) => void; generatedImages: GeneratedImage[]; + generatedVideos: GeneratedVideo[]; + addGeneratedVideo: (video: GeneratedVideo) => void; + removeGeneratedVideo: (videoId: string) => void; + removeVideosByConversationId: (conversationId: string) => string[]; addGeneratedImage: (image: GeneratedImage) => void; removeGeneratedImage: (imageId: string) => void; removeImagesByConversationId: (conversationId: string) => string[]; @@ -417,6 +422,14 @@ export const useAppStore = create()( setImagePreviewPath: path => set({ imagePreviewPath: path }), // Gallery generatedImages: [], + generatedVideos: [], + addGeneratedVideo: video => set(state => ({ generatedVideos: [video, ...state.generatedVideos] })), + removeGeneratedVideo: videoId => set(state => ({ generatedVideos: state.generatedVideos.filter(video => video.id !== videoId) })), + removeVideosByConversationId: conversationId => { + const videos = get().generatedVideos.filter(video => video.conversationId === conversationId); + set(state => ({ generatedVideos: state.generatedVideos.filter(video => video.conversationId !== conversationId) })); + return videos.map(video => video.id); + }, addGeneratedImage: image => set(state => ({ generatedImages: [image, ...state.generatedImages], @@ -494,6 +507,7 @@ function persistedAppState(state: AppState) { modelSettingProvenance: state.modelSettingProvenance, activeImageModelId: state.activeImageModelId, generatedImages: state.generatedImages, + generatedVideos: state.generatedVideos, warmedImageModels: state.warmedImageModels, textGenerationCount: state.textGenerationCount, imageGenerationCount: state.imageGenerationCount, diff --git a/src/types/index.ts b/src/types/index.ts index aca2cfd4b..caba8870a 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -195,7 +195,7 @@ export interface ModelRecommendation { // Media attachment types export interface MediaAttachment { id: string; - type: 'image' | 'document' | 'audio'; + type: 'image' | 'document' | 'audio' | 'video'; uri: string; mimeType?: string; width?: number; @@ -405,6 +405,26 @@ export const INFERENCE_BACKENDS = { /** 'auto' = smart detect, 'force' = always generate image, 'disabled' = never */ export type ImageModeState = 'auto' | 'force' | 'disabled'; +export interface GeneratedVideo { + id: string; + provenance?: RecordProvenance; + prompt: string; + negativePrompt?: string; + videoPath: string; + fileName?: string; + width: number; + height: number; + fps: number; + frames: number; + durationSeconds: number; + steps: number; + guidance: number; + seed: number; + modelId: string; + createdAt: string; + conversationId?: string; +} + export interface GeneratedImage { id: string; /** Immutable device attribution for portable Sync records. */ From d42bbb109dd29259ffb0490292e41b1c6391ad2c Mon Sep 17 00:00:00 2001 From: alichherawalla Date: Mon, 28 Sep 2026 18:29:21 +0530 Subject: [PATCH 003/129] feat(gallery): play save and delete videos on mobile [skip ci] --- .../components/MessageAttachments.tsx | 3 + src/screens/ChatScreen/ChatModalSection.tsx | 13 +++-- .../ChatScreen/useChatGenerationActions.ts | 5 ++ src/screens/GalleryScreen/index.tsx | 57 +++++++++++++++++-- src/screens/HomeScreen/hooks/useHomeScreen.ts | 2 + src/screens/HomeScreen/index.tsx | 6 +- 6 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/components/ChatMessage/components/MessageAttachments.tsx b/src/components/ChatMessage/components/MessageAttachments.tsx index 619639f62..048b05f0e 100644 --- a/src/components/ChatMessage/components/MessageAttachments.tsx +++ b/src/components/ChatMessage/components/MessageAttachments.tsx @@ -12,6 +12,7 @@ import Animated, { withTiming, } from 'react-native-reanimated'; import Icon from 'react-native-vector-icons/Feather'; +import Video from 'react-native-video'; // Imported directly, not through the barrel: a component that reaches its sibling via the index // resolves undefined at render time. import { LoadingDots } from '../../LoadingDots'; @@ -197,6 +198,8 @@ export function MessageAttachments({ styles={styles} colors={colors} /> + ) : attachment.type === 'video' ? ( +