diff --git a/contents/ui/CompactRepresentation.qml b/contents/ui/CompactRepresentation.qml index 56a8da9..b7bd625 100644 --- a/contents/ui/CompactRepresentation.qml +++ b/contents/ui/CompactRepresentation.qml @@ -1,41 +1,15 @@ -/* - * SPDX-FileCopyrightText: 2024 Denys Madureira - * SPDX-FileCopyrightText: 2025 Bruno Gonçalves - * - * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL - */ - import QtQuick -import QtQuick.Layouts - -import org.kde.plasma.core as PlasmaCore -import org.kde.kirigami as Kirigami +import org.kde.kirigami 2.20 as Kirigami +import org.kde.plasma.plasmoid 2.0 +import org.kde.plasma.core 2.0 as PlasmaCore Item { id: compactRoot - // Icon mode constants (must match ConfigAppearance.qml ComboBox order) - readonly property int iconModeFavicon: 0 - readonly property int iconModeAdaptive: 1 - readonly property int iconModeDark: 2 - readonly property int iconModeLight: 3 - readonly property int iconModeOutlined: 4 - readonly property int iconModeFilled: 5 - readonly property int iconModeColorful: 6 - readonly property int iconModeCustom: 7 - - property var models: [] - property var webview: null + property var models + property var webview property string fallbackIcon: "help-about" - readonly property bool isVertical: plasmoid.formFactor === PlasmaCore.Types.Vertical - - Layout.minimumWidth: isVertical ? 0 : Kirigami.Units.iconSizes.medium - Layout.minimumHeight: isVertical ? Kirigami.Units.iconSizes.medium : 0 - - implicitWidth: Kirigami.Units.iconSizes.medium - implicitHeight: Kirigami.Units.iconSizes.medium - MouseArea { id: mouseArea anchors.fill: parent @@ -44,74 +18,90 @@ Item { Kirigami.Icon { anchors.fill: parent - // Use a function that returns a URL or icon name appropriately - source: getIconSource() + source: Qt.resolvedUrl(getIcon()) } - function getIconSource() { - let icon = getIconNameOrPath(); - if (icon.indexOf("/") !== -1 || icon.endsWith(".svg") || icon.endsWith(".png")) { - return Qt.resolvedUrl(icon); + // WebView connection handlers + // Monitor and respond to webview state changes + Connections { + // Parent webview connection + target: parent && parent.webviewRoot && parent.webviewRoot.webview ? parent.webviewRoot.webview : null + enabled: target ? true : false + } + + // Direct webview connection for loading state changes + Connections { + target: webview + enabled: webview !== null + function onLoadingChanged(loadingInfo) { + if (loadingInfo?.status === WebEngineLoadRequest.LoadSucceededStatus) + // Handle successful load + {} } - return icon; } + // Helper Functions + // Determines and returns the appropriate chat model icon based on: + // - Current chat service + // - System theme (light/dark) + // - User icon style preferences function getChatModelIcon() { - if (!models || models.length === 0) return `assets/logo-${getBackgroundColorContrast()}.svg`; - - const mode = plasmoid.configuration.iconMode; - const currentModel = models.find(model => plasmoid.configuration.url.includes(model.url)); + const currentModel = models.find(model => Plasmoid.configuration.url.includes(model.url)); const colorContrast = getBackgroundColorContrast(); - - // Colorful mode. If not in colorful mode, some models only have colorful icons available - const hasOnlyColorfulIcon = mode !== iconModeColorful && ["lobechat", "bigagi"].includes(currentModel?.id); + const hasOnlyColorfulIcon = !Plasmoid.configuration.useColorfulChatIcon && ["lobechat", "bigagi"].includes(currentModel?.id); if (!currentModel || currentModel?.id === "blackbox" || hasOnlyColorfulIcon) { return `assets/logo-${colorContrast}.svg`; } + // Add custom icon mapping, For CustomModels & New Models when added if (currentModel.useIcon) { - const style = mode === iconModeFilled ? "filled" : "outlined"; + const style = Plasmoid.configuration.useFilledChatIcon ? "filled" : "outlined"; return `assets/${style}/${currentModel.useIcon}-${colorContrast}.svg`; } - if (mode === iconModeColorful) { + if (Plasmoid.configuration.useColorfulChatIcon) { return `assets/colorful/${currentModel.id}.svg`; } - const style = mode === iconModeFilled ? "filled" : "outlined"; + const style = Plasmoid.configuration.useFilledChatIcon ? "filled" : "outlined"; return `assets/${style}/${currentModel.id}-${colorContrast}.svg`; } - function getIconNameOrPath() { - const mode = plasmoid.configuration.iconMode; - - if (mode === iconModeCustom) { - return plasmoid.configuration.customIcon || fallbackIcon; - } - - if (mode === iconModeFavicon) { - const faviconUrl = plasmoid.configuration.favIcon || plasmoid.configuration.lastFavIcon; + // Main icon selection function that determines which icon to display: + // 1. Website favicon (if enabled) + // 2. Chat model specific icon (if enabled) + // 3. Default icon based on theme + function getIcon() { + if (Plasmoid.configuration.useFavicon) { + const faviconUrl = Plasmoid.configuration.favIcon || Plasmoid.configuration.lastFavIcon; if (faviconUrl) { return faviconUrl.replace("image://favicon/", ""); } } - if (mode >= iconModeOutlined) { + if (Plasmoid.configuration.useFilledChatIcon || Plasmoid.configuration.useOutlinedChatIcon || Plasmoid.configuration.useColorfulChatIcon) { return getChatModelIcon() || fallbackIcon; } const contrast = getBackgroundColorContrast(); - if (mode === iconModeDark) return "assets/logo-dark.svg"; - if (mode === iconModeLight) return "assets/logo-light.svg"; - - return `assets/logo-${contrast}.svg`; + return Plasmoid.configuration.useDefaultDarkIcon ? "assets/logo-dark.svg" : Plasmoid.configuration.useDefaultLightIcon ? "assets/logo-light.svg" : `assets/logo-${contrast}.svg`; } + // Calculates whether to use light or dark icons based on + // the system background color using luminance formula + // Returns: "dark" or "light" based on background contrast function getBackgroundColorContrast() { - // Use Kirigami.Theme for better Plasma 6 compatibility - const color = Kirigami.Theme.backgroundColor; - const luma = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; - return luma > 0.5 ? "dark" : "light"; + try { + const color = Kirigami.Theme.backgroundColor; + const hex = color.toString().replace("#", ""); + const r = parseInt(hex.substring(0, 2), 16); + const g = parseInt(hex.substring(2, 4), 16); + const b = parseInt(hex.substring(4, 6), 16); + const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; + return luma > 128 ? "dark" : "light"; + } catch(e) { + return "dark"; + } } }