matrix-art

An image gallery for Matrix
git clone git://archive.git.mtrnord.blog/MTRNord/matrix-art.git
Log | Files | Refs | README | LICENSE

commit fc070aacff8175dfb1a5728a44b440f98ae95245
parent a0073520199984f9bf7d23db698e8539a909bae0
Author: MTRNord <mtrnord1@gmail.com>
Date:   Fri, 31 Dec 2021 03:50:18 +0100

Add basic post displaying

Diffstat:
Mhelpers/matrix_client.ts | 6+++---
Mpages/Home.tsx | 10+++++-----
Mpages/post/[id].tsx | 56+++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/helpers/matrix_client.ts b/helpers/matrix_client.ts @@ -210,12 +210,12 @@ export default class MatrixClient { return userId.split(":")[0].substr(1); } - downloadLink(mxcUri: string) { + downloadLink(mxcUri: string): string | null { if (!mxcUri) { - return; + return null; } if (mxcUri.indexOf("mxc://") !== 0) { - return; + return null; } const mediaUrl = this.serverUrl?.slice(0, -1 * "/client".length); return mediaUrl + "/media/r0/download/" + mxcUri.split("mxc://")[1]; diff --git a/pages/Home.tsx b/pages/Home.tsx @@ -145,7 +145,7 @@ export default class Home extends Component<Props, State>{ <div className='m-10'> <ul className='flex flex-wrap gap-1'> {image_events.map(event => isImageGalleryEvent(event) ? this.render_gallery(event) : isImageEvent(event) ? this.render_image(event) : <div key={(event as MatrixEventBase).event_id}></div>)} - <li className='flex-grow-10'></li> + <li className='grow-[10]'></li> </ul> </div> @@ -189,11 +189,11 @@ export default class Home extends Component<Props, State>{ // TODO show creators display name instead of mxid and show avatar image const direct_link = `/post/${encodeURIComponent(post_id)}`; return ( - <li className='flex-grow-1 h-[270px]' key={id}> + <li className='h-[270px]' key={id}> <Link href={direct_link}> <div className='relative h-[270px] cursor-pointer'> <img className='relative max-w-full h-[270px] object-cover align-bottom z-0' src={this.context.client?.thumbnailLink(thumbnail_url, "scale", 270, 270)}></img> - <div className="flex-col max-w-full h-[270px] object-cover opacity-0 hover:opacity-100 duration-300 absolute bg-gradient-to-b from-transparent to-black/[.25] inset-0 z-10 flex justify-end items-start text-white p-4"> + <div className="flex-col max-w-full h-[270px] opacity-0 hover:opacity-100 duration-300 absolute bg-gradient-to-b from-transparent to-black/[.25] inset-0 z-10 flex justify-end items-start text-white p-4"> <h2 className='truncate max-w-full text-base font-semibold'>{caption}</h2> <p className='truncate max-w-full text-sm'>{sender}</p> </div> @@ -207,11 +207,11 @@ export default class Home extends Component<Props, State>{ Home.contextType = ClientContext; // TODO also render the edits properly later on -function isImageGalleryEvent(event: ImageEvents): event is ImageGalleryEvent { +export function isImageGalleryEvent(event: ImageEvents): event is ImageGalleryEvent { return event.type === "m.image_gallery" && event.redacted_because === undefined; } -function isImageEvent(event: ImageEvents): event is ImageEvent { +export function isImageEvent(event: ImageEvents): event is ImageEvent { return event.type === "m.image" && event.redacted_because === undefined; }; \ No newline at end of file diff --git a/pages/post/[id].tsx b/pages/post/[id].tsx @@ -4,8 +4,9 @@ import { Component, ReactNode } from "react"; import { RingLoader } from "react-spinners"; import { ClientContext } from "../../components/ClientContext"; import Header from "../../components/Header"; -import { MatrixImageEvents } from "../../helpers/event_types"; +import { ImageEvent, ImageGalleryEvent, MatrixEventBase, MatrixImageEvents } from "../../helpers/event_types"; import Client, { constMatrixArtServer } from "../../helpers/matrix_client"; +import { isImageEvent, isImageGalleryEvent } from "../Home"; const centerSpinner = ` position: fixed; @@ -15,7 +16,6 @@ const centerSpinner = ` `; interface Props { - client: Client | undefined; router: NextRouter; } @@ -132,7 +132,7 @@ class Post extends Component<Props, State> { } render() { - const { error, event_id, hasFullyLoaded } = this.state; + const { error, event_id, hasFullyLoaded, image_event } = this.state; if (!hasFullyLoaded) { return ( @@ -158,8 +158,15 @@ class Post extends Component<Props, State> { ); } - if (hasFullyLoaded) { - const post_title = ""; + if (hasFullyLoaded && image_event) { + let post_title = ""; + const caption = image_event.content['m.caption'].filter((cap) => { + const possible_html_caption = (cap as { body: string; mimetype: string; }); + return possible_html_caption.body !== undefined && possible_html_caption.mimetype === "text/html"; + }); + if (caption.length != 0) { + post_title = (caption[0] as { body: string; mimetype: string; }).body; + } return ( <div className="h-full bg-[#fefefe]/[.95] dark:bg-[#14181E]/[.95]"> <Head> @@ -167,8 +174,12 @@ class Post extends Component<Props, State> { </Head> <Header></Header> - <main className='lg:pt-[108px] pt-[216px] z-0'> - + <main className='flex-col h-full flex lg:pt-[108px] pt-[216px] z-0'> + {isImageGalleryEvent(image_event) ? this.renderImageGalleryEvent(image_event) : isImageEvent(image_event) ? this.renderSingleImageEvent(image_event) : <div key={(image_event as MatrixEventBase).event_id}></div>} + <div className="grow bg-[#f8f8f8] dark:bg-[#06070D]"> + <h1 className="mx-16 my-4 text-6xl text-gray-900 dark:text-gray-200 font-bold">{post_title}</h1> + <h3 className="mx-16 my-4 text-l text-gray-900 dark:text-gray-200 font-normal">{image_event.sender}</h3> + </div> </main> </div> ); @@ -177,9 +188,40 @@ class Post extends Component<Props, State> { <div>Error: {error.message}</div> ); } else { + return ( + <div className="h-full bg-[#fefefe]/[.95] dark:bg-[#14181E]/[.95]"> + <Head> + <title key="title">Matrix Art | Post not Found</title> + </Head> + <Header></Header> + <main className='h-full lg:pt-[108px] pt-[216px] z-0 flex items-center justify-center'> + <h1 className="text-6xl text-gray-900 dark:text-gray-200 font-bold">The Post you wanted does not exist!</h1> + </main> + </div> + ); + } + + } + + renderSingleImageEvent(imageEvent: ImageEvent) { + const url = this.context.client?.downloadLink(imageEvent.content["m.file"].url); + + if (!url) { return <></>; } + return this.renderImage(imageEvent.event_id, url); + } + + renderImageGalleryEvent(imageEvent: ImageGalleryEvent) { + return <div></div>; + } + renderImage(id: string, src: string) { + return ( + <div className="flex justify-center p-10"> + <img className="shadow-2xl max-w-3xl shadow-black" src={src} key={id}></img> + </div> + ); } }