Update media Postman collections and dashboard playback
هذا الالتزام موجود في:
1
.gitignore
مباع
1
.gitignore
مباع
@@ -2,6 +2,7 @@
|
||||
node_modules
|
||||
dist
|
||||
uploads
|
||||
stream_*/
|
||||
|
||||
# Env files
|
||||
.env
|
||||
|
||||
@@ -30,15 +30,18 @@ export function PostPreviewCard({ post }: { post: ApiPost }) {
|
||||
const durationLabel = formatDuration(post.durationSeconds);
|
||||
const [imageFailed, setImageFailed] = useState(false);
|
||||
const [sourceFailed, setSourceFailed] = useState(false);
|
||||
const [isVideoPlaying, setIsVideoPlaying] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setImageFailed(false);
|
||||
setSourceFailed(false);
|
||||
setIsVideoPlaying(false);
|
||||
}, [media.url, media.sourceUrl]);
|
||||
|
||||
const showAudioPreview = media.kind === "audio" && !!media.sourceUrl && !sourceFailed;
|
||||
const showVideoPreview = media.kind === "video" && !!media.sourceUrl && !sourceFailed && (!media.url || imageFailed);
|
||||
const showImagePreview = !!media.url && !imageFailed;
|
||||
const showVideoPreview =
|
||||
media.kind === "video" && !!media.sourceUrl && !sourceFailed && (isVideoPlaying || !media.url || imageFailed);
|
||||
const showImagePreview = !!media.url && !imageFailed && !(media.kind === "video" && isVideoPlaying);
|
||||
const showMediaShell = media.kind !== "text";
|
||||
const showUnavailable = !showImagePreview && !showVideoPreview && !showAudioPreview;
|
||||
|
||||
@@ -62,7 +65,9 @@ export function PostPreviewCard({ post }: { post: ApiPost }) {
|
||||
<video
|
||||
src={media.sourceUrl}
|
||||
preload="metadata"
|
||||
muted
|
||||
controls={isVideoPlaying}
|
||||
autoPlay={isVideoPlaying}
|
||||
muted={!isVideoPlaying}
|
||||
playsInline
|
||||
onError={() => setSourceFailed(true)}
|
||||
className="h-full w-full object-cover"
|
||||
@@ -114,7 +119,17 @@ export function PostPreviewCard({ post }: { post: ApiPost }) {
|
||||
</Badge>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="absolute bottom-3 right-3 rounded-full border border-border/60 bg-background/85 p-2 text-foreground">
|
||||
{media.kind === "video" && media.sourceUrl && !isVideoPlaying && !sourceFailed ? (
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Play video"
|
||||
onClick={() => setIsVideoPlaying(true)}
|
||||
className="absolute inset-0 z-10 cursor-pointer bg-transparent"
|
||||
>
|
||||
<span className="sr-only">Play video</span>
|
||||
</button>
|
||||
) : null}
|
||||
<div className="pointer-events-none absolute bottom-3 right-3 z-20 rounded-full border border-border/60 bg-background/85 p-2 text-foreground">
|
||||
{media.kind === "audio" ? <AudioLines className="h-4 w-4" /> : <PlayCircle className="h-4 w-4" />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -722,6 +722,40 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Media",
|
||||
"item": [
|
||||
{
|
||||
"name": "Media Health",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Authorization",
|
||||
"value": "Bearer {{accessToken}}"
|
||||
}
|
||||
],
|
||||
"url": "{{baseUrl}}/media/health"
|
||||
},
|
||||
"event": [
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"type": "text/javascript",
|
||||
"exec": [
|
||||
"pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.storage).to.be.an('object');",
|
||||
"pm.expect(json.storage.provider).to.be.oneOf(['local', 's3']);",
|
||||
"pm.expect(json.serving.rangeRequests).to.eql(true);",
|
||||
"pm.expect(json.processing).to.be.an('object');"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Users",
|
||||
"item": [
|
||||
@@ -1590,7 +1624,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('image');",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.imageUrls).to.be.an('array');",
|
||||
"pm.expect(json.media.images).to.be.an('array').that.is.not.empty;",
|
||||
"pm.expect(json.media.images[0].url).to.be.a('string');",
|
||||
"pm.expect(json.imageUrls.length).to.be.greaterThan(0);",
|
||||
"const pid = json._id || json.id;",
|
||||
"pm.environment.set('postId', pid);",
|
||||
@@ -1963,6 +2002,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('video');",
|
||||
"pm.expect(json.media.thumbnailUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.preferredPlaybackUrl).to.be.a('string');",
|
||||
"if (json.hlsUrl) { pm.expect(json.media.preferredPlaybackUrl).to.eql(json.hlsUrl); }",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.durationSeconds).to.eql(42);",
|
||||
"if (json.thumbnailUrl) { pm.expect(json.thumbnailUrl).to.be.a('string'); }",
|
||||
"pm.expect(json.style).to.eql('Sharqi');",
|
||||
@@ -2050,6 +2095,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('video');",
|
||||
"pm.expect(json.media.thumbnailUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.preferredPlaybackUrl).to.be.a('string');",
|
||||
"if (json.hlsUrl) { pm.expect(json.media.preferredPlaybackUrl).to.eql(json.hlsUrl); }",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.durationSeconds).to.eql(30);",
|
||||
"if (json.thumbnailUrl) { pm.expect(json.thumbnailUrl).to.be.a('string'); }",
|
||||
"pm.expect(json.style).to.eql('Sharqi');",
|
||||
@@ -2191,6 +2242,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('audio');",
|
||||
"pm.expect(json.media.audioUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.waveformPeaks).to.be.an('array');",
|
||||
"pm.expect(json.media.durationSeconds).to.exist;",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.durationSeconds).to.eql(54);",
|
||||
"if (json.thumbnailUrl) { pm.expect(json.thumbnailUrl).to.be.a('string'); }",
|
||||
"pm.expect(json.style).to.eql('Sharqi');",
|
||||
@@ -2283,6 +2340,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('audio');",
|
||||
"pm.expect(json.media.audioUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.waveformPeaks).to.be.an('array');",
|
||||
"pm.expect(json.media.durationSeconds).to.exist;",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.waveformPeaks).to.be.an('array');",
|
||||
"pm.expect(json.waveformPeaks.length).to.eql(6);",
|
||||
"pm.expect(json.maqam).to.eql('Hijaz');",
|
||||
|
||||
@@ -359,6 +359,40 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Media",
|
||||
"item": [
|
||||
{
|
||||
"name": "Media Health",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Authorization",
|
||||
"value": "Bearer {{accessToken}}"
|
||||
}
|
||||
],
|
||||
"url": "{{baseUrl}}/media/health"
|
||||
},
|
||||
"event": [
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"type": "text/javascript",
|
||||
"exec": [
|
||||
"pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.storage).to.be.an('object');",
|
||||
"pm.expect(json.storage.provider).to.be.oneOf(['local', 's3']);",
|
||||
"pm.expect(json.serving.rangeRequests).to.eql(true);",
|
||||
"pm.expect(json.processing).to.be.an('object');"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Users",
|
||||
"item": [
|
||||
|
||||
@@ -573,6 +573,40 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Media",
|
||||
"item": [
|
||||
{
|
||||
"name": "Media Health",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Authorization",
|
||||
"value": "Bearer {{accessToken}}"
|
||||
}
|
||||
],
|
||||
"url": "{{baseUrl}}/media/health"
|
||||
},
|
||||
"event": [
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"type": "text/javascript",
|
||||
"exec": [
|
||||
"pm.test('Status is 200', function () { pm.response.to.have.status(200); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.storage).to.be.an('object');",
|
||||
"pm.expect(json.storage.provider).to.be.oneOf(['local', 's3']);",
|
||||
"pm.expect(json.serving.rangeRequests).to.eql(true);",
|
||||
"pm.expect(json.processing).to.be.an('object');"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Users",
|
||||
"item": [
|
||||
@@ -1051,7 +1085,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('image');",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.imageUrls).to.be.an('array');",
|
||||
"pm.expect(json.media.images).to.be.an('array').that.is.not.empty;",
|
||||
"pm.expect(json.media.images[0].url).to.be.a('string');",
|
||||
"pm.expect(json.imageUrls.length).to.be.greaterThan(0);",
|
||||
"const pid = json._id || json.id;",
|
||||
"pm.environment.set('postId', pid);",
|
||||
@@ -1424,6 +1463,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('video');",
|
||||
"pm.expect(json.media.thumbnailUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.preferredPlaybackUrl).to.be.a('string');",
|
||||
"if (json.hlsUrl) { pm.expect(json.media.preferredPlaybackUrl).to.eql(json.hlsUrl); }",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.durationSeconds).to.eql(42);",
|
||||
"if (json.thumbnailUrl) { pm.expect(json.thumbnailUrl).to.be.a('string'); }",
|
||||
"pm.expect(json.style).to.eql('Sharqi');",
|
||||
@@ -1511,6 +1556,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('video');",
|
||||
"pm.expect(json.media.thumbnailUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.preferredPlaybackUrl).to.be.a('string');",
|
||||
"if (json.hlsUrl) { pm.expect(json.media.preferredPlaybackUrl).to.eql(json.hlsUrl); }",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.durationSeconds).to.eql(30);",
|
||||
"if (json.thumbnailUrl) { pm.expect(json.thumbnailUrl).to.be.a('string'); }",
|
||||
"pm.expect(json.style).to.eql('Sharqi');",
|
||||
@@ -1652,6 +1703,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('audio');",
|
||||
"pm.expect(json.media.audioUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.waveformPeaks).to.be.an('array');",
|
||||
"pm.expect(json.media.durationSeconds).to.exist;",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.durationSeconds).to.eql(54);",
|
||||
"if (json.thumbnailUrl) { pm.expect(json.thumbnailUrl).to.be.a('string'); }",
|
||||
"pm.expect(json.style).to.eql('Sharqi');",
|
||||
@@ -1744,6 +1801,12 @@
|
||||
"pm.test('Status is 201', function () { pm.response.to.have.status(201); });",
|
||||
"const json = pm.response.json();",
|
||||
"pm.expect(json.postType).to.eql('audio');",
|
||||
"pm.expect(json.media.audioUrl).to.be.a('string');",
|
||||
"pm.expect(json.media.waveformPeaks).to.be.an('array');",
|
||||
"pm.expect(json.media.durationSeconds).to.exist;",
|
||||
"pm.expect(json.processingStatus).to.eql('ready');",
|
||||
"pm.expect(json.media).to.be.an('object');",
|
||||
"pm.expect(json.media.mediaType).to.eql(json.postType);",
|
||||
"pm.expect(json.waveformPeaks).to.be.an('array');",
|
||||
"pm.expect(json.waveformPeaks.length).to.eql(6);",
|
||||
"pm.expect(json.maqam).to.eql('Hijaz');",
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم