aboutsummaryrefslogtreecommitdiff
path: root/pw_web/webconsole/components/uploadDb.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'pw_web/webconsole/components/uploadDb.tsx')
-rw-r--r--pw_web/webconsole/components/uploadDb.tsx79
1 files changed, 79 insertions, 0 deletions
diff --git a/pw_web/webconsole/components/uploadDb.tsx b/pw_web/webconsole/components/uploadDb.tsx
new file mode 100644
index 000000000..11a6ea9a5
--- /dev/null
+++ b/pw_web/webconsole/components/uploadDb.tsx
@@ -0,0 +1,79 @@
+// Copyright 2022 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+import Button from '@mui/material/Button';
+import {Alert} from '@mui/material';
+import {useState, useRef} from 'react';
+
+interface Props {
+ onUpload: (db: string) => void
+}
+
+function testTokenDB(tokenCsv: string) {
+ const lines = tokenCsv.trim().split(/\r?\n/).map(line => line.split(/,/));
+ lines.forEach((line) => {
+ // CSV has no columns or has malformed number.
+ if (line.length < 2 || !/^[a-fA-F0-9]+$/.test(line[0])) {
+ throw new Error("Not a valid token database.")
+ }
+ });
+}
+
+export default function BtnUploadDB({onUpload}: Props) {
+ const [uploaded, setUploaded] = useState(false);
+ const [error, setError] = useState("");
+ const uploadInputRef = useRef<HTMLInputElement>(null);
+
+ if (uploaded) return (<Alert severity="success">DB Loaded</Alert>)
+ return (
+ <>
+ <input
+ ref={uploadInputRef}
+ type="file"
+ accept="text/*"
+ style={{display: "none"}}
+ onChange={async e => {
+ const tokenCsv = await readFile(e.target.files![0]);
+ try {
+ testTokenDB(tokenCsv);
+ onUpload(tokenCsv);
+ setUploaded(true);
+ setError("");
+ }
+ catch (e: any) {
+ if (e instanceof Error) setError(e.message);
+ else setError("Error loading token database.");
+ }
+ }}
+ />
+ <Button
+ onClick={() => uploadInputRef.current && uploadInputRef.current.click()}
+ variant="contained">
+ Upload token database
+ </Button>
+ {error && <Alert severity="error">{error}</Alert>}
+ </>
+ )
+}
+
+function readFile(file: Blob): Promise<string> {
+ return new Promise((resolve, reject) => {
+ if (!file) return resolve('');
+ const reader = new FileReader();
+ reader.onload = function (e) {
+ resolve(String(e.target!.result));
+ };
+ reader.readAsText(file);
+ });
+}