profile: remove 'drag and drop' tile settings

Fixes #3791.
This commit is contained in:
Matilde Park 2020-10-23 16:35:27 -04:00
parent ae5561ee61
commit 278f5b4369
7 changed files with 31 additions and 289 deletions

Binary file not shown.

View File

@ -26,9 +26,6 @@
"prop-types": "^15.7.2",
"react": "^16.5.2",
"react-codemirror2": "^6.0.1",
"react-dnd-html5-backend": "^11.1.3",
"react-dnd-multi-backend": "^6.0.2",
"react-dnd-touch-backend": "^11.1.3",
"react-dom": "^16.8.6",
"react-helmet": "^6.1.0",
"react-markdown": "^4.3.1",
@ -73,7 +70,6 @@
"file-loader": "^6.0.0",
"html-webpack-plugin": "^4.2.0",
"moment-locales-webpack-plugin": "^1.2.0",
"react-dnd": "^11.1.3",
"react-hot-loader": "^4.12.21",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",

View File

@ -1,9 +1,7 @@
import BaseApi from './base';
import { StoreState } from '../store/type';
export default class LaunchApi extends BaseApi<StoreState> {
add(name: string, tile = { basic : { title: '', linkedUrl: '', iconUrl: '' }}) {
return this.launchAction({ add: { name, tile } });
}
@ -12,10 +10,6 @@ export default class LaunchApi extends BaseApi<StoreState> {
return this.launchAction({ remove: name });
}
changeOrder(orderedTiles: string[] = []) {
return this.launchAction({ 'change-order': orderedTiles });
}
changeFirstTime(firstTime = true) {
return this.launchAction({ 'change-first-time': firstTime });
}
@ -31,6 +25,5 @@ export default class LaunchApi extends BaseApi<StoreState> {
private launchAction(data) {
return this.action('launch', 'launch-action', data);
}
}

View File

@ -1,34 +1,28 @@
import React from "react";
import React from 'react';
import {
Box,
Label,
ManagedCheckboxField as Checkbox,
Button,
} from "@tlon/indigo-react";
import { Formik, Form } from "formik";
import * as Yup from "yup";
import _ from "lodash";
Button
} from '@tlon/indigo-react';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';
import GlobalApi from "../../../../api/global";
import { LaunchState } from "../../../../types/launch-update";
import { DropLaunchTiles } from "./DropLaunch";
import { S3State, BackgroundConfig } from "../../../../types";
import { BackgroundPicker, BgType } from "./BackgroundPicker";
import GlobalApi from '~/logic/api/global';
import { S3State, BackgroundConfig } from '~/types';
import { BackgroundPicker, BgType } from './BackgroundPicker';
const formSchema = Yup.object().shape({
tileOrdering: Yup.array().of(Yup.string()),
bgType: Yup.string()
.oneOf(["none", "color", "url"], "invalid")
.required("Required"),
.oneOf(['none', 'color', 'url'], 'invalid')
.required('Required'),
bgUrl: Yup.string().url(),
bgColor: Yup.string().matches(/#([A-F]|[a-f]|[0-9]){6}/, "Invalid color"),
bgColor: Yup.string().matches(/#([A-F]|[a-f]|[0-9]){6}/, 'Invalid color'),
avatars: Yup.boolean(),
nicknames: Yup.boolean(),
nicknames: Yup.boolean()
});
interface FormSchema {
tileOrdering: string[];
bgType: BgType;
bgColor: string | undefined;
bgUrl: string | undefined;
@ -38,7 +32,6 @@ interface FormSchema {
interface DisplayFormProps {
api: GlobalApi;
launch: LaunchState;
dark: boolean;
background: BackgroundConfig;
hideAvatars: boolean;
@ -47,16 +40,16 @@ interface DisplayFormProps {
}
export default function DisplayForm(props: DisplayFormProps) {
const { api, launch, background, hideAvatars, hideNicknames, s3 } = props;
const { api, background, hideAvatars, hideNicknames, s3 } = props;
let bgColor, bgUrl;
if (background?.type === "url") {
if (background?.type === 'url') {
bgUrl = background.url;
}
if (background?.type === "color") {
if (background?.type === 'color') {
bgColor = background.color;
}
const bgType = background?.type || "none";
const bgType = background?.type || 'none';
return (
<Formik
@ -67,18 +60,15 @@ export default function DisplayForm(props: DisplayFormProps) {
bgColor,
bgUrl,
avatars: hideAvatars,
nicknames: hideNicknames,
tileOrdering: launch.tileOrdering,
nicknames: hideNicknames
} as FormSchema
}
onSubmit={(values, actions) => {
api.launch.changeOrder(values.tileOrdering);
const bgConfig: BackgroundConfig =
values.bgType === "color"
? { type: "color", color: values.bgColor || "" }
: values.bgType === "url"
? { type: "url", url: values.bgUrl || "" }
values.bgType === 'color'
? { type: 'color', color: values.bgColor || '' }
: values.bgType === 'url'
? { type: 'url', url: values.bgUrl || '' }
: undefined;
api.local.setBackground(bgConfig);
@ -88,7 +78,7 @@ export default function DisplayForm(props: DisplayFormProps) {
actions.setSubmitting(false);
}}
>
{(props) => (
{props => (
<Form>
<Box
display="grid"
@ -99,17 +89,6 @@ export default function DisplayForm(props: DisplayFormProps) {
<Box color="black" fontSize={1} mb={3} fontWeight={900}>
Display Preferences
</Box>
<Box mb={2}>
<Label display="block" pb={2}>
Tile Order
</Label>
<DropLaunchTiles
id="tileOrdering"
name="tileOrdering"
tiles={launch.tiles}
order={launch.tileOrdering}
/>
</Box>
<BackgroundPicker
bgType={props.values.bgType}
bgUrl={props.values.bgUrl}

View File

@ -1,127 +0,0 @@
import React, { useMemo } from "react";
import { useDrag } from "react-dnd";
import { usePreview } from "react-dnd-multi-backend";
import { capitalize } from "lodash";
import { TileTypeBasic, Tile } from "../../../../types/launch-update";
import { Box, Image as _Image, Text } from "@tlon/indigo-react";
import styled from "styled-components";
// Need to change dojo image
const Image = styled(_Image)<{ invert?: boolean }>`
${(p) =>
p.theme.colors.white !== "rgba(255,255,255,1)" ? `filter: invert(1);` : ``}
${(p) =>
!p.invert
? ``
: p.theme.colors.white !== "rgba(255,255,255,1)"
? `
filter: invert(0);
`
: `filter: invert(1);`}
`;
interface DragTileProps {
index: number;
tile: Tile;
title: string;
style?: any;
}
function DragTileBox({ title, index, tile, ...props }: any) {
const [, dragRef] = useDrag({
item: { type: "launchTile", index, tile, title },
collect: (monitor) => ({}),
});
return (
<Box
ref={dragRef}
display="flex"
alignItems="center"
justifyContent="space-around"
flexDirection="column"
border={1}
borderColor="black"
height="100%"
width="100%"
style={{ cursor: "move" }}
{...props}
></Box>
);
}
function DragTileCustom({ index, title, style }: any) {
const tile = { type: { custom: null } };
return (
<DragTileBox
bg="white"
style={style}
title={title}
tile={tile}
index={index}
>
<Text fontSize={1}>{capitalize(title)}</Text>
</DragTileBox>
);
}
function DragTileBasic(props: {
tile: TileTypeBasic;
index: number;
style: any;
}) {
const { basic: tile } = props.tile;
const isDojo = useMemo(() => tile.title === "Dojo", [tile.title]);
return (
<DragTileBox
tile={{ type: props.tile }}
index={props.index}
bg={
"white" // isDojo ? "black" : "white"
}
style={props.style}
>
<Image width="48px" height="48px" src={tile.iconUrl} invert={isDojo} />
<Text
color={
"black" // isDojo ? "white" : "black"
}
>
{tile.title}
</Text>
</DragTileBox>
);
}
export function DragTile(props: DragTileProps) {
if ("basic" in props.tile.type) {
return (
<DragTileBasic
index={props.index}
style={props.style}
tile={props.tile.type}
/>
);
} else {
return (
<DragTileCustom
style={props.style}
title={props.title}
index={props.index}
/>
);
}
}
export function DragTilePreview() {
let { display, style, item } = usePreview();
if (!display) {
return null;
}
style = { ...style, height: "96px", width: "96px", "z-index": "5" };
return <DragTile style={style} {...item} />;
}

View File

@ -1,85 +0,0 @@
import React, { useCallback, ReactNode } from "react";
import { useDrop } from "react-dnd";
import { DndProvider, usePreview } from "react-dnd-multi-backend";
import HTML5toTouch from "react-dnd-multi-backend/dist/esm/HTML5toTouch";
import { Box } from "@tlon/indigo-react";
import { DragTile, DragTilePreview } from "./DragTile";
import { useField } from "formik";
function DropLaunchTile({
children,
index,
didDrop,
}: {
index: number;
children: ReactNode;
didDrop: (item: number, location: number) => void;
}) {
const onDrop = useCallback(
(item: any, monitor: any) => {
didDrop(item.index, index);
},
[index, didDrop]
);
const { display, style, item } = usePreview();
const [{ isOver }, drop] = useDrop({
accept: "launchTile",
drop: onDrop,
collect: (monitor) => ({
isOver: !!monitor.isOver(),
}),
});
return (
<div
ref={drop}
style={{
position: "relative",
width: "100%",
height: "100%",
}}
>
{children}
</div>
);
}
export function DropLaunchTiles({ tiles, name }: any) {
const [field, meta, helpers] = useField<string[]>(name);
const { value } = meta;
const { setValue } = helpers;
const onChange = useCallback(
(x: number, y: number) => {
// swap tiles
let t = value.slice();
const c = t[x];
t[x] = t[y];
t[y] = c;
setValue(t);
},
[setValue, value]
);
return (
<DndProvider options={HTML5toTouch}>
<Box
display="grid"
gridGap={2}
gridTemplateColumns={["96px 96px", "96px 96px 96px 96px"]}
gridAutoRows="96px"
>
<DragTilePreview />
{value.map((tile, i) => (
<DropLaunchTile didDrop={onChange} key={`${i}-${tile}`} index={i}>
<DragTile title={tile} tile={tiles[tile]} index={i} />
</DropLaunchTile>
))}
</Box>
</DndProvider>
);
}

View File

@ -1,31 +1,18 @@
import React from "react";
import React from 'react';
import {
Box,
Text,
Button,
Col,
Input,
InputLabel,
Radio,
Checkbox,
} from "@tlon/indigo-react";
import * as Yup from "yup";
import { Formik, Form } from "formik";
import _ from "lodash";
import { Box } from '@tlon/indigo-react';
import GlobalApi from "../../../api/global";
import { StoreState } from "../../../store/type";
import DisplayForm from "./lib/DisplayForm";
import S3Form from "./lib/S3Form";
import SecuritySettings from "./lib/Security";
import RemoteContentForm from "./lib/RemoteContent";
import GlobalApi from '~/logic/api/global';
import { StoreState } from '~/logic/store/type';
import DisplayForm from './lib/DisplayForm';
import S3Form from './lib/S3Form';
import SecuritySettings from './lib/Security';
import RemoteContentForm from './lib/RemoteContent';
type ProfileProps = StoreState & { api: GlobalApi; ship: string };
export default function Settings({
api,
launch,
s3,
dark,
hideAvatars,
@ -45,14 +32,13 @@ export default function Settings({
>
<DisplayForm
api={api}
launch={launch}
dark={dark}
hideNicknames={hideNicknames}
hideAvatars={hideAvatars}
background={background}
s3={s3}
/>
<RemoteContentForm {...{api, remoteContentPolicy}} />
<RemoteContentForm {...{ api, remoteContentPolicy }} />
<S3Form api={api} s3={s3} />
<SecuritySettings api={api} />
</Box>