/* * This file is part of the Flowee project * Copyright (C) 2023-2025 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick import QtQuick.Layouts import "../Flowee" as Flowee Page { id: root headerText: qsTr("Explore") background: Rectangle { color: palette.base } Item { anchors.fill: parent // clip: true Flickable { anchors.fill: parent anchors.topMargin: 10 anchors.bottomMargin: 10 contentWidth: width contentHeight: content.height Column { id: content width: parent.width spacing: 15 Repeater { model: ModuleManager.registeredModules Rectangle { width: root.width - 30 height: 35 + titleLabel.height + statusField.height + Math.min(120, descriptionLabel.implicitHeight) radius: 20 color: palette.light border.width: 1 border.color: palette.midlight visible: modelData.hasUISections // has user-visible parts. Flowee.Label { id: titleLabel y: 15 text: modelData.title font.bold: true anchors.horizontalCenter: parent.horizontalCenter } NewIndicator { id: newIndicator buddy: titleLabel buttonId: modelData.buttonId } Image { x: 10 width: 64 anchors.top: descriptionFrame.top source: modelData.iconSource visible: modelData.iconSource !== "" smooth: true fillMode: Image.PreserveAspectFit } Item { id: descriptionFrame anchors.top: titleLabel.bottom anchors.topMargin: 10 width: parent.width - (modelData.iconSource === "" ? 0 : 76) clip: true anchors.bottom: statusField.top anchors.bottomMargin: 10 anchors.right: parent.right z: 10 Flowee.Label { id: descriptionLabel width: parent.width - 20 x: 10 text: modelData.description horizontalAlignment: Text.AlignJustify wrapMode: Text.WrapAtWordBoundaryOrAnywhere MouseArea { anchors.fill: parent onClicked: descriptionFrame.clip = !descriptionFrame.clip } } } Item { id: statusField width: parent.width height: 40 anchors.bottom: parent.bottom z: 1 Image { id: openIcon rotation: 270; width: 12; height: 8 anchors.right: parent.right anchors.rightMargin: 10 source: Pay.useDarkSkin ? "qrc:/smallArrow-light.svg" : "qrc:/smallArrow.svg" anchors.verticalCenter: openLabel.verticalCenter } Flowee.Label { id: openLabel text: qsTr("Open") anchors.right: openIcon.left anchors.rightMargin: 6 anchors.bottom: parent.bottom anchors.bottomMargin: 10 } MouseArea { anchors.left: openLabel.left anchors.right: parent.right height: parent.height + 20 y: -10 onClicked: { newIndicator.markSeen() for (let s of modelData.sections) { if (s.isMainMenuMethod || s.isSendMethod || s.isForExploreTab) { thePile.replace(s.qml) return } } } } Row { id: enabledRow spacing: 10 height: parent.height x: 10 Flowee.CheckBox { id: moduleEnabled anchors.verticalCenter: parent.verticalCenter checked: modelData.enabled onClicked: modelData.enabled = checked visible: modelData.canBeEnabled } // one icon per section-type Image { source: "qrc:/sending" + (Pay.useDarkSkin ? "-light.svg" : ".svg") width: 16 height: width anchors.verticalCenter: parent.verticalCenter visible: section != null opacity: (visible && section.enabled) ? 0.8 : 0.3 property QtObject section: { // find the section our icon represents. for (let s of modelData.sections) { if (s.isSendMethod) return s } return null // module doesn't have such a section. } } Image { source: "qrc:/module-mainmenu" + (Pay.useDarkSkin ? "-light.svg" : ".svg") width: 16 height: width anchors.verticalCenter: parent.verticalCenter visible: section != null opacity: (visible && section.enabled) ? 0.8 : 0.3 property QtObject section: { // find the section our icon represents. for (let s of modelData.sections) { if (s.isMainMenuMethod) return s } return null } } Image { source: "qrc:/exploretab" + (Pay.useDarkSkin ? "-light.svg" : ".svg") width: 16 height: width anchors.verticalCenter: parent.verticalCenter visible: section != null opacity: (visible && section.enabled || !modelData.canBeEnabled) ? 0.8 : 0.3 property QtObject section: { // find the section our icon represents. for (let s of modelData.sections) { if (s.isForExploreTab) return s } return null } } } MouseArea { anchors.fill: enabledRow anchors.margins: -10 onClicked: { newIndicator.markSeen() modelData.enabled = !moduleEnabled.checked } } } } } } } } }