mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-01 20:28:16 +02:00
184 lines
5.5 KiB
QML
184 lines
5.5 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Commons
|
|
import "Model.js" as Model
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property var settings: ({})
|
|
property string omarchyPath: Quickshell.env("OMARCHY_PATH")
|
|
|
|
property bool installed: false
|
|
property bool running: false
|
|
property bool authenticated: false
|
|
property bool refreshing: false
|
|
property string statusText: "Checking…"
|
|
property string accountPath: ""
|
|
property string plan: ""
|
|
property double usedBytes: 0
|
|
property double quotaBytes: 0
|
|
property double usagePercent: 0
|
|
property bool quotaKnown: false
|
|
property var files: []
|
|
property string actionStatus: ""
|
|
property string lastError: ""
|
|
|
|
readonly property int refreshIntervalSec: intSetting("refreshIntervalSec", 60, 10, 3600)
|
|
readonly property bool busy: statusProcess.running || loginProcess.running
|
|
readonly property string helperPath: (omarchyPath || "") + "/shell/plugins/panels/dropbox/status.py"
|
|
|
|
property string _statusOutput: ""
|
|
property string _statusError: ""
|
|
property string _loginOutput: ""
|
|
property string _loginError: ""
|
|
property bool _loginUrlOpened: false
|
|
|
|
function setting(name, fallback) {
|
|
var value = settings ? settings[name] : undefined
|
|
return value === undefined || value === null ? fallback : value
|
|
}
|
|
|
|
function intSetting(name, fallback, min, max) {
|
|
var n = parseInt(String(setting(name, fallback)), 10)
|
|
if (!isFinite(n)) n = fallback
|
|
if (n < min) n = min
|
|
if (n > max) n = max
|
|
return n
|
|
}
|
|
|
|
function refresh() {
|
|
if (statusProcess.running || helperPath === "/shell/plugins/panels/dropbox/status.py") return
|
|
_statusOutput = ""
|
|
_statusError = ""
|
|
refreshing = true
|
|
statusProcess.command = ["python3", helperPath, "25"]
|
|
statusProcess.running = true
|
|
}
|
|
|
|
function applyStatus(raw) {
|
|
var parsed = Model.parseStatus(raw)
|
|
if (!parsed.ok) {
|
|
lastError = parsed.lastError || "Failed to read Dropbox status"
|
|
return
|
|
}
|
|
installed = parsed.installed === true
|
|
running = parsed.running === true
|
|
authenticated = parsed.authenticated === true
|
|
statusText = String(parsed.statusText || (installed ? "Stopped" : "Not installed"))
|
|
accountPath = String(parsed.accountPath || "")
|
|
plan = String(parsed.plan || "")
|
|
usedBytes = Number(parsed.usedBytes || 0)
|
|
quotaBytes = Number(parsed.quotaBytes || 0)
|
|
usagePercent = Number(parsed.usagePercent || 0)
|
|
quotaKnown = parsed.quotaKnown === true
|
|
files = parsed.files || []
|
|
lastError = ""
|
|
}
|
|
|
|
function elideStatus(text) {
|
|
var value = String(text || "").replace(/\s+/g, " ").trim()
|
|
return value.length > 140 ? value.substring(0, 137) + "…" : value
|
|
}
|
|
|
|
function login() {
|
|
if (!installed || loginProcess.running) return
|
|
_loginOutput = ""
|
|
_loginError = ""
|
|
_loginUrlOpened = false
|
|
actionStatus = "Starting Dropbox login…"
|
|
loginProcess.command = ["dropbox-cli", "start"]
|
|
loginProcess.running = true
|
|
}
|
|
|
|
function openFile(file) {
|
|
if (!file || !file.path) return
|
|
Quickshell.execDetached(["uwsm-app", "--", "nautilus", "--select", fileUri(String(file.path))])
|
|
}
|
|
|
|
function fileUri(path) {
|
|
var parts = String(path || "").split("/")
|
|
for (var i = 0; i < parts.length; i++) parts[i] = encodeURIComponent(parts[i])
|
|
return "file://" + parts.join("/")
|
|
}
|
|
|
|
function openAuthUrlFrom(text) {
|
|
if (_loginUrlOpened) return true
|
|
var match = String(text || "").match(/https?:\/\/\S+/)
|
|
if (match && match[0]) {
|
|
_loginUrlOpened = true
|
|
Qt.openUrlExternally(match[0])
|
|
actionStatus = "Opened Dropbox login"
|
|
actionStatusTimer.restart()
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
function handleLoginOutput(data, isError) {
|
|
var text = String(data || "")
|
|
if (isError) _loginError += text + "\n"
|
|
else _loginOutput += text + "\n"
|
|
openAuthUrlFrom(text)
|
|
}
|
|
|
|
Timer {
|
|
id: refreshTimer
|
|
interval: root.refreshIntervalSec * 1000
|
|
repeat: true
|
|
running: true
|
|
triggeredOnStart: true
|
|
onTriggered: root.refresh()
|
|
}
|
|
|
|
Timer {
|
|
id: delayedRefresh
|
|
interval: 1000
|
|
repeat: false
|
|
onTriggered: root.refresh()
|
|
}
|
|
|
|
Timer {
|
|
id: actionStatusTimer
|
|
interval: 2200
|
|
repeat: false
|
|
onTriggered: root.actionStatus = ""
|
|
}
|
|
|
|
Process {
|
|
id: statusProcess
|
|
running: false
|
|
command: []
|
|
stdout: StdioCollector { id: statusStdout; waitForEnd: true; onStreamFinished: root._statusOutput = text }
|
|
stderr: StdioCollector { id: statusStderr; waitForEnd: true; onStreamFinished: root._statusError = text }
|
|
onExited: function(exitCode) {
|
|
root.refreshing = false
|
|
var stdout = String(statusStdout.text || root._statusOutput || "")
|
|
var stderr = String(statusStderr.text || root._statusError || "")
|
|
if (exitCode === 0) root.applyStatus(stdout)
|
|
else root.lastError = root.elideStatus(stderr || stdout || "Could not read Dropbox status")
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: loginProcess
|
|
running: false
|
|
command: []
|
|
stdout: SplitParser { onRead: function(data) { root.handleLoginOutput(data, false) } }
|
|
stderr: SplitParser { onRead: function(data) { root.handleLoginOutput(data, true) } }
|
|
onExited: function(exitCode) {
|
|
var combined = String(root._loginOutput || "") + "\n" + String(root._loginError || "")
|
|
var opened = root.openAuthUrlFrom(combined)
|
|
if (exitCode !== 0 && !opened) {
|
|
root.lastError = root.elideStatus(combined || "Dropbox login failed")
|
|
root.actionStatus = root.lastError
|
|
} else if (!opened) {
|
|
root.actionStatus = ""
|
|
root.lastError = ""
|
|
}
|
|
delayedRefresh.restart()
|
|
}
|
|
}
|
|
}
|