1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-23 10:52:35 +01:00

implement message deletion

This commit is contained in:
Puyodead1 2023-11-26 14:26:16 -05:00
parent 8d645b07df
commit 2909d4270b
No known key found for this signature in database
GPG Key ID: BA5F91AAEF68E5CE
11 changed files with 107 additions and 57 deletions

2
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,2 @@
{
}

View File

@ -35,7 +35,7 @@ function Avatar(props: Props) {
<Wrapper <Wrapper
size={props.size ?? 32} size={props.size ?? 32}
style={props.style} style={props.style}
onContextMenu={(e) => contextMenu.open2(e, [ContextMenus.User(user)])} onContextMenu={(e) => contextMenu.open2(e, [...ContextMenus.User(user)])}
> >
<img src={user.avatarUrl} width={props.size ?? 32} height={props.size ?? 32} loading="eager" /> <img src={user.avatarUrl} width={props.size ?? 32} height={props.size ?? 32} loading="eager" />
</Wrapper> </Wrapper>

View File

@ -1,6 +1,7 @@
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import React, { memo } from "react"; import React, { memo } from "react";
import { ContextMenuContext } from "../../contexts/ContextMenuContext"; import { ContextMenuContext } from "../../contexts/ContextMenuContext";
import { useAppStore } from "../../stores/AppStore";
import { MessageLike } from "../../stores/objects/Message"; import { MessageLike } from "../../stores/objects/Message";
import { QueuedMessageStatus } from "../../stores/objects/QueuedMessage"; import { QueuedMessageStatus } from "../../stores/objects/QueuedMessage";
import ContextMenus from "../../utils/ContextMenus"; import ContextMenus from "../../utils/ContextMenus";
@ -19,8 +20,11 @@ interface Props {
} }
function Message({ message, header }: Props) { function Message({ message, header }: Props) {
const app = useAppStore();
const contextMenu = React.useContext(ContextMenuContext); const contextMenu = React.useContext(ContextMenuContext);
const [contextMenuItems, setContextMenuItems] = React.useState<IContextMenuItem[]>([ContextMenus.Message(message)]); const [contextMenuItems, setContextMenuItems] = React.useState<IContextMenuItem[]>([
...ContextMenus.Message(app, message, app.account),
]);
return ( return (
<MessageBase header={header} onContextMenu={(e) => contextMenu.open2(e, contextMenuItems)}> <MessageBase header={header} onContextMenu={(e) => contextMenu.open2(e, contextMenuItems)}>

View File

@ -64,7 +64,7 @@ export default function MessageAttachment({ attachment, contextMenuItems, maxWid
withPointer={attachment.content_type?.startsWith("image")} withPointer={attachment.content_type?.startsWith("image")}
key={attachment.id} key={attachment.id}
onContextMenu={(e) => onContextMenu={(e) =>
contextMenu.open2(e, [...(contextMenuItems ?? []), ContextMenus.MessageAttachment(attachment)]) contextMenu.open2(e, [...(contextMenuItems ?? []), ...ContextMenus.MessageAttachment(attachment)])
} }
onClick={() => { onClick={() => {
if (!attachment.content_type?.startsWith("image")) return; if (!attachment.content_type?.startsWith("image")) return;

View File

@ -46,7 +46,7 @@ function MessageAuthor({ message }: Props) {
style={{ style={{
color, color,
}} }}
onContextMenu={(e) => contextMenu.open2(e, [ContextMenus.User(message.author)])} onContextMenu={(e) => contextMenu.open2(e, [...ContextMenus.User(message.author)])}
> >
{message.author.username} {message.author.username}
</Container> </Container>

View File

@ -1,6 +1,6 @@
import type { Snowflake } from "@spacebarchat/spacebar-api-types/globals"; import type { Snowflake } from "@spacebarchat/spacebar-api-types/globals";
import type { APIGuildMember } from "@spacebarchat/spacebar-api-types/v9"; import type { APIGuildMember } from "@spacebarchat/spacebar-api-types/v9";
import { action, makeObservable, observable, ObservableMap } from "mobx"; import { action, computed, makeObservable, observable, ObservableMap } from "mobx";
import AppStore from "./AppStore"; import AppStore from "./AppStore";
import Guild from "./objects/Guild"; import Guild from "./objects/Guild";
import GuildMember from "./objects/GuildMember"; import GuildMember from "./objects/GuildMember";
@ -64,4 +64,11 @@ export default class GuildMemberStore {
get size() { get size() {
return this.members.size; return this.members.size;
} }
@computed
get me() {
const meId = this.app.account?.id;
if (!meId) return null;
return this.members.get(meId);
}
} }

View File

@ -1,22 +1,23 @@
import type { import {
APIActionRowComponent, Routes,
APIApplication, type APIActionRowComponent,
APIAttachment, type APIApplication,
APIChannel, type APIAttachment,
APIChannelMention, type APIChannel,
APIEmbed, type APIChannelMention,
APIMessage, type APIEmbed,
APIMessageActionRowComponent, type APIMessage,
APIMessageActivity, type APIMessageActionRowComponent,
APIMessageInteraction, type APIMessageActivity,
APIMessageReference, type APIMessageInteraction,
APIReaction, type APIMessageReference,
APIRole, type APIReaction,
APISticker, type APIRole,
APIStickerItem, type APISticker,
APIUser, type APIStickerItem,
MessageFlags, type APIUser,
Snowflake, type MessageFlags,
type Snowflake,
} from "@spacebarchat/spacebar-api-types/v9"; } from "@spacebarchat/spacebar-api-types/v9";
import { action, makeObservable, observable } from "mobx"; import { action, makeObservable, observable } from "mobx";
import AppStore from "../AppStore"; import AppStore from "../AppStore";
@ -247,4 +248,8 @@ export default class Message extends MessageBase {
this.timestamp = new Date(message.timestamp); this.timestamp = new Date(message.timestamp);
this.edited_timestamp = message.edited_timestamp ? new Date(message.edited_timestamp) : null; this.edited_timestamp = message.edited_timestamp ? new Date(message.edited_timestamp) : null;
} }
async delete() {
await this.app.rest.delete(Routes.channelMessage(this.channel_id, this.id));
}
} }

View File

@ -27,7 +27,7 @@ export default class MessageBase {
type: MessageType; type: MessageType;
author: User; author: User;
constructor(private readonly app: AppStore, data: MessageLikeData) { constructor(public readonly app: AppStore, data: MessageLikeData) {
this.id = data.id; this.id = data.id;
this.content = data.content; this.content = data.content;
this.timestamp = new Date(data.timestamp); this.timestamp = new Date(data.timestamp);

View File

@ -60,4 +60,8 @@ export default class QueuedMessage extends MessageBase {
this.error = error; this.error = error;
this.status = QueuedMessageStatus.FAILED; this.status = QueuedMessageStatus.FAILED;
} }
delete() {
//
}
} }

View File

@ -1,41 +1,73 @@
import { APIAttachment } from "@spacebarchat/spacebar-api-types/v9"; import { APIAttachment } from "@spacebarchat/spacebar-api-types/v9";
import { IContextMenuItem } from "../components/ContextMenuItem"; import { IContextMenuItem } from "../components/ContextMenuItem";
import AccountStore from "../stores/AccountStore"; import AccountStore from "../stores/AccountStore";
import AppStore from "../stores/AppStore";
import { MessageLike } from "../stores/objects/Message"; import { MessageLike } from "../stores/objects/Message";
import User from "../stores/objects/User"; import User from "../stores/objects/User";
import { Permissions } from "./Permissions";
export default { export default {
User: (user: User | AccountStore): IContextMenuItem => { User: (user: User | AccountStore): IContextMenuItem[] => {
return { return [
label: "Copy User ID", {
onClick: () => { label: "Copy User ID",
navigator.clipboard.writeText(user.id); onClick: () => {
navigator.clipboard.writeText(user.id);
},
iconProps: {
icon: "mdiIdentifier",
},
}, },
iconProps: { ];
icon: "mdiIdentifier",
},
};
}, },
Message: (message: MessageLike): IContextMenuItem => { Message: (app: AppStore, message: MessageLike, account: AccountStore | null): IContextMenuItem[] => {
return { const channel = app.channels.get(message.channel_id);
label: "Copy Message ID", const permissions = Permissions.getPermission(account?.id, channel?.guild, channel);
onClick: () => { const canDeleteMessage = permissions.has("MANAGE_MESSAGES") || message.author.id === account?.id;
navigator.clipboard.writeText(message.id);
const items: IContextMenuItem[] = [
{
label: "Copy Message ID",
onClick: () => {
navigator.clipboard.writeText(message.id);
},
iconProps: {
icon: "mdiIdentifier",
},
}, },
iconProps: { ];
icon: "mdiIdentifier",
}, if (canDeleteMessage) {
}; items.push({
label: "Delete Message",
onClick: () => {
message.delete();
},
iconProps: {
icon: "mdiTrashCanOutline",
color: "red",
},
color: "red",
hover: {
backgroundColor: "red",
color: "white",
},
});
}
return items;
}, },
MessageAttachment: (attachment: APIAttachment): IContextMenuItem => { MessageAttachment: (attachment: APIAttachment): IContextMenuItem[] => {
return { return [
label: "Copy Attachment URL", {
onClick: () => { label: "Copy Attachment URL",
navigator.clipboard.writeText(attachment.url); onClick: () => {
navigator.clipboard.writeText(attachment.url);
},
iconProps: {
icon: "mdiLink",
},
}, },
iconProps: { ];
icon: "mdiLink",
},
};
}, },
}; };

View File

@ -1,7 +1,3 @@
// import {Globals} from '../constants/Globals';
// import useLogger from '../hooks/useLogger';
// import {DomainStore} from '../stores/DomainStore';
import AppStore from "../stores/AppStore"; import AppStore from "../stores/AppStore";
import QueuedMessage from "../stores/objects/QueuedMessage"; import QueuedMessage from "../stores/objects/QueuedMessage";
import { Globals } from "./Globals"; import { Globals } from "./Globals";
@ -190,7 +186,7 @@ export default class REST {
): Promise<void> { ): Promise<void> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const url = REST.makeAPIUrl(path, queryParams); const url = REST.makeAPIUrl(path, queryParams);
// this.logger.debug(`DELETE ${url}`); this.logger.debug(`DELETE ${url}`);
return ( return (
fetch(url, { fetch(url, {
method: "DELETE", method: "DELETE",