Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement new connect popup #117

Merged
merged 6 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"devDependencies": {
"@biomejs/biome": "^1.7.2",
"@leaphy-robotics/playwright-arduino": "^1.0.4",
"@leaphy-robotics/playwright-arduino": "1.0.5",
"@playwright/test": "^1.43.1",
"@sentry/vite-plugin": "^2.16.1",
"@sveltejs/vite-plugin-svelte": "^3.0.2",
Expand All @@ -21,7 +21,7 @@
"@types/node": "^20.11.30",
"@types/w3c-web-serial": "^1.0.6",
"@types/wicg-file-system-access": "^2023.10.5",
"svelte": "5.0.0-next.121",
"svelte": "5.0.0-next.134",
"svelte-check": "3.7.1",
"tslib": "^2.6.2",
"typescript": "^5.2.2",
Expand All @@ -32,7 +32,8 @@
"@blockly/field-bitmap": "^4.0.16",
"@blockly/workspace-backpack": "^5.3.7",
"@floating-ui/dom": "^1.6.3",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/free-brands-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "6.6.0",
"@leaphy-robotics/avrdude-webassembly": "^1.6.1",
"@leaphy-robotics/dfu-util-wasm": "^1.0.2",
"@leaphy-robotics/leaphy-blocks": "3.2.1",
Expand Down
3 changes: 2 additions & 1 deletion src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ body[data-color-scheme="light"] {
--accent: #32a5a9;
--on-accent: #fff;
--text-muted: #d3d3d3;
--warning: #ffb818;
--warning: #ffcc00;
}
body[data-color-scheme="dark"] {
--background: #24242b;
Expand All @@ -42,6 +42,7 @@ body[data-color-scheme="dark"] {
--accent: #32a5a9;
--on-accent: #fff;
--text-muted: #535361;
--warning: #ffcc00;
}

body {
Expand Down
14 changes: 14 additions & 0 deletions src/assets/default-program.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"blocks": {
"languageVersion": 0,
"blocks": [
{
"type": "leaphy_start",
"id": "rzE0Ve:6bHB~8aIqyj-U",
"deletable": false,
"x": 500,
"y": 10
}
]
}
}
8 changes: 7 additions & 1 deletion src/assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,11 @@
"EXPLAIN_BLOCK": "Explain Block ✨",
"META_ATTRIBUTION": "Built with Meta Llama 3",
"AI_RATE_LIMITED": "The explanation robot is a little too busy right now, please try again later.",
"CHOOSING_ROBOT": "Choose your board"
"CHOOSING_ROBOT": "Choose your board",
"INVALID_ROBOT": "The selected robot {robot} does not work with the automatically detected {board}!",
"INCOMPATIBLE_PROJECT": "Incompatible",
"CONTINUE": "Continue",
"UNKNOWN_BOARD": "Unknown",
"CLEAR_PROJECT": "Clear project",
"CLEAR_PROJECT_DESC": "Selecting this robot will clear your project, are you sure?"
}
8 changes: 7 additions & 1 deletion src/assets/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,11 @@
"EXPLAIN_BLOCK": "Leg blok uit ✨",
"META_ATTRIBUTION": "Gemaakt met Meta Llama 3",
"AI_RATE_LIMITED": "De uitleg robot is op dit moment erg druk, probeer het later nog eens.",
"CHOOSING_ROBOT": "Kies je arduino"
"CHOOSING_ROBOT": "Kies je arduino",
"INVALID_ROBOT": "De geselecteerde robot {robot} werkt niet met de automatisch gedetecteerde {board}!",
"INCOMPATIBLE_PROJECT": "Ongeschikt",
"CONTINUE": "Ga door",
"UNKNOWN_BOARD": "Onbekend",
"CLEAR_PROJECT": "Wis project",
"CLEAR_PROJECT_DESC": "Door deze robot te selecteren wis je je project, weet je het zeker?"
}
22 changes: 9 additions & 13 deletions src/lib/components/core/header/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { _, locale } from "svelte-i18n";

import block from "$assets/block.svg";
import leaphyLogo from "$assets/leaphy-logo.svg";
import Connect from "$components/core/popups/popups/Connect.svelte";
import Button from "$components/ui/Button.svelte";
import ContextItem from "$components/ui/ContextItem.svelte";
import Select from "$components/ui/Select.svelte";
import { loadWorkspaceFromString } from "$domain/blockly/blockly";
import { FileHandle } from "$domain/handles";
import { robots } from "$domain/robots";
import { getSelector, robots } from "$domain/robots";
import { Screen, Theme, screen, theme } from "$state/app.svelte";
import {
audio,
Expand Down Expand Up @@ -77,9 +78,13 @@ async function upload() {
}

async function connect() {
try {
await port.connect(Prompt.ALWAYS);
} catch {}
if (getSelector($robot))
popups.open({
component: Connect,
data: {},
allowInteraction: false,
});
else port.connect(Prompt.ALWAYS);
}

async function newProject() {
Expand Down Expand Up @@ -393,15 +398,6 @@ function runPython() {
<div class="header">
<div class="comp">
<img class="logo" src={leaphyLogo} alt="Leaphy" />
{#if $screen === Screen.WORKSPACE && $mode === Mode.ADVANCED}
<Select
options={Object.values(robots).map((device) => [
device.name,
device,
])}
bind:value={$robot}
/>
{/if}
{#if $screen === Screen.WORKSPACE}
<Button
name={$_("PROJECT")}
Expand Down
110 changes: 110 additions & 0 deletions src/lib/components/core/popups/popups/Connect.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<script lang="ts">
import defaultProgram from "$assets/default-program.json?raw";
import Warning from "$components/core/popups/popups/Warning.svelte";
import Button from "$components/ui/Button.svelte";
import ChipSelect from "$components/ui/ChipSelect.svelte";
import ListSelect from "$components/ui/ListSelect.svelte";
import { isCompatible } from "$domain/blockly/blockly";
import { type RobotDevice, type Selector, getSelector } from "$domain/robots";
import { workspace } from "$state/blockly.svelte";
import { type PopupState, popups } from "$state/popup.svelte";
import { Mode, Prompt, handle, mode, robot } from "$state/workspace.svelte";
import { port } from "$state/workspace.svelte";
import { faUsb } from "@fortawesome/free-brands-svg-icons";
import type { WorkspaceSvg } from "blockly";
import * as Blockly from "blockly";
import { getContext } from "svelte";
import { _ } from "svelte-i18n";
import { type Writable, get } from "svelte/store";

interface Props {
connectOverride: boolean;
}

const { connectOverride }: Props = $props();
const { board } = port;

const categories = getSelector($robot) as Selector[];
const categoriesFilter = $derived(
categories.map((cat) => [cat.name, cat] as [string, Selector]),
);
let category = $state(
categories.find((cat) =>
cat.robots.find((robot) => $state.is(robot, $robot)),
),
);

const values = $derived(
category.robots.map((robot) => [robot.name, robot] as [string, RobotDevice]),
);

const popupState = getContext<Writable<PopupState>>("state");
function start() {
window._paq.push(["trackEvent", "SelectRobot", $robot.name]);
popups.close($popupState.id);
}

board.subscribe((board) => {
if (!connectOverride || !board) return;

const robotDevice = get(robot);
const robotType = getSelector(robotDevice)
.find((category) =>
category.robots.find((robot) => $state.is(robot, robotDevice)),
)
.robots.find((robot) => robot.board === board.board);

if (robotType) robot.set(robotType);
});

const warning = $derived(
$board && $robot && $board.board !== $robot.board
? $_("INVALID_ROBOT", {
values: { robot: $robot.name, board: $board.name },
})
: undefined,
);

function checkEnabled(robot: RobotDevice): boolean {
if ($mode !== Mode.BLOCKS) return true;

return $workspace ? isCompatible($workspace as WorkspaceSvg, robot) : true;
}

async function disabledSelect() {
const value = await popups.open({
component: Warning,
data: {
title: "CLEAR_PROJECT",
message: "CLEAR_PROJECT_DESC",
showCancel: true,
},
allowInteraction: false,
});
if (!value) return false;

Blockly.serialization.workspaces.load(JSON.parse(defaultProgram), $workspace);
handle.set(undefined);
return true;
}
</script>

<div class="content">
<Button onclick="{() => port.connect(Prompt.ALWAYS)}" mode="secondary" icon="{faUsb}" name={$port ? $board?.name || $_("UNKNOWN_BOARD") : $_("NOT_CONNECTED")} bold="{!!$port}" large />
{#if categories.length > 1}
<ChipSelect options="{categoriesFilter}" bind:value={category} />
{/if}
<ListSelect {warning} options="{values}" {checkEnabled} disabledText={$_("INCOMPATIBLE_PROJECT")} {disabledSelect} bind:value={$robot} />
<Button onclick="{start}" mode="primary" name={$_("CONTINUE")} center bold />
</div>

<style>
.content {
padding: 20px;
display: flex;
flex-direction: column;
min-width: 400px;
text-align: center;
gap: 15px;
}
</style>
21 changes: 3 additions & 18 deletions src/lib/components/start/RobotSelector.svelte
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
<script lang="ts">
import type { Robot, RobotListing } from "$domain/robots";
import type { Robot } from "$domain/robots";

interface Props {
robots: Robot[][];
secondary: boolean;
onselect: (robot: Robot) => void;
selected?: RobotListing;
compact?: boolean;
}

const {
robots,
secondary,
onselect,
selected,
compact = false,
}: Props = $props();
const { robots, onselect, compact = false }: Props = $props();
</script>

<div class="selector" class:secondary class:compact>
<div class="selector" class:compact>
{#each robots as row}
<div class="row">
{#each row as robot}
<button
class="robot"
onclick={() => onselect(robot)}
class:selected={selected?.id === robot.id}
>
<span class="icon">
<img class="image" src={robot.icon} alt={robot.name}/>
Expand All @@ -52,10 +43,6 @@ const {
width: unset;
}

.secondary {
background: var(--background);
}

.row {
display: flex;
justify-content: center;
Expand All @@ -74,7 +61,6 @@ const {
color: var(--on-background);
}

.robot.selected,
.robot:hover {
scale: 1.03;
}
Expand All @@ -95,7 +81,6 @@ const {
margin-bottom: 1vh;
}

.robot.selected .icon,
.robot:hover .icon {
border: 3px solid var(--primary) !important;
}
Expand Down
Loading