Skip to content

Commit 61d82f1

Browse files
authored
Merge pull request #850 from AppQuality/transcript-add-obs-button
Transcript-add-obs-button
2 parents db14f5a + 1cc33fb commit 61d82f1

File tree

1 file changed

+34
-142
lines changed

1 file changed

+34
-142
lines changed

src/pages/Video/components/Transcript.tsx

Lines changed: 34 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
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';
1211
import { useTranslation } from 'react-i18next';
1312
import { useParams } from 'react-router-dom';
1413
import { appTheme } from 'src/app/theme';
15-
import { ReactComponent as TagIcon } from 'src/assets/icons/tag-icon.svg';
1614
import { ReactComponent as InfoIcon } from 'src/assets/info-transcript.svg';
1715
import { getColorWithAlpha } from 'src/common/utils';
1816
import {
@@ -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-
7862
const 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

Comments
 (0)