499 lines
18 KiB
QML
499 lines
18 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import QtGraphicalEffects 1.15
|
|
import QtQml.Models 2.15
|
|
|
|
import StatusQ.Controls 0.1
|
|
import StatusQ.Core 0.1
|
|
import StatusQ.Core.Backpressure 0.1
|
|
import StatusQ.Core.Theme 0.1
|
|
import StatusQ.Popups.Dialog 0.1
|
|
|
|
import shared 1.0
|
|
import shared.popups 1.0
|
|
import shared.views.chat 1.0
|
|
|
|
import utils 1.0
|
|
|
|
import AppLayouts.Chat.stores 1.0 as ChatStores
|
|
|
|
import "../views"
|
|
import "../panels"
|
|
import "../stores"
|
|
|
|
Popup {
|
|
id: root
|
|
|
|
property ActivityCenterStore activityCenterStore
|
|
property ChatStores.RootStore store
|
|
|
|
onOpened: {
|
|
Global.activityPopupOpened = true
|
|
}
|
|
onClosed: {
|
|
Global.activityPopupOpened = false
|
|
Qt.callLater(activityCenterStore.markAsSeenActivityCenterNotifications)
|
|
}
|
|
|
|
width: 560
|
|
padding: 0
|
|
modal: true
|
|
parent: Overlay.overlay
|
|
|
|
QtObject {
|
|
id: d
|
|
|
|
readonly property var loadMoreNotificationsIfScrollBelowThreshold: Backpressure.oneInTimeQueued(root, 100, function() {
|
|
if (listView.contentY >= listView.contentHeight - listView.height - 1) {
|
|
root.activityCenterStore.fetchActivityCenterNotifications()
|
|
}
|
|
})
|
|
}
|
|
|
|
Overlay.modal: MouseArea { // eat every event behind the popup
|
|
hoverEnabled: true
|
|
onPressed: (event) => {
|
|
event.accept()
|
|
root.close()
|
|
}
|
|
onWheel: (event) => event.accept()
|
|
}
|
|
|
|
background: Rectangle {
|
|
color: Style.current.background
|
|
radius: Style.current.radius
|
|
layer.enabled: true
|
|
layer.effect: DropShadow {
|
|
verticalOffset: 3
|
|
radius: Style.current.radius
|
|
samples: 15
|
|
fast: true
|
|
cached: true
|
|
color: Style.current.dropShadow
|
|
}
|
|
}
|
|
|
|
ActivityCenterPopupTopBarPanel {
|
|
id: activityCenterTopBar
|
|
width: parent.width
|
|
unreadNotificationsCount: activityCenterStore.unreadNotificationsCount
|
|
hasAdmin: activityCenterStore.adminCount > 0
|
|
hasReplies: activityCenterStore.repliesCount > 0
|
|
hasMentions: activityCenterStore.mentionsCount > 0
|
|
hasContactRequests: activityCenterStore.contactRequestsCount > 0
|
|
hasIdentityVerification: activityCenterStore.identityVerificationCount > 0
|
|
hasMembership: activityCenterStore.membershipCount > 0
|
|
hideReadNotifications: activityCenterStore.activityCenterReadType === ActivityCenterStore.ActivityCenterReadType.Unread
|
|
activeGroup: activityCenterStore.activeNotificationGroup
|
|
onGroupTriggered: activityCenterStore.setActiveNotificationGroup(group)
|
|
onMarkAllReadClicked: activityCenterStore.markAllActivityCenterNotificationsRead()
|
|
onShowHideReadNotifications: activityCenterStore.setActivityCenterReadType(hideReadNotifications ?
|
|
ActivityCenterStore.ActivityCenterReadType.Unread :
|
|
ActivityCenterStore.ActivityCenterReadType.All)
|
|
}
|
|
|
|
StatusListView {
|
|
id: listView
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: activityCenterTopBar.bottom
|
|
anchors.bottom: parent.bottom
|
|
anchors.margins: Style.current.smallPadding
|
|
spacing: 1
|
|
|
|
model: root.activityCenterStore.activityCenterNotifications
|
|
|
|
onContentYChanged: d.loadMoreNotificationsIfScrollBelowThreshold()
|
|
|
|
delegate: Loader {
|
|
width: listView.availableWidth
|
|
|
|
property int filteredIndex: index
|
|
property var notification: model
|
|
|
|
sourceComponent: {
|
|
switch (model.notificationType) {
|
|
case ActivityCenterStore.ActivityCenterNotificationType.Mention:
|
|
return mentionNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.Reply:
|
|
return replyNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ContactRequest:
|
|
return contactRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ContactVerification:
|
|
return verificationRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityInvitation:
|
|
return communityInvitationNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityMembershipRequest:
|
|
return membershipRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityRequest:
|
|
return communityRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityKicked:
|
|
return communityKickedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ContactRemoved:
|
|
return contactRemovedComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewKeypairAddedToPairedDevice:
|
|
return newKeypairFromPairedDeviceComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityTokenReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.FirstCommunityTokenReceived:
|
|
return communityTokenReceivedComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnerTokenReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipLost:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipFailed:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipDeclined:
|
|
return ownerTokenReceivedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ShareAccounts:
|
|
return shareAccountsNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityBanned:
|
|
return communityBannedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityUnbanned:
|
|
return communityUnbannedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewPrivateGroupChat:
|
|
return groupChatInvitationNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewInstallationReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewInstallationCreated:
|
|
return newDeviceDetectedComponent
|
|
default:
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: mentionNotificationComponent
|
|
|
|
ActivityNotificationMention {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: replyNotificationComponent
|
|
|
|
ActivityNotificationReply {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: contactRequestNotificationComponent
|
|
|
|
ActivityNotificationContactRequest {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: verificationRequestNotificationComponent
|
|
|
|
ActivityNotificationContactVerification {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: communityInvitationNotificationComponent
|
|
|
|
ActivityNotificationCommunityInvitation {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: membershipRequestNotificationComponent
|
|
|
|
ActivityNotificationCommunityMembershipRequest {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: communityRequestNotificationComponent
|
|
|
|
ActivityNotificationCommunityRequest {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: communityKickedNotificationComponent
|
|
|
|
ActivityNotificationCommunityKicked {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityBannedNotificationComponent
|
|
|
|
ActivityNotificationCommunityBanUnban {
|
|
banned: true
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityUnbannedNotificationComponent
|
|
|
|
ActivityNotificationCommunityBanUnban {
|
|
banned: false
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: contactRemovedComponent
|
|
|
|
ActivityNotificationContactRemoved {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: newKeypairFromPairedDeviceComponent
|
|
|
|
ActivityNotificationNewKeypairFromPairedDevice {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: ownerTokenReceivedNotificationComponent
|
|
|
|
ActivityNotificationTransferOwnership {
|
|
|
|
readonly property var community : notification ? root.store.getCommunityDetailsAsJson(notification.communityId) : null
|
|
|
|
type: setType(notification)
|
|
|
|
communityName: community ? community.name : ""
|
|
communityColor: community ? community.color : Theme.palette.directColor1
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
|
|
onFinaliseOwnershipClicked: Global.openFinaliseOwnershipPopup(notification.communityId)
|
|
onNavigateToCommunityClicked: root.store.setActiveCommunity(notification.communityId)
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: newDeviceDetectedComponent
|
|
|
|
ActivityNotificationNewDevice {
|
|
type: setType(notification)
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
accountName: store.name
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
onMoreDetailsClicked: {
|
|
switch (type) {
|
|
case ActivityNotificationNewDevice.InstallationType.Received:
|
|
Global.openPopup(pairDeviceDialog, {
|
|
name: store.name,
|
|
deviceId: notification.installationId
|
|
});
|
|
break;
|
|
case ActivityNotificationNewDevice.InstallationType.Created:
|
|
Global.openPopup(checkOtherDeviceDialog, {
|
|
deviceId: notification.installationId
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityTokenReceivedComponent
|
|
|
|
ActivityNotificationCommunityTokenReceived {
|
|
|
|
readonly property var community : notification ? root.store.getCommunityDetailsAsJson(notification.communityId) : null
|
|
|
|
communityId: notification.communityId
|
|
communityName: community ? community.name : ""
|
|
communityImage: community ? community.image : ""
|
|
|
|
store: root.store
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: shareAccountsNotificationComponent
|
|
|
|
ActivityNotificationCommunityShareAddresses {
|
|
|
|
readonly property var community : notification ? root.store.getCommunityDetailsAsJson(notification.communityId) : null
|
|
|
|
communityName: community ? community.name : ""
|
|
communityColor: community ? community.color : "transparent"
|
|
communityImage: community ? community.image : ""
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
|
|
onOpenShareAccountsClicked: {
|
|
Global.communityShareAddressesPopupRequested(notification.communityId, communityName, communityImage)
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: groupChatInvitationNotificationComponent
|
|
|
|
ActivityNotificationUnknownGroupChatInvitation {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
function truncateDeviceId(deviceId) {
|
|
return deviceId.substring(0, 7).toUpperCase()
|
|
}
|
|
|
|
Component {
|
|
id: pairDeviceDialog
|
|
|
|
StatusDialog {
|
|
property string name
|
|
property string deviceId
|
|
|
|
width: 480
|
|
closePolicy: Popup.CloseOnPressOutside
|
|
destroyOnClose: true
|
|
|
|
title: qsTr("Pair new device and sync profile")
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 16
|
|
StatusBaseText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("New device with %1 profile has been detected. You can see the device ID below and on your other device. Only confirm the request if the device ID matches.")
|
|
.arg(name)
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
StatusBaseText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
font.pixelSize: 27
|
|
font.weight: Font.Medium
|
|
font.letterSpacing: 5
|
|
text: truncateDeviceId(deviceId)
|
|
}
|
|
}
|
|
|
|
footer: StatusDialogFooter {
|
|
leftButtons: ObjectModel {
|
|
StatusFlatButton {
|
|
text: qsTr("Cancel")
|
|
onClicked: {
|
|
close()
|
|
}
|
|
}
|
|
}
|
|
rightButtons: ObjectModel {
|
|
StatusButton {
|
|
text: qsTr("Pair and Sync")
|
|
onClicked: {
|
|
activityCenterStore.enableInstallationAndSync(deviceId)
|
|
close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: checkOtherDeviceDialog
|
|
|
|
StatusDialog {
|
|
property string deviceId
|
|
|
|
width: 480
|
|
closePolicy: Popup.CloseOnPressOutside
|
|
destroyOnClose: true
|
|
|
|
title: qsTr("Pair this device and sync profile")
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 16
|
|
StatusBaseText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Check your other device for a pairing request. Ensure that the this device ID displayed on your other device. Only proceed with pairing and syncing if the IDs are identical.")
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
StatusBaseText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
font.pixelSize: 27
|
|
font.weight: Font.Medium
|
|
font.letterSpacing: 5
|
|
text: truncateDeviceId(deviceId)
|
|
}
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
footer: null
|
|
}
|
|
}
|
|
}
|