Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Right panel chat style changes for read receipts and optimizations for smaller widths #7297

Merged
merged 7 commits into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions res/css/views/right_panel/_TimelineCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,55 @@ limitations under the License.
right: 0;
Copy link
Contributor

@MadLittleMods MadLittleMods Dec 13, 2021

Choose a reason for hiding this comment

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

From @toger5's demo of maximized widgets where it showed the right-panel chat style, I was surprised that it looked a lot more native and refined compared to the thread view. This probably comes down to the differences from the normal timeline view because we're changing some the pieces around like the timestamp position in the thread view. I understand that the right panel chat style and the thread view are different.

Right panel chat style that feels nice to me:

The unpolished feeling may apply to this PR iteration of the right-panel chat where things are getting condensed like the thread view but it's hard to judge because I haven't actually used it in the app like threads and it's nice to be able to judge the balance against the whole app and timeline view.

As @toger5 notes, some adaptations probably need to be made for the smaller layout,

We definitely have to make changes to the style. Just to get read-receipts not glitching/overlapping with the messages. The question is, if the style changes are too aggressive. I see both sides. It looking more like the main timeline (more native) when changing as a little as possible and adapting it to the right panel so the small area is used as efficient as possible.

-- @toger5, https://matrix.to/#/!tCaHWuHHvOHjWyqapP:matrix.org/$UibGBNcTpdbe-0zdRn1Ktp8_yHWYh9wL6HlfxJ3t-tc?via=matrix.org&via=element.io&via=uhoreg.ca


As a tiny point of reference, Slack and Discord are able to maintain the same layout between the main message view and threads but they have a different timestamp position and less UI (don't need to contend with read-receipts).

Slack image referencesSlack timestamp position for a burst of messages:

Slack thread view (bursts are always separated):

}
}
.mx_AutoHideScrollbar {
padding-right: 10px;
width: calc(100% - 10px);
}

// Style to optimize the layout for the right panel area
.mx_EventTile_content {
margin-right: 0;
}
.mx_EventTile:not([data-layout="bubble"]) .mx_EventTile_line {
padding-left: 36px;
padding-right: 36px;
}

.mx_GroupLayout .mx_EventTile > .mx_SenderProfile {
margin-left: 36px;
}
.mx_EventTile:not([data-layout="bubble"]) .mx_EventTile_avatar {
top: 12px;
left: 0px;
}

.mx_CallEvent_wrapper {
justify-content: center;
margin: auto 5px;
.mx_CallEvent {
margin: 4px;
}
}
.mx_EventTile:not([data-layout="bubble"]) .mx_MessageTimestamp {
right: -4px;
left: auto;
}

.mx_EventTile:not([data-layout="bubble"]) .mx_EventTile_msgOption {
margin-right: 2px;
}
.mx_GroupLayout .mx_EventTile .mx_EventTile_line {
padding-bottom: 8px;
}
.mx_EventTile_readAvatars {
top: -10px;
}

// mx_EventTile_info
.mx_EventTile:not([data-layout="bubble"]).mx_EventTile_info .mx_EventTile_line {
padding-left: 36px;
}
.mx_EventTile:not([data-layout="bubble"]).mx_EventTile_info .mx_EventTile_avatar {
left: 18px;
}
}
1 change: 1 addition & 0 deletions src/components/structures/RightPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
case RightPanelPhases.Timeline:
if (!SettingsStore.getValue("feature_maximised_widgets")) break;
panel = <TimelineCard
classNames="mx_ThreadPanel mx_TimelineCard"
jryans marked this conversation as resolved.
Show resolved Hide resolved
room={this.props.room}
timelineSet={this.props.room.getUnfilteredTimelineSet()}
resizeNotifier={this.props.resizeNotifier}
Expand Down
25 changes: 11 additions & 14 deletions src/components/views/right_panel/TimelineCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface IProps {
resizeNotifier: ResizeNotifier;
permalinkCreator?: RoomPermalinkCreator;
e2eStatus?: E2EStatus;
classNames?: string;
timelineSet?: EventTimelineSet;
timelineRenderingType?: TimelineRenderingType;
showComposer?: boolean;
Expand All @@ -68,19 +69,22 @@ export default class TimelineCard extends React.Component<IProps, IState> {
private dispatcherRef: string;
private timelinePanelRef: React.RefObject<TimelinePanel> = React.createRef();
private roomStoreToken: EventSubscription;
private settingWatchers: string[];
private readReceiptsSettingWatcher: string;

constructor(props: IProps) {
super(props);
this.state = {
showReadReceipts: false,
showReadReceipts: SettingsStore.getValue("showReadReceipts", props.room.roomId),
jryans marked this conversation as resolved.
Show resolved Hide resolved
};
this.settingWatchers = [];
this.readReceiptsSettingWatcher = null;
}

public componentDidMount(): void {
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.dispatcherRef = dis.register(this.onAction);
this.readReceiptsSettingWatcher = SettingsStore.watchSetting("showReadReceipts", null,
(...[,,, value]) => {this.setState({ showReadReceipts: value as boolean });},
);
}

public componentWillUnmount(): void {
Expand All @@ -89,28 +93,21 @@ export default class TimelineCard extends React.Component<IProps, IState> {
this.roomStoreToken.remove();
}
dis.unregister(this.dispatcherRef);
for (const watcher of this.settingWatchers) {
SettingsStore.unwatchSetting(watcher);
if (this.readReceiptsSettingWatcher) {
SettingsStore.unwatchSetting(this.readReceiptsSettingWatcher);
}
}

private onRoomViewStoreUpdate = async (initial?: boolean): Promise<void> => {
const roomId = this.props.room.roomId;
const newState: Pick<IState, any> = {
// roomLoading: RoomViewStore.isRoomLoading(),
// roomLoadError: RoomViewStore.getRoomLoadError(),

showReadReceipts: SettingsStore.getValue("showReadReceipts", roomId),
initialEventId: RoomViewStore.getInitialEventId(),
initialEventHighlighted: RoomViewStore.isInitialEventHighlighted(),
replyToEvent: RoomViewStore.getQuotingEvent(),
};

this.settingWatchers = this.settingWatchers.concat([
SettingsStore.watchSetting("showReadReceipts", roomId, (...[,,, value]) =>
this.setState({ showReadReceipts: value as boolean }),
),
]);
this.setState(newState);
};

Expand Down Expand Up @@ -160,14 +157,14 @@ export default class TimelineCard extends React.Component<IProps, IState> {
liveTimeline: this.props.timelineSet.getLiveTimeline(),
}}>
<BaseCard
className="mx_ThreadPanel mx_TimelineCard"
className={this.props.classNames}
onClose={this.props.onClose}
withoutScrollContainer={true}
header={this.renderTimelineCardHeader()}
>
<TimelinePanel
ref={this.timelinePanelRef}
showReadReceipts={/*this.state.showReadReceipts*/ false} // TODO: RR's cause issues with limited horizontal space
showReadReceipts={this.state.showReadReceipts}
manageReadReceipts={true}
manageReadMarkers={false} // No RM support in the TimelineCard
sendReadReceiptOnLoad={true}
Expand Down