From 05bc3b9278c586bf4df1c87f508476f861a4711e Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 30 Jun 2025 14:29:34 +0700 Subject: [PATCH] feat: better error messages --- .../providers/bluesky/bluesky.provider.tsx | 7 ++-- .../providers/dribbble/dribbble.provider.tsx | 11 ++++--- .../instagram/instagram.collaborators.tsx | 13 +++++--- .../providers/linkedin/linkedin.provider.tsx | 11 ++++--- .../pinterest/pinterest.provider.tsx | 15 +++++---- .../providers/threads/threads.provider.tsx | 33 +++++++++++++++++-- .../providers/tiktok/tiktok.provider.tsx | 7 ++-- .../providers/warpcast/warpcast.provider.tsx | 7 ++-- .../providers/youtube/youtube.provider.tsx | 7 ++-- 9 files changed, 82 insertions(+), 29 deletions(-) diff --git a/apps/frontend/src/components/new-launch/providers/bluesky/bluesky.provider.tsx b/apps/frontend/src/components/new-launch/providers/bluesky/bluesky.provider.tsx index 753f6f0b..de7e1f3b 100644 --- a/apps/frontend/src/components/new-launch/providers/bluesky/bluesky.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/bluesky/bluesky.provider.tsx @@ -1,6 +1,9 @@ 'use client'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { ThreadFinisher } from '@gitroom/frontend/components/new-launch/finisher/thread.finisher'; const SettingsComponent = () => { @@ -18,7 +21,7 @@ export default withProvider( (p) => p.some((a) => a.path.indexOf('mp4') > -1) && p.length > 1 ) ) { - return 'You can only upload one video to Bluesky per post.'; + return 'You can only upload one video per post.'; } if (posts.some((p) => p.length > 4)) { diff --git a/apps/frontend/src/components/new-launch/providers/dribbble/dribbble.provider.tsx b/apps/frontend/src/components/new-launch/providers/dribbble/dribbble.provider.tsx index de09351c..ce05ab9a 100644 --- a/apps/frontend/src/components/new-launch/providers/dribbble/dribbble.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/dribbble/dribbble.provider.tsx @@ -1,7 +1,10 @@ 'use client'; import { FC } from 'react'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import { Input } from '@gitroom/react/form/input'; import { DribbbleTeams } from '@gitroom/frontend/components/new-launch/providers/dribbble/dribbble.teams'; @@ -23,10 +26,10 @@ export default withProvider( async ([firstItem, ...otherItems]) => { const isMp4 = firstItem?.find((item) => item.path.indexOf('mp4') > -1); if (firstItem.length !== 1) { - return 'Dribbble requires one item'; + return 'Requires one item'; } if (isMp4) { - return 'Dribbble does not support mp4 files'; + return 'Does not support mp4 files'; } const details = await new Promise<{ width: number; @@ -45,7 +48,7 @@ export default withProvider( ) { return true; } - return 'Invalid image size. Dribbble requires 400x300 or 800x600 px images.'; + return 'Invalid image size. Requires 400x300 or 800x600 px images.'; }, 40000 ); diff --git a/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx b/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx index 72202a1c..1b64b379 100644 --- a/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx +++ b/apps/frontend/src/components/new-launch/providers/instagram/instagram.collaborators.tsx @@ -1,6 +1,9 @@ 'use client'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { FC } from 'react'; import { Select } from '@gitroom/react/form/select'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; @@ -57,10 +60,10 @@ export default withProvider( InstagramDto, async ([firstPost, ...otherPosts], settings) => { if (!firstPost.length) { - return 'Instagram should have at least one media'; + return 'Should have at least one media'; } if (firstPost.length > 1 && settings.post_type === 'story') { - return 'Instagram stories can only have one media'; + return 'Stories can only have one media'; } const checkVideosLength = await Promise.all( firstPost @@ -79,10 +82,10 @@ export default withProvider( ); for (const video of checkVideosLength) { if (video > 60 && settings.post_type === 'story') { - return 'Instagram stories should be maximum 60 seconds'; + return 'Stories should be maximum 60 seconds'; } if (video > 180 && settings.post_type === 'post') { - return 'Instagram reel should be maximum 180 seconds'; + return 'Reel should be maximum 180 seconds'; } } return true; diff --git a/apps/frontend/src/components/new-launch/providers/linkedin/linkedin.provider.tsx b/apps/frontend/src/components/new-launch/providers/linkedin/linkedin.provider.tsx index 5e33ebe7..d75fd54a 100644 --- a/apps/frontend/src/components/new-launch/providers/linkedin/linkedin.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/linkedin/linkedin.provider.tsx @@ -1,6 +1,9 @@ 'use client'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { Checkbox } from '@gitroom/react/form/checkbox'; import { useT } from '@gitroom/react/translation/get.transation.service.client'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; @@ -35,17 +38,17 @@ export default withProvider( (firstPost.length < 2 || firstPost.some((p) => p.path.indexOf('mp4') > -1)) ) { - return 'LinkedIn carousel can only be created with 2 or more images and no videos.'; + return 'Carousel can only be created with 2 or more images and no videos.'; } if ( firstPost.length > 1 && firstPost.some((p) => p.path.indexOf('mp4') > -1) ) { - return 'LinkedIn can have maximum 1 media when selecting a video.'; + return 'Can have maximum 1 media when selecting a video.'; } if (restPosts.some((p) => p.length > 0)) { - return 'LinkedIn comments can only contain text.'; + return 'Comments can only contain text.'; } return true; }, diff --git a/apps/frontend/src/components/new-launch/providers/pinterest/pinterest.provider.tsx b/apps/frontend/src/components/new-launch/providers/pinterest/pinterest.provider.tsx index 72c2ecae..080ed92d 100644 --- a/apps/frontend/src/components/new-launch/providers/pinterest/pinterest.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/pinterest/pinterest.provider.tsx @@ -1,7 +1,10 @@ 'use client'; import { FC } from 'react'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import { PinterestBoard } from '@gitroom/frontend/components/new-launch/providers/pinterest/pinterest.board'; import { PinterestSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/pinterest.dto'; @@ -34,16 +37,16 @@ export default withProvider( (item) => item.path.indexOf('mp4') === -1 ); if (firstItem.length === 0) { - return 'Pinterest requires at least one media'; + return 'Requires at least one media'; } if (isMp4 && firstItem.length !== 2 && !isPicture) { - return 'If posting a video to Pinterest you have to also include a cover image as second media'; + return 'If posting a video you have to also include a cover image as second media'; } if (isMp4 && firstItem.length > 2) { - return 'If posting a video to Pinterest you can only have two media items'; + return 'If posting a video you can only have two media items'; } if (otherItems.length) { - return 'Pinterest can only have one post'; + return 'Can only have one post'; } if ( firstItem.length > 1 && @@ -68,7 +71,7 @@ export default withProvider( return p.width === arr[0].width && p.height === arr[0].height; }); if (!checkAllTheSameWidthHeight) { - return 'Pinterest requires all images to have the same width and height'; + return 'Requires all images to have the same width and height'; } } return true; diff --git a/apps/frontend/src/components/new-launch/providers/threads/threads.provider.tsx b/apps/frontend/src/components/new-launch/providers/threads/threads.provider.tsx index fd6df166..eaf577e0 100644 --- a/apps/frontend/src/components/new-launch/providers/threads/threads.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/threads/threads.provider.tsx @@ -1,6 +1,9 @@ 'use client'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { ThreadFinisher } from '@gitroom/frontend/components/new-launch/finisher/thread.finisher'; const SettingsComponent = () => { return ; @@ -11,7 +14,33 @@ export default withProvider( SettingsComponent, undefined, undefined, - async () => { + async ([firstPost, ...otherPosts], settings) => { + if (!firstPost.length) { + return 'Should have at least one media'; + } + + const checkVideosLength = await Promise.all( + firstPost + .filter((f) => f.path.indexOf('mp4') > -1) + .flatMap((p) => p.path) + .map((p) => { + return new Promise((res) => { + const video = document.createElement('video'); + video.preload = 'metadata'; + video.src = p; + video.addEventListener('loadedmetadata', () => { + res(video.duration); + }); + }); + }) + ); + + for (const video of checkVideosLength) { + if (video > 300) { + return 'Video should be maximum 300 seconds (5 minutes)'; + } + } + return true; }, 500 diff --git a/apps/frontend/src/components/new-launch/providers/tiktok/tiktok.provider.tsx b/apps/frontend/src/components/new-launch/providers/tiktok/tiktok.provider.tsx index 07f0cb5f..9a35ff92 100644 --- a/apps/frontend/src/components/new-launch/providers/tiktok/tiktok.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/tiktok/tiktok.provider.tsx @@ -8,7 +8,10 @@ import { useMemo, useState, } from 'react'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { TikTokDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/tiktok.dto'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import { Select } from '@gitroom/react/form/select'; @@ -351,7 +354,7 @@ export default withProvider( async (items) => { const [firstItems] = items; if (items.length !== 1) { - return 'Tiktok items should be one'; + return 'Should have one item'; } if (firstItems.length === 0) { return 'No video / images selected'; diff --git a/apps/frontend/src/components/new-launch/providers/warpcast/warpcast.provider.tsx b/apps/frontend/src/components/new-launch/providers/warpcast/warpcast.provider.tsx index d7255e2f..e98f3d90 100644 --- a/apps/frontend/src/components/new-launch/providers/warpcast/warpcast.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/warpcast/warpcast.provider.tsx @@ -1,6 +1,9 @@ 'use client'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { FC, useCallback } from 'react'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import { useFieldArray } from 'react-hook-form'; @@ -63,7 +66,7 @@ export default withProvider( if ( list.some((item) => item.some((field) => field.path.indexOf('mp4') > -1)) ) { - return 'Warpcast can only accept images'; + return 'Can only accept images'; } return true; }, diff --git a/apps/frontend/src/components/new-launch/providers/youtube/youtube.provider.tsx b/apps/frontend/src/components/new-launch/providers/youtube/youtube.provider.tsx index 42b4cf9e..a175d216 100644 --- a/apps/frontend/src/components/new-launch/providers/youtube/youtube.provider.tsx +++ b/apps/frontend/src/components/new-launch/providers/youtube/youtube.provider.tsx @@ -1,7 +1,10 @@ 'use client'; import { FC } from 'react'; -import { PostComment, withProvider } from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; +import { + PostComment, + withProvider, +} from '@gitroom/frontend/components/new-launch/providers/high.order.provider'; import { YoutubeSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/youtube.settings.dto'; import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; import { Input } from '@gitroom/react/form/input'; @@ -61,7 +64,7 @@ export default withProvider( async (items) => { const [firstItems] = items; if (items.length !== 1) { - return 'Youtube items should be one'; + return 'Should have one item'; } if (items[0].length !== 1) { return 'You need one media';