aboutsummaryrefslogtreecommitdiffstats
path: root/examples/webchannel/chatclient-qml/qmlchatclient.qml
blob: 03f613b1320a3c233db528d6ce4eb6df327b86a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2016 basysKom GmbH, author Bernd Lamecker <bernd.lamecker@basyskom.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

import QtQuick
import QtQuick.Dialogs
import QtQuick.Controls
import QtQuick.Window
import QtQuick.Layouts
import QtWebSockets
import "qwebchannel.js" as WebChannel

ApplicationWindow {
    id: root

    property var channel
    property string loginName: loginUi.userName.text

    title: "Chat client"
    width: 640
    height: 480
    visible: true

    WebSocket {
        id: socket

        // the following three properties/functions are required to align the QML WebSocket API
        // with the HTML5 WebSocket API.
        property var send: function(arg) {
            sendTextMessage(arg);
        }

        onTextMessageReceived: function(message) {
            onmessage({data: message});
        }

        property var onmessage

        active: true
        url: "ws://localhost:12345"

        onStatusChanged: {
            switch (socket.status) {
            case WebSocket.Error:
                errorDialog.text = "Error: " + socket.errorString;
                errorDialog.visible = true;
                break;
            case WebSocket.Closed:
                errorDialog.text = "Error: Socket at " + url + " closed.";
                errorDialog.visible = true;
                break;
            case WebSocket.Open:
                //open the webchannel with the socket as transport
                new WebChannel.QWebChannel(socket, function(ch) {
                    root.channel = ch;

                    //connect to the changed signal of the userList property
                    ch.objects.chatserver.userListChanged.connect(function(args) {
                        mainUi.userlist.text = '';
                        ch.objects.chatserver.userList.forEach(function(user) {
                            mainUi.userlist.text += user + '\n';
                        });
                    });

                    //connect to the newMessage signal
                    ch.objects.chatserver.newMessage.connect(function(time, user, message) {
                        var line = "[" + time + "] " + user + ": " + message + '\n';
                        mainUi.chat.text = mainUi.chat.text + line;
                    });

                    //connect to the keep alive signal
                    ch.objects.chatserver.keepAlive.connect(function(args) {
                        if (loginName !== '')
                            //and call the keep alive response method as an answer
                            ch.objects.chatserver.keepAliveResponse(loginName);
                    });
                });

                loginWindow.show();
                break;
            }
        }
    }

    MainForm {
        id: mainUi
        anchors.fill: parent

        Connections {
            target: mainUi.message
            function onEditingFinished() {
                if (mainUi.message.text.length) {
                    //call the sendMessage method to send the message
                    root.channel.objects.chatserver.sendMessage(loginName,
                                                                mainUi.message.text);
                }
                mainUi.message.text = '';
            }
        }
    }

    Window {
        id: loginWindow

        title: "Login"
        modality: Qt.ApplicationModal
        width: 300
        height: 200

        LoginForm {
            id: loginUi
            anchors.fill: parent

            nameInUseError.visible: false

            Connections {
                target: loginUi.loginButton

                function onClicked() {
                    //call the login method
                    root.channel.objects.chatserver.login(loginName, function(arg) {
                        //check the return value for success
                        if (arg === true) {
                            loginUi.nameInUseError.visible = false;
                            loginWindow.close();
                        } else {
                            loginUi.nameInUseError.visible = true;
                        }
                    });
                }
            }
        }
    }

    Dialog {
        id: errorDialog
        property alias text: message.text

        anchors.centerIn: parent
        // FIXME: icon!
        //icon: StandardIcon.Critical
        standardButtons: Dialog.Close
        title: "Chat client"

        Text {
            id: message
        }

        onAccepted: {
            Qt.quit();
        }
        onRejected: {
            Qt.quit();
        }
    }
}