Support uploaded cover images for media posts
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled
هذا الالتزام موجود في:
@@ -87,6 +87,7 @@ export class PostsService {
|
||||
imageFiles: Array<{ mimetype?: string; size: number; buffer: Buffer; originalname?: string }> = [],
|
||||
videoFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
audioFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
coverImageFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
): Promise<PostDocument> {
|
||||
const inputImageUrls = dto.imageUrls ?? [];
|
||||
if (inputImageUrls.length > 10 || imageFiles.length > 10) {
|
||||
@@ -104,6 +105,12 @@ export class PostsService {
|
||||
if (audioFile && dto.audioUrl) {
|
||||
throw new BadRequestException('Provide either audioFile or audioUrl, not both');
|
||||
}
|
||||
if (coverImageFile && dto.thumbnailUrl) {
|
||||
throw new BadRequestException('Provide either coverImageFile or thumbnailUrl, not both');
|
||||
}
|
||||
if (coverImageFile && !(videoFile || audioFile || dto.videoUrl || dto.audioUrl)) {
|
||||
throw new BadRequestException('coverImageFile is allowed only with video or audio posts');
|
||||
}
|
||||
if ((videoFile || dto.videoUrl) && (imageFiles.length || inputImageUrls.length)) {
|
||||
throw new BadRequestException('Post can contain either images or video, not both');
|
||||
}
|
||||
@@ -115,10 +122,15 @@ export class PostsService {
|
||||
const uploadedImageUrls = savedImageUploads.map((item) => item.primaryUrl);
|
||||
const uploadedImageVariants = savedImageUploads.map((item) => item.variants);
|
||||
const savedVideoUpload = videoFile ? await this.saveVideoUpload(videoFile) : null;
|
||||
const savedCoverImageUpload = coverImageFile
|
||||
? await this.saveResponsiveImageAsset('thumbnails', coverImageFile)
|
||||
: null;
|
||||
const uploadedVideoUrl = savedVideoUpload?.videoUrl ?? '';
|
||||
const uploadedHlsUrl = savedVideoUpload?.hlsUrl ?? '';
|
||||
const uploadedThumbnailUrl = savedVideoUpload?.thumbnailUrl ?? '';
|
||||
const uploadedThumbnailVariants = savedVideoUpload?.thumbnailVariants ?? null;
|
||||
const generatedThumbnailUrl = savedVideoUpload?.thumbnailUrl ?? '';
|
||||
const generatedThumbnailVariants = savedVideoUpload?.thumbnailVariants ?? null;
|
||||
const uploadedThumbnailUrl = savedCoverImageUpload?.primaryUrl ?? generatedThumbnailUrl;
|
||||
const uploadedThumbnailVariants = savedCoverImageUpload?.variants ?? generatedThumbnailVariants;
|
||||
const uploadedAudioUrl = audioFile ? await this.saveMediaFile('audio', audioFile) : '';
|
||||
const finalImageUrls = uploadedImageUrls.length ? uploadedImageUrls : inputImageUrls;
|
||||
const finalImageVariants = uploadedImageVariants.length ? uploadedImageVariants : [];
|
||||
@@ -174,11 +186,18 @@ export class PostsService {
|
||||
uploadedThumbnailUrl
|
||||
? this.deleteThumbnailAsset(uploadedThumbnailUrl, uploadedThumbnailVariants)
|
||||
: Promise.resolve(),
|
||||
generatedThumbnailUrl && generatedThumbnailUrl !== uploadedThumbnailUrl
|
||||
? this.deleteThumbnailAsset(generatedThumbnailUrl, generatedThumbnailVariants)
|
||||
: Promise.resolve(),
|
||||
uploadedAudioUrl ? this.deleteManagedPostMedia(uploadedAudioUrl) : Promise.resolve(),
|
||||
]);
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (generatedThumbnailUrl && generatedThumbnailUrl !== uploadedThumbnailUrl) {
|
||||
await this.deleteThumbnailAsset(generatedThumbnailUrl, generatedThumbnailVariants);
|
||||
}
|
||||
|
||||
await this.usersRepository.incrementPostsCount(userId, 1);
|
||||
await this.feedVersionService.bumpGlobalVersion();
|
||||
await this.notifyMentionedUsers(userId, post.id, mentionResolution.mentionedUsers, finalContent);
|
||||
@@ -192,6 +211,7 @@ export class PostsService {
|
||||
imageFiles: Array<{ mimetype?: string; size: number; buffer: Buffer; originalname?: string }> = [],
|
||||
videoFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
audioFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
coverImageFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
): Promise<PostDocument> {
|
||||
const post = await this.postsRepository.findById(postId);
|
||||
if (!post) {
|
||||
@@ -219,6 +239,15 @@ export class PostsService {
|
||||
if (audioFile && dto.audioUrl) {
|
||||
throw new BadRequestException('Provide either audioFile or audioUrl, not both');
|
||||
}
|
||||
if (coverImageFile && dto.thumbnailUrl) {
|
||||
throw new BadRequestException('Provide either coverImageFile or thumbnailUrl, not both');
|
||||
}
|
||||
if (coverImageFile && (imageFiles.length || inputImageUrls.length)) {
|
||||
throw new BadRequestException('coverImageFile is allowed only with video or audio posts');
|
||||
}
|
||||
if (coverImageFile && !(videoFile || audioFile || dto.videoUrl || dto.audioUrl || post.videoUrl || post.audioUrl)) {
|
||||
throw new BadRequestException('coverImageFile is allowed only with video or audio posts');
|
||||
}
|
||||
if ((videoFile || dto.videoUrl) && (imageFiles.length || inputImageUrls.length)) {
|
||||
throw new BadRequestException('Post can contain either images or video, not both');
|
||||
}
|
||||
@@ -230,10 +259,15 @@ export class PostsService {
|
||||
const uploadedImageUrls = savedImageUploads.map((item) => item.primaryUrl);
|
||||
const uploadedImageVariants = savedImageUploads.map((item) => item.variants);
|
||||
const savedVideoUpload = videoFile ? await this.saveVideoUpload(videoFile) : null;
|
||||
const savedCoverImageUpload = coverImageFile
|
||||
? await this.saveResponsiveImageAsset('thumbnails', coverImageFile)
|
||||
: null;
|
||||
const uploadedVideoUrl = savedVideoUpload?.videoUrl ?? '';
|
||||
const uploadedHlsUrl = savedVideoUpload?.hlsUrl ?? '';
|
||||
const uploadedThumbnailUrl = savedVideoUpload?.thumbnailUrl ?? '';
|
||||
const uploadedThumbnailVariants = savedVideoUpload?.thumbnailVariants ?? null;
|
||||
const generatedThumbnailUrl = savedVideoUpload?.thumbnailUrl ?? '';
|
||||
const generatedThumbnailVariants = savedVideoUpload?.thumbnailVariants ?? null;
|
||||
const uploadedThumbnailUrl = savedCoverImageUpload?.primaryUrl ?? generatedThumbnailUrl;
|
||||
const uploadedThumbnailVariants = savedCoverImageUpload?.variants ?? generatedThumbnailVariants;
|
||||
const uploadedAudioUrl = audioFile ? await this.saveMediaFile('audio', audioFile) : '';
|
||||
const hasImageUpdate = typeof dto.imageUrls !== 'undefined' || imageFiles.length > 0;
|
||||
const existingImageVariants = Array.isArray((post as any).imageVariants)
|
||||
@@ -266,7 +300,7 @@ export class PostsService {
|
||||
? uploadedAudioUrl
|
||||
: dto.audioUrl ?? ''
|
||||
: post.audioUrl ?? '';
|
||||
const nextThumbnailVariants = videoFile
|
||||
const nextThumbnailVariants = coverImageFile || videoFile
|
||||
? uploadedThumbnailVariants
|
||||
: typeof dto.thumbnailUrl === 'string'
|
||||
? null
|
||||
@@ -392,6 +426,9 @@ export class PostsService {
|
||||
uploadedThumbnailUrl
|
||||
? this.deleteThumbnailAsset(uploadedThumbnailUrl, uploadedThumbnailVariants)
|
||||
: Promise.resolve(),
|
||||
generatedThumbnailUrl && generatedThumbnailUrl !== uploadedThumbnailUrl
|
||||
? this.deleteThumbnailAsset(generatedThumbnailUrl, generatedThumbnailVariants)
|
||||
: Promise.resolve(),
|
||||
uploadedAudioUrl ? this.deleteManagedPostMedia(uploadedAudioUrl) : Promise.resolve(),
|
||||
]);
|
||||
throw error;
|
||||
@@ -404,6 +441,9 @@ export class PostsService {
|
||||
uploadedThumbnailUrl
|
||||
? this.deleteThumbnailAsset(uploadedThumbnailUrl, uploadedThumbnailVariants)
|
||||
: Promise.resolve(),
|
||||
generatedThumbnailUrl && generatedThumbnailUrl !== uploadedThumbnailUrl
|
||||
? this.deleteThumbnailAsset(generatedThumbnailUrl, generatedThumbnailVariants)
|
||||
: Promise.resolve(),
|
||||
uploadedAudioUrl ? this.deleteManagedPostMedia(uploadedAudioUrl) : Promise.resolve(),
|
||||
]);
|
||||
throw new NotFoundException('Post not found');
|
||||
@@ -418,6 +458,9 @@ export class PostsService {
|
||||
if ((post.thumbnailUrl ?? '') !== (updated.thumbnailUrl ?? '')) {
|
||||
await this.deleteThumbnailAsset(post.thumbnailUrl ?? '', existingThumbnailVariants);
|
||||
}
|
||||
if (generatedThumbnailUrl && generatedThumbnailUrl !== uploadedThumbnailUrl) {
|
||||
await this.deleteThumbnailAsset(generatedThumbnailUrl, generatedThumbnailVariants);
|
||||
}
|
||||
if (hasAudioUpdate && (post.audioUrl ?? '') !== (updated.audioUrl ?? '')) {
|
||||
await this.deleteManagedPostMedia(post.audioUrl ?? '');
|
||||
}
|
||||
@@ -567,6 +610,7 @@ export class PostsService {
|
||||
userId: string,
|
||||
dto: CreateReelDto,
|
||||
videoFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
coverImageFile?: { mimetype?: string; size: number; buffer: Buffer; originalname?: string },
|
||||
): Promise<PostDocument> {
|
||||
if (!videoFile && !dto.videoUrl) {
|
||||
throw new BadRequestException('Reel requires videoFile or videoUrl');
|
||||
@@ -592,6 +636,7 @@ export class PostsService {
|
||||
[],
|
||||
videoFile,
|
||||
undefined,
|
||||
coverImageFile,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم