commit 5f084492edc5b09534cbd09d04bfb0023357da43
parent e11757fd021a22f0e1796cd4624fc09c8fceeb90
Author: MTRNord <mtrnord1@gmail.com>
Date: Fri, 31 Dec 2021 13:37:35 +0100
Fix post rendering
Diffstat:
5 files changed, 90 insertions(+), 91 deletions(-)
diff --git a/helpers/matrix_client.ts b/helpers/matrix_client.ts
@@ -47,7 +47,11 @@ export default class MatrixClient {
async registerAsGuest(serverUrl: string) {
function generateToken(len: number) {
var arr = new Uint8Array(len / 2);
- window.crypto.getRandomValues(arr);
+ if (typeof window !== "undefined") {
+ window.crypto.getRandomValues(arr);
+ } else {
+ require("crypto").randomFillSync(arr);
+ }
return Array.from(arr, (num) => {
return num.toString(16).padStart(2, "0");
}).join("");
diff --git a/package-lock.json b/package-lock.json
@@ -23,6 +23,7 @@
"@types/pouchdb": "^6.4.0",
"@types/react": "17.0.38",
"autoprefixer": "^10.4.0",
+ "cross-env": "^7.0.3",
"eslint": "8.5.0",
"eslint-config-next": "12.0.7",
"postcss": "^8.4.5",
@@ -2608,6 +2609,24 @@
"sha.js": "^2.4.8"
}
},
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "bin": {
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -8980,6 +8999,15 @@
"sha.js": "^2.4.8"
}
},
+ "cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.1"
+ }
+ },
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
diff --git a/package.json b/package.json
@@ -2,6 +2,7 @@
"name": "matrix-art",
"private": true,
"scripts": {
+ "dev-inspect": "cross-env NODE_OPTIONS='--inspect' next dev",
"dev": "next dev",
"build": "next build",
"start": "next start",
@@ -26,10 +27,11 @@
"@types/pouchdb": "^6.4.0",
"@types/react": "17.0.38",
"autoprefixer": "^10.4.0",
+ "cross-env": "^7.0.3",
"eslint": "8.5.0",
"eslint-config-next": "12.0.7",
"postcss": "^8.4.5",
"tailwindcss": "^3.0.7",
"typescript": "4.5.4"
}
-}
+}
+\ No newline at end of file
diff --git a/pages/Home.tsx b/pages/Home.tsx
@@ -188,12 +188,13 @@ export default class Home extends Component<Props, State>{
render_image_box(thumbnail_url: string, id: string, post_id: string, sender: string, caption: string) {
// TODO show creators display name instead of mxid and show avatar image
+ // TODO proper alt text
const direct_link = `/post/${encodeURIComponent(post_id)}`;
return (
<li className='h-[270px]' key={id}>
- <Link href={direct_link}>
+ <Link href={direct_link} passHref>
<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>
+ <img alt={caption} title={caption} 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] 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>
@@ -215,4 +216,9 @@ export function isImageGalleryEvent(event: ImageEvents): event is ImageGalleryEv
export function isImageEvent(event: ImageEvents): event is ImageEvent {
return event.type === "m.image" && event.redacted_because === undefined;
+};
+
+export const getServerSideProps = async (context: any) => {
+ console.log("getServerSideProps");
+ return { props: {} };
};
\ No newline at end of file
diff --git a/pages/post/[id].tsx b/pages/post/[id].tsx
@@ -1,3 +1,4 @@
+import { GetServerSidePropsContext, InferGetServerSidePropsType } from "next";
import Head from "next/head";
import { NextRouter, withRouter } from "next/router";
import { Component, ReactNode } from "react";
@@ -5,7 +6,8 @@ import { RingLoader } from "react-spinners";
import { ClientContext } from "../../components/ClientContext";
import Header from "../../components/Header";
import { ImageEvent, ImageGalleryEvent, MatrixEventBase, MatrixImageEvents } from "../../helpers/event_types";
-import { constMatrixArtServer } from "../../helpers/matrix_client";
+import MatrixClient, { constMatrixArtServer } from "../../helpers/matrix_client";
+import Storage from "../../helpers/storage";
import { get_data } from "../api/directory";
import { isImageEvent, isImageGalleryEvent } from "../Home";
@@ -16,16 +18,13 @@ const centerSpinner = `
transform: translate(-50%, -50%);
`;
-interface Props {
+type Props = InferGetServerSidePropsType<typeof getServerSideProps> & {
router: NextRouter;
-}
+};
type State = {
- directory_data: { _id: string; user_id: string; user_room: string; }[];
- event_id?: string;
hasFullyLoaded: boolean;
isLoadingImages: boolean;
- directoryIsLoaded: boolean;
image_event: MatrixImageEvents;
error?: any;
};
@@ -38,87 +37,13 @@ class Post extends Component<Props, State> {
this.state = {
hasFullyLoaded: false,
- directoryIsLoaded: false,
isLoadingImages: false
} as State;
}
- async componentDidUpdate() {
- if (this.state.event_id && this.state.event_id.startsWith("$")) {
- await this.loadEvent(this.state.event_id);
- }
- }
-
- async getStaticPaths() {
- const directory_data = await get_data();
- let paths: { params: { id: string; }; }[] = [];
- for (let user of directory_data) {
- // We dont need many events
- const roomId = await this.context.client?.followUser(user.user_room);
- await this.context.client?.getTimeline(roomId, 100, (events) => {
- // Filter events by type
- const image_events = events.filter((event) => event.type == "m.image_gallery" || event.type == "m.image");
- for (let event of image_events) {
- const path_non_encoded = { params: { id: event.event_id } };
- const path = { params: { id: encodeURIComponent(event.event_id) } };
- paths.push(path);
- }
- });
- }
- return {
- paths: paths,
- fallback: 'blocking'
- };
- }
-
-
async componentDidMount() {
- const { id } = this.props.router.query;
- console.log(`id: ${id}`);
- console.log(`is ready: ${this.props.router.isReady}`);
- const event_id = decodeURIComponent(id as string);
-
- if (event_id && event_id.startsWith("$")) {
- // auto-register as a guest if not logged in
- if (!this.context.client?.accessToken) {
- this.registerAsGuest();
- } else {
- console.log("Already logged in");
- try {
- const data = await (await fetch('/api/directory')).json();
- this.setState({ event_id: event_id, directory_data: data.data, directoryIsLoaded: true });
- } catch (error) {
- this.setState({
- hasFullyLoaded: true,
- error
- });
- }
- }
- }
- }
-
- async componentWillUnmount() {
- const { id } = this.props.router.query;
- console.log(`id: ${id}`);
- console.log(`is ready: ${this.props.router.isReady}`);
- const event_id = decodeURIComponent(id as string);
-
- if (event_id && event_id.startsWith("$")) {
- // auto-register as a guest if not logged in
- if (!this.context.client?.accessToken) {
- this.registerAsGuest();
- } else {
- console.log("Already logged in");
- try {
- const data = await (await fetch('/api/directory')).json();
- this.setState({ event_id: event_id, directory_data: data.data, directoryIsLoaded: true });
- } catch (error) {
- this.setState({
- hasFullyLoaded: true,
- error
- });
- }
- }
+ if (this.props.directory_data && this.props.event_id && this.props.event_id.startsWith("$")) {
+ await this.loadEvent(this.props.event_id);
}
}
@@ -138,8 +63,8 @@ class Post extends Component<Props, State> {
}
async loadEvent(event_id: string) {
- const { directoryIsLoaded, directory_data, hasFullyLoaded, isLoadingImages } = this.state;
- if (!directoryIsLoaded || isLoadingImages || hasFullyLoaded) {
+ const { hasFullyLoaded, isLoadingImages } = this.state;
+ if (isLoadingImages || hasFullyLoaded || !this.props.directory_data) {
return;
}
this.setState({
@@ -147,7 +72,7 @@ class Post extends Component<Props, State> {
});
try {
// TODO fix this. It is super inefficent.
- for (let user of directory_data) {
+ for (let user of this.props.directory_data) {
// We dont need many events
const roomId = await this.context.client?.followUser(user.user_room);
await this.context.client?.getTimeline(roomId, 100, (events) => {
@@ -171,7 +96,7 @@ class Post extends Component<Props, State> {
}
render() {
- const { error, event_id, hasFullyLoaded, image_event } = this.state;
+ const { error, hasFullyLoaded, image_event } = this.state;
if (!hasFullyLoaded) {
return (
@@ -183,7 +108,7 @@ class Post extends Component<Props, State> {
);
}
- if (!event_id || !event_id?.startsWith("$")) {
+ if (!this.props.event_id || !this.props.event_id?.startsWith("$")) {
return (
<div className="h-full bg-[#fefefe]/[.95] dark:bg-[#14181E]/[.95]">
<Head>
@@ -295,4 +220,37 @@ class Post extends Component<Props, State> {
}
Post.contextType = ClientContext;
+
+export const getServerSideProps = async (context: GetServerSidePropsContext) => {
+ const { query } = context;
+ const event_id = decodeURIComponent(query.id as string);
+
+ if (event_id && event_id.startsWith("$")) {
+ // auto-register as a guest if not logged in
+ const client = new MatrixClient(new Storage());
+ if (!client.accessToken) {
+ try {
+ let serverUrl = constMatrixArtServer + "/_matrix/client";
+ await client.registerAsGuest(serverUrl);
+ } catch (err) {
+ console.error("Failed to register as guest:", err);
+ }
+ } else {
+ console.log("Already logged in");
+ }
+ try {
+ const data = await get_data();
+
+ return {
+ props: {
+ directory_data: data, event_id: event_id
+ }
+ };
+ } catch (error) {
+ return { notFound: true, props: {} };
+ }
+ }
+ return { notFound: true, props: {} };
+
+};
export default withRouter(Post);
\ No newline at end of file