create-rezi 0.1.0-alpha.2 → 0.1.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,176 +0,0 @@
1
- import { createApp, rgb, ui } from "@rezi-ui/core";
2
- import { createNodeBackend } from "@rezi-ui/node";
3
-
4
- type Stream = {
5
- name: string;
6
- category: string;
7
- viewers: number;
8
- bitrate: number;
9
- health: "good" | "warning";
10
- };
11
-
12
- const streams: readonly Stream[] = [
13
- { name: "city-cam-01", category: "Urban", viewers: 1280, bitrate: 6.4, health: "good" },
14
- { name: "forest-node", category: "Nature", viewers: 860, bitrate: 4.8, health: "good" },
15
- { name: "harbor-live", category: "Maritime", viewers: 420, bitrate: 3.9, health: "warning" },
16
- { name: "lab-monitor", category: "Science", viewers: 96, bitrate: 2.1, health: "good" },
17
- ];
18
-
19
- const chatByStream: Record<string, string[]> = {
20
- "city-cam-01": ["switch to night mode?", "pan left a bit", "traffic spike @ 18:00"],
21
- "forest-node": ["birdsong level: high", "new fox spotted", "wind noise up"],
22
- "harbor-live": ["dock 3 unloading", "signal jitter", "fog incoming"],
23
- "lab-monitor": ["temperature stable", "note: calibrate sensor", "airflow normal"],
24
- };
25
-
26
- type State = {
27
- selected: number;
28
- paused: boolean;
29
- follow: boolean;
30
- };
31
-
32
- const app = createApp<State>({
33
- backend: createNodeBackend(),
34
- initialState: {
35
- selected: 0,
36
- paused: false,
37
- follow: true,
38
- },
39
- });
40
-
41
- const colors = {
42
- accent: rgb(116, 200, 255),
43
- muted: rgb(140, 150, 170),
44
- panel: rgb(18, 22, 34),
45
- panelAlt: rgb(22, 28, 44),
46
- ok: rgb(130, 220, 170),
47
- warn: rgb(255, 180, 120),
48
- ink: rgb(10, 14, 24),
49
- };
50
-
51
- function clamp(value: number, min: number, max: number) {
52
- return Math.max(min, Math.min(max, value));
53
- }
54
-
55
- function panel(title: string, children: ReturnType<typeof ui.column>[], flex = 1) {
56
- return ui.box(
57
- { title, flex, border: "rounded", px: 1, py: 0, style: { bg: colors.panel, fg: colors.muted } },
58
- children,
59
- );
60
- }
61
-
62
- app.view((state) => {
63
- const current = streams[state.selected] ?? streams[0];
64
- const chat = chatByStream[current?.name ?? ""] ?? [];
65
- const bufferValue = state.paused ? 0.2 : current ? Math.min(1, current.bitrate / 7) : 0;
66
-
67
- return ui.column({ flex: 1, p: 1, gap: 1, items: "stretch" }, [
68
- ui.row({ justify: "between", items: "center" }, [
69
- ui.text("__APP_NAME__", { fg: colors.accent, bold: true }),
70
- ui.row({ gap: 2 }, [
71
- ui.text(`Mode: ${state.paused ? "Paused" : "Live"}`, {
72
- fg: state.paused ? colors.warn : colors.ok,
73
- bold: true,
74
- }),
75
- ui.text(`Follow: ${state.follow ? "On" : "Off"}`, { fg: colors.muted }),
76
- ]),
77
- ]),
78
-
79
- ui.row({ flex: 1, gap: 1, items: "stretch" }, [
80
- panel(
81
- "Streams",
82
- [
83
- ui.column(
84
- { gap: 0 },
85
- streams.map((stream, index) => {
86
- const active = index === state.selected;
87
- const prefix = active ? ">" : " ";
88
- return ui.text(`${prefix} ${stream.name}`, {
89
- key: stream.name,
90
- style: {
91
- fg: active ? colors.accent : colors.muted,
92
- bold: active,
93
- },
94
- });
95
- }),
96
- ),
97
- ],
98
- 1,
99
- ),
100
-
101
- ui.column({ flex: 2, gap: 1, items: "stretch" }, [
102
- panel(
103
- "Viewer",
104
- [
105
- ui.column({ gap: 1 }, [
106
- ui.text(current ? current.name : "-", { fg: colors.accent, bold: true }),
107
- ui.text(`Category: ${current?.category ?? "-"}`),
108
- ui.text(`Viewers: ${current?.viewers ?? 0}`),
109
- ui.text(`Health: ${current?.health ?? "-"}`, {
110
- fg: current?.health === "warning" ? colors.warn : colors.ok,
111
- }),
112
- ui.text(`Bitrate: ${current?.bitrate ?? 0} Mbps`),
113
- ui.progress(bufferValue, { label: "Buffer", showPercent: true }),
114
- ]),
115
- ],
116
- 1,
117
- ),
118
- panel(
119
- "Chat",
120
- [
121
- ui.column({ gap: 1 }, [
122
- ui.text("Live chat", { fg: colors.muted }),
123
- ...chat.map((line) => ui.text(`- ${line}`)),
124
- ]),
125
- ],
126
- 1,
127
- ),
128
- ]),
129
- ]),
130
-
131
- ui.box({ px: 1, py: 0, style: { bg: colors.ink, fg: colors.muted } }, [
132
- ui.row({ justify: "between", items: "center" }, [
133
- ui.text("Streaming console ready"),
134
- ui.row({ gap: 1 }, [
135
- ui.kbd("up"),
136
- ui.text("Stream"),
137
- ui.kbd("space"),
138
- ui.text("Pause"),
139
- ui.kbd("f"),
140
- ui.text("Follow"),
141
- ui.kbd("q"),
142
- ui.text("Quit"),
143
- ]),
144
- ]),
145
- ]),
146
- ]);
147
- });
148
-
149
- app.keys({
150
- q: () => app.stop(),
151
- "ctrl+c": () => app.stop(),
152
- up: () =>
153
- app.update((s) => ({
154
- ...s,
155
- selected: clamp(s.selected - 1, 0, streams.length - 1),
156
- })),
157
- down: () =>
158
- app.update((s) => ({
159
- ...s,
160
- selected: clamp(s.selected + 1, 0, streams.length - 1),
161
- })),
162
- k: () =>
163
- app.update((s) => ({
164
- ...s,
165
- selected: clamp(s.selected - 1, 0, streams.length - 1),
166
- })),
167
- j: () =>
168
- app.update((s) => ({
169
- ...s,
170
- selected: clamp(s.selected + 1, 0, streams.length - 1),
171
- })),
172
- space: () => app.update((s) => ({ ...s, paused: !s.paused })),
173
- f: () => app.update((s) => ({ ...s, follow: !s.follow })),
174
- });
175
-
176
- await app.start();
@@ -1,14 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "Bundler",
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "skipLibCheck": true,
9
- "types": ["node"],
10
- "noUncheckedIndexedAccess": true,
11
- "exactOptionalPropertyTypes": true
12
- },
13
- "include": ["src/**/*.ts"]
14
- }