@@ -15,22 +15,47 @@ interface ToolbarProps {
1515 data : VideoData ;
1616 onOptimisticComment ?: ( comment : CommentType ) => void ;
1717 onCommentSuccess ?: ( comment : CommentType ) => void ;
18+ disableComments ?: boolean ;
1819 disableReactions ?: boolean ;
1920}
2021
22+ interface EmojiButtonProps {
23+ label : string ;
24+ emoji : string ;
25+ onClick : ( ) => void ;
26+ }
27+
28+ const EmojiButton = ( { label, emoji, onClick } : EmojiButtonProps ) => (
29+ < motion . div layout className = "relative size-10" >
30+ < motion . button
31+ layout
32+ className = "inline-flex relative justify-center items-center p-1 text-xl leading-6 align-middle bg-transparent rounded-full transition-colors ease-in-out size-full font-emoji sm:text-2xl duration-600 hover:bg-gray-200 active:bg-blue-500 active:duration-0"
33+ role = "img"
34+ aria-label = { label ? label : "" }
35+ aria-hidden = { label ? "false" : "true" }
36+ onClick = { onClick }
37+ >
38+ { emoji }
39+ </ motion . button >
40+ </ motion . div >
41+ ) ;
42+
2143export const Toolbar = ( {
2244 data,
2345 onOptimisticComment,
2446 onCommentSuccess,
47+ disableComments,
2548 disableReactions,
2649} : ToolbarProps ) => {
2750 const user = useCurrentUser ( ) ;
2851 const [ commentBoxOpen , setCommentBoxOpen ] = useState ( false ) ;
2952 const [ comment , setComment ] = useState ( "" ) ;
3053 const [ showAuthOverlay , setShowAuthOverlay ] = useState ( false ) ;
54+ const canComment = ! disableComments ;
55+ const canReact = ! disableReactions ;
3156
3257 const handleEmojiClick = async ( emoji : string ) => {
33- if ( ! user ) return ;
58+ if ( ! canReact || ! user ) return ;
3459 const videoElement = document . querySelector ( "video" ) as HTMLVideoElement ;
3560 const currentTime = videoElement ?. currentTime || 0 ;
3661 const optimisticComment : CommentType = {
@@ -71,7 +96,7 @@ export const Toolbar = ({
7196 } ;
7297
7398 const handleCommentSubmit = async ( ) => {
74- if ( comment . length === 0 || ! user ) {
99+ if ( ! canComment || comment . length === 0 || ! user ) {
75100 return ;
76101 }
77102 const videoElement = document . querySelector ( "video" ) as HTMLVideoElement ;
@@ -113,22 +138,9 @@ export const Toolbar = ({
113138 }
114139 } ;
115140
116- const Emoji = ( { label, emoji } : { label : string ; emoji : string } ) => (
117- < motion . div layout className = "relative size-10" >
118- < motion . button
119- layout
120- className = "inline-flex relative justify-center items-center p-1 text-xl leading-6 align-middle bg-transparent rounded-full transition-colors ease-in-out size-full font-emoji sm:text-2xl duration-600 hover:bg-gray-200 active:bg-blue-500 active:duration-0"
121- role = "img"
122- aria-label = { label ? label : "" }
123- aria-hidden = { label ? "false" : "true" }
124- onClick = { ( ) => handleEmojiClick ( emoji ) }
125- >
126- { emoji }
127- </ motion . button >
128- </ motion . div >
129- ) ;
130-
131141 useEffect ( ( ) => {
142+ if ( ! canComment ) return ;
143+
132144 const handleKeyPress = ( e : KeyboardEvent ) => {
133145 if (
134146 e . key . toLowerCase ( ) === "c" &&
@@ -161,9 +173,10 @@ export const Toolbar = ({
161173 return ( ) => {
162174 window . removeEventListener ( "keydown" , handleKeyPress ) ;
163175 } ;
164- } , [ commentBoxOpen , user ] ) ;
176+ } , [ canComment , commentBoxOpen , user ] ) ;
165177
166178 const handleCommentClick = ( ) => {
179+ if ( ! canComment ) return ;
167180 if ( ! user ) {
168181 setShowAuthOverlay ( true ) ;
169182 return ;
@@ -175,7 +188,7 @@ export const Toolbar = ({
175188 setCommentBoxOpen ( true ) ;
176189 } ;
177190
178- if ( disableReactions ) {
191+ if ( ! canComment && ! canReact ) {
179192 return null ;
180193 }
181194
@@ -186,7 +199,7 @@ export const Toolbar = ({
186199 className = "flex overflow-hidden p-2 mx-auto max-w-full bg-white rounded-full border border-gray-5 md:max-w-fit"
187200 >
188201 < AnimatePresence initial = { false } mode = "popLayout" >
189- { commentBoxOpen ? (
202+ { commentBoxOpen && canComment ? (
190203 < motion . div
191204 layout
192205 key = "comment-box"
@@ -252,33 +265,41 @@ export const Toolbar = ({
252265 transition = { { duration : 0.2 , ease : "easeInOut" } }
253266 className = "flex flex-col gap-2 items-center mx-auto w-full md:justify-center sm:grid sm:grid-flow-col md:w-fit min-h-[28px]"
254267 >
255- { /* Emoji reactions row */ }
256- < div className = "flex gap-2 justify-evenly items-center w-full md:w-fit md:justify-center" >
257- { REACTIONS . map ( ( reaction ) => (
258- < Emoji
259- key = { reaction . emoji }
260- emoji = { reaction . emoji }
261- label = { reaction . label }
262- />
263- ) ) }
264- </ div >
268+ { canReact && (
269+ < div className = "flex gap-2 justify-evenly items-center w-full md:w-fit md:justify-center" >
270+ { REACTIONS . map ( ( reaction ) => (
271+ < EmojiButton
272+ key = { reaction . emoji }
273+ emoji = { reaction . emoji }
274+ label = { reaction . label }
275+ onClick = { ( ) => handleEmojiClick ( reaction . emoji ) }
276+ />
277+ ) ) }
278+ </ div >
279+ ) }
265280
266- { /* Separator - hidden on mobile, visible on desktop */ }
267- < motion . div className = "hidden sm:block w-px bg-gray-5 h-[16px] mx-4" />
281+ { canReact && canComment && (
282+ < motion . div className = "hidden sm:block w-px bg-gray-5 h-[16px] mx-4" />
283+ ) }
268284
269- { /* Comment button - full width on mobile, normal on desktop */ }
270- < div className = "ml-auto w-full sm:w-auto" >
271- < MotionButton
272- onClick = { handleCommentClick }
273- variant = "dark"
274- layout = "position"
275- kbd = "c"
276- size = "sm"
277- className = "mx-auto w-fit"
285+ { canComment && (
286+ < div
287+ className = {
288+ canReact ? "ml-auto w-full sm:w-auto" : "w-full sm:w-auto"
289+ }
278290 >
279- Comment
280- </ MotionButton >
281- </ div >
291+ < MotionButton
292+ onClick = { handleCommentClick }
293+ variant = "dark"
294+ layout = "position"
295+ kbd = "c"
296+ size = "sm"
297+ className = "mx-auto w-fit"
298+ >
299+ Comment
300+ </ MotionButton >
301+ </ div >
302+ ) }
282303 </ motion . div >
283304 ) }
284305 </ AnimatePresence >
0 commit comments