Remove Sparrow and Bisq desktop launch feature from Hub tiles
Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/ffb330a3-9863-4f00-8476-67331a02a0b9 Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
9470ce74c1
commit
360654fe58
@@ -408,25 +408,20 @@ SERVICE_DESCRIPTIONS: dict[str, str] = {
|
||||
"Sparrow Wallet is a privacy-focused Bitcoin desktop wallet for sending, receiving, "
|
||||
"and managing your Bitcoin. Sovran_SystemsOS automatically connects it to your local "
|
||||
"Electrs server on first boot — your address lookups, balances, and transactions "
|
||||
"never touch a third-party server. Full privacy, zero configuration."
|
||||
"never touch a third-party server. Full privacy, zero configuration.\n\n"
|
||||
"To use Sparrow Wallet, open it directly from your desktop — it's already installed and "
|
||||
"auto-configured to connect to your local Electrs server."
|
||||
),
|
||||
"bisq-autoconnect.service": (
|
||||
"Bisq is a decentralized, peer-to-peer Bitcoin exchange — buy and sell Bitcoin "
|
||||
"with no KYC and no middleman. Sovran_SystemsOS automatically connects it to your "
|
||||
"local Bitcoin node on first boot, routing all traffic through Tor. Your trades are "
|
||||
"verified by your own node, keeping you fully sovereign."
|
||||
"verified by your own node, keeping you fully sovereign.\n\n"
|
||||
"To use Bisq, open it directly from your desktop — it's already installed and "
|
||||
"auto-configured to connect to your local Bitcoin node."
|
||||
),
|
||||
}
|
||||
|
||||
SERVICE_DESKTOP_LINKS: dict[str, list[dict[str, str]]] = {
|
||||
"sparrow-autoconnect.service": [
|
||||
{"label": "Open Sparrow Wallet", "desktop_file": "sparrow-desktop.desktop"},
|
||||
],
|
||||
"bisq-autoconnect.service": [
|
||||
{"label": "Open Bisq", "desktop_file": "Bisq.desktop"},
|
||||
],
|
||||
}
|
||||
|
||||
# ── App setup ────────────────────────────────────────────────────
|
||||
|
||||
_BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -2182,71 +2177,9 @@ async def api_service_detail(unit: str, icon: str | None = None):
|
||||
btc_ver = _format_bitcoin_version(raw_ver, icon=icon)
|
||||
service_detail["bitcoin_version"] = btc_ver # backwards compat
|
||||
service_detail["version"] = btc_ver
|
||||
desktop_links = SERVICE_DESKTOP_LINKS.get(unit, [])
|
||||
if desktop_links:
|
||||
service_detail["desktop_links"] = desktop_links
|
||||
return service_detail
|
||||
|
||||
|
||||
@app.post("/api/desktop/launch/{desktop_file}")
|
||||
async def api_desktop_launch(desktop_file: str):
|
||||
"""Launch a desktop application via gtk-launch on the local GNOME session."""
|
||||
import re as _re
|
||||
if not _re.match(r'^[a-zA-Z0-9_.-]+\.desktop$', desktop_file):
|
||||
raise HTTPException(status_code=400, detail="Invalid desktop file name")
|
||||
|
||||
target_user = "free"
|
||||
try:
|
||||
pw = pwd.getpwnam(target_user)
|
||||
uid = pw.pw_uid
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=500, detail=f"User '{target_user}' not found")
|
||||
|
||||
runtime_dir = f"/run/user/{uid}"
|
||||
|
||||
try:
|
||||
# Preferred: machinectl shell enters the user's actual login session scope,
|
||||
# inheriting the full graphical environment automatically.
|
||||
result = subprocess.run(
|
||||
[
|
||||
"machinectl", "shell", f"--uid={uid}",
|
||||
".host", "/usr/bin/env",
|
||||
f"XDG_RUNTIME_DIR={runtime_dir}",
|
||||
"WAYLAND_DISPLAY=wayland-0",
|
||||
f"DBUS_SESSION_BUS_ADDRESS=unix:path={runtime_dir}/bus",
|
||||
"DISPLAY=:0",
|
||||
"gtk-launch", desktop_file,
|
||||
],
|
||||
capture_output=True, text=True, timeout=10,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
# Fallback: su -l with explicit Wayland env vars
|
||||
env_prefix = (
|
||||
f"XDG_RUNTIME_DIR={runtime_dir} "
|
||||
f"WAYLAND_DISPLAY=wayland-0 "
|
||||
f"DBUS_SESSION_BUS_ADDRESS=unix:path={runtime_dir}/bus "
|
||||
f"DISPLAY=:0 "
|
||||
)
|
||||
result = subprocess.run(
|
||||
[
|
||||
"su", "-l", target_user, "-c",
|
||||
f"{env_prefix}gtk-launch {desktop_file}",
|
||||
],
|
||||
capture_output=True, text=True, timeout=10,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Failed to launch: {result.stderr.strip()}",
|
||||
)
|
||||
except FileNotFoundError:
|
||||
raise HTTPException(status_code=500, detail="Required launcher (machinectl or gtk-launch) not found on this system")
|
||||
except subprocess.TimeoutExpired:
|
||||
raise HTTPException(status_code=500, detail="Launch command timed out")
|
||||
|
||||
return {"ok": True, "launched": desktop_file}
|
||||
|
||||
|
||||
@app.get("/api/network")
|
||||
async def api_network():
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
@@ -85,21 +85,6 @@ async function openServiceDetailModal(unit, name, icon) {
|
||||
'</div>';
|
||||
}
|
||||
|
||||
// Section: Desktop Launch (only for services with desktop apps)
|
||||
if (data.desktop_links && data.desktop_links.length > 0) {
|
||||
var launchBtns = '';
|
||||
data.desktop_links.forEach(function(link) {
|
||||
launchBtns += '<button class="btn btn-primary svc-detail-launch-btn" data-desktop="' + escHtml(link.desktop_file) + '">' +
|
||||
'🖥️ ' + escHtml(link.label) +
|
||||
'</button>';
|
||||
});
|
||||
html += '<div class="svc-detail-section">' +
|
||||
'<div class="svc-detail-section-title">Open on Desktop</div>' +
|
||||
'<p class="svc-detail-desc" style="margin-bottom:12px">If you are accessing this machine locally on the GNOME desktop, click below to launch the app directly.</p>' +
|
||||
'<div class="svc-detail-launch-row">' + launchBtns + '</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
// Section B: Status
|
||||
// When a feature override is present, use the feature's enabled state so the
|
||||
// modal matches what the dashboard tile shows (feature toggle is authoritative).
|
||||
@@ -344,25 +329,6 @@ async function openServiceDetailModal(unit, name, icon) {
|
||||
$credsBody.innerHTML = html;
|
||||
_attachCopyHandlers($credsBody);
|
||||
|
||||
// Desktop launch button handlers
|
||||
$credsBody.querySelectorAll(".svc-detail-launch-btn").forEach(function(btn) {
|
||||
btn.addEventListener("click", async function() {
|
||||
var desktopFile = btn.dataset.desktop;
|
||||
btn.disabled = true;
|
||||
btn.textContent = "Launching…";
|
||||
try {
|
||||
await apiFetch("/api/desktop/launch/" + encodeURIComponent(desktopFile), {
|
||||
method: "POST"
|
||||
});
|
||||
btn.textContent = "✓ Launched!";
|
||||
setTimeout(function() { btn.textContent = "🖥️ " + btn.textContent; btn.disabled = false; }, 2000);
|
||||
} catch (err) {
|
||||
btn.textContent = "❌ Failed";
|
||||
btn.disabled = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (unit === "matrix-synapse.service") {
|
||||
var addBtn = document.getElementById("matrix-add-user-btn");
|
||||
var changePwBtn = document.getElementById("matrix-change-pw-btn");
|
||||
|
||||
Reference in New Issue
Block a user