random fixes
This commit is contained in:
parent
13f1a4cdec
commit
eeedc4a6ee
6 changed files with 141 additions and 59 deletions
|
@ -136,8 +136,13 @@ export default function App(): JSX.Element {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<header id="header">
|
<header id="header" style="display:flex">
|
||||||
header: settings, pinned, search, info, help
|
<div style="flex:1">
|
||||||
|
[room name] [room topic]
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
[voice] [settings] [info/pins] [search] [user] [help]
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main id="main" class={globals.scene.type === "home" ? "home" : "room"}>
|
<main id="main" class={globals.scene.type === "home" ? "home" : "room"}>
|
||||||
<Switch>
|
<Switch>
|
||||||
|
|
|
@ -27,12 +27,12 @@ menu.context {
|
||||||
|
|
||||||
&.submenu {
|
&.submenu {
|
||||||
& > .subwrap {
|
& > .subwrap {
|
||||||
padding-left: 8px;
|
padding: 0 8px;
|
||||||
display: none;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover > .subwrap, & > .subwrap:hover {
|
&:hover > .subwrap, & > .subwrap:hover {
|
||||||
display: block;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,3 +41,9 @@ menu.context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.subtext {
|
||||||
|
color: var(--foreground-2);
|
||||||
|
font-size: .9rem;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
|
163
src/Menu.tsx
163
src/Menu.tsx
|
@ -55,34 +55,31 @@ export function Separator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// the context menu for spaces (currently identical to rooms)
|
// the context menu for spaces (currently identical to rooms)
|
||||||
export function SpaceMenu(props: VoidProps<{ room: Room }>) {
|
// export function SpaceMenu(props: VoidProps<{ room: Room }>) {
|
||||||
const copyId = () => navigator.clipboard.writeText(props.room.id);
|
// const copyId = () => navigator.clipboard.writeText(props.room.id);
|
||||||
|
// const leave = () => {
|
||||||
|
// if (confirm("really leave?")) props.room.leave();
|
||||||
|
// };
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<Menu>
|
// <Menu>
|
||||||
<Item>mark as read</Item>
|
// <Item>mark as read</Item>
|
||||||
{
|
// <Item>copy link</Item>
|
||||||
// <Item>copy link</Item>
|
// <NotifcationMenu />
|
||||||
}
|
// <Separator />
|
||||||
<Submenu content={"mute"}>
|
// <Submenu content={"edit"}>
|
||||||
<Item>for 3 hours</Item>
|
// <Item>general</Item>
|
||||||
<Item>for 1 day</Item>
|
// <Item>log</Item>
|
||||||
<Item>for 1 week</Item>
|
// <Item>permissions</Item>
|
||||||
<Item>forever</Item>
|
// <Item>etc</Item>
|
||||||
</Submenu>
|
// </Submenu>
|
||||||
<Submenu content={"edit"}>
|
// <Item onClick={leave}><span style="color: var(--foreground-danger)">leave</span></Item>
|
||||||
<Item>general</Item>
|
// <Separator />
|
||||||
<Item>log</Item>
|
// <Item onClick={copyId}>copy id</Item>
|
||||||
<Item>permissions</Item>
|
// <Item>inspect</Item>
|
||||||
<Item>etc</Item>
|
// </Menu>
|
||||||
</Submenu>
|
// )
|
||||||
<Item>leave</Item>
|
// }
|
||||||
<Separator />
|
|
||||||
<Item onClick={copyId}>copy id</Item>
|
|
||||||
<Item>inspect</Item>
|
|
||||||
</Menu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// the context menu for rooms
|
// the context menu for rooms
|
||||||
export function RoomMenu(props: VoidProps<{ room: Room }>) {
|
export function RoomMenu(props: VoidProps<{ room: Room }>) {
|
||||||
|
@ -96,22 +93,16 @@ export function RoomMenu(props: VoidProps<{ room: Room }>) {
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Item>mark as read</Item>
|
<Item>mark as read</Item>
|
||||||
{
|
<Item>copy link</Item>
|
||||||
// <Item>copy link</Item>
|
<RoomNotificationMenu />
|
||||||
}
|
<Separator />
|
||||||
<Submenu content={"mute"}>
|
|
||||||
<Item>for 3 hours</Item>
|
|
||||||
<Item>for 1 day</Item>
|
|
||||||
<Item>for 1 week</Item>
|
|
||||||
<Item>forever</Item>
|
|
||||||
</Submenu>
|
|
||||||
<Submenu content={"edit"} onClick={edit}>
|
<Submenu content={"edit"} onClick={edit}>
|
||||||
<Item>general</Item>
|
<Item>general</Item>
|
||||||
<Item>log</Item>
|
<Item>log</Item>
|
||||||
<Item>permissions</Item>
|
<Item>permissions</Item>
|
||||||
<Item>etc</Item>
|
<Item>etc</Item>
|
||||||
</Submenu>
|
</Submenu>
|
||||||
<Item onClick={leave}>leave</Item>
|
<Item onClick={leave}><span style="color: var(--foreground-danger)">leave</span></Item>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Item onClick={copyId}>copy id</Item>
|
<Item onClick={copyId}>copy id</Item>
|
||||||
<Item>inspect</Item>
|
<Item>inspect</Item>
|
||||||
|
@ -136,6 +127,85 @@ export function UserMenu() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ThreadNotificationMenu() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Submenu content={"notifications"}>
|
||||||
|
<Item>
|
||||||
|
<div>default</div>
|
||||||
|
<div class="subtext">Uses the room's default notifications.</div>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<div>replies</div>
|
||||||
|
<div class="subtext">You will be notified of new replies in this thread.</div>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<div>watching</div>
|
||||||
|
<div class="subtext">Updates to this thread will show up in your inbox.</div>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<div>mentions</div>
|
||||||
|
<div class="subtext">You will only be notified on @mention</div>
|
||||||
|
</Item>
|
||||||
|
<Separator />
|
||||||
|
<Item>bookmark</Item>
|
||||||
|
<Submenu content={"remind me"}>
|
||||||
|
<Item>in 15 minutes</Item>
|
||||||
|
<Item>in 3 hours</Item>
|
||||||
|
<Item>in 8 hours</Item>
|
||||||
|
<Item>in 1 day</Item>
|
||||||
|
<Item>in 1 week</Item>
|
||||||
|
<Item>custom</Item>
|
||||||
|
</Submenu>
|
||||||
|
</Submenu>
|
||||||
|
<Submenu content={"mute"}>
|
||||||
|
<Item>for 15 minutes</Item>
|
||||||
|
<Item>for 3 hours</Item>
|
||||||
|
<Item>for 8 hours</Item>
|
||||||
|
<Item>for 1 day</Item>
|
||||||
|
<Item>for 1 week</Item>
|
||||||
|
<Item>custom</Item>
|
||||||
|
</Submenu>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RoomNotificationMenu() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Submenu content={"notifications"}>
|
||||||
|
<Item>
|
||||||
|
<div>default</div>
|
||||||
|
<div class="subtext">Uses your global default notification config.</div>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<div>replies</div>
|
||||||
|
<div class="subtext">You will be notified of new replies in threads.</div>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<div>creation</div>
|
||||||
|
<div class="subtext">You will be notified of new threads.</div>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<div>watching</div>
|
||||||
|
<div class="subtext">New threads and thread updates show up in your inbox.</div>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<div>mentions</div>
|
||||||
|
<div class="subtext">You will only be notified on @mention</div>
|
||||||
|
</Item>
|
||||||
|
</Submenu>
|
||||||
|
<Submenu content={"mute"}>
|
||||||
|
<Item>for 15 minutes</Item>
|
||||||
|
<Item>for 3 hours</Item>
|
||||||
|
<Item>for 8 hours</Item>
|
||||||
|
<Item>for 1 day</Item>
|
||||||
|
<Item>for 1 week</Item>
|
||||||
|
</Submenu>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// the context menu for threads
|
// the context menu for threads
|
||||||
export function ThreadMenu(props: VoidProps<{ thread: Thread }>) {
|
export function ThreadMenu(props: VoidProps<{ thread: Thread }>) {
|
||||||
const copyId = () => navigator.clipboard.writeText(props.thread.id);
|
const copyId = () => navigator.clipboard.writeText(props.thread.id);
|
||||||
|
@ -146,21 +216,8 @@ export function ThreadMenu(props: VoidProps<{ thread: Thread }>) {
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Item onClick={ack}>mark as read</Item>
|
<Item onClick={ack}>mark as read</Item>
|
||||||
{
|
<Item>copy link</Item>
|
||||||
// <Item>copy link</Item>
|
<ThreadNotificationMenu />
|
||||||
}
|
|
||||||
<Item>watch/unwatch</Item>
|
|
||||||
<Submenu content={"mute"}>
|
|
||||||
<Item>for 3 hours</Item>
|
|
||||||
<Item>for 1 day</Item>
|
|
||||||
<Item>for 1 week</Item>
|
|
||||||
<Item>forever</Item>
|
|
||||||
</Submenu>
|
|
||||||
<Submenu content={"remind"}>
|
|
||||||
<Item>in 3 hours</Item>
|
|
||||||
<Item>in 1 day</Item>
|
|
||||||
<Item>in 1 week</Item>
|
|
||||||
</Submenu>
|
|
||||||
<Separator />
|
<Separator />
|
||||||
<Item>edit</Item>
|
<Item>edit</Item>
|
||||||
<Submenu content={"tag"}>
|
<Submenu content={"tag"}>
|
||||||
|
@ -169,7 +226,7 @@ export function ThreadMenu(props: VoidProps<{ thread: Thread }>) {
|
||||||
<Item>baz</Item>
|
<Item>baz</Item>
|
||||||
</Submenu>
|
</Submenu>
|
||||||
<Item>pin</Item>
|
<Item>pin</Item>
|
||||||
<Item>redact</Item>
|
<Item><span style="color: var(--foreground-danger)">redact</span></Item>
|
||||||
<Separator />
|
<Separator />
|
||||||
<Item onClick={copyId}>copy id</Item>
|
<Item onClick={copyId}>copy id</Item>
|
||||||
<Item onClick={copyJSON}>view source</Item>
|
<Item onClick={copyJSON}>view source</Item>
|
||||||
|
|
|
@ -323,6 +323,13 @@ export function Inbox() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function markAllAsRead() {
|
||||||
|
// TODO: use bulk ack
|
||||||
|
for (const thread of threads()) {
|
||||||
|
thread.ack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const willOpenThreadMenu = (thread: Thread) => (e: MouseEvent) => {
|
const willOpenThreadMenu = (thread: Thread) => (e: MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
action({
|
action({
|
||||||
|
@ -334,6 +341,7 @@ export function Inbox() {
|
||||||
return (
|
return (
|
||||||
<div class="timeline threads" ref={scrollEl!} onScroll={handleScroll}>
|
<div class="timeline threads" ref={scrollEl!} onScroll={handleScroll}>
|
||||||
<button onClick={() => setFilter("unread", f => !f)}>{filter.unread ? "showing unread only" : "showing all"}</button>
|
<button onClick={() => setFilter("unread", f => !f)}>{filter.unread ? "showing unread only" : "showing all"}</button>
|
||||||
|
<button onClick={markAllAsRead}>mark all as read</button>
|
||||||
<Show when={!isLoading()} fallback={<div>keep calm...</div>}>
|
<Show when={!isLoading()} fallback={<div>keep calm...</div>}>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
|
|
@ -644,11 +644,16 @@ function ThreadInfo(props: VoidProps<{ thread: Thread, showHeader: boolean }>) {
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const willHandleThreadeContextMenu = (e: MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
action({ type: "contextmenu.set", menu: { type: "thread", thread: props.thread, x: e.clientX, y: e.clientY } });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<header>
|
<header onContextMenu={willHandleThreadeContextMenu}>
|
||||||
<div ref={stickyEl!} class="sticky" classList={{ stuck: stuck() || !props.showHeader }}>
|
<div ref={stickyEl!} class="sticky" classList={{ stuck: stuck() || !props.showHeader }}>
|
||||||
<h1>
|
<h1>
|
||||||
<TextBlock text={event().content.title} fallback={<Text>thread.untitled</Text>} />
|
<TextBlock text={event().content.title} fallback={<Text>thread.untitled</Text>} />
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
--foreground-1: #eae8efcc;
|
--foreground-1: #eae8efcc;
|
||||||
--foreground-2: #eae8ef9f;
|
--foreground-2: #eae8ef9f;
|
||||||
--foreground-link: #b18cf3;
|
--foreground-link: #b18cf3;
|
||||||
|
--foreground-danger: #fa6261;
|
||||||
--font-default: "Atkinson Hyperlegible", Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
--font-default: "Atkinson Hyperlegible", Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
--font-mono: "Iosevka Zesty", 'Courier New', Courier, monospace;
|
--font-mono: "Iosevka Zesty", 'Courier New', Courier, monospace;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue