Page MenuHomePhabricator

D7505.id25740.diff
No OneTemporary

D7505.id25740.diff

diff --git a/web/CommIcon.react.js b/web/CommIcon.react.js
--- a/web/CommIcon.react.js
+++ b/web/CommIcon.react.js
@@ -17,7 +17,8 @@
| 'copy-filled'
| 'emote-smile-filled'
| 'pin'
- | 'unpin';
+ | 'unpin'
+ | 'pin-mirror';
type CommIconProps = {
+icon: CommIcons,
diff --git a/web/chat/chat-message-list.css b/web/chat/chat-message-list.css
--- a/web/chat/chat-message-list.css
+++ b/web/chat/chat-message-list.css
@@ -236,3 +236,16 @@
div.avatarOffset {
width: 40px;
}
+
+.pinIconContainer {
+ position: absolute;
+ top: 1px;
+}
+
+.pinIconLeft {
+ left: -20px;
+}
+
+.pinIconRight {
+ right: -20px;
+}
diff --git a/web/chat/chat-message-list.react.js b/web/chat/chat-message-list.react.js
--- a/web/chat/chat-message-list.react.js
+++ b/web/chat/chat-message-list.react.js
@@ -178,6 +178,7 @@
<Message
item={item}
threadInfo={threadInfo}
+ shouldDisplayPinIndicator={true}
key={ChatMessageList.keyExtractor(item)}
/>
);
diff --git a/web/chat/composed-message.react.js b/web/chat/composed-message.react.js
--- a/web/chat/composed-message.react.js
+++ b/web/chat/composed-message.react.js
@@ -17,6 +17,7 @@
import css from './chat-message-list.css';
import FailedSend from './failed-send.react.js';
import InlineEngagement from './inline-engagement.react.js';
+import CommIcon from '../CommIcon.react.js';
import UserAvatar from '../components/user-avatar.react.js';
import { type InputState, InputStateContext } from '../input/input-state.js';
import { shouldRenderAvatars } from '../utils/avatar-utils.js';
@@ -47,6 +48,7 @@
type BaseProps = {
+item: ChatMessageInfoItem,
+threadInfo: ThreadInfo,
+ +shouldDisplayPinIndicator: boolean,
+sendFailed: boolean,
+children: React.Node,
+fixedWidth?: boolean,
@@ -69,8 +71,9 @@
render(): React.Node {
assertComposableMessageType(this.props.item.messageInfo.type);
- const { borderRadius, item, threadInfo } = this.props;
- const { hasBeenEdited } = item;
+ const { borderRadius, item, threadInfo, shouldDisplayPinIndicator } =
+ this.props;
+ const { hasBeenEdited, isPinned } = item;
const { id, creator } = item.messageInfo;
const threadColor = threadInfo.color;
@@ -163,6 +166,25 @@
avatar = <div className={css.avatarOffset} />;
}
+ const pinIconPositioning = isViewer ? 'left' : 'right';
+ const pinIconName = pinIconPositioning === 'left' ? 'pin-mirror' : 'pin';
+ const pinIconContainerClassName = classNames({
+ [css.pinIconContainer]: true,
+ [css.pinIconLeft]: pinIconPositioning === 'left',
+ [css.pinIconRight]: pinIconPositioning === 'right',
+ });
+ let pinIcon;
+ if (isPinned && shouldDisplayPinIndicator) {
+ pinIcon = (
+ <div
+ className={pinIconContainerClassName}
+ style={{ color: `#${threadColor}` }}
+ >
+ <CommIcon icon={pinIconName} size={12} />
+ </div>
+ );
+ }
+
return (
<React.Fragment>
{authorName}
@@ -173,6 +195,7 @@
onMouseEnter={this.props.onMouseEnter}
onMouseLeave={this.props.onMouseLeave}
>
+ {pinIcon}
<div className={messageBoxClassName} style={messageBoxStyle}>
{this.props.children}
</div>
diff --git a/web/chat/message.react.js b/web/chat/message.react.js
--- a/web/chat/message.react.js
+++ b/web/chat/message.react.js
@@ -16,6 +16,7 @@
type Props = {
+item: ChatMessageInfoItem,
+threadInfo: ThreadInfo,
+ +shouldDisplayPinIndicator: boolean,
};
function Message(props: Props): React.Node {
const { item } = props;
@@ -30,12 +31,24 @@
}
let message;
if (item.messageInfo.type === messageTypes.TEXT) {
- message = <TextMessage item={item} threadInfo={props.threadInfo} />;
+ message = (
+ <TextMessage
+ item={item}
+ threadInfo={props.threadInfo}
+ shouldDisplayPinIndicator={props.shouldDisplayPinIndicator}
+ />
+ );
} else if (
item.messageInfo.type === messageTypes.IMAGES ||
item.messageInfo.type === messageTypes.MULTIMEDIA
) {
- message = <MultimediaMessage item={item} threadInfo={props.threadInfo} />;
+ message = (
+ <MultimediaMessage
+ item={item}
+ threadInfo={props.threadInfo}
+ shouldDisplayPinIndicator={props.shouldDisplayPinIndicator}
+ />
+ );
} else {
invariant(item.robotext, "Flow can't handle our fancy types :(");
message = <RobotextMessage item={item} threadInfo={props.threadInfo} />;
diff --git a/web/chat/multimedia-message.react.js b/web/chat/multimedia-message.react.js
--- a/web/chat/multimedia-message.react.js
+++ b/web/chat/multimedia-message.react.js
@@ -15,6 +15,7 @@
type BaseProps = {
+item: ChatMessageInfoItem,
+threadInfo: ThreadInfo,
+ +shouldDisplayPinIndicator: boolean,
};
type Props = {
...BaseProps,
@@ -75,6 +76,7 @@
<ComposedMessage
item={item}
threadInfo={this.props.threadInfo}
+ shouldDisplayPinIndicator={this.props.shouldDisplayPinIndicator}
sendFailed={sendFailed(item, inputState)}
fixedWidth={multimedia.length > 1}
borderRadius={16}
diff --git a/web/chat/text-message.react.js b/web/chat/text-message.react.js
--- a/web/chat/text-message.react.js
+++ b/web/chat/text-message.react.js
@@ -19,6 +19,7 @@
type Props = {
+item: ChatMessageInfoItem,
+threadInfo: ThreadInfo,
+ +shouldDisplayPinIndicator: boolean,
};
function TextMessage(props: Props): React.Node {
invariant(
@@ -55,6 +56,7 @@
<ComposedMessage
item={props.item}
threadInfo={props.threadInfo}
+ shouldDisplayPinIndicator={props.shouldDisplayPinIndicator}
sendFailed={textMessageSendFailed(props.item)}
>
<div className={messageClassName} style={messageStyle}>
diff --git a/web/components/message-result.react.js b/web/components/message-result.react.js
--- a/web/components/message-result.react.js
+++ b/web/components/message-result.react.js
@@ -42,6 +42,7 @@
<Message
item={item}
threadInfo={threadInfo}
+ shouldDisplayPinIndicator={false}
key={item.messageInfo.id}
/>
</MessageListContext.Provider>

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 6:41 AM (22 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2578461
Default Alt Text
D7505.id25740.diff (6 KB)

Event Timeline