semantic-ui-react#Comment TypeScript Examples
The following examples show how to use
semantic-ui-react#Comment.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Chat.tsx From watchparty with MIT License | 4 votes |
render() {
return (
<div
className={this.props.className}
style={{
display: this.props.hide ? 'none' : 'flex',
flexDirection: 'column',
flexGrow: 1,
minHeight: 0,
marginTop: 0,
marginBottom: 0,
padding: '8px',
}}
>
<div
className="chatContainer"
ref={this.messagesRef}
style={{ position: 'relative', paddingTop: 13 }}
>
<Comment.Group>
{this.props.chat.map((msg) => (
<ChatMessage
key={msg.timestamp + msg.id}
className={
msg.id === this.state.reactionMenu.selectedMsgId &&
msg.timestamp === this.state.reactionMenu.selectedMsgTimestamp
? classes.selected
: ''
}
message={msg}
pictureMap={this.props.pictureMap}
nameMap={this.props.nameMap}
formatMessage={this.formatMessage}
owner={this.props.owner}
user={this.props.user}
socket={this.props.socket}
isChatDisabled={this.props.isChatDisabled}
setReactionMenu={this.setReactionMenu}
handleReactionClick={this.handleReactionClick}
/>
))}
{/* <div ref={this.messagesEndRef} /> */}
</Comment.Group>
{!this.state.isNearBottom && (
<Button
size="tiny"
onClick={this.scrollToBottom}
style={{
position: 'sticky',
bottom: 0,
display: 'block',
margin: '0 auto',
}}
>
Jump to bottom
</Button>
)}
</div>
<Separator />
{this.state.isPickerOpen && (
<PickerMenu
addEmoji={this.addEmoji}
closeMenu={() => this.setState({ isPickerOpen: false })}
/>
)}
<CSSTransition
in={this.state.reactionMenu.isOpen}
timeout={300}
classNames={{
enter: classes['reactionMenu-enter'],
enterActive: classes['reactionMenu-enter-active'],
exit: classes['reactionMenu-exit'],
exitActive: classes['reactionMenu-exit-active'],
}}
unmountOnExit
>
<ReactionMenu
handleReactionClick={this.handleReactionClick}
closeMenu={() => this.setReactionMenu(false)}
yPosition={this.state.reactionMenu.yPosition}
xPosition={this.state.reactionMenu.xPosition}
/>
</CSSTransition>
<Input
inverted
fluid
onKeyPress={(e: any) => e.key === 'Enter' && this.sendChatMsg()}
onChange={this.updateChatMsg}
value={this.state.chatMsg}
error={this.chatTooLong()}
icon
disabled={this.props.isChatDisabled}
placeholder={
this.props.isChatDisabled
? 'The chat was disabled by the room owner.'
: 'Enter a message...'
}
>
<input />
<Icon
// style={{ right: '40px' }}
onClick={() => this.setState({ isPickerOpen: true })}
name={'' as any}
inverted
circular
link
disabled={this.props.isChatDisabled}
style={{ opacity: 1 }}
>
<span role="img" aria-label="Emoji">
?
</span>
</Icon>
{/* <Icon onClick={this.sendChatMsg} name="send" inverted circular link /> */}
</Input>
</div>
);
}
Example #2
Source File: Chat.tsx From watchparty with MIT License | 4 votes |
ChatMessage = ({
message,
nameMap,
pictureMap,
formatMessage,
user,
socket,
owner,
isChatDisabled,
setReactionMenu,
handleReactionClick,
className,
}: {
message: ChatMessage;
nameMap: StringDict;
pictureMap: StringDict;
formatMessage: (cmd: string, msg: string) => React.ReactNode;
user: firebase.User | undefined;
socket: Socket;
owner: string | undefined;
isChatDisabled: boolean | undefined;
setReactionMenu: Function;
handleReactionClick: Function;
className: string;
}) => {
const { id, timestamp, cmd, msg, system, isSub, reactions } = message;
const spellFull = 5; // the number of people whose names should be written out in full in the reaction popup
return (
<Comment className={`${classes.comment} ${className}`}>
{id ? (
<Popup
content="WatchParty Plus subscriber"
disabled={!isSub}
trigger={
<Comment.Avatar
className={isSub ? classes.subscriber : ''}
src={
pictureMap[id] ||
getDefaultPicture(nameMap[id], getColorForStringHex(id))
}
/>
}
/>
) : null}
<Comment.Content>
<UserMenu
displayName={nameMap[id] || id}
user={user}
timestamp={timestamp}
socket={socket}
userToManage={id}
isChatMessage
disabled={!Boolean(owner && owner === user?.uid)}
trigger={
<Comment.Author as="a" className="light">
{Boolean(system) && 'System'}
{nameMap[id] || id}
</Comment.Author>
}
/>
<Comment.Metadata className="dark">
<div>{new Date(timestamp).toLocaleTimeString()}</div>
</Comment.Metadata>
<Comment.Text className="light system">
{cmd && formatMessage(cmd, msg)}
</Comment.Text>
<Linkify
componentDecorator={(
decoratedHref: string,
decoratedText: string,
key: string
) => (
<SecureLink href={decoratedHref} key={key}>
{decoratedText}
</SecureLink>
)}
>
<Comment.Text className="light">{!cmd && msg}</Comment.Text>
</Linkify>
<div className={classes.commentMenu}>
<Icon
onClick={(e: MouseEvent) => {
const viewportOffset = (e.target as any).getBoundingClientRect();
setReactionMenu(
true,
id,
timestamp,
viewportOffset.top,
viewportOffset.right
);
}}
name={'' as any}
inverted
link
disabled={isChatDisabled}
style={{
opacity: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: 10,
margin: 0,
}}
>
<span
role="img"
aria-label="React"
style={{ margin: 0, fontSize: 18 }}
>
?
</span>
</Icon>
</div>
<TransitionGroup>
{Object.keys(reactions ?? []).map((key) =>
reactions?.[key].length ? (
<CSSTransition
key={key}
timeout={200}
classNames={{
enter: classes['reaction-enter'],
enterActive: classes['reaction-enter-active'],
exit: classes['reaction-exit'],
exitActive: classes['reaction-exit-active'],
}}
unmountOnExit
>
<Popup
content={`${reactions[key]
.slice(0, spellFull)
.map((id) => nameMap[id] || 'Unknown')
.concat(
reactions[key].length > spellFull
? [`${reactions[key].length - spellFull} more`]
: []
)
.reduce(
(text, value, i, array) =>
text + (i < array.length - 1 ? ', ' : ' and ') + value
)} reacted.`}
offset={[0, 6]}
trigger={
<div
className={`${classes.reactionContainer} ${
reactions[key].includes(socket.id)
? classes.highlighted
: ''
}`}
onClick={() =>
handleReactionClick(key, message.id, message.timestamp)
}
>
<span
style={{
fontSize: 17,
position: 'relative',
bottom: 1,
}}
>
{key}
</span>
<SwitchTransition>
<CSSTransition
key={key + '-' + reactions[key].length}
classNames={{
enter: classes['reactionCounter-enter'],
enterActive:
classes['reactionCounter-enter-active'],
exit: classes['reactionCounter-exit'],
exitActive: classes['reactionCounter-exit-active'],
}}
addEndListener={(node, done) =>
node.addEventListener('transitionend', done, false)
}
unmountOnExit
>
<span
className={classes.reactionCounter}
style={{
color: 'rgba(255, 255, 255, 0.85)',
marginLeft: 3,
}}
>
{reactions[key].length}
</span>
</CSSTransition>
</SwitchTransition>
</div>
}
/>
</CSSTransition>
) : null
)}
</TransitionGroup>
</Comment.Content>
</Comment>
);
}
Example #3
Source File: episodepage.tsx From website with MIT License | 4 votes |
renderQuestDescription(quest) {
let screens = <span />;
if (quest.quest_type === 'NarrativeQuest' && quest.screens) {
screens = (
<Comment.Group threaded>
<Header as='h4' dividing>
Screens
</Header>
{quest.screens.map((screen, idx) => (
<Comment key={idx}>
<Comment.Avatar src={`${process.env.GATSBY_ASSETS_URL}${imageFileUrl(screen.speaker_image)}`} />
<Comment.Content>
<Comment.Author as='a'>{screen.speaker_name}</Comment.Author>
<Comment.Text>
<p>{screen.text}</p>
<ul>
{screen.responses.map((resp, idx) => (
<li key={idx}>
<b>{resp.paraphrase}</b> - {resp.text}
</li>
))}
</ul>
</Comment.Text>
</Comment.Content>
</Comment>
))}
</Comment.Group>
);
}
if (quest.quest_type === 'ShipBattleQuest') {
screens = (
<div>
{quest.mastery_levels.map(ml => (
<div key={ml.id}>
<span style={{ display: 'inline-block' }}>
<img src={`${process.env.GATSBY_ASSETS_URL}atlas/${CONFIG.MASTERY_LEVELS[ml.id].imageUrl}.png`} height={14} />
</span>
<span>
{' ' + CONFIG.MASTERY_LEVELS[ml.id].name} mastery - {ml.energy_cost}{' '}
<span style={{ display: 'inline-block' }}>
<img src={`${process.env.GATSBY_ASSETS_URL}atlas/energy_icon.png`} height={14} />
</span>
</span>
{ml.opponent && (
<span>
{' '}Opponent: {ml.opponent.name} ({ml.opponent.ship_name})
</span>
)}
</div>
))}
</div>
);
}
if (quest.quest_type === 'ConflictQuest') {
let cadet = <span />;
if (quest.crew_requirement) {
cadet = (
<div>
Cadet requirements: <span dangerouslySetInnerHTML={this._htmlDecode(quest.crew_requirement.description)} />
</div>
);
}
screens = (
<div>
{cadet}
<ul>
{quest.stages.map(stage => (
<li key={stage.grid_x}>{stage.text}</li>
))}
</ul>
</div>
);
}
return (
<div>
{quest.description && <p>{quest.description}</p>}
{quest.intro && (
<Comment.Group>
<Comment>
<Comment.Avatar src={`${process.env.GATSBY_ASSETS_URL}${imageFileUrl(quest.intro.portrait)}`} />
<Comment.Content>
<Comment.Author as='a'>{quest.intro.speaker_name}</Comment.Author>
<Comment.Text>
<p>{quest.intro.text}</p>
<ul>
<li>{quest.intro.response}</li>
</ul>
</Comment.Text>
</Comment.Content>
</Comment>
</Comment.Group>
)}
{screens}
</div>
);
}