mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-15 15:54:00 -04:00
212 lines
7.1 KiB
QML
212 lines
7.1 KiB
QML
import QtQuick
|
|
import qs.Common
|
|
import qs.Modules.Settings
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property var greeterRoot: parent ? parent.greeterRoot : null
|
|
|
|
readonly property var curatedPluginIds: ["quickCapture", "dankKDEConnect", "wallpaperCarousel", "calculator", "emojiLauncher", "dockerManager", "amdGpuMonitor", "bongoCat"]
|
|
|
|
readonly property real headerIconContainerSize: Math.round(Theme.iconSize * 2)
|
|
|
|
property var curatedPlugins: []
|
|
property bool isLoading: false
|
|
property string loadError: ""
|
|
|
|
function refresh() {
|
|
isLoading = true;
|
|
loadError = "";
|
|
DMSService.listPlugins(response => {
|
|
isLoading = false;
|
|
if (response.error) {
|
|
loadError = response.error;
|
|
return;
|
|
}
|
|
curatedPlugins = curate(response.result || []);
|
|
});
|
|
if (DMSService.apiVersion >= 8)
|
|
DMSService.listInstalled();
|
|
}
|
|
|
|
function curate(registry) {
|
|
const byId = {};
|
|
for (let i = 0; i < registry.length; i++)
|
|
byId[registry[i].id] = registry[i];
|
|
const result = [];
|
|
for (let i = 0; i < curatedPluginIds.length; i++) {
|
|
const plugin = byId[curatedPluginIds[i]];
|
|
if (plugin)
|
|
result.push(plugin);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function markInstalled(installedList) {
|
|
const installedKeys = {};
|
|
for (let i = 0; i < installedList.length; i++) {
|
|
const plugin = installedList[i];
|
|
if (plugin.id)
|
|
installedKeys[plugin.id] = true;
|
|
if (plugin.name)
|
|
installedKeys[plugin.name] = true;
|
|
}
|
|
curatedPlugins = curatedPlugins.map(p => Object.assign({}, p, {
|
|
"installed": installedKeys[p.id] || installedKeys[p.name] || false
|
|
}));
|
|
}
|
|
|
|
Component.onCompleted: refresh()
|
|
|
|
Connections {
|
|
target: DMSService
|
|
|
|
function onInstalledPluginsReceived(plugins) {
|
|
root.markInstalled(plugins);
|
|
}
|
|
|
|
function onIsConnectedChanged() {
|
|
if (DMSService.isConnected && root.curatedPlugins.length === 0 && !root.isLoading)
|
|
root.refresh();
|
|
}
|
|
}
|
|
|
|
DankFlickable {
|
|
anchors.fill: parent
|
|
clip: true
|
|
contentHeight: mainColumn.height + Theme.spacingL * 2
|
|
contentWidth: width
|
|
|
|
Column {
|
|
id: mainColumn
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: Math.min(640, parent.width - Theme.spacingXL * 2)
|
|
topPadding: Theme.spacingL
|
|
spacing: Theme.spacingL
|
|
|
|
Row {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
spacing: Theme.spacingM
|
|
|
|
Rectangle {
|
|
width: root.headerIconContainerSize
|
|
height: root.headerIconContainerSize
|
|
radius: Math.round(root.headerIconContainerSize * 0.29)
|
|
color: Theme.primaryContainer
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
DankIcon {
|
|
anchors.centerIn: parent
|
|
name: "extension"
|
|
size: Theme.iconSize + 4
|
|
color: Theme.primary
|
|
}
|
|
}
|
|
|
|
Column {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: Theme.spacingXXS
|
|
|
|
StyledText {
|
|
text: I18n.tr("Popular Plugins", "greeter plugins page title")
|
|
font.pixelSize: Theme.fontSizeXLarge
|
|
font.weight: Font.Bold
|
|
color: Theme.surfaceText
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Community favorites to get you started", "greeter plugins page subtitle")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
width: parent.width
|
|
height: Math.round(Theme.fontSizeMedium * 8)
|
|
visible: root.isLoading
|
|
|
|
DankSpinner {
|
|
anchors.centerIn: parent
|
|
running: root.isLoading
|
|
}
|
|
}
|
|
|
|
Column {
|
|
width: parent.width
|
|
spacing: Theme.spacingS
|
|
visible: !root.isLoading && root.loadError !== ""
|
|
|
|
DankIcon {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
name: "cloud_off"
|
|
size: Theme.iconSize + 16
|
|
color: Theme.outline
|
|
}
|
|
|
|
StyledText {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: I18n.tr("Couldn't load plugins", "plugin registry fetch error")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
|
|
StyledText {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: root.loadError
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.outline
|
|
}
|
|
|
|
DankButton {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: I18n.tr("Retry", "retry failed action button")
|
|
iconName: "refresh"
|
|
backgroundColor: Theme.surfaceContainerHighest
|
|
textColor: Theme.surfaceText
|
|
onClicked: root.refresh()
|
|
}
|
|
}
|
|
|
|
Grid {
|
|
width: parent.width
|
|
columns: 2
|
|
rowSpacing: Theme.spacingS
|
|
columnSpacing: Theme.spacingS
|
|
visible: !root.isLoading && root.curatedPlugins.length > 0
|
|
|
|
Repeater {
|
|
model: root.curatedPlugins
|
|
|
|
PluginCard {
|
|
required property var modelData
|
|
|
|
width: (parent.width - Theme.spacingS) / 2
|
|
previewHeight: Math.round(width * 0.45)
|
|
plugin: modelData
|
|
installed: modelData.installed || false
|
|
onClicked: {
|
|
if (modelData.repo)
|
|
Qt.openUrlExternally(modelData.repo);
|
|
}
|
|
onInstallRequested: PluginService.installFromRegistry(modelData.id, modelData.name, modelData.type === "desktop")
|
|
}
|
|
}
|
|
}
|
|
|
|
GreeterSettingsCard {
|
|
width: parent.width
|
|
iconName: "explore"
|
|
title: I18n.tr("Browse Plugins", "plugin browser window title")
|
|
description: I18n.tr("Browse or search plugins")
|
|
visible: !root.isLoading && root.loadError === ""
|
|
onClicked: PopoutService.openSettingsWithTab("plugins")
|
|
}
|
|
}
|
|
}
|
|
}
|