-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add publish status alerts and UI improvements
- Add publish status tracking for gift wrap events - Create new AlertManager component to display publish status notifications - Add ScrollingListView component to standardize list behavior - Update UI to show publish status with success/failure indicators - Improve message list scrolling behavior and layout resolves #79
- Loading branch information
Showing
14 changed files
with
279 additions
and
119 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import QtQuick 2.15 | ||
import QtQuick.Layouts 1.15 | ||
|
||
Column { | ||
id: root | ||
spacing: 8 | ||
|
||
anchors.top: parent.top | ||
anchors.horizontalCenter: parent.horizontalCenter | ||
anchors.topMargin: 16 | ||
|
||
width: Math.min(600, parent.width - 32) // max 600, or window width minus margins | ||
z: 1000 | ||
|
||
function showPublishStatus(status) { | ||
var component = Qt.createComponent("PublishAlert.ui.qml") | ||
if (component.status === Component.Ready) { | ||
var alert = component.createObject(root, { | ||
"publishStatus": status, | ||
"width": root.width | ||
}) | ||
// Remove the alert when it's hidden | ||
alert.onVisibleChanged.connect(function() { | ||
if (!alert.visible) { | ||
alert.destroy() | ||
} | ||
}) | ||
} | ||
} | ||
|
||
Repeater { | ||
model: publishStatuses | ||
delegate: PublishAlert { | ||
width: root.width | ||
publishStatus: modelData | ||
} | ||
} | ||
} |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import QtQuick 2.15 | ||
import QtQuick.Controls 2.15 | ||
import QtQuick.Controls.Material 2.15 | ||
import QtQuick.Layouts 1.15 | ||
import QtGraphicalEffects 1.15 | ||
|
||
import Futr 1.0 | ||
import Components 1.0 | ||
|
||
Rectangle { | ||
id: root | ||
|
||
property var publishStatus | ||
property int timeout: 5000 // 5 seconds | ||
|
||
height: layout.implicitHeight + 16 | ||
radius: 4 | ||
|
||
color: Qt.rgba(Material.backgroundColor.r, Material.backgroundColor.g, Material.backgroundColor.b, 0.8) | ||
|
||
ColumnLayout { | ||
id: layout | ||
anchors.fill: parent | ||
anchors.margins: 8 | ||
spacing: 8 | ||
|
||
RowLayout { | ||
Layout.fillWidth: true | ||
spacing: 8 | ||
|
||
Text { | ||
text: "Publishing: " + publishStatus.eventId | ||
color: Material.foreground | ||
font: Constants.font | ||
Layout.fillWidth: true | ||
elide: Text.ElideMiddle | ||
} | ||
|
||
Button { | ||
flat: true | ||
implicitWidth: 32 | ||
implicitHeight: 32 | ||
text: "×" | ||
onClicked: root.visible = false | ||
} | ||
} | ||
|
||
Repeater { | ||
model: publishStatus.relayStatuses | ||
delegate: RowLayout { | ||
spacing: 8 | ||
|
||
Image { | ||
source: modelData[1] === "" ? "qrc:/icons/check.svg" : "qrc:/icons/error.svg" | ||
width: 16 | ||
height: 16 | ||
} | ||
|
||
Text { | ||
text: modelData[0] + (modelData[1] ? ": " + modelData[1] : "") | ||
color: Material.foreground | ||
font: Constants.font | ||
} | ||
} | ||
} | ||
} | ||
|
||
layer.enabled: true | ||
layer.effect: DropShadow { | ||
transparentBorder: true | ||
horizontalOffset: 1 | ||
verticalOffset: 1 | ||
radius: 8.0 | ||
samples: 17 | ||
color: "#80000000" | ||
} | ||
|
||
Timer { | ||
id: hideTimer | ||
interval: root.timeout | ||
running: true | ||
onTriggered: root.visible = false | ||
} | ||
|
||
onPublishStatusChanged: { | ||
hideTimer.restart() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import QtQuick 2.15 | ||
import QtQuick.Controls 2.15 | ||
import QtQuick.Controls.Material 2.15 | ||
|
||
import Futr 1.0 | ||
|
||
ListView { | ||
id: root | ||
clip: true | ||
verticalLayoutDirection: ListView.TopToBottom | ||
leftMargin: Constants.spacing_m | ||
rightMargin: Constants.spacing_m | ||
spacing: Constants.spacing_m | ||
bottomMargin: 0 | ||
|
||
property bool autoScroll: true | ||
property real scrollThreshold: 50 // pixels from bottom | ||
property int lastContentY: 0 | ||
property int lastContentHeight: 0 | ||
|
||
onContentHeightChanged: { | ||
// If content height increased and we were at bottom, maintain bottom position | ||
if (contentHeight > lastContentHeight && autoScroll) { | ||
scrollToBottom() | ||
} | ||
lastContentHeight = contentHeight | ||
} | ||
|
||
onContentYChanged: { | ||
// Update autoScroll based on user's scroll position | ||
if (contentHeight > height) { | ||
autoScroll = contentHeight - (contentY + height) < scrollThreshold | ||
} | ||
lastContentY = contentY | ||
} | ||
|
||
function scrollToBottom() { | ||
Qt.callLater(() => { | ||
positionViewAtEnd() | ||
autoScroll = true // Ensure autoScroll is enabled after manual scroll | ||
}) | ||
} | ||
|
||
Component.onCompleted: { | ||
// Initial scroll to bottom when view is created | ||
Qt.callLater(() => { | ||
scrollToBottom() | ||
}) | ||
} | ||
|
||
onModelChanged: { | ||
if (model) { | ||
scrollToBottom() | ||
} | ||
} | ||
|
||
ScrollBar.vertical: ScrollBar { | ||
active: true | ||
interactive: true | ||
policy: ScrollBar.AlwaysOn | ||
|
||
contentItem: Rectangle { | ||
implicitWidth: 6 | ||
radius: width / 2 | ||
color: parent.pressed ? Material.scrollBarPressedColor : | ||
parent.hovered ? Material.scrollBarHoveredColor : | ||
Material.scrollBarColor | ||
opacity: parent.active ? 1 : 0 | ||
|
||
Behavior on opacity { | ||
NumberAnimation { duration: 150 } | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
module Components | ||
AlertManager 1.0 AlertManager.ui.qml | ||
FutrInput 1.0 FutrInput.ui.qml | ||
FutrCard 1.0 FutrCard.ui.qml | ||
MessageInput 1.0 MessageInput.ui.qml | ||
PostContent 1.0 PostContent.ui.qml | ||
PostDelegate 1.0 PostDelegate.ui.qml | ||
ProfilePicture 1.0 ProfilePicture.ui.qml | ||
PublishAlert 1.0 PublishAlert.ui.qml | ||
RelayStatusIcon 1.0 RelayStatusIcon.ui.qml | ||
ScrollingListView 1.0 ScrollingListView.ui.qml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.