From 6d9974b2b142d8025938d947d261d08ed3911157 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 27 Oct 2025 16:46:10 -0400 Subject: [PATCH] Improve the Jitsi meeting button UX Widgets support is incredibly useful and so is this button, but it has a few problems. The most obvious is that it's still enabled even if you don't actually have the permission to start Jitsi meetings, so I fixed that. I also made sure it's hidden when viewing spaces too. Another problem is that you can't easily tell if a meeting is currently in progress either, nor do we have a good icon for that in Breeze. So I changed the tooltip and colored the icon in this case. The final problem I fixed is something not exclusive to NeoChat, but generally all chat applications with this feature - there's no confirmation! To stop "butt-dialing" random people or rooms, I added a prompt before starting or joining a meeting. --- src/app/CMakeLists.txt | 1 + src/app/qml/MeetingDialog.qml | 22 ++++++++++++++++++++++ src/app/qml/RoomPage.qml | 30 ++++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 src/app/qml/MeetingDialog.qml diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index e92e56f1a..c711c6e3a 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -103,6 +103,7 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE qml/ReasonDialog.qml qml/NewPollDialog.qml qml/UserMenu.qml + qml/MeetingDialog.qml DEPENDENCIES QtCore QtQuick diff --git a/src/app/qml/MeetingDialog.qml b/src/app/qml/MeetingDialog.qml new file mode 100644 index 000000000..085441c23 --- /dev/null +++ b/src/app/qml/MeetingDialog.qml @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2025 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-only + +import QtQuick + +import org.kde.kirigami as Kirigami + +Kirigami.PromptDialog { + id: root + + required property bool hasExistingMeeting + + title: hasExistingMeeting ? i18nc("@title", "Join Meeting") : i18nc("@title", "Start Meeting") + subtitle: hasExistingMeeting ? i18nc("@info:label", "You are about to join a Jitsi meeting in your web browser.") : i18nc("@info:label", "You are about to start a new Jitsi meeting in your web browser.") + standardButtons: Kirigami.Dialog.Cancel + + customFooterActions: Kirigami.Action { + icon.name: "camera-video-symbolic" + text: hasExistingMeeting ? i18nc("@action:button Join the Jitsi meeting", "Join") : i18nc("@action:button Start a new Jitsi meeting", "Start") + onTriggered: root.accept() + } +} diff --git a/src/app/qml/RoomPage.qml b/src/app/qml/RoomPage.qml index 2a00559ee..a2231430c 100644 --- a/src/app/qml/RoomPage.qml +++ b/src/app/qml/RoomPage.qml @@ -77,11 +77,33 @@ Kirigami.Page { actions: [ Kirigami.Action { - tooltip: i18nc("@action:button", "Open Jitsi Meet in browser") - icon.name: "camera-video-symbolic" + id: jitsiMeetingAction + + readonly property bool hasExistingMeeting: root.widgetModel.jitsiIndex >= 0 + readonly property bool canStartNewMeeting: root.currentRoom.canSendState("im.vector.modular.widgets") + + tooltip: { + if (hasExistingMeeting) { + return i18nc("@action:button", "Join Jitsi meeting…"); + } + + return canStartNewMeeting ? i18nc("@action:button", "Start Jitsi meeting…") : i18nc("@action:button", "You do not have permissions to start Jitsi meetings") + } + icon { + name: "camera-video-symbolic" + color: hasExistingMeeting ? Kirigami.Theme.highlightColor : "transparent" + } + enabled: hasExistingMeeting || canStartNewMeeting + visible: root.currentRoom && !root.currentRoom.isSpace onTriggered: { - let url - if (root.widgetModel.jitsiIndex < 0) { + const dialog = Qt.createComponent("org.kde.neochat", "MeetingDialog").createObject(QQC2.Overlay.overlay, { hasExistingMeeting }); + dialog.onAccepted.connect(doAction); + dialog.open(); + } + + function doAction(): void { + let url; + if (!hasExistingMeeting) { url = root.widgetModel.addJitsiConference(); } else { let idx = root.widgetModel.index(root.widgetModel.jitsiIndex, 0);