From 51f4fd4ae8039902161ac4b9bf9e2ec4c7f9bffe Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Wed, 3 Mar 2021 18:23:47 +0000 Subject: [PATCH 1/7] WIP alternative layout --- src/workbench/Files.tsx | 5 ++++- src/workbench/LeftPanel.tsx | 8 ++++++-- src/workbench/OpenButton.tsx | 8 ++++++-- src/workbench/Workbench.tsx | 4 ---- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/workbench/Files.tsx b/src/workbench/Files.tsx index 439722cc1..16b8681bf 100644 --- a/src/workbench/Files.tsx +++ b/src/workbench/Files.tsx @@ -1,5 +1,6 @@ import { Button, + Center, HStack, IconButton, List, @@ -13,6 +14,7 @@ import { useFileSystem, useFileSystemState } from "../fs/fs-hooks"; import { saveAs } from "file-saver"; import useActionFeedback from "../common/use-action-feedback"; import ProjectNameEditable from "./ProjectNameEditable"; +import OpenButton from "./OpenButton"; interface FilesProps { onSelectedFileChanged: (name: string) => void; @@ -27,7 +29,8 @@ const Files = ({ onSelectedFileChanged }: FilesProps) => { return null; } return ( - + + {fs.files.map((f) => ( diff --git a/src/workbench/LeftPanel.tsx b/src/workbench/LeftPanel.tsx index d4f25e0a6..386c04a94 100644 --- a/src/workbench/LeftPanel.tsx +++ b/src/workbench/LeftPanel.tsx @@ -15,6 +15,7 @@ import { IconType } from "react-icons"; import { RiFile3Line, RiLayoutMasonryFill, + RiSave2Line, RiSettings2Line, } from "react-icons/ri"; import GradientLine from "../common/GradientLine"; @@ -44,8 +45,8 @@ const LeftPanel = ({ onSelectedFileChanged }: LeftPanelProps) => { }, { id: "files", - title: "Files", - icon: RiFile3Line, + title: "Load and save", + icon: RiSave2Line, contents: , }, { @@ -74,6 +75,9 @@ interface LeftPanelConentsProps { const LeftPanelContents = ({ panes }: LeftPanelConentsProps) => { return ( + + + {panes.map((p) => ( diff --git a/src/workbench/OpenButton.tsx b/src/workbench/OpenButton.tsx index fd0be6f57..bc3e5ebcc 100644 --- a/src/workbench/OpenButton.tsx +++ b/src/workbench/OpenButton.tsx @@ -4,10 +4,14 @@ import { RiFolderOpenLine } from "react-icons/ri"; import useActionFeedback from "../common/use-action-feedback"; import { useFileSystem } from "../fs/fs-hooks"; +interface OpenButtonProps extends ButtonProps { + text?: string; +} + /** * Open HEX button, with an associated input field. */ -const OpenButton = (props: ButtonProps) => { +const OpenButton = ({ text = "Open", ...props }: OpenButtonProps) => { const fs = useFileSystem(); const actionFeedback = useActionFeedback(); const ref = useRef(null); @@ -51,7 +55,7 @@ const OpenButton = (props: ButtonProps) => { onClick={handleChooseFile} {...props} > - Open + {text} ); diff --git a/src/workbench/Workbench.tsx b/src/workbench/Workbench.tsx index e8a0e129a..d1eb4b573 100644 --- a/src/workbench/Workbench.tsx +++ b/src/workbench/Workbench.tsx @@ -20,10 +20,6 @@ const Workbench = () => { return ( // https://github.com/aeagle/react-spaces - -
- - Date: Thu, 4 Mar 2021 09:40:34 +0000 Subject: [PATCH 2/7] Somewhat improve the alt-layout. Share and help are still missing. --- src/workbench/Files.tsx | 31 ++++++++++++++++++--------- src/workbench/LeftPanel.tsx | 12 ++++------- src/workbench/ProjectNameEditable.tsx | 6 +++++- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/workbench/Files.tsx b/src/workbench/Files.tsx index 16b8681bf..249c38c64 100644 --- a/src/workbench/Files.tsx +++ b/src/workbench/Files.tsx @@ -5,6 +5,7 @@ import { IconButton, List, ListItem, + Text, VStack, } from "@chakra-ui/react"; import React, { useCallback } from "react"; @@ -29,16 +30,26 @@ const Files = ({ onSelectedFileChanged }: FilesProps) => { return null; } return ( - - - - - {fs.files.map((f) => ( - - onSelectedFileChanged(f.name)} /> - - ))} - + + + + + + + File list + + + {fs.files.map((f) => ( + + onSelectedFileChanged(f.name)} + /> + + ))} + + + ); }; diff --git a/src/workbench/LeftPanel.tsx b/src/workbench/LeftPanel.tsx index 386c04a94..54858d59c 100644 --- a/src/workbench/LeftPanel.tsx +++ b/src/workbench/LeftPanel.tsx @@ -1,24 +1,20 @@ import { - Box, + Center, Flex, - HStack, Icon, Tab, TabList, TabPanel, TabPanels, Tabs, - VStack, } from "@chakra-ui/react"; import React, { ReactNode, useMemo } from "react"; import { IconType } from "react-icons"; import { - RiFile3Line, RiLayoutMasonryFill, RiSave2Line, RiSettings2Line, } from "react-icons/ri"; -import GradientLine from "../common/GradientLine"; import DeviceConnection from "./DeviceConnection"; import Files from "./Files"; import LeftPanelTabContent from "./LeftPanelTabContent"; @@ -75,9 +71,9 @@ interface LeftPanelConentsProps { const LeftPanelContents = ({ panes }: LeftPanelConentsProps) => { return ( - - - +
+ +
{panes.map((p) => ( diff --git a/src/workbench/ProjectNameEditable.tsx b/src/workbench/ProjectNameEditable.tsx index ad7b7d6f6..7ea5f442f 100644 --- a/src/workbench/ProjectNameEditable.tsx +++ b/src/workbench/ProjectNameEditable.tsx @@ -53,7 +53,11 @@ const ProjectNameEditable = () => { display="flex" alignItems="center" /> - + )} From 2a1ef9c7e3b9dafb5ebaa8b59947e3cee79d2850 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Thu, 4 Mar 2021 09:54:08 +0000 Subject: [PATCH 3/7] Help in the side panel. It's an option... --- src/workbench/Help.tsx | 50 +++++++++++++++++++++++++++++++++++++ src/workbench/HelpMenu.tsx | 33 +++++++++++++----------- src/workbench/LeftPanel.tsx | 8 ++++++ 3 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 src/workbench/Help.tsx diff --git a/src/workbench/Help.tsx b/src/workbench/Help.tsx new file mode 100644 index 000000000..2712903c0 --- /dev/null +++ b/src/workbench/Help.tsx @@ -0,0 +1,50 @@ +import { + Button, + HStack, + IconButton, + Link, + Text, + VStack, +} from "@chakra-ui/react"; +import React, { useCallback } from "react"; +import { RiExternalLinkLine, RiFileCopy2Line } from "react-icons/ri"; +import Separate from "../common/Separate"; +import useActionFeedback from "../common/use-action-feedback"; +import config from "../config"; +import { copyVersion, versionInfo } from "./HelpMenu"; + +/** + * Help as a tab. + */ +const Help = () => { + const externalLinkIcon = ; + const actionFeedback = useActionFeedback(); + const handleCopyVersion = useCallback(() => { + copyVersion(actionFeedback); + }, [actionFeedback]); + return ( + + + + {externalLinkIcon} Documentation + + {externalLinkIcon} Support + + + +
}> + {versionInfo} +
+
+ } + variant="outline" + aria-label="Copy version information to the clipboard" + /> +
+
+ ); +}; + +export default Help; diff --git a/src/workbench/HelpMenu.tsx b/src/workbench/HelpMenu.tsx index f5362625b..488e4f29d 100644 --- a/src/workbench/HelpMenu.tsx +++ b/src/workbench/HelpMenu.tsx @@ -1,6 +1,4 @@ -import React, { useCallback } from "react"; import { - Button, IconButton, Menu, MenuButton, @@ -12,23 +10,24 @@ import { ThemeTypings, ThemingProps, } from "@chakra-ui/react"; +import React, { useCallback } from "react"; import { - RiArrowDropDownLine, RiExternalLinkLine, RiFileCopy2Line, - RiInformationLine, RiQuestionLine, } from "react-icons/ri"; -import { microPythonVersions } from "../fs/fs"; import Separate from "../common/Separate"; +import useActionFeedback, { + ActionFeedback, +} from "../common/use-action-feedback"; import config from "../config"; -import useActionFeedback from "../common/use-action-feedback"; +import { microPythonVersions } from "../fs/fs"; interface HelpMenuProps extends ThemingProps<"Menu"> { size?: ThemeTypings["components"]["Button"]["sizes"]; } -const versionInfo = [ +export const versionInfo = [ `Editor ${process.env.REACT_APP_VERSION}`, `MicroPython ${microPythonVersions.map((mpy) => mpy.version).join("/")}`, ]; @@ -36,18 +35,22 @@ const versionInfo = [ const openInNewTab = (href: string) => () => window.open(href, "_blank", "noopener"); -const handleDocumentation = openInNewTab(config.documentationLink); -const handleSupport = openInNewTab(config.supportLink); +// Exported for now so we can share them in alt-layouts. +export const handleDocumentation = openInNewTab(config.documentationLink); +export const handleSupport = openInNewTab(config.supportLink); +export const copyVersion = async (actionFeedback: ActionFeedback) => { + try { + await navigator.clipboard.writeText(versionInfo.join("\n")); + } catch (e) { + actionFeedback.unexpectedError(e); + } +}; const HelpMenu = ({ size, ...props }: HelpMenuProps) => { const actionFeedback = useActionFeedback(); const handleCopyVersion = useCallback(async () => { - try { - await navigator.clipboard.writeText(versionInfo.join("\n")); - } catch (e) { - actionFeedback.unexpectedError(e); - } - }, [actionFeedback, versionInfo]); + copyVersion(actionFeedback); + }, [actionFeedback]); // TODO: Can we make these actual links and still use the menu components? return ( diff --git a/src/workbench/LeftPanel.tsx b/src/workbench/LeftPanel.tsx index 54858d59c..3348b7e93 100644 --- a/src/workbench/LeftPanel.tsx +++ b/src/workbench/LeftPanel.tsx @@ -12,11 +12,13 @@ import React, { ReactNode, useMemo } from "react"; import { IconType } from "react-icons"; import { RiLayoutMasonryFill, + RiQuestionLine, RiSave2Line, RiSettings2Line, } from "react-icons/ri"; import DeviceConnection from "./DeviceConnection"; import Files from "./Files"; +import Help from "./Help"; import LeftPanelTabContent from "./LeftPanelTabContent"; import Logo from "./Logo"; import Packages from "./Packages"; @@ -51,6 +53,12 @@ const LeftPanel = ({ onSelectedFileChanged }: LeftPanelProps) => { icon: RiSettings2Line, contents: , }, + { + id: "help", + title: "Help", + icon: RiQuestionLine, + contents: , + }, ], [onSelectedFileChanged] ); From fc3e5984072676113d3be97f16ddec7d4bceeff5 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Thu, 4 Mar 2021 12:43:32 +0000 Subject: [PATCH 4/7] Alt-alt layout. Some of this ideas are probably worth stealing even if we don't go with it as-is. --- src/editor/EditorContainer.tsx | 1 + src/editor/EditorToolbar.tsx | 31 +++++++++++ src/workbench/CollapsableButton.tsx | 42 ++++++++++++++ src/workbench/DeviceConnection.tsx | 71 ++++++------------------ src/workbench/DownloadButton.tsx | 23 ++++++-- src/workbench/FlashButton.tsx | 79 +++++++++++++++++++++++++++ src/workbench/LeftPanel.tsx | 4 -- src/workbench/LeftPanelTabContent.tsx | 2 +- src/workbench/ProjectNameEditable.tsx | 1 - src/workbench/Serial.tsx | 24 ++++++++ src/workbench/Workbench.tsx | 33 ++++++----- 11 files changed, 232 insertions(+), 79 deletions(-) create mode 100644 src/editor/EditorToolbar.tsx create mode 100644 src/workbench/CollapsableButton.tsx create mode 100644 src/workbench/FlashButton.tsx create mode 100644 src/workbench/Serial.tsx diff --git a/src/editor/EditorContainer.tsx b/src/editor/EditorContainer.tsx index 6b7569423..f0ad644e3 100644 --- a/src/editor/EditorContainer.tsx +++ b/src/editor/EditorContainer.tsx @@ -5,6 +5,7 @@ import { useSettings } from "../settings"; import ZoomControls from "../workbench/ZoomControls"; import Editor from "./Editor"; import NonMainFileNotice from "./NonMainFileNotice"; +import EditorToolbar from "./EditorToolbar"; interface EditorContainerProps { filename: string; diff --git a/src/editor/EditorToolbar.tsx b/src/editor/EditorToolbar.tsx new file mode 100644 index 000000000..6fd5fd222 --- /dev/null +++ b/src/editor/EditorToolbar.tsx @@ -0,0 +1,31 @@ +import { HStack } from "@chakra-ui/react"; +import React from "react"; +import DownloadButton from "../workbench/DownloadButton"; +import ProjectNameEditable from "../workbench/ProjectNameEditable"; +import ZoomControls from "../workbench/ZoomControls"; + +interface EditorToolbarProps {} + +const EditorToolbar = ({}: EditorToolbarProps) => { + return ( + + + + + + + + + + ); +}; + +export default EditorToolbar; diff --git a/src/workbench/CollapsableButton.tsx b/src/workbench/CollapsableButton.tsx new file mode 100644 index 000000000..529be61ac --- /dev/null +++ b/src/workbench/CollapsableButton.tsx @@ -0,0 +1,42 @@ +import { + Button, + HTMLChakraProps, + IconButton, + ThemingProps, +} from "@chakra-ui/react"; +import React from "react"; + +export interface CollapsableButtonProps + extends HTMLChakraProps<"button">, + ThemingProps<"Button"> { + mode: "icon" | "button"; + text: string; + icon: React.ReactElement; + /** + * Width used only in button mode. + */ + buttonWidth?: number | string; +} + +/** + * Button that can be a regular or icon button. + * + * We'd like to do this at a lower-level so we can animate a transition. + */ +const CollapsableButton = ({ + mode, + text, + icon, + buttonWidth, + ...props +}: CollapsableButtonProps) => { + return mode === "icon" ? ( + + ) : ( + + ); +}; + +export default CollapsableButton; diff --git a/src/workbench/DeviceConnection.tsx b/src/workbench/DeviceConnection.tsx index 6ad391a9c..e4f631dc4 100644 --- a/src/workbench/DeviceConnection.tsx +++ b/src/workbench/DeviceConnection.tsx @@ -1,4 +1,4 @@ -import { Button, HStack, Switch, Text, VStack } from "@chakra-ui/react"; +import { Button, Flex, HStack, Switch, Text, VStack } from "@chakra-ui/react"; import React, { useCallback, useState } from "react"; import { RiFlashlightFill } from "react-icons/ri"; import { useConnectionStatus, useDevice } from "../device/device-hooks"; @@ -10,6 +10,7 @@ import useActionFeedback, { } from "../common/use-action-feedback"; import { BoardId } from "../device/board-id"; import Separate from "../common/Separate"; +import FlashButton from "./FlashButton"; class HexGenerationError extends Error {} @@ -23,7 +24,6 @@ const DeviceConnection = () => { const connectionStatus = useConnectionStatus(); const connected = connectionStatus === ConnectionStatus.CONNECTED; const supported = connectionStatus !== ConnectionStatus.NOT_SUPPORTED; - const [progress, setProgress] = useState(undefined); const actionFeedback = useActionFeedback(); const device = useDevice(); const fs = useFileSystem(); @@ -38,67 +38,28 @@ const DeviceConnection = () => { } } }, [device, connected]); - - const handleFlash = useCallback(async () => { - const dataSource = async (boardId: BoardId) => { - try { - return await fs.toHexForFlash(boardId); - } catch (e) { - throw new HexGenerationError(e.message); - } - }; - - try { - await device.flash(dataSource, { partial: true, progress: setProgress }); - } catch (e) { - if (e instanceof HexGenerationError) { - actionFeedback.expectedError({ - title: "Failed to build the hex file", - description: e.message, - }); - } else { - handleWebUSBError(actionFeedback, e); - } - } - }, [fs, device, actionFeedback]); - + const buttonWidth = "10rem"; return ( - + {supported ? ( - - + + {connected ? "micro:bit connected" : "micro:bit disconnected"} ) : null} - - - {connected && ( - - )} - + + + - + ); }; diff --git a/src/workbench/DownloadButton.tsx b/src/workbench/DownloadButton.tsx index 5db12ac09..692b1529d 100644 --- a/src/workbench/DownloadButton.tsx +++ b/src/workbench/DownloadButton.tsx @@ -1,8 +1,18 @@ -import { Button, ButtonProps } from "@chakra-ui/react"; +import { + BoxProps, + Button, + ButtonProps, + Icon, + IconButton, +} from "@chakra-ui/react"; import React, { useCallback } from "react"; import { RiDownload2Line } from "react-icons/ri"; import useActionFeedback from "../common/use-action-feedback"; import { useFileSystem } from "../fs/fs-hooks"; +import CollapsableButton, { CollapsableButtonProps } from "./CollapsableButton"; + +interface DownloadButtonProps + extends Omit {} /** * Download HEX button. @@ -12,7 +22,7 @@ import { useFileSystem } from "../fs/fs-hooks"; * * Otherwise it's a more minor action. */ -const DownloadButton = (props: ButtonProps) => { +const DownloadButton = (props: DownloadButtonProps) => { const fs = useFileSystem(); const actionFeedback = useActionFeedback(); const handleDownload = useCallback(async () => { @@ -33,9 +43,12 @@ const DownloadButton = (props: ButtonProps) => { }, []); return ( - + } + onClick={handleDownload} + text="Download" + /> ); }; diff --git a/src/workbench/FlashButton.tsx b/src/workbench/FlashButton.tsx new file mode 100644 index 000000000..534b4ff8a --- /dev/null +++ b/src/workbench/FlashButton.tsx @@ -0,0 +1,79 @@ +import React, { useCallback, useState } from "react"; +import { RiFlashlightFill } from "react-icons/ri"; +import Separate from "../common/Separate"; +import useActionFeedback, { + ActionFeedback, +} from "../common/use-action-feedback"; +import { WebUSBError } from "../device"; +import { BoardId } from "../device/board-id"; +import { useConnectionStatus, useDevice } from "../device/device-hooks"; +import { useFileSystem } from "../fs/fs-hooks"; +import CollapsableButton, { CollapsableButtonProps } from "./CollapsableButton"; + +class HexGenerationError extends Error {} + +/** + * Flash button. + */ +const FlashButton = ( + props: Omit +) => { + const fs = useFileSystem(); + const actionFeedback = useActionFeedback(); + const device = useDevice(); + const connected = useConnectionStatus(); + const [progress, setProgress] = useState(); + + const handleFlash = useCallback(async () => { + const dataSource = async (boardId: BoardId) => { + try { + return await fs.toHexForFlash(boardId); + } catch (e) { + throw new HexGenerationError(e.message); + } + }; + + try { + await device.flash(dataSource, { partial: true, progress: setProgress }); + } catch (e) { + if (e instanceof HexGenerationError) { + actionFeedback.expectedError({ + title: "Failed to build the hex file", + description: e.message, + }); + } else { + handleWebUSBError(actionFeedback, e); + } + } + }, [fs, device, actionFeedback]); + const text = + typeof progress === "undefined" + ? "Flash" + : `Flashing… (${(progress * 100).toFixed(0)}%)`; + return ( + } + onClick={handleFlash} + text={text} + /> + ); +}; + +const handleWebUSBError = (actionFeedback: ActionFeedback, e: any) => { + if (e instanceof WebUSBError) { + actionFeedback.expectedError({ + title: e.title, + description: ( +
}> + {[e.message, e.description].filter(Boolean)} +
+ ), + }); + } else { + actionFeedback.unexpectedError(e); + } +}; + +export default FlashButton; diff --git a/src/workbench/LeftPanel.tsx b/src/workbench/LeftPanel.tsx index 3348b7e93..dafc34ab8 100644 --- a/src/workbench/LeftPanel.tsx +++ b/src/workbench/LeftPanel.tsx @@ -79,9 +79,6 @@ interface LeftPanelConentsProps { const LeftPanelContents = ({ panes }: LeftPanelConentsProps) => { return ( -
- -
{panes.map((p) => ( @@ -100,7 +97,6 @@ const LeftPanelContents = ({ panes }: LeftPanelConentsProps) => { ))} -
); }; diff --git a/src/workbench/LeftPanelTabContent.tsx b/src/workbench/LeftPanelTabContent.tsx index 9151deafa..53af91aff 100644 --- a/src/workbench/LeftPanelTabContent.tsx +++ b/src/workbench/LeftPanelTabContent.tsx @@ -8,7 +8,7 @@ interface LeftPanelTabContentProps { const LeftPanelTabContent = ({ title, children }: LeftPanelTabContentProps) => { return ( - + {title} diff --git a/src/workbench/ProjectNameEditable.tsx b/src/workbench/ProjectNameEditable.tsx index 7ea5f442f..0f247b134 100644 --- a/src/workbench/ProjectNameEditable.tsx +++ b/src/workbench/ProjectNameEditable.tsx @@ -44,7 +44,6 @@ const ProjectNameEditable = () => { defaultValue={"Name your project"} whiteSpace="nowrap" onChange={handleChange} - justifyContent="space-between" > {(props) => ( <> diff --git a/src/workbench/Serial.tsx b/src/workbench/Serial.tsx new file mode 100644 index 000000000..a28e512da --- /dev/null +++ b/src/workbench/Serial.tsx @@ -0,0 +1,24 @@ +import { Flex, HStack, VStack } from "@chakra-ui/react"; +import React from "react"; +import Placeholder from "../common/Placeholder"; +import DeviceConnection from "./DeviceConnection"; +import ProjectNameEditable from "./ProjectNameEditable"; + +const Serial = () => { + return ( + + + + + + + + ); +}; + +export default Serial; diff --git a/src/workbench/Workbench.tsx b/src/workbench/Workbench.tsx index d1eb4b573..9dbd7422f 100644 --- a/src/workbench/Workbench.tsx +++ b/src/workbench/Workbench.tsx @@ -1,5 +1,6 @@ import React, { useState } from "react"; import { + Bottom, BottomResizable, Fill, LeftResizable, @@ -13,6 +14,7 @@ import EditorContainer from "../editor/EditorContainer"; import { MAIN_FILE } from "../fs/fs"; import Header from "./Header"; import LeftPanel from "./LeftPanel"; +import Serial from "./Serial"; import Simulator from "./Simulator"; const Workbench = () => { @@ -30,22 +32,27 @@ const Workbench = () => {
- + + + + + + - - + + - - -
); From db395ddbbe251f66a0c7c8fb759819bf6ab95cd4 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Thu, 4 Mar 2021 13:25:01 +0000 Subject: [PATCH 5/7] Not needed in this layout. --- src/workbench/Files.tsx | 6 ------ src/workbench/Serial.tsx | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/workbench/Files.tsx b/src/workbench/Files.tsx index 249c38c64..5e99e1190 100644 --- a/src/workbench/Files.tsx +++ b/src/workbench/Files.tsx @@ -31,13 +31,7 @@ const Files = ({ onSelectedFileChanged }: FilesProps) => { } return ( - - - - - File list - {fs.files.map((f) => ( diff --git a/src/workbench/Serial.tsx b/src/workbench/Serial.tsx index a28e512da..11532feb9 100644 --- a/src/workbench/Serial.tsx +++ b/src/workbench/Serial.tsx @@ -7,7 +7,7 @@ import ProjectNameEditable from "./ProjectNameEditable"; const Serial = () => { return ( - + From d14f15d4fd4156fac60d8c4fa1cb49f59550dcab Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Thu, 4 Mar 2021 13:47:29 +0000 Subject: [PATCH 6/7] Fix enablement bug. --- src/workbench/DeviceConnection.tsx | 10 ++++++---- src/workbench/FlashButton.tsx | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/workbench/DeviceConnection.tsx b/src/workbench/DeviceConnection.tsx index e4f631dc4..d8b0542e0 100644 --- a/src/workbench/DeviceConnection.tsx +++ b/src/workbench/DeviceConnection.tsx @@ -50,10 +50,12 @@ const DeviceConnection = () => { ) : null} - + {supported && ( + + )} (); const handleFlash = useCallback(async () => { From a59d1cbce6ccc70dd8280f0c421eb5814a0a6750 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Thu, 4 Mar 2021 15:11:06 +0000 Subject: [PATCH 7/7] Make this look worse by adding branding :) --- src/workbench/LeftPanel.tsx | 12 ++++++++++++ src/workbench/python-icon.png | Bin 0 -> 3994 bytes 2 files changed, 12 insertions(+) create mode 100644 src/workbench/python-icon.png diff --git a/src/workbench/LeftPanel.tsx b/src/workbench/LeftPanel.tsx index dafc34ab8..c410efabb 100644 --- a/src/workbench/LeftPanel.tsx +++ b/src/workbench/LeftPanel.tsx @@ -2,6 +2,7 @@ import { Center, Flex, Icon, + Image, Tab, TabList, TabPanel, @@ -23,6 +24,7 @@ import LeftPanelTabContent from "./LeftPanelTabContent"; import Logo from "./Logo"; import Packages from "./Packages"; import Settings from "./Settings"; +import pythonLogo from "./python-icon.png"; interface LeftPanelProps { onSelectedFileChanged: (filename: string) => void; @@ -79,6 +81,16 @@ interface LeftPanelConentsProps { const LeftPanelContents = ({ panes }: LeftPanelConentsProps) => { return ( + + + Python logo + {panes.map((p) => ( diff --git a/src/workbench/python-icon.png b/src/workbench/python-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3c69cc4978b56f7f1a5a612c8cec5af4c02cd117 GIT binary patch literal 3994 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 A&j0`b literal 0 HcmV?d00001