From 80b6bdcabedf82be108790e3183696d6f21ac236 Mon Sep 17 00:00:00 2001 From: Santosh Bhandari Date: Tue, 12 May 2026 16:23:11 +0545 Subject: [PATCH] feat: hasExtension helper for media type detection --- .../src/components/agents/agent.chat.tsx | 3 ++- .../helpers/media.settings.component.tsx | 3 ++- .../src/components/media/media.component.tsx | 11 +++++---- .../videos/providers/veo3.provider.tsx | 3 ++- libraries/helpers/src/utils/has.extension.ts | 10 ++++++++ .../database/prisma/posts/posts.service.ts | 3 ++- .../integrations/social/bluesky.provider.ts | 5 ++-- .../integrations/social/facebook.provider.ts | 3 ++- .../integrations/social/instagram.provider.ts | 24 +++++++++---------- .../integrations/social/linkedin.provider.ts | 7 +++--- .../src/integrations/social/mewe.provider.ts | 3 ++- .../integrations/social/pinterest.provider.ts | 5 ++-- .../integrations/social/reddit.provider.ts | 5 ++-- .../integrations/social/threads.provider.ts | 3 ++- .../integrations/social/tiktok.provider.ts | 9 +++---- .../src/integrations/social/vk.provider.ts | 5 ++-- .../src/integrations/social/x.provider.ts | 3 ++- .../src/helpers/video.or.image.tsx | 3 ++- 18 files changed, 67 insertions(+), 41 deletions(-) create mode 100644 libraries/helpers/src/utils/has.extension.ts diff --git a/apps/frontend/src/components/agents/agent.chat.tsx b/apps/frontend/src/components/agents/agent.chat.tsx index 4fafd204..66a42ce2 100644 --- a/apps/frontend/src/components/agents/agent.chat.tsx +++ b/apps/frontend/src/components/agents/agent.chat.tsx @@ -33,6 +33,7 @@ import dayjs from 'dayjs'; import { makeId } from '@gitroom/nestjs-libraries/services/make.is'; import { ExistingDataContextProvider } from '@gitroom/frontend/components/launches/helpers/use.existing.data'; import { useT } from '@gitroom/react/translation/get.transation.service.client'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; export const AgentChat: FC = () => { const { backendUrl } = useVariables(); @@ -162,7 +163,7 @@ const NewInput: FC = (props) => { ? '\n[--Media--]' + media .map((m) => - m.path.indexOf('mp4') > -1 + hasExtension(m.path, 'mp4') ? `Video: ${m.path}` : `Image: ${m.path}` ) diff --git a/apps/frontend/src/components/launches/helpers/media.settings.component.tsx b/apps/frontend/src/components/launches/helpers/media.settings.component.tsx index 3ce19f2c..d64ecbe6 100644 --- a/apps/frontend/src/components/launches/helpers/media.settings.component.tsx +++ b/apps/frontend/src/components/launches/helpers/media.settings.component.tsx @@ -4,6 +4,7 @@ import { EventEmitter } from 'events'; import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.title.component'; import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; import { useLaunchStore } from '@gitroom/frontend/components/new-launch/store'; import { useVariables } from '@gitroom/react/helpers/variable.context'; const postUrlEmitter = new EventEmitter(); @@ -375,7 +376,7 @@ export const MediaComponentInner: FC<{ className="w-full px-3 py-2 bg-fifth border border-tableBorder rounded-lg text-textColor placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-forth focus:border-transparent" /> - {media?.path.indexOf('mp4') > -1 && ( + {hasExtension(media?.path, 'mp4') && ( <> {/* Alt Text Input */}
diff --git a/apps/frontend/src/components/media/media.component.tsx b/apps/frontend/src/components/media/media.component.tsx index 78cf0957..2dbbd83f 100644 --- a/apps/frontend/src/components/media/media.component.tsx +++ b/apps/frontend/src/components/media/media.component.tsx @@ -14,6 +14,7 @@ import React, { import { Button } from '@gitroom/react/form/button'; import useSWR from 'swr'; import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; import { Media } from '@prisma/client'; import { useMediaDirectory } from '@gitroom/react/helpers/use.media.directory'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; @@ -351,7 +352,7 @@ export const MediaBox: FC<{ top: 10, children: (
- {media.path.indexOf('mp4') > -1 ? ( + {hasExtension(media.path, 'mp4') ? ( { if (type === 'video') { - return f.path.indexOf('mp4') > -1; + return hasExtension(f.path, 'mp4'); } else if (type === 'image') { - return f.path.indexOf('mp4') === -1; + return !hasExtension(f.path, 'mp4'); } return true; }) @@ -579,7 +580,7 @@ export const MediaBox: FC<{
- {media.path.indexOf('mp4') > -1 ? ( + {hasExtension(media.path, 'mp4') ? ( ) : ( - {media?.path?.indexOf('mp4') > -1 ? ( + {hasExtension(media?.path, 'mp4') ? ( ) : ( { setValue( 'images', val.target.value - .filter((f) => f.path.indexOf('mp4') === -1) + .filter((f) => !hasExtension(f.path, 'mp4')) .slice(0, 3) ) } diff --git a/libraries/helpers/src/utils/has.extension.ts b/libraries/helpers/src/utils/has.extension.ts new file mode 100644 index 00000000..8f51a228 --- /dev/null +++ b/libraries/helpers/src/utils/has.extension.ts @@ -0,0 +1,10 @@ +export const hasExtension = ( + path: string | undefined | null, + extension: string +): boolean => { + if (!path) { + return false; + } + const ext = extension.startsWith('.') ? extension : `.${extension}`; + return path.toLowerCase().indexOf(ext.toLowerCase()) > -1; +}; diff --git a/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts b/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts index 2ca5c875..ffc75339 100644 --- a/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts @@ -37,6 +37,7 @@ import { timer } from '@gitroom/helpers/utils/timer'; import { ioRedis } from '@gitroom/nestjs-libraries/redis/redis.service'; import { RefreshToken } from '@gitroom/nestjs-libraries/integrations/social.abstract'; import { RefreshIntegrationService } from '@gitroom/nestjs-libraries/integrations/refresh.integration.service'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; type PostWithConditionals = Post & { integration?: Integration; @@ -359,7 +360,7 @@ export class PostsService { return m; } - if (m.path.indexOf('.png') > -1) { + if (hasExtension(m.path, 'png')) { imageUpdateNeeded = true; const response = await axios.get(m.url, { responseType: 'arraybuffer', diff --git a/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts b/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts index 936aae68..206f1458 100644 --- a/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/bluesky.provider.ts @@ -27,6 +27,7 @@ import { timer } from '@gitroom/helpers/utils/timer'; import axios from 'axios'; import { stripHtmlValidation } from '@gitroom/helpers/utils/strip.html.validation'; import { Rules } from '@gitroom/nestjs-libraries/chat/rules.description.decorator'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; async function reduceImageBySize(url: string, maxSizeKB = 976) { try { @@ -266,9 +267,9 @@ export class BlueskyProvider extends SocialAbstract implements SocialProvider { ): Promise<{ embed: any; images: any[] }> { // Separate images and videos const imageMedia = - post.media?.filter((p) => p.path.indexOf('mp4') === -1) || []; + post.media?.filter((p) => !hasExtension(p.path, 'mp4')) || []; const videoMedia = - post.media?.filter((p) => p.path.indexOf('mp4') !== -1) || []; + post.media?.filter((p) => hasExtension(p.path, 'mp4')) || []; // Upload images const images = await Promise.all( diff --git a/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts b/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts index ab03455a..3b0d11d1 100644 --- a/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/facebook.provider.ts @@ -11,6 +11,7 @@ import { SocialAbstract } from '@gitroom/nestjs-libraries/integrations/social.ab import { FacebookDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/facebook.dto'; import { DribbbleDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/dribbble.dto'; import { Integration } from '@prisma/client'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; export class FacebookProvider extends SocialAbstract implements SocialProvider { identifier = 'facebook'; @@ -415,7 +416,7 @@ export class FacebookProvider extends SocialAbstract implements SocialProvider { let finalId = ''; let finalUrl = ''; - if ((firstPost?.media?.[0]?.path?.indexOf('mp4') || -2) > -1) { + if (hasExtension(firstPost?.media?.[0]?.path, 'mp4')) { const { id: videoId, permalink_url, diff --git a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts index 74ace32b..eb10f0c6 100644 --- a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts @@ -12,6 +12,7 @@ import { SocialAbstract } from '@gitroom/nestjs-libraries/integrations/social.ab import { InstagramDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/instagram.dto'; import { Integration } from '@prisma/client'; import { Rules } from '@gitroom/nestjs-libraries/chat/rules.description.decorator'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; @Rules( "Instagram should have at least one attachment, if it's a story, it can have only one picture" @@ -544,22 +545,21 @@ export class InstagramProvider (firstPost?.media?.length || 0) > 1 && !isStory ? `&is_carousel_item=true` : ``; - const mediaType = - m.path.indexOf('.mp4') > -1 - ? firstPost?.media?.length === 1 - ? isStory - ? `video_url=${m.path}&media_type=STORIES` - : `video_url=${m.path}&media_type=REELS&thumb_offset=${ - m?.thumbnailTimestamp || 0 - }` - : isStory + const mediaType = hasExtension(m.path, 'mp4') + ? firstPost?.media?.length === 1 + ? isStory ? `video_url=${m.path}&media_type=STORIES` - : `video_url=${m.path}&media_type=VIDEO&thumb_offset=${ + : `video_url=${m.path}&media_type=REELS&thumb_offset=${ m?.thumbnailTimestamp || 0 }` : isStory - ? `image_url=${m.path}&media_type=STORIES` - : `image_url=${m.path}`; + ? `video_url=${m.path}&media_type=STORIES` + : `video_url=${m.path}&media_type=VIDEO&thumb_offset=${ + m?.thumbnailTimestamp || 0 + }` + : isStory + ? `image_url=${m.path}&media_type=STORIES` + : `image_url=${m.path}`; const trialParams = isTrialReel ? `&trial_params=${encodeURIComponent( diff --git a/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts b/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts index 978b237b..b74f9868 100644 --- a/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts @@ -8,6 +8,7 @@ import { makeId } from '@gitroom/nestjs-libraries/services/make.is'; import sharp from 'sharp'; import { lookup } from 'mime-types'; import { readOrFetch } from '@gitroom/helpers/utils/read.or.fetch'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; import { SocialAbstract } from '@gitroom/nestjs-libraries/integrations/social.abstract'; import { Integration } from '@prisma/client'; import { PostPlug } from '@gitroom/helpers/decorators/post.plug'; @@ -234,8 +235,8 @@ export class LinkedinProvider extends SocialAbstract implements SocialProvider { type = 'personal' as 'company' | 'personal' ) { // Determine the appropriate endpoint based on file type - const isVideo = fileName.indexOf('mp4') > -1; - const isPdf = fileName.toLowerCase().indexOf('pdf') > -1; + const isVideo = hasExtension(fileName, 'mp4'); + const isPdf = hasExtension(fileName, 'pdf'); let endpoint: string; if (isVideo) { @@ -477,7 +478,7 @@ export class LinkedinProvider extends SocialAbstract implements SocialProvider { } private async prepareMediaBuffer(mediaUrl: string): Promise { - const isVideo = mediaUrl.indexOf('mp4') > -1; + const isVideo = hasExtension(mediaUrl, 'mp4'); const isGif = lookup(mediaUrl) === 'image/gif'; if (isVideo || isGif) { diff --git a/libraries/nestjs-libraries/src/integrations/social/mewe.provider.ts b/libraries/nestjs-libraries/src/integrations/social/mewe.provider.ts index 4fc27a35..51c51c53 100644 --- a/libraries/nestjs-libraries/src/integrations/social/mewe.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/mewe.provider.ts @@ -10,6 +10,7 @@ import dayjs from 'dayjs'; import { Integration } from '@prisma/client'; import { MeweDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/mewe.dto'; import { Tool } from '@gitroom/nestjs-libraries/integrations/tool.decorator'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; export class MeweProvider extends SocialAbstract implements SocialProvider { identifier = 'mewe'; @@ -244,7 +245,7 @@ export class MeweProvider extends SocialAbstract implements SocialProvider { // Upload photos if present (exclude videos) const imageMedia = - firstPost.media?.filter((m) => !m.path || m.path.indexOf('mp4') === -1) || + firstPost.media?.filter((m) => !m.path || !hasExtension(m.path, 'mp4')) || []; const uploadedPhotoIds: string[] = []; diff --git a/libraries/nestjs-libraries/src/integrations/social/pinterest.provider.ts b/libraries/nestjs-libraries/src/integrations/social/pinterest.provider.ts index 56165c8f..85b7a67c 100644 --- a/libraries/nestjs-libraries/src/integrations/social/pinterest.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/pinterest.provider.ts @@ -17,6 +17,7 @@ import { import dayjs from 'dayjs'; import { Tool } from '@gitroom/nestjs-libraries/integrations/tool.decorator'; import { Rules } from '@gitroom/nestjs-libraries/chat/rules.description.decorator'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; @Rules( 'Pinterest requires at least one media, if posting a video, you must have two attachment, one for video, one for the cover picture, When posting a video, there can be only one' @@ -185,10 +186,10 @@ export class PinterestProvider ): Promise { let mediaId = ''; const findMp4 = postDetails?.[0]?.media?.find( - (p) => (p.path?.indexOf('mp4') || -1) > -1 + (p) => hasExtension(p.path, 'mp4') ); const picture = postDetails?.[0]?.media?.find( - (p) => (p.path?.indexOf('mp4') || -1) === -1 + (p) => !hasExtension(p.path, 'mp4') ); if (findMp4) { diff --git a/libraries/nestjs-libraries/src/integrations/social/reddit.provider.ts b/libraries/nestjs-libraries/src/integrations/social/reddit.provider.ts index ae8fcc3c..bfd4d666 100644 --- a/libraries/nestjs-libraries/src/integrations/social/reddit.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/reddit.provider.ts @@ -14,6 +14,7 @@ import axios from 'axios'; import WebSocket from 'ws'; import { Tool } from '@gitroom/nestjs-libraries/integrations/tool.decorator'; import { Integration } from '@prisma/client'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; // @ts-ignore global.WebSocket = WebSocket; @@ -186,7 +187,7 @@ export class RedditProvider extends SocialAbstract implements SocialProvider { for (const firstPostSettings of post.settings.subreddit) { const kind = firstPostSettings.value.type === 'media' - ? post.media[0].path.indexOf('mp4') > -1 + ? hasExtension(post.media[0].path, 'mp4') ? 'video' : 'image' : firstPostSettings.value.type; @@ -211,7 +212,7 @@ export class RedditProvider extends SocialAbstract implements SocialProvider { accessToken, post.media[0].path ), - ...(post.media[0].path.indexOf('mp4') > -1 + ...(hasExtension(post.media[0].path, 'mp4') ? { video_poster_url: await this.uploadFileToReddit( accessToken, diff --git a/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts b/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts index 30cbee04..06fb60a8 100644 --- a/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/threads.provider.ts @@ -13,6 +13,7 @@ import { capitalize, chunk } from 'lodash'; import { Plug } from '@gitroom/helpers/decorators/plug.decorator'; import { Integration } from '@prisma/client'; import { stripHtmlValidation } from '@gitroom/helpers/utils/strip.html.validation'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; export class ThreadsProvider extends SocialAbstract implements SocialProvider { identifier = 'threads'; @@ -189,7 +190,7 @@ export class ThreadsProvider extends SocialAbstract implements SocialProvider { replyToId?: string ): Promise { const mediaType = - media.path.indexOf('.mp4') > -1 ? 'video_url' : 'image_url'; + hasExtension(media.path, 'mp4') ? 'video_url' : 'image_url'; const mediaParams = new URLSearchParams({ ...(mediaType === 'video_url' ? { video_url: media.path } : {}), ...(mediaType === 'image_url' ? { image_url: media.path } : {}), diff --git a/libraries/nestjs-libraries/src/integrations/social/tiktok.provider.ts b/libraries/nestjs-libraries/src/integrations/social/tiktok.provider.ts index 768403e0..a714add0 100644 --- a/libraries/nestjs-libraries/src/integrations/social/tiktok.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/tiktok.provider.ts @@ -12,6 +12,7 @@ import { } from '@gitroom/nestjs-libraries/integrations/social.abstract'; import { TikTokDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/tiktok.dto'; import { timer } from '@gitroom/helpers/utils/timer'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; import { Integration } from '@prisma/client'; import { Rules } from '@gitroom/nestjs-libraries/chat/rules.description.decorator'; @@ -457,7 +458,7 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider { } private buildTikokPostInfoBody(firstPost: PostDetails) { - const isPhoto = (firstPost?.media?.[0]?.path?.indexOf('mp4') || -1) === -1; + const isPhoto = !hasExtension(firstPost?.media?.[0]?.path, 'mp4'); const method = firstPost?.settings?.content_posting_method; if (method === 'DIRECT_POST') { @@ -507,7 +508,7 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider { } private buildTikokSourceInfoBody(firstPost: PostDetails) { - const isPhoto = (firstPost?.media?.[0]?.path?.indexOf('mp4') || -1) === -1; + const isPhoto = !hasExtension(firstPost?.media?.[0]?.path, 'mp4'); if (isPhoto) { return { @@ -545,7 +546,7 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider { integration: Integration ): Promise { const [firstPost] = postDetails; - const isPhoto = (firstPost?.media?.[0]?.path?.indexOf('mp4') || -1) === -1; + const isPhoto = !hasExtension(firstPost?.media?.[0]?.path, 'mp4'); console.log({ ...this.buildTikokPostInfoBody(firstPost), @@ -557,7 +558,7 @@ export class TiktokProvider extends SocialAbstract implements SocialProvider { await this.fetch( `https://open.tiktokapis.com/v2/post/publish${this.postingMethod( firstPost.settings.content_posting_method, - (firstPost?.media?.[0]?.path?.indexOf('mp4') || -1) === -1 + !hasExtension(firstPost?.media?.[0]?.path, 'mp4') )}`, { method: 'POST', diff --git a/libraries/nestjs-libraries/src/integrations/social/vk.provider.ts b/libraries/nestjs-libraries/src/integrations/social/vk.provider.ts index c871e1b6..f767d531 100644 --- a/libraries/nestjs-libraries/src/integrations/social/vk.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/vk.provider.ts @@ -12,6 +12,7 @@ import axios from 'axios'; import FormDataNew from 'form-data'; import mime from 'mime-types'; import { Integration } from '@prisma/client'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; export class VkProvider extends SocialAbstract implements SocialProvider { override maxConcurrentJob = 2; // VK has moderate API limits @@ -168,7 +169,7 @@ export class VkProvider extends SocialAbstract implements SocialProvider { (post?.media || []).map(async (media) => { const all = await ( await this.fetch( - media.path.indexOf('mp4') > -1 + hasExtension(media.path, 'mp4') ? `https://api.vk.com/method/video.save?access_token=${accessToken}&v=5.251` : `https://api.vk.com/method/photos.getWallUploadServer?owner_id=${userId}&access_token=${accessToken}&v=5.251` ) @@ -193,7 +194,7 @@ export class VkProvider extends SocialAbstract implements SocialProvider { }) ).data; - if (media.path.indexOf('mp4') > -1) { + if (hasExtension(media.path, 'mp4')) { return { id: all.response.video_id, type: 'video', diff --git a/libraries/nestjs-libraries/src/integrations/social/x.provider.ts b/libraries/nestjs-libraries/src/integrations/social/x.provider.ts index 68284508..fcedcd15 100644 --- a/libraries/nestjs-libraries/src/integrations/social/x.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/x.provider.ts @@ -20,6 +20,7 @@ import { uniqBy } from 'lodash'; import { stripHtmlValidation } from '@gitroom/helpers/utils/strip.html.validation'; import { XDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/x.dto'; import { Rules } from '@gitroom/nestjs-libraries/chat/rules.description.decorator'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; @Rules( 'X can have maximum 4 pictures, or maximum one video, it can also be without attachments' @@ -387,7 +388,7 @@ export class XProvider extends SocialAbstract implements SocialProvider { id: await this.runInConcurrent( async () => client.v2.uploadMedia( - m.path.indexOf('mp4') > -1 + hasExtension(m.path, 'mp4') ? Buffer.from(await readOrFetch(m.path)) : await sharp(await readOrFetch(m.path), { animated: lookup(m.path) === 'image/gif', diff --git a/libraries/react-shared-libraries/src/helpers/video.or.image.tsx b/libraries/react-shared-libraries/src/helpers/video.or.image.tsx index 7fa8149f..ee90f804 100644 --- a/libraries/react-shared-libraries/src/helpers/video.or.image.tsx +++ b/libraries/react-shared-libraries/src/helpers/video.or.image.tsx @@ -1,5 +1,6 @@ import { FC } from 'react'; import { clsx } from 'clsx'; +import { hasExtension } from '@gitroom/helpers/utils/has.extension'; export const VideoOrImage: FC<{ src: string; autoplay: boolean; @@ -8,7 +9,7 @@ export const VideoOrImage: FC<{ videoClassName?: string; }> = (props) => { const { src, autoplay, isContain, imageClassName, videoClassName } = props; - if (src?.indexOf('mp4') > -1) { + if (hasExtension(src, 'mp4')) { return (