Fix pin/unpin slowness and non refresh from the message action bar (#12934)
* Improve PinningUtils.ts doc and use common methods to check pin or unpin. Removed unused methods. * Send room account data and state event in parallel * Rerender MessageActionBar.tsx if there is a room pinned event * Update pinning util tests * Add test for room pinned events in MessageActionBar-test.tsx
This commit is contained in:
parent
43941efbdb
commit
ea3c5cf787
5 changed files with 57 additions and 16 deletions
|
@ -24,6 +24,9 @@ import {
|
|||
MsgType,
|
||||
RelationType,
|
||||
M_BEACON_INFO,
|
||||
EventTimeline,
|
||||
RoomStateEvent,
|
||||
EventType,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import classNames from "classnames";
|
||||
import { Icon as PinIcon } from "@vector-im/compound-design-tokens/icons/pin.svg";
|
||||
|
@ -278,12 +281,20 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
|||
this.props.mxEvent.once(MatrixEventEvent.Decrypted, this.onDecrypted);
|
||||
}
|
||||
this.props.mxEvent.on(MatrixEventEvent.BeforeRedaction, this.onBeforeRedaction);
|
||||
this.context.room
|
||||
?.getLiveTimeline()
|
||||
.getState(EventTimeline.FORWARDS)
|
||||
?.on(RoomStateEvent.Events, this.onRoomEvent);
|
||||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
this.props.mxEvent.off(MatrixEventEvent.Status, this.onSent);
|
||||
this.props.mxEvent.off(MatrixEventEvent.Decrypted, this.onDecrypted);
|
||||
this.props.mxEvent.off(MatrixEventEvent.BeforeRedaction, this.onBeforeRedaction);
|
||||
this.context.room
|
||||
?.getLiveTimeline()
|
||||
.getState(EventTimeline.FORWARDS)
|
||||
?.off(RoomStateEvent.Events, this.onRoomEvent);
|
||||
}
|
||||
|
||||
private onDecrypted = (): void => {
|
||||
|
@ -297,6 +308,12 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
|||
this.forceUpdate();
|
||||
};
|
||||
|
||||
private onRoomEvent = (event?: MatrixEvent): void => {
|
||||
// If the event is pinned or unpinned, rerender the component.
|
||||
if (!event || event.getType() !== EventType.RoomPinnedEvents) return;
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
private onSent = (): void => {
|
||||
// When an event is sent and echoed the possible actions change.
|
||||
this.forceUpdate();
|
||||
|
|
|
@ -286,10 +286,6 @@ export function hasThreadSummary(event: MatrixEvent): boolean {
|
|||
return event.isThreadRoot && !!event.getThread()?.length && !!event.getThread()!.replyToEvent;
|
||||
}
|
||||
|
||||
export function canPinEvent(event: MatrixEvent): boolean {
|
||||
return !M_BEACON_INFO.matches(event.getType());
|
||||
}
|
||||
|
||||
export const highlightEvent = (roomId: string, eventId: string): void => {
|
||||
defaultDispatcher.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import { MatrixEvent, EventType, M_POLL_START, MatrixClient, EventTimeline } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { canPinEvent, isContentActionable } from "./EventUtils";
|
||||
import { isContentActionable } from "./EventUtils";
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
import { ReadPinsEventId } from "../components/views/right_panel/types";
|
||||
|
||||
|
@ -31,7 +31,8 @@ export default class PinningUtils {
|
|||
];
|
||||
|
||||
/**
|
||||
* Determines if the given event may be pinned.
|
||||
* Determines if the given event can be pinned.
|
||||
* This is a simple check to see if the event is of a type that can be pinned.
|
||||
* @param {MatrixEvent} event The event to check.
|
||||
* @return {boolean} True if the event may be pinned, false otherwise.
|
||||
*/
|
||||
|
@ -62,7 +63,8 @@ export default class PinningUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determines if the given event may be pinned or unpinned.
|
||||
* Determines if the given event may be pinned or unpinned by the current user.
|
||||
* This checks if the user has the necessary permissions to pin or unpin the event, and if the event is pinnable.
|
||||
* @param matrixClient
|
||||
* @param mxEvent
|
||||
*/
|
||||
|
@ -77,7 +79,7 @@ export default class PinningUtils {
|
|||
room
|
||||
.getLiveTimeline()
|
||||
.getState(EventTimeline.FORWARDS)
|
||||
?.mayClientSendStateEvent(EventType.RoomPinnedEvents, matrixClient) && canPinEvent(mxEvent),
|
||||
?.mayClientSendStateEvent(EventType.RoomPinnedEvents, matrixClient) && PinningUtils.isPinnable(mxEvent),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -101,16 +103,21 @@ export default class PinningUtils {
|
|||
?.getStateEvents(EventType.RoomPinnedEvents, "")
|
||||
?.getContent().pinned || [];
|
||||
|
||||
let roomAccountDataPromise: Promise<{} | void> = Promise.resolve();
|
||||
// If the event is already pinned, unpin it
|
||||
if (pinnedIds.includes(eventId)) {
|
||||
pinnedIds.splice(pinnedIds.indexOf(eventId), 1);
|
||||
} else {
|
||||
// Otherwise, pin it
|
||||
pinnedIds.push(eventId);
|
||||
await matrixClient.setRoomAccountData(room.roomId, ReadPinsEventId, {
|
||||
// We don't want to wait for the roomAccountDataPromise to resolve before sending the state event
|
||||
roomAccountDataPromise = matrixClient.setRoomAccountData(room.roomId, ReadPinsEventId, {
|
||||
event_ids: [...(room.getAccountData(ReadPinsEventId)?.getContent()?.event_ids || []), eventId],
|
||||
});
|
||||
}
|
||||
await matrixClient.sendStateEvent(room.roomId, EventType.RoomPinnedEvents, { pinned: pinnedIds }, "");
|
||||
await Promise.all([
|
||||
matrixClient.sendStateEvent(room.roomId, EventType.RoomPinnedEvents, { pinned: pinnedIds }, ""),
|
||||
roomAccountDataPromise,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue