Skip to content

Refactor EventTile using the MVVM pattern - #7b#33668

Open
rbondesson wants to merge 11 commits into
element-hq:developfrom
ZacksBot:refactor/event-tile-replay
Open

Refactor EventTile using the MVVM pattern - #7b#33668
rbondesson wants to merge 11 commits into
element-hq:developfrom
ZacksBot:refactor/event-tile-replay

Conversation

@rbondesson
Copy link
Copy Markdown
Contributor

@rbondesson rbondesson commented May 29, 2026

Checklist

Refactor EventTile using the MVVM pattern

Partially implements: https://github.com/element-hq/wat-internal/issues/414

Summary - Step 7b

This PR continues thinning EventTile by moving stable leaf UI and stateful UI surfaces into focused adapters. EventTile keeps layout/composition ownership, while adapters handle local React/context wiring and VM-backed view rendering where needed.

Changes

  • Added EventTile leaf adapters: MessageTimestampAdapter, ThreadMessagePreviewAdapter, ThreadSummaryAdapter, ThreadListActionBarAdapter, E2eMessageSharedIconAdapter, ActionBarAdapter, ReactionsRowAdapter, ReceiptAdapter, SenderIdentityAdapter
  • Moved child VM ownership into EventTileViewModel for EventTile-scoped VMs: thread preview, thread summary, E2E message-shared icon, action bar, reactions row
  • Moved action bar menu state and reaction picker/menu wiring out of EventTile.
  • Moved reactions row relation listeners, decrypted-event handling, reaction grouping, and reaction picker state out of EventTile.
  • Moved receipt rendering out of EventTile, including sent/sending receipt vs read receipt selection.
  • Moved sender/avatar rendering out of EventTile while keeping layout placement in EventTile.
  • Added lifecycle cleanup for listener-owning child VMs when their adapter surfaces unmount.

Implementation plan

  1. Cover existing behavior with tests - Refactor EventTile using the MVVM pattern - #1 #33463
    Add/maintain focused tests around current EventTile behavior before moving logic.

  2. Extract pure decision helpers - Refactor EventTile using the MVVM pattern - #2 #33489
    Move low-risk derived state calculations out of EventTile, without changing rendering ownership yet.

  3. Introduce small view models - Refactor EventTile using the MVVM pattern - #3 #33516
    Start with isolated surfaces such as timestamp visibility, root attributes/classes, message type classes, and sender/avatar decisions.

  4. Move interaction state - Refactor EventTile using the MVVM pattern - #4 #33539
    Extract hover/focus/action-bar/context-menu state once the pure rendering decisions are stable.

  5. Move feature-specific state - Refactor EventTile using the MVVM pattern - #5a #33587, Refactor EventTile using the MVVM pattern - #5b #33600
    a. Extract reaction relations, reply-chain state, thread-info state, and receipt state into separate view-model boundaries.
    b. Extract E2E padlock into separate view-model boundaries

  6. Thin the React component - Refactor EventTile using the MVVM pattern - #6 #33621
    Keep EventTile mostly as composition/wiring: render views, pass event handlers, and bridge Matrix/React context.

  7. Split view components - Refactor EventTile using the MVVM pattern - #7a #33640
    Move stable UI fragments into smaller view components where it reduces EventTile complexity.

  8. Remove legacy duplication
    After behavior is covered by view models and views, clean up old inline helpers and dead conditional branches.

Copy link
Copy Markdown
Member

@dbkr dbkr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other than doc on the adapters, looking good!

getRelationsForEvent?: GetRelationsForEvent;
}

export function ActionBarAdapter({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this get some doc?

customReactionImagesEnabled?: boolean;
}

function ReactionsRowButtonAdapter(props: Readonly<ReactionsRowButtonAdapterProps>): JSX.Element {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick bit of doc on here would be appreciated too

reactions?: Relations | null;
}

export function ReactionsRowAdapter({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likewise on doc

isTwelveHour?: boolean;
}

export function ReceiptAdapter({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likewise doc

senderSnapshot: EventTileSenderSnapshot;
}

export function EventTileAvatarAdapter({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc again

showDisplayName?: boolean;
}

export function ThreadMessagePreviewAdapter({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also doc

thread: Thread;
}

export function ThreadSummaryAdapter({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also doc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-Task Tasks for the team like planning

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants