Skip to content

Commit

Permalink
Merge pull request #6 from whaaaley/next
Browse files Browse the repository at this point in the history
Next
  • Loading branch information
whaaaley authored Dec 21, 2024
2 parents d76483e + 6305e18 commit 71535b7
Show file tree
Hide file tree
Showing 48 changed files with 522 additions and 294 deletions.
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "module",
"scripts": {
"build": "vite build",
"build-watch": "vite build --watch",
"build-watch": "env BUILD_ENV=local vite build --watch",
"dev": "vite"
},
"dependencies": {
Expand Down
12 changes: 12 additions & 0 deletions client/shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_20
];

shellHook = ''
echo "🚀 Starting whaleybar client..."
npm run dev
'';
}
9 changes: 7 additions & 2 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@ const Zebar = defineComponent({
})

return () => (
<div class='flex h-screen items-center gap-4 px-6'>
<div class='flex h-screen items-center gap-4 bg-gradient-to-b from-transparent to-black/50 px-6'>
<TimeDate/>
<WeatherLocation location='Des Moines, Iowa'/>
<WeatherLocation
includeTime
label='Haywards Heath, UK'
location='RH16'
timezone='Europe/London'
/>
<MonitorGrid monitors={allMonitors.value}/>
<WorkspaceGrid workspaces={monitorWorkspaces.value}/>
</div>
Expand All @@ -77,7 +83,6 @@ const routes = [{
setup () {
return () => (
<div class='h-screen overflow-auto bg-black text-white'>
<Zebar/>
<LiveLogs/>
</div>
)
Expand Down
3 changes: 0 additions & 3 deletions client/src/components/LiveLogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ const statusVariants = cva([
fatal: 'bg-fuchsia-600',
},
},
compoundVariants: [
// {}
],
defaultVariants: {
level: 'info',
},
Expand Down
3 changes: 2 additions & 1 deletion client/src/components/TimeDate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export default defineComponent({
name: 'TimeDate',
setup () {
const { monthlyAppleEmojiUrl } = useEmoji()
const now = useNow()

const now = useNow({ interval: 1000 })

const timeFormat = useDateFormat(now, 'h:mm')
const dateFormat = useDateFormat(now, 'MM/DD/YYYY')
Expand Down
47 changes: 43 additions & 4 deletions client/src/components/WeatherLocation.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
import { useQuery } from '@tanstack/vue-query'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { useNow } from '@vueuse/core'
import { computed, defineComponent, onMounted } from 'vue'
import { useEmoji } from '~/hooks/useEmoji'
import { weatherQueries } from '~/io/queries/index'
import { getWeatherEmoji } from '~/utils/getWeatherEmoji'
import { getWeatherEmoji } from '~/utils/emoji.utils'

export default defineComponent({
name: 'WeatherLocation',
props: {
includeTime: {
type: Boolean,
default: false,
},
location: {
type: String,
default: 'Des Moines, Iowa',
},
label: {
type: [String, null],
default: null,
},
timezone: {
type: String,
default: 'America/Chicago',
},
},
setup (props) {
const { getEmoji } = useEmoji()
const queryClient = useQueryClient()

const now = useNow({ interval: 1000 })

const timezoneNow = computed(() => {
const date = now.value

return date.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: '2-digit',
timeZone: props.timezone,
})
})

const {
data: weather,
Expand All @@ -31,6 +57,7 @@ export default defineComponent({
})

const isLoading = computed(() => isLoadingWeather.value)
const labelValue = computed(() => isLoading.value ? '' : (props.label ?? props.location))

const emojiUrl = computed(() => {
if (!weather.value) return
Expand All @@ -48,6 +75,12 @@ export default defineComponent({

onMounted(async () => {
await refetchWeather()

// 3600000 ms = 1 hour
setInterval(async () => {
queryClient.resetQueries({ queryKey: [props.location] })
await refetchWeather()
}, 3600000)
})

return () => (
Expand All @@ -63,12 +96,18 @@ export default defineComponent({
)}
<div class='grid text-xs'>
{weather.value && (
<div>{weather.value.temp}°F {weather.value.condition}</div>
<div>
<span>{weather.value.temp}°F {weather.value.condition}</span>
{props.includeTime && (
// <span> ({timezoneNow.value})</span>
<span> / {timezoneNow.value}</span>
)}
</div>
)}
{weatherError.value && (
<div>{weatherError.value.message}</div>
)}
<div>{props.location}</div>
<div>{labelValue.value}</div>
</div>
</div>
)
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { z } from 'zod'
// import { withGet } from '~/io/chains/fetchPipeline'
import { makeRequest } from '~/io/streams/ajaxStreams'
import { makeRequest } from '~/io/streams/fetch.streams'

type GetWeatherEmojiParams = {
weatherCondition: string
Expand All @@ -14,8 +13,6 @@ const WeatherEmojiResponseSchema = z.object({

type WeatherEmojiResponse = z.infer<typeof WeatherEmojiResponseSchema>

// Todo: add middleware to swap out the URL based on the environment

// Type casting with 'as Promise<WeatherEmojiResponse>' is safe here because:
// 1. The Zod schema (WeatherEmojiResponseSchema) validates the data at runtime
// 2. If the API returns invalid data, Zod's parse() will throw regardless of the type cast
Expand Down
6 changes: 2 additions & 4 deletions client/src/io/queries/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
export { emojiQueries } from './emojiQueries'
export { weatherQueries } from './weatherQueries'
export * as logStreamQueries from './logStreamQueries'
export * from './weatherQueries'
export * as logStreamQueries from './logStream.queries'
export * as weatherQueries from './weather.queries'
51 changes: 51 additions & 0 deletions client/src/io/queries/logStream.queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { type LogRequestSchema, logResponseSchema, messageSchema } from '$models/logStream.model'
import { makeRequest } from '~/io/streams/fetch.streams'
import { connect, disconnect } from '~/io/streams/sse.streams'

export type LogResponseSchema = z.infer<typeof logResponseSchema>
export type MessageSchema = z.infer<typeof messageSchema>

type NextFn = (data: unknown) => void

let lastNext: NextFn | undefined

export const connectLogs = async (next: NextFn) => {
lastNext = next

const data = await connect({
url: '/stream/logs',
messageSchema,
next,
error: (err) => { throw err },
})

return [data] as Promise<MessageSchema>[]
}

export const disconnectLogs = () => {
disconnect({ url: '/stream/logs' })
}

export const reconnectLogs = async (next?: NextFn) => {
disconnectLogs()

if (!next && !lastNext) {
throw new Error('Next function is not defined')
}

return connectLogs(next ?? lastNext!)
}

export const sendLog = async (params: LogRequestSchema) => {
const data = await makeRequest({
method: 'POST',
url: '/api/log',
responseSchema: logResponseSchema,
body: JSON.stringify(params),
headers: {
'Content-Type': 'application/json',
},
})

return data as Promise<LogResponseSchema>
}
64 changes: 0 additions & 64 deletions client/src/io/queries/logStreamQueries.ts

This file was deleted.

20 changes: 20 additions & 0 deletions client/src/io/queries/weather.queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { type WeatherRequest, type WeatherResponse, weatherResponseSchema } from '$models/weather.model'
import { makeRequest } from '~/io/streams/fetch.streams'

// Type casting with 'as Promise<WeatherResponse>' is safe here because:
// 1. The Zod schema (WeatherResponseSchema) validates the data at runtime
// 2. If the API returns invalid data, Zod's parse() will throw regardless of the type cast
// 3. The cast just helps TypeScript understand the shape of the data after Zod validates it
export const getWeather = async (params: WeatherRequest) => {
const data = await makeRequest({
method: 'GET',
url: '/api/weather',
queryString: params,
responseSchema: weatherResponseSchema,
headers: {
'Cache-Control': 'public, max-age=3600, immutable',
},
})

return data as Promise<WeatherResponse>
}
35 changes: 0 additions & 35 deletions client/src/io/queries/weatherQueries.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { lastValueFrom, map, of, pipe, switchMap } from 'rxjs'
import { fromFetch } from 'rxjs/fetch'
import { type ZodSchema } from 'zod'
import { http, marshal, prefixUrl, unmarshal, zod } from '~/io/operators/requestOperators'
import { http, marshal, prefixUrl, unmarshal, zod } from '~/io/operators/request.operators'

type RequestConfig = RequestInit & {
url: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fromEvent, lastValueFrom, map, of, pipe, switchMap, tap } from 'rxjs'
import { type ZodSchema } from 'zod'
import { prefixUrl } from '~/io/operators/requestOperators'
import { logging, unmarshal, zod } from '~/io/operators/streamOperators'
import { prefixUrl } from '~/io/operators/request.operators'
import { logging, unmarshal, zod } from '~/io/operators/stream.operators'

type ConnectConfig = {
url: string
Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
import { defineConfig } from 'vite'
import { viteSingleFile } from 'vite-plugin-singlefile'

const outDir = process.env.NODE_ENV === 'development'
const outDir = process.env.BUILD_ENV === 'local'
? '/mnt/c/Users/dustin/.glzr/zebar/whaleybar-build'
: undefined

Expand All @@ -21,6 +21,8 @@ export default defineConfig({
resolve: {
alias: {
'~': fileURLToPath(new URL('./src', import.meta.url)),
$: fileURLToPath(new URL('..', import.meta.url)),
$models: fileURLToPath(new URL('../server/models', import.meta.url)),
},
},
server: {
Expand Down
Loading

0 comments on commit 71535b7

Please sign in to comment.