Skip to content

Commit f5826dc

Browse files
committed
backup + restore + reset
1 parent a86e275 commit f5826dc

File tree

3 files changed

+190
-40
lines changed

3 files changed

+190
-40
lines changed

popup/index.js

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,57 @@ function initSettings() {
644644
};
645645
body.appendChild(smoothScrollRow);
646646

647+
// backup/restore button
648+
const backupRestoreRow = document.createElement("div");
649+
backupRestoreRow.className = "row";
650+
backupRestoreRow.innerHTML = `
651+
<button
652+
data-flow="bottom"
653+
data-tooltip="${t({
654+
vi: "Lưu toàn bộ dữ liệu extension ra file",
655+
en: "Backup all extension data to file",
656+
})}">
657+
<i class="fa-solid fa-download"></i>
658+
${t({ vi: "Sao lưu", en: "Backup" })}
659+
</button>
660+
<button
661+
data-flow="bottom"
662+
data-tooltip="${t({
663+
vi: "Khôi phục dữ liệu extension từ file",
664+
en: "Restore all extension data from file",
665+
})}">
666+
<i class="fa-solid fa-upload"></i>
667+
${t({ vi: "Khôi phục", en: "Restore" })}
668+
</button>
669+
`;
670+
const [backupBtn, restoreBtn] = Array.from(
671+
backupRestoreRow.querySelectorAll("button")
672+
);
673+
backupBtn.onclick = backup;
674+
restoreBtn.onclick = restore;
675+
body.appendChild(backupRestoreRow);
676+
677+
// reset row
678+
const resetRow = document.createElement("div");
679+
resetRow.classList.add("row");
680+
resetRow.innerHTML = `
681+
<button
682+
data-flow="bottom"
683+
data-tooltip="${t({
684+
vi: "Xoá toàn bộ dữ liệu, đặt lại cài đặt gốc",
685+
en: "Delete all data, reset to default settings",
686+
})}">
687+
<i class="fa-solid fa-rotate-left"></i>
688+
${t({
689+
vi: "Đặt lại dữ liệu",
690+
en: "Reset extension",
691+
})}
692+
</button>
693+
`;
694+
const resetBtn = resetRow.querySelector("button");
695+
resetBtn.onclick = reset;
696+
body.appendChild(resetRow);
697+
647698
openModal(
648699
t({
649700
en: "Settings",
@@ -654,6 +705,99 @@ function initSettings() {
654705
};
655706
}
656707

708+
async function backup() {
709+
const data = {
710+
localStorage,
711+
chromeStorage: await chrome.storage.local.get(),
712+
time: new Date().getTime(),
713+
};
714+
const name = "useful-script-backup-" + new Date().toISOString() + ".json";
715+
UfsGlobal.Utils.downloadData(JSON.stringify(data), name);
716+
}
717+
718+
function restore() {
719+
Swal.fire({
720+
title: t({ en: "Restore data", vi: "Khôi phục dữ liệu" }),
721+
text: t({ en: "Select backup file", vi: "Chọn file đã sao lưu" }),
722+
input: "file",
723+
inputAttributes: {
724+
accept: ".json",
725+
},
726+
showCancelButton: true,
727+
confirmButtonText: t({ en: "Restore", vi: "Khôi phục" }),
728+
showLoaderOnConfirm: true,
729+
inputValidator: (value) => {
730+
if (!value)
731+
return t({ en: "Please select a file", vi: "Vui lòng chọn file" });
732+
},
733+
preConfirm: (file) => {
734+
return new Promise((resolve) => {
735+
const reader = new FileReader();
736+
reader.onload = () => {
737+
resolve(reader.result);
738+
};
739+
reader.readAsText(file);
740+
});
741+
},
742+
allowOutsideClick: () => !Swal.isLoading(),
743+
}).then(async (result) => {
744+
if (result.isConfirmed) {
745+
try {
746+
const json = JSON.parse(result.value);
747+
const { localStorage: l, chromeStorage } = json;
748+
749+
if (l) {
750+
Object.keys(l).forEach((key) => {
751+
localStorage[key] = l[key];
752+
});
753+
}
754+
755+
if (chromeStorage) {
756+
for (let key in chromeStorage) {
757+
await chrome.storage.local.set({ [key]: chromeStorage[key] });
758+
}
759+
}
760+
761+
Swal.fire({
762+
icon: "success",
763+
title: t({ en: "Restore Success", vi: "Khôi phục thành công" }),
764+
text: t({
765+
en: "Imported data from",
766+
vi: "Đã nạp dữ liệu",
767+
}),
768+
});
769+
} catch (e) {
770+
Swal.fire({
771+
icon: "error",
772+
title: t({ en: "Error", vi: "Lỗi" }),
773+
text: e?.message || e,
774+
});
775+
}
776+
}
777+
});
778+
}
779+
780+
function reset() {
781+
Swal.fire({
782+
icon: "warning",
783+
title: t({ en: "Reset", vi: "Đặt lại" }),
784+
text: t({
785+
en: "All data will be deleted. Are you sure?",
786+
vi: "Tất cả dữ liệu sẽ bị xoá. Bạn có chắc không?",
787+
}),
788+
showCancelButton: true,
789+
confirmButtonText: t({ en: "Delete all", vi: "Xoá hết" }),
790+
confirmButtonColor: "#d33",
791+
cancelButtonText: t({ en: "Cancel", vi: "Huỷ" }),
792+
}).then((result) => {
793+
if (result.isConfirmed) {
794+
localStorage.clear();
795+
chrome.storage.local.clear();
796+
chrome.runtime.reload();
797+
}
798+
});
799+
}
800+
657801
function initSearch() {
658802
searchInput.addEventListener("input", (event) => {
659803
let keyword = event.target.value;

popup/popup.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ <h3>
5252
</div>
5353

5454
<!-- settings -->
55-
<div class="settings" title="Settings" data-tooltip="Settings" data-flow="left">
55+
<div class="settings" data-tooltip="Settings" data-flow="left">
5656
<i class="fa-solid fa-gear fa-lg"></i>
5757
</div>
5858

5959
<!-- reload -->
60-
<div class="reload" title="Reload extension" data-tooltip="Reload extension" data-flow="right">
60+
<div class="reload" data-tooltip="Reload extension" data-flow="right">
6161
<i class="fa-solid fa-arrows-rotate fa-lg"></i>
6262
</div>
6363

popup/themes/default.less

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -119,43 +119,6 @@ option {
119119
left: 0px;
120120
}
121121

122-
.settings-body {
123-
.row {
124-
display: flex;
125-
justify-content: center;
126-
align-items: center;
127-
margin-bottom: 5px;
128-
129-
.label {
130-
flex-grow: 1;
131-
}
132-
133-
.right-container {
134-
display: flex;
135-
justify-content: center;
136-
align-items: center;
137-
138-
a:hover {
139-
background-color: transparent;
140-
}
141-
142-
img {
143-
width: 40px;
144-
margin: 0 5px;
145-
146-
&.avatar {
147-
border-radius: 50%;
148-
}
149-
}
150-
}
151-
152-
select {
153-
padding: 5px;
154-
}
155-
156-
}
157-
}
158-
159122
#update-btn {
160123
display: none;
161124
border: none;
@@ -317,7 +280,6 @@ option {
317280
background-color: @bg_script_btn_hover;
318281
cursor: pointer;
319282
z-index: 3;
320-
border: linear-gradient(rgb(210 213 219) 1px, transparent 1px), linear-gradient(to right, rgb(210 213 219) 1px, rgb(240 241 245) 1px);
321283

322284
.more-item {
323285
opacity: 1;
@@ -393,6 +355,50 @@ option {
393355
}
394356
}
395357

358+
.settings-body {
359+
.row {
360+
display: flex;
361+
justify-content: center;
362+
align-items: center;
363+
margin-bottom: 5px;
364+
365+
.label {
366+
flex-grow: 1;
367+
}
368+
369+
button {
370+
justify-content: center;
371+
372+
i {
373+
margin-right: 5px;
374+
}
375+
}
376+
377+
select {
378+
padding: 5px;
379+
}
380+
381+
.right-container {
382+
display: flex;
383+
justify-content: center;
384+
align-items: center;
385+
386+
a:hover {
387+
background-color: transparent;
388+
}
389+
390+
img {
391+
width: 40px;
392+
margin: 0 5px;
393+
394+
&.avatar {
395+
border-radius: 50%;
396+
}
397+
}
398+
}
399+
}
400+
}
401+
396402
.checkmark {
397403
display: inline-block;
398404
position: relative;

0 commit comments

Comments
 (0)