Skip to content

Commit 8266275

Browse files
committed
src/js/portal-picker.js
1 parent 6364d58 commit 8266275

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

β€Žpackage.jsonβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "emulsion",
3-
"version": "0.9.47",
3+
"version": "0.9.48",
44
"summary": "Better gaming throught chemistry",
55
"description": "Emulsion is a modern, responsive game launcher that organizes platforms into galleries, manages game metadata and cover art, and launches titles through configured emulators.",
66
"homepage": "https://yphil.gitlab.io/emulsion",

β€Žsrc/js/portal-picker.jsβ€Ž

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { sessionBus, Variant } from "dbus-next";
2+
3+
function uriToPath(uri) {
4+
return uri.replace("file://", "");
5+
}
6+
7+
export async function pickFolderPersist() {
8+
console.log("πŸ“‚ PORTAL PICKER: Starting folder picker");
9+
10+
// Only use portals in Flatpak
11+
const isFlatpak = process.env.FLATPAK_ID !== undefined;
12+
console.log("πŸ“‚ PORTAL PICKER: Running in Flatpak?", isFlatpak);
13+
14+
if (!isFlatpak) {
15+
console.log("πŸ“‚ PORTAL PICKER: Not in Flatpak, skipping portals");
16+
throw new Error("NOT_FLATPAK");
17+
}
18+
19+
try {
20+
const bus = sessionBus();
21+
console.log("πŸ“‚ PORTAL PICKER: Got session bus");
22+
23+
const fcObj = await bus.getProxyObject("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop");
24+
const fileChooser = fcObj.getInterface("org.freedesktop.portal.FileChooser");
25+
26+
const options = {
27+
directory: new Variant("b", true),
28+
multiple: new Variant("b", false),
29+
modal: new Variant("b", true),
30+
title: new Variant("s", "Choose a folder"),
31+
};
32+
33+
const appId = process.env.FLATPAK_ID || "io.gitlab.yphil.emulsion";
34+
console.log("πŸ“‚ PORTAL PICKER: Using app ID:", appId);
35+
36+
console.log("πŸ“‚ PORTAL PICKER: Calling OpenFile...");
37+
const requestPath = await fileChooser.OpenFile(appId, "", options);
38+
console.log("πŸ“‚ PORTAL PICKER: Request path:", requestPath);
39+
40+
const reqObj = await bus.getProxyObject("org.freedesktop.portal.Desktop", requestPath);
41+
const reqIface = reqObj.getInterface("org.freedesktop.portal.Request");
42+
43+
console.log("πŸ“‚ PORTAL PICKER: Waiting for response...");
44+
45+
return new Promise((resolve, reject) => {
46+
const timeout = setTimeout(() => {
47+
console.log("πŸ“‚ PORTAL PICKER: Timeout");
48+
reqIface.removeListener("Response", handler);
49+
reject(new Error("PORTAL_TIMEOUT"));
50+
}, 30000);
51+
52+
const handler = (code, results) => {
53+
console.log("πŸ“‚ PORTAL PICKER: Response received - Code:", code);
54+
clearTimeout(timeout);
55+
reqIface.removeListener("Response", handler);
56+
57+
if (code === 0 && results && results.uris && results.uris.length > 0) {
58+
const path = uriToPath(results.uris[0].value);
59+
console.log("πŸ“‚ PORTAL PICKER: Returning path:", path);
60+
resolve({ path });
61+
} else {
62+
console.log("πŸ“‚ PORTAL PICKER: User cancelled");
63+
reject(new Error("User cancelled"));
64+
}
65+
};
66+
67+
reqIface.on("Response", handler);
68+
});
69+
70+
} catch (e) {
71+
console.error("πŸ“‚ PORTAL PICKER: Error:", e.message);
72+
if (e.message === "NOT_FLATPAK") {
73+
throw e;
74+
}
75+
throw new Error("PORTAL_NOT_AVAILABLE");
76+
}
77+
}

0 commit comments

Comments
Β (0)