aboutsummaryrefslogtreecommitdiff
path: root/vnext/src/ui/Comment.js
blob: 3a3f4429f4861b9863c05409a5a6eee6dd106d19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { useEffect, useRef, useState } from 'react'

import MessageInput from './MessageInput'
import Avatar from './Avatar'
import { UserLink } from './UserInfo'
import Button from './Button'

import { format, embedUrls } from '../utils/embed'

import { chatItemStyle } from './helpers/BubbleStyle'
import { useVisitor } from './VisitorContext'

/**
 * @param {{
    visitor: import('../client').SecureUser,
    msg: import('../client').Message,
    draft: string,
    active: number,
    setActive: Function,
    onStartEditing: Function,
    postComment: function({body:string, attach: string | File}) : void
  }} props props
 * @returns import('react').ReactElement
 */
export default function Comment({ msg, draft, active, setActive, onStartEditing, postComment }) {
  const [visitor] = useVisitor()
  /** @type {import('react').MutableRefObject<HTMLDivElement?>} */
  const embedRef = useRef(null)
  /** @type {import('react').MutableRefObject<HTMLDivElement?>} */
  const msgRef = useRef(null)
  const [author] = useState(msg.user)
  useEffect(() => {
    if (msgRef.current && embedRef.current) {
      embedUrls(msgRef.current.querySelectorAll('a'), embedRef.current)
      if (!embedRef.current.hasChildNodes()) {
        embedRef.current.style.display = 'none'
      }
    }
  }, [])
  return (
    <div style={chatItemStyle(visitor, msg)}>
      <div className="msg-header">
        <Avatar user={author} link={author.uri}>
          <div className="msg-ts">
            {
              msg.to && msg.replyto && msg.replyto > 0 &&
              (
                <UserLink user={msg.to} />
              )
            }
          </div>
        </Avatar>
      </div>
      {
        msg.body &&
        <div className={visitor && visitor.uid === msg.user.uid ? 'msg-bubble msg-bubble-my' : 'msg-bubble'}>
          <div ref={msgRef}>
            <p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid.toString(), (msg.tags || []).indexOf('code') >= 0) }} />
          </div>
        </div>
      }
      {
        msg.photo &&
        <div className="msg-media">
          <a href={`//i.juick.com/p/${msg.mid}-${msg.rid}.${msg.attach}`} data-fname={`${msg.mid}-${msg.rid}.${msg.attach}`}>
            <img src={`//i.juick.com/photos-512/${msg.mid}-${msg.rid}.${msg.attach}`} alt="" />
          </a>
        </div>
      }
      <div className="embedContainer" ref={embedRef} />
      {
        active === msg.rid && <MessageInput text={draft || ''} onSend={postComment} placeholder="Write a comment..." />
      }
      {visitor && visitor.uid > 0 &&
        <div className="msg-links">
          {
            visitor.uid > 0 ? (
              <>
                {active === msg.rid || <span style={linkStyle} onClick={() => setActive(msg.rid)}>Reply</span>}
                {
                  visitor.uid == msg.user.uid &&
                  <>
                    <span>&nbsp;&middot;&nbsp;</span>
                    <span style={linkStyle} onClick={() => onStartEditing(msg)}>Edit</span>
                  </>
                }
              </>
            ) : (
              <>
                <span>&nbsp;&middot;&nbsp;</span>{active === msg.rid || <Button>Reply</Button>}
              </>
            )
          }
        </div>
      }
    </div>
  )
}
/**
 * @type {import('react').CSSProperties}
 */
const linkStyle = {
  cursor: 'pointer'
}