Front: Typecheck Elements

This commit is contained in:
Arthur Jamet
2023-06-08 10:42:59 +01:00
parent ff0fc7a8ae
commit 63d4b10ebb
8 changed files with 1438 additions and 1204 deletions
+2 -2
View File
@@ -12,7 +12,7 @@ import HomeView from './views/HomeView';
import SearchView from './views/SearchView';
import SetttingsNavigator from './views/settings/SettingsView';
import { useQuery } from 'react-query';
import API from './API';
import API, { APIError } from './API';
import PlayView from './views/PlayView';
import ScoreView from './views/ScoreView';
import { LoadingView } from './components/Loading';
@@ -94,7 +94,7 @@ export const Router = () => {
retry: 1,
refetchOnWindowFocus: false,
onError: (err) => {
if (err.status === 401) {
if (err instanceof APIError && err.status === 401) {
dispatch(unsetAccessToken());
}
},
+6 -2
View File
@@ -12,14 +12,18 @@ const cardBorder = (theme: ReturnType<typeof useTheme>) => ({
borderWidth: 1
})
const Card = (props: Parameters<typeof Box>[0] & { onPress: () => void }) => {
type CardProps = Parameters<typeof Box>[0] & {
onPress: () => void
}
const Card = (props: CardProps) => {
const theme = useTheme();
const colorScheme = useSelector((state: RootState) => state.settings.local.colorScheme);
const systemColorMode = useColorScheme();
return <Pressable onPress={props.onPress}>
{({ isHovered, isPressed }) => (
<Box {...props} style={{ ...(props.style ?? {}), ...cardBorder(theme) }}
<Box {...props} style={[props.style, cardBorder(theme)]}
bg={(colorScheme == 'system' ? systemColorMode : colorScheme) == 'dark'
? (isHovered || isPressed) ? 'gray.800' : undefined
: (isHovered || isPressed) ? 'coolGray.200' : undefined
+5 -4
View File
@@ -1,10 +1,11 @@
import React from "react";
import { ElementProps } from "./ElementList";
import { ElementProps } from "./ElementTypes";
import { RawElement } from "./RawElement";
import { Pressable } from "native-base";
import { Pressable, IPressableProps } from "native-base";
import { ElementTextProps, ElementToggleProps } from './ElementTypes';
export const Element = (props: ElementProps) => {
let actionFunction = null as null | Function;
export const Element = <T extends ElementProps,>(props: T) => {
let actionFunction: IPressableProps['onPress'] = null;
switch (props.type) {
case "text":
+5 -25
View File
@@ -2,14 +2,7 @@ import React from "react";
import { StyleProp, ViewStyle } from "react-native";
import { Element } from "./Element";
import useColorScheme from "../../hooks/colorScheme";
import {
ElementTextProps,
ElementToggleProps,
ElementDropdownProps,
ElementRangeProps,
ElementType,
} from "./ElementTypes";
import { ElementProps } from "./ElementTypes";
import {
Box,
@@ -17,21 +10,6 @@ import {
Divider,
} from "native-base";
export type ElementProps = {
title: string;
icon?: React.ReactNode;
type?: ElementType;
helperText?: string;
description?: string;
disabled?: boolean;
data?:
| ElementTextProps
| ElementToggleProps
| ElementDropdownProps
| ElementRangeProps
| React.ReactNode;
};
type ElementListProps = {
elements: ElementProps[];
style?: StyleProp<ViewStyle>;
@@ -42,9 +20,11 @@ const ElementList = ({ elements, style }: ElementListProps) => {
const isDark = colorScheme === "dark";
const elementStyle = {
borderRadius: 10,
boxShadow: isDark ? "0px 0px 3px 0px rgba(255,255,255,0.6)" : "0px 0px 3px 0px rgba(0,0,0,0.4)",
boxShadow: isDark
? "0px 0px 3px 0px rgba(255,255,255,0.6)"
: "0px 0px 3px 0px rgba(0,0,0,0.4)",
overflow: "hidden",
};
} as const;
return (
<Column style={[style, elementStyle]}>
+14 -7
View File
@@ -1,12 +1,19 @@
import { Select, Switch, Text, Icon, Row, Slider } from "native-base";
import { MaterialIcons } from "@expo/vector-icons";
export type ElementType =
| "custom"
| "default"
| "text"
| "toggle"
| "dropdown"
| "range";
export type ElementProps = {
title: string;
icon?: React.ReactNode;
helperText?: string;
description?: string;
disabled?: boolean;
} & (
{ type: 'text', data : ElementTextProps } |
{ type: 'toggle', data : ElementToggleProps } |
{ type: 'dropdown', data : ElementDropdownProps } |
{ type: 'range', data : ElementRangeProps } |
{ type: 'custom', data : React.ReactNode }
);
export type DropdownOption = {
label: string;
+6 -19
View File
@@ -12,7 +12,7 @@ import {
} from "native-base";
import useColorScheme from "../../hooks/colorScheme";
import { Ionicons } from "@expo/vector-icons";
import { ElementProps } from "./ElementList";
import { ElementProps } from "./ElementTypes";
import {
getElementDropdownNode,
getElementTextNode,
@@ -121,28 +121,15 @@ export const RawElement = ({ element, isHovered }: RawElementProps) => {
{(() => {
switch (type) {
case "text":
return getElementTextNode(
data as ElementTextProps,
disabled ?? false
);
return getElementTextNode(data, disabled ?? false);
case "toggle":
return getElementToggleNode(
data as ElementToggleProps,
disabled ?? false
);
return getElementToggleNode(data, disabled ?? false);
case "dropdown":
return getElementDropdownNode(
data as ElementDropdownProps,
disabled ?? false
);
return getElementDropdownNode(data, disabled ?? false);
case "range":
return getElementRangeNode(
data as ElementRangeProps,
disabled ?? false,
title
);
return getElementRangeNode(data, disabled ?? false, title);
case "custom":
return data as React.ReactNode;
return data;
default:
return <Text>Unknown type</Text>;
}
+6 -6
View File
@@ -37,7 +37,7 @@ const handleChangePassword = async (oldPassword: string, newPassword: string): P
}
}
const MainView = ({navigation}) => {
const MainView = ({ navigation }) => {
const dispatch = useDispatch();
return (
@@ -73,7 +73,7 @@ const MainView = ({navigation}) => {
)
}
export const ChangePasswordView = ({navigation}) => {
export const ChangePasswordView = ({ navigation }) => {
return (
<Center style={{ flex: 1}}>
<Heading paddingBottom={'2%'}>{translate('changePassword')}</Heading>
@@ -82,7 +82,7 @@ export const ChangePasswordView = ({navigation}) => {
)
}
export const ChangeEmailView = ({navigation}) => {
export const ChangeEmailView = ({ navigation }) => {
return (
<Center style={{ flex: 1}}>
<Heading paddingBottom={'2%'}>{translate('changeEmail')}</Heading>
@@ -91,7 +91,7 @@ export const ChangeEmailView = ({navigation}) => {
)
}
export const GoogleAccountView = ({navigation}) => {
export const GoogleAccountView = ({ navigation }) => {
return (
<Center style={{ flex: 1}}>
<Text>GoogleAccount</Text>
@@ -99,7 +99,7 @@ export const GoogleAccountView = ({navigation}) => {
)
}
export const PianoSettingsView = ({navigation}) => {
export const PianoSettingsView = ({ navigation }) => {
return (
<Center style={{ flex: 1}}>
<Text>Global settings for the virtual piano</Text>
@@ -111,7 +111,7 @@ const TabRow = createTabRowNavigator();
const SetttingsNavigator = () => {
const userQuery = useQuery(['user'], () => API.getUserInfo());
const user = userQuery.data;
const user = useMemo(() => userQuery.data, [userQuery]);
if (userQuery.isError) {
user.isGuest = false;
+1394 -1139
View File
File diff suppressed because it is too large Load Diff