diff --git a/src/components/library/UpdateChecker.tsx b/src/components/library/UpdateChecker.tsx
new file mode 100644
index 00000000..678cb94a
--- /dev/null
+++ b/src/components/library/UpdateChecker.tsx
@@ -0,0 +1,67 @@
+import React, { useEffect, useState } from 'react';
+import IconButton from '@mui/material/IconButton';
+import RefreshIcon from '@mui/icons-material/Refresh';
+import CircularProgress from '@mui/material/CircularProgress';
+import { Box } from '@mui/system';
+import Typography from '@mui/material/Typography';
+import client from 'util/client';
+import makeToast from '../util/Toast';
+
+interface IProgressProps {
+ progress: number
+}
+
+function Progress({ progress }: IProgressProps) {
+ return (
+
+
+
+
+ {`${Math.round(progress)}%`}
+
+
+
+
+ );
+}
+
+const baseWebsocketUrl = JSON.parse(window.localStorage.getItem('serverBaseURL')!).replace('http', 'ws');
+
+function UpdateChecker() {
+ const [loading, setLoading] = useState(false);
+ const [progress, setProgress] = useState(0);
+
+ const onClick = async () => {
+ try {
+ setLoading(true);
+ setProgress(0);
+ await client.post('/api/v1/update/fetch');
+ } catch (e) {
+ makeToast('Checking for updates failed!', 'error');
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ const wsc = new WebSocket(`${baseWebsocketUrl}/api/v1/update`);
+ wsc.onmessage = (e) => {
+ const data = JSON.parse(e.data) as IUpdateStatus;
+ const { COMPLETE, RUNNING, PENDING } = data.statusMap;
+
+ setLoading(data.running);
+ const currentProgress = 100 * (COMPLETE / (COMPLETE + RUNNING + PENDING));
+
+ setProgress(Number.isNaN(currentProgress) ? 0 : currentProgress);
+ };
+
+ return () => wsc.close();
+ }, []);
+
+ return (
+
+ {loading ? : }
+
+ );
+}
+
+export default UpdateChecker;
diff --git a/src/screens/Library.tsx b/src/screens/Library.tsx
index baa2be63..f904c043 100644
--- a/src/screens/Library.tsx
+++ b/src/screens/Library.tsx
@@ -17,6 +17,7 @@ import LibraryOptions from 'components/library/LibraryOptions';
import LibraryMangaGrid from 'components/library/LibraryMangaGrid';
import AppbarSearch from 'components/util/AppbarSearch';
import { useQueryParam, NumberParam } from 'use-query-params';
+import UpdateChecker from '../components/library/UpdateChecker';
interface IMangaCategory {
category: ICategory
@@ -31,6 +32,7 @@ export default function Library() {
<>
+
>,
);
}, []);
diff --git a/src/typings.d.ts b/src/typings.d.ts
index 327a7af3..0938eee6 100644
--- a/src/typings.d.ts
+++ b/src/typings.d.ts
@@ -187,6 +187,15 @@ interface IQueue {
queue: IDownloadChapter[]
}
+interface IUpdateStatus {
+ running: boolean
+ statusMap: {
+ COMPLETE: number,
+ RUNNING: number,
+ PENDING: number
+ }
+}
+
interface PreferenceProps {
key: string
title: string