5.8 KiB · text History 5fae34f
import QtQuick
import QtQuick.Layouts
import org.kde.plasma.plasmoid
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents3
import org.kde.plasma.extras as PlasmaExtras
import org.kde.kirigami as Kirigami

// The worked example of a widget on apollos-dbus: every query's points, a
// heading each, dimmed when stale. Everything it knows comes from two
// properties on the bus; it has no idea what a GTFS feed is.
PlasmoidItem {
    id: root

    Crib {
        id: crib
    }

    readonly property var wanted: Plasmoid.configuration.queries.split(",")
        .map(k => k.trim())
        .filter(k => k !== "")

    // In the configured order, or the board's if none is configured.
    readonly property var entries: {
        const board = crib.board;
        const keys = wanted.length > 0 ? wanted.filter(k => k in board) : Object.keys(board).sort();
        return keys
            .map(k => Object.assign({ key: k }, board[k]))
            .filter(e => Plasmoid.configuration.showStale || !e.stale);
    }

    readonly property string status: !crib.running ? i18n("apollos-dbus is not running")
        : !crib.connected ? i18n("Not connected to Apollo's Crib")
        : ""

    function clock(epoch) {
        return Qt.formatTime(new Date(epoch * 1000), Locale.ShortFormat);
    }

    Plasmoid.icon: "globe"
    toolTipMainText: i18n("Apollo's Crib")
    toolTipSubText: status !== "" ? status
        : entries.slice(0, 4).map(e => e.points.length > 0 ? e.points[0].text : e.name).join("\n")

    Plasmoid.contextualActions: [
        PlasmaCore.Action {
            text: i18n("Refresh")
            icon.name: "view-refresh"
            enabled: crib.running
            onTriggered: crib.refresh()
        }
    ]

    compactRepresentation: Kirigami.Icon {
        source: Plasmoid.icon
        active: compactMouse.containsMouse
        opacity: crib.connected ? 1 : 0.5

        MouseArea {
            id: compactMouse
            anchors.fill: parent
            hoverEnabled: true
            onClicked: root.expanded = !root.expanded
        }
    }

    fullRepresentation: PlasmaExtras.Representation {
        Layout.minimumWidth: Kirigami.Units.gridUnit * 16
        Layout.minimumHeight: Kirigami.Units.gridUnit * 12
        Layout.preferredWidth: Kirigami.Units.gridUnit * 22
        Layout.preferredHeight: Kirigami.Units.gridUnit * 24

        header: PlasmaExtras.PlasmoidHeading {
            RowLayout {
                anchors.fill: parent

                Kirigami.Heading {
                    Layout.fillWidth: true
                    level: 3
                    text: i18n("Apollo's Crib")
                }
                PlasmaComponents3.ToolButton {
                    icon.name: "view-refresh"
                    enabled: crib.running
                    onClicked: crib.refresh()
                    PlasmaComponents3.ToolTip.text: i18n("Ask for fresh data")
                    PlasmaComponents3.ToolTip.visible: hovered
                }
            }
        }

        PlasmaComponents3.ScrollView {
            anchors.fill: parent

            ListView {
                id: list
                model: root.entries
                spacing: Kirigami.Units.largeSpacing
                clip: true

                PlasmaExtras.PlaceholderMessage {
                    anchors.centerIn: parent
                    width: parent.width - Kirigami.Units.gridUnit * 2
                    visible: list.count === 0
                    iconName: "globe"
                    text: root.status !== "" ? root.status : i18n("Nothing heard yet")
                }

                delegate: ColumnLayout {
                    required property var modelData
                    width: ListView.view.width
                    spacing: Kirigami.Units.smallSpacing
                    opacity: modelData.stale ? 0.5 : 1

                    RowLayout {
                        Layout.fillWidth: true

                        PlasmaComponents3.Label {
                            Layout.fillWidth: true
                            text: modelData.name
                            font.weight: Font.DemiBold
                            elide: Text.ElideRight
                        }
                        PlasmaComponents3.Label {
                            text: modelData.stale ? i18n("stale, %1", root.clock(modelData.updated)) : root.clock(modelData.updated)
                            opacity: 0.6
                            font: Kirigami.Theme.smallFont
                        }
                    }

                    Repeater {
                        model: modelData.points

                        RowLayout {
                            required property var modelData
                            Layout.fillWidth: true
                            spacing: Kirigami.Units.smallSpacing

                            // A transit line's own colour; nothing else has one.
                            Rectangle {
                                Layout.preferredWidth: Kirigami.Units.smallSpacing
                                Layout.fillHeight: true
                                radius: width / 2
                                color: modelData.color || "transparent"
                            }
                            PlasmaComponents3.Label {
                                Layout.fillWidth: true
                                text: modelData.text
                                wrapMode: Text.Wrap
                            }
                        }
                    }

                    // A type apollos-dbus cannot say in words still says it is there.
                    PlasmaComponents3.Label {
                        visible: modelData.points.length === 0
                        text: i18n("%1: nothing to summarise", modelData.type)
                        opacity: 0.6
                    }
                }
            }
        }
    }
}