From fcf14a87102bee031b7bf29b3e7ba7233bade6a8 Mon Sep 17 00:00:00 2001 From: SujithThirumalaisamy Date: Sun, 1 Dec 2024 18:41:24 +0530 Subject: [PATCH 1/4] Fixed appx video with appx videoJson --- .../migration.sql | 2 ++ prisma/schema.prisma | 1 + src/actions/user/index.ts | 4 ---- src/app/api/admin/content/route.ts | 2 +- src/components/FolderView.tsx | 4 ++-- src/components/VideoPlayer2.tsx | 12 ++++------ src/components/VideoPlayerSegment.tsx | 5 +++- src/components/admin/AddContent.tsx | 9 ++++--- src/components/admin/ContentRenderer.tsx | 14 ++++++++--- .../admin/ContentRendererClient.tsx | 7 ++++-- src/db/course.ts | 14 +++++------ src/lib/auth.ts | 2 +- src/utiles/appx.ts | 24 +++++++++++++++++++ 13 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 prisma/migrations/20241130091016_added_appx_video_id_mapping_with_appx_video_json/migration.sql diff --git a/prisma/migrations/20241130091016_added_appx_video_id_mapping_with_appx_video_json/migration.sql b/prisma/migrations/20241130091016_added_appx_video_id_mapping_with_appx_video_json/migration.sql new file mode 100644 index 000000000..cabfaf250 --- /dev/null +++ b/prisma/migrations/20241130091016_added_appx_video_id_mapping_with_appx_video_json/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "VideoMetadata" ADD COLUMN "appxVideoJSON" JSONB; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 90d2d78a1..ca8e4431c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -88,6 +88,7 @@ model VideoMetadata { id Int @id @default(autoincrement()) contentId Int appxVideoId String? + appxVideoJSON Json? video_1080p_mp4_1 String? // Link to 1080p mp4 quality video variant 1 video_1080p_mp4_2 String? // Link to 1080p mp4 quality video variant 2 video_1080p_mp4_3 String? // Link to 1080p mp4 quality video variant 3 diff --git a/src/actions/user/index.ts b/src/actions/user/index.ts index 73680e434..7f6f960a7 100644 --- a/src/actions/user/index.ts +++ b/src/actions/user/index.ts @@ -70,13 +70,9 @@ export const GetAppxVideoPlayerUrl = async (courseId: string, videoId: string): 'User-Id': appxUserId, }, }; - console.log(config); - console.log(url); const res = await axios.request(config); const { video_player_token, video_player_url } = res.data.data; - console.log(video_player_token); - console.log(video_player_url); const full_video_url = `${video_player_url}${video_player_token}&watermark=${name}%0A${email}`; return full_video_url; }; diff --git a/src/app/api/admin/content/route.ts b/src/app/api/admin/content/route.ts index acd30502b..b24636cc7 100644 --- a/src/app/api/admin/content/route.ts +++ b/src/app/api/admin/content/route.ts @@ -113,7 +113,7 @@ export const POST = async (req: NextRequest) => { } else if (type === 'appx') { await db.videoMetadata.create({ data: { - appxVideoId: metadata.appxVideoId, + appxVideoJSON: metadata.appxVideoJSON, contentId: content.id, }, }); diff --git a/src/components/FolderView.tsx b/src/components/FolderView.tsx index c9f24c430..61839d191 100644 --- a/src/components/FolderView.tsx +++ b/src/components/FolderView.tsx @@ -45,8 +45,8 @@ export const FolderView = ({ {courseContent.map((content) => { const videoProgressPercent = content.type === 'video' && - content.videoFullDuration && - content.duration + content.videoFullDuration && + content.duration ? (content.duration / content.videoFullDuration) * 100 : 0; return ( diff --git a/src/components/VideoPlayer2.tsx b/src/components/VideoPlayer2.tsx index 7257173ab..6cbdd4684 100644 --- a/src/components/VideoPlayer2.tsx +++ b/src/components/VideoPlayer2.tsx @@ -26,6 +26,7 @@ interface VideoPlayerProps { subtitles?: string; contentId: number; appxVideoId?: string; + appxCourseId?: string; onVideoEnd: () => void; } @@ -40,18 +41,13 @@ export const VideoPlayer: FunctionComponent = ({ subtitles, onVideoEnd, appxVideoId, + appxCourseId }) => { const videoRef = useRef(null); const playerRef = useRef(null); const [player, setPlayer] = useState(null); const searchParams = useSearchParams(); const vidUrl = options.sources[0].src; - let href: string | null = null; - let courseId: string | null = null; - if (typeof window !== 'undefined') { - href = window.location.href; - courseId = href.split('/')[4]; - } const togglePictureInPicture = async () => { try { @@ -482,8 +478,8 @@ export const VideoPlayer: FunctionComponent = ({ if (isYoutubeUrl(vidUrl)) return ; - if (appxVideoId && typeof window !== 'undefined' && courseId) - return ; + if (appxVideoId && typeof window !== 'undefined' && appxCourseId) + return ; return (
void; } @@ -36,6 +37,7 @@ export const VideoPlayerSegment: FunctionComponent = ({ videoJsOptions, onVideoEnd, appxVideoId, + appxCourseId }) => { const playerRef = useRef(null); @@ -52,7 +54,7 @@ export const VideoPlayerSegment: FunctionComponent = ({ if (mouseTimeDisplay) { const timeTooltip: any = mouseTimeDisplay.getChild('timeTooltip'); if (timeTooltip) { - timeTooltip.update = function ( + timeTooltip.update = function( seekBarRect: any, seekBarPoint: any, time: string, @@ -104,6 +106,7 @@ export const VideoPlayerSegment: FunctionComponent = ({ subtitles={subtitles} options={videoJsOptions} appxVideoId={appxVideoId} + appxCourseId={appxCourseId} onVideoEnd={onVideoEnd} onReady={handlePlayerReady} /> diff --git a/src/components/admin/AddContent.tsx b/src/components/admin/AddContent.tsx index efe9d9438..957ef5c32 100644 --- a/src/components/admin/AddContent.tsx +++ b/src/components/admin/AddContent.tsx @@ -46,9 +46,8 @@ export const AddContent = ({ const [loading, setLoading] = useState(false); const getLabelClassName = (value: string) => { - return `flex gap-1 p-4 rounded-lg items-center space-x-2 ${ - type === value ? 'border-[3px] border-blue-500' : 'border-[3px]' - }`; + return `flex gap-1 p-4 rounded-lg items-center space-x-2 ${type === value ? 'border-[3px] border-blue-500' : 'border-[3px]' + }`; }; const handleContentSubmit = async () => { @@ -215,8 +214,8 @@ function AddAppxVideoMetadata({
onChange({ appxVideoId: e.target.value })} + placeholder="Appx Video JSON" + onChange={(e) => onChange({ appxVideoJSON: JSON.stringify(e.target.value) })} className="h-14" />
diff --git a/src/components/admin/ContentRenderer.tsx b/src/components/admin/ContentRenderer.tsx index dc1602f61..1af77c9ee 100644 --- a/src/components/admin/ContentRenderer.tsx +++ b/src/components/admin/ContentRenderer.tsx @@ -3,6 +3,7 @@ import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { ContentRendererClient } from './ContentRendererClient'; import { Bookmark } from '@prisma/client'; +import { getAppxCourseId } from '@/utiles/appx'; function bunnyUrl(url?: string) { if (!url) return ''; @@ -86,7 +87,7 @@ export const getMetadata = async (contentId: number) => { slides: metadata['slides'], segments: metadata['segments'], thumbnails: metadata['thumbnail_mosiac_url'], - appxVideoId: metadata['appxVideoId'], + appxVideoJSON: metadata['appxVideoJSON'], }; if (user?.bunnyProxyEnabled) { @@ -104,7 +105,7 @@ export const getMetadata = async (contentId: number) => { slides: metadata['slides'], segments: metadata['segments'], thumbnails: metadata['thumbnail_mosiac_url'], - appxVideoId: metadata['appxVideoId'], + appxVideoJSON: metadata['appxVideoJSON'], }; const isHighestQualityUrlAccessible = await isUrlAccessible(mainUrls['1080']); @@ -147,12 +148,19 @@ export const ContentRenderer = async ({ }; }) => { const metadata = await getMetadata(content.id); + const appxCourseId = await getAppxCourseId(); + if (!appxCourseId) { + return
Loading...
; + } + //@ts-ignore + const appxVideoId: string = metadata?.appxVideoJSON[appxCourseId]; + return (
); diff --git a/src/components/admin/ContentRendererClient.tsx b/src/components/admin/ContentRendererClient.tsx index 5615bbcee..f73c0422e 100644 --- a/src/components/admin/ContentRendererClient.tsx +++ b/src/components/admin/ContentRendererClient.tsx @@ -25,6 +25,8 @@ export const ContentRendererClient = ({ thumbnail: string; description: string; markAsCompleted: boolean; + appxVideoId?: string; + appxCourseId?: string; }; }) => { const [showChapters, setShowChapters] = useState( @@ -79,7 +81,8 @@ export const ContentRendererClient = ({ contentId={content.id} subtitles={metadata.subtitles} thumbnails={[]} - appxVideoId={metadata.appxVideoId} + appxVideoId={content.appxVideoId} + appxCourseId={content.appxCourseId} segments={metadata?.segments || []} videoJsOptions={{ playbackrates: [0.5, 1, 1.25, 1.5, 1.75, 2], @@ -99,7 +102,7 @@ export const ContentRendererClient = ({ responsive: true, sources: [source], }} - onVideoEnd={() => {}} + onVideoEnd={() => { }} />
diff --git a/src/db/course.ts b/src/db/course.ts index 6183cf084..d8b57ef92 100644 --- a/src/db/course.ts +++ b/src/db/course.ts @@ -296,13 +296,13 @@ export const getFullCourseContent = async ( videoProgress: content.type === 'video' ? { - duration: videoProgress.find((x) => x.contentId === content.id) - ?.currentTimestamp, - markAsCompleted: videoProgress.find( - (x) => x.contentId === content.id, - )?.markAsCompleted, - videoFullDuration: content.VideoMetadata?.duration, - } + duration: videoProgress.find((x) => x.contentId === content.id) + ?.currentTimestamp, + markAsCompleted: videoProgress.find( + (x) => x.contentId === content.id, + )?.markAsCompleted, + videoFullDuration: content.VideoMetadata?.duration, + } : null, }, ]), diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 1ead921cf..4b09a6a68 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -76,7 +76,7 @@ async function validateUser( } return { data: null }; } - const url = 'https://harkiratapi.classx.co.in/post/userLogin'; + const url = `${process.env.APPX_BASE_API}/post/userLogin`; const headers = { 'Client-Service': process.env.APPX_CLIENT_SERVICE || '', 'Auth-Key': process.env.APPX_AUTH_KEY || '', diff --git a/src/utiles/appx.ts b/src/utiles/appx.ts index 92988612b..52847c726 100644 --- a/src/utiles/appx.ts +++ b/src/utiles/appx.ts @@ -13,6 +13,11 @@ import { refreshDbInternal } from '@/actions/refresh-db'; const LOCAL_CMS_PROVIDER = process.env.LOCAL_CMS_PROVIDER; const COHORT_3_PARENT_COURSES = [8, 9, 10, 11, 12]; +// 8 -> Web + Devops + Web3 +// 9 -> Web + Devops +// 10 -> Web3 +// 11 -> Web +// 12 -> Devops export const APPX_COURSE_IDS = [1, 2, 3, 8, 9, 10, 11, 12]; @@ -212,3 +217,22 @@ export async function getPurchases(email: string): Promise { }; } } + +export async function getAppxCourseId() { + const session = await getServerSession(authOptions); + const parentCourses = await prisma.userPurchases.findFirst({ + where: { + courseId: { + in: COHORT_3_PARENT_COURSES, + }, + userId: session?.user?.id, + }, + include: { + course: true, + }, + orderBy: { + courseId: 'asc' + } + }); + return parentCourses?.course.appxCourseId || null; +} From 420aac2d579c750fc7fc060fe6aa2cf1fcd493c9 Mon Sep 17 00:00:00 2001 From: SujithThirumalaisamy Date: Sun, 1 Dec 2024 19:23:13 +0530 Subject: [PATCH 2/4] Fixed parsing on api --- src/app/api/admin/content/route.ts | 16 +-------------- src/components/admin/AddContent.tsx | 31 ++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/app/api/admin/content/route.ts b/src/app/api/admin/content/route.ts index b24636cc7..dbc4e39c8 100644 --- a/src/app/api/admin/content/route.ts +++ b/src/app/api/admin/content/route.ts @@ -60,19 +60,6 @@ export const POST = async (req: NextRequest) => { discordChecked: boolean; } = await req.json(); - console.log({ - type, - thumbnail, - title, - courseId, - parentContentId, - metadata, - adminPassword, - courseTitle, - rest, - discordChecked, - }); - if (adminPassword !== process.env.ADMIN_SECRET) { return NextResponse.json({}, { status: 403 }); } @@ -113,7 +100,7 @@ export const POST = async (req: NextRequest) => { } else if (type === 'appx') { await db.videoMetadata.create({ data: { - appxVideoJSON: metadata.appxVideoJSON, + appxVideoJSON: JSON.parse(metadata.appxVideoJSON), contentId: content.id, }, }); @@ -181,7 +168,6 @@ export const POST = async (req: NextRequest) => { mediaId: content.id, }; - console.log(data); await sendUpdateToDiscord(data); } diff --git a/src/components/admin/AddContent.tsx b/src/components/admin/AddContent.tsx index 957ef5c32..4af3f4a27 100644 --- a/src/components/admin/AddContent.tsx +++ b/src/components/admin/AddContent.tsx @@ -50,9 +50,35 @@ export const AddContent = ({ }`; }; + const formatInputJSON = (value: string) => { + const valWithout = value.replaceAll("\\", "").slice(1, -1); + if (valWithout[0] === "{") { + return valWithout; + } + return valWithout.slice(1, -1); + }; + + const validateJSON = (value: string) => { + try { + JSON.parse(value); + return true; + } catch (error) { + return false; + } + }; + const handleContentSubmit = async () => { setLoading(true); - console.log(courseTitle); + if (type === "appx") { + //@ts-ignore + metadata.appxVideoJSON = formatInputJSON(metadata.appxVideoJSON); + } + //@ts-ignore + if (!validateJSON(metadata.appxVideoJSON)) { + toast.error("Invalid JSON"); + setLoading(false); + return; + } const response = await fetch('/api/admin/content', { body: JSON.stringify({ type, @@ -73,13 +99,12 @@ export const AddContent = ({ }, }); setLoading(false); - console.log(response); const responseData = await response.json(); - console.log(responseData); if (response.status === 200) { // handle success if needed toast.success(responseData.message); + setMetadata({}); } else { // handle error if needed toast.error(responseData.message || 'Something went wrong'); From 7c912a9ce607f4070a298afbb3cc2dfad6deb73e Mon Sep 17 00:00:00 2001 From: SujithThirumalaisamy Date: Sun, 1 Dec 2024 22:01:18 +0530 Subject: [PATCH 3/4] Fixed course ref --- src/components/AppxVideoPlayer.tsx | 8 +++++--- src/components/CourseView.tsx | 1 + src/components/admin/ContentRenderer.tsx | 3 ++- src/utiles/appx.ts | 19 ++++++++++++++++--- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/components/AppxVideoPlayer.tsx b/src/components/AppxVideoPlayer.tsx index d2b5c0082..33158780e 100644 --- a/src/components/AppxVideoPlayer.tsx +++ b/src/components/AppxVideoPlayer.tsx @@ -36,7 +36,9 @@ export const AppxVideoPlayer = ({ if (!url.length) { return

Loading...

; } - - return ; + return ; }; - diff --git a/src/components/CourseView.tsx b/src/components/CourseView.tsx index 30094a0db..da5928bad 100644 --- a/src/components/CourseView.tsx +++ b/src/components/CourseView.tsx @@ -66,6 +66,7 @@ export const CourseView = ({ markAsCompleted: courseContent?.value?.videoProgress?.markAsCompleted || false, bookmark: courseContent?.value.bookmark || null, + courseId: course.id, }} /> ) : null} diff --git a/src/components/admin/ContentRenderer.tsx b/src/components/admin/ContentRenderer.tsx index 1af77c9ee..99a70e188 100644 --- a/src/components/admin/ContentRenderer.tsx +++ b/src/components/admin/ContentRenderer.tsx @@ -145,10 +145,11 @@ export const ContentRenderer = async ({ slides?: string; markAsCompleted: boolean; bookmark: Bookmark | null; + courseId: string; }; }) => { const metadata = await getMetadata(content.id); - const appxCourseId = await getAppxCourseId(); + const appxCourseId = await getAppxCourseId(content.courseId); if (!appxCourseId) { return
Loading...
; } diff --git a/src/utiles/appx.ts b/src/utiles/appx.ts index 52847c726..90c490bc6 100644 --- a/src/utiles/appx.ts +++ b/src/utiles/appx.ts @@ -218,9 +218,9 @@ export async function getPurchases(email: string): Promise { } } -export async function getAppxCourseId() { +export async function getAppxCourseId(courseId: string) { const session = await getServerSession(authOptions); - const parentCourses = await prisma.userPurchases.findFirst({ + const parentCourses = await prisma.userPurchases.findMany({ where: { courseId: { in: COHORT_3_PARENT_COURSES, @@ -234,5 +234,18 @@ export async function getAppxCourseId() { courseId: 'asc' } }); - return parentCourses?.course.appxCourseId || null; + + const CMS_APPX_COURSE_MAP: Record = { + 13: ["8", "10"], + 14: ["8", "9", "11"], + 15: ["8", "9", "12"] + }; + + let appxCourseId: string | null = null; + parentCourses.forEach((pc => { + if (CMS_APPX_COURSE_MAP[courseId].includes(pc.courseId.toString())) { + appxCourseId = pc.course.appxCourseId; + } + })); + return appxCourseId; } From 2cb4c3110c31ecf8d914b0c842b761d50495d6dd Mon Sep 17 00:00:00 2001 From: Sargam Date: Mon, 2 Dec 2024 02:37:57 +0530 Subject: [PATCH 4/4] Update src/components/admin/AddContent.tsx --- src/components/admin/AddContent.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/admin/AddContent.tsx b/src/components/admin/AddContent.tsx index 4af3f4a27..df4af0e96 100644 --- a/src/components/admin/AddContent.tsx +++ b/src/components/admin/AddContent.tsx @@ -72,12 +72,12 @@ export const AddContent = ({ if (type === "appx") { //@ts-ignore metadata.appxVideoJSON = formatInputJSON(metadata.appxVideoJSON); - } - //@ts-ignore - if (!validateJSON(metadata.appxVideoJSON)) { - toast.error("Invalid JSON"); - setLoading(false); - return; + //@ts-ignore + if (!validateJSON(metadata.appxVideoJSON)) { + toast.error("Invalid JSON"); + setLoading(false); + return; + } } const response = await fetch('/api/admin/content', { body: JSON.stringify({