diff --git a/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts b/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts index 74185e59..05dd16cc 100644 --- a/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts +++ b/apps/backend/src/public-api/routes/v1/public.integrations.controller.ts @@ -1,12 +1,5 @@ import { - Body, - Controller, - Get, - HttpException, - Post, - Query, - UploadedFile, - UseInterceptors, + Body, Controller, Delete, Get, HttpException, Param, Post, Query, UploadedFile, UseInterceptors } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request'; @@ -76,6 +69,15 @@ export class PublicIntegrationsController { return this._postsService.createPost(org.id, body); } + @Delete('/posts/:id') + async deletePost( + @GetOrgFromRequest() org: Organization, + @Param() body: { id: string } + ) { + const getPostById = await this._postsService.getPost(org.id, body.id); + return this._postsService.deletePost(org.id, getPostById.group); + } + @Get('/integrations') async listIntegration(@GetOrgFromRequest() org: Organization) { return (await this._integrationService.getIntegrationsList(org.id)).map( diff --git a/apps/frontend/src/app/global.scss b/apps/frontend/src/app/global.scss index f9e668fa..0dcf5173 100644 --- a/apps/frontend/src/app/global.scss +++ b/apps/frontend/src/app/global.scss @@ -282,7 +282,7 @@ html { width: auto !important; } -.editor * { +.editor :not(.removeEditor *) { @apply text-textColor; } diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index 15a3fc15..66232dbb 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -561,7 +561,7 @@ export const CalendarColumn: FC<{ ))} {!showAll && postList.length > 3 && (
+ Show more ({postList.length - 3}) @@ -683,7 +683,7 @@ const CalendarItem: FC<{ className={clsx('w-full flex h-full flex-1 flex-col group', 'relative')} style={{ opacity }} > -
+
{ return (
-
+
{ >
@@ -193,7 +193,7 @@ export const Filters = () => { ? `Week ${week.currentWeek}` : `${dayjs().month(week.currentMonth).format('MMMM')}`}
-
+
{ >
diff --git a/apps/frontend/src/components/launches/helpers/pick.platform.component.tsx b/apps/frontend/src/components/launches/helpers/pick.platform.component.tsx index b733bfa7..104899fc 100644 --- a/apps/frontend/src/components/launches/helpers/pick.platform.component.tsx +++ b/apps/frontend/src/components/launches/helpers/pick.platform.component.tsx @@ -316,7 +316,7 @@ export const PickPlatforms: FC<{ height={15} />
-
{integration.name}
+
{integration.name.slice(0, 10)}{integration.name.length > 10 ? '...' : ''}
diff --git a/apps/frontend/src/components/launches/providers/high.order.provider.tsx b/apps/frontend/src/components/launches/providers/high.order.provider.tsx index a2d67a16..9c5bd66b 100644 --- a/apps/frontend/src/components/launches/providers/high.order.provider.tsx +++ b/apps/frontend/src/components/launches/providers/high.order.provider.tsx @@ -409,7 +409,9 @@ export const withProvider = function ( > {editInPlace ? 'Edit globally' - : `Edit only ${integration?.name} (${capitalize( + : `Edit only ${integration?.name.slice(0, 10)}${ + (integration?.name?.length || 0) > 10 ? '...' : '' + } (${capitalize( integration?.identifier.replace('-', ' ') )})`} diff --git a/apps/frontend/src/components/media/media.component.tsx b/apps/frontend/src/components/media/media.component.tsx index 0e9d6f95..e1f6fc60 100644 --- a/apps/frontend/src/components/media/media.component.tsx +++ b/apps/frontend/src/components/media/media.component.tsx @@ -75,8 +75,8 @@ export const Pagination: FC<{ aria-current="page" onClick={() => setPage(page)} className={clsx( - 'cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border hover:bg-forth h-10 w-10 hover:text-white border-[#1F1F1F] text-white', - current === page && 'bg-forth' + 'cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border hover:bg-forth h-10 w-10 hover:text-white border-[#1F1F1F]', + current === page ? 'bg-forth !text-white' : 'text-textColor hover:text-white' )} > {page + 1} @@ -89,7 +89,7 @@ export const Pagination: FC<{ )} > setPage(current + 1)} > @@ -292,7 +292,7 @@ export const MediaBox: FC<{ }, [data]); return ( -
+
@@ -375,8 +375,10 @@ export const MediaBox: FC<{ ) : ( <> {selectedMedia.length > 0 && ( -
- +
+
)} @@ -403,7 +405,7 @@ export const MediaBox: FC<{ >
X
@@ -445,15 +447,7 @@ export const MultiMediaComponent: FC<{ target: { name: string; value?: Array<{ id: string; path: string }> }; }) => void; }> = (props) => { - const { - onOpen, - onClose, - name, - error, - text, - onChange, - value, - } = props; + const { onOpen, onClose, name, error, text, onChange, value } = props; const user = useUser(); useEffect(() => { @@ -577,14 +571,14 @@ export const MultiMediaComponent: FC<{
window.open(mediaDirectory.set(media.path))} + onClick={() => window.open(mediaDirectory.set(media?.path))} > - {media.path.indexOf('mp4') > -1 ? ( - + {media?.path?.indexOf('mp4') > -1 ? ( + ) : ( )}
diff --git a/libraries/nestjs-libraries/src/database/prisma/media/media.repository.ts b/libraries/nestjs-libraries/src/database/prisma/media/media.repository.ts index 06696e12..a2b5da58 100644 --- a/libraries/nestjs-libraries/src/database/prisma/media/media.repository.ts +++ b/libraries/nestjs-libraries/src/database/prisma/media/media.repository.ts @@ -19,6 +19,14 @@ export class MediaRepository { }); } + getMediaById(id: string) { + return this._media.model.media.findUnique({ + where: { + id, + }, + }); + } + deleteMedia(org: string, id: string) { return this._media.model.media.update({ where: { diff --git a/libraries/nestjs-libraries/src/database/prisma/media/media.service.ts b/libraries/nestjs-libraries/src/database/prisma/media/media.service.ts index 53840fa0..921ebc11 100644 --- a/libraries/nestjs-libraries/src/database/prisma/media/media.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/media/media.service.ts @@ -16,6 +16,10 @@ export class MediaService { return this._mediaRepository.deleteMedia(org, id); } + getMediaById(id: string) { + return this._mediaRepository.getMediaById(id); + } + async generateImage( prompt: string, org: Organization, diff --git a/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts b/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts index 9f4c8523..3b0d25ed 100644 --- a/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts +++ b/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts @@ -51,6 +51,17 @@ export class PostsRepository { }); } + updateImages(id: string, images: string) { + return this._post.model.post.update({ + where: { + id, + }, + data: { + image: images, + }, + }); + } + getPostUrls(orgId: string, ids: string[]) { return this._post.model.post.findMany({ where: { 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 5265ed88..d4320b6e 100644 --- a/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts @@ -20,6 +20,7 @@ import { BullMqClient } from '@gitroom/nestjs-libraries/bull-mq-transport-new/cl import { timer } from '@gitroom/helpers/utils/timer'; import { AuthTokenDetails } from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface'; import utc from 'dayjs/plugin/utc'; +import { MediaService } from '@gitroom/nestjs-libraries/database/prisma/media/media.service'; dayjs.extend(utc); type PostWithConditionals = Post & { @@ -36,7 +37,8 @@ export class PostsService { private _notificationService: NotificationService, private _messagesService: MessagesService, private _stripeService: StripeService, - private _integrationService: IntegrationService + private _integrationService: IntegrationService, + private _mediaService: MediaService ) {} async getPostsRecursively( @@ -73,18 +75,63 @@ export class PostsService { return this._postRepository.getPosts(orgId, query); } + async updateMedia(id: string, imagesList: any[]) { + let imageUpdateNeeded = false; + const getImageList = ( + await Promise.all( + imagesList.map(async (p: any) => { + if (!p.path && p.id) { + imageUpdateNeeded = true; + return this._mediaService.getMediaById(p.id); + } + + return p; + }) + ) + ).map((m) => { + return { + ...m, + url: + m.path.indexOf('http') === -1 + ? process.env.FRONTEND_URL + + '/' + + process.env.NEXT_PUBLIC_UPLOAD_STATIC_DIRECTORY + + m.path + : m.path, + type: 'image', + path: + m.path.indexOf('http') === -1 + ? process.env.UPLOAD_DIRECTORY + m.path + : m.path, + }; + }); + + if (imageUpdateNeeded) { + await this._postRepository.updateImages(id, JSON.stringify(getImageList)); + } + + return getImageList; + } + async getPost(orgId: string, id: string) { const posts = await this.getPostsRecursively(id, true, orgId, true); - return { + const list = { group: posts?.[0]?.group, - posts: posts.map((post) => ({ - ...post, - image: JSON.parse(post.image || '[]'), - })), + posts: await Promise.all( + posts.map(async (post) => ({ + ...post, + image: await this.updateMedia( + post.id, + JSON.parse(post.image || '[]') + ), + })) + ), integrationPicture: posts[0]?.integration?.picture, integration: posts[0].integrationId, settings: JSON.parse(posts[0].settings || '{}'), }; + + return list; } async getOldPosts(orgId: string, date: string) { @@ -280,25 +327,14 @@ export class PostsService { const publishedPosts = await getIntegration.post( integration.internalId, integration.token, - newPosts.map((p) => ({ - id: p.id, - message: p.content, - settings: JSON.parse(p.settings || '{}'), - media: (JSON.parse(p.image || '[]') as Media[]).map((m) => ({ - url: - m.path.indexOf('http') === -1 - ? process.env.FRONTEND_URL + - '/' + - process.env.NEXT_PUBLIC_UPLOAD_STATIC_DIRECTORY + - m.path - : m.path, - type: 'image', - path: - m.path.indexOf('http') === -1 - ? process.env.UPLOAD_DIRECTORY + m.path - : m.path, - })), - })), + await Promise.all( + newPosts.map(async (p) => ({ + id: p.id, + message: p.content, + settings: JSON.parse(p.settings || '{}'), + media: await this.updateMedia(p.id, JSON.parse(p.image || '[]')), + })) + ), integration ); @@ -469,7 +505,10 @@ export class PostsService { const post = await this._postRepository.deletePost(orgId, group); if (post?.id) { await this._workerServiceProducer.delete('post', post.id); + return {id: post.id}; } + + return {error: true}; } async countPostsFromDay(orgId: string, date: Date) { @@ -513,6 +552,7 @@ export class PostsService { } async createPost(orgId: string, body: CreatePostDto) { + const postList = []; for (const post of body.posts) { const { previousPost, posts } = await this._postRepository.createOrUpdatePost( @@ -560,7 +600,14 @@ export class PostsService { }, }); } + + postList.push({ + postId: posts[0].id, + integration: post.integration.id, + }) } + + return postList; } async changeDate(orgId: string, id: string, date: string) { @@ -802,7 +849,12 @@ export class PostsService { return this._postRepository.getComments(postId); } - createComment(orgId: string, userId: string, postId: string, comment: string) { + createComment( + orgId: string, + userId: string, + postId: string, + comment: string + ) { return this._postRepository.createComment(orgId, userId, postId, comment); } } 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 47e6b5a8..7cbded76 100644 --- a/libraries/react-shared-libraries/src/helpers/video.or.image.tsx +++ b/libraries/react-shared-libraries/src/helpers/video.or.image.tsx @@ -7,7 +7,7 @@ export const VideoOrImage: FC<{ isContain?: boolean; }> = (props) => { const { src, autoplay, isContain } = props; - if (src.indexOf('mp4') > -1) { + if (src?.indexOf('mp4') > -1) { return (