Skip to content
Snippets Groups Projects
Root.qml 16.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • // SPDX-FileCopyrightText: Nheko Contributors
    
    //
    // SPDX-License-Identifier: GPL-3.0-or-later
    
    import "./delegates"
    import "./device-verification"
    
    import "./dialogs"
    
    import "./pages"
    
    import "./ui"
    
    import Qt.labs.platform 1.1 as Platform
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    import QtQuick
    import QtQuick.Controls
    import QtQuick.Layouts
    import QtQuick.Window
    import im.nheko
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    Pane {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        function destroyOnClose(obj) {
            if (obj.closing != undefined)
                obj.closing.connect(() => obj.destroy(1000));
            else if (obj.aboutToHide != undefined)
                obj.aboutToHide.connect(() => obj.destroy(1000));
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        function destroyOnClosed(obj) {
            obj.aboutToHide.connect(() => obj.destroy(1000));
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        //Timer {
        //    onTriggered: gc()
        //    interval: 1000
        //    running: true
        //    repeat: true
        //}
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        function showAliasEditor(settings) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            var component = Qt.createComponent("qrc:/resources/qml/dialogs/AliasEditor.qml");
    
            if (component.status == Component.Ready) {
                var dialog = component.createObject(timelineRoot, {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                        "roomSettings": settings
                    });
    
                dialog.show();
                destroyOnClose(dialog);
            } else {
                console.error("Failed to create component: " + component.errorString());
            }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        function showAllowedRoomsEditor(settings) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            var component = Qt.createComponent("qrc:/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml");
    
            if (component.status == Component.Ready) {
                var dialog = component.createObject(timelineRoot, {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                        "roomSettings": settings
                    });
    
                dialog.show();
                destroyOnClose(dialog);
            } else {
                console.error("Failed to create component: " + component.errorString());
            }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        function showPLEditor(settings) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            var component = Qt.createComponent("qrc:/resources/qml/dialogs/PowerLevelEditor.qml");
    
            if (component.status == Component.Ready) {
                var dialog = component.createObject(timelineRoot, {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                        "roomSettings": settings
                    });
    
                dialog.show();
                destroyOnClose(dialog);
            } else {
                console.error("Failed to create component: " + component.errorString());
            }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        function showSpacePLApplyPrompt(settings, editingModel) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            var component = Qt.createComponent("qrc:/resources/qml/dialogs/PowerLevelSpacesApplyDialog.qml");
    
            if (component.status == Component.Ready) {
                var dialog = component.createObject(timelineRoot, {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                        "roomSettings": settings,
                        "editingModel": editingModel
                    });
    
                dialog.show();
                destroyOnClose(dialog);
            } else {
                console.error("Failed to create component: " + component.errorString());
            }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        background: null
        padding: 0
    
        FontMetrics {
            id: fontMetrics
    
        }
        UserDirectoryModel {
            id: userDirectory
    
        }
    
        RoomDirectoryModel {
            id: publicRooms
    
        Component {
            id: readReceiptsDialog
    
            ReadReceipts {
            }
        }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        Shortcut {
            sequence: StandardKey.Quit
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            onActivated: Qt.quit()
        }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/QuickSwitcher.qml");
    
                if (component.status == Component.Ready) {
                    var quickSwitch = component.createObject(timelineRoot);
                    quickSwitch.open();
                    destroyOnClosed(quickSwitch);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
            // Add alternative shortcut, because sometimes Alt+A is stolen by the TextEdit
            sequences: ["Alt+A", "Ctrl+Shift+A"]
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
    
            onActivated: Rooms.nextRoomWithActivity()
        }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        Shortcut {
            sequence: "Ctrl+Down"
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
    
            onActivated: Rooms.nextRoom()
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        }
        Shortcut {
            sequence: "Ctrl+Up"
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
    
            onActivated: Rooms.previousRoom()
    
    Loren Burkholder's avatar
    Loren Burkholder committed
        Connections {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onOpenJoinRoomDialog() {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/JoinRoomDialog.qml");
    
                if (component.status == Component.Ready) {
                    var dialog = component.createObject(timelineRoot);
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                    dialog.show();
    
                    destroyOnClose(dialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onOpenLogoutDialog() {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/LogoutDialog.qml");
    
                if (component.status == Component.Ready) {
                    var dialog = component.createObject(timelineRoot);
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                    dialog.open();
    
                    destroyOnClose(dialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
            function onShowRoomJoinPrompt(summary) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/ConfirmJoinRoomDialog.qml");
    
                if (component.status == Component.Ready) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                    var dialog = component.createObject(timelineRoot, {
                            "summary": summary
                        });
    
                    dialog.show();
                    destroyOnClose(dialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
    Loren Burkholder's avatar
    Loren Burkholder committed
            target: Nheko
        }
    
            function onNewDeviceVerificationRequest(flow) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/device-verification/DeviceVerification.qml");
    
                if (component.status == Component.Ready) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                    var dialog = component.createObject(timelineRoot, {
                            "flow": flow
                        });
    
                    dialog.show();
                    destroyOnClose(dialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
            target: VerificationManager
        }
        Connections {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onOpenInviteUsersDialog(invitees) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/InviteDialog.qml");
    
                if (component.status == Component.Ready) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                    var dialog = component.createObject(timelineRoot, {
                            "invitees": invitees
                        });
                    dialog.show();
                    destroyOnClose(dialog);
    
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onOpenLeaveRoomDialog(roomid, reason) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/LeaveRoomDialog.qml");
    
                if (component.status == Component.Ready) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                    var dialog = component.createObject(timelineRoot, {
                            "roomId": roomid,
                            "reason": reason
                        });
                    dialog.open();
                    destroyOnClose(dialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
            }
            function onOpenProfile(profile) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/UserProfile.qml");
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                if (component.status == Component.Ready) {
                    var userProfile = component.createObject(timelineRoot, {
                            "profile": profile
                        });
                    userProfile.show();
                    destroyOnClose(userProfile);
    
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
            function onOpenRoomMembersDialog(members, room) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/RoomMembers.qml");
    
                if (component.status == Component.Ready) {
                    var membersDialog = component.createObject(timelineRoot, {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                            "members": members,
                            "room": room
                        });
    
                    membersDialog.show();
                    destroyOnClose(membersDialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
    Loren Burkholder's avatar
    Loren Burkholder committed
            }
    
            function onOpenRoomSettingsDialog(settings) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/RoomSettings.qml");
    
                if (component.status == Component.Ready) {
                    var roomSettings = component.createObject(timelineRoot, {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                            "roomSettings": settings
                        });
    
                    roomSettings.show();
                    destroyOnClose(roomSettings);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
    Loren Burkholder's avatar
    Loren Burkholder committed
            }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onShowImageOverlay(room, eventId, url, originalWidth, proportionalHeight) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/ImageOverlay.qml");
    
                if (component.status == Component.Ready) {
                    var dialog = component.createObject(timelineRoot, {
                            "room": room,
                            "eventId": eventId,
                            "url": url,
                            "originalWidth": originalWidth ?? 0,
                            "proportionalHeight": proportionalHeight ?? 0
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                        });
    
                    dialog.showFullScreen();
                    destroyOnClose(dialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onShowImagePackSettings(room, packlist) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/ImagePackSettingsDialog.qml");
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                if (component.status == Component.Ready) {
                    var packSet = component.createObject(timelineRoot, {
                            "room": room,
                            "packlist": packlist
                        });
                    packSet.show();
                    destroyOnClose(packSet);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
            }
    
            target: TimelineManager
        }
        Connections {
            function onNewInviteState() {
                if (CallManager.haveCallInvite && Settings.mobileMode) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                    var component = Qt.createComponent("qrc:/resources/qml/voip/CallInvite.qml");
    
                    if (component.status == Component.Ready) {
                        var dialog = component.createObject(timelineRoot);
                        dialog.open();
                        destroyOnClose(dialog);
                    } else {
                        console.error("Failed to create component: " + component.errorString());
                    }
    
                }
            }
    
            target: CallManager
    
    Loren Burkholder's avatar
    Loren Burkholder committed
        }
    
        SelfVerificationCheck {
        }
        InputDialog {
            id: uiaPassPrompt
    
            echoMode: TextInput.Password
            prompt: qsTr("Please enter your login password to continue:")
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            title: UIA.title
    
            onAccepted: t => {
    
                return UIA.continuePassword(t);
            }
        }
    
        InputDialog {
            id: uiaEmailPrompt
    
            prompt: qsTr("Please enter a valid email address to continue:")
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            title: UIA.title
    
            onAccepted: t => {
    
                return UIA.continueEmail(t);
            }
        }
        PhoneNumberInputDialog {
            id: uiaPhoneNumberPrompt
    
            prompt: qsTr("Please enter a valid phone number to continue:")
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            title: UIA.title
    
    
            onAccepted: (p, t) => {
                return UIA.continuePhoneNumber(p, t);
            }
        }
        InputDialog {
            id: uiaTokenPrompt
    
    
            prompt: qsTr("Please enter the token which has been sent to you:")
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            title: UIA.title
    
            onAccepted: t => {
    
                return UIA.submit3pidToken(t);
            }
        }
        Platform.MessageDialog {
            id: uiaConfirmationLinkDialog
    
            buttons: Platform.MessageDialog.Ok
            text: qsTr("Wait for the confirmation link to arrive, then continue.")
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
    
            onAccepted: UIA.continue3pidReceived()
        }
    
        Connections {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onConfirm3pidToken() {
                uiaConfirmationLinkDialog.open();
    
            function onEmail() {
                uiaEmailPrompt.show();
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            }
            function onPassword() {
                console.log("UIA: password needed");
                uiaPassPrompt.show();
            }
    
            function onPhoneNumber() {
                uiaPhoneNumberPrompt.show();
            }
            function onPrompt3pidToken() {
                uiaTokenPrompt.show();
            }
    
            function onReCaptcha(recaptcha) {
                var component = Qt.createComponent("qrc:/resources/qml/dialogs/ReCaptchaDialog.qml");
                if (component.status == Component.Ready) {
                    var dialog = component.createObject(timelineRoot, {
                            "recaptcha": recaptcha
                        });
                    dialog.show();
                    destroyOnClose(dialog);
                } else {
                    console.error("Failed to create component: " + component.errorString());
                }
            }
    
        StackView {
            id: mainWindow
    
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            property Transition popEnterOrg
            property Transition popExitOrg
    
    
            // for some reason direct bindings to a hidden StackView don't work, so manually store and restore here.
            property Transition pushEnterOrg
            property Transition pushExitOrg
            property Transition replaceEnterOrg
            property Transition replaceExitOrg
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
            function updateTrans() {
                pushEnter = Settings.reducedMotion ? reducedMotionTransitionEnter : pushEnterOrg;
                pushExit = Settings.reducedMotion ? reducedMotionTransitionExit : pushExitOrg;
                popEnter = Settings.reducedMotion ? reducedMotionTransitionEnter : popEnterOrg;
                popExit = Settings.reducedMotion ? reducedMotionTransitionExit : popExitOrg;
                replaceEnter = Settings.reducedMotion ? reducedMotionTransitionEnter : replaceEnterOrg;
                replaceExit = Settings.reducedMotion ? reducedMotionTransitionExit : replaceExitOrg;
            }
    
            anchors.fill: parent
            initialItem: welcomePage
    
    
            Component.onCompleted: {
                pushEnterOrg = pushEnter;
                popEnterOrg = popEnter;
                replaceEnterOrg = replaceEnter;
                pushExitOrg = pushExit;
                popExitOrg = popExit;
                replaceExitOrg = replaceExit;
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                updateTrans();
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            Transition {
                id: reducedMotionTransitionExit
    
                PropertyAnimation {
                    duration: 200
                    from: 1
                    property: "opacity"
                    to: 0
                }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            Transition {
                id: reducedMotionTransitionEnter
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                SequentialAnimation {
                    PropertyAction {
                        property: "opacity"
                        value: 0
                    }
                    PauseAnimation {
                        duration: 200
                    }
                    PropertyAnimation {
                        duration: 200
                        from: 0
                        property: "opacity"
                        to: 1
                    }
                }
            }
    
            Connections {
                function onReducedMotionChanged() {
                    mainWindow.updateTrans();
                }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
                target: Settings
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        }
        Component {
            id: welcomePage
    
            WelcomePage {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        Component {
            id: chatPage
    
            ChatPage {
            }
        }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        Component {
            id: loginPage
    
            LoginPage {
            }
        }
    
        Component {
            id: registerPage
    
    
            RegisterPage {
    
        Component {
            id: userSettingsPage
    
            UserSettingsPage {
            }
        }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        Snackbar {
            id: snackbar
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
        Connections {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onShowNotification(msg) {
                snackbar.showNotification(msg);
                console.log("New snack: " + msg);
            }
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            function onSwitchToChatPage() {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                mainWindow.replace(null, chatPage);
            }
            function onSwitchToLoginPage(error) {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
                mainWindow.replace(welcomePage, {}, loginPage, {
                        "error": error
                    }, StackView.PopTransition);
    
    Nicolas Werner's avatar
    Nicolas Werner committed
    
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            target: MainWindow
        }