Improve backend media readiness for mobile clients
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled
هذا الالتزام موجود في:
105
src/common/utils/post-media-response.util.ts
Normal file
105
src/common/utils/post-media-response.util.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { PostType } from '../enums/post-type.enum';
|
||||
|
||||
type VariantSet = {
|
||||
originalUrl?: string;
|
||||
lowUrl?: string;
|
||||
mediumUrl?: string;
|
||||
highUrl?: string;
|
||||
} | null;
|
||||
|
||||
type PostMediaInput = {
|
||||
postType?: PostType | string;
|
||||
imageUrls?: string[];
|
||||
imageItems?: Array<{ url?: string; caption?: string; altText?: string; order?: number }>;
|
||||
imageVariants?: VariantSet[];
|
||||
videoUrl?: string;
|
||||
hlsUrl?: string;
|
||||
audioUrl?: string;
|
||||
thumbnailUrl?: string;
|
||||
thumbnailVariants?: VariantSet;
|
||||
waveformPeaks?: number[];
|
||||
durationSeconds?: number | null;
|
||||
};
|
||||
|
||||
const firstNonEmpty = (...values: Array<string | undefined | null>): string =>
|
||||
values.find((value): value is string => typeof value === 'string' && value.trim().length > 0) ?? '';
|
||||
|
||||
const normalizeVariantSet = (variants: VariantSet) => {
|
||||
if (!variants) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
originalUrl: variants.originalUrl ?? '',
|
||||
lowUrl: variants.lowUrl ?? variants.mediumUrl ?? variants.highUrl ?? variants.originalUrl ?? '',
|
||||
mediumUrl: variants.mediumUrl ?? variants.highUrl ?? variants.lowUrl ?? variants.originalUrl ?? '',
|
||||
highUrl: variants.highUrl ?? variants.mediumUrl ?? variants.originalUrl ?? variants.lowUrl ?? '',
|
||||
};
|
||||
};
|
||||
|
||||
const preferredImageUrl = (variants: ReturnType<typeof normalizeVariantSet>, fallback = ''): string =>
|
||||
firstNonEmpty(variants?.mediumUrl, variants?.highUrl, variants?.lowUrl, variants?.originalUrl, fallback);
|
||||
|
||||
export const buildPostMediaResponse = (post: PostMediaInput) => {
|
||||
const imageUrls = Array.isArray(post.imageUrls) ? post.imageUrls : [];
|
||||
const imageItems = Array.isArray(post.imageItems) ? post.imageItems : [];
|
||||
const imageVariants = Array.isArray(post.imageVariants) ? post.imageVariants : [];
|
||||
const thumbnailVariants = normalizeVariantSet(post.thumbnailVariants ?? null);
|
||||
const fallbackImageItems: NonNullable<PostMediaInput['imageItems']> = imageUrls.map((url, index) => ({
|
||||
url,
|
||||
caption: '',
|
||||
altText: '',
|
||||
order: index,
|
||||
}));
|
||||
const images = (imageItems.length ? imageItems : fallbackImageItems).map(
|
||||
(item, index) => {
|
||||
const variants = normalizeVariantSet(imageVariants[index] ?? null);
|
||||
const url = item.url || imageUrls[index] || '';
|
||||
return {
|
||||
url: preferredImageUrl(variants, url),
|
||||
originalUrl: firstNonEmpty(variants?.originalUrl, url),
|
||||
variants,
|
||||
caption: item.caption ?? '',
|
||||
altText: item.altText ?? '',
|
||||
order: typeof item.order === 'number' ? item.order : index,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
const mediaType =
|
||||
post.postType === PostType.IMAGE && images.length
|
||||
? PostType.IMAGE
|
||||
: post.postType === PostType.VIDEO || post.videoUrl || post.hlsUrl
|
||||
? PostType.VIDEO
|
||||
: post.postType === PostType.AUDIO || post.audioUrl
|
||||
? PostType.AUDIO
|
||||
: PostType.TEXT;
|
||||
const thumbnailUrl = preferredImageUrl(thumbnailVariants, post.thumbnailUrl ?? '');
|
||||
const preferredPlaybackUrl =
|
||||
mediaType === PostType.VIDEO
|
||||
? firstNonEmpty(post.hlsUrl, post.videoUrl)
|
||||
: mediaType === PostType.AUDIO
|
||||
? post.audioUrl ?? ''
|
||||
: '';
|
||||
const displayUrl =
|
||||
mediaType === PostType.IMAGE
|
||||
? images[0]?.url ?? ''
|
||||
: mediaType === PostType.VIDEO || mediaType === PostType.AUDIO
|
||||
? thumbnailUrl
|
||||
: '';
|
||||
|
||||
return {
|
||||
mediaType,
|
||||
displayUrl,
|
||||
thumbnailUrl,
|
||||
thumbnailVariants,
|
||||
preferredPlaybackUrl,
|
||||
hlsUrl: post.hlsUrl ?? '',
|
||||
videoUrl: post.videoUrl ?? '',
|
||||
audioUrl: post.audioUrl ?? '',
|
||||
images,
|
||||
durationSeconds: post.durationSeconds ?? null,
|
||||
waveformPeaks: Array.isArray(post.waveformPeaks) ? post.waveformPeaks : [],
|
||||
isPlayable: mediaType === PostType.VIDEO ? !!preferredPlaybackUrl : mediaType === PostType.AUDIO ? !!post.audioUrl : false,
|
||||
};
|
||||
};
|
||||
المرجع في مشكلة جديدة
حظر مستخدم