Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

features improvement #33

Merged
merged 5 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions server/controllers/questions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,20 @@ questionController.put({ path: '/:id', userType: UserType.CLASS }, async (req, r
question.soundVolume = data.soundVolume !== undefined ? data.soundVolume : question.soundVolume;
const dataStatus = data.status;
logger.info(`dataStatus: ${dataStatus}`);
if (dataStatus !== undefined && dataStatus !== null) {
const previousStatus = question.status;
if (previousStatus === QuestionStatus.STORYBOARD && dataStatus === QuestionStatus.PREMOUNTING) {
question.status = dataStatus;
question.feedback = [QuestionStatus.ONGOING, QuestionStatus.PREMOUNTING].includes(dataStatus) && data.feedback ? data.feedback : null;
question.feedbacks = null;
} else {
if (dataStatus !== undefined && dataStatus !== null) {
question.status = dataStatus;
question.feedbacks =
[QuestionStatus.ONGOING, QuestionStatus.PREMOUNTING].includes(dataStatus) && data.feedback
? [...(question.feedbacks || []), data.feedback]
: question.feedbacks || [];
}
}

await getRepository(Question).save(question);
res.sendJSON(question);
});
Expand Down
11 changes: 9 additions & 2 deletions server/entities/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export class Question implements QuestionInterface {
})
status: QuestionStatus;

@Column({ type: 'varchar', length: 2000, nullable: true })
public feedback: string | null;
@Column({
type: 'text',
nullable: true,
transformer: {
to: (value: string[] | null) => (value ? JSON.stringify(value) : null),
from: (value: string | null) => (value ? JSON.parse(value) : null),
},
})
public feedbacks: string[] | null;
}
11 changes: 6 additions & 5 deletions server/translations/defaultLocales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ export const locales = {
left: "gauche",
center: "centre",
right: "droite",
black: 'noir',
white: 'blanc',
red: 'rouge',
green: 'vert',
blue: 'bleu',
//--- part4 ---
part4_title: 'Prémontez votre <1>film</1>',
part4_subtitle1: 'Pour chaque séquence vous pouvez écrire et enregistrer une voix-off.',
Expand Down Expand Up @@ -107,13 +112,8 @@ export const locales = {
part6_subtitle1: 'À cette étape, vous pouvez pré-visualiser votre diaporama sonore achevé.',
part6_pdf_button: 'Télécharger le storyboard',
part6_mlt_button: 'Télécharger le fichier de montage',
part6_mp4_button: 'Générer votre vidéo',
part6_mp4_download_button: 'Télécharger votre vidéo !',
part6_mp4_generate_button: 'Générer une nouvelle vidéo',
part6_mp4_loading: 'Création de votre vidéo...',
part6_mp4_description_1: 'La génération de votre vidéo peut prendre du temps.',
part6_mp4_description_2: "Vous pouvez quitter et suivre à tout moment l'avancement du montage de votre vidéo sur cette page.",
part6_mp4_description_3: 'Votre vidéo sera disponible pendant 2 jours. Passé ce delai elle sera supprimée.',
part6_mp4_user_disabled: 'Connectez-vous et créez un projet pour générer une vidéo.',
part6_mp4_project_disabled: 'Créez un projet pour générer une vidéo.',
part6_subtitle2:
Expand Down Expand Up @@ -297,6 +297,7 @@ export const locales = {
collaboration_form_feedback_btn_feedback: 'Envoyer le retour',
collaboration_form_feedback_btn_ok: 'Valider le travail',
collaboration_form_feedback_error: 'Veuillez renseigner un message de retour.',
collaboration_previous_feedbacks_label: 'Retours précédents',
collaboration_form_feedback_label: 'Retours',
collaboration_form_feedback_placeholder: 'Vos retours (Raccourcir la durée de la séquence, monter le son, ...)',
collaboration_form_feedback_title: 'Travail à vérifier',
Expand Down
6 changes: 3 additions & 3 deletions server/xml/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ export function projectToMlt(allQuestions: Question[], project: Project, urlTran
size: fontSize,
weight: '500',
style: 'normal',
fgcolour: '#000000',
bgcolour: '#ffffffff',
olcolour: '#ffffffff',
fgcolour: style.color || '#000000',
bgcolour: style.backgroundColor || '#ffffffff',
olcolour: style.backgroundColor || '#ffffffff',
halign: 'center',
valign: 'middle',
mlt_service: 'dynamictext',
Expand Down
13 changes: 12 additions & 1 deletion src/components/collaboration/FormFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const FormFeedback: React.FunctionComponent<FormFeedbackProps> = ({ quest
newQuestions[question.index] = {
...newQuestions[question.index],
status,
feedback: feedbackData,
feedbacks: feedbackData ? [...(question.feedbacks ?? []), feedbackData] : question.feedbacks,
};
const updatedProject = updateProject({ questions: newQuestions });
if (updatedProject) {
Expand Down Expand Up @@ -87,6 +87,17 @@ export const FormFeedback: React.FunctionComponent<FormFeedbackProps> = ({ quest
{t('collaboration_form_feedback_title')}
</h2>

{question.feedbacks && question.feedbacks.length > 0 && (
<div>
<div style={{ fontSize: '14px' }}>{t('collaboration_previous_feedbacks_label')} :</div>
<ul>
{question.feedbacks.map((feedbackItem, index) => (
<li key={index}>{feedbackItem}</li>
))}
</ul>
</div>
)}

<Field
marginTop="sm"
name="feedback"
Expand Down
12 changes: 11 additions & 1 deletion src/components/create/DiaporamaCard/DiaporamaCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export const DiaporamaCard = ({ projectId, questionIndex, sequence, isAuthorized
const [frameIndex, setFrameIndex] = React.useState<'title' | number>(sequence.title !== null ? 'title' : 0);
const [canvasRef, { height: canvasHeight }] = useResizeObserver<HTMLAnchorElement>();

const baseButtonStyle: React.CSSProperties = { width: '100%', height: '100%', pointerEvents: isAuthorized ? 'auto' : 'none' };
const buttonStyle = React.useMemo(() => {
const plan = frameIndex !== 'title' ? (sequence.plans || [])[frameIndex] : undefined;
if (plan && plan.imageUrl) {
Expand All @@ -48,6 +47,14 @@ export const DiaporamaCard = ({ projectId, questionIndex, sequence, isAuthorized
}
}, [sequence]);

const baseButtonStyle: React.CSSProperties = {
width: '100%',
height: '100%',
pointerEvents: isAuthorized ? 'auto' : 'none',
backgroundColor: style.backgroundColor || 'white',
color: style.color || 'black',
};

const updateFrameIndex = React.useCallback(() => {
setFrameIndex((prevFrame) => {
let nextFrame: 'title' | number = prevFrame === 'title' ? 0 : prevFrame + 1;
Expand Down Expand Up @@ -87,6 +94,9 @@ export const DiaporamaCard = ({ projectId, questionIndex, sequence, isAuthorized
left: `${style.x ?? 15}%`,
top: `${style.y ?? 30}%`,
width: `${style.width ?? 70}%`,
backgroundColor: style.backgroundColor || 'white',
textAlign: style.textAlign || 'center',
color: style.color || 'black',
}
}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/create/DiaporamaPlayer/DiaporamaPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ export const DiaporamaPlayer = ({
setVolume(newValue);
onUpdateVolume(newValue);
}}
max={200}
max={300}
min={0}
orientation="vertical"
/>
Expand Down
10 changes: 9 additions & 1 deletion src/components/create/DiaporamaPlayer/Frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ type FrameProps = {
time: number;
className?: string;
};

type TextAlign = 'left' | 'center' | 'right';

export const Frame = ({ questions, time, className }: FrameProps) => {
const [canvasRef, { height: canvasHeight }] = useResizeObserver<HTMLDivElement>();
const currentFrame = getCurrentFrame(questions, time);
Expand All @@ -62,7 +65,11 @@ export const Frame = ({ questions, time, className }: FrameProps) => {
style={{
width: '100%',
height: '100%',
backgroundColor: currentFrame !== null && currentFrame.kind === 'title' ? 'white' : 'unset',
backgroundColor:
currentFrame !== null && currentFrame.kind === 'title' ? (currentFrame.style.backgroundColor as string) || 'white' : 'white',
color: currentFrame !== null && currentFrame.kind === 'title' ? String(currentFrame.style.color) || 'black' : 'black',
textAlign:
currentFrame !== null && currentFrame.kind === 'title' ? (currentFrame.style.textAlign as TextAlign) || 'center' : 'center',
}}
ref={canvasRef}
>
Expand All @@ -81,6 +88,7 @@ export const Frame = ({ questions, time, className }: FrameProps) => {
left: `${currentFrame.style.x ?? 15}%`,
top: `${currentFrame.style.y ?? 30}%`,
width: `${currentFrame.style.width ?? 70}%`,
textAlign: (currentFrame.style.textAlign as TextAlign) || 'center',
}
}
>
Expand Down
68 changes: 66 additions & 2 deletions src/components/create/TitleCanvas/TitleCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {
const [fontFamily, setFontFamily] = React.useState<string>(style.fontFamily || 'serif');
const [fontSize, setFontSize] = React.useState<number>(style.fontSize || 8); // %
const [textAlign, setTextAlign] = React.useState<TextAlign>(style.textAlign || 'center');
const [backgroundColor, setBackgroundColor] = React.useState<string>(style.backgroundColor || 'white');
const [color, setColor] = React.useState<string>(style.color || 'black');
// relative pos
const [textXPer, setTextXPer] = React.useState<number>(style.x ?? 15); // %
const [textYPer, setTextYPer] = React.useState<number>(style.y ?? 30); // %
Expand All @@ -46,6 +48,8 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {
setTextYPer(style.y ?? 35);
setTextWidthPer(style.width || 50);
setTextAlign(style.textAlign || 'center');
setBackgroundColor(style.backgroundColor || 'white');
setColor(style.color || 'black');
}, [title, style]);

const onChangeStyle = (newPartialSyle: Record<string, string | number>) => {
Expand All @@ -69,7 +73,7 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {
if (textAreaRef.current) {
setTextAreaRefHeight(textAreaRef.current.scrollHeight);
}
}, [titleText, textWidthPer, canvasWidth, fontSize, fontFamily, textAlign]); // update textAreaRefHeight on title change.
}, [titleText, textWidthPer, canvasWidth, fontSize, fontFamily, textAlign, backgroundColor]); // update textAreaRefHeight on title change.

// Absolute pos
const { textX, textY, textWidth } = React.useMemo(
Expand Down Expand Up @@ -141,7 +145,42 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {

return (
<div style={{ width: '100%', maxWidth: '600px', margin: '2rem auto' }} ref={canvasRef}>
<KeepRatio ratio={9 / 16} style={{ border: '1px solid grey', borderRadius: '8px' }}>
<div
style={{
display: 'inline-flex',
flexDirection: 'row',
alignItems: 'center',
backgroundColor: PrimaryColor,
color: '#fff',
padding: '0.1rem',
borderTopLeftRadius: '4px',
borderTopRightRadius: '4px',
}}
>
<select
value={backgroundColor}
onChange={(event) => {
const newBackgroundColor = event.target.value;
setBackgroundColor(newBackgroundColor);
onChangeStyle({ backgroundColor: newBackgroundColor });
}}
style={{
margin: '0 0.5rem',
backgroundColor: PrimaryColor,
color: '#fff',
border: 'none',
outline: 'none',
cursor: 'pointer',
}}
>
<option value={'white'}>{t('white')}</option>
<option value={'black'}>{t('black')}</option>
<option value={'#fbe5d3'}>{t('red')}</option>
<option value={'#dad7fe'}>{t('blue')}</option>
<option value={'#e2fbd7'}>{t('green')}</option>
</select>
</div>
<KeepRatio ratio={9 / 16} style={{ border: '1px solid grey', borderRadius: '0 8px 8px 8px', backgroundColor: backgroundColor }}>
<div
style={{
display: 'inline-block',
Expand Down Expand Up @@ -209,6 +248,7 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {
<option value={8}>{t('medium')}</option>
<option value={10}>{t('big')}</option>
</select>
<div style={{ height: '1rem', width: '1px', backgroundColor: '#fff' }}></div>
<select
value={textAlign}
onChange={(event) => {
Expand All @@ -229,6 +269,26 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {
<option value={'center'}>{t('center')}</option>
<option value={'right'}>{t('right')}</option>
</select>
<div style={{ height: '1rem', width: '1px', backgroundColor: '#fff' }}></div>
<select
value={color}
onChange={(event) => {
const newColor = event.target.value;
setBackgroundColor(color);
onChangeStyle({ color: newColor });
}}
style={{
margin: '0 0.5rem',
backgroundColor: PrimaryColor,
color: '#fff',
border: 'none',
outline: 'none',
cursor: 'pointer',
}}
>
<option value={'black'}>{t('black')}</option>
<option value={'white'}>{t('white')}</option>
</select>
</div>
<textarea
value={titleText}
Expand All @@ -255,6 +315,8 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {
fontFamily: fontFamily,
textAlign: textAlign,
resize: 'none',
backgroundColor: backgroundColor,
color: color,
}}
/>
<textarea
Expand All @@ -279,6 +341,8 @@ export function TitleCanvas({ title, onChange }: TitleCanvasProps) {
resize: 'none',
whiteSpace: 'pre-wrap',
wordBreak: 'break-word',
backgroundColor: backgroundColor,
color: color,
}}
></textarea>
<div
Expand Down
11 changes: 10 additions & 1 deletion src/components/create/TitleCard/TitleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ export const TitleCard = ({ projectId, questionIndex, title, onDelete = () => {}
}
}, [title]);
const [canvasRef, { height: canvasHeight }] = useResizeObserver<HTMLAnchorElement>();
const buttonStyle: React.CSSProperties = { width: '100%', height: '100%', pointerEvents: canEdit ? 'auto' : 'none' };
const buttonStyle: React.CSSProperties = {
width: '100%',
height: '100%',
pointerEvents: canEdit ? 'auto' : 'none',
backgroundColor: style ? style.backgroundColor : 'white',
color: style ? style.color : 'black',
};

return (
<Link
Expand All @@ -52,6 +58,9 @@ export const TitleCard = ({ projectId, questionIndex, title, onDelete = () => {}
left: `${style.x ?? 15}%`,
top: `${style.y ?? 30}%`,
width: `${style.width ?? 70}%`,
backgroundColor: style.backgroundColor || 'white',
textAlign: style.textAlign || 'center',
color: style.color || 'black',
}
}
>
Expand Down
1 change: 0 additions & 1 deletion src/components/layout/Form/input.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
.inputContainer {
display: block;
position: relative;
width: 300px;

&--is-full-width {
width: 100%;
Expand Down
6 changes: 3 additions & 3 deletions src/pages/create/3-storyboard/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const EditPlan = () => {
const { user } = React.useContext(userContext);
const isStudent = user?.type === UserType.STUDENT;
const [showButtonFeedback, setShowButtonFeedback] = React.useState(
(isStudent && sequence && sequence.feedback && QuestionStatus.ONGOING === sequence.status) as boolean,
(isStudent && sequence && sequence.feedbacks && QuestionStatus.ONGOING === sequence.status) as boolean,
);
const [showFeedback, setShowFeedback] = React.useState(false);
const imageUrl = React.useMemo(() => {
Expand All @@ -165,7 +165,7 @@ const EditPlan = () => {
}, [imageBlob, plan]);

React.useEffect(() => {
if (isStudent && sequence && sequence.feedback && QuestionStatus.ONGOING === sequence.status) {
if (isStudent && sequence && sequence.feedbacks && QuestionStatus.ONGOING === sequence.status) {
setShowButtonFeedback(true);
}
}, [isStudent, sequence]);
Expand Down Expand Up @@ -531,7 +531,7 @@ const EditPlan = () => {
<FeedbackModal
isOpen={showFeedback}
onClose={() => setShowFeedback(false)}
feedback={sequence && sequence.feedback ? sequence.feedback : ''}
feedback={sequence && sequence.feedbacks && sequence.feedbacks.length > 0 ? sequence.feedbacks[sequence.feedbacks.length - 1] : ''}
/>
</Container>
);
Expand Down
6 changes: 4 additions & 2 deletions src/pages/create/3-storyboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const Scenario = ({

const plans = React.useMemo(() => sequence.plans || [], [sequence]);
const [showFeedback, setShowFeedback] = React.useState(false);
const showButtonFeedback = isStudent && sequence.feedback && QuestionStatus.ONGOING === sequence.status;
const showButtonFeedback = isStudent && sequence.feedbacks && QuestionStatus.ONGOING === sequence.status;
const studentColor = COLORS[sequenceIndex];

const { project, isLoading: isProjectLoading, questions, updateProject } = useCurrentProject();
Expand Down Expand Up @@ -267,7 +267,9 @@ const Scenario = ({
<FeedbackModal
isOpen={showFeedback}
onClose={() => setShowFeedback(false)}
feedback={sequence && sequence.feedback ? sequence.feedback : ''}
feedback={
sequence && sequence.feedbacks && sequence.feedbacks.length > 0 ? sequence.feedbacks[sequence.feedbacks.length - 1] : ''
}
/>
</div>
{isCollaborationActive && !isStudent && sequence.status === QuestionStatus.STORYBOARD && (
Expand Down
Loading
Loading