@@ -189,8 +189,8 @@ function formatTime(time: number): string {
}
function getDimensions(info: { width?: number, height?: number }, bounding?: { width?: number, height?: number }) {
- let height = Math.max(info.height || bounding?.height || 300, 100);
- let width = Math.max(info.width || bounding?.width || 300, 100);
+ let height = Math.max(info.height || bounding?.height || 300, 10);
+ let width = Math.max(info.width || bounding?.width || 300, 10);
if (bounding?.height) {
const newHeight = Math.min(height, bounding.height);
@@ -199,7 +199,7 @@ function getDimensions(info: { width?: number, height?: number }, bounding?: { w
}
if (bounding?.width) {
- const newWidth = Math.min(width, 300);
+ const newWidth = Math.min(width, bounding.width);
height *= newWidth / width;
width = newWidth;
}
diff --git a/src/Menu.tsx b/src/Menu.tsx
index d60814f..7ef2956 100644
--- a/src/Menu.tsx
+++ b/src/Menu.tsx
@@ -86,8 +86,9 @@ export function SpaceMenu(props: VoidProps<{ room: Room }>) {
// the context menu for rooms
export function RoomMenu(props: VoidProps<{ room: Room }>) {
+ const [_globals, action] = useGlobals();
const copyId = () => navigator.clipboard.writeText(props.room.id);
- const edit = () => location.hash = `#/rooms/${props.room.id}/settings`;
+ const edit = () => action({ type: "scene.set", scene: { type: "config-room", room: props.room, sub: "general" }});
const leave = () => {
if (confirm("really leave?")) props.room.leave();
};
diff --git a/src/Message.tsx b/src/Message.tsx
index c242ad9..47a97e7 100644
--- a/src/Message.tsx
+++ b/src/Message.tsx
@@ -82,14 +82,14 @@ export function TextBlock(props: VoidProps<{ text: any, formatting?: boolean, fa
}
const text = props.text.find((i: any) => !i.type || i.type === "text/plain")?.body;
- if (text) return escape(text);
+ if (text) return `
${escape(text)}
`;
return "";
}
// for portability, it might be better to add a custom renderer instead of using html
return (
-
+
);
}
diff --git a/src/Room.tsx b/src/Room.tsx
index 622aee5..a1e42e0 100644
--- a/src/Room.tsx
+++ b/src/Room.tsx
@@ -5,7 +5,6 @@ import { Dropdown, Text, Time } from "./Atoms";
import { ThreadTimeline } from "sdk/dist/src/timeline";
import { shouldSplit } from "./util";
import { Message, TextBlock } from "./Message";
-import { A, useNavigate } from "@solidjs/router";
import { SetStoreFunction, createStore } from "solid-js/store";
import "./Room.scss";
import { EVENT_TYPE_THREAD_CHAT } from "./consts";
@@ -71,6 +70,7 @@ function RoomActions(props: VoidProps<{ room: Room }>) {
}
function RoomHeader(props: VoidProps<{ room: Room }>) {
+ const [_globals, action] = useGlobals();
const name = () => props.room.getState("m.room.name")?.content.name || "unnamed room";
const topic = () => props.room.getState("m.room.topic")?.content.topic || "";
@@ -79,14 +79,17 @@ function RoomHeader(props: VoidProps<{ room: Room }>) {
if (uid) props.room.client.net.roomInvite(props.room.id, uid);
}
- const navigate = useNavigate();
+ function openSettings() {
+ action({ type: "scene.set", scene: { type: "config-room", room: props.room, sub: "general" } });
+ }
+
return (
room.welcome
room.topic
Debug: room_id={props.room.id}
-
+
@@ -346,7 +349,7 @@ export function Inbox() {
thread.unnamed} />
- e.stopPropagation()} target="_self">{thread.baseEvent.room.getState("m.room.name")?.content.name || thread.baseEvent.room.id}
+ e.stopPropagation()} target="_self">{thread.baseEvent.room.getState("m.room.name")?.content.name || thread.baseEvent.room.id}
|
}
diff --git a/src/RoomSettings.tsx b/src/RoomSettings.tsx
index 532d7d5..9fbff86 100644
--- a/src/RoomSettings.tsx
+++ b/src/RoomSettings.tsx
@@ -1,6 +1,5 @@
import { For, Match, Switch, VoidProps, createEffect, createSignal, lazy, onCleanup } from "solid-js";
import { Dropdown } from "./Atoms";
-import { A, useParams } from "@solidjs/router";
import "./RoomSettings.scss";
import { createForm } from "@modular-forms/solid";
import { useGlobals } from "./Context";
@@ -9,64 +8,51 @@ import { ROOM_TYPE_SPACE } from "./consts";
import { createStore, unwrap } from "solid-js/store";
const Editor = lazy(() => import("./Editor"));
-export default function RoomSettings() {
- const tabs = ["general", "permissions", "security", "integrations", "members", "rooms"];
- const [selected, setSelected] = createSignal("general");
- const params = useParams();
- const [globals] = useGlobals();
- const [room, setRoom] = createSignal(globals.client.rooms.get(params.roomId));
-
- const resetRoom = () => {
- setRoom(globals.client.rooms.get(params.roomId));
- };
-
- globals.client.on("roomInit", resetRoom);
- onCleanup(() => globals.client.off("roomInit", resetRoom));
+export default function RoomSettings(props: { room: Room }) {
+ const tabs = ["general", "permissions", "security", "integrations", "members", ...props.room.getState("m.room.create")?.content.type === ROOM_TYPE_SPACE ? ["rooms"] : []];
+ const [globals, action] = useGlobals();
+ if (globals.scene.type !== "config-room") throw new Error("unreachable");
return (
-
-
+
+
-
+
-
-
+
+
-
+
integrations
bridges
bots
-
-
+
+
-
+
room list
-
+
{(ev) => - {ev.stateKey}: {JSON.stringify(ev.content)}
}
-
- room list
- this only should exist in spaces
-
diff --git a/src/Thread.scss b/src/Thread.scss
index 1b70da7..9de3a8b 100644
--- a/src/Thread.scss
+++ b/src/Thread.scss
@@ -75,6 +75,11 @@
& > .header {
display: contents;
+ & > .spacer {
+ min-height: 100px;
+ flex: 1;
+ }
+
& > header {
display: contents;
@@ -93,6 +98,9 @@
transition: all .2s;
flex: 1;
margin: 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
&.stuck {
diff --git a/src/Thread.tsx b/src/Thread.tsx
index 91703f1..527369a 100644
--- a/src/Thread.tsx
+++ b/src/Thread.tsx
@@ -13,7 +13,6 @@ import "./Thread.scss";
import { createProgress, delay, shouldSplit } from "./util";
import { createStore, reconcile } from "solid-js/store";
import { classList } from "solid-js/web";
-import { action } from "@solidjs/router";
import { useFloating } from "solid-floating-ui";
const Editor = lazy(() => import("./Editor"));
@@ -49,15 +48,15 @@ function createTimeline(timelineSet: Accessor) {
function updateItems() {
const { start, end } = info()!;
const items: Array = [];
- if (!isAtBeginning()) {
- items.push({ type: "spacer", key: "space-begin" });
- }
items.push({
type: "info",
- key: "info",
+ key: "info" + isAtBeginning(),
header: isAtBeginning(),
class: "header",
});
+ if (!isAtBeginning()) {
+ items.push({ type: "spacer", key: "space-begin" });
+ }
const events = timeline().getEvents();
const lastAck = timelineSet()?.thread.unreads?.last_ack;
for (let i = start; i < end; i++) {
@@ -143,7 +142,7 @@ function createTimeline(timelineSet: Accessor) {
// async function append(_event: Event) {
async function append() {
- console.log("append", { status: status(), auto: isAutoscrolling() });
+ console.log("append", { status: status(), auto: isAutoscrolling(), timeline: timeline() });
if (status() !== "ready") return;
if (!isAutoscrolling()) return;
@@ -237,52 +236,15 @@ function createList(options: {
});
function setRefs() {
+ // console.log("set refs", {
+ // topPos: options.topPos?.() ?? 0,
+ // bottomPos: options.bottomPos?.() ?? options.items().length - 1,
+ // });
const children = [...wrapperEl()?.children ?? []] as Array;
- console.log(wrapperEl(), children);
setTopEl(children[options.topPos?.() ?? 0]);
setBottomEl(children[options.bottomPos?.() ?? options.items().length - 1]);
}
- createEffect(on(options.items, () => {
- console.log("updating!", { topRef, bottomRef });
- if (!topRef || !bottomRef) {
- setRefs();
- return;
- }
- if (shouldAutoscroll) {
- console.log("will scroll now!");
- wrapperEl()!.scrollBy({ top: 999999, behavior: "instant" });
- } else if (wrapperEl()?.contains(topRef)) {
- const newOffsetTop = topRef.offsetTop;
- const newOffsetHeight = topRef.offsetHeight;
- wrapperEl()?.scrollBy(0, (newOffsetTop - topOffset!) - (topHeight! - newOffsetHeight));
- } else if (wrapperEl()?.contains(bottomRef)) {
- const newOffsetBottom = bottomRef.offsetTop;
- const newOffsetHeight = bottomRef.offsetHeight;
- console.log({ bottomRef, bottomOffset, newOffsetBottom, bottomHeight, newOffsetHeight, diff: (newOffsetBottom - bottomOffset!) - (bottomHeight! - newOffsetHeight), scrollTop: wrapperEl()?.scrollTop });
- wrapperEl()?.scrollBy(0, (newOffsetBottom - bottomOffset!) - (bottomHeight! - newOffsetHeight));
- }
- setRefs();
- }));
-
- createEffect(on(topEl, (topEl) => {
- if (!topEl) return;
- if (topRef) observer.unobserve(topRef);
- topOffset = topEl.offsetTop;
- topHeight = topEl.offsetHeight;
- topRef = topEl;
- observer.observe(topEl);
- }));
-
- createEffect(on(bottomEl, (bottomEl) => {
- if (!bottomEl) return;
- if (bottomRef) observer.unobserve(bottomRef);
- bottomOffset = bottomEl.offsetTop;
- bottomHeight = bottomEl.offsetHeight;
- bottomRef = bottomEl;
- observer.observe(bottomEl);
- }));
-
onCleanup(() => {
observer.disconnect();
});
@@ -301,12 +263,46 @@ function createList(options: {
});
},
List(props: { children: (item: T, idx: Accessor) => JSX.Element }) {
- onMount(() => {
- console.log("mounted");
- console.log(wrapperEl());
- console.log(wrapperEl()?.children);
- console.log(options.items());
- });
+ createEffect(on(options.items, () => {
+ queueMicrotask(() => {
+ if (!topRef || !bottomRef) {
+ setRefs();
+ return;
+ }
+ if (shouldAutoscroll) {
+ console.log("will scroll now!");
+ wrapperEl()!.scrollBy({ top: 999999, behavior: "instant" });
+ } else if (wrapperEl()?.contains(topRef)) {
+ const newOffsetTop = topRef.offsetTop;
+ const newOffsetHeight = topRef.offsetHeight;
+ wrapperEl()?.scrollBy(0, (newOffsetTop - topOffset!) - (topHeight! - newOffsetHeight));
+ } else if (wrapperEl()?.contains(bottomRef)) {
+ const newOffsetBottom = bottomRef.offsetTop;
+ const newOffsetHeight = bottomRef.offsetHeight;
+ console.log({ bottomRef, bottomOffset, newOffsetBottom, bottomHeight, newOffsetHeight, diff: (newOffsetBottom - bottomOffset!) - (bottomHeight! - newOffsetHeight), scrollTop: wrapperEl()?.scrollTop });
+ wrapperEl()?.scrollBy(0, (newOffsetBottom - bottomOffset!) - (bottomHeight! - newOffsetHeight));
+ }
+ setRefs();
+ });
+ }));
+
+ createEffect(on(topEl, (topEl) => {
+ if (!topEl) return;
+ if (topRef) observer.unobserve(topRef);
+ topOffset = topEl.offsetTop;
+ topHeight = topEl.offsetHeight;
+ topRef = topEl;
+ observer.observe(topEl);
+ }));
+
+ createEffect(on(bottomEl, (bottomEl) => {
+ if (!bottomEl) return;
+ if (bottomRef) observer.unobserve(bottomRef);
+ bottomOffset = bottomEl.offsetTop;
+ bottomHeight = bottomEl.offsetHeight;
+ bottomRef = bottomEl;
+ observer.observe(bottomEl);
+ }));
return (