Fixes #9 and closes #8. This adds a way to mark servers as read.

Servers are also marked as read when joining them.
You can now also mark DMs as read.
This commit is contained in:
Paul 2021-08-07 12:30:19 +01:00
parent 2f06112921
commit 0ea80b5717
7 changed files with 54 additions and 11 deletions

View file

@ -113,7 +113,7 @@
"react-scroll": "^1.8.2", "react-scroll": "^1.8.2",
"redux": "^4.1.0", "redux": "^4.1.0",
"revolt-api": "0.5.1-alpha.10-patch.0", "revolt-api": "0.5.1-alpha.10-patch.0",
"revolt.js": "5.0.0-alpha.19", "revolt.js": "5.0.0-alpha.20",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sass": "^1.35.1", "sass": "^1.35.1",
"shade-blend-color": "^1.0.0", "shade-blend-color": "^1.0.0",

View file

@ -114,7 +114,7 @@ export const UserButton = observer((props: UserProps) => {
}); });
type ChannelProps = CommonProps & { type ChannelProps = CommonProps & {
channel: Channel & { unread?: string }; channel: Channel;
user?: User; user?: User;
compact?: boolean; compact?: boolean;
}; };
@ -140,7 +140,7 @@ export const ChannelButton = observer((props: ChannelProps) => {
className={classNames(styles.item, { [styles.compact]: compact })} className={classNames(styles.item, { [styles.compact]: compact })}
onContextMenu={attachContextMenu("Menu", { onContextMenu={attachContextMenu("Menu", {
channel: channel._id, channel: channel._id,
unread: typeof channel.unread !== "undefined", unread: typeof alert !== "undefined",
})}> })}>
<ChannelIcon <ChannelIcon
className={styles.avatar} className={styles.avatar}

View file

@ -288,6 +288,7 @@ export const ServerListSidebar = observer(({ unreads, lastOpened }: Props) => {
active={active} active={active}
onContextMenu={attachContextMenu("Menu", { onContextMenu={attachContextMenu("Menu", {
server: entry.server._id, server: entry.server._id,
unread: entry.unread,
})}> })}>
<Swoosh /> <Swoosh />
<Tooltip <Tooltip

View file

@ -75,6 +75,7 @@ type Action =
| { action: "copy_selection" } | { action: "copy_selection" }
| { action: "copy_text"; content: string } | { action: "copy_text"; content: string }
| { action: "mark_as_read"; channel: Channel } | { action: "mark_as_read"; channel: Channel }
| { action: "mark_server_as_read"; server: Server }
| { action: "retry_message"; message: QueuedMessage } | { action: "retry_message"; message: QueuedMessage }
| { action: "cancel_message"; message: QueuedMessage } | { action: "cancel_message"; message: QueuedMessage }
| { action: "mention"; user: string } | { action: "mention"; user: string }
@ -178,10 +179,17 @@ function ContextMenus(props: Props) {
message, message,
}); });
client.req( data.channel.ack(message);
"PUT", }
`/channels/${data.channel._id}/ack/${message}` as "/channels/id/ack/id", break;
); case "mark_server_as_read":
{
dispatch({
type: "UNREADS_MARK_MULTIPLE_READ",
channels: data.server.channel_ids,
});
data.server.ack();
} }
break; break;
@ -547,6 +555,16 @@ function ContextMenus(props: Props) {
generateAction({ action: "mark_as_read", channel }); generateAction({ action: "mark_as_read", channel });
} }
if (server && unread) {
generateAction(
{
action: "mark_server_as_read",
server,
},
"mark_as_read",
);
}
if (contextualChannel) { if (contextualChannel) {
if (user && user._id !== userId) { if (user && user._id !== userId) {
generateAction({ generateAction({

View file

@ -10,6 +10,8 @@ import { useContext, useEffect, useState } from "preact/hooks";
import { defer } from "../../lib/defer"; import { defer } from "../../lib/defer";
import { TextReact } from "../../lib/i18n"; import { TextReact } from "../../lib/i18n";
import { dispatch } from "../../redux";
import RequiresOnline from "../../context/revoltjs/RequiresOnline"; import RequiresOnline from "../../context/revoltjs/RequiresOnline";
import { import {
AppContext, AppContext,
@ -134,6 +136,12 @@ export default function Invite() {
defer(() => { defer(() => {
if (server) { if (server) {
dispatch({
type: "UNREADS_MARK_MULTIPLE_READ",
channels:
server.channel_ids,
});
history.push( history.push(
`/server/${server._id}/channel/${invite.channel_id}`, `/server/${server._id}/channel/${invite.channel_id}`,
); );

View file

@ -1,4 +1,5 @@
import type { ChannelUnread } from "revolt-api/types/Sync"; import type { ChannelUnread } from "revolt-api/types/Sync";
import { ulid } from "ulid";
export interface Unreads { export interface Unreads {
[key: string]: Partial<Omit<ChannelUnread, "_id">>; [key: string]: Partial<Omit<ChannelUnread, "_id">>;
@ -11,6 +12,10 @@ export type UnreadsAction =
channel: string; channel: string;
message: string; message: string;
} }
| {
type: "UNREADS_MARK_MULTIPLE_READ";
channels: string[];
}
| { | {
type: "UNREADS_SET"; type: "UNREADS_SET";
unreads: ChannelUnread[]; unreads: ChannelUnread[];
@ -33,6 +38,17 @@ export function unreads(state = {} as Unreads, action: UnreadsAction): Unreads {
last_id: action.message, last_id: action.message,
}, },
}; };
case "UNREADS_MARK_MULTIPLE_READ": {
const newState = { ...state };
const last_id = ulid();
for (const channel of action.channels) {
newState[channel] = {
last_id,
};
}
return newState;
}
case "UNREADS_SET": { case "UNREADS_SET": {
const obj: Unreads = {}; const obj: Unreads = {};
for (const entry of action.unreads) { for (const entry of action.unreads) {

View file

@ -3572,10 +3572,10 @@ revolt-api@0.5.1-alpha.10-patch.0:
resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.1-alpha.10-patch.0.tgz#97d31bec7dfa4573567097443acb059c4feaac20" resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.1-alpha.10-patch.0.tgz#97d31bec7dfa4573567097443acb059c4feaac20"
integrity sha512-UyM890HkGlYNQOxpHuEpUsJHLt8Ujnjg9/zPEDGpbvS4iy0jmHX23Hh8tOCfb/ewxbNrtT3G1HpSWKOneW/vYg== integrity sha512-UyM890HkGlYNQOxpHuEpUsJHLt8Ujnjg9/zPEDGpbvS4iy0jmHX23Hh8tOCfb/ewxbNrtT3G1HpSWKOneW/vYg==
revolt.js@5.0.0-alpha.19: revolt.js@5.0.0-alpha.20:
version "5.0.0-alpha.19" version "5.0.0-alpha.20"
resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.0.0-alpha.19.tgz#51f75d02d173e6f6de1b10fae22ba31a99785f76" resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.0.0-alpha.20.tgz#c9e80c2ea71f4d5d9e33733644a49d66b7d4d164"
integrity sha512-D4HWszUozO4ss252GZw1k0m8p2yjnFtzAARUGo2bJsBYlC00l61hg2xsAvXcemfFParh9x6hAK9xq7olcAt6KA== integrity sha512-yZwzBsgT7yXpwftdDtDh6BTVXOPF1OiMsfz2TNsgle/Ab3SXsdR7sCNu0hbhQgjPwxmWYApZLD4RoDnvvr6TRg==
dependencies: dependencies:
axios "^0.19.2" axios "^0.19.2"
eventemitter3 "^4.0.7" eventemitter3 "^4.0.7"