From c53aa5ffa910b461eb45737b74deffabd3896e21 Mon Sep 17 00:00:00 2001 From: miruka Date: Fri, 10 Jul 2020 16:44:08 -0400 Subject: [PATCH] Add presence details to member profile --- TODO.md | 4 + .../RoomPane/MemberView/MemberProfile.qml | 82 +++++++++++++++++-- src/gui/Utils.qml | 35 ++++++-- 3 files changed, 107 insertions(+), 14 deletions(-) diff --git a/TODO.md b/TODO.md index 023364ec..ae41ab47 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,9 @@ # TODO +- profile max avatar width +- retrieve last seen time for offline members on hover/in profile +- auto-away after a configurable idle time +- status based on process detection - retry if media not found - fix members not synced bug - fix local unread counters order diff --git a/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml b/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml index f42dffe7..998afe67 100644 --- a/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml +++ b/src/gui/Pages/Chat/RoomPane/MemberView/MemberProfile.qml @@ -67,18 +67,86 @@ HListView { iconItem.small: true onClicked: profile.stackView.pop() } + } + HColumnLayout { // no spacing between these children + HLabel { + wrapMode: HLabel.Wrap + horizontalAlignment: Qt.AlignHCenter + color: utils.nameColor(member.display_name || member.id) + text: member.display_name.trim() || member.id + + Layout.fillWidth: true + } + + HLabel { + wrapMode: HLabel.Wrap + horizontalAlignment: Qt.AlignHCenter + color: theme.colors.dimText + text: member.id + visible: member.display_name.trim() !== "" + + Layout.fillWidth: true + } + } + + HColumnLayout { + HLabel { + wrapMode: HLabel.Wrap + horizontalAlignment: Qt.AlignHCenter + + text: + member.presence === "online" ? qsTr("Online") : + member.presence === "unavailable" ? qsTr("Unavailable") : + member.presence === "invisible" ? qsTr("Invisible") : + qsTr("Offline / Unknown") + + color: + member.presence === "online" ? + theme.colors.positiveText : + + member.presence === "unavailable" ? + theme.colors.warningText : + + theme.colors.halfDimText + + Layout.fillWidth: true + } + + HLabel { + wrapMode: HLabel.Wrap + horizontalAlignment: Qt.AlignHCenter + visible: ! member.currently_active && text !== "" + color: theme.colors.dimText + + Timer { + repeat: true + triggeredOnStart: true + + running: + ! member.currently_active && + member.last_active_at > new Date(1) + + interval: + new Date() - member.last_active_at < 60000 ? + 1000 : + 60000 + + onTriggered: parent.text = Qt.binding(() => + qsTr("Last seen %1 ago").arg(utils.formatRelativeTime( + new Date() - member.last_active_at, false, + )) + ) + } + + Layout.fillWidth: true + } } HLabel { - textFormat: HLabel.StyledText wrapMode: HLabel.Wrap - horizontalAlignment: Qt.AlignHCenter - text: - utils.coloredNameHtml(member.display_name, member.user_id) + - (member.display_name.trim() ? - `
${member.id}` : - "") + text: member.status_msg.trim() + visible: text !== "" Layout.fillWidth: true Layout.bottomMargin: theme.spacing diff --git a/src/gui/Utils.qml b/src/gui/Utils.qml index 4963b09d..1de9ab02 100644 --- a/src/gui/Utils.qml +++ b/src/gui/Utils.qml @@ -328,26 +328,47 @@ QtObject { } - function formatRelativeTime(milliseconds) { + function formatRelativeTime(milliseconds, shortForm=true) { const seconds = Math.floor(milliseconds / 1000) + if (shortForm) { + return ( + seconds < 60 ? + qsTr("%1s").arg(seconds) : + + seconds < 60 * 60 ? + qsTr("%1mn").arg(Math.floor(seconds / 60)) : + + seconds < 60 * 60 * 24 ? + qsTr("%1h").arg(Math.floor(seconds / 60 / 60)) : + + seconds < 60 * 60 * 24 * 30 ? + qsTr("%1d").arg(Math.floor(seconds / 60 / 60 / 24)) : + + seconds < 60 * 60 * 24 * 30 * 12 ? + qsTr("%1mo").arg(Math.floor(seconds / 60 / 60 / 24 / 30)) : + + qsTr("%1y").arg(Math.floor(seconds / 60 / 60 / 24 / 30 / 12)) + ) + } + return ( seconds < 60 ? - qsTr("%1s").arg(seconds) : + qsTr("%1 seconds").arg(seconds) : seconds < 60 * 60 ? - qsTr("%1mn").arg(Math.floor(seconds / 60)) : + qsTr("%1 minutes").arg(Math.floor(seconds / 60)) : seconds < 60 * 60 * 24 ? - qsTr("%1h").arg(Math.floor(seconds / 60 / 60)) : + qsTr("%1 hours").arg(Math.floor(seconds / 60 / 60)) : seconds < 60 * 60 * 24 * 30 ? - qsTr("%1d").arg(Math.floor(seconds / 60 / 60 / 24)) : + qsTr("%1 days").arg(Math.floor(seconds / 60 / 60 / 24)) : seconds < 60 * 60 * 24 * 30 * 12 ? - qsTr("%1mo").arg(Math.floor(seconds / 60 / 60 / 24 / 30)) : + qsTr("%1 months").arg(Math.floor(seconds / 60 / 60 / 24 / 30)) : - qsTr("%1y").arg(Math.floor(seconds / 60 / 60 / 24 / 30 / 12)) + qsTr("%1 years").arg(Math.floor(seconds / 60 / 60 / 24 / 30 / 12)) ) }