Previously, I wrote an article, "Writing a High-Performance Viewport for a Messenger" / Habr, which demonstrated the creation of a simple viewport for a messenger, and it wasn't based on a cross-platform solution.

Selection of technologies
Before creating our future messenger, we need to decide on the technology we'll use for its development. Among web development tools for single-page applications (SPAs), Angular and React are clear favorites. I won't dwell on the advantages of each of these tools, but will focus on Angular, as I've previously conducted research on non-classical virtualized lists and found that it handles this task better than React.
A solution for creating non-classic virtualized lists using Angular's ng-virtual-list and React's rcx-virtual-list (not yet cross-platform, as Angular handles this task better).
Technical requirements
We'll create a group viewing area that will open from the dock.
A viewing area for messages, sorted by creation date.
A process for editing and deleting messages.
A message compose block.
A search for messages by substring.
A unique design with themes.
A cross-browser and cross-platform solution.
Developing a solution
Let's create a new Angular project; in this example, we'll use version 20.x. Add the ng-virtual-list package and configure it as described.
I'll provide the source code for the ng-virtual-list-chat-demo project right away. Later, I'll highlight key points in the repository code to explain it in more detail.
The project runs entirely on mocks, and the transport is implemented using mock services.
Services
A service for working with message groups (groups-mock.service.ts). Implements the getGroups, createGroup, updateGroup, and deleteGroup methods.
A service for switching chats (message.service.ts)
A mock service for working with messages (messages-mock.service.ts). This service provides the getMessages, createMessage, updateMessage, patchMessages, and deleteMessage functionality for the specified chatId.
A service for working with new message notifications (a mock WS) (messages-notification-mock.service.ts) implements two Observables: $typing (signals that a user with the specified userId has typed a message) and $messages (signals that a message has been added, passing the version of the changes as its value).
Theme service (theme.service.ts)
Localization service (localization.service.ts). It is important to note that the interface can be adapted to right-to-left languages, such as Hebrew. The locale-sensitive.directive.ts directive is responsible for this.
Main components
Messenger main page: chat.component.ts
Chat group component: groups.component.ts
Message view area component: messages.component.ts. The collection implementation is based on ProxyCollection. When raw data is received, it is converted to a ProxyCollection<IMessageItemData>, which, when modified, generates a new list of elements for <ng-virtual-list>.
It's important to note that ng-virtual-list can cache messages by type. To do this, it introduces element types such as typing-indicator, unmailed-separator, group, quote, and message, which are rendered as elements of a specific type.
<ng-template #itemRenderer let-index="index" let-data="data" let-prevData="prevData" let-nextData="nextData" let-measures="measures" let-config="config" let-reseted="reseted"> <div staticClick [maxStaticClickDistance]="maxStaticClickDistance" class="message-template" (onStaticClick)="config.select(data.edited ? true : undefined)"> @if (data?.data) { @switch (data.data.type) { @case ("typing-indicator") { <x-messages-typing-indicator ... /> } @case ("unmailed-separator") { <x-message-unmailed-separator ... /> } @case ("group") { <x-message-group ... /> } @case ("quote") { <x-message-box [messageType]="'quote'"... /> } @default { <x-message-box ... /> } } } </div> </ng-template>The message component message-box.component.ts implements viewing, selecting, editing, and deleting functionality. The component uses the SVG rendering of message-substrate.component.ts with various visual effects and animations.
The project implements a number of @shared/components controls, also based on SVG rendering, including a button, button-group, check-box, context-menu, dialog, drawer, and the basic substrate component.
Message search by substring is implemented using the ng-virtual-list library, and substring highlighting is implemented using the search-highlight.directive.ts directive.
The project implements its own ResourceManager with image loading and caching policies.
The design of the elements is developed with gradient fill animation in mind.
The solution works in any browser and on any platform.
Live demo: https://chat-demo.eugene-grebennikov.pro/

Live demo ng-virtual-list: ng-virtual-list-examples
P.S.: If you liked the project, please rate the ng-virtual-list tool for working with virtualized lists with ⭐ stars.