Skip to content

Commit 82bcd41

Browse files
committed
refactor: migrate renderer state to zustand v0.19.0
1 parent 0be0f13 commit 82bcd41

31 files changed

+970
-458
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,33 @@
22

33
All notable changes to this project are documented in this file.
44

5+
## [0.19.0] - 2026-03-24
6+
7+
### Added
8+
9+
- Zustand as renderer state management dependency.
10+
- Domain stores under `src/stores/*`:
11+
- `coreStore`
12+
- `uiStore`
13+
- `logsStore`
14+
- `accountsStore`
15+
- `streamStore`
16+
- `settingsUiStore`
17+
- `liveSetupUiStore`
18+
- `dashboardStore`
19+
- `pulseUiStore`
20+
21+
### Changed
22+
23+
- Migrated renderer global state and orchestration from hook-local state to Zustand store facades.
24+
- Refactored lifecycle wiring (`bootstrap`, `event listeners`, `persistence`, `driver readiness`, `shell controls`) to use store-backed state flow.
25+
- Migrated remaining page-level UI states in Settings/LiveSetup/Dashboard/Pulse to Zustand.
26+
27+
### Notes
28+
29+
- IPC contract and main/preload runtime behavior remain unchanged.
30+
- Existing page props and route content contracts were kept compatible.
31+
532
## [0.18.1] - 2026-03-24
633

734
### Fixed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<p><strong>TikTok Live Stream Key Generator for OBS from Streamlabs</strong></p>
66
<p><em>Windows desktop app for fetching RTMP URL and Stream Key for OBS.</em></p>
77
<p>
8-
<img src="https://img.shields.io/badge/Version-0.18.1-primary?style=for-the-badge&logo=electron" alt="Version" />
8+
<img src="https://img.shields.io/badge/Version-0.19.0-primary?style=for-the-badge&logo=electron" alt="Version" />
99
<img src="https://img.shields.io/badge/Platform-Windows-blue?style=for-the-badge&logo=windows" alt="Platform" />
1010
<img src="https://img.shields.io/badge/Framework-React_19-61DAFB?style=for-the-badge&logo=react" alt="Framework" />
1111
<img src="https://img.shields.io/badge/Database-SQLite_3-003B57?style=for-the-badge&logo=sqlite" alt="Database" />
@@ -166,17 +166,17 @@ GitHub Actions uses four workflows:
166166

167167
Release tag rule:
168168
- Tag must match `package.json` version exactly, in the format `v<version>`.
169-
- Example: if version is `0.18.1`, release tag must be `v0.18.1`.
169+
- Example: if version is `0.19.0`, release tag must be `v0.19.0`.
170170

171171
Typical release flow:
172172
```bash
173173
# 1) bump version in package.json
174174
# 2) commit changes
175175
git add .
176-
git commit -m "release: v0.18.1"
176+
git commit -m "release: v0.19.0"
177177

178178
# 3) create and push release tag
179-
git tag v0.18.1
179+
git tag v0.19.0
180180
git push origin main --tags
181181
```
182182

docs/ci-release.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Publish provider:
6060

6161
Tag must exactly match package version:
6262

63-
- package version `0.18.0` -> tag `v0.18.0`
63+
- package version `0.19.0` -> tag `v0.19.0`
6464

6565
Mismatch fails release workflow.
6666

@@ -95,4 +95,3 @@ This improves triage and tracking for:
9595
- `scope:*`
9696
- `priority:*`
9797
- `status:*`
98-

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "labsgen-tiktok",
3-
"version": "0.18.1",
3+
"version": "0.19.0",
44
"description": "TikTok Live Stream Key Generator for OBS from Streamlabs",
55
"packageManager": "pnpm@10.32.1",
66
"engines": {
@@ -77,8 +77,7 @@
7777
"multiLanguageInstaller": false,
7878
"displayLanguageSelector": false,
7979
"warningsAsErrors": false
80-
}
81-
,
80+
},
8281
"publish": [
8382
{
8483
"provider": "github",
@@ -99,10 +98,15 @@
9998
"react-dom": "^19.2.4",
10099
"react-i18next": "^15.4.0",
101100
"selenium-webdriver": "^4.40.0",
102-
"semver": "^7.6.0"
101+
"semver": "^7.6.0",
102+
"zustand": "^5.0.12"
103103
},
104104
"devDependencies": {
105105
"@electron/rebuild": "^4.0.3",
106+
"@types/electron": "^1.6.12",
107+
"@types/node": "^24.3.1",
108+
"@types/react": "^19.1.13",
109+
"@types/react-dom": "^19.1.9",
106110
"@vitejs/plugin-react": "^5.1.3",
107111
"@vitejs/plugin-react-swc": "^3.8.0",
108112
"autoprefixer": "^10.4.24",
@@ -113,10 +117,6 @@
113117
"postcss": "^8.5.6",
114118
"tailwindcss": "^3.4.19",
115119
"typescript": "^5.9.2",
116-
"@types/node": "^24.3.1",
117-
"@types/electron": "^1.6.12",
118-
"@types/react": "^19.1.13",
119-
"@types/react-dom": "^19.1.9",
120120
"vite": "^7.3.1"
121121
}
122122
}

pnpm-lock.yaml

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/hooks/pages/useDashboardPerformance.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { useEffect, useMemo, useState } from "react"
1+
import { useEffect, useMemo } from "react"
22
import { useApiBridge } from "../useApiBridge"
3+
import { useDashboardStore } from "../../stores"
34

45
type DashboardPerformanceState = {
56
cpuPercent: number | null
@@ -16,13 +17,10 @@ type UseDashboardPerformanceResult = {
1617

1718
export const useDashboardPerformance = (): UseDashboardPerformanceResult => {
1819
const api = useApiBridge()
19-
const [performance, setPerformance] = useState<DashboardPerformanceState>({
20-
cpuPercent: null,
21-
memPercent: null,
22-
memUsedMB: 0,
23-
memTotalMB: 0
24-
})
25-
const [perfLoading, setPerfLoading] = useState(true)
20+
const performance = useDashboardStore((state) => state.performance)
21+
const setPerformance = useDashboardStore((state) => state.setPerformance)
22+
const perfLoading = useDashboardStore((state) => state.perfLoading)
23+
const setPerfLoading = useDashboardStore((state) => state.setPerfLoading)
2624

2725
useEffect(() => {
2826
let isMounted = true
@@ -68,4 +66,3 @@ export const useDashboardPerformance = (): UseDashboardPerformanceResult => {
6866
memLabel
6967
}
7068
}
71-

src/hooks/pages/useLiveSetupActions.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { useEffect, useRef, useState } from "react"
1+
import { useEffect, useRef } from "react"
22
import type { MutableRefObject } from "react"
33
import { useAnimation } from "framer-motion"
44
import type { TFunction } from "i18next"
55
import type { LiveSetupPageProps } from "../../app/types"
66
import { useApiBridge } from "../useApiBridge"
7+
import { useLiveSetupUiStore } from "../../stores"
78

89
type UseLiveSetupActionsDeps = Pick<
910
LiveSetupPageProps,
@@ -34,8 +35,10 @@ export const useLiveSetupActions = ({
3435
gameCategory
3536
}: UseLiveSetupActionsDeps): UseLiveSetupActionsResult => {
3637
const api = useApiBridge()
37-
const [isSyncing, setIsSyncing] = useState(false)
38-
const [localCount, setLocalCount] = useState(0)
38+
const isSyncing = useLiveSetupUiStore((state) => state.isSyncing)
39+
const setIsSyncing = useLiveSetupUiStore((state) => state.setIsSyncing)
40+
const localCount = useLiveSetupUiStore((state) => state.localCount)
41+
const setLocalCount = useLiveSetupUiStore((state) => state.setLocalCount)
3942
const controls = useAnimation()
4043
const dropdownRef = useRef<HTMLDivElement | null>(null)
4144

src/hooks/pages/useSettingsActions.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { useState } from "react"
21
import type { TFunction } from "i18next"
32
import type { SettingsPageProps } from "../../app/types"
43
import { useApiBridge } from "../useApiBridge"
4+
import { useSettingsUiStore } from "../../stores"
55

66
type UseSettingsActionsDeps = Pick<
77
SettingsPageProps,
@@ -29,9 +29,12 @@ export const useSettingsActions = ({
2929
setSettings
3030
}: UseSettingsActionsDeps): UseSettingsActionsResult => {
3131
const api = useApiBridge()
32-
const [checkingUpdate, setCheckingUpdate] = useState(false)
33-
const [isInstallingDriver, setIsDriverInstalling] = useState(false)
34-
const [isUpToDate, setIsUpToDate] = useState(false)
32+
const checkingUpdate = useSettingsUiStore((state) => state.checkingUpdate)
33+
const setCheckingUpdate = useSettingsUiStore((state) => state.setCheckingUpdate)
34+
const isInstallingDriver = useSettingsUiStore((state) => state.isInstallingDriver)
35+
const setIsDriverInstalling = useSettingsUiStore((state) => state.setIsInstallingDriver)
36+
const isUpToDate = useSettingsUiStore((state) => state.isUpToDate)
37+
const setIsUpToDate = useSettingsUiStore((state) => state.setIsUpToDate)
3538

3639
const handleUpdateCheck = async () => {
3740
setCheckingUpdate(true)

0 commit comments

Comments
 (0)