Create room threads list view (#6904)
Implement https://github.com/vector-im/element-web/issues/18957 following requirements: * Create a new right panel view to list all the threads in a given room. * Change ThreadView previous phase to be ThreadPanel rather than RoomSummary * Implement local filters for My and All threads In addition: * Create a new TileShape for proper rendering requirements (hiding typing indicator) * Create new timelineRenderingType for proper rendering requirements
This commit is contained in:
parent
6bb47ec710
commit
562a880c7d
17 changed files with 623 additions and 121 deletions
|
@ -31,6 +31,8 @@ import RightPanelStore from "../../../stores/RightPanelStore";
|
|||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { useSettingValue } from "../../../hooks/useSettings";
|
||||
import { useReadPinnedEvents, usePinnedEvents } from './PinnedMessagesCard';
|
||||
import { dispatchShowThreadsPanelEvent } from "../../../dispatcher/dispatch-actions/threads";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
||||
const ROOM_INFO_PHASES = [
|
||||
RightPanelPhases.RoomSummary,
|
||||
|
@ -122,6 +124,13 @@ export default class RoomHeaderButtons extends HeaderButtons<IProps> {
|
|||
isHighlighted={this.isPhase(RightPanelPhases.PinnedMessages)}
|
||||
onClick={this.onPinnedMessagesClicked}
|
||||
/>
|
||||
{ SettingsStore.getValue("feature_thread") && <HeaderButton
|
||||
name="threadsButton"
|
||||
title={_t("Threads")}
|
||||
onClick={dispatchShowThreadsPanelEvent}
|
||||
isHighlighted={this.isPhase(RightPanelPhases.ThreadPanel)}
|
||||
analytics={['Right Panel', 'Threads List Button', 'click']}
|
||||
/> }
|
||||
<HeaderButton
|
||||
name="notifsButton"
|
||||
title={_t('Notifications')}
|
||||
|
|
|
@ -48,6 +48,7 @@ import { Container, MAX_PINNED, WidgetLayoutStore } from "../../../stores/widget
|
|||
import RoomName from "../elements/RoomName";
|
||||
import UIStore from "../../../stores/UIStore";
|
||||
import ExportDialog from "../dialogs/ExportDialog";
|
||||
import { dispatchShowThreadsPanelEvent } from "../../../dispatcher/dispatch-actions/threads";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
|
@ -221,13 +222,6 @@ const onRoomFilesClick = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const onRoomThreadsClick = () => {
|
||||
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||
action: Action.SetRightPanelPhase,
|
||||
phase: RightPanelPhases.ThreadPanel,
|
||||
});
|
||||
};
|
||||
|
||||
const onRoomSettingsClick = () => {
|
||||
defaultDispatcher.dispatch({ action: "open_room_settings" });
|
||||
};
|
||||
|
@ -291,7 +285,7 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
|
|||
{ _t("Export chat") }
|
||||
</Button>
|
||||
{ SettingsStore.getValue("feature_thread") && (
|
||||
<Button className="mx_RoomSummaryCard_icon_threads" onClick={onRoomThreadsClick}>
|
||||
<Button className="mx_RoomSummaryCard_icon_threads" onClick={dispatchShowThreadsPanelEvent}>
|
||||
{ _t("Show threads") }
|
||||
</Button>
|
||||
) }
|
||||
|
|
|
@ -56,9 +56,9 @@ import ReadReceiptMarker from "./ReadReceiptMarker";
|
|||
import MessageActionBar from "../messages/MessageActionBar";
|
||||
import ReactionsRow from '../messages/ReactionsRow';
|
||||
import { getEventDisplayInfo } from '../../../utils/EventUtils';
|
||||
import { RightPanelPhases } from "../../../stores/RightPanelStorePhases";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import MKeyVerificationConclusion from "../messages/MKeyVerificationConclusion";
|
||||
import { dispatchShowThreadEvent } from '../../../dispatcher/dispatch-actions/threads';
|
||||
|
||||
const eventTileTypes = {
|
||||
[EventType.RoomMessage]: 'messages.MessageEvent',
|
||||
|
@ -193,6 +193,7 @@ export enum TileShape {
|
|||
FileGrid = "file_grid",
|
||||
Pinned = "pinned",
|
||||
Thread = "thread",
|
||||
ThreadPanel = "thread_list"
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
|
@ -511,6 +512,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
if (this.props.showReactions) {
|
||||
this.props.mxEvent.removeListener("Event.relationsCreated", this.onReactionsCreated);
|
||||
}
|
||||
if (SettingsStore.getValue("feature_thread")) {
|
||||
this.props.mxEvent.off(ThreadEvent.Ready, this.updateThread);
|
||||
this.props.mxEvent.off(ThreadEvent.Update, this.updateThread);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
|
@ -541,13 +546,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
<div
|
||||
className="mx_ThreadInfo"
|
||||
onClick={() => {
|
||||
dis.dispatch({
|
||||
action: Action.SetRightPanelPhase,
|
||||
phase: RightPanelPhases.ThreadView,
|
||||
refireParams: {
|
||||
event: this.props.mxEvent,
|
||||
},
|
||||
});
|
||||
dispatchShowThreadEvent(this.props.mxEvent);
|
||||
}}
|
||||
>
|
||||
<span className="mx_EventListSummary_avatars">
|
||||
|
|
|
@ -155,58 +155,55 @@ export default class RoomHeader extends React.Component<IProps> {
|
|||
/>;
|
||||
}
|
||||
|
||||
let forgetButton;
|
||||
if (this.props.onForgetClick) {
|
||||
forgetButton =
|
||||
<AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_forgetButton"
|
||||
onClick={this.props.onForgetClick}
|
||||
title={_t("Forget room")} />;
|
||||
}
|
||||
const buttons: JSX.Element[] = [];
|
||||
|
||||
let appsButton;
|
||||
if (this.props.onAppsClick) {
|
||||
appsButton =
|
||||
<AccessibleTooltipButton
|
||||
className={classNames("mx_RoomHeader_button mx_RoomHeader_appsButton", {
|
||||
mx_RoomHeader_appsButton_highlight: this.props.appsShown,
|
||||
})}
|
||||
onClick={this.props.onAppsClick}
|
||||
title={this.props.appsShown ? _t("Hide Widgets") : _t("Show Widgets")} />;
|
||||
}
|
||||
|
||||
let searchButton;
|
||||
if (this.props.onSearchClick && this.props.inRoom) {
|
||||
searchButton =
|
||||
<AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_searchButton"
|
||||
onClick={this.props.onSearchClick}
|
||||
title={_t("Search")} />;
|
||||
}
|
||||
|
||||
let voiceCallButton;
|
||||
let videoCallButton;
|
||||
if (this.props.inRoom && SettingsStore.getValue("showCallButtonsInComposer")) {
|
||||
voiceCallButton =
|
||||
<AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_voiceCallButton"
|
||||
onClick={() => this.props.onCallPlaced(PlaceCallType.Voice)}
|
||||
title={_t("Voice call")} />;
|
||||
videoCallButton =
|
||||
<AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_videoCallButton"
|
||||
onClick={(ev: React.MouseEvent<Element>) => ev.shiftKey ?
|
||||
this.displayInfoDialogAboutScreensharing() : this.props.onCallPlaced(PlaceCallType.Video)}
|
||||
title={_t("Video call")} />;
|
||||
const voiceCallButton = <AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_voiceCallButton"
|
||||
onClick={() => this.props.onCallPlaced(PlaceCallType.Voice)}
|
||||
title={_t("Voice call")}
|
||||
/>;
|
||||
const videoCallButton = <AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_videoCallButton"
|
||||
onClick={(ev: React.MouseEvent<Element>) => ev.shiftKey ?
|
||||
this.displayInfoDialogAboutScreensharing() : this.props.onCallPlaced(PlaceCallType.Video)}
|
||||
title={_t("Video call")}
|
||||
/>;
|
||||
buttons.push(voiceCallButton, videoCallButton);
|
||||
}
|
||||
|
||||
if (this.props.onForgetClick) {
|
||||
const forgetButton = <AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_forgetButton"
|
||||
onClick={this.props.onForgetClick}
|
||||
title={_t("Forget room")}
|
||||
/>;
|
||||
buttons.push(forgetButton);
|
||||
}
|
||||
|
||||
if (this.props.onAppsClick) {
|
||||
const appsButton = <AccessibleTooltipButton
|
||||
className={classNames("mx_RoomHeader_button mx_RoomHeader_appsButton", {
|
||||
mx_RoomHeader_appsButton_highlight: this.props.appsShown,
|
||||
})}
|
||||
onClick={this.props.onAppsClick}
|
||||
title={this.props.appsShown ? _t("Hide Widgets") : _t("Show Widgets")}
|
||||
/>;
|
||||
buttons.push(appsButton);
|
||||
}
|
||||
|
||||
if (this.props.onSearchClick && this.props.inRoom) {
|
||||
const searchButton = <AccessibleTooltipButton
|
||||
className="mx_RoomHeader_button mx_RoomHeader_searchButton"
|
||||
onClick={this.props.onSearchClick}
|
||||
title={_t("Search")}
|
||||
/>;
|
||||
buttons.push(searchButton);
|
||||
}
|
||||
|
||||
const rightRow =
|
||||
<div className="mx_RoomHeader_buttons">
|
||||
{ videoCallButton }
|
||||
{ voiceCallButton }
|
||||
{ forgetButton }
|
||||
{ appsButton }
|
||||
{ searchButton }
|
||||
{ buttons }
|
||||
</div>;
|
||||
|
||||
const e2eIcon = this.props.e2eStatus ? <E2EIcon status={this.props.e2eStatus} /> : undefined;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue