Move to automatic type registration

pull/1500/head
Nicolas Werner 1 year ago
parent 2cb04fd741
commit ce1a64bc19
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
  1. 136
      CMakeLists.txt
  2. 2
      resources/qml/Avatar.qml
  3. 2
      resources/qml/ImageButton.qml
  4. 2
      resources/qml/MatrixText.qml
  5. 4
      resources/qml/MessageView.qml
  6. 8
      resources/qml/Root.qml
  7. 2
      resources/qml/TimelineRow.qml
  8. 19
      resources/qml/TimelineView.qml
  9. 2
      resources/qml/TopBar.qml
  10. 2
      resources/qml/components/AdaptiveLayout.qml
  11. 2
      resources/qml/components/TextButton.qml
  12. 2
      resources/qml/delegates/FileMessage.qml
  13. 2
      resources/qml/delegates/Reply.qml
  14. 2
      resources/qml/delegates/TextMessage.qml
  15. 2
      resources/qml/dialogs/InviteDialog.qml
  16. 2
      resources/qml/dialogs/ReadReceipts.qml
  17. 2
      resources/qml/dialogs/RoomMembers.qml
  18. 2
      resources/qml/dialogs/RoomSettings.qml
  19. 1
      resources/qml/emoji/StickerPicker.qml
  20. 2
      resources/qml/ui/animations/qmldir
  21. 3
      resources/qml/ui/media/qmldir
  22. 4
      resources/qml/ui/qmldir
  23. 24
      resources/qml/voip/ActiveCallBar.qml
  24. 2
      resources/qml/voip/CallDevices.qml
  25. 8
      resources/qml/voip/CallInvite.qml
  26. 8
      resources/qml/voip/CallInviteBar.qml
  27. 4
      resources/qml/voip/PlaceCall.qml
  28. 8
      resources/qml/voip/ScreenShare.qml
  29. 100
      resources/res.qrc
  30. 4
      src/AliasEditModel.h
  31. 3
      src/CacheCryptoStructs.h
  32. 4
      src/Clipboard.h
  33. 8
      src/LoginPage.h
  34. 215
      src/MainWindow.cpp
  35. 25
      src/MainWindow.h
  36. 4
      src/PowerlevelsEditModels.h
  37. 4
      src/ReadReceiptsModel.h
  38. 2
      src/RegisterPage.h
  39. 2
      src/RoomDirectoryModel.h
  40. 2
      src/UserDirectoryModel.h
  41. 24
      src/UserSettingsPage.h
  42. 3
      src/encryption/Olm.h
  43. 5
      src/encryption/SelfVerificationStatus.cpp
  44. 4
      src/encryption/SelfVerificationStatus.h
  45. 1
      src/encryption/VerificationManager.cpp
  46. 27
      src/encryption/VerificationManager.h
  47. 2
      src/main.cpp
  48. 1
      src/timeline/CommunitiesModel.cpp
  49. 28
      src/timeline/CommunitiesModel.h
  50. 2
      src/timeline/DelegateChooser.h
  51. 6
      src/timeline/InputBar.h
  52. 27
      src/timeline/PresenceEmitter.h
  53. 2
      src/timeline/RoomlistModel.cpp
  54. 26
      src/timeline/RoomlistModel.h
  55. 2
      src/timeline/TimelineFilter.h
  56. 5
      src/timeline/TimelineModel.h
  57. 20
      src/timeline/TimelineViewManager.cpp
  58. 25
      src/timeline/TimelineViewManager.h
  59. 2
      src/ui/HiddenEvents.h
  60. 1
      src/ui/MxcAnimatedImage.h
  61. 3
      src/ui/MxcMediaProxy.h
  62. 2
      src/ui/NhekoCursorShape.h
  63. 1
      src/ui/NhekoDropArea.h
  64. 60
      src/ui/NhekoEventObserver.cpp
  65. 27
      src/ui/NhekoEventObserver.h
  66. 4
      src/ui/NhekoGlobalObject.h
  67. 4
      src/ui/RoomSummary.h
  68. 22
      src/ui/UIA.h
  69. 2
      src/ui/UserProfile.h
  70. 21
      src/voip/CallManager.cpp
  71. 7
      src/voip/CallManager.h
  72. 40
      src/voip/WebRTCSession.cpp
  73. 2
      src/voip/WebRTCSession.h

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 3.13..3.21)
option(APPVEYOR_BUILD "Build on appveyor" OFF)
option(CI_BUILD "Set when building in CI. Enables -Werror where possible" OFF)
@ -395,8 +395,6 @@ set(SRC_FILES
src/ui/NhekoCursorShape.h
src/ui/NhekoDropArea.cpp
src/ui/NhekoDropArea.h
src/ui/NhekoEventObserver.cpp
src/ui/NhekoEventObserver.h
src/ui/NhekoGlobalObject.cpp
src/ui/NhekoGlobalObject.h
src/ui/RoomSettings.cpp
@ -499,8 +497,6 @@ set(SRC_FILES
src/SingleImagePackModel.h
src/TrayIcon.cpp
src/TrayIcon.h
src/UserDirectoryModel.cpp
src/UserDirectoryModel.h
src/UserSettingsPage.cpp
src/UserSettingsPage.h
src/UsersModel.cpp
@ -679,10 +675,10 @@ if(ASAN)
endif()
if(WIN32)
add_executable (nheko WIN32 ${OS_BUNDLE} ${NHEKO_DEPS})
qt_add_executable (nheko WIN32 ${OS_BUNDLE} ${NHEKO_DEPS})
target_compile_definitions(nheko PRIVATE _WIN32_WINNT=0x0601 NOMINMAX WIN32_LEAN_AND_MEAN STRICT)
else()
add_executable (nheko ${OS_BUNDLE} ${NHEKO_DEPS})
qt_add_executable (nheko ${OS_BUNDLE} ${NHEKO_DEPS})
if (HAVE_BACKTRACE_SYMBOLS_FD AND NOT CMAKE_BUILD_TYPE STREQUAL "Release")
set_target_properties(nheko PROPERTIES ENABLE_EXPORTS ON)
@ -700,6 +696,130 @@ set_target_properties(nheko
file(GLOB LANG_TS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/resources/langs/*.ts")
qt_add_translations(nheko RESOURCE_PREFIX "/translations" TS_FILES ${LANG_TS_SRC})
#
# Add qml files
#
set(QML_SOURCES
resources/qml/Root.qml
resources/qml/ChatPage.qml
resources/qml/CommunitiesList.qml
resources/qml/RoomList.qml
resources/qml/TimelineView.qml
resources/qml/Avatar.qml
resources/qml/Completer.qml
resources/qml/EncryptionIndicator.qml
resources/qml/ImageButton.qml
resources/qml/ElidedLabel.qml
resources/qml/MatrixText.qml
resources/qml/MatrixTextField.qml
resources/qml/ToggleButton.qml
resources/qml/UploadBox.qml
resources/qml/MessageInput.qml
resources/qml/MessageView.qml
resources/qml/PrivacyScreen.qml
resources/qml/Reactions.qml
resources/qml/ReplyPopup.qml
resources/qml/StatusIndicator.qml
resources/qml/TimelineRow.qml
resources/qml/TopBar.qml
resources/qml/QuickSwitcher.qml
resources/qml/ForwardCompleter.qml
resources/qml/SelfVerificationCheck.qml
resources/qml/TypingIndicator.qml
resources/qml/MessageInputWarning.qml
resources/qml/components/AdaptiveLayout.qml
resources/qml/components/AdaptiveLayoutElement.qml
resources/qml/components/AvatarListTile.qml
resources/qml/components/FlatButton.qml
resources/qml/components/MainWindowDialog.qml
resources/qml/components/NhekoTabButton.qml
resources/qml/components/NotificationBubble.qml
resources/qml/components/ReorderableListview.qml
resources/qml/components/SpaceMenuLevel.qml
resources/qml/components/TextButton.qml
resources/qml/components/UserListRow.qml
resources/qml/delegates/Encrypted.qml
resources/qml/delegates/FileMessage.qml
resources/qml/delegates/ImageMessage.qml
resources/qml/delegates/MessageDelegate.qml
resources/qml/delegates/NoticeMessage.qml
resources/qml/delegates/Pill.qml
resources/qml/delegates/Placeholder.qml
resources/qml/delegates/PlayableMediaMessage.qml
resources/qml/delegates/Redacted.qml
resources/qml/delegates/Reply.qml
resources/qml/delegates/TextMessage.qml
resources/qml/device-verification/DeviceVerification.qml
resources/qml/device-verification/DigitVerification.qml
resources/qml/device-verification/EmojiVerification.qml
resources/qml/device-verification/Failed.qml
resources/qml/device-verification/NewVerificationRequest.qml
resources/qml/device-verification/Success.qml
resources/qml/device-verification/Waiting.qml
resources/qml/dialogs/AliasEditor.qml
resources/qml/dialogs/ConfirmJoinRoomDialog.qml
resources/qml/dialogs/CreateDirect.qml
resources/qml/dialogs/CreateRoom.qml
resources/qml/dialogs/HiddenEventsDialog.qml
resources/qml/dialogs/ImageOverlay.qml
resources/qml/dialogs/ImagePackEditorDialog.qml
resources/qml/dialogs/ImagePackSettingsDialog.qml
resources/qml/dialogs/InputDialog.qml
resources/qml/dialogs/InviteDialog.qml
resources/qml/dialogs/JoinRoomDialog.qml
resources/qml/dialogs/LeaveRoomDialog.qml
resources/qml/dialogs/LogoutDialog.qml
resources/qml/dialogs/PhoneNumberInputDialog.qml
resources/qml/dialogs/PowerLevelEditor.qml
resources/qml/dialogs/PowerLevelSpacesApplyDialog.qml
resources/qml/dialogs/RawMessageDialog.qml
resources/qml/dialogs/ReadReceipts.qml
resources/qml/dialogs/RoomDirectory.qml
resources/qml/dialogs/RoomMembers.qml
resources/qml/dialogs/AllowedRoomsSettingsDialog.qml
resources/qml/dialogs/RoomSettings.qml
resources/qml/dialogs/UserProfile.qml
resources/qml/emoji/StickerPicker.qml
resources/qml/pages/LoginPage.qml
resources/qml/pages/RegisterPage.qml
resources/qml/pages/UserSettingsPage.qml
resources/qml/pages/WelcomePage.qml
resources/qml/ui/NhekoSlider.qml
resources/qml/ui/Ripple.qml
resources/qml/ui/Snackbar.qml
resources/qml/ui/Spinner.qml
resources/qml/ui/animations/BlinkAnimation.qml
resources/qml/ui/media/MediaControls.qml
resources/qml/voip/ActiveCallBar.qml
resources/qml/voip/CallDevices.qml
resources/qml/voip/CallInvite.qml
resources/qml/voip/CallInviteBar.qml
resources/qml/voip/DeviceError.qml
resources/qml/voip/PlaceCall.qml
resources/qml/voip/ScreenShare.qml
resources/qml/voip/VideoCall.qml
resources/qml/delegates/EncryptionEnabled.qml
resources/qml/ui/TimelineEffects.qml
)
qt_add_qml_module(nheko
URI im.nheko
NO_RESOURCE_TARGET_PATH
RESOURCE_PREFIX "/"
VERSION 1.1
DEPENDENCIES QtQml QtQuick # https://bugreports.qt.io/browse/QTBUG-102554
QML_FILES
${QML_SOURCES}
SOURCES
src/UserDirectoryModel.cpp
src/UserDirectoryModel.h
)
#qt_target_qml_sources(nheko
# #PREFIX "/"
#)
if(WIN32)
target_compile_definitions(nheko PRIVATE WIN32_LEAN_AND_MEAN)
if(MSVC)
@ -712,7 +832,7 @@ else()
endif()
endif()
target_include_directories(nheko PRIVATE src includes)
target_include_directories(nheko PRIVATE src includes src/timeline/ src/ui/ src/encryption/ src/voip/)
if (USE_BUNDLED_CPPHTTPLIB)
target_include_directories(nheko PRIVATE third_party/cpp-httplib-0.5.12)

@ -102,7 +102,7 @@ AbstractButton {
target: Presence
}
}
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}

@ -31,7 +31,7 @@ AbstractButton {
sourceSize.height: button.height
sourceSize.width: button.width
}
CursorShape {
NhekoCursorShape {
id: mouseArea
anchors.fill: parent

@ -44,7 +44,7 @@ TextArea {
onPressAndHold: (event) => event.accepted = false
onPressed: (event) => event.accepted = (event.button == Qt.LeftButton)
CursorShape {
NhekoCursorShape {
id: cs
anchors.fill: parent

@ -332,7 +332,7 @@ Item {
sourceSize.height: button.height
sourceSize.width: button.width
}
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}
@ -590,7 +590,7 @@ Item {
elideWidth: userInfo.remainingWidth - Math.min(statusMsg.implicitWidth, userInfo.remainingWidth / 3)
text: userName
}
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}

@ -15,7 +15,6 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import im.nheko
import im.nheko.EmojiModel
Pane {
id: timelineRoot
@ -92,15 +91,14 @@ Pane {
FontMetrics {
id: fontMetrics
}
RoomDirectoryModel {
id: publicRooms
}
UserDirectoryModel {
id: userDirectory
}
RoomDirectoryModel {
id: publicRooms
}
Component {
id: readReceiptsDialog

@ -173,7 +173,7 @@ AbstractButton {
Layout.row: 0
blurhash: r.relatedEventCacheBuster, fromModel(Room.Blurhash) ?? ""
body: r.relatedEventCacheBuster, fromModel(Room.Body) ?? ""
callType: r.relatedEventCacheBuster, fromModel(Room.CallType) ?? ""
callType: r.relatedEventCacheBuster, fromModel(Room.Voip) ?? ""
duration: r.relatedEventCacheBuster, fromModel(Room.Duration) ?? 0
encryptionError: r.relatedEventCacheBuster, fromModel(Room.EncryptionError) ?? 0
eventId: fromModel(Room.EventId) ?? ""

@ -8,14 +8,13 @@ import "./device-verification"
import "./emoji"
import "./ui"
import "./voip"
import Qt.labs.platform 1.1 as Platform
import QtQuick 2.15
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import QtQuick.Particles 2.15
import QtQuick.Window 2.13
import im.nheko 1.0
import im.nheko.EmojiModel 1.0
import Qt.labs.platform as Platform
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Particles
import QtQuick.Window
import im.nheko
Item {
id: timelineView
@ -123,7 +122,7 @@ Item {
searchString: topBar.searchString
}
Loader {
source: CallManager.isOnCall && CallManager.callType != CallType.VOICE ? "voip/VideoCall.qml" : ""
source: CallManager.isOnCall && CallManager.callType != Voip.VOICE ? "voip/VideoCall.qml" : ""
onLoaded: TimelineManager.setVideoCallItem()
}
@ -249,7 +248,7 @@ Item {
onLinkActivated: Nheko.openLink(link)
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}

@ -369,7 +369,7 @@ Pane {
onAccepted: topBar.searchString = text
}
}
CursorShape {
NhekoCursorShape {
anchors.bottomMargin: (pinnedMessages.visible ? pinnedMessages.height : 0) + (widgets.visible ? widgets.height : 0)
anchors.fill: parent
cursorShape: Qt.PointingHandCursor

@ -87,7 +87,7 @@ Container {
x: parent.preferredWidth
z: 3
CursorShape {
NhekoCursorShape {
height: parent.height
width: container.splitterGrabMargin * 2
x: -container.splitterGrabMargin

@ -32,7 +32,7 @@ AbstractButton {
horizontalAlignment: Text.AlignHCenter
}
CursorShape {
NhekoCursorShape {
id: mouseArea
anchors.fill: parent

@ -49,7 +49,7 @@ Item {
gesturePolicy: TapHandler.ReleaseWithinBounds
}
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}

@ -43,7 +43,7 @@ AbstractButton {
implicitHeight: replyContainer.height
implicitWidth: visible? colorLine.width+Math.max(replyContainer.implicitWidth,userName_.fullTextWidth) : 0 // visible? seems to be causing issues
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}

@ -46,7 +46,7 @@ MatrixText {
enabled: !Settings.mobileMode
font.pointSize: (Settings.enlargeEmojiOnlyMessages && isOnlyEmoji > 0 && isOnlyEmoji < 4) ? Settings.fontSize * 3 : Settings.fontSize
CursorShape {
NhekoCursorShape {
enabled: isReply
anchors.fill: parent
cursorShape: Qt.PointingHandCursor

@ -212,7 +212,7 @@ ApplicationWindow {
onClicked: invitees.removeUser(model.mxid)
}
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}

@ -110,7 +110,7 @@ ApplicationWindow {
}
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}

@ -220,7 +220,7 @@ ApplicationWindow {
}
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}

@ -213,7 +213,7 @@ ApplicationWindow {
horizontalAlignment: TextEdit.AlignHCenter
onLinkActivated: Nheko.openLink(link)
CursorShape {
NhekoCursorShape {
anchors.fill: parent
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}

@ -7,7 +7,6 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import im.nheko
import im.nheko.EmojiModel
Menu {
id: stickerPopup

@ -1,2 +0,0 @@
module im.nheko.UI.Animations
BlinkAnimation 1.0 BlinkAnimation.qml

@ -1,3 +0,0 @@
module im.nheko.UI.Media
VolumeSlider 1.0 VolumeSlider.qml
MediaControls 1.0 MediaControls.qml

@ -1,4 +0,0 @@
module im.nheko.UI
NhekoSlider 1.0 NhekoSlider.qml
Ripple 1.0 Ripple.qml
Spinner 1.0 Spinner.qml

@ -16,7 +16,7 @@ Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
if (CallManager.callType != CallType.VOICE)
if (CallManager.callType != Voip.VOICE)
stackLayout.currentIndex = stackLayout.currentIndex ? 0 : 1;
}
@ -58,7 +58,7 @@ Rectangle {
states: [
State {
name: "VOICE"
when: CallManager.callType == CallType.VOICE
when: CallManager.callType == Voip.VOICE
PropertyChanges {
target: callTypeIcon
@ -68,7 +68,7 @@ Rectangle {
},
State {
name: "VIDEO"
when: CallManager.callType == CallType.VIDEO
when: CallManager.callType == Voip.VIDEO
PropertyChanges {
target: callTypeIcon
@ -78,7 +78,7 @@ Rectangle {
},
State {
name: "SCREEN"
when: CallManager.callType == CallType.SCREEN
when: CallManager.callType == Voip.SCREEN
PropertyChanges {
target: callTypeIcon
@ -100,7 +100,7 @@ Rectangle {
states: [
State {
name: "OFFERSENT"
when: CallManager.callState == WebRTCState.OFFERSENT
when: CallManager.callState == Voip.OFFERSENT
PropertyChanges {
target: callStateLabel
@ -110,7 +110,7 @@ Rectangle {
},
State {
name: "CONNECTING"
when: CallManager.callState == WebRTCState.CONNECTING
when: CallManager.callState == Voip.CONNECTING
PropertyChanges {
target: callStateLabel
@ -120,7 +120,7 @@ Rectangle {
},
State {
name: "ANSWERSENT"
when: CallManager.callState == WebRTCState.ANSWERSENT
when: CallManager.callState == Voip.ANSWERSENT
PropertyChanges {
target: callStateLabel
@ -130,7 +130,7 @@ Rectangle {
},
State {
name: "CONNECTED"
when: CallManager.callState == WebRTCState.CONNECTED
when: CallManager.callState == Voip.CONNECTED
PropertyChanges {
target: callStateLabel
@ -144,13 +144,13 @@ Rectangle {
PropertyChanges {
target: stackLayout
currentIndex: CallManager.callType != CallType.VOICE ? 1 : 0
currentIndex: CallManager.callType != Voip.VOICE ? 1 : 0
}
},
State {
name: "DISCONNECTED"
when: CallManager.callState == WebRTCState.DISCONNECTED
when: CallManager.callState == Voip.DISCONNECTED
PropertyChanges {
target: callStateLabel
@ -176,7 +176,7 @@ Rectangle {
}
interval: 1000
running: CallManager.callState == WebRTCState.CONNECTED
running: CallManager.callState == Voip.CONNECTED
repeat: true
onTriggered: {
var d = new Date();
@ -190,7 +190,7 @@ Rectangle {
Label {
Layout.leftMargin: 16
visible: CallManager.callType == CallType.SCREEN && CallManager.callState == WebRTCState.CONNECTED
visible: CallManager.callType == Voip.SCREEN && CallManager.callState == Voip.CONNECTED
text: qsTr("You are screen sharing")
font.pointSize: fontMetrics.font.pointSize * 1.1
color: "#000000"

@ -43,7 +43,7 @@ Popup {
}
RowLayout {
visible: CallManager.callType == CallType.VIDEO && CallManager.cameras.length > 0
visible: CallManager.callType == Voip.VIDEO && CallManager.cameras.length > 0
Image {
Layout.preferredWidth: 22

@ -62,7 +62,7 @@ Popup {
Layout.bottomMargin: callInv.height / 25
Image {
property string image: CallManager.callType == CallType.VIDEO ? ":/icons/icons/ui/video.svg" : ":/icons/icons/ui/place-call.svg"
property string image: CallManager.callType == Voip.VIDEO ? ":/icons/icons/ui/video.svg" : ":/icons/icons/ui/place-call.svg"
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: callInv.height / 10
@ -72,7 +72,7 @@ Popup {
Label {
Layout.alignment: Qt.AlignCenter
text: CallManager.callType == CallType.VIDEO ? qsTr("Video Call") : qsTr("Voice Call")
text: CallManager.callType == Voip.VIDEO ? qsTr("Video Call") : qsTr("Voice Call")
font.pointSize: fontMetrics.font.pointSize * 2
color: palette.windowText
}
@ -106,7 +106,7 @@ Popup {
}
RowLayout {
visible: CallManager.callType == CallType.VIDEO && CallManager.cameras.length > 0
visible: CallManager.callType == Voip.VIDEO && CallManager.cameras.length > 0
Layout.alignment: Qt.AlignCenter
Image {
@ -169,7 +169,7 @@ Popup {
RoundButton {
id: acceptButton
property string image: CallManager.callType == CallType.VIDEO ? ":/icons/icons/ui/video.svg" : ":/icons/icons/ui/place-call.svg"
property string image: CallManager.callType == Voip.VIDEO ? ":/icons/icons/ui/video.svg" : ":/icons/icons/ui/place-call.svg"
implicitWidth: buttonLayout.buttonSize
implicitHeight: buttonLayout.buttonSize

@ -57,12 +57,12 @@ Rectangle {
Layout.leftMargin: 4
Layout.preferredWidth: 24
Layout.preferredHeight: 24
source: CallManager.callType == CallType.VIDEO ? "qrc:/icons/icons/ui/video.svg" : "qrc:/icons/icons/ui/place-call.svg"
source: CallManager.callType == Voip.VIDEO ? "qrc:/icons/icons/ui/video.svg" : "qrc:/icons/icons/ui/place-call.svg"
}
Label {
font.pointSize: fontMetrics.font.pointSize * 1.1
text: CallManager.callType == CallType.VIDEO ? qsTr("Video Call") : qsTr("Voice Call")
text: CallManager.callType == Voip.VIDEO ? qsTr("Video Call") : qsTr("Voice Call")
color: "#000000"
}
@ -88,7 +88,7 @@ Rectangle {
Button {
Layout.rightMargin: 4
icon.source: CallManager.callType == CallType.VIDEO ? "qrc:/icons/icons/ui/video.svg" : "qrc:/icons/icons/ui/place-call.svg"
icon.source: CallManager.callType == Voip.VIDEO ? "qrc:/icons/icons/ui/video.svg" : "qrc:/icons/icons/ui/place-call.svg"
text: qsTr("Accept")
onClicked: {
if (CallManager.mics.length == 0) {
@ -108,7 +108,7 @@ Rectangle {
timelineRoot.destroyOnClose(dialog);
return ;
}
if (CallManager.callType == CallType.VIDEO && CallManager.cameras.length > 0 && !CallManager.cameras.includes(Settings.camera)) {
if (CallManager.callType == Voip.VIDEO && CallManager.cameras.length > 0 && !CallManager.cameras.includes(Settings.camera)) {
var dialog = deviceError.createObject(timelineRoot, {
"errorString": qsTr("Unknown camera: %1").arg(Settings.camera),
"image": ":/icons/icons/ui/video.svg"

@ -81,7 +81,7 @@ Popup {
onClicked: {
if (buttonLayout.validateMic()) {
Settings.microphone = micCombo.currentText;
CallManager.sendInvite(room.roomId, CallType.VOICE);
CallManager.sendInvite(room.roomId, Voip.VOICE);
close();
}
}
@ -95,7 +95,7 @@ Popup {
if (buttonLayout.validateMic()) {
Settings.microphone = micCombo.currentText;
Settings.camera = cameraCombo.currentText;
CallManager.sendInvite(room.roomId, CallType.VIDEO);
CallManager.sendInvite(room.roomId, Voip.VIDEO);
close();
}
}

@ -47,7 +47,7 @@ Popup {
Layout.fillWidth: true
model: CallManager.screenShareTypeList()
onCurrentIndexChanged: CallManager.setScreenShareType(currentIndex);
onCurrentIndexChanged: CallManager.setVoip(currentIndex);
}
}
@ -63,7 +63,7 @@ Popup {
}
ComboBox {
visible: CallManager.screenShareType == ScreenShareType.X11
visible: CallManager.screenShareType == Voip.X11
id: windowCombo
Layout.fillWidth: true
@ -71,7 +71,7 @@ Popup {
}
Button {
visible: CallManager.screenShareType == ScreenShareType.XDP
visible: CallManager.screenShareType == Voip.XDP
highlighted: !CallManager.screenShareReady
text: qsTr("Request screencast")
onClicked: {
@ -165,7 +165,7 @@ Popup {
Settings.screenShareRemoteVideo = remoteVideoCheckBox.checked;
Settings.screenShareHideCursor = hideCursorCheckBox.checked;
CallManager.sendInvite(room.roomId, CallType.SCREEN, windowCombo.currentIndex);
CallManager.sendInvite(room.roomId, Voip.SCREEN, windowCombo.currentIndex);
close();
}
}

@ -92,107 +92,7 @@
</qresource>
<qresource prefix="/">
<file>qtquickcontrols2.conf</file>
<file>qml/Root.qml</file>
<file>qml/ChatPage.qml</file>
<file>qml/CommunitiesList.qml</file>
<file>qml/RoomList.qml</file>
<file>qml/TimelineView.qml</file>
<file>qml/Avatar.qml</file>
<file>qml/Completer.qml</file>
<file>qml/EncryptionIndicator.qml</file>
<file>qml/ImageButton.qml</file>
<file>qml/ElidedLabel.qml</file>
<file>qml/MatrixText.qml</file>
<file>qml/MatrixTextField.qml</file>
<file>qml/ToggleButton.qml</file>
<file>qml/UploadBox.qml</file>
<file>qml/MessageInput.qml</file>
<file>qml/MessageView.qml</file>
<file>qml/PrivacyScreen.qml</file>
<file>qml/Reactions.qml</file>
<file>qml/ReplyPopup.qml</file>
<file>qml/StatusIndicator.qml</file>
<file>qml/TimelineRow.qml</file>
<file>qml/TopBar.qml</file>
<file>qml/QuickSwitcher.qml</file>
<file>qml/ForwardCompleter.qml</file>
<file>qml/SelfVerificationCheck.qml</file>
<file>qml/TypingIndicator.qml</file>
<file>qml/MessageInputWarning.qml</file>
<file>qml/components/AdaptiveLayout.qml</file>
<file>qml/components/AdaptiveLayoutElement.qml</file>
<file>qml/components/AvatarListTile.qml</file>
<file>qml/components/FlatButton.qml</file>
<file>qml/components/MainWindowDialog.qml</file>
<file>qml/components/NhekoTabButton.qml</file>
<file>qml/components/NotificationBubble.qml</file>
<file>qml/components/ReorderableListview.qml</file>
<file>qml/components/SpaceMenuLevel.qml</file>
<file>qml/components/TextButton.qml</file>
<file>qml/components/UserListRow.qml</file>
<file>qml/delegates/Encrypted.qml</file>
<file>qml/delegates/FileMessage.qml</file>
<file>qml/delegates/ImageMessage.qml</file>
<file>qml/delegates/MessageDelegate.qml</file>
<file>qml/delegates/NoticeMessage.qml</file>
<file>qml/delegates/Pill.qml</file>
<file>qml/delegates/Placeholder.qml</file>
<file>qml/delegates/PlayableMediaMessage.qml</file>
<file>qml/delegates/Redacted.qml</file>
<file>qml/delegates/Reply.qml</file>
<file>qml/delegates/TextMessage.qml</file>
<file>qml/device-verification/DeviceVerification.qml</file>
<file>qml/device-verification/DigitVerification.qml</file>
<file>qml/device-verification/EmojiVerification.qml</file>
<file>qml/device-verification/Failed.qml</file>
<file>qml/device-verification/NewVerificationRequest.qml</file>
<file>qml/device-verification/Success.qml</file>
<file>qml/device-verification/Waiting.qml</file>
<file>qml/dialogs/AliasEditor.qml</file>
<file>qml/dialogs/ConfirmJoinRoomDialog.qml</file>
<file>qml/dialogs/CreateDirect.qml</file>
<file>qml/dialogs/CreateRoom.qml</file>
<file>qml/dialogs/HiddenEventsDialog.qml</file>
<file>qml/dialogs/ImageOverlay.qml</file>
<file>qml/dialogs/ImagePackEditorDialog.qml</file>
<file>qml/dialogs/ImagePackSettingsDialog.qml</file>
<file>qml/dialogs/InputDialog.qml</file>
<file>qml/dialogs/InviteDialog.qml</file>
<file>qml/dialogs/JoinRoomDialog.qml</file>
<file>qml/dialogs/LeaveRoomDialog.qml</file>
<file>qml/dialogs/LogoutDialog.qml</file>
<file>qml/dialogs/PhoneNumberInputDialog.qml</file>
<file>qml/dialogs/PowerLevelEditor.qml</file>
<file>qml/dialogs/PowerLevelSpacesApplyDialog.qml</file>
<file>qml/dialogs/RawMessageDialog.qml</file>
<file>qml/dialogs/ReadReceipts.qml</file>
<file>qml/dialogs/RoomDirectory.qml</file>
<file>qml/dialogs/RoomMembers.qml</file>
<file>qml/dialogs/AllowedRoomsSettingsDialog.qml</file>
<file>qml/dialogs/RoomSettings.qml</file>
<file>qml/dialogs/UserProfile.qml</file>
<file>qml/emoji/StickerPicker.qml</file>
<file>qml/pages/LoginPage.qml</file>
<file>qml/pages/RegisterPage.qml</file>
<file>qml/pages/UserSettingsPage.qml</file>
<file>qml/pages/WelcomePage.qml</file>
<file>qml/ui/NhekoSlider.qml</file>
<file>qml/ui/Ripple.qml</file>
<file>qml/ui/Snackbar.qml</file>
<file>qml/ui/Spinner.qml</file>
<file>qml/ui/animations/BlinkAnimation.qml</file>
<file>qml/ui/media/MediaControls.qml</file>
<file>qml/voip/ActiveCallBar.qml</file>
<file>qml/voip/CallDevices.qml</file>
<file>qml/voip/CallInvite.qml</file>
<file>qml/voip/CallInviteBar.qml</file>
<file>qml/voip/DeviceError.qml</file>
<file>qml/voip/PlaceCall.qml</file>
<file>qml/voip/ScreenShare.qml</file>
<file>qml/voip/VideoCall.qml</file>
<file>confettiparticle.svg</file>
<file>qml/delegates/EncryptionEnabled.qml</file>
<file>qml/ui/TimelineEffects.qml</file>
</qresource>
<qresource prefix="/media">
<file>media/ring.ogg</file>

@ -5,6 +5,7 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <QVector>
#include <mtx/events/canonical_alias.hpp>
@ -29,6 +30,9 @@ signals:
class AliasEditingModel final : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("Please use editAliases to create the models")
Q_PROPERTY(bool canAdvertize READ canAdvertize CONSTANT)
public:

@ -5,6 +5,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <map>
#include <mutex>
@ -16,6 +17,8 @@
namespace crypto {
Q_NAMESPACE
QML_NAMED_ELEMENT(Crypto)
//! How much a participant is trusted.
enum Trust
{

@ -5,11 +5,15 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QString>
class Clipboard final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
public:

@ -5,13 +5,10 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QVariantList>
namespace mtx {
namespace responses {
struct Login;
}
}
#include <mtx/responses/login.hpp>
struct SSOProvider
{
@ -33,6 +30,7 @@ public:
class LoginPage : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QString mxid READ mxid WRITE setMxid NOTIFY matrixIdChanged)
Q_PROPERTY(QString homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged)

@ -25,21 +25,15 @@
#include "InviteesModel.h"
#include "JdenticonProvider.h"
#include "Logging.h"
#include "LoginPage.h"
#include "MainWindow.h"
#include "MatrixClient.h"
#include "MemberList.h"
#include "MxcImageProvider.h"
#include "PowerlevelsEditModels.h"
#include "ReadReceiptsModel.h"
#include "RegisterPage.h"
#include "RoomDirectoryModel.h"
#include "RoomsModel.h"
#include "SingleImagePackModel.h"
#include "TrayIcon.h"
#include "UserDirectoryModel.h"
#include "UserSettingsPage.h"
#include "UsersModel.h"
#include "Utils.h"
#include "dock/Dock.h"
#include "emoji/Provider.h"
@ -48,12 +42,6 @@
#include "timeline/DelegateChooser.h"
#include "timeline/TimelineFilter.h"
#include "timeline/TimelineViewManager.h"
#include "ui/HiddenEvents.h"
#include "ui/MxcAnimatedImage.h"
#include "ui/MxcMediaProxy.h"
#include "ui/NhekoCursorShape.h"
#include "ui/NhekoDropArea.h"
#include "ui/NhekoEventObserver.h"
#include "ui/NhekoGlobalObject.h"
#include "ui/RoomSummary.h"
#include "ui/UIA.h"
@ -83,7 +71,7 @@ MainWindow::MainWindow(QWindow *parent)
registerQmlTypes();
setColor(Theme::paletteFromTheme(userSettings_->theme()).window().color());
setSource(QUrl(QStringLiteral("qrc:///qml/Root.qml")));
setSource(QUrl(QStringLiteral("qrc:///resources/qml/Root.qml")));
trayIcon_ = new TrayIcon(QStringLiteral(":/logos/nheko.svg"), this);
@ -132,156 +120,57 @@ MainWindow::MainWindow(QWindow *parent)
void
MainWindow::registerQmlTypes()
{
qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject,
"im.nheko",
1,
0,
"MtxEvent",
QStringLiteral("Can't instantiate enum!"));
qmlRegisterUncreatableMetaObject(
olm::staticMetaObject, "im.nheko", 1, 0, "Olm", QStringLiteral("Can't instantiate enum!"));
qmlRegisterUncreatableMetaObject(crypto::staticMetaObject,
"im.nheko",
1,
0,
"Crypto",
QStringLiteral("Can't instantiate enum!"));
qmlRegisterUncreatableMetaObject(verification::staticMetaObject,
"im.nheko",
1,
0,
"VerificationStatus",
QStringLiteral("Can't instantiate enum!"));
qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice");
qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser");
qmlRegisterType<NhekoDropArea>("im.nheko", 1, 0, "NhekoDropArea");
qmlRegisterType<NhekoCursorShape>("im.nheko", 1, 0, "CursorShape");
qmlRegisterType<NhekoEventObserver>("im.nheko", 1, 0, "EventObserver");
qmlRegisterType<MxcAnimatedImage>("im.nheko", 1, 0, "MxcAnimatedImage");
qmlRegisterType<MxcMediaProxy>("im.nheko", 1, 0, "MxcMedia");
qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel");
qmlRegisterType<UserDirectoryModel>("im.nheko", 1, 0, "UserDirectoryModel");
qmlRegisterType<LoginPage>("im.nheko", 1, 0, "Login");
qmlRegisterType<RegisterPage>("im.nheko", 1, 0, "Registration");
qmlRegisterType<HiddenEvents>("im.nheko", 1, 0, "HiddenEvents");
qmlRegisterType<TimelineFilter>("im.nheko", 1, 0, "TimelineFilter");
qmlRegisterUncreatableType<RoomSummary>(
"im.nheko",
1,
0,
"RoomSummary",
QStringLiteral("Please use joinRoom to create a room summary."));
qmlRegisterUncreatableType<AliasEditingModel>(
"im.nheko",
1,
0,
"AliasEditingModel",
QStringLiteral("Please use editAliases to create the models"));
qmlRegisterUncreatableType<PowerlevelEditingModels>(
"im.nheko",
1,
0,
"PowerlevelEditingModels",
QStringLiteral("Please use editPowerlevels to create the models"));
qmlRegisterUncreatableType<DeviceVerificationFlow>(
"im.nheko",
1,
0,
"DeviceVerificationFlow",
QStringLiteral("Can't create verification flow from QML!"));
qmlRegisterUncreatableType<UserProfile>(
"im.nheko",
1,
0,
"UserProfileModel",
QStringLiteral("UserProfile needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<MemberList>(
"im.nheko",
1,
0,
"MemberList",
QStringLiteral("MemberList needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<RoomSettings>(
"im.nheko",
1,
0,
"RoomSettingsModel",
QStringLiteral("Room Settings needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<TimelineModel>(
"im.nheko", 1, 0, "Room", QStringLiteral("Room needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<ImagePackListModel>(
"im.nheko",
1,
0,
"ImagePackListModel",
QStringLiteral("ImagePackListModel needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<SingleImagePackModel>(
"im.nheko",
1,
0,
"SingleImagePackModel",
QStringLiteral("SingleImagePackModel needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<InviteesModel>(
"im.nheko",
1,
0,
"InviteesModel",
QStringLiteral("InviteesModel needs to be instantiated on the C++ side"));
qmlRegisterUncreatableType<ReadReceiptsProxy>(
"im.nheko",
1,
0,
"ReadReceiptsProxy",
QStringLiteral("ReadReceiptsProxy needs to be instantiated on the C++ side"));
qmlRegisterSingletonType<Clipboard>(
"im.nheko", 1, 0, "Clipboard", [](QQmlEngine *, QJSEngine *) -> QObject * {
return new Clipboard();
});
qmlRegisterSingletonType<Nheko>(
"im.nheko", 1, 0, "Nheko", [](QQmlEngine *, QJSEngine *) -> QObject * {
return new Nheko();
});
qmlRegisterSingletonType<UserSettingsModel>(
"im.nheko", 1, 0, "UserSettingsModel", [](QQmlEngine *, QJSEngine *) -> QObject * {
return new UserSettingsModel();
});
qmlRegisterSingletonInstance("im.nheko", 1, 0, "Settings", userSettings_.data());
qmlRegisterUncreatableType<FilteredCommunitiesModel>(
"im.nheko",
1,
0,
"FilteredCommunitiesModel",
QStringLiteral("Use Communities.filtered() to create a FilteredCommunitiesModel"));
qmlRegisterUncreatableType<MediaUpload>(
"im.nheko", 1, 0, "MediaUpload", QStringLiteral("MediaUploads can not be created in Qml"));
qmlRegisterUncreatableMetaObject(emoji::staticMetaObject,
"im.nheko.EmojiModel",
1,
0,
"EmojiCategory",
QStringLiteral("Error: Only enums"));
qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel");
qmlRegisterSingletonType<SelfVerificationStatus>(
"im.nheko", 1, 0, "SelfVerificationStatus", [](QQmlEngine *, QJSEngine *) -> QObject * {
auto ptr = new SelfVerificationStatus();
QObject::connect(ChatPage::instance(),
&ChatPage::initializeEmptyViews,
ptr,
&SelfVerificationStatus::invalidate);
return ptr;
});
qmlRegisterSingletonInstance("im.nheko", 1, 0, "MainWindow", this);
qmlRegisterSingletonInstance("im.nheko", 1, 0, "UIA", UIA::instance());
qmlRegisterSingletonInstance(
"im.nheko", 1, 0, "CallManager", ChatPage::instance()->callManager());
// qmlRegisterUncreatableType<DeviceVerificationFlow>(
// "im.nheko",
// 1,
// 0,
// "DeviceVerificationFlow",
// QStringLiteral("Can't create verification flow from QML!"));
// qmlRegisterUncreatableType<UserProfile>(
// "im.nheko",
// 1,
// 0,
// "UserProfileModel",
// QStringLiteral("UserProfile needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<MemberList>(
// "im.nheko",
// 1,
// 0,
// "MemberList",
// QStringLiteral("MemberList needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<RoomSettings>(
// "im.nheko",
// 1,
// 0,
// "RoomSettingsModel",
// QStringLiteral("Room Settings needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<TimelineModel>(
// "im.nheko", 1, 0, "Room", QStringLiteral("Room needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<ImagePackListModel>(
// "im.nheko",
// 1,
// 0,
// "ImagePackListModel",
// QStringLiteral("ImagePackListModel needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<SingleImagePackModel>(
// "im.nheko",
// 1,
// 0,
// "SingleImagePackModel",
// QStringLiteral("SingleImagePackModel needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<InviteesModel>(
// "im.nheko",
// 1,
// 0,
// "InviteesModel",
// QStringLiteral("InviteesModel needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableMetaObject(emoji::staticMetaObject,
// "im.nheko.EmojiModel",
// 1,
// 0,
// "EmojiCategory",
// QStringLiteral("Error: Only enums"));
imgProvider = new MxcImageProvider();
engine()->addImageProvider(QStringLiteral("MxcImage"), imgProvider);

@ -50,14 +50,35 @@ public:
bool eventFilter(QObject *obj, QEvent *event) override;
};
class MainWindow final : public QQuickView
class MainWindow : public QQuickView
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
explicit MainWindow(QWindow *parent = nullptr);
explicit MainWindow(QWindow *parent);
static MainWindow *instance() { return instance_; }
static MainWindow *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance_);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance_->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership);
return instance_;
}
void saveCurrentWindowSize();
void openJoinRoomDialog(std::function<void(const QString &room_id)> callback);

@ -5,6 +5,7 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include <mtx/events/power_levels.hpp>
@ -196,6 +197,9 @@ class PowerlevelEditingModels final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("Please use editPowerlevels to create the models")
Q_PROPERTY(PowerlevelsUserListModel *users READ users CONSTANT)
Q_PROPERTY(PowerlevelsTypeListModel *types READ types CONSTANT)
Q_PROPERTY(PowerlevelsSpacesListModel *spaces READ spaces CONSTANT)

@ -8,6 +8,7 @@
#include <QAbstractListModel>
#include <QDateTime>
#include <QObject>
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include <QString>
@ -54,6 +55,9 @@ class ReadReceiptsProxy final : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_PROPERTY(QString eventId READ eventId CONSTANT)
Q_PROPERTY(QString roomId READ roomId CONSTANT)

@ -5,6 +5,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <mtx/user_interactive.hpp>
@ -13,6 +14,7 @@
class RegisterPage : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QString error READ error NOTIFY errorChanged)
Q_PROPERTY(QString hsError READ hsError NOTIFY hsErrorChanged)

@ -5,6 +5,7 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <QString>
#include <string>
#include <vector>
@ -32,6 +33,7 @@ signals:
class RoomDirectoryModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(bool loadingMoreRooms READ loadingMoreRooms NOTIFY loadingMoreRoomsChanged)
Q_PROPERTY(

@ -5,6 +5,7 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <QString>
#include <string>
#include <vector>
@ -26,6 +27,7 @@ signals:
class UserDirectoryModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(bool searchingUsers READ searchingUsers NOTIFY searchingUsersChanged)

@ -6,6 +6,7 @@
#include <QAbstractListModel>
#include <QProcessEnvironment>
#include <QQmlEngine>
#include <QSettings>
#include <QSharedPointer>
@ -23,6 +24,8 @@ class QVBoxLayout;
class UserSettings final : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(Settings)
QML_SINGLETON
Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged)
Q_PROPERTY(bool messageHoverHighlight READ messageHoverHighlight WRITE setMessageHoverHighlight
@ -131,6 +134,24 @@ class UserSettings final : public QObject
public:
static QSharedPointer<UserSettings> instance();
static void initialize(std::optional<QString> profile);
static UserSettings *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance());
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance()->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance().get(), QJSEngine::CppOwnership);
return instance().get();
}
QSettings *qsettings() { return &settings; }
@ -431,9 +452,10 @@ private:
static QSharedPointer<UserSettings> instance_;
};
class UserSettingsModel final : public QAbstractListModel
class UserSettingsModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
enum Indices
{

@ -9,10 +9,13 @@
#include <mtx/events/encrypted.hpp>
#include <mtxclient/crypto/client.hpp>
#include <QQmlEngine>
#include <CacheCryptoStructs.h>
namespace olm {
Q_NAMESPACE
QML_NAMED_ELEMENT(Olm)
enum DecryptionErrorCode
{

@ -29,6 +29,11 @@ SelfVerificationStatus::SelfVerificationStatus(QObject *o)
Qt::UniqueConnection);
cache::client()->markUserKeysOutOfDate({http::client()->user_id().to_string()});
});
connect(ChatPage::instance(),
&ChatPage::initializeEmptyViews,
this,
&SelfVerificationStatus::invalidate);
}
void

@ -5,11 +5,15 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
class SelfVerificationStatus final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(bool hasSSSS READ hasSSSS NOTIFY hasSSSSChanged)

@ -15,6 +15,7 @@ VerificationManager::VerificationManager(TimelineViewManager *o)
: QObject(o)
, rooms_(o->rooms())
{
instance_ = this;
}
static bool

@ -6,6 +6,7 @@
#include <QHash>
#include <QObject>
#include <QQmlEngine>
#include <QSharedPointer>
#include <mtx/events.hpp>
@ -21,8 +22,30 @@ class VerificationManager final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
VerificationManager(TimelineViewManager *o = nullptr);
VerificationManager(TimelineViewManager *o);
static VerificationManager *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance_);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance_->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership);
return instance_;
}
Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow);
void verifyUser(QString userid);
@ -45,4 +68,6 @@ private:
QHash<QString, QSharedPointer<DeviceVerificationFlow>> dvList;
bool isInitialSync_ = false;
RoomlistModel *rooms_;
inline static VerificationManager *instance_ = nullptr;
};

@ -346,7 +346,7 @@ main(int argc, char *argv[])
QStringLiteral(":/translations")))
app.installTranslator(&appTranslator);
MainWindow w;
MainWindow w(nullptr);
// QQuickView w;
// Move the MainWindow to the center

@ -22,6 +22,7 @@ CommunitiesModel::CommunitiesModel(QObject *parent)
, hiddenTagIds_{UserSettings::instance()->hiddenTags()}
, mutedTagIds_{UserSettings::instance()->mutedTags()}
{
instance_ = this;
}
QHash<int, QByteArray>

@ -6,6 +6,7 @@
#include <QAbstractListModel>
#include <QHash>
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include <QString>
#include <QStringList>
@ -21,6 +22,8 @@ class CommunitiesModel;
class FilteredCommunitiesModel final : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("Use Communities.filtered() to create a FilteredCommunitiesModel")
public:
explicit FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent = nullptr);
@ -73,6 +76,9 @@ public:
class CommunitiesModel final : public QAbstractListModel
{
Q_OBJECT
QML_NAMED_ELEMENT(Communities)
QML_SINGLETON
Q_PROPERTY(QString currentTagId READ currentTagId WRITE setCurrentTagId NOTIFY
currentTagIdChanged RESET resetCurrentTagId)
Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged)
@ -149,6 +155,26 @@ public:
};
CommunitiesModel(QObject *parent = nullptr);
static CommunitiesModel *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance_);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance_->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership);
return instance_;
}
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
@ -221,4 +247,6 @@ private:
mtx::responses::UnreadNotifications dmUnreads{};
friend class FilteredCommunitiesModel;
inline static CommunitiesModel *instance_ = nullptr;
};

@ -19,6 +19,7 @@ class QQmlAdaptorModel;
class DelegateChoice : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_CLASSINFO("DefaultProperty", "delegate")
public:
@ -45,6 +46,7 @@ private:
class DelegateChooser : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_CLASSINFO("DefaultProperty", "choices")
public:

@ -7,11 +7,13 @@
#include <QIODevice>
#include <QImage>
#include <QObject>
#include <QQmlEngine>
#include <QSize>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QVariantList>
#include <deque>
#include <memory>
@ -43,6 +45,10 @@ enum class MarkdownOverride
class MediaUpload final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_PROPERTY(int mediaType READ type NOTIFY mediaTypeChanged)
// https://stackoverflow.com/questions/33422265/pass-qimage-to-qml/68554646#68554646
Q_PROPERTY(QUrl thumbnail READ thumbnailDataUrl NOTIFY thumbnailChanged)

@ -5,6 +5,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <vector>
@ -15,10 +16,33 @@ class PresenceEmitter final : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(Presence)
QML_SINGLETON
public:
PresenceEmitter(QObject *p = nullptr)
: QObject(p)
{
instance_ = this;
}
static PresenceEmitter *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance_);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance_->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership);
return instance_;
}
void sync(const std::vector<mtx::events::Event<mtx::events::presence::Presence>> &presences);
@ -28,4 +52,7 @@ public:
signals:
void presenceChanged(QString userid);
private:
inline static PresenceEmitter *instance_ = nullptr;
};

@ -909,6 +909,8 @@ FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *pare
: QSortFilterProxyModel(parent)
, roomlistmodel(model)
{
instance_ = this;
this->sortByImportance = UserSettings::instance()->sortByImportance();
this->sortByAlphabet = UserSettings::instance()->sortByAlphabet();
setSourceModel(model);

@ -167,12 +167,36 @@ private:
class FilteredRoomlistModel final : public QSortFilterProxyModel
{
Q_OBJECT
QML_NAMED_ELEMENT(Rooms)
QML_SINGLETON
Q_PROPERTY(
TimelineModel *currentRoom READ currentRoom NOTIFY currentRoomChanged RESET resetCurrentRoom)
Q_PROPERTY(RoomPreview currentRoomPreview READ currentRoomPreview NOTIFY currentRoomChanged
RESET resetCurrentRoom)
public:
FilteredRoomlistModel(RoomlistModel *model, QObject *parent = nullptr);
static FilteredRoomlistModel *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance_);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance_->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership);
return instance_;
}
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
bool filterAcceptsRow(int sourceRow, const QModelIndex &) const override;
@ -249,4 +273,6 @@ private:
FilterBy filterType = FilterBy::Nothing;
QStringList hiddenTags, hiddenSpaces;
bool hideDMs = false;
inline static FilteredRoomlistModel *instance_ = nullptr;
};

@ -4,6 +4,7 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include <QString>
@ -14,6 +15,7 @@
class TimelineFilter : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QString filterByThread READ filterByThread WRITE setThreadId NOTIFY threadIdChanged)
Q_PROPERTY(QString filterByContent READ filterByContent WRITE setContentFilter NOTIFY

@ -11,6 +11,7 @@
#include <QTimer>
#include <QVariant>
#include <mtx/responses/common.hpp>
#include <mtxclient/http/errors.hpp>
#include "CacheCryptoStructs.h"
@ -36,6 +37,7 @@ struct RelatedInfo;
namespace qml_mtx_events {
Q_NAMESPACE
QML_NAMED_ELEMENT(MtxEvent)
enum EventType
{
@ -193,6 +195,9 @@ class TimelineViewManager;
class TimelineModel final : public QAbstractListModel
{
Q_OBJECT
QML_NAMED_ELEMENT(Room)
QML_UNCREATABLE("")
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY
typingUsersChanged)

@ -96,29 +96,21 @@ TimelineViewManager::userColor(QString id, QColor background)
TimelineViewManager::TimelineViewManager(CallManager *, ChatPage *parent)
: QObject(parent)
, rooms_(new RoomlistModel(this))
, frooms_(new FilteredRoomlistModel(this->rooms_))
, communities_(new CommunitiesModel(this))
, verificationManager_(new VerificationManager(this))
, presenceEmitter(new PresenceEmitter(this))
{
static auto self = this;
qmlRegisterSingletonInstance("im.nheko", 1, 0, "TimelineManager", self);
qmlRegisterSingletonType<RoomlistModel>(
"im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * {
auto ptr = new FilteredRoomlistModel(self->rooms_);
instance_ = this;
connect(self->communities_,
connect(this->communities_,
&CommunitiesModel::currentTagIdChanged,
ptr,
frooms_,
&FilteredRoomlistModel::updateFilterTag);
connect(self->communities_,
connect(this->communities_,
&CommunitiesModel::hiddenTagsChanged,
ptr,
frooms_,
&FilteredRoomlistModel::updateHiddenTagsAndSpaces);
return ptr;
});
qmlRegisterSingletonInstance("im.nheko", 1, 0, "Communities", self->communities_);
qmlRegisterSingletonInstance("im.nheko", 1, 0, "VerificationManager", verificationManager_);
qmlRegisterSingletonInstance("im.nheko", 1, 0, "Presence", presenceEmitter);
updateColorPalette();

@ -34,6 +34,9 @@ class TimelineViewManager final : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(TimelineManager)
QML_SINGLETON
Q_PROPERTY(
bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged)
@ -41,6 +44,25 @@ class TimelineViewManager final : public QObject
public:
TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr);
static TimelineViewManager *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance_);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance_->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership);
return instance_;
}
void sync(const mtx::responses::Sync &sync_);
VerificationManager *verificationManager() { return verificationManager_; }
@ -123,6 +145,7 @@ private:
bool isConnected_ = true;
RoomlistModel *rooms_ = nullptr;
FilteredRoomlistModel *frooms_ = nullptr;
CommunitiesModel *communities_ = nullptr;
// don't move this above the rooms_
@ -130,4 +153,6 @@ private:
PresenceEmitter *presenceEmitter = nullptr;
QHash<QPair<QString, quint64>, QColor> userColors;
inline static TimelineViewManager *instance_ = nullptr;
};

@ -5,6 +5,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QVariantList>
@ -13,6 +14,7 @@
class HiddenEvents : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged REQUIRED)
Q_PROPERTY(QVariantList hiddenEvents READ hiddenEvents NOTIFY hiddenEventsChanged)
public:

@ -15,6 +15,7 @@
class MxcAnimatedImage : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED)
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
Q_PROPERTY(bool animatable READ animatable NOTIFY animatableChanged)

@ -8,6 +8,7 @@
#include <QMediaPlayer>
#include <QObject>
#include <QPointer>
#include <QQuickItem>
#include <QString>
#include <QUrl>
#include <QVideoSink>
@ -21,6 +22,8 @@ class TimelineModel;
class MxcMediaProxy : public QMediaPlayer
{
Q_OBJECT
QML_NAMED_ELEMENT(MxcMedia)
Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED)
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)

@ -12,7 +12,7 @@
class NhekoCursorShape : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(
Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY cursorShapeChanged)

@ -7,6 +7,7 @@
class NhekoDropArea : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged)
public:
NhekoDropArea(QQuickItem *parent = nullptr);

@ -1,60 +0,0 @@
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "NhekoEventObserver.h"
#include <QMouseEvent>
#include "Logging.h"
NhekoEventObserver::NhekoEventObserver(QQuickItem *parent)
: QQuickItem(parent)
{
setFiltersChildMouseEvents(true);
}
bool
NhekoEventObserver::childMouseEventFilter(QQuickItem * /*item*/, QEvent *event)
{
// nhlog::ui()->debug("Touched {}", item->metaObject()->className());
auto setTouched = [this](bool touched) {
if (touched != this->wasTouched_) {
this->wasTouched_ = touched;
emit wasTouchedChanged();
}
};
// see
// https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quicktemplates2/qquickscrollview.cpp?id=7f29e89c26ae2babc358b1c4e6f965af6ec759f4#n471
switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchEnd:
setTouched(true);
break;
case QEvent::MouseButtonPress:
if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) {
setTouched(false);
}
break;
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized)
setTouched(false);
break;
case QEvent::HoverEnter:
case QEvent::HoverMove:
case QEvent::Wheel:
setTouched(false);
break;
default:
break;
}
return false;
}

@ -1,27 +0,0 @@
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QQuickItem>
class NhekoEventObserver : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(bool wasTouched READ wasTouched NOTIFY wasTouchedChanged)
public:
explicit NhekoEventObserver(QQuickItem *parent = 0);
bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
private:
bool wasTouched() { return wasTouched_; }
bool wasTouched_ = false;
signals:
void wasTouchedChanged();
};

@ -7,6 +7,7 @@
#include <QFontDatabase>
#include <QObject>
#include <QPalette>
#include <QQmlEngine>
#include <QWindow>
#include "AliasEditModel.h"
@ -19,6 +20,9 @@ class Nheko final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(QPalette colors READ colors NOTIFY colorsChanged)
Q_PROPERTY(QPalette inactiveColors READ inactiveColors NOTIFY colorsChanged)
Q_PROPERTY(Theme theme READ theme NOTIFY colorsChanged)

@ -7,6 +7,7 @@
#include <optional>
#include <QObject>
#include <QQmlEngine>
#include <mtx/responses/public_rooms.hpp>
@ -25,6 +26,9 @@ class RoomSummary final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("Please use joinRoom to create a room summary.")
Q_PROPERTY(QString reason READ reason WRITE setReason NOTIFY reasonChanged)
Q_PROPERTY(QString roomid READ roomid NOTIFY loaded)

@ -5,6 +5,7 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <mtxclient/http/client.hpp>
@ -12,10 +13,31 @@ class UIA final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
public:
static UIA *instance();
static UIA *create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
Q_ASSERT(instance());
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance()->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance(), QJSEngine::CppOwnership);
return instance();
}
UIA(QObject *parent = nullptr)
: QObject(parent)

@ -6,6 +6,7 @@
#include <QAbstractListModel>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QVector>
#include <mtx/responses.hpp>
@ -16,6 +17,7 @@
namespace verification {
Q_NAMESPACE
QML_NAMED_ELEMENT(VerificationStatus)
enum Status
{

@ -54,6 +54,27 @@ std::vector<std::string>
getTurnURIs(const mtx::responses::TurnServer &turnServer);
}
CallManager *
CallManager::create(QQmlEngine *qmlEngine, QJSEngine *)
{
// The instance has to exist before it is used. We cannot replace it.
auto instance = ChatPage::instance()->callManager();
Q_ASSERT(instance);
// The engine has to have the same thread affinity as the singleton.
Q_ASSERT(qmlEngine->thread() == instance->thread());
// There can only be one engine accessing the singleton.
static QJSEngine *s_engine = nullptr;
if (s_engine)
Q_ASSERT(qmlEngine == s_engine);
else
s_engine = qmlEngine;
QJSEngine::setObjectOwnership(instance, QJSEngine::CppOwnership);
return instance;
}
CallManager::CallManager(QObject *parent)
: QObject(parent)
, session_(WebRTCSession::instance())

@ -9,6 +9,7 @@
#include <QMediaPlayer>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QStringList>
#include <QTimer>
@ -29,6 +30,10 @@ class QUrl;
class CallManager final : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(bool haveCallInvite READ haveCallInvite NOTIFY newInviteState)
Q_PROPERTY(bool isOnCall READ isOnCall NOTIFY newCallState)
Q_PROPERTY(bool isOnCallOnOtherDevice READ isOnCallOnOtherDevice NOTIFY newCallDeviceState)
@ -49,6 +54,8 @@ class CallManager final : public QObject
public:
CallManager(QObject *);
static CallManager *create(QQmlEngine *qmlEngine, QJSEngine *);
bool haveCallInvite() const { return haveCallInvite_; }
bool isOnCall() const { return (session_.state() != webrtc::State::DISCONNECTED); }
bool isOnCallOnOtherDevice() const { return (isOnCallOnOtherDevice_ != ""); }

@ -48,26 +48,26 @@ using webrtc::State;
WebRTCSession::WebRTCSession()
: devices_(CallDevices::instance())
{
qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
"im.nheko",
1,
0,
"CallType",
QStringLiteral("Can't instantiate enum"));
qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
"im.nheko",
1,
0,
"ScreenShareType",
QStringLiteral("Can't instantiate enum"));
qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
"im.nheko",
1,
0,
"WebRTCState",
QStringLiteral("Can't instantiate enum"));
// qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
// "im.nheko",
// 1,
// 0,
// "CallType",
// QStringLiteral("Can't instantiate enum"));
// qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
// "im.nheko",
// 1,
// 0,
// "ScreenShareType",
// QStringLiteral("Can't instantiate enum"));
// qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject,
// "im.nheko",
// 1,
// 0,
// "WebRTCState",
// QStringLiteral("Can't instantiate enum"));
connect(this, &WebRTCSession::stateChanged, this, &WebRTCSession::setState);
init();

@ -8,6 +8,7 @@
#include <vector>
#include <QObject>
#include <QQmlEngine>
#include "mtx/events/voip.hpp"
@ -17,6 +18,7 @@ class QQuickItem;
namespace webrtc {
Q_NAMESPACE
QML_NAMED_ELEMENT(Voip)
enum class CallType
{

Loading…
Cancel
Save