diff --git a/net/server/transform/transform_acopy.sh b/net/server/transform/transform_acopy.sh
new file mode 100755
index 00000000..7c696e83
--- /dev/null
+++ b/net/server/transform/transform_acopy.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+#ffmpeg -i $1 -y -f mp4 -map_metadata -1 -c:v copy -c:a copy $2
+#ffmpeg -f mp4 -i color=c=black:s=1280x720:r=5 -i $1 -crf 0 -c:a copy -shortest $2
+ffmpeg -i $1 -y -f mp3 -map_metadata -1 -c:a copy $2
diff --git a/net/server/transform/transform_icopy.sh b/net/server/transform/transform_icopy.sh
new file mode 100755
index 00000000..ac13f2aa
--- /dev/null
+++ b/net/server/transform/transform_icopy.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+convert -strip $1 -auto-orient $2
+
diff --git a/net/server/transform/transform_ithumb.sh b/net/server/transform/transform_ithumb.sh
new file mode 100755
index 00000000..51561afd
--- /dev/null
+++ b/net/server/transform/transform_ithumb.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+convert -strip $1 -auto-orient -resize '640x640>' $2
+
diff --git a/net/server/transform/transform_vcopy.sh b/net/server/transform/transform_vcopy.sh
new file mode 100755
index 00000000..b71c4c33
--- /dev/null
+++ b/net/server/transform/transform_vcopy.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+ffmpeg -i $1 -y -f mp4 -map_metadata -1 -c:v copy -c:a copy $2
+
diff --git a/net/server/transform/transform_vthumb.sh b/net/server/transform/transform_vthumb.sh
new file mode 100755
index 00000000..b7930c9a
--- /dev/null
+++ b/net/server/transform/transform_vthumb.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+TMPFILE=$(mktemp /tmp/databag-XXXXX)
+ffmpeg -ss 0 -i $1 -y -vframes 1 -q:v 2 $TMPFILE.jpg
+convert -strip $TMPFILE.jpg -auto-orient -resize '640x640>' $2
diff --git a/net/web/src/Carousel/Carousel.jsx b/net/web/src/Carousel/Carousel.jsx
index e3f74df7..fa736147 100644
--- a/net/web/src/Carousel/Carousel.jsx
+++ b/net/web/src/Carousel/Carousel.jsx
@@ -130,8 +130,8 @@ export function Carousel({ ready, items, itemRenderer, itemRemove }) {
)
@@ -144,8 +144,8 @@ export function Carousel({ ready, items, itemRenderer, itemRemove }) {
{slots}
);
diff --git a/net/web/src/User/Conversation/TopicItem/AudioAsset/AudioAsset.jsx b/net/web/src/User/Conversation/TopicItem/AudioAsset/AudioAsset.jsx
new file mode 100644
index 00000000..163ee7cb
--- /dev/null
+++ b/net/web/src/User/Conversation/TopicItem/AudioAsset/AudioAsset.jsx
@@ -0,0 +1,8 @@
+import React, { useEffect, useState } from 'react';
+import ReactPlayer from 'react-player'
+
+export function AudioAsset({ label, audioUrl }) {
+
+ return
+}
+
diff --git a/net/web/src/User/Conversation/TopicItem/TopicItem.jsx b/net/web/src/User/Conversation/TopicItem/TopicItem.jsx
index e1aa8d3e..9589c19b 100644
--- a/net/web/src/User/Conversation/TopicItem/TopicItem.jsx
+++ b/net/web/src/User/Conversation/TopicItem/TopicItem.jsx
@@ -1,8 +1,8 @@
import React, { useEffect, useState } from 'react';
-import ReactPlayer from 'react-player'
import { TopicItemWrapper } from './TopicItem.styled';
-import ReactResizeDetector from 'react-resize-detector';
import { useTopicItem } from './useTopicItem.hook';
+import { VideoAsset } from './VideoAsset/VideoAsset';
+import { AudioAsset } from './AudioAsset/AudioAsset';
import { Avatar } from 'avatar/Avatar';
import { CommentOutlined } from '@ant-design/icons';
import { Carousel } from 'Carousel/Carousel';
@@ -18,13 +18,16 @@ export function TopicItem({ topic }) {
const renderAsset = (asset) => {
if (asset.image) {
- return
+ if (asset.image.thumb) {
+ return
+ }
+ return
}
if (asset.video) {
- return
+ return
}
if (asset.audio) {
- return
+ return
}
return <>>
}
diff --git a/net/web/src/User/Conversation/TopicItem/VideoAsset/VideoAsset.jsx b/net/web/src/User/Conversation/TopicItem/VideoAsset/VideoAsset.jsx
new file mode 100644
index 00000000..c9c3c371
--- /dev/null
+++ b/net/web/src/User/Conversation/TopicItem/VideoAsset/VideoAsset.jsx
@@ -0,0 +1,57 @@
+import React, { useEffect, useState } from 'react';
+import { Button } from 'antd';
+import ReactPlayer from 'react-player'
+import ReactResizeDetector from 'react-resize-detector';
+import { PlayCircleOutlined } from '@ant-design/icons';
+import { VideoAssetWrapper } from './VideoAsset.styled';
+
+export function VideoAsset({ thumbUrl, videoUrl }) {
+
+ const [active, setActive] = useState(false);
+ const [dimension, setDimension] = useState({});
+ const [visibility, setVisibility] = useState('hidden');
+ const [playing, setPlaying] = useState(false);
+
+ useEffect(() => {
+ setActive(false);
+ setVisibility('hidden');
+ setPlaying(false);
+ }, [thumbUrl, videoUrl]);
+
+ const onReady = () => {
+ setVisibility('visible');
+ setPlaying(true);
+ }
+
+ if (!thumbUrl) {
+ return
+ }
+
+ const Player = () => {
+ if (!active) {
+ return (
+
+ )
+ }
+ return
+ }
+
+ return (
+
+
+ {({ width, height }) => {
+ if (width != dimension.width || height != dimension.height) {
+ setDimension({ width, height });
+ }
+ return
+ }}
+
+
+
+ )
+}
+
diff --git a/net/web/src/User/Conversation/TopicItem/VideoAsset/VideoAsset.styled.js b/net/web/src/User/Conversation/TopicItem/VideoAsset/VideoAsset.styled.js
new file mode 100644
index 00000000..3afbc638
--- /dev/null
+++ b/net/web/src/User/Conversation/TopicItem/VideoAsset/VideoAsset.styled.js
@@ -0,0 +1,16 @@
+import styled from 'styled-components';
+
+export const VideoAssetWrapper = styled.div`
+ position: relative;
+ height: 100%;
+
+ .player {
+ top: 0;
+ position: absolute;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+`;
+
+
diff --git a/net/web/src/api/addChannelTopic.js b/net/web/src/api/addChannelTopic.js
index 5754f031..50ee1faa 100644
--- a/net/web/src/api/addChannelTopic.js
+++ b/net/web/src/api/addChannelTopic.js
@@ -38,12 +38,13 @@ export async function addChannelTopic(token, channelId, message, assets ) {
else if (asset.video) {
const formData = new FormData();
formData.append('asset', asset.video);
- let transform = encodeURIComponent(JSON.stringify(["vcopy;video"]));
+ let transform = encodeURIComponent(JSON.stringify(["vcopy;video", 'vthumb;video']));
let topicAsset = await fetch(`/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&agent=${token}`, { method: 'POST', body: formData });
checkResponse(topicAsset);
let assetEntry = await topicAsset.json();
message.assets.push({
video: {
+ thumb: assetEntry.find(item => item.transform === 'vthumb;video').assetId,
full: assetEntry.find(item => item.transform === 'vcopy;video').assetId,
}
});
diff --git a/net/web/src/api/addContactChannelTopic.js b/net/web/src/api/addContactChannelTopic.js
index 6d0911fc..ffdcdb54 100644
--- a/net/web/src/api/addContactChannelTopic.js
+++ b/net/web/src/api/addContactChannelTopic.js
@@ -39,12 +39,13 @@ export async function addContactChannelTopic(server, token, channelId, message,
else if (asset.video) {
const formData = new FormData();
formData.append('asset', asset.video);
- let transform = encodeURIComponent(JSON.stringify(["vcopy;video"]));
+ let transform = encodeURIComponent(JSON.stringify(["vcopy;video", "vthumb;video"]));
let topicAsset = await fetch(`https://${server}/content/channels/${channelId}/topics/${slot.id}/assets?transforms=${transform}&contact=${token}`, { method: 'POST', body: formData });
checkResponse(topicAsset);
let assetEntry = await topicAsset.json();
message.assets.push({
video: {
+ thumb: assetEntry.find(item => item.transform === 'vthumb;video').assetId,
full: assetEntry.find(item => item.transform === 'vcopy;video').assetId,
}
});