Skip to content

Commit 3feec9d

Browse files
committed
feat: implement temporary progressbar
- implement UI feature to trigger download asset progress bar - UI design is temporary
1 parent 9c91647 commit 3feec9d

File tree

9 files changed

+133
-34
lines changed

9 files changed

+133
-34
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Progress } from '@kobalte/core'
2+
import { Show } from 'solid-js'
3+
import './style.css'
4+
5+
interface IProgressBarProps {
6+
progress: number
7+
msg: string
8+
show: boolean
9+
}
10+
11+
export const ProgressBar = (props: IProgressBarProps) => {
12+
return (
13+
<Show when={props.show}>
14+
<div class="fixed bottom-0 right-0">
15+
<Progress.Root value={props.progress} class="progress">
16+
<div class="progress__label-container">
17+
<Progress.Label class="progress__label">{props.msg}</Progress.Label>
18+
<Progress.ValueLabel class="progress__value-label" />
19+
</div>
20+
<Progress.Track class="progress__track">
21+
<Progress.Fill class="progress__fill" />
22+
</Progress.Track>
23+
</Progress.Root>
24+
</div>
25+
</Show>
26+
)
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.progress {
2+
display: flex;
3+
flex-direction: column;
4+
gap: 2px;
5+
width: 300px;
6+
}
7+
8+
.progress__label-container {
9+
display: flex;
10+
justify-content: space-between;
11+
}
12+
13+
.progress__label,
14+
.progress__value-label {
15+
color: hsl(240 4% 16%);
16+
font-size: 14px;
17+
}
18+
19+
.progress__track {
20+
height: 10px;
21+
background-color: hsl(240 6% 90%);
22+
}
23+
24+
.progress__fill {
25+
background-color: hsl(200 98% 39%);
26+
height: 100%;
27+
width: var(--kb-progress-fill-width);
28+
transition: width 250ms linear;
29+
}
30+
31+
.progress__fill[data-progress="complete"] {
32+
background-color: #16a34a;
33+
}

GUI/ETVR/src/components/WebSerial/index.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ const WebSerial = () => {
1717

1818
createEffect(() => {
1919
appDataDir().then((appDataDirPath) => {
20-
console.log('appDataDirPath', appDataDirPath)
20+
//console.log('[WebSerial]: appDataDirPath', appDataDirPath)
2121
join(appDataDirPath, 'manifest.json').then((manifestfilePath) => {
22-
console.log('manifestfilePath', manifestfilePath)
22+
//console.log('[WebSerial]: manifestfilePath', manifestfilePath)
2323
const url = convertFileSrc(manifestfilePath)
24-
console.log('url', url)
24+
//console.log('[WebSerial]: url', url)
2525
setManifest(url)
2626
})
2727
})

GUI/ETVR/src/pages/appSettings/index.tsx

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { ProgressBar } from '@components/ProgessBar'
12
import WebSerial from '@components/WebSerial'
3+
import { progressBar } from '@src/store/ui/selectors'
24
import { useGHRelease } from '@utils/hooks/api/useGHReleases'
35

46
const AppSettings = () => {
5-
const { data, downloadAsset } = useGHRelease()
7+
const downloadAsset = useGHRelease()
68
return (
79
<div class="flex justify-center items-center content-center flex-col pt-[100px] text-white">
810
Coming Soon
@@ -12,6 +14,11 @@ const AppSettings = () => {
1214
Download Release Asset
1315
</button>
1416
<WebSerial />
17+
<ProgressBar
18+
progress={progressBar()?.progress as number}
19+
msg={progressBar()?.msg as string}
20+
show={progressBar()?.show as boolean}
21+
/>
1522
</div>
1623
)
1724
}

GUI/ETVR/src/store/api/ghAPI.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { RESTStatus } from './restAPI'
44

55
export interface IGHAsset {
66
name: string
7-
url: string
7+
browser_download_url: string
88
}
99

1010
export interface IGHRest {

GUI/ETVR/src/store/ui/selectors.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ export const showCameraView = createMemo(() => uiState().showCameraView)
1010
export const notifications = createMemo(() => uiState().notifications)
1111
export const notificationsType = createMemo(() => uiState().notificationsType)
1212
export const hideHeaderButtons = createMemo(() => uiState().hideHeaderButtons)
13+
export const progressBar = createMemo(() => uiState().progressBar)

GUI/ETVR/src/store/ui/ui.ts

+15
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ interface IMenuOpen {
88
y: number
99
}
1010

11+
interface IProgressBar {
12+
progress: number
13+
msg: string
14+
show: boolean
15+
}
16+
1117
export interface INewMenu {
1218
children: JSXElement
1319
ref: HTMLElement | null
@@ -30,6 +36,7 @@ export interface IUiStore {
3036
notifications?: ToasterStore<string>
3137
notificationsType?: ENotificationType
3238
hideHeaderButtons: boolean
39+
progressBar?: IProgressBar
3340
}
3441

3542
export const defaultState = {
@@ -110,4 +117,12 @@ export const setNotificationsType = (type: ENotificationType) => {
110117
)
111118
}
112119

120+
export const setProgressBar = (progress: number, msg: string, show: boolean) => {
121+
setState(
122+
produce((s) => {
123+
s.progressBar = { progress, msg, show }
124+
}),
125+
)
126+
}
127+
113128
export const uiState = createMemo(() => state)

GUI/ETVR/src/utils/hooks/api/useGHReleases.ts

+42-29
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import { readTextFile, BaseDirectory, writeTextFile } from '@tauri-apps/api/fs'
22
import { getClient, ResponseType } from '@tauri-apps/api/http'
33
import { appConfigDir, join } from '@tauri-apps/api/path'
44
import { invoke, convertFileSrc } from '@tauri-apps/api/tauri'
5-
import { createSignal } from 'solid-js'
65
import { download } from 'tauri-plugin-upload-api'
7-
import { RESTStatus } from '@src/store/api/restAPI'
6+
import { addNotification, ENotificationType, ENotificationAction } from '@hooks/notifications'
87
import { setFirmwareAssets, setGHRestStatus, setFirmwareVersion } from '@store/api/ghAPI'
8+
import { RESTStatus } from '@store/api/restAPI'
99
import { ghRESTEndpoint, firmwareAssets, firmwareVersion } from '@store/api/selectors'
10+
import { setProgressBar } from '@store/ui/ui'
1011

1112
interface IGHRelease {
1213
data: object
@@ -35,19 +36,38 @@ const getRelease = async (firmware: string) => {
3536

3637
if (firmwareAsset) {
3738
console.log('[Github Release]: Downloading firmware: ', firmware)
39+
console.log('[Github Release]: Firmware URL: ', firmwareAsset)
3840

3941
// parse out the file name from the firmwareAsset.url and append it to the appConfigDirPath
40-
const fileName = firmwareAsset.url.split('/')[firmwareAsset.url.split('/').length - 1]
42+
const fileName =
43+
firmwareAsset.browser_download_url.split('/')[
44+
firmwareAsset.browser_download_url.split('/').length - 1
45+
]
4146
//console.log('[Github Release]: File Name: ', fileName)
4247
// ${appConfigDirPath}${fileName}
4348
const path = await join(appConfigDirPath, fileName)
4449
console.log('[Github Release]: Path: ', path)
4550
// get the latest release
4651
const response = await download(
47-
firmwareAsset.url,
52+
firmwareAsset.browser_download_url,
4853
path,
49-
(progress, total) =>
50-
console.log(`[Github Release]: Downloaded ${progress} of ${total} bytes`), // a callback that will be called with the upload progress
54+
(progress, total) => {
55+
// UI store set prgoress bar to true and set progress
56+
const download_percent = Math.round((progress / total) * 100)
57+
setProgressBar(download_percent, `Downloading Firmware ${firmware}`, true)
58+
console.log(`[Github Release]: Downloaded ${progress} of ${total} bytes`)
59+
},
60+
)
61+
setProgressBar(0, '', false)
62+
console.log('[Github Release]: Download Response: ', response)
63+
64+
addNotification(
65+
{
66+
title: 'ETVR Firmware Downloaded',
67+
message: `Downloaded Firmware ${firmware}`,
68+
type: ENotificationType.INFO,
69+
},
70+
ENotificationAction.OS,
5171
)
5272

5373
const res = await invoke('unzip_archive', {
@@ -95,7 +115,6 @@ const getRelease = async (firmware: string) => {
95115
console.log('[Github Release]: Manifest: ', config_json)
96116
return
97117
}
98-
return response
99118
}
100119
}
101120

@@ -105,47 +124,41 @@ const getRelease = async (firmware: string) => {
105124
* @returns {function} downloadAsset - The function that will download the asset from the github release endpoint
106125
*/
107126
export const useGHRelease = () => {
108-
const [data, setData] = createSignal({})
109127
const downloadAsset = async (firmware: string) => {
110128
const response = await getRelease(firmware)
111-
112-
if (typeof response === 'string') {
113-
setGHRestStatus(RESTStatus.ACTIVE)
114-
const parsedResponse = JSON.parse(response)
115-
setData((prevData) => ({
116-
...prevData,
117-
...parsedResponse,
118-
}))
119-
}
129+
console.log('[Github Release]: Download Response: ', response)
120130
}
121-
122-
return { data, downloadAsset }
131+
return downloadAsset
123132
}
124133

125134
const setGHData = (data: IGHRelease, update: boolean) => {
126135
setFirmwareVersion(data['name'])
127136
const assets = data['assets']
128137
const download_urls = assets.map((asset) => asset.browser_download_url)
138+
129139
const firmware_assets = assets.map((asset) => asset.name)
130140

131141
// split the firmware_assets array of strings on the first dash and return the first element of the array
132142
const boardName = firmware_assets.map((asset) => asset.split('-')[0])
133143

134144
// set the board name in the store
135145
for (let i = 0; i < boardName.length; i++) {
136-
setFirmwareAssets({ name: boardName[i], url: download_urls[i] })
146+
//console.log('[Github Release]: Board Name: ', boardName[i])
147+
//console.log('[Github Release]: URLs: ', download_urls[i])
148+
setFirmwareAssets({ name: boardName[i], browser_download_url: download_urls[i] })
137149
}
138150

139151
if (update) {
140-
// parse out the assets and the version from the ghRestState
141-
// write the config file
142-
const config = {
143-
version: firmwareVersion(),
144-
assets: firmwareAssets(),
145-
}
146-
writeTextFile('config.json', JSON.stringify(config), {
147-
dir: BaseDirectory.AppConfig,
148-
})
152+
writeTextFile(
153+
'config.json',
154+
JSON.stringify({
155+
version: firmwareVersion(),
156+
assets: firmwareAssets(),
157+
}),
158+
{
159+
dir: BaseDirectory.AppConfig,
160+
},
161+
)
149162
.then(() => {
150163
console.log(
151164
update

GUI/ETVR/src/utils/hooks/notifications/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ export const NotificationsType = (
5252
return callbackApp()
5353
}
5454
}
55+
56+
// export imported enum
57+
export { ENotificationType, ENotificationAction }

0 commit comments

Comments
 (0)