11import {
2- Button ,
32 ContainerCard ,
43 Highlight ,
54 LG ,
@@ -8,11 +7,10 @@ import {
87 Skeleton ,
98 useToast ,
109} from '@appquality/unguess-design-system' ;
11- import { useEffect , useRef , useState } from 'react' ;
10+ import { useRef , useState } from 'react' ;
1211import { useTranslation } from 'react-i18next' ;
1312import { useParams } from 'react-router-dom' ;
1413import { appTheme } from 'src/app/theme' ;
15- import { ReactComponent as TagIcon } from 'src/assets/icons/tag-icon.svg' ;
1614import { ReactComponent as InfoIcon } from 'src/assets/info-transcript.svg' ;
1715import { getColorWithAlpha } from 'src/common/utils' ;
1816import {
@@ -61,20 +59,6 @@ export const TitleWrapper = styled.div`
6159 gap: ${ ( { theme } ) => theme . space . xs } ;
6260` ;
6361
64- const CreateObservationButton = styled ( Button ) < {
65- position : {
66- x : number ;
67- y : number ;
68- } ;
69- } > `
70- user-select: none;
71- position: absolute;
72- left: ${ ( { position } ) => position . x } px;
73- top: ${ ( { position } ) => position . y } px;
74- transform: translate(-50%, 0);
75- z-index: ${ ( { theme } ) => theme . levels . front } ;
76- ` ;
77-
7862const TagsWrapper = styled . div `
7963 display: flex;
8064 justify-content: center;
@@ -92,16 +76,6 @@ const Transcript = ({
9276} ) => {
9377 const { t } = useTranslation ( ) ;
9478 const { videoId } = useParams ( ) ;
95- const [ selection , setSelection ] = useState < {
96- from : number ;
97- to : number ;
98- text : string ;
99- } > ( ) ;
100- const [ isSelecting , setIsSelecting ] = useState < boolean > ( false ) ;
101- const [ position , setPosition ] = useState < {
102- x : number ;
103- y : number ;
104- } > ( ) ;
10579 const [ searchValue , setSearchValue ] = useState ( '' ) ;
10680 const containerRef = useRef < HTMLDivElement > ( null ) ;
10781 const wrapperRef = useRef < HTMLDivElement > ( null ) ;
@@ -127,111 +101,46 @@ const Transcript = ({
127101 vid : videoId || '' ,
128102 } ) ;
129103
130- const handleAddObservation = async ( ) => {
131- if ( selection ) {
132- const body = {
133- start : selection . from ,
134- end : selection . to ,
135- } ;
136- await postVideoByVidObservations ( {
137- vid : videoId || '' ,
138- body,
139- } )
140- . unwrap ( )
141- . then ( ( res ) => {
142- setOpenAccordion ( { id : res . id } ) ;
143- setIsSelecting ( false ) ;
144- } )
145- . catch ( ( err ) => {
146- addToast (
147- ( { close } ) => (
148- < Notification
149- onClose = { close }
150- type = "error"
151- message = { t ( '__VIDEO_PAGE_PLAYER_ERROR_OBSERVATION' ) }
152- closeText = { t ( '__TOAST_CLOSE_TEXT' ) }
153- isPrimary
154- />
155- ) ,
156- { placement : 'top' }
157- ) ;
158- // eslint-disable-next-line no-console
159- console . error ( err ) ;
160- } ) ;
161- }
162- } ;
163-
164- const handleSelection = ( part : {
104+ const handleAddObservation = async ( part : {
165105 from : number ;
166106 to : number ;
167107 text : string ;
168108 } ) => {
169- setSelection ( {
170- from : part . from ,
171- to : part . to ,
172- text : part . text ,
173- } ) ;
109+ const body = {
110+ start : part . from ,
111+ end : part . to ,
112+ } ;
113+ await postVideoByVidObservations ( {
114+ vid : videoId || '' ,
115+ body,
116+ } )
117+ . unwrap ( )
118+ . then ( ( res ) => {
119+ setOpenAccordion ( { id : res . id } ) ;
120+ } )
121+ . catch ( ( err ) => {
122+ addToast (
123+ ( { close } ) => (
124+ < Notification
125+ onClose = { close }
126+ type = "error"
127+ message = { t ( '__VIDEO_PAGE_PLAYER_ERROR_OBSERVATION' ) }
128+ closeText = { t ( '__TOAST_CLOSE_TEXT' ) }
129+ isPrimary
130+ />
131+ ) ,
132+ { placement : 'top' }
133+ ) ;
134+ // eslint-disable-next-line no-console
135+ console . error ( err ) ;
136+ } ) ;
174137 } ;
138+
175139 const sanitizeInput = ( input : string ) => {
176140 const sanitizedInput = input . replace ( / [ - [ \] { } ( ) * + ? . , \\ ^ $ | # \s ] / g, '\\$&' ) ;
177141 return sanitizedInput ;
178142 } ;
179143
180- useEffect ( ( ) => {
181- const handleSelectionChange = ( ) => {
182- if ( ! wrapperRef || ! wrapperRef . current ) return ;
183-
184- const s = document . getSelection ( ) ;
185-
186- if ( s && s . toString ( ) . length > 0 ) {
187- const anchorNode = s ?. anchorNode ?. parentElement ;
188- const focusNode = s ?. focusNode ?. parentElement ;
189-
190- if (
191- ! anchorNode ||
192- ! focusNode ||
193- ! wrapperRef . current . contains ( anchorNode ) ||
194- ! wrapperRef . current . contains ( focusNode )
195- ) {
196- setIsSelecting ( false ) ;
197- return ;
198- }
199-
200- setIsSelecting ( true ) ;
201-
202- const range = s . getRangeAt ( 0 ) ;
203- const rects = range . getClientRects ( ) ;
204- const lastRect = rects [ rects . length - 1 ] ;
205- const containerRect =
206- wrapperRef && wrapperRef . current
207- ? wrapperRef . current . getBoundingClientRect ( )
208- : null ;
209-
210- if ( ! lastRect || ! containerRect ) return ;
211-
212- const relativeY =
213- lastRect . bottom - containerRect . top + wrapperRef . current . scrollTop ;
214- const relativeX =
215- lastRect . right - containerRect . left + wrapperRef . current . scrollLeft ;
216-
217- if ( relativeY > 0 || relativeX > 0 )
218- // Fix to avoid the button to be placed sometimes at the top left corner of the screen (X: 0, Y: 0)
219- setPosition ( {
220- x : relativeX ,
221- y : relativeY + 15 ,
222- } ) ;
223- } else {
224- setIsSelecting ( false ) ;
225- }
226- } ;
227-
228- document . addEventListener ( 'selectionchange' , handleSelectionChange ) ;
229-
230- return ( ) => {
231- document . removeEventListener ( 'selectionchange' , handleSelectionChange ) ;
232- } ;
233- } , [ wrapperRef ] ) ;
234-
235144 if ( ! video || isErrorVideo || ! video . transcript || isErrorObservations )
236145 return null ;
237146 if (
@@ -265,10 +174,9 @@ const Transcript = ({
265174 < HighlightContainer ref = { wrapperRef } >
266175 < Highlight
267176 search = { sanitizeInput ( debouncedValue ) }
268- handleSelection = { ( part ) => {
269- if ( ! isSelecting ) return ;
270-
271- handleSelection ( part ) ;
177+ onSelectionButtonClick = { handleAddObservation }
178+ i18n = { {
179+ selectionButtonLabel : t ( '__VIDEO_PAGE_ADD_OBSERVATION' ) ,
272180 } }
273181 >
274182 < ChipsWrap id = "chips-wrap" >
@@ -313,7 +221,6 @@ const Transcript = ({
313221 color = { o . color }
314222 observationId = { o . id }
315223 label = { o . label }
316- isSelecting = { isSelecting }
317224 />
318225 ) ) }
319226 </ TagsWrapper >
@@ -322,21 +229,6 @@ const Transcript = ({
322229 ) ) }
323230 </ ParagraphMeta >
324231 ) ) }
325- { isSelecting && (
326- < CreateObservationButton
327- size = "small"
328- id = "add-observation-button"
329- isAccent
330- isPrimary
331- onClick = { handleAddObservation }
332- position = { position || { x : 0 , y : 0 } }
333- >
334- < Button . StartIcon >
335- < TagIcon />
336- </ Button . StartIcon >
337- { t ( '__VIDEO_PAGE_ADD_OBSERVATION' ) }
338- </ CreateObservationButton >
339- ) }
340232 </ ChipsWrap >
341233 </ Highlight >
342234 </ HighlightContainer >
0 commit comments