Skip to content

Commit

Permalink
📏Added support for dynamic viewport units in question (#225)+:bug:Fix…
Browse files Browse the repository at this point in the history
…ed overflow on mobile landscape (#226)+:hammer:Converted JavaScript files to TypeScript (#216)
  • Loading branch information
Rllyyy committed Dec 20, 2022
1 parent a301a35 commit fada6cc
Show file tree
Hide file tree
Showing 32 changed files with 195 additions and 173 deletions.
3 changes: 2 additions & 1 deletion .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"tsmerge",
"unicode",
"USEEFFECTS",
"vmatrix"
"vmatrix",
"wicg"
],
// flagWords - list of words to be always considered incorrect
// This is useful for offensive words and common spelling errors.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
},
"devDependencies": {
"@types/react-modal": "^3.13.1",
"@types/wicg-file-system-access": "^2020.9.5",
"cypress-plugin-tab": "^1.0.5",
"electron": "^17.4.7",
"electron-builder": "^23.6.0"
Expand Down
5 changes: 2 additions & 3 deletions src/components/Footer/Footer.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ footer a:focus-visible {
outline-offset: 3px;
}


@media screen and (pointer: fine) and (hover: hover) {
footer a:hover {
color: var(--custom-border-color-lighter);
Expand All @@ -54,7 +53,7 @@ footer a:focus-visible {
}
}

@media(min--moz-device-pixel-ratio:0) and (max-width: 650px) {
@media (min--moz-device-pixel-ratio: 0) and (max-width: 650px) {
footer {
padding-bottom: 50px;
}
Expand All @@ -66,4 +65,4 @@ footer a:focus-visible {
footer ul li {
font-size: 1.25rem;
}
}
}
4 changes: 2 additions & 2 deletions src/components/GridCards/GridCards.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.grid-cards {
margin: 10px 0px 20px 0px;
margin: 10px 0px 15px 0px;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(370px, 1fr));
grid-auto-rows: 1fr;
Expand All @@ -11,4 +11,4 @@
.grid-cards {
grid-template-columns: repeat(auto-fill, 100%);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "./GridCards.css";

export const GridCards = ({ children }) => {
export const GridCards = ({ children }: { children: React.ReactNode }) => {
return <div className='grid-cards'>{children}</div>;
};
42 changes: 25 additions & 17 deletions src/components/Home/Modules.js → src/components/Home/Modules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { toast } from "react-toastify";
import { fetchModuleFromPublicFolder } from "../../utils/fetchModuleFromPublicFolder.js";

//Components
import { GridCards } from "../GridCards/GridCards.jsx";
import { GridCards } from "../GridCards/GridCards";
import { Card, LinkElement } from "../Card/Card";
import { PopoverButton, PopoverMenu, PopoverMenuItem } from "../Card/Popover";
import { Spinner } from "../Spinner/Spinner.js";
Expand All @@ -15,7 +15,11 @@ import { TbFileExport } from "react-icons/tb";
import { BiTrash } from "react-icons/bi";

//Functions
import { saveFile } from "../../utils/saveFile.js";
import { saveFile } from "../../utils/saveFile";

//Interfaces and Types
import { IModule } from "./CreateModule";
import { parseJSON } from "../../utils/parseJSON";

//Component
export const Modules = () => {
Expand All @@ -33,12 +37,11 @@ export const Modules = () => {
return (
<GridCards>
{modules?.map((module) => {
const { id, name, questions, disabled } = module;
const { id, name, questions } = module;
return (
<Card
key={id}
data-cy={`module-${id}`}
disabled={disabled}
type='module'
title={`${name} (${id})`}
description={`${questions?.length} Questions`}
Expand All @@ -65,25 +68,30 @@ export const Modules = () => {
// Return the whole localStorage
const useAllModules = () => {
const [loading, setLoading] = useState(true);
const [modules, setModules] = useState([]);
const [errors, setErrors] = useState([]);
const [modules, setModules] = useState<IModule[]>([]);
const [errors, setErrors] = useState<string[]>([]);

//Get the modules from the localStorage and set the module state
//Updates every time localeStorage changes
const modulesFromBrowserStorage = useCallback(async () => {
//Setup variables for the module and possible errors
let localStorageModules = [];
let moduleErrors = [];
let localStorageModules: IModule[] = [];
let moduleErrors: string[] = [];

Object.entries(localStorage).forEach((key) => {
if (key[0].startsWith("repeatio-module")) {
//Get item, transform to object, on error add to moduleErrors array
try {
const module = localStorage.getItem(key[0]);
localStorageModules.push(JSON.parse(module));
const moduleJSON = parseJSON<IModule>(module);
if (moduleJSON !== undefined && moduleJSON !== null) {
localStorageModules.push(moduleJSON);
}
} catch (error) {
toast.warn(`${key[0]}: ${error.message}`);
moduleErrors.push(`${key[0]}: ${error.message}`);
if (error instanceof Error) {
toast.warn(`${key[0]}: ${error.message}`);
moduleErrors.push(`${key[0]}: ${error.message}`);
}
}
}
});
Expand Down Expand Up @@ -114,10 +122,10 @@ const useAllModules = () => {
useEffect(() => {
if (isElectron()) {
// Send a message to the main process
window.api.request("toMain", ["getModules"]);
(window as any).api.request("toMain", ["getModules"]);

// Called when message received from main process
window.api.response("fromMain", (data) => {
(window as any).api.response("fromMain", (data: IModule[]) => {
setModules(data);
setLoading(false);
});
Expand All @@ -140,7 +148,7 @@ const useAllModules = () => {

//Hook to use the functions inside the Popover component
const useHomePopover = () => {
const [anchorEl, setAnchorEl] = useState(null);
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);

//Reset anchor if component unmounts
useLayoutEffect(() => {
Expand All @@ -150,7 +158,7 @@ const useHomePopover = () => {
}, []);

//Set the anchor
const handlePopoverButtonClick = (event) => {
const handlePopoverButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};

Expand All @@ -162,7 +170,7 @@ const useHomePopover = () => {
//Handle deletion of module
const handleDelete = () => {
//Get id of module by custom attribute
const moduleID = anchorEl.getAttribute("data-target");
const moduleID = anchorEl?.getAttribute("data-target");

//Prevent deletion of example module as that is saved in the public folder
if (moduleID === "types_1") {
Expand Down Expand Up @@ -202,7 +210,7 @@ const useHomePopover = () => {
}

//Get id of the module from the button
const moduleID = anchorEl.getAttribute("data-target");
const moduleID = anchorEl?.getAttribute("data-target");
let file;

if (moduleID !== "types_1") {
Expand Down
16 changes: 3 additions & 13 deletions src/components/Question/Question.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.question-form {
position: relative;
/*40px represents the padding (top+bottom) of the main component defined in index.css, so the user doesn't need scroll and the navigation is always at the bottom*/
height: calc(100vh - 40px);
height: calc(100dvh - 40px);
width: 100%;
background-color: white;
border-radius: 5px;
Expand Down Expand Up @@ -406,12 +406,9 @@
}

/* Media query for phones */
/* Second query is for development on desktop */
@media only screen and (pointer: coarse), only screen and (pointer: fine) and (max-width: 650px) {
@media only screen and (max-width: 650px) {
.question-form {
height: calc(100vh - 120px);
/*The viewport of mobile devices includes the address bar. Because why not. */
margin-bottom: 0;
height: calc(100dvh - 70px); /* Height of the header + padding of main - 3px to look beetter */
}

.question-data {
Expand Down Expand Up @@ -450,13 +447,6 @@
}
}

/* For desktop very small */
@media only screen and (pointer: fine) and (max-width: 650px) {
.question-form {
height: calc(100vh - 70px);
}
}

/* On mobile firefox the scrollbar is part of the html viewport. In other browsers it is not */
@media (min--moz-device-pixel-ratio: 0) and (max-width: 650px) {
.question-data {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Question/Question.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { EditQuestion } from "./components/Actions/EditQuestion";
import { BookmarkQuestion } from "./components/Actions/BookmarkQuestion";

//Context
import { ModuleContext } from "../module/moduleContext.js";
import { ModuleContext } from "../module/moduleContext";

//Hooks
import { useQuestion } from "./useQuestion.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import "./ExtendedMatch.css";

//Import functions
import { isEqual } from "lodash";
import { shuffleArray } from "../../../../utils/shuffleArray.js";
import { shuffleArray } from "../../../../utils/shuffleArray";

//I am really not proud of this component :/ and refactor it for a future release
//Each line in the canvas is an object in the lines array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import "katex/dist/katex.min.css";
import "./MultipleChoice.css";

//Import functions
import { shuffleArray } from "../../../../utils/shuffleArray.js";
import { shuffleArray } from "../../../../utils/shuffleArray";

/* Component */
export const MultipleChoice = forwardRef(({ options, formDisabled }, ref) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import FormControl from "@mui/material/FormControl";
import "./MultipleResponse.css";

//Import functions
import { shuffleArray } from "../../../../utils/shuffleArray.js";
import { shuffleArray } from "../../../../utils/shuffleArray";

//Component
export const MultipleResponse = forwardRef(({ options, formDisabled }, ref) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Question/__tests__/Question.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { screen, render, cleanup } from "@testing-library/react";
import user from "@testing-library/user-event";
import { Question } from "../Question.js";
import { ModuleContext } from "../../module/moduleContext.js";
import { ModuleContext } from "../../module/moduleContext";
import { Router, Route, Switch, MemoryRouter } from "react-router-dom";
import { createMemoryHistory } from "history";

Expand Down
5 changes: 2 additions & 3 deletions src/components/Question/components/Actions/DeleteQuestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { toast } from "react-toastify";
import { getBookmarkedLocalStorageItem } from "./BookmarkQuestion";

//Context
import { ModuleContext } from "../../../module/moduleContext.js";
import { IModuleContext, ModuleContext } from "../../../module/moduleContext";

//TODO add moduleID as Component param not useParams

Expand Down Expand Up @@ -33,8 +33,7 @@ export const DeleteQuestion = ({ questionID, disabled, ...props }: IDeleteQuesti
let history = useHistory();

//Access Module
//TODO fix this any
const { moduleData, setModuleData, filteredQuestions } = useContext<any>(ModuleContext);
const { moduleData, setModuleData, filteredQuestions } = useContext<IModuleContext>(ModuleContext);

//Delete Question from storage
const handleDelete = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useParams, useHistory, useLocation } from "react-router-dom";
import { toast } from "react-toastify";

//Context
import { ModuleContext } from "../../../module/moduleContext.js";
import { ModuleContext } from "../../../module/moduleContext";

//Navigation svg from https://tablericons.com

Expand Down
2 changes: 1 addition & 1 deletion src/components/Question/useQuestion.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useParams } from "react-router-dom";
import { useQuestionNavigation } from "./components/QuestionNavigation/QuestionNavigation.jsx";

//Context
import { ModuleContext } from "../module/moduleContext.js";
import { ModuleContext } from "../module/moduleContext";

export const useQuestion = () => {
//States
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ export const AnswerOptionsEditor = ({
const { selectionStart, selectionEnd } = ref.current;
if (selectionStart !== selectionEnd) {
handleEditorChange({
tempText: removeBracketsFromSelection((answerValues as IGapText)?.tempText, selectionStart, selectionEnd),
tempText: removeBracketsFromSelection(
(answerValues as IGapText)?.tempText || "",
selectionStart,
selectionEnd
),
});
ref.current.focus();
} else {
Expand Down Expand Up @@ -170,7 +174,7 @@ export const AnswerOptionsEditor = ({
<GapTextEditor
ref={ref}
name='gap-text'
tempText={(answerValues as IGapText)?.tempText}
tempText={(answerValues as IGapText)?.tempText || ""}
handleEditorChange={handleEditorChange}
answerOptionsError={answerOptionsError}
setErrors={setErrors}
Expand Down
2 changes: 1 addition & 1 deletion src/components/QuestionEditor/QuestionEditor.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { Form } from "./QuestionEditor";
import { Router } from "react-router-dom";
import { createMemoryHistory } from "history";
import { ModuleProvider } from "../module/moduleContext.js";
import { ModuleProvider } from "../module/moduleContext";
import { CustomToastContainer } from "../toast/toast";

//CSS
Expand Down
Loading

0 comments on commit fada6cc

Please sign in to comment.