diff --git a/packages/app/src/components/PostCard/components/attachments/index.jsx b/packages/app/src/components/PostCard/components/attachments/index.jsx index 5f177d7a..47a04b0a 100755 --- a/packages/app/src/components/PostCard/components/attachments/index.jsx +++ b/packages/app/src/components/PostCard/components/attachments/index.jsx @@ -1,4 +1,5 @@ import React from "react" +import { Skeleton } from "antd" import loadable from "@loadable/component" import { Carousel } from "react-responsive-carousel" import Plyr from "plyr-react" @@ -28,96 +29,139 @@ import "react-responsive-carousel/lib/styles/carousel.min.css" import "plyr-react/dist/plyr.css" import "./index.less" -export default class PostAttachments extends React.PureComponent { - getAttachments = (data) => { - return data.map((addition, index) => { - if (typeof addition === "string") { - addition = { - url: addition, - } - } +const Attachment = React.memo((props) => { + const { url, id, name } = props.attachment - const { url, id, name } = addition + const [loaded, setLoaded] = React.useState(false) - const MediaRender = loadable(async () => { - let extension = null + const [mediaType, setMediaType] = React.useState(null) + const [mimeType, setMimeType] = React.useState(null) - try { - // get media type by parsing the url - const mediaTypeExt = /\.([a-zA-Z0-9]+)$/.exec(url) + const getMediaType = async () => { + let extension = null - if (mediaTypeExt) { - extension = mediaTypeExt[1] - } else { - // try to get media by creating requesting the url - const response = await fetch(url, { - method: "HEAD", - }) + // get media type by parsing the url + const mediaTypeExt = /\.([a-zA-Z0-9]+)$/.exec(url) - extension = response.headers.get("content-type").split("/")[1] - } - - extension = extension.toLowerCase() - - const mediaType = mediaTypes[extension] - const mimeType = `${mediaType}/${extension}` - - if (!mediaType) { - return () => - } - - switch (mediaType.split("/")[0]) { - case "image": { - return () => - } - case "video": { - return () => - } - case "audio": { - return () => - } - default: { - return () =>

- Unsupported media type [{mediaType}/{mediaTypeExt}] -

- } - } - } catch (error) { - console.error(error) - return () => - } + if (mediaTypeExt) { + extension = mediaTypeExt[1] + } else { + // try to get media by creating requesting the url + const response = await fetch(url, { + method: "HEAD", }) - return
- Loading
} > - - - - }) + extension = response.headers.get("content-type").split("/")[1] + } + + extension = extension.toLowerCase() + + const mediaType = mediaTypes[extension] + const mimeType = `${mediaType}/${extension}` + + setMediaType(mediaType) + setMimeType(mimeType) + + setLoaded(true) } - render() { - return
- 1 ?? false} - > - {this.getAttachments(this.props.attachments)} - -
+ const renderMedia = () => { + switch (mediaType.split("/")[0]) { + case "image": { + return + } + case "video": { + return + } + case "audio": { + return + } + default: { + return

+ Unsupported media type [{mediaType}/{mediaTypeExt}] +

+ } + } } + + React.useEffect(() => { + getMediaType() + }, []) + + if (!loaded) { + return + } + + if (loaded && !mediaType && !mimeType) { + return + } + + return
+ {renderMedia()} +
+}) + +export default (props) => { + const carouselRef = React.useRef(null) + const [attachmentIndex, setAttachmentIndex] = React.useState(0) + + const handleAttachmentChange = (index) => { + const currentAttachmentIndex = carouselRef.current.state.selectedItem + const currentAttachment = carouselRef.current.itemsRef[currentAttachmentIndex].querySelector("video, audio") + + if (currentAttachmentIndex !== index) { + // if the attachment is a video, pause it + if (currentAttachment) { + currentAttachment.pause() + } + } else { + // else if the attachment is a video, play it + if (currentAttachment) { + currentAttachment.play() + } + } + + setAttachmentIndex(index) + } + + React.useEffect(() => { + // get attachment index from query string + const attachmentIndex = parseInt(new URLSearchParams(window.location.search).get("attachment")) + + if (attachmentIndex) { + setAttachmentIndex(attachmentIndex) + } + }, []) + + return
+ 1 ?? false} + selectedItem={attachmentIndex} + onChange={handleAttachmentChange} + transitionTime={150} + stopOnHover={true} + > + { + props.attachments.map((attachment, index) => { + return + }) + } + +
} \ No newline at end of file diff --git a/packages/app/src/components/PostCard/components/attachments/index.less b/packages/app/src/components/PostCard/components/attachments/index.less index 03d1bf25..016f7112 100755 --- a/packages/app/src/components/PostCard/components/attachments/index.less +++ b/packages/app/src/components/PostCard/components/attachments/index.less @@ -19,8 +19,13 @@ width: 100%; .carousel { + display: flex; background-color: black; border-radius: 8px; + + .slider-wrapper { + align-self: center; + } } .control-prev, @@ -82,7 +87,7 @@ } } - .addition { + .attachment { width: 100%; height: 100%; diff --git a/packages/app/src/components/PostCard/components/content/index.jsx b/packages/app/src/components/PostCard/components/content/index.jsx index 6ff8ac2b..3a2ffc50 100755 --- a/packages/app/src/components/PostCard/components/content/index.jsx +++ b/packages/app/src/components/PostCard/components/content/index.jsx @@ -5,19 +5,13 @@ import classnames from "classnames" import { processString } from "utils" -import { Icons } from "components/Icons" - -import PostAttachments from "../attachments" - import "./index.less" -export default React.memo((props) => { - let { message, attachments, type, data, flags } = props.data +export default (props) => { + let { message, data } = props.data const [nsfwAccepted, setNsfwAccepted] = React.useState(false) - const isNSFW = flags?.includes("nsfw") - if (typeof data === "string") { try { data = JSON.parse(data) @@ -27,12 +21,6 @@ export default React.memo((props) => { } } - const onClickPlaylist = () => { - if (data.playlist) { - app.AudioPlayer.startPlaylist(data.playlist) - } - } - // parse message const regexs = [ { @@ -63,57 +51,17 @@ export default React.memo((props) => { message = processString(regexs)(message) - const renderContent = () => { - switch (type) { - case "playlist": { - return <> -
- -
-
-

- {data.title ?? "Untitled Playlist"} -

-

- {data.artist} -

-
- -

- {message} -

- -
- - - Play - -
-
- - } - default: { - return <> -
- {message} -
- - {attachments.length > 0 && } - - } - } - } - return
- {isNSFW && !nsfwAccepted && + {props.nsfw && !nsfwAccepted &&

This post may contain sensitive content. @@ -125,6 +73,12 @@ export default React.memo((props) => {

} - {renderContent()} +
+ {message} +
+ + { + props.children + }
-}) \ No newline at end of file +} \ No newline at end of file diff --git a/packages/app/src/components/PostCard/index.jsx b/packages/app/src/components/PostCard/index.jsx index 569b0c5d..a871ee4d 100755 --- a/packages/app/src/components/PostCard/index.jsx +++ b/packages/app/src/components/PostCard/index.jsx @@ -7,10 +7,11 @@ import { Icons } from "components/Icons" import PostHeader from "./components/header" import PostContent from "./components/content" import PostActions from "./components/actions" +import PostAttachments from "./components/attachments" import "./index.less" -export default React.memo(({ +export default ({ expansibleActions = window.app.settings.get("postCard_expansible_actions"), autoCarrousel = window.app.settings.get("postCard_carrusel_auto"), data = {}, @@ -160,7 +161,12 @@ export default React.memo(({ autoCarrousel={autoCarrousel} fullmode={fullmode} onDoubleClick={onDoubleClick} - /> + nsfw={data.flags && data.flags.includes("nsfw")} + > + {data.attachments && data.attachments.length > 0 && } +
{!fullmode &&
@@ -181,4 +187,4 @@ export default React.memo(({ /> }
-}) \ No newline at end of file +} \ No newline at end of file