One-click backups for AT Protocol

fix: show custom scrollbar under titlebar

Turtlepaw 190f21e0 92fbed7b

Changed files
+98 -92
src
+11 -8
src/App.css
··· 192 192 } 193 193 194 194 /* width */ 195 - ::-webkit-scrollbar { 195 + .custom-scroll { 196 + margin-right: 3px; 197 + } 198 + 199 + .custom-scroll::-webkit-scrollbar { 196 200 width: 5px; 197 - margin-right: 5px; 198 201 } 199 202 200 203 /* Track */ 201 - ::-webkit-scrollbar-track { 204 + .custom-scroll::-webkit-scrollbar-track { 202 205 background: var(--background); 203 206 } 204 207 205 208 /* Handle */ 206 - ::-webkit-scrollbar-thumb { 207 - background: rgba(225, 225, 225, 0.2); 208 - border-radius: 100px; 209 + .custom-scroll::-webkit-scrollbar-thumb { 210 + background: rgba(225, 225, 225, 0.15); 211 + border-radius: 500px; 209 212 } 210 213 211 214 /* Handle on hover */ 212 - ::-webkit-scrollbar-thumb:hover { 213 - background: rgba(225, 225, 225, 0.3); 215 + .custom-scroll::-webkit-scrollbar-thumb:hover { 216 + background: rgba(225, 225, 225, 0.2); 214 217 } 215 218 216 219 .hide-scroll::-webkit-scrollbar {
+87 -84
src/App.tsx
··· 160 160 }, []); 161 161 162 162 return ( 163 - <main className="bg-background dark min-h-screen flex flex-col"> 163 + <> 164 164 <div className="titlebar hide-scroll" data-tauri-drag-region> 165 165 <div className="controls pr-[4px]"> 166 166 <Button ··· 217 217 </Button> 218 218 </div> 219 219 </div> 220 + <div className="flex flex-col h-screen overflow-hidden"> 221 + <main className="flex-1 overflow-y-auto custom-scroll"> 222 + <Dialog 223 + open={update != null} 224 + onOpenChange={(it) => { 225 + if (it == false) setUpdate(null); 226 + }} 227 + > 228 + {/* <DialogTrigger>Open</DialogTrigger> */} 229 + <DialogContent> 230 + <DialogHeader> 231 + <DialogTitle> 232 + New update available ({update?.currentVersion} ➜{" "} 233 + {update?.version}) 234 + </DialogTitle> 235 + <DialogDescription> 236 + <MarkdownRenderer 237 + children={update?.body ?? "No details provided"} 238 + /> 239 + </DialogDescription> 240 + <DialogFooter className="mt-4"> 241 + {downloadProgress == null ? ( 242 + <> 243 + <DialogClose asChild className="cursor-pointer"> 244 + <Button variant="outline">Skip</Button> 245 + </DialogClose> 246 + <Button 247 + className="cursor-pointer" 248 + onClick={async () => { 249 + if (update == null) toast("Failed: update not found"); 250 + toast("Downloading new update..."); 251 + let downloaded = 0; 252 + let contentLength = 0; 253 + // alternatively we could also call update.download() and update.install() separately 254 + await update!!.downloadAndInstall((event) => { 255 + switch (event.event) { 256 + case "Started": 257 + //@ts-expect-error 258 + contentLength = event.data.contentLength; 259 + setDownloadProgress(0); 260 + console.log( 261 + `started downloading ${event.data.contentLength} bytes` 262 + ); 263 + break; 264 + case "Progress": 265 + downloaded += event.data.chunkLength; 266 + setDownloadProgress(downloaded / contentLength); 267 + console.log( 268 + `downloaded ${downloaded} from ${contentLength}` 269 + ); 270 + break; 271 + case "Finished": 272 + setDownloadProgress(100); 273 + console.log("download finished"); 274 + break; 275 + } 276 + }); 220 277 221 - <Dialog 222 - open={update != null} 223 - onOpenChange={(it) => { 224 - if (it == false) setUpdate(null); 225 - }} 226 - > 227 - {/* <DialogTrigger>Open</DialogTrigger> */} 228 - <DialogContent> 229 - <DialogHeader> 230 - <DialogTitle> 231 - New update available ({update?.currentVersion} ➜ {update?.version} 232 - ) 233 - </DialogTitle> 234 - <DialogDescription> 235 - <MarkdownRenderer 236 - children={update?.body ?? "No details provided"} 237 - /> 238 - </DialogDescription> 239 - <DialogFooter className="mt-4"> 240 - {downloadProgress == null ? ( 241 - <> 242 - <DialogClose asChild className="cursor-pointer"> 243 - <Button variant="outline">Skip</Button> 244 - </DialogClose> 245 - <Button 246 - className="cursor-pointer" 247 - onClick={async () => { 248 - if (update == null) toast("Failed: update not found"); 249 - toast("Downloading new update..."); 250 - let downloaded = 0; 251 - let contentLength = 0; 252 - // alternatively we could also call update.download() and update.install() separately 253 - await update!!.downloadAndInstall((event) => { 254 - switch (event.event) { 255 - case "Started": 256 - //@ts-expect-error 257 - contentLength = event.data.contentLength; 258 - setDownloadProgress(0); 259 - console.log( 260 - `started downloading ${event.data.contentLength} bytes` 261 - ); 262 - break; 263 - case "Progress": 264 - downloaded += event.data.chunkLength; 265 - setDownloadProgress(downloaded / contentLength); 266 - console.log( 267 - `downloaded ${downloaded} from ${contentLength}` 268 - ); 269 - break; 270 - case "Finished": 271 - setDownloadProgress(100); 272 - console.log("download finished"); 273 - break; 274 - } 275 - }); 278 + toast("Update ready, restarting..."); 279 + await relaunch(); 280 + }} 281 + > 282 + Download 283 + </Button> 284 + </> 285 + ) : ( 286 + <Progress value={downloadProgress} className="w-full" /> 287 + )} 288 + </DialogFooter> 289 + </DialogHeader> 290 + </DialogContent> 291 + </Dialog> 276 292 277 - toast("Update ready, restarting..."); 278 - await relaunch(); 279 - }} 280 - > 281 - Download 282 - </Button> 283 - </> 284 - ) : ( 285 - <Progress value={downloadProgress} className="w-full" /> 286 - )} 287 - </DialogFooter> 288 - </DialogHeader> 289 - </DialogContent> 290 - </Dialog> 291 - 292 - <ScrollArea> 293 - {isLoading || !isLocalStorageReady ? ( 294 - <div className="fixed inset-0 flex items-center justify-center"> 295 - <LoaderCircleIcon className="animate-spin text-white/80" /> 296 - </div> 297 - ) : isAuthenticated ? ( 298 - <Home profile={profile!!} onLogout={logout} /> 299 - ) : ( 300 - <LoginPage onLogin={login} client={client} /> 301 - )} 302 - </ScrollArea> 293 + <ScrollArea> 294 + {isLoading || !isLocalStorageReady ? ( 295 + <div className="fixed inset-0 flex items-center justify-center"> 296 + <LoaderCircleIcon className="animate-spin text-white/80" /> 297 + </div> 298 + ) : isAuthenticated ? ( 299 + <Home profile={profile!!} onLogout={logout} /> 300 + ) : ( 301 + <LoginPage onLogin={login} client={client} /> 302 + )} 303 + </ScrollArea> 303 304 304 - <Toaster /> 305 - </main> 305 + <Toaster /> 306 + </main> 307 + </div> 308 + </> 306 309 ); 307 310 } 308 311