8000 feat: unified title bar (v2) by greatgitsby · Pull Request #577 · commaai/new-connect · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: unified title bar (v2) #577

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

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft
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
27 changes: 12 additions & 15 deletions src/components/material/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createContext, createSignal, Show, useContext } from 'solid-js'
import { createContext, createEffect, createSignal, useContext } from 'solid-js'
import type { Accessor, JSXElement, ParentComponent, Setter, VoidComponent } from 'solid-js'

import IconButton from '~/components/material/IconButton'
Expand All @@ -19,12 +19,8 @@ export function useDrawerContext() {
}

export const DrawerToggleButton: VoidComponent = () => {
const { modal, setOpen } = useDrawerContext()
return (
<Show when={modal()}>
<IconButton name="menu" => setOpen((prev) => !prev)} />
</Show>
)
const { setOpen } = useDrawerContext()
return <IconButton name="menu" => setOpen((prev) => !prev)} />
}

const PEEK = 56
Expand All @@ -39,34 +35,35 @@ const Drawer: ParentComponent<DrawerProps> = (props) => {
const modal = () => dimensions().width < 1280
const contentWidth = () => `calc(100% - ${modal() ? 0 : drawerWidth()}px)`

createEffect(() => {
if (!modal() && open()) setOpen(false)
})

const [open, setOpen] = createSignal(false)
const drawerVisible = () => !modal() || open()

return (
<DrawerContext.Provider value={{ modal, open, setOpen }}>
<nav
class="hide-scrollbar fixed inset-y-0 left-0 h-full touch-pan-y overflow-y-auto overscroll-y-contain transition-drawer ease-in-out duration-300"
class={'fixed hide-scrollbar inset-y-0 z-10 transition-drawer ease-in-out duration-300'}
style={{
left: drawerVisible() ? 0 : `${-PEEK}px`,
opacity: drawerVisible() ? 1 : 0.5,
left: drawerVisible() ? 0 : `${-drawerWidth()}px`,
width: `${drawerWidth()}px`,
}}
>
<div class="flex size-full flex-col rounded-r-lg bg-surface-container-low text-on-surface-variant sm:rounded-r-none">
{props.drawer}
</div>
<div class="flex size-full flex-col bg-surface-container text-on-surface-variant sm:rounded-r-none">{props.drawer}</div>
</nav>

<main
class="absolute inset-y-0 overflow-y-auto bg-background transition-drawer ease-in-out duration-300"
style={{
left: drawerVisible() ? `${drawerWidth()}px` : 0,
left: !modal() ? `${drawerWidth()}px` : 0,
width: contentWidth(),
}}
>
{props.children}
<div
class="absolute inset-0 z-[9999] bg-background transition-drawer ease-in-out duration-300"
class="absolute inset-0 bg-background transition-drawer ease-in-out duration-300"
style={{
'pointer-events': modal() && open() ? 'auto' : 'none',
opacity: modal() && open() ? 0.5 : 0,
Expand Down
2 changes: 1 addition & 1 deletion src/components/material/TopAppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type TopAppBarProps = {

const TopAppBar: ParentComponent<TopAppBarProps> = (props) => {
return (
<header class={clsx('inset-x-0 top-0 flex h-16 items-center gap-4 px-4 py-5 text-on-surface', props.class)}>
<header class={clsx('flex gap-4 items-center', props.class)}>
{props.leading}
<Dynamic class="grow truncate text-title-lg" component={props.component || 'h1'}>
{props.children}
Expand Down
48 changes: 21 additions & 27 deletions src/pages/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createMemo, createResource, ErrorBoundary, lazy, Match, Show, Suspense, Switch } from 'solid-js'
import { createMemo, createResource, ErrorBoundary, lazy, Match, Suspense, Switch } from 'solid-js'
import type { Component, JSXElement, VoidComponent } from 'solid-js'
import { Navigate, type RouteSectionProps, useLocation } from '@solidjs/router'
import clsx from 'clsx'
Expand Down Expand Up @@ -26,24 +26,15 @@ import BuildInfo from '~/components/BuildInfo'
const PairActivity = lazy(() => import('./activities/PairActivity'))

const DashboardDrawer: VoidComponent<{ devices: Device[] | undefined }> = (props) => {
const { modal, setOpen } = useDrawerContext()
const { setOpen } = useDrawerContext()
const => setOpen(false)

const [profile] = createResource(getProfile)

return (
<>
<TopAppBar
component="h2"
leading={
<Show when={modal()}>
<IconButton name="arrow_back" />
</Show>
}
>
Devices
</TopAppBar>
<DeviceList class="overflow-y-auto p-2" devices={props.devices} />
<AppHeader />
<DeviceList class="overflow-y-auto p-4" devices={props.devices} />
<div class="grow" />
<Button class="m-4" leading={<Icon name="add" />} href="/pair" >
Add new device
Expand Down Expand Up @@ -71,42 +62,45 @@ const DashboardDrawer: VoidComponent<{ devices: Device[] | undefined }> = (props
)
}

const AppHeader: VoidComponent<{ class?: string; leading?: JSXElement }> = (props) => {
return (
<TopAppBar
component="h2"
class={clsx('text-white p-4 bg-surface-container-highest border-b-2 border-b-outline-variant h-[4rem]', props.class)}
leading={props.leading || <img src="/images/comma-white.svg" height="32" width="32" />}
>
connect
</TopAppBar>
)
}

const DashboardLayout: Component<{
paneOne: JSXElement
paneTwo: JSXElement
paneTwoContent: boolean
}> = (props) => {
return (
<div class="relative size-full overflow-hidden">
<AppHeader class="fixed top-0 inset-x-0 left-0 right-0" leading={<DrawerToggleButton />} />
<div
class={clsx(
'mx-auto size-full max-w-[1600px] md:grid md:grid-cols-2 lg:gap-2',
'mt-16 mx-auto size-full max-w-[1600px] md:grid md:grid-cols-2 lg:gap-2',
// Flex layout for mobile with horizontal transition
'flex transition-transform duration-300 ease-in-out',
props.paneTwoContent ? '-translate-x-full md:translate-x-0' : 'translate-x-0',
)}
>
<div class="min-w-full overflow-y-scroll">{props.paneOne}</div>
<div class="min-w-full overflow-y-scroll">{props.paneTwo}</div>
<div class="pt-4 min-w-full overflow-y-scroll">{props.paneOne}</div>
<div class="pt-4 min-w-full overflow-y-scroll">{props.paneTwo}</div>
</div>
</div>
)
}

const FirstPairActivity: Component = () => {
const { modal } = useDrawerContext()
return (
<>
<TopAppBar
class="font-bold"
leading={
<Show when={!modal()} fallback={<DrawerToggleButton />}>
<img alt="" src="/images/comma-white.png" class="h-8" />
</Show>
}
>
connect
</TopAppBar>
<AppHeader class="fixed top-0 inset-x-0 left-0 right-0" />
<section class="flex flex-col gap-4 py-2 items-center mx-auto max-w-md px-4 mt-4 sm:mt-8 md:mt-16">
<h2 class="text-xl">Pair your device</h2>
<p class="text-lg">Scan the QR code on your device</p>
Expand Down
14 changes: 0 additions & 14 deletions src/pages/dashboard/activities/DeviceActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import clsx from 'clsx'

import { takeSnapshot } from '~/api/athena'
import { getDevice, SHARED_DEVICE } from '~/api/devices'
import { DrawerToggleButton, useDrawerContext } from '~/components/material/Drawer'
import Icon from '~/components/material/Icon'
import IconButton from '~/components/material/IconButton'
import TopAppBar from '~/components/material/TopAppBar'
import DeviceLocation from '~/components/DeviceLocation'
import DeviceStatistics from '~/components/DeviceStatistics'
import UploadQueue from '~/components/UploadQueue'
Expand Down Expand Up @@ -74,20 +72,8 @@ const DeviceActivity: VoidComponent<DeviceActivityProps> = (props) => {

const clearError = () => setSnapshot('error', null)

const { modal } = useDrawerContext()

return (
<>
<TopAppBar
class="font-bold"
leading={
<Show when={!modal()} fallback={<DrawerToggleButton />}>
<img alt="" src="/images/comma-white.png" class="h-8" />
</Show>
}
>
connect
</TopAppBar>
<div class="flex flex-col gap-4 px-4 pb-4">
<div class="h-min overflow-hidden rounded-lg bg-surface-container-low">
<Suspense fallback={<div class="h-[240px] skeleton-loader size-full" />}>
Expand Down
6 changes: 4 additions & 2 deletions src/pages/dashboard/activities/PairActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const PairActivity: VoidComponent<{ onPaired: () => void }> = (props) => {

return (
<>
<TopAppBar>Add new device</TopAppBar>
<TopAppBar class="m-8">Add new device</TopAppBar>

<div class="flex flex-col items-center gap-4">
<Icon name="autorenew" class="animate-spin" size="40" />
Expand All @@ -106,7 +106,9 @@ const PairActivity: VoidComponent<{ onPaired: () => void }> = (props) => {
error(input, to) {
return (
<>
<TopAppBar trailing={<IconButton name="close" href="/" />}>Add new device</TopAppBar>
<TopAppBar class="m-8" trailing={<IconButton name="close" href="/" />}>
Add new device
</TopAppBar>

<div class="flex flex-col items-center gap-4 px-4 max-w-sm mx-auto">
An error occurred: {input.error.message}
Expand Down
6 changes: 5 additions & 1 deletion src/pages/dashboard/activities/RouteActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ const RouteActivity: VoidComponent<RouteActivityProps> = (props) => {

return (
<>
<TopAppBar component="h2" leading={<IconButton class="md:hidden" name="arrow_back" href={`/${props.dongleId}`} />}>
<TopAppBar
class="mx-4 mb-4 h-[28px]"
component="h2"
leading={<IconButton class="md:hidden" name="arrow_back" href={`/${props.dongleId}`} />}
>
<Suspense fallback={<div class="skeleton-loader max-w-64 rounded-xs h-[28px]" />}>{startTime()}</Suspense>
</TopAppBar>

Expand Down
2 changes: 1 addition & 1 deletion src/pages/dashboard/activities/SettingsActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ const SettingsActivity: VoidComponent<PrimeActivityProps> = (props) => {
})
return (
<>
<TopAppBar component="h2" leading={<IconButton class="md:hidden" name="arrow_back" href={`/${props.dongleId}`} />}>
<TopAppBar class="mx-4 mb-4" component="h2" leading={<IconButton class="md:hidden" name="arrow_back" href={`/${props.dongleId}`} />}>
Device Settings
</TopAppBar>
<div class="flex flex-col gap-4 max-w-lg px-4">
Expand Down
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default defineConfig({
short_name: 'connect',
description: 'manage your openpilot experience',
background_color: '#131318',
theme_color: '#131318',
theme_color: '#34343a',
start_url: '/',
id: '/',
},
Expand Down
0