From d0b1c8c1b37a421e9cdcb0e4d3ee300d5cbfcafc Mon Sep 17 00:00:00 2001 From: Emil <Emil> Date: Tue, 27 Apr 2021 18:47:01 +0200 Subject: [PATCH 1/2] viewType added --- client/src/actions/editor.ts | 14 ++++- client/src/actions/types.ts | 1 + client/src/interfaces/ApiModels.ts | 2 + .../PresentationEditorPage.tsx | 14 +++-- .../components/SlideSettings.tsx | 9 +++- .../components/TextComponentEdit.tsx | 1 + .../slideSettingsComponents/Images.tsx | 4 +- .../slideSettingsComponents/Texts.tsx | 4 +- client/src/reducers/editorReducer.ts | 7 +++ server/app/apis/components.py | 1 + server/app/core/schemas.py | 1 + server/app/core/sockets.py | 52 ++++++++++++++----- server/app/database/controller/add.py | 6 +-- server/app/database/controller/copy.py | 1 + server/app/database/models.py | 3 +- server/populate.py | 2 +- server/tests/test_helpers.py | 2 +- 17 files changed, 96 insertions(+), 28 deletions(-) diff --git a/client/src/actions/editor.ts b/client/src/actions/editor.ts index db688dcb..526ad9ff 100644 --- a/client/src/actions/editor.ts +++ b/client/src/actions/editor.ts @@ -18,16 +18,28 @@ export const getEditorCompetition = (id: string) => async (dispatch: AppDispatch if (getState().editor.activeSlideId === -1 && res.data.slides[0]) { setEditorSlideId(res.data.slides[0].id)(dispatch) } + const defaultViewType = getState().types.viewTypes.find((viewType) => viewType.name === 'Audience') + if (getState().editor.activeViewTypeId === -1 && defaultViewType) { + setEditorViewId(defaultViewType.id)(dispatch) + } }) .catch((err) => { console.log(err) }) } -// Set currentSlideId in editor state +// Set activeSlideId in editor state export const setEditorSlideId = (id: number) => (dispatch: AppDispatch) => { dispatch({ type: Types.SET_EDITOR_SLIDE_ID, payload: id, }) } + +// Set activeViewTypeId in editor state +export const setEditorViewId = (id: number) => (dispatch: AppDispatch) => { + dispatch({ + type: Types.SET_EDITOR_VIEW_ID, + payload: id, + }) +} diff --git a/client/src/actions/types.ts b/client/src/actions/types.ts index 445a8d86..2e9fc776 100644 --- a/client/src/actions/types.ts +++ b/client/src/actions/types.ts @@ -24,6 +24,7 @@ export default { SET_COMPETITIONS_COUNT: 'SET_COMPETITIONS_COUNT', SET_EDITOR_COMPETITION: 'SET_EDITOR_COMPETITION', SET_EDITOR_SLIDE_ID: 'SET_EDITOR_SLIDE_ID', + SET_EDITOR_VIEW_ID: 'SET_EDITOR_VIEW_ID', SET_PRESENTATION_COMPETITION: 'SET_PRESENTATION_COMPETITION', SET_PRESENTATION_SLIDE: 'SET_PRESENTATION_SLIDE', SET_PRESENTATION_SLIDE_PREVIOUS: 'SET_PRESENTATION_SLIDE_PREVIOUS', diff --git a/client/src/interfaces/ApiModels.ts b/client/src/interfaces/ApiModels.ts index 4de675fb..faecc98f 100644 --- a/client/src/interfaces/ApiModels.ts +++ b/client/src/interfaces/ApiModels.ts @@ -81,6 +81,8 @@ export interface Component { w: number h: number type_id: number + view_type_id: number + slide_id: number } export interface ImageComponent extends Component { diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx index 3c86afe9..50c3ae52 100644 --- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx +++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx @@ -14,7 +14,7 @@ import axios from 'axios' import React, { useEffect, useState } from 'react' import { Link, useParams } from 'react-router-dom' import { getCities } from '../../actions/cities' -import { getEditorCompetition, setEditorSlideId } from '../../actions/editor' +import { getEditorCompetition, setEditorSlideId, setEditorViewId } from '../../actions/editor' import { getTypes } from '../../actions/typesAction' import { useAppDispatch, useAppSelector } from '../../hooks' import { RichSlide } from '../../interfaces/ApiRichModels' @@ -165,6 +165,14 @@ const PresentationEditorPage: React.FC = () => { })((props: CheckboxProps) => <Checkbox color="default" {...props} />) const [checkbox, setCheckbox] = useState(false) + const viewTypes = useAppSelector((state) => state.types.viewTypes) + const changeView = (clickedViewTypeName: string) => { + const clickedViewTypeId = viewTypes.find((viewType) => viewType.name === clickedViewTypeName)?.id + if (clickedViewTypeId) { + dispatch(setEditorViewId(clickedViewTypeId)) + } + } + return ( <PresentationEditorContainer> <CssBaseline /> @@ -182,10 +190,10 @@ const PresentationEditorPage: React.FC = () => { <Typography className={classes.alignCheckboxText} variant="button"> Applicera ändringar på samtliga vyer </Typography> - <ViewButton variant="contained" color="secondary"> + <ViewButton variant="contained" color="secondary" onClick={() => changeView('Audience')}> Åskådarvy </ViewButton> - <ViewButton variant="contained" color="secondary"> + <ViewButton variant="contained" color="secondary" onClick={() => changeView('Team')}> Deltagarvy </ViewButton> </ViewButtonGroup> diff --git a/client/src/pages/presentationEditor/components/SlideSettings.tsx b/client/src/pages/presentationEditor/components/SlideSettings.tsx index 278887c1..41c1354f 100644 --- a/client/src/pages/presentationEditor/components/SlideSettings.tsx +++ b/client/src/pages/presentationEditor/components/SlideSettings.tsx @@ -24,6 +24,7 @@ const SlideSettings: React.FC = () => { // Gets the slide with id=activeSlideId from the database. state.editor.competition.slides.find((slide) => slide && slide.id === state.editor.activeSlideId) ) + const activeViewTypeId = useAppSelector((state) => state.editor.activeViewTypeId) return ( <PanelContainer> @@ -47,9 +48,13 @@ const SlideSettings: React.FC = () => { <MultipleChoiceAlternatives activeSlide={activeSlide} competitionId={competitionId} /> )} - {activeSlide && <Texts activeSlide={activeSlide} competitionId={competitionId} />} + {activeSlide && ( + <Texts activeViewTypeId={activeViewTypeId} activeSlide={activeSlide} competitionId={competitionId} /> + )} - {activeSlide && <Images activeSlide={activeSlide} competitionId={competitionId} />} + {activeSlide && ( + <Images activeViewTypeId={activeViewTypeId} activeSlide={activeSlide} competitionId={competitionId} /> + )} <SettingsList> <ListItem button> diff --git a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx index b03696f3..f6cda576 100644 --- a/client/src/pages/presentationEditor/components/TextComponentEdit.tsx +++ b/client/src/pages/presentationEditor/components/TextComponentEdit.tsx @@ -20,6 +20,7 @@ const TextComponentEdit = ({ component }: ImageComponentProps) => { const [content, setContent] = useState('') const [timerHandle, setTimerHandle] = React.useState<number | undefined>(undefined) const activeSlideId = useAppSelector((state) => state.editor.activeSlideId) + const activeViewTypeId = useAppSelector((state) => state.editor.activeViewTypeId) const dispatch = useAppDispatch() useEffect(() => { diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx index fa087dcc..bc83d2fa 100644 --- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx +++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx @@ -11,11 +11,12 @@ import { ImageComponent, Media } from '../../../../interfaces/ApiModels' import { useAppDispatch, useAppSelector } from '../../../../hooks' type ImagesProps = { + activeViewTypeId: number activeSlide: RichSlide competitionId: string } -const Images = ({ activeSlide, competitionId }: ImagesProps) => { +const Images = ({ activeViewTypeId, activeSlide, competitionId }: ImagesProps) => { const dispatch = useAppDispatch() const uploadFile = async (formData: FormData) => { @@ -37,6 +38,7 @@ const Images = ({ activeSlide, competitionId }: ImagesProps) => { y: 0, media_id: media.id, type_id: 2, + view_type_id: activeViewTypeId, } await axios .post(`/api/competitions/${competitionId}/slides/${activeSlide?.id}/components`, imageData) diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx index 39cf09af..b1e9fa9b 100644 --- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx +++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx @@ -9,11 +9,12 @@ import axios from 'axios' import { getEditorCompetition } from '../../../../actions/editor' type TextsProps = { + activeViewTypeId: number activeSlide: RichSlide competitionId: string } -const Texts = ({ activeSlide, competitionId }: TextsProps) => { +const Texts = ({ activeViewTypeId, activeSlide, competitionId }: TextsProps) => { const texts = useAppSelector( (state) => state.editor.competition.slides @@ -29,6 +30,7 @@ const Texts = ({ activeSlide, competitionId }: TextsProps) => { text: 'Ny text', w: 315, h: 50, + view_type_id: activeViewTypeId, }) dispatch(getEditorCompetition(competitionId)) } diff --git a/client/src/reducers/editorReducer.ts b/client/src/reducers/editorReducer.ts index 88e6e368..4f245d1d 100644 --- a/client/src/reducers/editorReducer.ts +++ b/client/src/reducers/editorReducer.ts @@ -5,6 +5,7 @@ import { RichCompetition } from '../interfaces/ApiRichModels' interface EditorState { competition: RichCompetition activeSlideId: number + activeViewTypeId: number loading: boolean } @@ -19,6 +20,7 @@ const initialState: EditorState = { background_image: undefined, }, activeSlideId: -1, + activeViewTypeId: -1, loading: true, } @@ -35,6 +37,11 @@ export default function (state = initialState, action: AnyAction) { ...state, activeSlideId: action.payload as number, } + case Types.SET_EDITOR_VIEW_ID: + return { + ...state, + activeViewTypeId: action.payload as number, + } default: return state } diff --git a/server/app/apis/components.py b/server/app/apis/components.py index 8ab67b8c..8f253151 100644 --- a/server/app/apis/components.py +++ b/server/app/apis/components.py @@ -22,6 +22,7 @@ component_edit_parser.add_argument("media_id", type=str, location="json") component_create_parser = component_edit_parser.copy() component_create_parser.add_argument("type_id", type=int, required=True, location="json") +component_create_parser.add_argument("view_type_id", type=int, required=True, location="json") @api.route("/<component_id>") diff --git a/server/app/core/schemas.py b/server/app/core/schemas.py index 0abe0252..31e79e69 100644 --- a/server/app/core/schemas.py +++ b/server/app/core/schemas.py @@ -161,6 +161,7 @@ class ComponentSchema(BaseSchema): h = ma.auto_field() slide_id = ma.auto_field() type_id = ma.auto_field() + view_type_id = ma.auto_field() text = fields.fields.String() media = fields.Nested(MediaSchema, many=False) diff --git a/server/app/core/sockets.py b/server/app/core/sockets.py index 00b2ddf5..b62f82c9 100644 --- a/server/app/core/sockets.py +++ b/server/app/core/sockets.py @@ -9,7 +9,7 @@ logger = logging.getLogger(__name__) logger.propagate = False logger.setLevel(logging.INFO) -formatter = logging.Formatter('[%(levelname)s] %(funcName)s: %(message)s') +formatter = logging.Formatter("[%(levelname)s] %(funcName)s: %(message)s") stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) logger.addHandler(stream_handler) @@ -44,7 +44,9 @@ def start_presentation(data): competition_id = data["competition_id"] if competition_id in presentations: - logger.error(f"Client '{request.sid}' failed to start competition '{competition_id}', presentation already active") + logger.error( + f"Client '{request.sid}' failed to start competition '{competition_id}', presentation already active" + ) return presentations[competition_id] = { @@ -58,16 +60,21 @@ def start_presentation(data): logger.info(f"Client '{request.sid}' started competition '{competition_id}'") + @sio.on("end_presentation") def end_presentation(data): competition_id = data["competition_id"] if competition_id not in presentations: - logger.error(f"Client '{request.sid}' failed to end presentation '{competition_id}', no such presentation exists") + logger.error( + f"Client '{request.sid}' failed to end presentation '{competition_id}', no such presentation exists" + ) return if request.sid not in presentations[competition_id]["clients"]: - logger.error(f"Client '{request.sid}' failed to end presentation '{competition_id}', client not in presentation") + logger.error( + f"Client '{request.sid}' failed to end presentation '{competition_id}', client not in presentation" + ) return if presentations[competition_id]["clients"][request.sid]["view_type"] != "Operator": @@ -96,11 +103,15 @@ def join_presentation(data): competition_id = item_code.competition_id if competition_id not in presentations: - logger.error(f"Client '{request.sid}' failed to join presentation '{competition_id}', no such presentation exists") + logger.error( + f"Client '{request.sid}' failed to join presentation '{competition_id}', no such presentation exists" + ) return if request.sid in presentations[competition_id]["clients"]: - logger.error(f"Client '{request.sid}' failed to join presentation '{competition_id}', client already in presentation") + logger.error( + f"Client '{request.sid}' failed to join presentation '{competition_id}', client already in presentation" + ) return # TODO: Write function in database controller to do this @@ -120,21 +131,29 @@ def set_slide(data): slide_order = data["slide_order"] if competition_id not in presentations: - logger.error(f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', no such presentation exists") + logger.error( + f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', no such presentation exists" + ) return if request.sid not in presentations[competition_id]["clients"]: - logger.error(f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client not in presentation") + logger.error( + f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client not in presentation" + ) return if presentations[competition_id]["clients"][request.sid]["view_type"] != "Operator": - logger.error(f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client is not operator") + logger.error( + f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client is not operator" + ) return num_slides = db.session.query(Slide).filter(Slide.competition_id == competition_id).count() if not (0 <= slide_order < num_slides): - logger.error(f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', slide number {slide_order} does not exist") + logger.error( + f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', slide number {slide_order} does not exist" + ) return presentations[competition_id]["slide"] = slide_order @@ -151,15 +170,21 @@ def set_timer(data): timer = data["timer"] if competition_id not in presentations: - logger.error(f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', no such presentation exists") + logger.error( + f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', no such presentation exists" + ) return if request.sid not in presentations[competition_id]["clients"]: - logger.error(f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client not in presentation") + logger.error( + f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client not in presentation" + ) return if presentations[competition_id]["clients"][request.sid]["view_type"] != "Operator": - logger.error(f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client is not operator") + logger.error( + f"Client '{request.sid}' failed to set slide in presentation '{competition_id}', client is not operator" + ) return # TODO: Save timer in presentation, maybe? @@ -168,4 +193,3 @@ def set_timer(data): logger.debug(f"Emitting event 'set_timer' to room {competition_id} including self") logger.info(f"Client '{request.sid}' set timer '{timer}' in presentation '{competition_id}'") - diff --git a/server/app/database/controller/add.py b/server/app/database/controller/add.py index a83f5b95..f7b0edbb 100644 --- a/server/app/database/controller/add.py +++ b/server/app/database/controller/add.py @@ -59,7 +59,7 @@ def db_add(item): return item -def component(type_id, slide_id, x=0, y=0, w=0, h=0, **data): +def component(type_id, slide_id, view_type_id, x=0, y=0, w=0, h=0, **data): """ Adds a component to the slide at the specified coordinates with the provided size and data . @@ -80,10 +80,10 @@ def component(type_id, slide_id, x=0, y=0, w=0, h=0, **data): h *= ratio if type_id == 1: - item = db_add(TextComponent(slide_id, type_id, x, y, w, h)) + item = db_add(TextComponent(slide_id, type_id, view_type_id, x, y, w, h)) item.text = data.get("text") elif type_id == 2: - item = db_add(ImageComponent(slide_id, type_id, x, y, w, h)) + item = db_add(ImageComponent(slide_id, type_id, view_type_id, x, y, w, h)) item.media_id = data.get("media_id") else: abort(codes.BAD_REQUEST, f"Invalid type_id{type_id}") diff --git a/server/app/database/controller/copy.py b/server/app/database/controller/copy.py index 7e9d28d0..1874b5dc 100644 --- a/server/app/database/controller/copy.py +++ b/server/app/database/controller/copy.py @@ -45,6 +45,7 @@ def _component(item_component, item_slide_new): add.component( item_component.type_id, item_slide_new.id, + item_component.view_type_id, item_component.x, item_component.y, item_component.w, diff --git a/server/app/database/models.py b/server/app/database/models.py index 30129389..c84677b2 100644 --- a/server/app/database/models.py +++ b/server/app/database/models.py @@ -199,13 +199,14 @@ class Component(db.Model): __mapper_args__ = {"polymorphic_on": type_id} - def __init__(self, slide_id, type_id, x=0, y=0, w=1, h=1): + def __init__(self, slide_id, type_id, view_type_id, x=0, y=0, w=1, h=1): self.x = x self.y = y self.w = w self.h = h self.slide_id = slide_id self.type_id = type_id + self.view_type_id = view_type_id class TextComponent(Component): diff --git a/server/populate.py b/server/populate.py index 6a4be4ef..8bd2badc 100644 --- a/server/populate.py +++ b/server/populate.py @@ -86,7 +86,7 @@ def _add_items(): y = random.randrange(1, 500) w = random.randrange(150, 400) h = random.randrange(150, 400) - dbc.add.component(1, item_slide.id, x, y, w, h, text=f"hej{k}") + dbc.add.component(1, item_slide.id, 1, x, y, w, h, text=f"hej{k}") # item_slide = dbc.add.slide(item_comp) # item_slide.title = f"Slide {len(item_comp.slides)}" diff --git a/server/tests/test_helpers.py b/server/tests/test_helpers.py index b5f1e54e..9603fa59 100644 --- a/server/tests/test_helpers.py +++ b/server/tests/test_helpers.py @@ -59,7 +59,7 @@ def add_default_values(): # dbc.add.question(name=f"Q{i+1}", total_score=i + 1, type_id=1, slide_id=item_slide.id) # Add text component - dbc.add.component(1, item_slide.id, i, 2 * i, 3 * i, 4 * i, text="Text") + dbc.add.component(1, item_slide.id, 1, i, 2 * i, 3 * i, 4 * i, text="Text") def get_body(response): -- GitLab From 61d47b9aa60cce4c0c5faa4f4a435fb6136e8d8e Mon Sep 17 00:00:00 2001 From: Emil <Emil> Date: Wed, 28 Apr 2021 10:11:19 +0200 Subject: [PATCH 2/2] Feat: change view type in editor --- .../PresentationEditorPage.tsx | 20 +++++++-- .../components/SlideDisplay.tsx | 42 +++++++++++-------- .../slideSettingsComponents/Images.tsx | 24 ++++++----- .../slideSettingsComponents/Texts.tsx | 14 ++++--- .../src/pages/presentationEditor/styled.tsx | 12 +++++- client/src/pages/views/AudienceViewPage.tsx | 15 ++++--- client/src/pages/views/JudgeViewPage.tsx | 4 +- .../src/pages/views/ParticipantViewPage.tsx | 4 +- client/src/pages/views/PresenterViewPage.tsx | 4 +- 9 files changed, 90 insertions(+), 49 deletions(-) diff --git a/client/src/pages/presentationEditor/PresentationEditorPage.tsx b/client/src/pages/presentationEditor/PresentationEditorPage.tsx index 50c3ae52..47a746f2 100644 --- a/client/src/pages/presentationEditor/PresentationEditorPage.tsx +++ b/client/src/pages/presentationEditor/PresentationEditorPage.tsx @@ -30,6 +30,7 @@ import { SlideListItem, ToolBarContainer, ViewButton, + ViewButtonClicked, ViewButtonGroup, } from './styled' @@ -91,6 +92,7 @@ const PresentationEditorPage: React.FC = () => { const { competitionId }: CompetitionParams = useParams() const dispatch = useAppDispatch() const activeSlideId = useAppSelector((state) => state.editor.activeSlideId) + const activeViewTypeId = useAppSelector((state) => state.editor.activeViewTypeId) const competition = useAppSelector((state) => state.editor.competition) const competitionLoading = useAppSelector((state) => state.editor.loading) useEffect(() => { @@ -166,7 +168,9 @@ const PresentationEditorPage: React.FC = () => { const [checkbox, setCheckbox] = useState(false) const viewTypes = useAppSelector((state) => state.types.viewTypes) + const [activeViewTypeName, setActiveViewTypeName] = useState('') const changeView = (clickedViewTypeName: string) => { + setActiveViewTypeName(clickedViewTypeName) const clickedViewTypeId = viewTypes.find((viewType) => viewType.name === clickedViewTypeName)?.id if (clickedViewTypeId) { dispatch(setEditorViewId(clickedViewTypeId)) @@ -190,10 +194,20 @@ const PresentationEditorPage: React.FC = () => { <Typography className={classes.alignCheckboxText} variant="button"> Applicera ändringar på samtliga vyer </Typography> - <ViewButton variant="contained" color="secondary" onClick={() => changeView('Audience')}> + <ViewButton + activeView={activeViewTypeName === 'Audience'} + variant="contained" + color="secondary" + onClick={() => changeView('Audience')} + > Åskådarvy </ViewButton> - <ViewButton variant="contained" color="secondary" onClick={() => changeView('Team')}> + <ViewButton + activeView={activeViewTypeName === 'Team'} + variant="contained" + color="secondary" + onClick={() => changeView('Team')} + > Deltagarvy </ViewButton> </ViewButtonGroup> @@ -255,7 +269,7 @@ const PresentationEditorPage: React.FC = () => { <Content leftDrawerWidth={leftDrawerWidth} rightDrawerWidth={rightDrawerWidth}> <InnerContent> - <SlideDisplay editor /> + <SlideDisplay variant="editor" activeViewTypeId={activeViewTypeId} /> </InnerContent> </Content> <Menu diff --git a/client/src/pages/presentationEditor/components/SlideDisplay.tsx b/client/src/pages/presentationEditor/components/SlideDisplay.tsx index 6ddb38ef..b2ca9233 100644 --- a/client/src/pages/presentationEditor/components/SlideDisplay.tsx +++ b/client/src/pages/presentationEditor/components/SlideDisplay.tsx @@ -1,4 +1,3 @@ -import { Button, Typography } from '@material-ui/core' import React, { useEffect, useLayoutEffect, useRef, useState } from 'react' import { getTypes } from '../../../actions/typesAction' import { useAppDispatch, useAppSelector } from '../../../hooks' @@ -8,12 +7,13 @@ import { SlideEditorContainer, SlideEditorContainerRatio, SlideEditorPaper } fro type SlideDisplayProps = { //Prop to distinguish between editor and active competition - editor?: boolean | undefined + variant: 'editor' | 'presentation' + activeViewTypeId: number } -const SlideDisplay = ({ editor }: SlideDisplayProps) => { +const SlideDisplay = ({ variant, activeViewTypeId }: SlideDisplayProps) => { const components = useAppSelector((state) => { - if (editor) + if (variant === 'editor') return state.editor.competition.slides.find((slide) => slide.id === state.editor.activeSlideId)?.components return state.presentation.competition.slides.find((slide) => slide.id === state.presentation.slide.id)?.components }) @@ -43,21 +43,29 @@ const SlideDisplay = ({ editor }: SlideDisplayProps) => { <SlideEditorContainerRatio> <SlideEditorPaper ref={editorPaperRef}> {components && - components.map((component) => { - if (editor) + components + .filter((component) => component.view_type_id === activeViewTypeId) + .map((component) => { + if (variant === 'editor') + return ( + <RndComponent + height={height} + width={width} + key={component.id} + component={component} + scale={scale} + /> + ) return ( - <RndComponent height={height} width={width} key={component.id} component={component} scale={scale} /> + <PresentationComponent + height={height} + width={width} + key={component.id} + component={component} + scale={scale} + /> ) - return ( - <PresentationComponent - height={height} - width={width} - key={component.id} - component={component} - scale={scale} - /> - ) - })} + })} </SlideEditorPaper> </SlideEditorContainerRatio> </SlideEditorContainer> diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx index bc83d2fa..a76075c4 100644 --- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx +++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Images.tsx @@ -96,17 +96,19 @@ const Images = ({ activeViewTypeId, activeSlide, competitionId }: ImagesProps) = </Center> </ListItem> {images && - images.map((image) => ( - <div key={image.id}> - <ListItem divider button> - <ImportedImage src={`http://localhost:5000/static/images/thumbnail_${image.media?.filename}`} /> - <Center> - <ListItemText primary={image.media?.filename} /> - </Center> - <CloseIcon onClick={() => handleCloseimageClick(image)} /> - </ListItem> - </div> - ))} + images + .filter((image) => image.view_type_id === activeViewTypeId) + .map((image) => ( + <div key={image.id}> + <ListItem divider button> + <ImportedImage src={`http://localhost:5000/static/images/thumbnail_${image.media?.filename}`} /> + <Center> + <ListItemText primary={image.media?.filename} /> + </Center> + <CloseIcon onClick={() => handleCloseimageClick(image)} /> + </ListItem> + </div> + ))} <ListItem button style={{ padding: 0 }}> <HiddenInput accept="image/*" id="contained-button-file" multiple type="file" onChange={handleFileSelected} /> diff --git a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx index b1e9fa9b..03656614 100644 --- a/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx +++ b/client/src/pages/presentationEditor/components/slideSettingsComponents/Texts.tsx @@ -44,12 +44,14 @@ const Texts = ({ activeViewTypeId, activeSlide, competitionId }: TextsProps) => </Center> </ListItem> {texts && - texts.map((text) => ( - <TextCard elevation={4} key={text.id}> - <TextComponentEdit component={text} /> - <Divider /> - </TextCard> - ))} + texts + .filter((text) => text.view_type_id === activeViewTypeId) + .map((text) => ( + <TextCard elevation={4} key={text.id}> + <TextComponentEdit component={text} /> + <Divider /> + </TextCard> + ))} <ListItem button onClick={handleAddText}> <Center> <AddButton variant="button">Lägg till text</AddButton> diff --git a/client/src/pages/presentationEditor/styled.tsx b/client/src/pages/presentationEditor/styled.tsx index d1f05d6b..ea266c5e 100644 --- a/client/src/pages/presentationEditor/styled.tsx +++ b/client/src/pages/presentationEditor/styled.tsx @@ -7,8 +7,18 @@ export const ToolBarContainer = styled(Toolbar)` padding-left: 0; ` -export const ViewButton = styled(Button)` +interface ViewButtonProps { + activeView: boolean +} + +export const ViewButton = styled(Button)<ViewButtonProps>` + margin-right: 8px; + background: ${(props) => (props.activeView ? '#5a0017' : undefined)}; +` + +export const ViewButtonClicked = styled(Button)` margin-right: 8px; + background: #5a0017; ` export const ViewButtonGroup = styled.div` diff --git a/client/src/pages/views/AudienceViewPage.tsx b/client/src/pages/views/AudienceViewPage.tsx index 8d58a364..d03f3367 100644 --- a/client/src/pages/views/AudienceViewPage.tsx +++ b/client/src/pages/views/AudienceViewPage.tsx @@ -1,16 +1,15 @@ +import { Typography } from '@material-ui/core' import React from 'react' +import { useAppSelector } from '../../hooks' import SlideDisplay from '../presentationEditor/components/SlideDisplay' -import PresentationComponent from './components/PresentationComponent' -import mockedAxios from 'axios' const AudienceViewPage: React.FC = () => { - const res = { - data: {}, + const viewTypes = useAppSelector((state) => state.types.viewTypes) + const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Audience')?.id + if (activeViewTypeId) { + return <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} /> } - ;(mockedAxios.get as jest.Mock).mockImplementation(() => { - return Promise.resolve(res) - }) - return <SlideDisplay /> + return <Typography>Error: Åskådarvyn kunde inte laddas</Typography> } export default AudienceViewPage diff --git a/client/src/pages/views/JudgeViewPage.tsx b/client/src/pages/views/JudgeViewPage.tsx index de5abe40..f72c052d 100644 --- a/client/src/pages/views/JudgeViewPage.tsx +++ b/client/src/pages/views/JudgeViewPage.tsx @@ -46,6 +46,8 @@ const JudgeViewPage = ({ competitionId, code }: JudgeViewPageProps) => { const history = useHistory() const dispatch = useAppDispatch() const [activeSlideIndex, setActiveSlideIndex] = useState<number>(0) + const viewTypes = useAppSelector((state) => state.types.viewTypes) + const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Judge')?.id const teams = useAppSelector((state) => state.presentation.competition.teams) const slides = useAppSelector((state) => state.presentation.competition.slides) const handleSelectSlide = (index: number) => { @@ -114,7 +116,7 @@ const JudgeViewPage = ({ competitionId, code }: JudgeViewPageProps) => { <div style={{ height: 64 }} /> <Content leftDrawerWidth={leftDrawerWidth} rightDrawerWidth={rightDrawerWidth}> <InnerContent> - <SlideDisplay /> + {activeViewTypeId && <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />} </InnerContent> </Content> </div> diff --git a/client/src/pages/views/ParticipantViewPage.tsx b/client/src/pages/views/ParticipantViewPage.tsx index ffee1ee1..0c4db2c0 100644 --- a/client/src/pages/views/ParticipantViewPage.tsx +++ b/client/src/pages/views/ParticipantViewPage.tsx @@ -9,6 +9,8 @@ import { useAppSelector } from '../../hooks' const ParticipantViewPage: React.FC = () => { const history = useHistory() const code = useAppSelector((state) => state.presentation.code) + const viewTypes = useAppSelector((state) => state.types.viewTypes) + const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Participant')?.id useEffect(() => { //hides the url so people can't sneak peak history.push('participant') @@ -19,7 +21,7 @@ const ParticipantViewPage: React.FC = () => { }, []) return ( <ParticipantContainer> - <SlideDisplay /> + {activeViewTypeId && <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />} </ParticipantContainer> ) } diff --git a/client/src/pages/views/PresenterViewPage.tsx b/client/src/pages/views/PresenterViewPage.tsx index f221f5a9..6c853a60 100644 --- a/client/src/pages/views/PresenterViewPage.tsx +++ b/client/src/pages/views/PresenterViewPage.tsx @@ -61,6 +61,8 @@ const PresenterViewPage: React.FC = () => { const presentation = useAppSelector((state) => state.presentation) const history = useHistory() const dispatch = useAppDispatch() + const viewTypes = useAppSelector((state) => state.types.viewTypes) + const activeViewTypeId = viewTypes.find((viewType) => viewType.name === 'Presenter')?.id useEffect(() => { dispatch(getPresentationCompetition(id)) @@ -137,7 +139,7 @@ const PresenterViewPage: React.FC = () => { <div style={{ height: 0, paddingTop: 120 }} /> <PresenterContent> <PresenterInnerContent> - <SlideDisplay /> + {activeViewTypeId && <SlideDisplay variant="presentation" activeViewTypeId={activeViewTypeId} />} </PresenterInnerContent> </PresenterContent> <div style={{ height: 0, paddingTop: 140 }} /> -- GitLab