Skip to content

Commit

Permalink
revert "do not render controls for no inview comments" (#394)
Browse files Browse the repository at this point in the history
  • Loading branch information
4vanger authored Aug 26, 2024
1 parent 9c02b3d commit cc31207
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 168 deletions.
21 changes: 0 additions & 21 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"react-hook-form": "^7.29.0",
"react-hotkeys-hook": "^4.3.8",
"react-icons": "^4.3.1",
"react-intersection-observer": "^9.13.0",
"react-outside-click-handler": "^1.3.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.0",
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/API/use/useInterpreter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useAPI} from '../../AppState/AppState';
import React, {useEffect, useState} from 'react';
import React, {useEffect, useRef, useState} from 'react';
import {TranslateModes} from '../PostAPI';
import googleTranslate from '../../Utils/googleTranslate';
import {toast} from 'react-toastify';
Expand All @@ -14,8 +14,9 @@ export type AltContentType = 'translate' | TranslateModes;
export const ANNOTATE_LIMIT = 1024;
export const ALT_TRANSLATE_LIMIT = 4*1024;

export function useInterpreter(contentRef: React.RefObject<HTMLDivElement>, originalContent: string, originalTitle: string | undefined, id: number, type: 'post' | 'comment') {
export function useInterpreter(originalContent: string, originalTitle: string | undefined, id: number, type: 'post' | 'comment') {
const api = useAPI();
const contentRef = useRef<HTMLDivElement>(null);
const [currentMode, setCurrentMode] = React.useState<AltContentType | undefined>();
const [cachedTitleTranslation, setCachedTitleTranslation] = useState<string | undefined>();
const [cachedContentTranslation, setCachedContentTranslation] = useState<string | undefined>();
Expand Down Expand Up @@ -148,7 +149,7 @@ export function useInterpreter(contentRef: React.RefObject<HTMLDivElement>, orig
}
}

}, [currentMode, contentRef]);
}, [currentMode]);

return {contentRef, currentMode, inProgress, altTitle, altContent, translate, annotate, altTranslate,
calcShowAltTranslate, calcShowAnnotate
Expand Down
180 changes: 74 additions & 106 deletions frontend/src/Components/CommentComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {CommentInfo, PostLinkInfo} from '../Types/PostInfo';
import styles from './CommentComponent.module.scss';
import postStyles from './PostComponent.module.scss';
import RatingSwitch from './RatingSwitch';
import React, {useContext, useEffect, useMemo, useRef, useState} from 'react';
import React, {useMemo, useState} from 'react';
import {CreateCommentComponentRestricted} from './CreateCommentComponent';
import ContentComponent, {LARGE_AUTO_CUT} from './ContentComponent';
import {ReactComponent as OptionsIcon} from '../Assets/options.svg';
Expand All @@ -14,7 +14,6 @@ import Conf from '../Conf';
import {useInterpreter} from '../API/use/useInterpreter';
import OutsideClickHandler from 'react-outside-click-handler';
import {AltTranslateButton, AnnotateButton, TranslateButton} from './ContentButtons';
import {InviewContext} from '../Pages/PostPage';
import {getPreferredLang, getShowInlineTranslateButton} from './UserProfileSettings';

interface CommentProps {
Expand All @@ -35,8 +34,22 @@ export default function CommentComponent(props: CommentProps) {
const [answerOpen, setAnswerOpen] = useState(false);
const [editingText, setEditingText] = useState<false | string>(false);
const [showHistory, setShowHistory] = useState(false);
const [altContent, setAltContent] = useState<string | undefined>(undefined);
const contentRef = useRef<HTMLDivElement>(null);
const [showOptions, setShowOptions] = useState(false);

const api = useAPI();
const {currentMode, inProgress, contentRef, altContent, translate, annotate, altTranslate,
calcShowAnnotate, calcShowAltTranslate
} = useInterpreter(props.comment.content, undefined, props.comment.id, 'comment');

const handleAnswerSwitch = (e: React.MouseEvent) => {
e.preventDefault();
setAnswerOpen(!answerOpen);
};

const toggleOptions = () => {
setShowOptions(!showOptions);
};

const handleAnswer = async (text: string, post?: PostLinkInfo, comment?: CommentInfo) => {
if (!post) {
return undefined;
Expand All @@ -59,6 +72,23 @@ export default function CommentComponent(props: CommentProps) {
}
};

const handleVote = useMemo(() => {
return (value: number, vote?: number) => {
props.comment.rating = value;
props.comment.vote = vote;
};
}, [props.comment]);

const handleEdit = async () => {
try {
const comment = await api.postAPI.getComment(props.comment.id, 'source');
setEditingText(comment.comment.content);
}
catch (e) {
console.log('Get comment error:', e);
toast.error('Не удалось включить редактирование');
}
};

const toggleHistory = () => {
setShowHistory(!showHistory);
Expand All @@ -70,7 +100,10 @@ export default function CommentComponent(props: CommentProps) {
const depth = props.depth || 0;
const maxDepth = props.maxTreeDepth || 0;
const isFlat = depth > maxDepth;
const isInView = useContext(InviewContext);

const showTranslateButtonInline = useMemo(() => {
return getShowInlineTranslateButton() && props.comment.language !== getPreferredLang();
}, [props.comment]);

return (
<div className={`comment ${styles.comment} ${props.comment.isNew ? ' isNew': ''} ${isFlat?' isFlat':''}`} data-comment-id={props.comment.id}>
Expand All @@ -95,17 +128,42 @@ export default function CommentComponent(props: CommentProps) {
comment={props.comment}
open={true} text={editingText} onAnswer={handleEditComplete} />
}
{isInView && <Controls {...{
contentRef,
comment: props.comment,
setEditingText,
hideRating: props.hideRating,
onEdit: props.onEdit,
onAnswer: props.onAnswer,
answerOpen,
setAnswerOpen,
setAltContent
}}/>}

<div className={styles.controls}>
{!props.hideRating &&
<div className={styles.control}>
<RatingSwitch type="comment" id={props.comment.id} rating={{ vote: props.comment.vote, value: props.comment.rating }} onVote={handleVote} />
</div>}
{props.comment.canEdit && props.onEdit && <div className={styles.control}><button onClick={handleEdit} className='i i-edit' /></div>}

<div className={styles.control + ' ' + postStyles.options}>
{(showTranslateButtonInline || currentMode === 'translate') &&
<div className={styles.control}>
<TranslateButton iconOnly={true} isActive={currentMode === 'translate'} inProgress={inProgress} onClick={translate} />
</div>}
{currentMode === 'altTranslate' &&
<div className={styles.control}>
<AltTranslateButton iconOnly={true} isActive={true} inProgress={inProgress} onClick={altTranslate}/>
</div>}
{currentMode === 'annotate' &&
<div className={styles.control}>
<AnnotateButton iconOnly={true} isActive={true} inProgress={inProgress} onClick={annotate} />
</div>}

<button onClick={toggleOptions} className={styles.options + ' ' + (showOptions ? styles.active : '')}><OptionsIcon /></button>
{showOptions &&
<OutsideClickHandler onOutsideClick={() => setShowOptions(false)}>
<div className={postStyles.optionsList}>
<TranslateButton inProgress={inProgress} onClick={() => {setShowOptions(false);translate();}} isActive={currentMode === 'translate'} />
{calcShowAltTranslate() &&
<AltTranslateButton inProgress={inProgress} onClick={() => {setShowOptions(false);altTranslate();}} isActive={currentMode === 'altTranslate'}/>}
{calcShowAnnotate() &&
<AnnotateButton inProgress={inProgress} onClick={() => {setShowOptions(false);annotate();}} isActive={currentMode === 'annotate'} />}
</div>
</OutsideClickHandler>}
</div>
{props.onAnswer && <div className={styles.control}><button onClick={handleAnswerSwitch}>{!answerOpen ? 'Ответить' : 'Не отвечать'}</button></div>}
</div>
</div>
{(props.comment.answers || answerOpen) ?
<div className={styles.answers + (isFlat?' isFlat':'')}>
Expand All @@ -122,94 +180,4 @@ export default function CommentComponent(props: CommentProps) {

</div>
);
}

interface ControlsProps {
contentRef: React.RefObject<HTMLDivElement>;
comment: CommentInfo;
setEditingText: (text: string) => void;
hideRating?: boolean;
onEdit?: (text: string, comment: CommentInfo) => Promise<CommentInfo | undefined>;
onAnswer?: (text: string, post?: PostLinkInfo, comment?: CommentInfo) => Promise<CommentInfo | undefined>;
answerOpen: boolean;
setAnswerOpen: (value: boolean) => void;
setAltContent: (value: string | undefined) => void;
}

function Controls({contentRef, comment, setEditingText, hideRating, onEdit, onAnswer, answerOpen, setAnswerOpen, setAltContent: setCommentAltContent}: ControlsProps) {
const api = useAPI();

const handleVote = useMemo(() => {
return (value: number, vote?: number) => {
comment.rating = value;
comment.vote = vote;
};
}, [comment]);
const handleEdit = async () => {
try {
const commentResponse = await api.postAPI.getComment(comment.id, 'source');
setEditingText(commentResponse.comment.content);
}
catch (e) {
console.log('Get comment error:', e);
toast.error('Не удалось включить редактирование');
}
};

const [showOptions, setShowOptions] = useState(false);
const toggleOptions = () => {
setShowOptions(!showOptions);
};


const {currentMode, inProgress, altContent, translate, annotate, altTranslate,
calcShowAnnotate, calcShowAltTranslate
} = useInterpreter(contentRef, comment.content, undefined, comment.id, 'comment');
const handleAnswerSwitch = (e: React.MouseEvent) => {
e.preventDefault();
setAnswerOpen(!answerOpen);
};
useEffect(() => setCommentAltContent(altContent), [setCommentAltContent, altContent]);
const showTranslateButtonInline = useMemo(() => {
return getShowInlineTranslateButton() && comment.language !== getPreferredLang();
}, [comment]);

return (
<div className={styles.controls}>
{!hideRating &&
<div className={styles.control}>
<RatingSwitch type="comment" id={comment.id} rating={{ vote: comment.vote, value: comment.rating }} onVote={handleVote} />
</div>}
{comment.canEdit && onEdit && <div className={styles.control}><button onClick={handleEdit} className='i i-edit' /></div>}

<div className={styles.control + ' ' + postStyles.options}>
{(showTranslateButtonInline || currentMode === 'translate') &&
<div className={styles.control}>
<TranslateButton iconOnly={true} isActive={currentMode === 'translate'} inProgress={inProgress} onClick={translate} />
</div>}
{currentMode === 'altTranslate' &&
<div className={styles.control}>
<AltTranslateButton iconOnly={true} isActive={true} inProgress={inProgress} onClick={altTranslate}/>
</div>}
{currentMode === 'annotate' &&
<div className={styles.control}>
<AnnotateButton iconOnly={true} isActive={true} inProgress={inProgress} onClick={annotate} />
</div>}

<button onClick={toggleOptions} className={styles.options + ' ' + (showOptions ? styles.active : '')}><OptionsIcon /></button>
{showOptions &&
<OutsideClickHandler onOutsideClick={() => setShowOptions(false)}>
<div className={postStyles.optionsList}>
{!showTranslateButtonInline && <TranslateButton inProgress={inProgress} onClick={() => {setShowOptions(false);translate();}} isActive={currentMode === 'translate'} />}
{calcShowAltTranslate() &&
<AltTranslateButton inProgress={inProgress} onClick={() => {setShowOptions(false);altTranslate();}} isActive={currentMode === 'altTranslate'}/>}
{calcShowAnnotate() &&
<AnnotateButton inProgress={inProgress} onClick={() => {setShowOptions(false);annotate();}} isActive={currentMode === 'annotate'} />}
</div>
</OutsideClickHandler>}
</div>
{onAnswer && <div className={styles.control}><button onClick={handleAnswerSwitch}>{!answerOpen ? 'Ответить' : 'Не отвечать'}</button></div>}
</div>
);

}
7 changes: 3 additions & 4 deletions frontend/src/Components/PostComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styles from './PostComponent.module.scss';
import RatingSwitch from './RatingSwitch';
import React, {useMemo, useRef, useState} from 'react';
import React, {useMemo, useState} from 'react';
import {PostInfo} from '../Types/PostInfo';
import ContentComponent from './ContentComponent';
import {ReactComponent as CommentsIcon} from '../Assets/comments.svg';
Expand Down Expand Up @@ -32,16 +32,15 @@ interface PostComponentProps {


export default function PostComponent(props: PostComponentProps) {
const contentRef = useRef<HTMLDivElement>(null);
const api = useAPI();
const currentUsername = useAppState().userInfo?.username;
const [showOptions, setShowOptions] = useState(false);
const [editingText, setEditingText] = useState<false | string>(false);
const [editingTitle, setEditingTitle] = useState<string>(props.post.title || '');
const [showHistory, setShowHistory] = useState(false);
const {currentMode, altTitle, altContent, inProgress,
translate, annotate, altTranslate, calcShowAltTranslate, calcShowAnnotate
} = useInterpreter(contentRef, props.post.content, props.post.title, props.post.id, 'post');
contentRef, translate, annotate, altTranslate, calcShowAltTranslate, calcShowAnnotate
} = useInterpreter(props.post.content, props.post.title, props.post.id, 'post');

const handleVote = useMemo(() => {
return (value: number, vote?: number) => {
Expand Down
Loading

0 comments on commit cc31207

Please sign in to comment.