message-and-dropdown.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import type { Message } from '@/features/chat/context/chat-context'
  2. import { User } from '../../../../../types/user'
  3. import {
  4. getBackgroundColorForUserId,
  5. hslStringToLuminance,
  6. } from '@/shared/utils/colors'
  7. import MessageContent from '@/features/chat/components/message-content'
  8. import classNames from 'classnames'
  9. import MaterialIcon from '@/shared/components/material-icon'
  10. import MessageDropdown from '@/features/chat/components/message-dropdown'
  11. import { useFeatureFlag } from '@/shared/context/split-test-context'
  12. import firstCharacter from '@/shared/utils/first-character'
  13. function getAvatarStyle(user?: User) {
  14. if (!user?.id) {
  15. // Deleted user
  16. return {
  17. backgroundColor: 'var(--bg-light-disabled)',
  18. borderColor: 'var(--bg-light-disabled)',
  19. color: 'var(--content-disabled)',
  20. }
  21. }
  22. const backgroundColor = getBackgroundColorForUserId(user.id)
  23. return {
  24. borderColor: backgroundColor,
  25. backgroundColor,
  26. color:
  27. hslStringToLuminance(backgroundColor) < 0.5
  28. ? 'var(--content-primary-dark)'
  29. : 'var(--content-primary)',
  30. }
  31. }
  32. export function MessageAndDropdown({
  33. message,
  34. fromSelf,
  35. isLast,
  36. isFirst,
  37. }: {
  38. message: Message
  39. fromSelf: boolean
  40. isLast: boolean
  41. isFirst: boolean
  42. }) {
  43. const hasChatEditDelete = useFeatureFlag('chat-edit-delete')
  44. return (
  45. <div className="message-row">
  46. {!fromSelf && isLast ? (
  47. <div className="message-avatar">
  48. <div className="avatar" style={getAvatarStyle(message.user)}>
  49. {message.user?.id && message.user.email ? (
  50. firstCharacter(message.user.first_name || message.user.email)
  51. ) : (
  52. <MaterialIcon
  53. type="delete"
  54. className="message-avatar-deleted-user-icon"
  55. />
  56. )}
  57. </div>
  58. </div>
  59. ) : (
  60. <div className="message-avatar-placeholder" />
  61. )}
  62. <div
  63. className={classNames('message-container', {
  64. 'message-from-self': fromSelf,
  65. 'first-row-in-message': isFirst,
  66. 'last-row-in-message': isLast,
  67. 'pending-message': message.pending,
  68. })}
  69. >
  70. <div>
  71. {hasChatEditDelete && fromSelf ? (
  72. <MessageDropdown message={message} />
  73. ) : null}
  74. </div>
  75. <div className="message-content">
  76. <MessageContent
  77. content={message.content}
  78. messageId={message.id}
  79. edited={message.edited}
  80. />
  81. </div>
  82. </div>
  83. </div>
  84. )
  85. }