2021-03-05 02:35:15 +03:00
|
|
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
2021-03-14 04:45:20 +03:00
|
|
|
//
|
2021-03-05 02:35:15 +03:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
2020-10-08 22:11:21 +03:00
|
|
|
import "./delegates"
|
|
|
|
import "./device-verification"
|
|
|
|
import "./emoji"
|
2020-12-17 19:25:32 +03:00
|
|
|
import "./voip"
|
2021-03-15 00:22:52 +03:00
|
|
|
import Qt.labs.platform 1.1 as Platform
|
2020-10-08 22:11:21 +03:00
|
|
|
import QtGraphicalEffects 1.0
|
2021-01-12 17:03:39 +03:00
|
|
|
import QtQuick 2.9
|
2020-02-02 02:27:28 +03:00
|
|
|
import QtQuick.Controls 2.3
|
2021-01-12 17:03:39 +03:00
|
|
|
import QtQuick.Layouts 1.3
|
|
|
|
import QtQuick.Window 2.2
|
2019-11-30 03:43:39 +03:00
|
|
|
import im.nheko 1.0
|
2020-05-14 03:19:15 +03:00
|
|
|
import im.nheko.EmojiModel 1.0
|
2019-09-03 00:28:05 +03:00
|
|
|
|
2020-03-28 21:12:00 +03:00
|
|
|
Page {
|
2020-10-08 22:11:21 +03:00
|
|
|
id: timelineRoot
|
|
|
|
|
|
|
|
property var colors: currentActivePalette
|
|
|
|
property var systemInactive
|
|
|
|
property var inactiveColors: currentInactivePalette ? currentInactivePalette : systemInactive
|
2021-03-14 18:24:04 +03:00
|
|
|
readonly property int avatarSize: 40
|
2020-10-08 22:11:21 +03:00
|
|
|
property real highlightHue: colors.highlight.hslHue
|
|
|
|
property real highlightSat: colors.highlight.hslSaturation
|
|
|
|
property real highlightLight: colors.highlight.hslLightness
|
|
|
|
|
|
|
|
palette: colors
|
|
|
|
|
|
|
|
FontMetrics {
|
|
|
|
id: fontMetrics
|
|
|
|
}
|
|
|
|
|
|
|
|
EmojiPicker {
|
|
|
|
id: emojiPopup
|
|
|
|
|
|
|
|
colors: palette
|
2021-04-18 21:21:03 +03:00
|
|
|
model: TimelineManager.completerFor("allemoji", "")
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2020-10-26 16:57:54 +03:00
|
|
|
Component {
|
|
|
|
id: userProfileComponent
|
|
|
|
|
|
|
|
UserProfile {
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-02-09 20:41:39 +03:00
|
|
|
Component {
|
|
|
|
id: roomSettingsComponent
|
|
|
|
|
|
|
|
RoomSettings {
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-01-12 22:22:52 +03:00
|
|
|
Component {
|
|
|
|
id: mobileCallInviteDialog
|
|
|
|
|
|
|
|
CallInvite {
|
|
|
|
}
|
2021-01-17 06:05:02 +03:00
|
|
|
|
2021-01-12 22:22:52 +03:00
|
|
|
}
|
|
|
|
|
2021-02-21 20:40:21 +03:00
|
|
|
Component {
|
|
|
|
id: quickSwitcherComponent
|
|
|
|
|
|
|
|
QuickSwitcher {
|
|
|
|
}
|
2021-03-14 03:24:26 +03:00
|
|
|
|
2021-02-21 20:40:21 +03:00
|
|
|
}
|
|
|
|
|
2021-04-11 17:31:49 +03:00
|
|
|
Component {
|
2021-04-13 20:01:49 +03:00
|
|
|
id: forwardCompleterComponent
|
2021-04-11 17:31:49 +03:00
|
|
|
|
2021-04-13 20:01:49 +03:00
|
|
|
ForwardCompleter {
|
2021-04-11 17:31:49 +03:00
|
|
|
}
|
2021-04-27 12:08:21 +03:00
|
|
|
|
2021-04-11 17:31:49 +03:00
|
|
|
}
|
|
|
|
|
2021-02-21 20:40:21 +03:00
|
|
|
Shortcut {
|
2021-02-24 17:20:36 +03:00
|
|
|
sequence: "Ctrl+K"
|
2021-02-21 20:40:21 +03:00
|
|
|
onActivated: {
|
|
|
|
var quickSwitch = quickSwitcherComponent.createObject(timelineRoot);
|
2021-03-14 03:24:26 +03:00
|
|
|
TimelineManager.focusTimeline();
|
2021-02-21 20:40:21 +03:00
|
|
|
quickSwitch.open();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.Menu {
|
2020-10-08 22:11:21 +03:00
|
|
|
id: messageContextMenu
|
|
|
|
|
|
|
|
property string eventId
|
2021-04-30 00:09:13 +03:00
|
|
|
property string link
|
2021-04-30 00:38:45 +03:00
|
|
|
property string text
|
2020-10-08 22:11:21 +03:00
|
|
|
property int eventType
|
|
|
|
property bool isEncrypted
|
2021-04-11 23:24:39 +03:00
|
|
|
property bool isEditable
|
2020-10-08 22:11:21 +03:00
|
|
|
|
2021-04-30 00:38:45 +03:00
|
|
|
function show(eventId_, eventType_, isEncrypted_, isEditable_, link_, text_, showAt_) {
|
2020-10-08 22:11:21 +03:00
|
|
|
eventId = eventId_;
|
|
|
|
eventType = eventType_;
|
|
|
|
isEncrypted = isEncrypted_;
|
2021-04-11 23:24:39 +03:00
|
|
|
isEditable = isEditable_;
|
2021-04-30 00:38:45 +03:00
|
|
|
if (text_)
|
|
|
|
text = text_;
|
|
|
|
else
|
|
|
|
text = "";
|
2021-04-30 00:09:13 +03:00
|
|
|
if (link_)
|
|
|
|
link = link_;
|
|
|
|
else
|
|
|
|
link = "";
|
2021-03-15 00:22:52 +03:00
|
|
|
if (showAt_)
|
|
|
|
open(showAt_);
|
|
|
|
else
|
|
|
|
open();
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-04-30 00:38:45 +03:00
|
|
|
Platform.MenuItem {
|
|
|
|
visible: messageContextMenu.text
|
|
|
|
enabled: visible
|
|
|
|
text: qsTr("Copy")
|
|
|
|
onTriggered: Clipboard.text = messageContextMenu.text
|
|
|
|
}
|
|
|
|
|
2021-04-30 00:09:13 +03:00
|
|
|
Platform.MenuItem {
|
|
|
|
visible: messageContextMenu.link
|
|
|
|
enabled: visible
|
2021-04-30 01:10:14 +03:00
|
|
|
text: qsTr("Copy link location")
|
2021-04-30 00:09:13 +03:00
|
|
|
onTriggered: Clipboard.text = messageContextMenu.link
|
|
|
|
}
|
|
|
|
|
2021-04-11 23:24:39 +03:00
|
|
|
Platform.MenuItem {
|
|
|
|
id: reactionOption
|
|
|
|
|
2020-10-08 22:11:21 +03:00
|
|
|
text: qsTr("React")
|
2021-03-23 20:05:43 +03:00
|
|
|
onTriggered: emojiPopup.show(null, function(emoji) {
|
2020-11-16 20:41:29 +03:00
|
|
|
TimelineManager.queueReactionMessage(messageContextMenu.eventId, emoji);
|
|
|
|
})
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2020-10-08 22:11:21 +03:00
|
|
|
text: qsTr("Reply")
|
2021-03-15 00:22:52 +03:00
|
|
|
onTriggered: TimelineManager.timeline.replyAction(messageContextMenu.eventId)
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2021-02-10 16:32:16 +03:00
|
|
|
visible: messageContextMenu.isEditable
|
2021-03-15 00:22:52 +03:00
|
|
|
enabled: visible
|
2021-02-02 20:54:45 +03:00
|
|
|
text: qsTr("Edit")
|
2021-03-15 00:22:52 +03:00
|
|
|
onTriggered: TimelineManager.timeline.editAction(messageContextMenu.eventId)
|
2021-02-02 20:54:45 +03:00
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2020-10-08 22:11:21 +03:00
|
|
|
text: qsTr("Read receipts")
|
2020-10-26 23:44:31 +03:00
|
|
|
onTriggered: TimelineManager.timeline.readReceiptsAction(messageContextMenu.eventId)
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-04-11 17:31:49 +03:00
|
|
|
Platform.MenuItem {
|
2021-04-27 12:08:21 +03:00
|
|
|
visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker || messageContextMenu.eventType == MtxEvent.TextMessage || messageContextMenu.eventType == MtxEvent.LocationMessage || messageContextMenu.eventType == MtxEvent.EmoteMessage || messageContextMenu.eventType == MtxEvent.NoticeMessage
|
2021-04-11 17:31:49 +03:00
|
|
|
text: qsTr("Forward")
|
|
|
|
onTriggered: {
|
2021-04-13 20:01:49 +03:00
|
|
|
var forwardMess = forwardCompleterComponent.createObject(timelineRoot);
|
2021-04-15 18:44:58 +03:00
|
|
|
forwardMess.setMessageEventId(messageContextMenu.eventId);
|
2021-04-11 17:31:49 +03:00
|
|
|
forwardMess.open();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2020-10-08 22:11:21 +03:00
|
|
|
text: qsTr("Mark as read")
|
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2020-10-08 22:11:21 +03:00
|
|
|
text: qsTr("View raw message")
|
2020-10-26 23:44:31 +03:00
|
|
|
onTriggered: TimelineManager.timeline.viewRawMessage(messageContextMenu.eventId)
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2020-11-25 19:38:06 +03:00
|
|
|
// TODO(Nico): Fix this still being iterated over, when using keyboard to select options
|
2020-10-08 22:11:21 +03:00
|
|
|
visible: messageContextMenu.isEncrypted
|
2021-03-15 00:22:52 +03:00
|
|
|
enabled: visible
|
2020-10-08 22:11:21 +03:00
|
|
|
text: qsTr("View decrypted raw message")
|
2020-10-26 23:44:31 +03:00
|
|
|
onTriggered: TimelineManager.timeline.viewDecryptedRawMessage(messageContextMenu.eventId)
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2020-11-26 11:50:37 +03:00
|
|
|
text: qsTr("Remove message")
|
2020-10-26 23:44:31 +03:00
|
|
|
onTriggered: TimelineManager.timeline.redactEvent(messageContextMenu.eventId)
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2020-10-08 22:11:21 +03:00
|
|
|
visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker
|
2021-03-15 00:22:52 +03:00
|
|
|
enabled: visible
|
2020-10-08 22:11:21 +03:00
|
|
|
text: qsTr("Save as")
|
|
|
|
onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId)
|
|
|
|
}
|
|
|
|
|
2021-03-15 00:22:52 +03:00
|
|
|
Platform.MenuItem {
|
2021-01-24 03:29:30 +03:00
|
|
|
visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker
|
2021-03-15 00:22:52 +03:00
|
|
|
enabled: visible
|
2021-01-24 03:29:30 +03:00
|
|
|
text: qsTr("Open in external program")
|
|
|
|
onTriggered: TimelineManager.timeline.openMedia(messageContextMenu.eventId)
|
2021-04-30 00:09:13 +03:00
|
|
|
}
|
2021-04-29 22:46:49 +03:00
|
|
|
|
|
|
|
Platform.MenuItem {
|
|
|
|
visible: messageContextMenu.eventId
|
|
|
|
enabled: visible
|
|
|
|
text: qsTr("Copy link to event")
|
|
|
|
onTriggered: TimelineManager.timeline.copyLinkToEvent(messageContextMenu.eventId)
|
2021-01-24 03:29:30 +03:00
|
|
|
}
|
2020-10-08 22:11:21 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
anchors.fill: parent
|
|
|
|
color: colors.window
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: deviceVerificationDialog
|
|
|
|
|
|
|
|
DeviceVerification {
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Connections {
|
2020-11-15 00:38:17 +03:00
|
|
|
target: TimelineManager
|
|
|
|
onNewDeviceVerificationRequest: {
|
2020-10-08 22:11:21 +03:00
|
|
|
var dialog = deviceVerificationDialog.createObject(timelineRoot, {
|
|
|
|
"flow": flow
|
|
|
|
});
|
|
|
|
dialog.show();
|
|
|
|
}
|
2020-11-15 00:38:17 +03:00
|
|
|
onOpenProfile: {
|
2020-10-08 22:11:21 +03:00
|
|
|
var userProfile = userProfileComponent.createObject(timelineRoot, {
|
|
|
|
"profile": profile
|
|
|
|
});
|
|
|
|
userProfile.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-09 20:41:39 +03:00
|
|
|
Connections {
|
2021-02-11 21:20:45 +03:00
|
|
|
target: TimelineManager.timeline
|
2021-02-09 20:41:39 +03:00
|
|
|
onOpenRoomSettingsDialog: {
|
2021-02-10 18:52:42 +03:00
|
|
|
var roomSettings = roomSettingsComponent.createObject(timelineRoot, {
|
2021-02-11 17:24:09 +03:00
|
|
|
"roomSettings": settings
|
2021-02-10 18:52:42 +03:00
|
|
|
});
|
2021-02-09 20:41:39 +03:00
|
|
|
roomSettings.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-12 22:22:52 +03:00
|
|
|
Connections {
|
|
|
|
target: CallManager
|
|
|
|
onNewInviteState: {
|
|
|
|
if (CallManager.haveCallInvite && Settings.mobileMode) {
|
|
|
|
var dialog = mobileCallInviteDialog.createObject(msgView);
|
|
|
|
dialog.open();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-08 22:11:21 +03:00
|
|
|
Label {
|
|
|
|
visible: !TimelineManager.timeline && !TimelineManager.isInitialSync
|
|
|
|
anchors.centerIn: parent
|
|
|
|
text: qsTr("No room open")
|
|
|
|
font.pointSize: 24
|
|
|
|
color: colors.text
|
|
|
|
}
|
|
|
|
|
|
|
|
BusyIndicator {
|
|
|
|
visible: running
|
|
|
|
anchors.centerIn: parent
|
|
|
|
running: TimelineManager.isInitialSync
|
|
|
|
height: 200
|
|
|
|
width: 200
|
|
|
|
z: 3
|
|
|
|
}
|
|
|
|
|
|
|
|
ColumnLayout {
|
2021-01-26 07:46:55 +03:00
|
|
|
id: timelineLayout
|
2021-01-26 08:03:09 +03:00
|
|
|
|
2020-10-18 23:30:42 +03:00
|
|
|
visible: TimelineManager.timeline != null
|
2020-10-08 22:11:21 +03:00
|
|
|
anchors.fill: parent
|
2020-10-26 15:50:44 +03:00
|
|
|
spacing: 0
|
2020-10-08 22:11:21 +03:00
|
|
|
|
2020-10-26 16:57:54 +03:00
|
|
|
TopBar {
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2020-10-26 15:50:44 +03:00
|
|
|
Rectangle {
|
2020-10-08 22:11:21 +03:00
|
|
|
Layout.fillWidth: true
|
2020-10-26 15:50:44 +03:00
|
|
|
height: 1
|
2020-10-08 22:11:21 +03:00
|
|
|
z: 3
|
2020-10-26 15:50:44 +03:00
|
|
|
color: colors.mid
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2020-10-26 15:50:44 +03:00
|
|
|
Rectangle {
|
2021-01-12 22:22:52 +03:00
|
|
|
id: msgView
|
2021-01-17 06:05:02 +03:00
|
|
|
|
2020-10-08 22:11:21 +03:00
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
2020-10-26 15:50:44 +03:00
|
|
|
color: colors.base
|
2020-10-27 20:14:06 +03:00
|
|
|
|
2020-10-26 16:57:54 +03:00
|
|
|
ColumnLayout {
|
2020-10-26 15:50:44 +03:00
|
|
|
anchors.fill: parent
|
2020-10-26 16:57:54 +03:00
|
|
|
spacing: 0
|
2020-10-27 20:14:06 +03:00
|
|
|
|
2020-10-27 22:29:53 +03:00
|
|
|
StackLayout {
|
|
|
|
id: stackLayout
|
2020-11-15 06:52:49 +03:00
|
|
|
|
2020-10-27 22:29:53 +03:00
|
|
|
currentIndex: 0
|
2020-10-08 22:11:21 +03:00
|
|
|
|
2020-10-27 22:29:53 +03:00
|
|
|
Connections {
|
|
|
|
function onActiveTimelineChanged() {
|
|
|
|
stackLayout.currentIndex = 0;
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
2020-11-15 06:52:49 +03:00
|
|
|
|
|
|
|
target: TimelineManager
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2020-10-27 22:29:53 +03:00
|
|
|
MessageView {
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2020-10-27 22:29:53 +03:00
|
|
|
Loader {
|
2021-02-22 00:30:10 +03:00
|
|
|
source: CallManager.isOnCall && CallManager.callType != CallType.VOICE ? "voip/VideoCall.qml" : ""
|
2020-10-27 22:29:53 +03:00
|
|
|
onLoaded: TimelineManager.setVideoCallItem()
|
2020-10-27 20:14:06 +03:00
|
|
|
}
|
2020-11-15 06:52:49 +03:00
|
|
|
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2020-10-26 16:57:54 +03:00
|
|
|
TypingIndicator {
|
2020-10-27 20:14:06 +03:00
|
|
|
}
|
2020-10-08 22:11:21 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-12-17 19:25:32 +03:00
|
|
|
CallInviteBar {
|
|
|
|
id: callInviteBar
|
2021-01-12 01:51:39 +03:00
|
|
|
|
2020-12-17 19:25:32 +03:00
|
|
|
Layout.fillWidth: true
|
|
|
|
z: 3
|
|
|
|
}
|
|
|
|
|
2020-10-08 22:11:21 +03:00
|
|
|
ActiveCallBar {
|
|
|
|
Layout.fillWidth: true
|
|
|
|
z: 3
|
|
|
|
}
|
|
|
|
|
2020-10-26 15:50:44 +03:00
|
|
|
Rectangle {
|
2020-10-08 22:11:21 +03:00
|
|
|
Layout.fillWidth: true
|
|
|
|
z: 3
|
2020-10-26 15:50:44 +03:00
|
|
|
height: 1
|
|
|
|
color: colors.mid
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2020-10-26 16:57:54 +03:00
|
|
|
ReplyPopup {
|
|
|
|
}
|
2020-10-26 15:50:44 +03:00
|
|
|
|
2020-11-01 01:24:07 +03:00
|
|
|
MessageInput {
|
|
|
|
}
|
2021-02-03 05:12:08 +03:00
|
|
|
|
2021-02-03 03:30:03 +03:00
|
|
|
}
|
2020-10-26 15:50:44 +03:00
|
|
|
|
2021-02-03 03:30:03 +03:00
|
|
|
NhekoDropArea {
|
2021-02-03 05:12:08 +03:00
|
|
|
anchors.fill: parent
|
2021-02-03 03:30:03 +03:00
|
|
|
roomid: TimelineManager.timeline ? TimelineManager.timeline.roomId() : ""
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
2021-02-03 05:12:08 +03:00
|
|
|
}
|
2021-01-26 07:46:55 +03:00
|
|
|
|
2021-02-03 05:12:08 +03:00
|
|
|
PrivacyScreen {
|
|
|
|
anchors.fill: parent
|
|
|
|
visible: Settings.privacyScreen
|
|
|
|
screenTimeout: Settings.privacyScreenTimeout
|
|
|
|
timelineRoot: timelineLayout
|
2020-10-08 22:11:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
systemInactive: SystemPalette {
|
|
|
|
colorGroup: SystemPalette.Disabled
|
|
|
|
}
|
|
|
|
|
2019-08-30 20:29:25 +03:00
|
|
|
}
|