mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-05 06:50:28 +03:00
Edit option (#1447)
* add func to parse html to editor input * add plain to html input function * re-construct markdown * fix missing return * fix falsy condition * fix reading href instead of src of emoji * add message editor - WIP * fix plain to editor input func * add save edit message functionality * show edited event source code * focus message input on after editing message * use del tag for strike-through instead of s * prevent autocomplete from re-opening after esc * scroll out of view msg editor in view * handle up arrow edit * handle scroll to message editor without effect * revert prev commit: effect run after editor render * ignore relation event from editable * allow data-md tag for del and em in sanitize html * prevent edit without changes * ignore previous reply when replying to msg * fix up arrow edit not working sometime
This commit is contained in:
parent
152576e85d
commit
f5bcc9b851
18 changed files with 957 additions and 108 deletions
|
|
@ -2,17 +2,22 @@ import { IconName, IconSrc } from 'folds';
|
|||
|
||||
import {
|
||||
EventTimeline,
|
||||
EventTimelineSet,
|
||||
EventType,
|
||||
IPushRule,
|
||||
IPushRules,
|
||||
JoinRule,
|
||||
MatrixClient,
|
||||
MatrixEvent,
|
||||
MsgType,
|
||||
NotificationCountType,
|
||||
RelationType,
|
||||
Room,
|
||||
} from 'matrix-js-sdk';
|
||||
import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend';
|
||||
import { AccountDataEvent } from '../../types/matrix/accountData';
|
||||
import {
|
||||
MessageEvent,
|
||||
NotificationType,
|
||||
RoomToParents,
|
||||
RoomType,
|
||||
|
|
@ -249,6 +254,21 @@ export const getRoomAvatarUrl = (mx: MatrixClient, room: Room): string | undefin
|
|||
return room.getAvatarUrl(mx.baseUrl, 32, 32, 'crop') ?? undefined;
|
||||
};
|
||||
|
||||
export const trimReplyFromBody = (body: string): string => {
|
||||
const match = body.match(/^>\s<.+?>\s.+\n\n/);
|
||||
if (!match) return body;
|
||||
return body.slice(match[0].length);
|
||||
};
|
||||
|
||||
export const trimReplyFromFormattedBody = (formattedBody: string): string => {
|
||||
const suffix = '</mx-reply>';
|
||||
const i = formattedBody.lastIndexOf(suffix);
|
||||
if (i < 0) {
|
||||
return formattedBody;
|
||||
}
|
||||
return formattedBody.slice(i + suffix.length);
|
||||
};
|
||||
|
||||
export const parseReplyBody = (userId: string, body: string) =>
|
||||
`> <${userId}> ${body.replace(/\n/g, '\n> ')}\n\n`;
|
||||
|
||||
|
|
@ -301,3 +321,52 @@ export const getReactionContent = (eventId: string, key: string, shortcode?: str
|
|||
},
|
||||
shortcode,
|
||||
});
|
||||
|
||||
export const getEventReactions = (timelineSet: EventTimelineSet, eventId: string) =>
|
||||
timelineSet.relations.getChildEventsForEvent(
|
||||
eventId,
|
||||
RelationType.Annotation,
|
||||
EventType.Reaction
|
||||
);
|
||||
|
||||
export const getEventEdits = (timelineSet: EventTimelineSet, eventId: string, eventType: string) =>
|
||||
timelineSet.relations.getChildEventsForEvent(eventId, RelationType.Replace, eventType);
|
||||
|
||||
export const getLatestEdit = (
|
||||
targetEvent: MatrixEvent,
|
||||
editEvents: MatrixEvent[]
|
||||
): MatrixEvent | undefined => {
|
||||
const eventByTargetSender = (rEvent: MatrixEvent) =>
|
||||
rEvent.getSender() === targetEvent.getSender();
|
||||
return editEvents.sort((m1, m2) => m2.getTs() - m1.getTs()).find(eventByTargetSender);
|
||||
};
|
||||
|
||||
export const getEditedEvent = (
|
||||
mEventId: string,
|
||||
mEvent: MatrixEvent,
|
||||
timelineSet: EventTimelineSet
|
||||
): MatrixEvent | undefined => {
|
||||
const edits = getEventEdits(timelineSet, mEventId, mEvent.getType());
|
||||
return edits && getLatestEdit(mEvent, edits.getRelations());
|
||||
};
|
||||
|
||||
export const canEditEvent = (mx: MatrixClient, mEvent: MatrixEvent) =>
|
||||
mEvent.getSender() === mx.getUserId() &&
|
||||
!mEvent.isRelation() &&
|
||||
mEvent.getType() === MessageEvent.RoomMessage &&
|
||||
(mEvent.getContent().msgtype === MsgType.Text ||
|
||||
mEvent.getContent().msgtype === MsgType.Emote ||
|
||||
mEvent.getContent().msgtype === MsgType.Notice);
|
||||
|
||||
export const getLatestEditableEvt = (
|
||||
timeline: EventTimeline,
|
||||
canEdit: (mEvent: MatrixEvent) => boolean
|
||||
): MatrixEvent | undefined => {
|
||||
const events = timeline.getEvents();
|
||||
|
||||
for (let i = events.length - 1; i >= 0; i -= 1) {
|
||||
const evt = events[i];
|
||||
if (canEdit(evt)) return evt;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue