+
setTheme("light")}
+ >
+
-
{t('header.settingsMenu.themeOptions.light')}
+
{t("header.settingsMenu.themeOptions.light")}
-
setTheme('dark')}>
-
- )
-}
+ );
+};
-export default ThemeToggle
+export default ThemeToggle;
diff --git a/src/components/ThemeToggle/ThemeToggle.test.js b/src/components/ThemeToggle/ThemeToggle.test.js
index 231b07264..7500624dc 100644
--- a/src/components/ThemeToggle/ThemeToggle.test.js
+++ b/src/components/ThemeToggle/ThemeToggle.test.js
@@ -1,7 +1,7 @@
import React from "react";
-import { act, render, fireEvent } from "@testing-library/react"
+import { act, render, fireEvent } from "@testing-library/react";
import ThemeToggle from "./ThemeToggle";
-import { Cookies, CookiesProvider } from 'react-cookie';
+import { Cookies, CookiesProvider } from "react-cookie";
describe("When default theme is light mode and cookie unset", () => {
let cookies;
@@ -17,29 +17,31 @@ describe("When default theme is light mode and cookie unset", () => {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
- })
+ });
cookies = new Cookies();
toggleContainer = render(
-
- )
- })
+ ,
+ );
+ });
- test('Cookie remains unset after render', () => {
- expect(cookies.cookies.theme).toBeUndefined()
- })
+ test("Cookie remains unset after render", () => {
+ expect(cookies.cookies.theme).toBeUndefined();
+ });
- test('Sets cookie to dark when button clicked', async () => {
- const button = toggleContainer.getByText("header.settingsMenu.themeOptions.dark").parentElement
- fireEvent.click(button)
- expect(cookies.cookies.theme).toBe("dark")
- })
+ test("Sets cookie to dark when button clicked", async () => {
+ const button = toggleContainer.getByText(
+ "header.settingsMenu.themeOptions.dark",
+ ).parentElement;
+ fireEvent.click(button);
+ expect(cookies.cookies.theme).toBe("dark");
+ });
afterEach(() => {
- cookies.remove("theme")
- })
-})
+ cookies.remove("theme");
+ });
+});
describe("When default theme is dark mode and cookie unset", () => {
let cookies;
@@ -55,56 +57,62 @@ describe("When default theme is dark mode and cookie unset", () => {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
- })
+ });
cookies = new Cookies();
toggleContainer = render(
-
- )
- })
+ ,
+ );
+ });
- test('Cookie remains unset after render', () => {
- expect(cookies.cookies.theme).toBeUndefined()
- })
+ test("Cookie remains unset after render", () => {
+ expect(cookies.cookies.theme).toBeUndefined();
+ });
- test('Sets cookie to light when button clicked', async () => {
- const button = toggleContainer.getByText("header.settingsMenu.themeOptions.light").parentElement
- fireEvent.click(button)
- expect(cookies.cookies.theme).toBe("light")
- })
+ test("Sets cookie to light when button clicked", async () => {
+ const button = toggleContainer.getByText(
+ "header.settingsMenu.themeOptions.light",
+ ).parentElement;
+ fireEvent.click(button);
+ expect(cookies.cookies.theme).toBe("light");
+ });
afterEach(() => {
- cookies.remove("theme")
- })
-})
+ cookies.remove("theme");
+ });
+});
-test('Cookie set to dark intially changes to light when button clicked', () => {
+test("Cookie set to dark intially changes to light when button clicked", () => {
var cookies = new Cookies();
- cookies.set("theme", "dark")
+ cookies.set("theme", "dark");
const toggleContainer = render(
-
- )
- const button = toggleContainer.getByText("header.settingsMenu.themeOptions.light").parentElement
+ ,
+ );
+ const button = toggleContainer.getByText(
+ "header.settingsMenu.themeOptions.light",
+ ).parentElement;
act(() => {
- fireEvent.click(button)
- })
- expect(cookies.cookies.theme).toBe("light")
-})
+ fireEvent.click(button);
+ });
+ expect(cookies.cookies.theme).toBe("light");
+});
-test('Cookie set to light intially changes to dark when button clicked', () => {
+test("Cookie set to light intially changes to dark when button clicked", () => {
var cookies = new Cookies();
- cookies.set("theme", "light")
+ cookies.set("theme", "light");
var toggleContainer = render(
-
- )
- const button = toggleContainer.getByText("header.settingsMenu.themeOptions.dark").parentElement
+ ,
+ );
+ const button = toggleContainer.getByText(
+ "header.settingsMenu.themeOptions.dark",
+ ).parentElement;
act(() => {
- fireEvent.click(button)
- })
- expect(cookies.cookies.theme).toBe("dark")
-})
+ fireEvent.click(button);
+ });
+ expect(cookies.cookies.theme).toBe("dark");
+});
diff --git a/src/components/WebComponent/Project/WebComponentProject.js b/src/components/WebComponent/Project/WebComponentProject.js
index d397e0500..eb421e1c2 100644
--- a/src/components/WebComponent/Project/WebComponentProject.js
+++ b/src/components/WebComponent/Project/WebComponentProject.js
@@ -1,39 +1,42 @@
-import React, { useEffect } from 'react';
-import { useDispatch, useSelector } from 'react-redux'
-import { useCookies } from 'react-cookie';
-import Style from 'style-it';
-import internalStyles from '../InternalStyles.scss';
-import externalStyles from '../ExternalStyles.scss';
+import React, { useEffect } from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { useCookies } from "react-cookie";
+import Style from "style-it";
+import internalStyles from "../InternalStyles.scss";
+import externalStyles from "../ExternalStyles.scss";
-import Project from '../../Editor/Project/Project';
-import { defaultMZCriteria } from '../../AstroPiModel/DefaultMZCriteria'
-import Sk from 'skulpt';
-import store from '../../../app/store';
-import { setIsSplitView } from '../../Editor/EditorSlice';
+import Project from "../../Editor/Project/Project";
+import { defaultMZCriteria } from "../../AstroPiModel/DefaultMZCriteria";
+import Sk from "skulpt";
+import store from "../../../app/store";
+import { setIsSplitView } from "../../Editor/EditorSlice";
const WebComponentProject = () => {
const project = useSelector((state) => state.editor.project);
- const codeRunTriggered = useSelector((state) => state.editor.codeRunTriggered)
- const [cookies] = useCookies(['theme', 'fontSize'])
- const defaultTheme = window.matchMedia("(prefers-color-scheme:dark)").matches ? "dark" : "light"
+ const codeRunTriggered = useSelector(
+ (state) => state.editor.codeRunTriggered,
+ );
+ const [cookies] = useCookies(["theme", "fontSize"]);
+ const defaultTheme = window.matchMedia("(prefers-color-scheme:dark)").matches
+ ? "dark"
+ : "light";
const [timeoutId, setTimeoutId] = React.useState(null);
- const webComponent = document.querySelector('editor-wc')
+ const webComponent = document.querySelector("editor-wc");
const [codeHasRun, setCodeHasRun] = React.useState(false);
- const dispatch = useDispatch()
- dispatch(setIsSplitView(false))
+ const dispatch = useDispatch();
+ dispatch(setIsSplitView(false));
useEffect(() => {
- setCodeHasRun(false)
- if(timeoutId) clearTimeout(timeoutId);
- const id = setTimeout(
- function() {
- const customEvent = new CustomEvent("codeChanged", {
- bubbles: true,
- cancelable: false,
- composed: true
- });
- webComponent.dispatchEvent(customEvent)
- }, 2000);
+ setCodeHasRun(false);
+ if (timeoutId) clearTimeout(timeoutId);
+ const id = setTimeout(function () {
+ const customEvent = new CustomEvent("codeChanged", {
+ bubbles: true,
+ cancelable: false,
+ composed: true,
+ });
+ webComponent.dispatchEvent(customEvent);
+ }, 2000);
setTimeoutId(id);
}, [project]);
@@ -42,38 +45,44 @@ const WebComponentProject = () => {
const runStartedEvent = new CustomEvent("runStarted", {
bubbles: true,
cancelable: false,
- composed: true
+ composed: true,
});
- webComponent.dispatchEvent(runStartedEvent)
- setCodeHasRun(true)
+ webComponent.dispatchEvent(runStartedEvent);
+ setCodeHasRun(true);
} else if (codeHasRun) {
const state = store.getState();
- const mz_criteria = Sk.sense_hat ? Sk.sense_hat.mz_criteria : {...defaultMZCriteria}
+ const mz_criteria = Sk.sense_hat
+ ? Sk.sense_hat.mz_criteria
+ : { ...defaultMZCriteria };
const runCompletedEvent = new CustomEvent("runCompleted", {
bubbles: true,
cancelable: false,
composed: true,
detail: {
isErrorFree: state.editor.error === "",
- ...mz_criteria
- }
+ ...mz_criteria,
+ },
});
- webComponent.dispatchEvent(runCompletedEvent)
+ webComponent.dispatchEvent(runCompletedEvent);
}
-
- }, [codeRunTriggered] )
+ }, [codeRunTriggered]);
return (
<>
>
);
-}
+};
-export default WebComponentProject
+export default WebComponentProject;
diff --git a/src/components/WebComponent/WebComponentLoader/WebComponentLoader.js b/src/components/WebComponent/WebComponentLoader/WebComponentLoader.js
index a35efdc71..14a17ec27 100644
--- a/src/components/WebComponent/WebComponentLoader/WebComponentLoader.js
+++ b/src/components/WebComponent/WebComponentLoader/WebComponentLoader.js
@@ -1,31 +1,31 @@
-import React, { useEffect } from 'react';
-import { useSelector, useDispatch } from 'react-redux'
-import { setProject, setSenseHatAlwaysEnabled } from '../../Editor/EditorSlice';
-import WebComponentProject from '../Project/WebComponentProject';
+import React, { useEffect } from "react";
+import { useSelector, useDispatch } from "react-redux";
+import { setProject, setSenseHatAlwaysEnabled } from "../../Editor/EditorSlice";
+import WebComponentProject from "../Project/WebComponentProject";
const ProjectComponentLoader = (props) => {
const loading = useSelector((state) => state.editor.loading);
const { code, sense_hat_always_enabled } = props;
- const dispatch = useDispatch()
+ const dispatch = useDispatch();
useEffect(() => {
const proj = {
- type: 'python',
- components: [{ name: 'main', extension: 'py', content: code }]
- }
- dispatch(setSenseHatAlwaysEnabled(typeof sense_hat_always_enabled !== 'undefined'))
- dispatch(setProject(proj))
+ type: "python",
+ components: [{ name: "main", extension: "py", content: code }],
+ };
+ dispatch(
+ setSenseHatAlwaysEnabled(typeof sense_hat_always_enabled !== "undefined"),
+ );
+ dispatch(setProject(proj));
}, [code, sense_hat_always_enabled, dispatch]);
-
-
- return loading === 'success' ? (
+ return loading === "success" ? (
<>
>
) : (
<>
-
Loading
+
Loading
>
);
};
diff --git a/src/components/WebComponent/WebComponentSlice.js b/src/components/WebComponent/WebComponentSlice.js
index e33fb1190..ef8934aad 100644
--- a/src/components/WebComponent/WebComponentSlice.js
+++ b/src/components/WebComponent/WebComponentSlice.js
@@ -1,20 +1,18 @@
-import { createSlice } from '@reduxjs/toolkit'
+import { createSlice } from "@reduxjs/toolkit";
export const WebComponentSlice = createSlice({
- name: 'component',
+ name: "component",
initialState: {
- project: {}
+ project: {},
},
reducers: {
setProject: (state, action) => {
state.project = action.payload;
- }
- }
-})
+ },
+ },
+});
-export const {
- setProject,
-} = WebComponentSlice.actions
+export const { setProject } = WebComponentSlice.actions;
-export default WebComponentSlice.reducer
+export default WebComponentSlice.reducer;
diff --git a/src/hooks/useUserFont.js b/src/hooks/useUserFont.js
index 2ef35917f..30fcadd81 100644
--- a/src/hooks/useUserFont.js
+++ b/src/hooks/useUserFont.js
@@ -1,10 +1,10 @@
-import { useCookies } from 'react-cookie';
+import { useCookies } from "react-cookie";
-const fontScaleFactors = {'small': 1, 'medium': 1.44, 'large': 2.074}
+const fontScaleFactors = { small: 1, medium: 1.44, large: 2.074 };
export const useUserFont = (defaultScale = 1) => {
- const [cookies] = useCookies(['fontSize'])
- const scale = fontScaleFactors[cookies.fontSize] || defaultScale
+ const [cookies] = useCookies(["fontSize"]);
+ const scale = fontScaleFactors[cookies.fontSize] || defaultScale;
- return scale
-}
\ No newline at end of file
+ return scale;
+};
diff --git a/src/i18n.js b/src/i18n.js
index 1fcd4fe68..ed52f6867 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -155,10 +155,11 @@ i18n
newFileModal: {
cancel: "Cancel",
heading: "Add a new file to your project",
- helpText: "Remember to add the file extension at the end of your file name, for example, {{examples}}",
- helpTextExample:{
+ helpText:
+ "Remember to add the file extension at the end of your file name, for example, {{examples}}",
+ helpTextExample: {
html: "'file.html' or 'file.css'",
- python: "'file.py'"
+ python: "'file.py'",
},
inputLabel: "Name your file",
addFile: "Add file",
@@ -236,7 +237,7 @@ i18n
"Log in to your Raspberry Pi account to save your work, and you'll be able to access and edit your project whenever you need to.",
},
modals: {
- close: 'Close'
+ close: "Close",
},
notifications: {
close: "close",
@@ -339,7 +340,7 @@ i18n
},
updated: "Edited",
python_type: "Python",
- html_type: "HTML"
+ html_type: "HTML",
},
runButton: {
run: "Run",
@@ -347,7 +348,7 @@ i18n
stopping: "Stopping...",
},
runners: {
- HtmlOutput: 'HTML Output Preview'
+ HtmlOutput: "HTML Output Preview",
},
sideMenu: {
collapse: "Collapse file pane",
diff --git a/src/index.js b/src/index.js
index e7075b02b..080c13c23 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,22 +1,29 @@
-import React from 'react';
-import { createRoot } from 'react-dom/client';
+import React from "react";
+import { createRoot } from "react-dom/client";
-import { SentryLink } from 'apollo-link-sentry';
+import { SentryLink } from "apollo-link-sentry";
-import './index.css';
-import './sentry';
-import App from './App';
-import './i18n';
-import { ApolloLink, ApolloProvider, ApolloClient, createHttpLink } from '@apollo/client';
-import { setContext } from '@apollo/client/link/context';
-import { OidcProvider } from 'redux-oidc';
-import { Provider } from 'react-redux';
-import store from './app/store';
-import userManager from './utils/userManager';
-import apolloCache from './utils/apolloCache';
-import { CookiesProvider } from 'react-cookie';
+import "./index.css";
+import "./sentry";
+import App from "./App";
+import "./i18n";
+import {
+ ApolloLink,
+ ApolloProvider,
+ ApolloClient,
+ createHttpLink,
+} from "@apollo/client";
+import { setContext } from "@apollo/client/link/context";
+import { OidcProvider } from "redux-oidc";
+import { Provider } from "react-redux";
+import store from "./app/store";
+import userManager from "./utils/userManager";
+import apolloCache from "./utils/apolloCache";
+import { CookiesProvider } from "react-cookie";
-const apiEndpointLink = createHttpLink({ uri: process.env.REACT_APP_API_ENDPOINT + '/graphql' });
+const apiEndpointLink = createHttpLink({
+ uri: process.env.REACT_APP_API_ENDPOINT + "/graphql",
+});
const apiAuthLink = setContext((_, { headers }) => {
// TODO: ... better way to handle state in Apollo
const user = store.getState().auth.user;
@@ -26,27 +33,23 @@ const apiAuthLink = setContext((_, { headers }) => {
headers: {
...headers,
Authorization: user ? user.access_token : "",
- }
- }
+ },
+ };
});
const client = new ApolloClient({
- link: ApolloLink.from([
- new SentryLink(),
- apiAuthLink,
- apiEndpointLink
- ]),
- cache: apolloCache
+ link: ApolloLink.from([new SentryLink(), apiAuthLink, apiEndpointLink]),
+ cache: apolloCache,
});
-const supportsContainerQueries = 'container' in document.documentElement.style
+const supportsContainerQueries = "container" in document.documentElement.style;
if (!supportsContainerQueries) {
// eslint-disable-next-line no-unused-expressions
- import('container-query-polyfill')
+ import("container-query-polyfill");
}
-const div = document.getElementById('root')
-const root = createRoot(div)
+const div = document.getElementById("root");
+const root = createRoot(div);
root.render(
@@ -58,7 +61,7 @@ root.render(
-
+ ,
);
// If you want to start measuring performance in your app, pass a function
diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js
index 5253d3ad9..9ecd33f9c 100644
--- a/src/reportWebVitals.js
+++ b/src/reportWebVitals.js
@@ -1,6 +1,6 @@
-const reportWebVitals = onPerfEntry => {
+const reportWebVitals = (onPerfEntry) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
diff --git a/src/sentry.js b/src/sentry.js
index 1e92e24dc..04c51570c 100644
--- a/src/sentry.js
+++ b/src/sentry.js
@@ -1,9 +1,14 @@
-import React from 'react';
-import { useLocation, useNavigationType, createRoutesFromChildren, matchRoutes } from "react-router-dom";
+import React from "react";
+import {
+ useLocation,
+ useNavigationType,
+ createRoutesFromChildren,
+ matchRoutes,
+} from "react-router-dom";
-import * as Sentry from '@sentry/react'
-import { BrowserTracing } from '@sentry/tracing';
-import { excludeGraphQLFetch } from 'apollo-link-sentry';
+import * as Sentry from "@sentry/react";
+import { BrowserTracing } from "@sentry/tracing";
+import { excludeGraphQLFetch } from "apollo-link-sentry";
Sentry.init({
dsn: process.env.REACT_APP_SENTRY_DSN,
@@ -22,4 +27,4 @@ Sentry.init({
environment: process.env.REACT_APP_SENTRY_ENV,
beforeBreadcrumb: excludeGraphQLFetch,
tracesSampleRate: 0.8,
-})
+});
diff --git a/src/settings.js b/src/settings.js
index 41fb3d20d..e20dedc90 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -1,8 +1,10 @@
-import { createContext } from "react"
+import { createContext } from "react";
const SettingsContext = createContext({
- theme: window.matchMedia("(prefers-color-scheme:dark)").matches ? "dark" : "light",
- fontSize: 'small'
-})
+ theme: window.matchMedia("(prefers-color-scheme:dark)").matches
+ ? "dark"
+ : "light",
+ fontSize: "small",
+});
-export { SettingsContext }
\ No newline at end of file
+export { SettingsContext };
diff --git a/src/utils/Geometry.js b/src/utils/Geometry.js
index 5529337d8..e5ac51afa 100644
--- a/src/utils/Geometry.js
+++ b/src/utils/Geometry.js
@@ -1,28 +1,26 @@
var Geometry = {
- _Eps: 1e-5
+ _Eps: 1e-5,
};
-
-Geometry.Vector = function(x, y, z) {
+Geometry.Vector = function (x, y, z) {
this.x = x;
this.y = y;
this.z = z;
-}
+};
Geometry.Vector.prototype = {
- length: function() {
+ length: function () {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
},
- normalize: function() {
+ normalize: function () {
var length = this.length();
- if (length <= Geometry._Eps)
- return;
+ if (length <= Geometry._Eps) return;
this.x /= length;
this.y /= length;
this.z /= length;
- }
-}
+ },
+};
/**
* Transposes a 2-dim Array
@@ -31,38 +29,42 @@ Geometry.Vector.prototype = {
*
* @returns {Array} transposed a
*/
-Geometry.transpose3x3Matrix = function(a) {
- var t = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
-
- t[0][0] = a[0][0];
- t[0][1] = a[1][0];
- t[0][2] = a[2][0];
-
- t[1][0] = a[0][1];
- t[1][1] = a[1][1];
- t[1][2] = a[2][1];
-
- t[2][0] = a[0][2];
- t[2][1] = a[1][2];
- t[2][2] = a[2][2];
-
- return t;
-}
+Geometry.transpose3x3Matrix = function (a) {
+ var t = [
+ [0, 0, 0],
+ [0, 0, 0],
+ [0, 0, 0],
+ ];
+
+ t[0][0] = a[0][0];
+ t[0][1] = a[1][0];
+ t[0][2] = a[2][0];
+
+ t[1][0] = a[0][1];
+ t[1][1] = a[1][1];
+ t[1][2] = a[2][1];
+
+ t[2][0] = a[0][2];
+ t[2][1] = a[1][2];
+ t[2][2] = a[2][2];
+
+ return t;
+};
/**
* Dot multiplication of a 3 by 3 and a 3 by 1 array
*
* @returns {Array} 3 by 1 array
*/
-Geometry.dot3x3and3x1 = function(a, b) {
- var rs = [];
+Geometry.dot3x3and3x1 = function (a, b) {
+ var rs = [];
- rs[0] = a[0][0]*b[0] + a[0][1] * b[1] + a[0][2] * b[2];
- rs[1] = a[1][0]*b[0] + a[1][1] * b[1] + a[1][2] * b[2];
- rs[2] = a[2][0]*b[0] + a[2][1] * b[1] + a[2][2] * b[2];
+ rs[0] = a[0][0] * b[0] + a[0][1] * b[1] + a[0][2] * b[2];
+ rs[1] = a[1][0] * b[0] + a[1][1] * b[1] + a[1][2] * b[2];
+ rs[2] = a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2];
- return rs;
-}
+ return rs;
+};
/**
* Mulitplies each array element in a with the scalar s
@@ -72,14 +74,9 @@ Geometry.dot3x3and3x1 = function(a, b) {
*
* @returns {Array}
*/
-Geometry.multiplyArrayWithScalar = function(a, s) {
- return [
- a[0] * s,
- a[1] * s,
- a[2] * s
- ];
-}
-
+Geometry.multiplyArrayWithScalar = function (a, s) {
+ return [a[0] * s, a[1] * s, a[2] * s];
+};
/**
* Divides each array element in a by scalar s
@@ -89,14 +86,9 @@ Geometry.multiplyArrayWithScalar = function(a, s) {
*
* @returns {Array}
*/
-Geometry.divideArrayWithScalar = function(a, s) {
- return [
- a[0] / s,
- a[1] / s,
- a[2] / s
- ];
-}
-
+Geometry.divideArrayWithScalar = function (a, s) {
+ return [a[0] / s, a[1] / s, a[2] / s];
+};
// Some useful defaults for the orientation calculations
Geometry.Defaults = {};
@@ -105,7 +97,10 @@ Geometry.Defaults.X = [1, 0, 0]; // x mask
Geometry.Defaults.Y = [0, 1, 0]; // y mask
Geometry.Defaults.Z = [0, 0, 1]; // z mask
-Geometry.Defaults.NORTH = Geometry.multiplyArrayWithScalar(Geometry.Defaults.X, 0.33);
+Geometry.Defaults.NORTH = Geometry.multiplyArrayWithScalar(
+ Geometry.Defaults.X,
+ 0.33,
+);
// Gravity vector
Geometry.Defaults.GRAVITY = Geometry.Defaults.Z;
@@ -113,10 +108,10 @@ Geometry.Defaults.GRAVITY = Geometry.Defaults.Z;
/**
* Constrain/clamp a given value to upper and lower limit
*/
-Geometry.clamp = function(value, min_value, max_value) {
- var clampVal = Math.min(max_value, Math.max(min_value, value))
- return clampVal;
-}
+Geometry.clamp = function (value, min_value, max_value) {
+ var clampVal = Math.min(max_value, Math.max(min_value, value));
+ return clampVal;
+};
/**
* Converts degrees to radians
@@ -125,16 +120,16 @@ Geometry.clamp = function(value, min_value, max_value) {
*
* @returns {Number|Array} depends on the deg param
*/
-Geometry.degToRad = function(deg) {
+Geometry.degToRad = function (deg) {
if (deg instanceof Array) {
return [
- deg[0] * Math.PI / 180,
- deg[1] * Math.PI / 180,
- deg[2] * Math.PI / 180
+ (deg[0] * Math.PI) / 180,
+ (deg[1] * Math.PI) / 180,
+ (deg[2] * Math.PI) / 180,
];
}
- return deg * Math.PI / 180;
-}
+ return (deg * Math.PI) / 180;
+};
/**
* Converts radians to degrees
@@ -143,15 +138,15 @@ Geometry.degToRad = function(deg) {
*
* @returns {Number|Array} depends on the rad param
*/
-Geometry.radToDeg = function(rad) {
+Geometry.radToDeg = function (rad) {
if (rad instanceof Array) {
return [
- rad[0] * 180 / Math.PI,
- rad[1] * 180 / Math.PI,
- rad[2] * 180 / Math.PI
+ (rad[0] * 180) / Math.PI,
+ (rad[1] * 180) / Math.PI,
+ (rad[2] * 180) / Math.PI,
];
}
- return rad * 180 / Math.PI;
-}
+ return (rad * 180) / Math.PI;
+};
-export {Geometry}
+export { Geometry };
diff --git a/src/utils/Notifications.js b/src/utils/Notifications.js
index d922da107..57c62f06b 100644
--- a/src/utils/Notifications.js
+++ b/src/utils/Notifications.js
@@ -5,61 +5,66 @@ import Button from "../components/Button/Button";
const CloseButton = ({ closeToast }) => {
return (
-
- )
-}
+
+ );
+};
const bottomCenterSettings = {
position: toast.POSITION.BOTTOM_CENTER,
autoClose: 3000,
- className: 'toast--bottom-center__message',
+ className: "toast--bottom-center__message",
closeButton: false,
- containerId: 'bottom-center',
- hideProgressBar: true
-}
+ containerId: "bottom-center",
+ hideProgressBar: true,
+};
const topCenterSettings = {
position: toast.POSITION.TOP_CENTER,
autoClose: 6000,
- className: 'toast--top-center__message',
+ className: "toast--top-center__message",
closeButton: CloseButton,
- containerId: 'top-center',
- hideProgressBar: true
-}
+ containerId: "top-center",
+ hideProgressBar: true,
+};
export const showSavePrompt = () => {
- toast(i18n.t('notifications.savePrompt'), {
+ toast(i18n.t("notifications.savePrompt"), {
...topCenterSettings,
className: `${topCenterSettings.className} toast--info`,
- icon: InfoIcon
+ icon: InfoIcon,
});
-}
+};
export const showLoginPrompt = () => {
- toast(i18n.t('notifications.loginPrompt'), {
+ toast(i18n.t("notifications.loginPrompt"), {
...topCenterSettings,
className: `${topCenterSettings.className} toast--info`,
- icon: InfoIcon
+ icon: InfoIcon,
});
-}
+};
export const showSavedMessage = () => {
- toast(i18n.t('notifications.projectSaved'), {
+ toast(i18n.t("notifications.projectSaved"), {
...bottomCenterSettings,
- icon: TickIcon
+ icon: TickIcon,
});
-}
+};
export const showRenamedMessage = () => {
- toast(i18n.t('notifications.projectRenamed'), {
+ toast(i18n.t("notifications.projectRenamed"), {
...bottomCenterSettings,
- icon: TickIcon
- })
-}
+ icon: TickIcon,
+ });
+};
export const showRemixedMessage = () => {
- toast(i18n.t('notifications.projectRemixed'), {
+ toast(i18n.t("notifications.projectRemixed"), {
...bottomCenterSettings,
- icon: TickIcon
+ icon: TickIcon,
});
-}
+};
diff --git a/src/utils/Notifications.test.js b/src/utils/Notifications.test.js
index 2d69c9aea..ffc395d1b 100644
--- a/src/utils/Notifications.test.js
+++ b/src/utils/Notifications.test.js
@@ -1,27 +1,44 @@
-import { toast } from 'react-toastify'
-import { showLoginPrompt, showRemixedMessage, showSavedMessage, showSavePrompt } from "./Notifications";
+import { toast } from "react-toastify";
+import {
+ showLoginPrompt,
+ showRemixedMessage,
+ showSavedMessage,
+ showSavePrompt,
+} from "./Notifications";
-jest.mock('../i18n', () => ({
- t: (string) => string
-}))
-jest.mock('react-toastify')
+jest.mock("../i18n", () => ({
+ t: (string) => string,
+}));
+jest.mock("react-toastify");
-test('Calling showRemixedMessage calls toast with correct string', () => {
- showRemixedMessage()
- expect(toast).toHaveBeenCalledWith('notifications.projectRemixed', expect.anything())
-})
+test("Calling showRemixedMessage calls toast with correct string", () => {
+ showRemixedMessage();
+ expect(toast).toHaveBeenCalledWith(
+ "notifications.projectRemixed",
+ expect.anything(),
+ );
+});
-test('Calling showSavedMessage calls toast with correct string', () => {
- showSavedMessage()
- expect(toast).toHaveBeenCalledWith('notifications.projectSaved', expect.anything())
-})
+test("Calling showSavedMessage calls toast with correct string", () => {
+ showSavedMessage();
+ expect(toast).toHaveBeenCalledWith(
+ "notifications.projectSaved",
+ expect.anything(),
+ );
+});
-test('Calling showSavePrompt calls toast with correct string', () => {
- showSavePrompt()
- expect(toast).toHaveBeenCalledWith('notifications.savePrompt', expect.anything())
-})
+test("Calling showSavePrompt calls toast with correct string", () => {
+ showSavePrompt();
+ expect(toast).toHaveBeenCalledWith(
+ "notifications.savePrompt",
+ expect.anything(),
+ );
+});
-test('Calling showLoginPrompt calls toast with correct string', () => {
- showLoginPrompt()
- expect(toast).toHaveBeenCalledWith('notifications.loginPrompt', expect.anything())
-})
+test("Calling showLoginPrompt calls toast with correct string", () => {
+ showLoginPrompt();
+ expect(toast).toHaveBeenCalledWith(
+ "notifications.loginPrompt",
+ expect.anything(),
+ );
+});
diff --git a/src/utils/Orientation.js b/src/utils/Orientation.js
index 926233ce1..d5cbb7a82 100644
--- a/src/utils/Orientation.js
+++ b/src/utils/Orientation.js
@@ -1,20 +1,20 @@
-import { Geometry } from './Geometry';
-import Sk from 'skulpt';
+import { Geometry } from "./Geometry";
+import Sk from "skulpt";
-function getTimestamp () {
+function getTimestamp() {
var time = Date.now(); // millis
- var timestamp = time * 1e+3; // milliseconds
+ var timestamp = time * 1e3; // milliseconds
return timestamp;
}
/**
-* Update call for periodically updating our internal sensehat data object.
-*
-* The UI events and the polling are async and therefore we can "simulate"
-* even changes when the user does not rotate.
-*/
+ * Update call for periodically updating our internal sensehat data object.
+ *
+ * The UI events and the polling are async and therefore we can "simulate"
+ * even changes when the user does not rotate.
+ */
export function updateRTIMU() {
-// Retriev the previous timestamp
+ // Retriev the previous timestamp
var oldTimestamp = Sk.sense_hat.rtimu.timestamp;
// Special case, if we call this function the first time and
@@ -25,7 +25,7 @@ export function updateRTIMU() {
// Get a new timestamp and calc the delta
var newTimestamp = getTimestamp();
- var timeDelta = (newTimestamp - oldTimestamp) / 1e+6;
+ var timeDelta = (newTimestamp - oldTimestamp) / 1e6;
// Special case, when the delta is 0, everything gets null
// Using a sane interval should avoid this case
@@ -39,7 +39,7 @@ export function updateRTIMU() {
var oldOrientation = Sk.sense_hat.rtimu.raw_old_orientation;
if (oldOrientation === null || oldOrientation === undefined) {
- oldOrientation = [0,90,0];
+ oldOrientation = [0, 90, 0];
}
var newOrientation = Geometry.degToRad(Sk.sense_hat.rtimu.raw_orientation);
@@ -48,7 +48,7 @@ export function updateRTIMU() {
var _gyro = [
newOrientation[0] - oldOrientation[0],
newOrientation[1] - oldOrientation[1],
- newOrientation[2] - oldOrientation[2]
+ newOrientation[2] - oldOrientation[2],
];
// Divide the orientation delta by the time delta
@@ -71,8 +71,8 @@ export function updateRTIMU() {
var R = [
[c1 * c2, c1 * s2 * s3 - c3 * s1, s1 * s3 + c1 * c3 * s2],
[c2 * s1, c1 * c3 + s1 * s2 * s3, c3 * s1 * s2 - c1 * s3],
- [-s2, c2 * s3, c2 * c3],
- ]
+ [-s2, c2 * s3, c2 * c3],
+ ];
// Transposed R matrix
var T = Geometry.transpose3x3Matrix(R);
@@ -97,17 +97,12 @@ export function updateRTIMU() {
Sk.sense_hat.rtimu.accel = [
Geometry.clamp(_accel[0], -8, 8),
Geometry.clamp(_accel[1], -8, 8),
- Geometry.clamp(_accel[2], -8, 8)
+ Geometry.clamp(_accel[2], -8, 8),
];
// _gyro = perturb(_gyro, .5);
// radians per second
- Sk.sense_hat.rtimu.gyro = [
- _gyro[0],
- _gyro[1],
- _gyro[2],
- ];
-
+ Sk.sense_hat.rtimu.gyro = [_gyro[0], _gyro[1], _gyro[2]];
// _compass = perturb(_compass, .01);
// multiply with 100 -> from Gauss to microteslas (µT)
@@ -118,24 +113,28 @@ export function updateRTIMU() {
];
}
-window.rotatemodel = function(x, y, z){
+window.rotatemodel = function (x, y, z) {
window.mod.rotation.x = x;
window.mod.rotation.y = y;
window.mod.rotation.z = z;
-}
+};
export function resetModel(event) {
event.preventDefault();
- var x = 0
- , y = 0
- , z = 0;
- window.rotatemodel(Geometry.degToRad(x), Geometry.degToRad(y), Geometry.degToRad(z));
+ var x = 0,
+ y = 0,
+ z = 0;
+ window.rotatemodel(
+ Geometry.degToRad(x),
+ Geometry.degToRad(y),
+ Geometry.degToRad(z),
+ );
}
export function extractRollPitchYaw(x, y, z) {
- const roll = ((y * 180 / Math.PI) + 360) % 360
- const pitch = ((x * 180 / Math.PI) + 90 + 360) % 360
- const yaw = ((z * 180 / Math.PI) + 360) % 360
- return [roll, pitch, yaw]
+ const roll = ((y * 180) / Math.PI + 360) % 360;
+ const pitch = ((x * 180) / Math.PI + 90 + 360) % 360;
+ const yaw = ((z * 180) / Math.PI + 360) % 360;
+ return [roll, pitch, yaw];
}
diff --git a/src/utils/ResizableWithHandle.js b/src/utils/ResizableWithHandle.js
index c58a3bfaa..2a07f0cff 100644
--- a/src/utils/ResizableWithHandle.js
+++ b/src/utils/ResizableWithHandle.js
@@ -1,59 +1,92 @@
import React, { useState, useMemo } from "react";
import PropTypes from "prop-types";
-import { Resizable } from 're-resizable';
+import { Resizable } from "re-resizable";
-import './ResizableWithHandle.scss';
+import "./ResizableWithHandle.scss";
const VerticalHandle = () => (
-