feat: checkpoint QML view migration
This commit is contained in:
@@ -0,0 +1,297 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import qEmby
|
||||
|
||||
Item {
|
||||
id: page
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Theme.bgBase
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Theme.spacingLg
|
||||
anchors.rightMargin: Theme.spacingLg
|
||||
anchors.topMargin: Theme.spacingLg
|
||||
anchors.bottomMargin: Theme.spacingXl
|
||||
spacing: Theme.spacingLg
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Theme.spacingMd
|
||||
|
||||
Text {
|
||||
text: qsTr("Logs")
|
||||
color: Theme.textPrimary
|
||||
font.pixelSize: Theme.fontTitle
|
||||
font.weight: Font.ExtraBold
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: logsPage.statsText
|
||||
color: Theme.textMuted
|
||||
font.pixelSize: Theme.fontBody
|
||||
}
|
||||
|
||||
ThemedButton {
|
||||
text: logsPage.refreshing ? qsTr("Refreshing…") : qsTr("Refresh")
|
||||
enabled: !logsPage.refreshing
|
||||
Accessible.name: qsTr("Refresh log files")
|
||||
onClicked: logsPage.refresh()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Math.min(190, Math.max(118, page.height * 0.25))
|
||||
radius: Theme.radiusLg
|
||||
color: Theme.alpha(Theme.bgSurface, Theme.dark ? 0.64 : 0.94)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.borderSoft, 0.7)
|
||||
|
||||
ListView {
|
||||
id: fileList
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingXs
|
||||
clip: true
|
||||
model: logsPage.model
|
||||
spacing: 2
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
currentIndex: -1
|
||||
|
||||
ScrollBar.vertical: ThemedScrollBar {
|
||||
}
|
||||
|
||||
delegate: Rectangle {
|
||||
id: logRow
|
||||
|
||||
required property string name
|
||||
required property string modified
|
||||
required property string modifiedCompact
|
||||
required property string sizeText
|
||||
|
||||
width: fileList.width
|
||||
height: 42
|
||||
radius: Theme.radiusMd
|
||||
color: logsPage.selectedName === name ? Theme.alpha(Theme.accent, Theme.dark ? 0.2 : 0.12) : rowMouse.containsMouse ? Theme.alpha(Theme.bgRaised, 0.76) : "transparent"
|
||||
border.width: logsPage.selectedName === name ? 1 : 0
|
||||
border.color: Theme.alpha(Theme.accent, 0.42)
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Theme.spacingMd
|
||||
anchors.rightMargin: Theme.spacingSm
|
||||
spacing: Theme.spacingMd
|
||||
|
||||
Text {
|
||||
text: logRow.name
|
||||
color: Theme.textPrimary
|
||||
font.pixelSize: Theme.fontBody
|
||||
font.weight: Font.Medium
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: logRow.sizeText + " · " + logRow.modifiedCompact
|
||||
color: Theme.textMuted
|
||||
font.pixelSize: Theme.fontSmall
|
||||
}
|
||||
|
||||
ThemedButton {
|
||||
implicitWidth: 74
|
||||
text: qsTr("Save…")
|
||||
enabled: !logsPage.saving
|
||||
Accessible.name: qsTr("Save %1").arg(logRow.name)
|
||||
onClicked: logsPage.saveLog(logRow.name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: rowMouse
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 80
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
Accessible.role: Accessible.ListItem
|
||||
Accessible.name: logRow.name
|
||||
onClicked: logsPage.selectLog(logRow.name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EmptyState {
|
||||
anchors.centerIn: parent
|
||||
visible: logsPage.hasLoaded && !logsPage.loading && logsPage.totalCount === 0
|
||||
text: qsTr("No log files found")
|
||||
hint: qsTr("The server did not report any downloadable logs.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
radius: Theme.radiusLg
|
||||
color: Theme.alpha(Theme.bgSurface, Theme.dark ? 0.64 : 0.94)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.borderSoft, 0.7)
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Theme.spacingLg
|
||||
Layout.rightMargin: Theme.spacingMd
|
||||
Layout.topMargin: Theme.spacingMd
|
||||
Layout.bottomMargin: Theme.spacingMd
|
||||
spacing: Theme.spacingMd
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Theme.spacingXs
|
||||
|
||||
Text {
|
||||
text: logsPage.selectedName.length > 0 ? logsPage.selectedName : qsTr("No log file selected")
|
||||
color: Theme.textPrimary
|
||||
font.pixelSize: Theme.fontHeading
|
||||
font.weight: Font.DemiBold
|
||||
elide: Text.ElideMiddle
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: logsPage.selectedMeta
|
||||
color: Theme.textMuted
|
||||
font.pixelSize: Theme.fontSmall
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ThemedButton {
|
||||
visible: logsPage.selectedName.length > 0
|
||||
text: logsPage.saving ? qsTr("Saving…") : qsTr("Save as…")
|
||||
enabled: !logsPage.saving && !logsPage.contentLoading
|
||||
onClicked: logsPage.saveLog(logsPage.selectedName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Theme.borderSoft
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
id: contentScroll
|
||||
|
||||
visible: logsPage.selectedName.length > 0 && !logsPage.contentLoading && logsPage.contentError.length === 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
|
||||
TextArea {
|
||||
width: contentScroll.availableWidth
|
||||
text: logsPage.content
|
||||
readOnly: true
|
||||
selectByMouse: true
|
||||
wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
|
||||
color: Theme.textBody
|
||||
selectionColor: Theme.accent
|
||||
selectedTextColor: "white"
|
||||
font.family: "monospace"
|
||||
font.pixelSize: Theme.fontSmall
|
||||
padding: Theme.spacingLg
|
||||
Accessible.name: qsTr("Log contents")
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ThemedScrollBar {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LoadingState {
|
||||
visible: logsPage.contentLoading
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
title: qsTr("Loading log")
|
||||
message: logsPage.selectedName
|
||||
}
|
||||
|
||||
ErrorState {
|
||||
visible: !logsPage.contentLoading && logsPage.contentError.length > 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
title: qsTr("Could not load log")
|
||||
message: logsPage.contentError
|
||||
retryText: qsTr("Try again")
|
||||
onRetryRequested: logsPage.selectLog(logsPage.selectedName)
|
||||
}
|
||||
|
||||
EmptyState {
|
||||
visible: logsPage.selectedName.length === 0 && logsPage.totalCount > 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: qsTr("Select a log file")
|
||||
hint: qsTr("Choose a file above to inspect its contents.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LoadingState {
|
||||
anchors.fill: parent
|
||||
visible: logsPage.loading && !logsPage.hasLoaded
|
||||
title: qsTr("Loading logs")
|
||||
message: qsTr("Fetching available server log files…")
|
||||
}
|
||||
|
||||
ErrorState {
|
||||
anchors.fill: parent
|
||||
visible: !logsPage.loading && !logsPage.hasLoaded && logsPage.errorMessage.length > 0
|
||||
title: qsTr("Could not load logs")
|
||||
message: logsPage.errorMessage
|
||||
onRetryRequested: logsPage.refresh()
|
||||
}
|
||||
|
||||
ToastHost {
|
||||
id: toastHost
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onToastRequested(message, kind) {
|
||||
toastHost.show(message, kind);
|
||||
}
|
||||
|
||||
target: logsPage
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user