Skip to content

Commit b0367a4

Browse files
committed
feat: backup plugins
1 parent 22a7d11 commit b0367a4

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/lang/en-us.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@
269269
"server port": "Server port",
270270
"preview settings": "Preview settings",
271271
"preview settings note": "If preview port and server port are different, app will not start server and it will instead open https://<host>:<preview port> in browser or in-app browser. This is useful when you are running a server somewhere else.",
272-
"backup/restore note": "It will only backup your settings, custom theme and key bindings. It will not backup your FTP/SFTP.",
272+
"backup/restore note": "It will only backup your settings, custom theme, installed plugins and key bindings. It will not backup your FTP/SFTP or App state.",
273273
"host": "Host",
274274
"retry ftp/sftp when fail": "Retry ftp/sftp when fail",
275275
"more": "More",

src/settings/backupRestore.js

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import settingsPage from "components/settingsPage";
2+
import toast from "components/toast";
23
import alert from "dialogs/alert";
34
import fsOperation from "fileSystem";
5+
import constants from "lib/constants";
46
import appSettings from "lib/settings";
57
import FileBrowser from "pages/fileBrowser";
68
import Uri from "utils/Uri";
79
import Url from "utils/Url";
10+
import helpers from "utils/helpers";
811

912
function backupRestore() {
1013
const title =
@@ -46,6 +49,9 @@ function backupRestore() {
4649
try {
4750
const settings = appSettings.value;
4851
const keyBindings = await fsOperation(KEYBINDING_FILE).readFile("json");
52+
const installedPlugins = (
53+
await fsOperation(window.PLUGIN_DIR).lsDir()
54+
).map((plugin) => plugin.name);
4955

5056
const { url } = await FileBrowser("folder", strings["select folder"]);
5157

@@ -68,6 +74,7 @@ function backupRestore() {
6874
const backupString = JSON.stringify({
6975
settings,
7076
keyBindings,
77+
installedPlugins,
7178
});
7279

7380
await backupFileFS.writeFile(backupString);
@@ -104,14 +111,61 @@ backupRestore.restore = async function (url) {
104111
backup = JSON.parse(backup);
105112
} catch (error) {
106113
alert(strings.error.toUpperCase(), strings["invalid backup file"]);
114+
return;
107115
}
108116

109117
try {
110118
const text = JSON.stringify(backup.keyBindings, undefined, 2);
111119
await fsOperation(window.KEYBINDING_FILE).writeFile(text);
112-
} catch (error) {}
120+
} catch (error) {
121+
console.error("Error restoring key bindings:", error);
122+
}
123+
124+
const { settings, installedPlugins } = backup;
125+
126+
const { default: installPlugin } = await import("lib/installPlugin");
127+
128+
// Restore plugins
129+
if (Array.isArray(installedPlugins)) {
130+
for (const id of installedPlugins) {
131+
try {
132+
if (!id) continue;
133+
const pluginUrl = Url.join(constants.API_BASE, `plugin/${id}`);
134+
const remotePlugin = await fsOperation(pluginUrl)
135+
.readFile("json")
136+
.catch(() => null);
137+
138+
if (remotePlugin) {
139+
let purchaseToken = null;
140+
if (Number.parseFloat(remotePlugin.price) > 0) {
141+
try {
142+
const [product] = await helpers.promisify(iap.getProducts, [
143+
remotePlugin.sku,
144+
]);
145+
if (product) {
146+
async function getPurchase(sku) {
147+
const purchases = await helpers.promisify(iap.getPurchases);
148+
const purchase = purchases.find((p) =>
149+
p.productIds.includes(sku),
150+
);
151+
return purchase;
152+
}
153+
const purchase = await getPurchase(product.productId);
154+
purchaseToken = purchase?.purchaseToken;
155+
}
156+
} catch (error) {
157+
helpers.error(error);
158+
}
159+
}
160+
toast("Restoring plugins", 3000);
161+
await installPlugin(id, remotePlugin.name, purchaseToken);
162+
}
163+
} catch (error) {
164+
console.error(`Error restoring plugin ${id}:`, error);
165+
}
166+
}
167+
}
113168

114-
const { settings } = backup;
115169
await appSettings.update(settings);
116170
location.reload();
117171
} catch (err) {

0 commit comments

Comments
 (0)