Skip to content

Commit

Permalink
Refactor to show deleted message
Browse files Browse the repository at this point in the history
  • Loading branch information
yinxin630 committed Sep 6, 2021
1 parent 2f2e320 commit b3a0197
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 54 deletions.
1 change: 0 additions & 1 deletion .eslintrc
Expand Up @@ -47,7 +47,6 @@
"jsx-a11y/interactive-supports-focus": 0,
"jsx-a11y/no-noninteractive-element-interactions": 0,
"jsx-a11y/no-noninteractive-element-to-interactive-role": 0,
"no-console": 0,
"no-param-reassign": 0,
"no-plusplus": 0,
"no-script-url": 0,
Expand Down
3 changes: 2 additions & 1 deletion packages/app/src/pages/Chat/Message.tsx
Expand Up @@ -49,7 +49,8 @@ function Message({
const self = useSelfId();
const focus = useFocus();

const couldDelete = isAdmin || message.from._id === self;
const couldDelete =
message.type !== 'system' && (isAdmin || message.from._id === self);

useEffect(() => {
if (shouldScroll) {
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/socket.ts
Expand Up @@ -38,7 +38,7 @@ const options = {
transports: ['websocket'],
};

const host = 'https://fiora.suisuijiang.com';
const host = 'http://10.132.67.127:9200';
const socket = IO(host, options);

function fetch<T = any>(
Expand Down
9 changes: 5 additions & 4 deletions packages/app/src/state/reducer.ts
Expand Up @@ -117,7 +117,7 @@ const reducer = produce((state: State = initialState, action: ActionTypes) => {
...linkman,
...(action.linkmans[linkman._id]
? {
messages: action.linkmans[linkman._id].messages,
messages: action.linkmans[linkman._id].messages.map(convertMessage),
unread: action.linkmans[linkman._id].unread,
}
: {}),
Expand Down Expand Up @@ -259,11 +259,12 @@ const reducer = produce((state: State = initialState, action: ActionTypes) => {
(linkman) => linkman._id === action.linkmanId,
);
if (targetLinkman) {
const targetMessageIndex = targetLinkman.messages.findIndex(
const targetMessage = targetLinkman.messages.find(
(message) => message._id === action.messageId,
);
if (targetMessageIndex !== -1) {
targetLinkman.messages.splice(targetMessageIndex, 1);
if (targetMessage) {
targetMessage.deleted = true;
convertMessage(targetMessage);
}
}
return state;
Expand Down
3 changes: 2 additions & 1 deletion packages/app/src/types/redux.ts
Expand Up @@ -17,7 +17,7 @@ export type SetLinkmanMessagesAction = {
linkmans: Record<
string,
{
messages: { [linkmanId: string]: Message[] };
messages: Message[];
unread: number;
}
>;
Expand Down Expand Up @@ -154,6 +154,7 @@ export type Message = {
originUsername?: string;
};
to: string;
deleted?: boolean;
};

export type Group = {
Expand Down
9 changes: 9 additions & 0 deletions packages/app/src/utils/convertMessage.ts
Expand Up @@ -46,7 +46,16 @@ function convertSystemMessage(message: Message) {
message.content = '不支持的指令';
}
}
} else if (message.deleted) {
message.type = 'system';
message.from._id = 'system';
message.from.originUsername = message.from.username;
message.from.username = '乌贼娘殿下';
message.from.avatar = WuZeiNiangImage;
message.from.tag = 'system';
message.content = `撤回了消息`;
}

return message;
}

Expand Down
12 changes: 12 additions & 0 deletions packages/database/mongoose/models/message.ts
Expand Up @@ -22,6 +22,10 @@ const MessageSchema = new Schema({
type: String,
default: '',
},
deleted: {
type: Boolean,
default: false,
},
});

export interface MessageDocument extends Document {
Expand All @@ -35,6 +39,8 @@ export interface MessageDocument extends Document {
content: string;
/** 创建时间 */
createTime: Date;
/** Has it been deleted */
deleted: boolean;
}

/**
Expand All @@ -45,6 +51,12 @@ const Message = model<MessageDocument>('Message', MessageSchema);

export default Message;

interface SendMessageData {
to: string;
type: string;
content: string;
}

export async function handleInviteV2Message(message: SendMessageData) {
if (message.type === 'inviteV2') {
const inviteInfo = JSON.parse(message.content);
Expand Down
21 changes: 10 additions & 11 deletions packages/server/src/routes/message.ts
Expand Up @@ -64,7 +64,7 @@ async function pushNotification(
}
});
} catch (error) {
logger.error('[Notification]', error.message);
logger.error('[Notification]', (error as Error).message);
}
}
}
Expand Down Expand Up @@ -237,6 +237,7 @@ export async function getLinkmansLastMessages(
content: 1,
from: 1,
createTime: 1,
deleted: 1,
},
{ sort: { createTime: -1 }, limit: FirstTimeMessagesCount },
).populate('from', { username: 1, avatar: 1, tag: 1 });
Expand Down Expand Up @@ -282,6 +283,7 @@ export async function getLinkmansLastMessagesV2(
content: 1,
from: 1,
createTime: 1,
deleted: 1,
},
{
sort: { createTime: -1 },
Expand Down Expand Up @@ -340,6 +342,7 @@ export async function getLinkmanHistoryMessages(
content: 1,
from: 1,
createTime: 1,
deleted: 1,
},
{
sort: { createTime: -1 },
Expand Down Expand Up @@ -371,6 +374,7 @@ export async function getDefaultGroupHistoryMessages(
content: 1,
from: 1,
createTime: 1,
deleted: 1,
},
{
sort: { createTime: -1 },
Expand All @@ -382,22 +386,17 @@ export async function getDefaultGroupHistoryMessages(
return result;
}

interface DeleteMessageData {
/** 消息id */
messageId: string;
}

/**
* 删除消息, 需要管理员权限
*/
export async function deleteMessage(ctx: Context<{ messageId: string }>) {
const { messageId } = ctx.data;
assert(messageId, 'messageId不能为空');

assert(
!client.disableDeleteMessage || ctx.socket.isAdmin,
'已禁止撤回消息',
);

const { messageId } = ctx.data;
assert(messageId, 'messageId不能为空');

const message = await Message.findOne({ _id: messageId });
if (!message) {
Expand All @@ -409,8 +408,8 @@ export async function deleteMessage(ctx: Context<{ messageId: string }>) {
'只能撤回本人的消息',
);

await Message.deleteOne({ _id: message._id });
await History.deleteMany({ message: message._id });
message.deleted = true;
await message.save();

/**
* 广播删除消息通知, 区分群消息和私聊消息
Expand Down
3 changes: 2 additions & 1 deletion packages/server/src/routes/user.ts
Expand Up @@ -117,7 +117,7 @@ export async function register(
avatar: getRandomAvatar(),
} as UserDocument);
} catch (err) {
if (err.name === 'ValidationError') {
if ((err as Error).name === 'ValidationError') {
return '用户名包含不支持的字符或者长度超过限制';
}
throw err;
Expand Down Expand Up @@ -357,6 +357,7 @@ export async function guest(ctx: Context<Environment>) {
content: 1,
from: 1,
createTime: 1,
deleted: 1,
},
{ sort: { createTime: -1 }, limit: 15 },
).populate('from', { username: 1, avatar: 1 });
Expand Down
9 changes: 9 additions & 0 deletions packages/utils/convertMessage.ts
Expand Up @@ -37,9 +37,18 @@ function convertSystemMessage(message: any) {
message.content = '不支持的指令';
}
}
} else if (message.deleted) {
message.type = 'system';
message.from._id = 'system';
message.from.originUsername = message.from.username;
message.from.username = '乌贼娘殿下';
message.from.avatar = WuZeiNiangImage;
message.from.tag = 'system';
message.content = `撤回了消息`;
}
}

export default function convertMessage(message: any) {
convertSystemMessage(message);
return message;
}
6 changes: 5 additions & 1 deletion packages/web/src/modules/Chat/Message/Message.tsx
Expand Up @@ -73,7 +73,10 @@ class Message extends Component<MessageProps, MessageState> {
}

handleMouseEnter = () => {
const { isAdmin, isSelf } = this.props;
const { isAdmin, isSelf, type } = this.props;
if (type === 'system') {
return;
}
if (isAdmin || (!client.disableDeleteMessage && isSelf)) {
this.setState({ showButtonList: true });
}
Expand Down Expand Up @@ -111,6 +114,7 @@ class Message extends Component<MessageProps, MessageState> {
messageId: id,
} as DeleteMessagePayload,
});
this.setState({ showButtonList: false });
}
};

Expand Down
38 changes: 18 additions & 20 deletions packages/web/src/state/reducer.ts
@@ -1,5 +1,6 @@
import { isMobile } from '@fiora/utils/ua';
import getFriendId from '@fiora/utils/getFriendId';
import convertMessage from '@fiora/utils/convertMessage';
import getData from '../localStorage';
import {
Action,
Expand Down Expand Up @@ -31,6 +32,7 @@ export interface Message {
loading: boolean;
percent: number;
createTime: string;
deleted?: boolean;
}

export interface MessagesMap {
Expand Down Expand Up @@ -225,7 +227,7 @@ function transformFriend(friend: Linkman): Linkman {
// @ts-ignore
createTime: friend.createTime,
};
initLinkmanFields((transformedFriend as unknown) as Linkman, 'friend');
initLinkmanFields(transformedFriend as unknown as Linkman, 'friend');
return transformedFriend as Linkman;
}

Expand Down Expand Up @@ -304,15 +306,8 @@ function reducer(state: State = initialState, action: Action): State {
}

case ActionTypes.SetUser: {
const {
_id,
username,
avatar,
tag,
groups,
friends,
isAdmin,
} = action.payload as SetUserPayload;
const { _id, username, avatar, tag, groups, friends, isAdmin } =
action.payload as SetUserPayload;
// @ts-ignore
const linkmans: Linkman[] = [
// @ts-ignore
Expand Down Expand Up @@ -466,7 +461,8 @@ function reducer(state: State = initialState, action: Action): State {
}

case ActionTypes.SetLinkmansLastMessages: {
const linkmansMessages = action.payload as SetLinkmansLastMessagesPayload;
const linkmansMessages =
action.payload as SetLinkmansLastMessagesPayload;
const { linkmans } = state;
const newState = { ...state, linkmans: {} };
Object.keys(linkmans).forEach((linkmanId) => {
Expand Down Expand Up @@ -527,10 +523,8 @@ function reducer(state: State = initialState, action: Action): State {
}

case ActionTypes.DeleteMessage: {
const {
linkmanId,
messageId,
} = action.payload as DeleteMessagePayload;
const { linkmanId, messageId } =
action.payload as DeleteMessagePayload;
if (!state.linkmans[linkmanId]) {
/* istanbul ignore next */
if (!__TEST__) {
Expand All @@ -541,17 +535,21 @@ function reducer(state: State = initialState, action: Action): State {
return state;
}

const messages = deleteObjectKey(
state.linkmans[linkmanId].messages,
messageId,
);
return {
...state,
linkmans: {
...state.linkmans,
[linkmanId]: {
...state.linkmans[linkmanId],
messages,
messages: {
...state.linkmans[linkmanId].messages,
[messageId]: convertMessage({
...state.linkmans[linkmanId].messages[
messageId
],
deleted: true,
}),
},
},
},
};
Expand Down

0 comments on commit b3a0197

Please sign in to comment.