@wereform/pkgm-video 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Thumbnail.js +1 -1
- package/dist/components/VideoPlayer.js +1 -1
- package/dist/layout/VideoCardHorizontalLayout.js +1 -1
- package/dist/layout/VideoCardLayout.js +1 -1
- package/dist/layout/VideoViewLayout.js +1 -1
- package/package.json +37 -36
- package/src/components/Thumbnail.jsx +15 -0
- package/src/components/VideoPlayer.jsx +29 -17
- package/src/layout/VideoCardHorizontalLayout.jsx +19 -0
- package/src/layout/VideoCardLayout.jsx +20 -0
- package/src/layout/VideoViewLayout.jsx +32 -9
- package/src/styles/VideoCardLayoutStyles.js +10 -0
- package/src/styles/VideoPlayerStyles.js +6 -3
- package/src/styles/globalStyles.js +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:true});exports.Thumbnail=Thumbnail;var _reactNative=require("react-native");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:true});exports.Thumbnail=Thumbnail;var _reactNative=require("react-native");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\Mobile\\packages\\begenone-pkgm-video\\src\\components\\Thumbnail.jsx";function Thumbnail(_ref){var thumbnailURL=_ref.thumbnailURL,thumbHeight=_ref.thumbHeight;return(0,_jsxRuntime.jsx)(_reactNative.View,{style:{width:"auto"},children:(0,_jsxRuntime.jsx)(_reactNative.Image,{source:{uri:thumbnailURL||"https://begenone-images.s3.us-east-1.amazonaws.com/let+Me+Love+you.jpg"},style:{width:"100%",height:thumbHeight,aspectRatio:16/9,borderRadius:5}})});}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoPlayer=VideoPlayer;var _expo=require("expo");var _expoVideo=require("expo-video");var _reactNative=require("react-native");var _VideoPlayerStyles=require("../styles/VideoPlayerStyles");var _react=require("react");var _native=require("@react-navigation/native");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoPlayer=VideoPlayer;var _expo=require("expo");var _expoVideo=require("expo-video");var _reactNative=require("react-native");var _VideoPlayerStyles=require("../styles/VideoPlayerStyles");var _react=require("react");var _native=require("@react-navigation/native");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\Mobile\\packages\\begenone-pkgm-video\\src\\components\\VideoPlayer.jsx";function VideoPlayer(_ref){var videoSource=_ref.videoSource;var _useWindowDimensions=(0,_reactNative.useWindowDimensions)(),width=_useWindowDimensions.width;var isFocused=(0,_native.useIsFocused)();var playerRef=(0,_react.useRef)(null);var player=(0,_expoVideo.useVideoPlayer)(videoSource,function(p){p.loop=true;p.play();playerRef.current=p;});(0,_react.useEffect)(function(){if(!player)return;if(isFocused)player.play();else player.pause();},[isFocused,player]);(0,_expo.useEvent)(player,"playingChange");return(0,_jsxRuntime.jsx)(_reactNative.View,{style:_VideoPlayerStyles.VideoPlayerStyles.contentContainer,children:(0,_jsxRuntime.jsx)(_expoVideo.VideoView,{style:[_VideoPlayerStyles.VideoPlayerStyles.video,{width:width,height:width*(9/16)}],player:player,allowsPictureInPicture:true})});}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoCardHorizontalLayout=VideoCardHorizontalLayout;var _reactNative=require("react-native");var _Thumbnail=require("../components/Thumbnail");var _pkgmShared=require("@wereform/pkgm-shared");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoCardHorizontalLayout=VideoCardHorizontalLayout;var _reactNative=require("react-native");var _Thumbnail=require("../components/Thumbnail");var _pkgmShared=require("@wereform/pkgm-shared");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\Mobile\\packages\\begenone-pkgm-video\\src\\layout\\VideoCardHorizontalLayout.jsx";function VideoCardHorizontalLayout(_ref){var eyeIcon=_ref.eyeIcon,timeAgo=_ref.timeAgo,viewsText=_ref.viewsText,titleText=_ref.titleText,contentThumbUrl=_ref.contentThumbUrl,navigateToVideo=_ref.navigateToVideo;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{onPress:navigateToVideo,style:{flexDirection:"row",padding:8},children:[(0,_jsxRuntime.jsx)(_Thumbnail.Thumbnail,{thumbHeight:90,thumbnailURL:contentThumbUrl}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flex:1,marginLeft:12},children:[(0,_jsxRuntime.jsx)(_pkgmShared.CustomizedTitle,{title:titleText||"This is a dummy text title for the video",fontSize:18,textColor:"white",style:{width:"100%"}}),(0,_jsxRuntime.jsx)(_pkgmShared.DateViews,{eyeIcon:eyeIcon,timeAgo:timeAgo,viewsText:viewsText,containerStyles:{flexDirection:"column",justifyContent:"start",height:40},dateContainerStyles:{paddingBottom:4},dateTextStyles:{fontSize:12},viewsTextStyles:{fontSize:12}})]})]});}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoCardLayout=void 0;var _reactNative=require("react-native");var _VideoCardLayoutStyles=require("../styles/VideoCardLayoutStyles");var _pkgmShared=require("@wereform/pkgm-shared");var _jsxRuntime=require("react/jsx-runtime");var _this=this,_jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoCardLayout=void 0;var _reactNative=require("react-native");var _VideoCardLayoutStyles=require("../styles/VideoCardLayoutStyles");var _pkgmShared=require("@wereform/pkgm-shared");var _jsxRuntime=require("react/jsx-runtime");var _this=this,_jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\Mobile\\packages\\begenone-pkgm-video\\src\\layout\\VideoCardLayout.jsx";var VideoCardLayout=exports.VideoCardLayout=function VideoCardLayout(_ref){var timeAgo=_ref.timeAgo,viewsText=_ref.viewsText,titleText=_ref.titleText,userNameText=_ref.userNameText,contentThumbUrl=_ref.contentThumbUrl,channelLogo=_ref.channelLogo,containerStyles=_ref.containerStyles,dateViewsContainerStyle=_ref.dateViewsContainerStyle,userImageStyles=_ref.userImageStyles,titleNameContainerStyles=_ref.titleNameContainerStyles,userNameTextStyles=_ref.userNameTextStyles,titleTextStyles=_ref.titleTextStyles,thumbnailImageStyles=_ref.thumbnailImageStyles,customMetaDataStyles=_ref.customMetaDataStyles,navigateToVideo=_ref.navigateToVideo;console.log("Checking for Conent Thumbnail URL: ",contentThumbUrl);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[_VideoCardLayoutStyles.VideoCardLayoutStyles.container,containerStyles],onPress:navigateToVideo,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:_VideoCardLayoutStyles.VideoCardLayoutStyles.imageWrapper,children:(0,_jsxRuntime.jsx)(_reactNative.Image,{source:{uri:contentThumbUrl||"https://begenone-images.s3.us-east-1.amazonaws.com/let+Me+Love+you.jpg"},style:[_VideoCardLayoutStyles.VideoCardLayoutStyles.image,thumbnailImageStyles]})}),(0,_jsxRuntime.jsx)(_pkgmShared.DateViews,{timeAgo:timeAgo,viewsText:viewsText,containerStyles:dateViewsContainerStyle}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[_VideoCardLayoutStyles.VideoCardLayoutStyles.metaData,customMetaDataStyles],children:[(0,_jsxRuntime.jsx)(_reactNative.Image,{source:{uri:channelLogo||"https://begenone-images.s3.us-east-1.amazonaws.com/default-user-photo.jpg"},style:[_VideoCardLayoutStyles.VideoCardLayoutStyles.userImage,userImageStyles]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[_VideoCardLayoutStyles.VideoCardLayoutStyles.titleNameContainer,titleNameContainerStyles],children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[_VideoCardLayoutStyles.VideoCardLayoutStyles.titleText,titleTextStyles],numberOfLines:2,children:titleText||"This is a Default Title Text in case of nothing being passed in."}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[_VideoCardLayoutStyles.VideoCardLayoutStyles.userNameText,userNameTextStyles],children:userNameText||"Default Username"})]})]})]});};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoViewLayout=VideoViewLayout;var _reactNative=require("react-native");var _VideoPlayer=require("../components/VideoPlayer");var _pkgmShared=require("@wereform/pkgm-shared");var _vectorIcons=require("@expo/vector-icons");var _VideoCardLayout=require("./VideoCardLayout");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\
|
|
1
|
+
Object.defineProperty(exports,"__esModule",{value:true});exports.VideoViewLayout=VideoViewLayout;var _reactNative=require("react-native");var _VideoPlayer=require("../components/VideoPlayer");var _pkgmShared=require("@wereform/pkgm-shared");var _vectorIcons=require("@expo/vector-icons");var _VideoCardLayout=require("./VideoCardLayout");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="F:\\WeReform Corporation\\Products\\BEGENONE\\App\\Mobile\\packages\\begenone-pkgm-video\\src\\layout\\VideoViewLayout.jsx";function VideoViewLayout(_ref){var _this=this;var videoSource=_ref.videoSource,CustomizedTitleText=_ref.CustomizedTitleText,MenuChannelMetaTimeAgo=_ref.MenuChannelMetaTimeAgo,MenuChannelMetaViews=_ref.MenuChannelMetaViews,MenuChannelMetaUserName=_ref.MenuChannelMetaUserName,MenuChannelMetaSubCount=_ref.MenuChannelMetaSubCount,MenuChannelMetaChannelLogo=_ref.MenuChannelMetaChannelLogo,suggestedVideos=_ref.suggestedVideos;console.log("SUGGESTED VIDEOS FROM VIDEO VIEWS LAYOUT: =>\n"+JSON.stringify(suggestedVideos[0].videos,null,2));return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{children:(0,_jsxRuntime.jsx)(_VideoPlayer.VideoPlayer,{videoSource:videoSource},videoSource)}),(0,_jsxRuntime.jsx)(_pkgmShared.CustomizedTitle,{title:CustomizedTitleText,fontSize:22,fontFamily:"Inter",textColor:"white",style:{paddingTop:18,paddingLeft:22,paddingRight:22,paddingBottom:18,alignSelf:"start"},textStyle:{lineHeight:28}}),(0,_jsxRuntime.jsx)(_pkgmShared.MenuInteraction,{likeIcon:(0,_jsxRuntime.jsx)(_vectorIcons.Ionicons,{name:"thumbs-up-outline",size:24,color:"white"}),dislikeIcon:(0,_jsxRuntime.jsx)(_vectorIcons.Ionicons,{name:"thumbs-down-outline",size:24,color:"white"}),shareIcon:(0,_jsxRuntime.jsx)(_vectorIcons.Ionicons,{name:"arrow-redo-outline",size:24,color:"white"}),containerStyles:{marginLeft:12}}),(0,_jsxRuntime.jsx)(_pkgmShared.MenuChannelMeta,{calendarIcon:(0,_jsxRuntime.jsx)(_vectorIcons.Ionicons,{name:"calendar-clear-outline",size:18,color:"white"}),timeAgo:MenuChannelMetaTimeAgo,eyeIcon:(0,_jsxRuntime.jsx)(_vectorIcons.Ionicons,{name:"eye-outline",size:18,color:"white"}),viewsText:MenuChannelMetaViews,userName:MenuChannelMetaUserName,subscribersCount:MenuChannelMetaSubCount,channelLogo:MenuChannelMetaChannelLogo,containerStyles:{marginTop:12}}),suggestedVideos[0].videos.map(function(video){var _video$channel;return(0,_jsxRuntime.jsx)(_reactNative.View,{style:{marginTop:24},children:(0,_jsxRuntime.jsx)(_VideoCardLayout.VideoCardLayout,{titleText:video.title,contentThumbUrl:video.thumbUrl,userNameText:((_video$channel=video.channel)==null?void 0:_video$channel.name)||"Unknown",channelLogo:video.channelLogo,timeAgo:video.videoTimeAgo,viewsText:String(video.views),calendarIcon:(0,_jsxRuntime.jsx)(_vectorIcons.Ionicons,{name:"calendar-clear-outline",size:18,color:"white"}),eyeIcon:(0,_jsxRuntime.jsx)(_vectorIcons.Ionicons,{name:"eye-outline",size:18,color:"white"})},video._id)},video._id);})]});}
|
package/package.json
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@wereform/pkgm-video",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"source": "
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"react-native": "
|
|
7
|
-
"files": [
|
|
8
|
-
"dist",
|
|
9
|
-
"src",
|
|
10
|
-
"README.md"
|
|
11
|
-
],
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@wereform/pkgm-video",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"source": "dist/index.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"react-native": "dist/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"src",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "babel src --out-dir dist --extensions .js,.jsx",
|
|
14
|
+
"prepublishOnly": "pnpm run build"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@expo/vector-icons": "*",
|
|
21
|
+
"expo": "*",
|
|
22
|
+
"expo-video": "*",
|
|
23
|
+
"react": "*",
|
|
24
|
+
"react-native": "*"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@wereform/pkgm-api": "^1.0.10",
|
|
28
|
+
"@wereform/pkgm-shared": "^1.0.4",
|
|
29
|
+
"@expo/vector-icons": "^15.0.3"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@babel/cli": "^7.28.3",
|
|
33
|
+
"@babel/core": "^7.28.5",
|
|
34
|
+
"@babel/preset-env": "^7.28.5",
|
|
35
|
+
"metro-react-native-babel-preset": "^0.77.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { Image, View } from "react-native";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Thumbnail
|
|
5
|
+
*
|
|
6
|
+
* Lightweight thumbnail renderer for video and content previews.
|
|
7
|
+
*
|
|
8
|
+
* Props:
|
|
9
|
+
* - thumbnailURL: string URL of the thumbnail image
|
|
10
|
+
* - thumbHeight: numeric height for the thumbnail container
|
|
11
|
+
*
|
|
12
|
+
* Behavior:
|
|
13
|
+
* - Falls back to a default image when no URL is provided
|
|
14
|
+
* - Maintains a fixed 16:9 aspect ratio
|
|
15
|
+
* - Intended for list cards and compact layouts
|
|
16
|
+
*/
|
|
17
|
+
|
|
3
18
|
export function Thumbnail({ thumbnailURL, thumbHeight }) {
|
|
4
19
|
return (
|
|
5
20
|
<View style={{ width: "auto" }}>
|
|
@@ -2,11 +2,32 @@ import { useEvent } from "expo";
|
|
|
2
2
|
import { useVideoPlayer, VideoView } from "expo-video";
|
|
3
3
|
import { View, useWindowDimensions } from "react-native";
|
|
4
4
|
import { VideoPlayerStyles } from "../styles/VideoPlayerStyles";
|
|
5
|
-
import { useCallback, useRef } from "react";
|
|
6
|
-
import { useFocusEffect } from "@react-navigation/native";
|
|
5
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
6
|
+
import { useIsFocused, useFocusEffect } from "@react-navigation/native";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* VideoPlayer
|
|
10
|
+
*
|
|
11
|
+
* Mobile-optimized video playback component using expo-video.
|
|
12
|
+
*
|
|
13
|
+
* Props:
|
|
14
|
+
* - videoSource: video URI or source object compatible with useVideoPlayer
|
|
15
|
+
*
|
|
16
|
+
* Behavior:
|
|
17
|
+
* - Auto-plays and loops video on mount
|
|
18
|
+
* - Resumes playback when screen gains focus
|
|
19
|
+
* - Pauses playback when screen loses focus
|
|
20
|
+
* - Maintains responsive 16:9 aspect ratio based on device width
|
|
21
|
+
*
|
|
22
|
+
* Notes:
|
|
23
|
+
* - Player instance is stored via ref for lifecycle control
|
|
24
|
+
* - Picture-in-picture is enabled
|
|
25
|
+
* - Designed for full video view screens
|
|
26
|
+
*/
|
|
7
27
|
|
|
8
28
|
export function VideoPlayer({ videoSource }) {
|
|
9
29
|
const { width } = useWindowDimensions(); // Dynamically get device width
|
|
30
|
+
const isFocused = useIsFocused();
|
|
10
31
|
|
|
11
32
|
const playerRef = useRef(null);
|
|
12
33
|
|
|
@@ -16,21 +37,12 @@ export function VideoPlayer({ videoSource }) {
|
|
|
16
37
|
playerRef.current = p; // store instance
|
|
17
38
|
});
|
|
18
39
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return () => {
|
|
26
|
-
if (playerRef.current) {
|
|
27
|
-
playerRef.current.pause();
|
|
28
|
-
// Optional: fully unload the video
|
|
29
|
-
// playerRef.current.unloadAsync?.();
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}, [])
|
|
33
|
-
);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!player) return;
|
|
42
|
+
|
|
43
|
+
if (isFocused) player.play();
|
|
44
|
+
else player.pause();
|
|
45
|
+
}, [isFocused, player]);
|
|
34
46
|
|
|
35
47
|
useEvent(player, "playingChange");
|
|
36
48
|
|
|
@@ -2,6 +2,25 @@ import { Text, TouchableOpacity, View } from "react-native";
|
|
|
2
2
|
import { Thumbnail } from "../components/Thumbnail";
|
|
3
3
|
import { CustomizedTitle, DateViews } from "@wereform/pkgm-shared";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* VideoCardHorizontalLayout
|
|
7
|
+
*
|
|
8
|
+
* Compact horizontal video card used in lists or history views.
|
|
9
|
+
* Displays thumbnail, title, and basic metadata (date + views).
|
|
10
|
+
*
|
|
11
|
+
* Props:
|
|
12
|
+
* - eyeIcon: ReactNode for views icon
|
|
13
|
+
* - timeAgo: string representing publish time
|
|
14
|
+
* - viewsText: string/number of views
|
|
15
|
+
* - titleText: video title
|
|
16
|
+
* - contentThumbUrl: thumbnail image URL
|
|
17
|
+
* - navigateToVideo: navigation handler on press
|
|
18
|
+
*
|
|
19
|
+
* Notes:
|
|
20
|
+
* - Entire card is pressable
|
|
21
|
+
* - Uses shared UI components for consistency
|
|
22
|
+
*/
|
|
23
|
+
|
|
5
24
|
export function VideoCardHorizontalLayout({
|
|
6
25
|
eyeIcon,
|
|
7
26
|
timeAgo,
|
|
@@ -2,6 +2,25 @@ import { Image, Text, TouchableOpacity, View } from "react-native";
|
|
|
2
2
|
import { VideoCardLayoutStyles } from "../styles/VideoCardLayoutStyles";
|
|
3
3
|
import { DateViews } from "@wereform/pkgm-shared";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* VideoCardHorizontalLayout
|
|
7
|
+
*
|
|
8
|
+
* Compact horizontal video card used in lists or history views.
|
|
9
|
+
* Displays thumbnail, title, and basic metadata (date + views).
|
|
10
|
+
*
|
|
11
|
+
* Props:
|
|
12
|
+
* - eyeIcon: ReactNode for views icon
|
|
13
|
+
* - timeAgo: string representing publish time
|
|
14
|
+
* - viewsText: string/number of views
|
|
15
|
+
* - titleText: video title
|
|
16
|
+
* - contentThumbUrl: thumbnail image URL
|
|
17
|
+
* - navigateToVideo: navigation handler on press
|
|
18
|
+
*
|
|
19
|
+
* Notes:
|
|
20
|
+
* - Entire card is pressable
|
|
21
|
+
* - Uses shared UI components for consistency
|
|
22
|
+
*/
|
|
23
|
+
|
|
5
24
|
export const VideoCardLayout = ({
|
|
6
25
|
timeAgo,
|
|
7
26
|
viewsText,
|
|
@@ -19,6 +38,7 @@ export const VideoCardLayout = ({
|
|
|
19
38
|
customMetaDataStyles,
|
|
20
39
|
navigateToVideo,
|
|
21
40
|
}) => {
|
|
41
|
+
console.log("Checking for Conent Thumbnail URL: ", contentThumbUrl);
|
|
22
42
|
return (
|
|
23
43
|
<View
|
|
24
44
|
style={[VideoCardLayoutStyles.container, containerStyles]}
|
|
@@ -8,6 +8,29 @@ import {
|
|
|
8
8
|
import { Ionicons } from "@expo/vector-icons";
|
|
9
9
|
import { VideoCardLayout } from "./VideoCardLayout";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* VideoViewLayout
|
|
13
|
+
*
|
|
14
|
+
* Full video viewing screen layout.
|
|
15
|
+
* Renders video player, title, interactions, channel metadata,
|
|
16
|
+
* and a list of suggested videos.
|
|
17
|
+
*
|
|
18
|
+
* Props:
|
|
19
|
+
* - videoSource: video stream/source
|
|
20
|
+
* - CustomizedTitleText: main video title
|
|
21
|
+
* - MenuChannelMetaTimeAgo: publish time
|
|
22
|
+
* - MenuChannelMetaViews: view count
|
|
23
|
+
* - MenuChannelMetaUserName: channel name
|
|
24
|
+
* - MenuChannelMetaSubCount: subscriber count
|
|
25
|
+
* - MenuChannelMetaChannelLogo: channel avatar
|
|
26
|
+
* - suggestedVideos: array of related video objects
|
|
27
|
+
*
|
|
28
|
+
* Notes:
|
|
29
|
+
* - Suggested videos are rendered using VideoCardLayout
|
|
30
|
+
* - Layout is scrollable and mobile-optimized
|
|
31
|
+
* - Interaction icons are visual; behavior is wired elsewhere
|
|
32
|
+
*/
|
|
33
|
+
|
|
11
34
|
export function VideoViewLayout({
|
|
12
35
|
videoSource,
|
|
13
36
|
CustomizedTitleText,
|
|
@@ -20,12 +43,12 @@ export function VideoViewLayout({
|
|
|
20
43
|
}) {
|
|
21
44
|
console.log(
|
|
22
45
|
"SUGGESTED VIDEOS FROM VIDEO VIEWS LAYOUT: =>\n" +
|
|
23
|
-
JSON.stringify(suggestedVideos[0].videos, null, 2)
|
|
46
|
+
JSON.stringify(suggestedVideos[0].videos, null, 2),
|
|
24
47
|
);
|
|
25
48
|
return (
|
|
26
49
|
<ScrollView>
|
|
27
50
|
<View>
|
|
28
|
-
<VideoPlayer videoSource={videoSource} />
|
|
51
|
+
<VideoPlayer key={videoSource} videoSource={videoSource} />
|
|
29
52
|
</View>
|
|
30
53
|
<CustomizedTitle
|
|
31
54
|
title={CustomizedTitleText}
|
|
@@ -52,13 +75,13 @@ export function VideoViewLayout({
|
|
|
52
75
|
shareIcon={
|
|
53
76
|
<Ionicons name="arrow-redo-outline" size={24} color="white" />
|
|
54
77
|
}
|
|
55
|
-
commentIcon={
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
78
|
+
// commentIcon={
|
|
79
|
+
// <Ionicons
|
|
80
|
+
// name="chatbubble-ellipses-outline"
|
|
81
|
+
// size={24}
|
|
82
|
+
// color="white"
|
|
83
|
+
// />
|
|
84
|
+
// }
|
|
62
85
|
containerStyles={{
|
|
63
86
|
marginLeft: 12,
|
|
64
87
|
}}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { globalStyles } from "./globalStyles";
|
|
2
2
|
|
|
3
|
+
/* Video card layout styles for feed and listings */
|
|
3
4
|
export const VideoCardLayoutStyles = {
|
|
4
5
|
container: {
|
|
6
|
+
// Video card outer container
|
|
5
7
|
width: "auto",
|
|
6
8
|
flexDirection: "column",
|
|
7
9
|
marginRight: 12,
|
|
8
10
|
marginLeft: 12,
|
|
9
11
|
marginBottom: 40,
|
|
10
12
|
},
|
|
13
|
+
|
|
11
14
|
imageWrapper: {
|
|
15
|
+
// Video thumbnail wrapper
|
|
12
16
|
width: "100%",
|
|
13
17
|
},
|
|
14
18
|
|
|
15
19
|
image: {
|
|
20
|
+
// Video thumbnail image
|
|
16
21
|
width: "100%",
|
|
17
22
|
resizeMode: "contain",
|
|
18
23
|
aspectRatio: 16 / 9,
|
|
@@ -20,6 +25,7 @@ export const VideoCardLayoutStyles = {
|
|
|
20
25
|
},
|
|
21
26
|
|
|
22
27
|
metaData: {
|
|
28
|
+
// Metadata row below thumbnail
|
|
23
29
|
flexDirection: "row",
|
|
24
30
|
marginTop: 16,
|
|
25
31
|
paddingLeft: 8,
|
|
@@ -27,12 +33,14 @@ export const VideoCardLayoutStyles = {
|
|
|
27
33
|
},
|
|
28
34
|
|
|
29
35
|
userImage: {
|
|
36
|
+
// Channel avatar image
|
|
30
37
|
width: 40,
|
|
31
38
|
height: 40,
|
|
32
39
|
borderRadius: globalStyles.borders.borderPrimary50,
|
|
33
40
|
},
|
|
34
41
|
|
|
35
42
|
titleNameContainer: {
|
|
43
|
+
// Video title and author container
|
|
36
44
|
width: "100%",
|
|
37
45
|
flexDirection: "column",
|
|
38
46
|
paddingLeft: 16,
|
|
@@ -40,6 +48,7 @@ export const VideoCardLayoutStyles = {
|
|
|
40
48
|
},
|
|
41
49
|
|
|
42
50
|
titleText: {
|
|
51
|
+
// Video title text
|
|
43
52
|
fontSize: 22,
|
|
44
53
|
paddingBottom: 12,
|
|
45
54
|
lineHeight: 30,
|
|
@@ -48,6 +57,7 @@ export const VideoCardLayoutStyles = {
|
|
|
48
57
|
},
|
|
49
58
|
|
|
50
59
|
userNameText: {
|
|
60
|
+
// Channel name text
|
|
51
61
|
color: globalStyles.colors.colorPrimary400,
|
|
52
62
|
fontWeight: "bold",
|
|
53
63
|
},
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
2
|
|
|
3
|
+
/* Video player layout and control styles */
|
|
3
4
|
export const VideoPlayerStyles = StyleSheet.create({
|
|
4
5
|
contentContainer: {
|
|
5
|
-
//
|
|
6
|
+
// Player content wrapper
|
|
6
7
|
alignItems: "center",
|
|
7
8
|
justifyContent: "flex-start",
|
|
8
|
-
// backgroundColor: "#000",
|
|
9
9
|
},
|
|
10
|
+
|
|
10
11
|
video: {
|
|
11
|
-
//
|
|
12
|
+
// Video element styling
|
|
12
13
|
},
|
|
14
|
+
|
|
13
15
|
controlsContainer: {
|
|
16
|
+
// Playback controls container
|
|
14
17
|
padding: 10,
|
|
15
18
|
},
|
|
16
19
|
});
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
2
|
|
|
3
|
+
/* Global design tokens for colors and border radii */
|
|
3
4
|
export const globalStyles = StyleSheet.create({
|
|
4
5
|
colors: {
|
|
6
|
+
// Primary background shades
|
|
5
7
|
colorPrimary50: "rgba(21, 21, 21, .7)",
|
|
6
8
|
colorPrimary100: "#151515",
|
|
7
|
-
|
|
8
9
|
colorPrimary200: "#252525",
|
|
9
|
-
|
|
10
10
|
colorPrimary300: "#3C3C3C",
|
|
11
11
|
colorPrimary350: "rgba(60,60,60,.2)",
|
|
12
|
-
|
|
13
12
|
colorPrimary400: "#7F7F7F",
|
|
14
|
-
|
|
15
13
|
colorPrimary500: "#D3D3D3",
|
|
16
14
|
|
|
15
|
+
// Accent and action colors
|
|
17
16
|
colorPrimary600: "#ff6600ff",
|
|
18
|
-
|
|
19
17
|
colorPrimary700: "#FF8800",
|
|
20
18
|
},
|
|
19
|
+
|
|
21
20
|
borders: {
|
|
21
|
+
// Standard border radius scale
|
|
22
22
|
borderPrimary50: 8,
|
|
23
23
|
borderPrimary100: 10,
|
|
24
24
|
borderPrimary200: 12,
|