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 vote down vote up
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 vote down vote up
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 vote down vote up
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>
		);
	}