mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-04 04:42:05 -04:00
core: add DL helper, apply to TrackArt OSD, DankLocationSearch
- unrelated change to add gsettingsOrDconf helpers
This commit is contained in:
@@ -853,7 +853,8 @@ Item {
|
||||
icon: "folder",
|
||||
priority: 4,
|
||||
items: fileItems,
|
||||
collapsed: collapsedSections["files"] || false
|
||||
collapsed: collapsedSections["files"] || false,
|
||||
flatStartIndex: 0
|
||||
};
|
||||
|
||||
var newSections;
|
||||
@@ -1284,7 +1285,11 @@ Item {
|
||||
},
|
||||
actions: [],
|
||||
primaryAction: null,
|
||||
_diskCached: true
|
||||
_diskCached: true,
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
});
|
||||
}
|
||||
sectionsData.push({
|
||||
@@ -1293,7 +1298,8 @@ Item {
|
||||
icon: s.icon || "",
|
||||
priority: s.priority || 0,
|
||||
items: items,
|
||||
collapsed: false
|
||||
collapsed: false,
|
||||
flatStartIndex: 0
|
||||
});
|
||||
}
|
||||
return sectionsData;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.pragma library
|
||||
|
||||
.import "ControllerUtils.js" as Utils
|
||||
.import "ControllerUtils.js" as Utils
|
||||
|
||||
function transformApp(app, override, defaultActions, primaryActionLabel) {
|
||||
var appId = app.id || app.execString || app.exec || "";
|
||||
@@ -31,7 +31,11 @@ function transformApp(app, override, defaultActions, primaryActionLabel) {
|
||||
name: primaryActionLabel,
|
||||
icon: "open_in_new",
|
||||
action: "launch"
|
||||
}
|
||||
},
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,7 +70,11 @@ function transformCoreApp(app, openLabel) {
|
||||
name: openLabel,
|
||||
icon: "open_in_new",
|
||||
action: "launch"
|
||||
}
|
||||
},
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -100,7 +108,11 @@ function transformBuiltInLauncherItem(item, pluginId, openLabel) {
|
||||
name: openLabel,
|
||||
icon: "open_in_new",
|
||||
action: "execute"
|
||||
}
|
||||
},
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -133,7 +145,11 @@ function transformFileResult(file, openLabel, openFolderLabel, copyPathLabel) {
|
||||
name: openLabel,
|
||||
icon: "open_in_new",
|
||||
action: "open"
|
||||
}
|
||||
},
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -166,7 +182,11 @@ function transformPluginItem(item, pluginId, selectLabel) {
|
||||
name: selectLabel,
|
||||
icon: "check",
|
||||
action: "execute"
|
||||
}
|
||||
},
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -188,7 +208,11 @@ function createCalculatorItem(calc, query, copyLabel) {
|
||||
name: copyLabel,
|
||||
icon: "content_copy",
|
||||
action: "copy"
|
||||
}
|
||||
},
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -218,6 +242,10 @@ function createPluginBrowseItem(pluginId, plugin, trigger, isBuiltIn, isAllowed,
|
||||
name: browseLabel,
|
||||
icon: "arrow_forward",
|
||||
action: "browse_plugin"
|
||||
}
|
||||
},
|
||||
_hName: "",
|
||||
_hSub: "",
|
||||
_hRich: false,
|
||||
_preScored: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -187,7 +187,8 @@ function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSec
|
||||
icon: sectionOrder[i].icon,
|
||||
priority: sectionOrder[i].priority,
|
||||
items: [],
|
||||
collapsed: false
|
||||
collapsed: false,
|
||||
flatStartIndex: 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +221,7 @@ function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSec
|
||||
|
||||
function flattenSections(sections) {
|
||||
var flat = []
|
||||
flat._sectionBounds = null
|
||||
var bounds = {}
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Effects
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
@@ -37,9 +36,23 @@ DankOSD {
|
||||
}
|
||||
}
|
||||
|
||||
property bool _pendingShow: false
|
||||
|
||||
onPlayerChanged: {
|
||||
if (!player)
|
||||
if (!player) {
|
||||
_pendingShow = false;
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: TrackArtService
|
||||
function onLoadingChanged() {
|
||||
if (!TrackArtService.loading && root._pendingShow) {
|
||||
root._pendingShow = false;
|
||||
root.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -48,10 +61,20 @@ DankOSD {
|
||||
function handleUpdate() {
|
||||
if (!root.player?.trackTitle)
|
||||
return;
|
||||
if (SettingsData.osdMediaPlaybackEnabled) {
|
||||
TrackArtService.loadArtwork(player.trackArtUrl);
|
||||
if (!SettingsData.osdMediaPlaybackEnabled)
|
||||
return;
|
||||
|
||||
TrackArtService.loadArtwork(player.trackArtUrl);
|
||||
|
||||
if (!player.trackArtUrl || player.trackArtUrl === "") {
|
||||
root.show();
|
||||
return;
|
||||
}
|
||||
if (!TrackArtService.loading) {
|
||||
root.show();
|
||||
return;
|
||||
}
|
||||
root._pendingShow = true;
|
||||
}
|
||||
|
||||
function onTrackArtUrlChanged() {
|
||||
|
||||
@@ -3,62 +3,62 @@ pragma ComponentBehavior: Bound
|
||||
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Mpris
|
||||
import qs.Common
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property string _lastArtUrl: ""
|
||||
property string _bgArtSource: ""
|
||||
|
||||
property string activeTrackArtFile: ""
|
||||
property bool loading: false
|
||||
|
||||
function loadArtwork(url) {
|
||||
if (!url || url == "") {
|
||||
if (!url || url === "") {
|
||||
_bgArtSource = "";
|
||||
_lastArtUrl = "";
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
if (url == _lastArtUrl)
|
||||
if (url === _lastArtUrl)
|
||||
return;
|
||||
_lastArtUrl = url;
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
||||
const filename = "/tmp/.dankshell/trackart_" + Date.now() + ".jpg";
|
||||
activeTrackArtFile = filename;
|
||||
|
||||
cleanupProcess.command = ["sh", "-c", "mkdir -p /tmp/.dankshell && find /tmp/.dankshell -name 'trackart_*' ! -name '" + filename.split('/').pop() + "' -delete"];
|
||||
cleanupProcess.running = true;
|
||||
_bgArtSource = "";
|
||||
loading = true;
|
||||
|
||||
imageDownloader.command = ["curl", "-L", "-s", "--user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", "-o", filename, url];
|
||||
imageDownloader.targetFile = filename;
|
||||
imageDownloader.running = true;
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
const localUrl = url;
|
||||
const filePath = url.startsWith("file://") ? url.substring(7) : url;
|
||||
Proc.runCommand("trackart", ["test", "-f", filePath], (output, exitCode) => {
|
||||
if (_lastArtUrl !== localUrl)
|
||||
return;
|
||||
if (exitCode === 0)
|
||||
_bgArtSource = localUrl;
|
||||
loading = false;
|
||||
}, 200);
|
||||
return;
|
||||
}
|
||||
// otherwise
|
||||
_bgArtSource = url;
|
||||
|
||||
const filename = "/tmp/.dankshell/trackart_" + Date.now() + ".jpg";
|
||||
activeTrackArtFile = filename;
|
||||
|
||||
Proc.runCommand("trackart_cleanup", ["sh", "-c", "mkdir -p /tmp/.dankshell && find /tmp/.dankshell -name 'trackart_*' ! -name '" + filename.split('/').pop() + "' -delete"], null, 0);
|
||||
|
||||
Proc.runCommand("trackart", ["dms", "dl", "-o", filename, "--user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", url], (output, exitCode) => {
|
||||
const resultPath = output.trim();
|
||||
if (resultPath !== filename)
|
||||
return;
|
||||
if (exitCode === 0)
|
||||
_bgArtSource = "file://" + resultPath;
|
||||
loading = false;
|
||||
}, 200);
|
||||
}
|
||||
|
||||
property MprisPlayer activePlayer: MprisController.activePlayer
|
||||
|
||||
onActivePlayerChanged: {
|
||||
loadArtwork(activePlayer.trackArtUrl);
|
||||
}
|
||||
|
||||
Process {
|
||||
id: imageDownloader
|
||||
running: false
|
||||
property string targetFile: ""
|
||||
|
||||
onExited: exitCode => {
|
||||
if (exitCode === 0 && targetFile)
|
||||
_bgArtSource = "file://" + targetFile;
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: cleanupProcess
|
||||
running: false
|
||||
loadArtwork(activePlayer?.trackArtUrl ?? "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import qs.Common
|
||||
import qs.Widgets
|
||||
|
||||
@@ -13,7 +12,7 @@ Item {
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
locationInput.forceActiveFocus()
|
||||
locationInput.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +27,10 @@ Item {
|
||||
signal locationSelected(string displayName, string coordinates)
|
||||
|
||||
function resetSearchState() {
|
||||
locationSearchTimer.stop()
|
||||
dropdownHideTimer.stop()
|
||||
isLoading = false
|
||||
searchResultsModel.clear()
|
||||
locationSearchTimer.stop();
|
||||
dropdownHideTimer.stop();
|
||||
isLoading = false;
|
||||
searchResultsModel.clear();
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
@@ -49,52 +48,49 @@ Item {
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (locationInput.text.length > 2) {
|
||||
searchResultsModel.clear()
|
||||
root.isLoading = true
|
||||
const searchLocation = locationInput.text
|
||||
root.currentSearchText = searchLocation
|
||||
const encodedLocation = encodeURIComponent(searchLocation)
|
||||
const curlCommand = `curl -4 -s --connect-timeout 5 --max-time 10 'https://nominatim.openstreetmap.org/search?q=${encodedLocation}&format=json&limit=5&addressdetails=1'`
|
||||
Proc.runCommand("locationSearch", ["bash", "-c", curlCommand], (output, exitCode) => {
|
||||
root.isLoading = false
|
||||
searchResultsModel.clear();
|
||||
root.isLoading = true;
|
||||
const searchLocation = locationInput.text;
|
||||
root.currentSearchText = searchLocation;
|
||||
const encodedLocation = encodeURIComponent(searchLocation);
|
||||
const searchUrl = "https://nominatim.openstreetmap.org/search?q=" + encodedLocation + "&format=json&limit=5&addressdetails=1";
|
||||
Proc.runCommand("locationSearch", ["dms", "dl", "-4", "--timeout", "10", searchUrl], (output, exitCode) => {
|
||||
root.isLoading = false;
|
||||
if (exitCode !== 0) {
|
||||
searchResultsModel.clear()
|
||||
return
|
||||
searchResultsModel.clear();
|
||||
return;
|
||||
}
|
||||
if (root.currentSearchText !== locationInput.text)
|
||||
return
|
||||
|
||||
const raw = output.trim()
|
||||
searchResultsModel.clear()
|
||||
return;
|
||||
const raw = output.trim();
|
||||
searchResultsModel.clear();
|
||||
if (!raw || raw[0] !== "[") {
|
||||
return
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const data = JSON.parse(raw)
|
||||
const data = JSON.parse(raw);
|
||||
if (data.length === 0) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < Math.min(data.length, 5); i++) {
|
||||
const location = data[i]
|
||||
const location = data[i];
|
||||
if (location.display_name && location.lat && location.lon) {
|
||||
const parts = location.display_name.split(', ')
|
||||
let cleanName = parts[0]
|
||||
const parts = location.display_name.split(', ');
|
||||
let cleanName = parts[0];
|
||||
if (parts.length > 1) {
|
||||
const state = parts[parts.length - 2]
|
||||
const state = parts[parts.length - 2];
|
||||
if (state && state !== cleanName)
|
||||
cleanName += `, ${state}`
|
||||
cleanName += `, ${state}`;
|
||||
}
|
||||
const query = `${location.lat},${location.lon}`
|
||||
const query = `${location.lat},${location.lon}`;
|
||||
searchResultsModel.append({
|
||||
"name": cleanName,
|
||||
"query": query
|
||||
})
|
||||
"name": cleanName,
|
||||
"query": query
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
})
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,7 +103,7 @@ Item {
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (!locationInput.getActiveFocus() && !searchDropdown.hovered)
|
||||
root.resetSearchState()
|
||||
root.resetSearchState();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,23 +128,23 @@ Item {
|
||||
keyNavigationBacktab: root.keyNavigationBacktab
|
||||
onTextEdited: {
|
||||
if (root._internalChange)
|
||||
return
|
||||
return;
|
||||
if (getActiveFocus()) {
|
||||
if (text.length > 2) {
|
||||
root.isLoading = true
|
||||
locationSearchTimer.restart()
|
||||
root.isLoading = true;
|
||||
locationSearchTimer.restart();
|
||||
} else {
|
||||
root.resetSearchState()
|
||||
root.resetSearchState();
|
||||
}
|
||||
}
|
||||
}
|
||||
onFocusStateChanged: hasFocus => {
|
||||
if (hasFocus) {
|
||||
dropdownHideTimer.stop()
|
||||
} else {
|
||||
dropdownHideTimer.start()
|
||||
}
|
||||
}
|
||||
if (hasFocus) {
|
||||
dropdownHideTimer.stop();
|
||||
} else {
|
||||
dropdownHideTimer.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
@@ -187,13 +183,13 @@ Item {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
parent.hovered = true
|
||||
dropdownHideTimer.stop()
|
||||
parent.hovered = true;
|
||||
dropdownHideTimer.stop();
|
||||
}
|
||||
onExited: {
|
||||
parent.hovered = false
|
||||
parent.hovered = false;
|
||||
if (!locationInput.getActiveFocus())
|
||||
dropdownHideTimer.start()
|
||||
dropdownHideTimer.start();
|
||||
}
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
@@ -245,14 +241,14 @@ Item {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root._internalChange = true
|
||||
const selectedName = model.name
|
||||
const selectedQuery = model.query
|
||||
locationInput.text = selectedName
|
||||
root.locationSelected(selectedName, selectedQuery)
|
||||
root.resetSearchState()
|
||||
locationInput.setFocus(false)
|
||||
root._internalChange = false
|
||||
root._internalChange = true;
|
||||
const selectedName = model.name;
|
||||
const selectedQuery = model.query;
|
||||
locationInput.text = selectedName;
|
||||
root.locationSelected(selectedName, selectedQuery);
|
||||
root.resetSearchState();
|
||||
locationInput.setFocus(false);
|
||||
root._internalChange = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user