Skip to content

Commit

Permalink
Fix hardcoded URL, show items in cart
Browse files Browse the repository at this point in the history
  • Loading branch information
dqbd committed Oct 10, 2023
1 parent 4b54bc8 commit 8a2fa6f
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 71 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -26,6 +26,7 @@
"@emotion/styled": "^11.1.5",
"@material-ui/core": "^5.0.0-alpha.21",
"@material-ui/lab": "^5.0.0-alpha.21",
"@tanstack/react-query": "^4.36.1",
"@use-gesture/react": "^10.2.23",
"chokidar": "^3.5.1",
"cors": "^2.8.5",
Expand Down
3 changes: 2 additions & 1 deletion src/components/Controls/Controls.tsx
Expand Up @@ -6,7 +6,8 @@ import { useStreamStore } from "utils/stream"
import { css } from "@emotion/react"
import { theme } from "utils/theme"
import { ScrobberRange } from "components/Scrobber/ScrobberRange"
import { MutableRefObject } from "react"
import { MutableRefObject, useEffect } from "react"
import { useQuery } from "@tanstack/react-query"

function ControlsHeader(props: {
stream: {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Scrobber/ScrobberShift.utils.ts
Expand Up @@ -3,7 +3,7 @@ import { useEffect, useLayoutEffect, useState } from "react"
async function getServerTimeDiff() {
const clientStart = Date.now(),
timeBefore = performance.now()
const serverReq = await fetch("http://192.168.2.152:3000/api/time")
const serverReq = await fetch("/api/time")
const timeAfter = performance.now()

const roundTripTime = timeAfter - timeBefore
Expand Down
123 changes: 64 additions & 59 deletions src/pages/_app.tsx
Expand Up @@ -12,9 +12,12 @@ import NoSleep from "nosleep.js"

import dayjs from "dayjs"
import minMax from "dayjs/plugin/minMax"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"

dayjs.extend(minMax)

const queryClient = new QueryClient()

export default function App(props: AppProps) {
const { Component, pageProps } = props

Expand All @@ -35,68 +38,70 @@ export default function App(props: AppProps) {
)

return (
<ConfigContext.Provider value={config}>
<SleepContext.Provider value={sleep}>
<StreamContext.Provider value={{ streams }}>
<Head>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<link
rel="mask-icon"
href="/safari-pinned-tab.svg"
color="#1b263e"
/>
<link rel="shortcut icon" href="/favicon.ico" />
<meta name="msapplication-TileColor" content="#1b263e" />
<meta name="msapplication-config" content="/browserconfig.xml" />
<meta name="theme-color" content="#ffffff" />
<QueryClientProvider client={queryClient}>
<ConfigContext.Provider value={config}>
<SleepContext.Provider value={sleep}>
<StreamContext.Provider value={{ streams }}>
<Head>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<link
rel="mask-icon"
href="/safari-pinned-tab.svg"
color="#1b263e"
/>
<link rel="shortcut icon" href="/favicon.ico" />
<meta name="msapplication-TileColor" content="#1b263e" />
<meta name="msapplication-config" content="/browserconfig.xml" />
<meta name="theme-color" content="#ffffff" />

<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>

<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1, maximum-scale=5.0, viewport-fit=cover"
/>
</Head>
<DefaultSeo titleTemplate="%s | Kamera" defaultTitle="Kamera" />
<Global
styles={css`
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
"Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
"Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1, maximum-scale=5.0, viewport-fit=cover"
/>
</Head>
<DefaultSeo titleTemplate="%s | Kamera" defaultTitle="Kamera" />
<Global
styles={css`
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
"Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
"Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
`}
/>
overflow-x: hidden;
}
`}
/>

<Component {...pageProps} />
</StreamContext.Provider>
</SleepContext.Provider>
</ConfigContext.Provider>
<Component {...pageProps} />
</StreamContext.Provider>
</SleepContext.Provider>
</ConfigContext.Provider>
</QueryClientProvider>
)
}
2 changes: 1 addition & 1 deletion src/pages/api/data/[folder]/log/stream.ts
Expand Up @@ -6,7 +6,7 @@ import cors from "cors"

const dbRef = createPersistentDatabase()

const RANGE = 10 * 2 // 20s
const RANGE = 10 * 60 // 20s

export default async function handler(
req: NextApiRequest,
Expand Down
120 changes: 120 additions & 0 deletions src/pages/camera/[cameraKey].tsx
Expand Up @@ -11,13 +11,131 @@ import {
useStreamStore,
useStreamPeriodicRefreshNow,
generateUrl,
fitDateInBounds,
getDateBounds,
} from "utils/stream"
import { NextSeo } from "next-seo"
import Head from "next/head"
import { GetServerSideProps } from "next"
import { loadServerConfig } from "shared/config"
import { theme } from "utils/theme"
import { useVisibleTimer } from "components/Controls/Controls.utils"
import { useQuery } from "@tanstack/react-query"
import { encodeQuery } from "utils/query"
import { z } from "zod"
import { useServerTimeDiff } from "components/Scrobber/ScrobberShift.utils"
import dayjs from "dayjs"

const schema = z.object({
cart: z.object({
items: z.array(
z.object({ name: z.string(), price: z.number(), qty: z.number() })
),
}),
})

function LogStream(props: {
stream: {
key: string
}
}) {
const stream = useStreamStore((state) => state.stream)
const log = useQuery(
[props.stream.key, stream] as const,
async ({ queryKey: [camera, args] }) => {
let url: string

if ("from" in args && "to" in args) {
url = encodeQuery(`/api/data/${camera}/log/stream`, {
from: Math.floor(args.from / 1000),
to: Math.floor(args.to / 1000),
})
} else {
url = encodeQuery(`/api/data/${camera}/log/stream`, {
shift: Math.floor(args.shift / 1000),
})
}

const json: Array<{
json: string
timestamp: number
}> = await fetch(url).then((res) => res.json())

return json
.map(({ json, timestamp }) => ({
timestamp,
data: schema.parse(JSON.parse(json)),
}))
.reverse()
},
{ refetchInterval: 1000 }
)

const serverDiff = useServerTimeDiff()
const now = useStreamStore((state) => state.now)
const playback = useStreamStore((state) => state.playback)

const displayDate = (
"playing" in playback
? now.add(playback.playing, "millisecond")
: playback.paused
).add(serverDiff, "millisecond")

const currentItem = log.data?.find(
({ timestamp }) => dayjs(timestamp).valueOf() <= displayDate.valueOf()
)

return (
<div
css={css`
top: 0;
left: 0;
right: 0;
bottom: 0;
position: fixed;
z-index: 9999;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
pointer-events: none;
`}
>
<div
css={css`
aspect-ratio: 16 / 9;
width: 100%;
`}
>
<div
css={css`
display: flex;
flex-direction: column;
gap: 6px;
font-size: 1.5em;
font-weight: bold;
margin: 16px;
font-family: monospace;
-webkit-text-stroke: 1px black;
`}
>
{currentItem?.data.cart.items.map((item, idx) => {
const name = item.name || "Zboží"
return (
<div key={idx}>
{item.qty} x {name} ... {item.price * item.qty}
</div>
)
})}
</div>
</div>
</div>
)
}

export default function Page() {
useStreamPeriodicRefreshNow()
Expand Down Expand Up @@ -98,6 +216,8 @@ export default function Page() {
}}
/>
)}

{meta && <LogStream stream={meta} />}
</div>
</Fragment>
)
Expand Down
13 changes: 5 additions & 8 deletions src/utils/stream.ts
Expand Up @@ -21,16 +21,13 @@ export type PlaybackType = { playing: number } | { paused: dayjs.Dayjs }

export function generateUrl(name: string, args: StreamType): string | null {
if ("from" in args && "to" in args) {
return encodeQuery(
`http://192.168.2.152:3000/api/data/${name}/slice.m3u8`,
{
from: Math.floor(args.from / 1000),
to: Math.floor(args.to / 1000),
}
)
return encodeQuery(`/api/data/${name}/slice.m3u8`, {
from: Math.floor(args.from / 1000),
to: Math.floor(args.to / 1000),
})
}

return encodeQuery(`http://192.168.2.152:3000/api/data/${name}/stream.m3u8`, {
return encodeQuery(`/api/data/${name}/stream.m3u8`, {
shift: Math.floor(args.shift / 1000),
})
}
Expand Down
15 changes: 14 additions & 1 deletion yarn.lock
Expand Up @@ -954,6 +954,19 @@
dependencies:
"@sinonjs/commons" "^1.7.0"

"@tanstack/query-core@4.36.1":
version "4.36.1"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.36.1.tgz#79f8c1a539d47c83104210be2388813a7af2e524"
integrity sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==

"@tanstack/react-query@^4.36.1":
version "4.36.1"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.36.1.tgz#acb589fab4085060e2e78013164868c9c785e5d2"
integrity sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw==
dependencies:
"@tanstack/query-core" "4.36.1"
use-sync-external-store "^1.2.0"

"@types/babel__core@^7.1.14":
version "7.1.19"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460"
Expand Down Expand Up @@ -4642,7 +4655,7 @@ use-subscription@1.5.1:
dependencies:
object-assign "^4.1.1"

use-sync-external-store@1.2.0:
use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
Expand Down

0 comments on commit 8a2fa6f

Please sign in to comment.