mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-21 18:50:47 +03:00
Move to automatic type registration
This commit is contained in:
parent
2cb04fd741
commit
ce1a64bc19
73 changed files with 570 additions and 472 deletions
136
CMakeLists.txt
136
CMakeLists.txt
|
@ -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!"));
|
||||
// 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"));
|
||||
|
||||
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());
|
||||
// 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_,
|
||||
&CommunitiesModel::currentTagIdChanged,
|
||||
ptr,
|
||||
&FilteredRoomlistModel::updateFilterTag);
|
||||
connect(self->communities_,
|
||||
&CommunitiesModel::hiddenTagsChanged,
|
||||
ptr,
|
||||
&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);
|
||||
connect(this->communities_,
|
||||
&CommunitiesModel::currentTagIdChanged,
|
||||
frooms_,
|
||||
&FilteredRoomlistModel::updateFilterTag);
|
||||
connect(this->communities_,
|
||||
&CommunitiesModel::hiddenTagsChanged,
|
||||
frooms_,
|
||||
&FilteredRoomlistModel::updateHiddenTagsAndSpaces);
|
||||
|
||||
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)
|
||||
|
|
22
src/ui/UIA.h
22
src/ui/UIA.h
|
@ -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,
|
||||
// "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,
|
||||
// "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,
|
||||
// "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…
Reference in a new issue