This fixes some glitches during animation, which had the background disappearing when the pop animation was running, and now uses always the pagerow for viewing the room. This depends from the new PageRow animation on mobile, https://invent.kde.org/frameworks/kirigami/-/merge_requests/1925 which makes all applications coherent with an application which looks a bit more like the one on most android apps. Also, the swipe back gesture now will work there too
382 lines
13 KiB
QML
382 lines
13 KiB
QML
// SPDX-FileCopyrightText: 2018-2020 Black Hat <bhat@encom.eu.org>
|
|
// SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
import QtQuick
|
|
|
|
import org.kde.kirigami as Kirigami
|
|
import org.kde.config as KConfig
|
|
|
|
import org.kde.neochat
|
|
import org.kde.neochat.login
|
|
import org.kde.neochat.settings
|
|
|
|
Kirigami.ApplicationWindow {
|
|
id: root
|
|
|
|
property NeoChatConnection connection: Controller.activeConnection
|
|
readonly property HoverLinkIndicator hoverLinkIndicator: linkIndicator
|
|
|
|
property bool initialized: false
|
|
|
|
readonly property QuickSwitcher quickSwitcher: QuickSwitcher {
|
|
connection: root.connection
|
|
window: root
|
|
}
|
|
|
|
title: {
|
|
if (NeoChatConfig.windowTitleFocus) {
|
|
return activeFocusItem + " " + (activeFocusItem ? activeFocusItem.Accessible.name : "");
|
|
} else if (RoomManager.currentRoom) {
|
|
return RoomManager.currentRoom.displayName;
|
|
} else {
|
|
return Application.displayName;
|
|
}
|
|
}
|
|
|
|
minimumWidth: Kirigami.Units.gridUnit * 20
|
|
minimumHeight: Kirigami.Units.gridUnit * 15
|
|
|
|
visible: false // Will be overridden in Component.onCompleted
|
|
wideScreen: width > Kirigami.Units.gridUnit * 65
|
|
|
|
pageStack {
|
|
initialPage: WelcomePage {
|
|
showExisting: true
|
|
onConnectionChosen: root.load()
|
|
}
|
|
columnView.columnResizeMode: pageStack.wideMode ? Kirigami.ColumnView.DynamicColumns : Kirigami.ColumnView.SingleColumn
|
|
globalToolBar.canContainHandles: true
|
|
globalToolBar {
|
|
style: Kirigami.ApplicationHeaderStyle.ToolBar
|
|
showNavigationButtons: pageStack.currentIndex > 0 || pageStack.layers.depth > 1 ? Kirigami.ApplicationHeaderStyle.ShowBackButton : 0
|
|
}
|
|
}
|
|
|
|
onConnectionChanged: {
|
|
CustomEmojiModel.connection = root.connection;
|
|
SpaceHierarchyCache.connection = root.connection;
|
|
NeoChatSettingsView.connection = root.connection;
|
|
if (ShareHandler.text && root.connection) {
|
|
root.handleShare();
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: LoginHelper
|
|
function onLoaded() {
|
|
root.load();
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: Registration
|
|
function onLoaded() {
|
|
root.load();
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: root.quitAction
|
|
function onTriggered() {
|
|
Qt.quit();
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
active: Kirigami.Settings.hasPlatformMenuBar && !Kirigami.Settings.isMobile
|
|
sourceComponent: GlobalMenu {
|
|
connection: root.connection
|
|
appWindow: root
|
|
}
|
|
}
|
|
|
|
KConfig.WindowStateSaver {
|
|
configGroupName: "MainWindow"
|
|
}
|
|
|
|
Connections {
|
|
target: RoomManager
|
|
|
|
function onCurrentRoomChanged() {
|
|
if (RoomManager.currentRoom && root.pageStack.depth <= 1 && root.initialized && Kirigami.Settings.isMobile) {
|
|
let roomPage = pageStack.push(Qt.createComponent('org.kde.neochat', 'RoomPage'));
|
|
roomPage.forceActiveFocus();
|
|
roomPage.backRequested.connect(event => {
|
|
RoomManager.clearCurrentRoom();
|
|
});
|
|
}
|
|
}
|
|
|
|
function onAskJoinRoom(room) {
|
|
(Qt.createComponent("org.kde.neochat", "JoinRoomDialog").createObject(root, {
|
|
room: room,
|
|
connection: root.connection
|
|
}) as JoinRoomDialog).open();
|
|
}
|
|
|
|
function onShowUserDetail(user, room) {
|
|
root.showUserDetail(user, room);
|
|
}
|
|
|
|
function onAskDirectChatConfirmation(user) {
|
|
(Qt.createComponent("org.kde.neochat", "AskDirectChatConfirmation").createObject(this, {
|
|
user: user
|
|
}) as AskDirectChatConfirmation).open();
|
|
}
|
|
|
|
function onExternalUrl(url) {
|
|
(Qt.createComponent("org.kde.neochat", "ConfirmUrlDialog").createObject(this, {
|
|
link: url
|
|
}) as ConfirmUrlDialog).open();
|
|
}
|
|
}
|
|
|
|
function pushReplaceLayer(page, args) {
|
|
if (pageStack.layers.depth === 2) {
|
|
pageStack.layers.replace(page, args);
|
|
} else {
|
|
pageStack.layers.push(page, args);
|
|
}
|
|
}
|
|
|
|
function openRoomDrawer() {
|
|
const page = pageStack.push(Qt.createComponent('org.kde.neochat', 'RoomDrawerPage'), {
|
|
connection: root.connection,
|
|
room: RoomManager.currentRoom,
|
|
userListModel: RoomManager.userListModel,
|
|
mediaMessageFilterModel: RoomManager.mediaMessageFilterModel
|
|
});
|
|
page.resolveResource.connect((idOrUri, action) => RoomManager.resolveResource(idOrUri, action))
|
|
}
|
|
|
|
contextDrawer: RoomDrawer {
|
|
id: contextDrawer
|
|
|
|
// This is a memory for all user initiated actions on the drawer, i.e. clicking the button
|
|
// It is used to ensure that user choice is remembered when changing pages and expanding and contracting the window width
|
|
property bool drawerUserState: NeoChatConfig.autoRoomInfoDrawer
|
|
|
|
room: RoomManager.currentRoom
|
|
connection: root.connection
|
|
userListModel: RoomManager.userListModel
|
|
mediaMessageFilterModel: RoomManager.mediaMessageFilterModel
|
|
|
|
onResolveResource: (idOrUri, action) => RoomManager.resolveResource(idOrUri, action)
|
|
|
|
roomDrawerWidth: NeoChatConfig.roomDrawerWidth
|
|
onRoomDrawerWidthChanged: {
|
|
NeoChatConfig.roomDrawerWidth = actualWidth;
|
|
NeoChatConfig.save();
|
|
}
|
|
|
|
handleClosedIcon.source: "documentinfo-symbolic"
|
|
handleClosedToolTip: i18nc("@action:button", "Show Room Information")
|
|
|
|
// Default icon is fine, only need to override the tooltip text
|
|
handleOpenToolTip: i18nc("@action:button", "Close Room Information Drawer")
|
|
|
|
// Connect to the onClicked function of the RoomDrawer handle button
|
|
Connections {
|
|
target: contextDrawer.handle.children[0]
|
|
function onClicked() {
|
|
contextDrawer.drawerUserState = contextDrawer.drawerOpen;
|
|
}
|
|
}
|
|
|
|
modal: (!root.wideScreen || !enabled)
|
|
onEnabledChanged: drawerOpen = enabled && !modal
|
|
onModalChanged: {
|
|
if (NeoChatConfig.autoRoomInfoDrawer) {
|
|
drawerOpen = !modal && drawerUserState;
|
|
dim = false;
|
|
}
|
|
}
|
|
enabled: RoomManager.hasOpenRoom && root.pageStack.layers.depth < 2 && root.pageStack.depth < 3 && (root.pageStack.visibleItems.length > 1 || root.pageStack.currentIndex > 0) && !Kirigami.Settings.isMobile && root.pageStack.wideMode
|
|
handleVisible: enabled
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
CustomEmojiModel.connection = root.connection;
|
|
SpaceHierarchyCache.connection = root.connection;
|
|
RoomSettingsView.window = root;
|
|
NeoChatSettingsView.window = root;
|
|
NeoChatSettingsView.connection = root.connection;
|
|
WindowController.setBlur(pageStack, NeoChatConfig.blur && !NeoChatConfig.compactLayout);
|
|
if (ShareHandler.text && root.connection) {
|
|
root.handleShare()
|
|
}
|
|
const hasSystemTray = Controller.supportSystemTray && NeoChatConfig.systemTray;
|
|
if (Kirigami.Settings.isMobile || !(hasSystemTray && NeoChatConfig.minimizeToSystemTrayOnStartup)) {
|
|
visible = true;
|
|
}
|
|
}
|
|
Connections {
|
|
target: NeoChatConfig
|
|
function onBlurChanged() {
|
|
WindowController.setBlur(root.pageStack, NeoChatConfig.blur && !NeoChatConfig.compactLayout);
|
|
}
|
|
function onCompactLayoutChanged() {
|
|
WindowController.setBlur(root.pageStack, NeoChatConfig.blur && !NeoChatConfig.compactLayout);
|
|
}
|
|
}
|
|
|
|
// blur effect
|
|
color: NeoChatConfig.blur && !NeoChatConfig.compactLayout ? "transparent" : Kirigami.Theme.backgroundColor
|
|
|
|
// we need to apply the translucency effect separately on top of the color
|
|
background: Rectangle {
|
|
color: NeoChatConfig.blur && !NeoChatConfig.compactLayout ? Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 1 - NeoChatConfig.transparency) : "transparent"
|
|
}
|
|
|
|
Component {
|
|
id: roomListComponent
|
|
RoomListPage {
|
|
id: roomList
|
|
|
|
onSearch: root.quickSwitcher.open()
|
|
|
|
connection: root.connection
|
|
|
|
Shortcut {
|
|
sequences: ["Ctrl+PgUp", "Ctrl+Backtab", "Alt+Up"]
|
|
onActivated: {
|
|
roomList.goToPreviousRoom();
|
|
}
|
|
}
|
|
|
|
Shortcut {
|
|
sequences: ["Ctrl+PgDown", "Ctrl+Tab", "Alt+Down"]
|
|
onActivated: {
|
|
roomList.goToNextRoom();
|
|
}
|
|
}
|
|
|
|
Shortcut {
|
|
sequence: "Alt+Shift+Up"
|
|
onActivated: {
|
|
roomList.goToPreviousUnreadRoom();
|
|
}
|
|
}
|
|
|
|
Shortcut {
|
|
sequence: "Alt+Shift+Down"
|
|
onActivated: {
|
|
roomList.goToNextUnreadRoom();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: root.connection
|
|
function onLoggedOut(): void {
|
|
root.pageStack.clear();
|
|
let page = root.pageStack.push(Qt.createComponent('org.kde.neochat.login', 'WelcomePage'), {
|
|
showExisting: true,
|
|
}) as WelcomePage;
|
|
page.connectionChosen.connect(() => root.load())
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: AccountRegistry
|
|
function onRowsRemoved() {
|
|
if (AccountRegistry.rowCount() === 0) {
|
|
root.pageStack.clear();
|
|
root.pageStack.push(Qt.createComponent('org.kde.neochat.login', 'WelcomePage'));
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: Controller
|
|
|
|
function onErrorOccured(error) {
|
|
root.showPassiveNotification(error, "short");
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: root.connection
|
|
|
|
function onNewKeyVerificationSession(session) {
|
|
root.pageStack.pushDialogLayer(Qt.createComponent("org.kde.neochat", "KeyVerificationDialog"), {
|
|
session: session
|
|
}, {
|
|
title: i18nc("@title:window", "Session Verification")
|
|
});
|
|
}
|
|
function onUserConsentRequired(url) {
|
|
(Qt.createComponent("org.kde.neochat", "ConsentDialog").createObject(this, {
|
|
url: url
|
|
}) as ConsentDialog).open();
|
|
}
|
|
}
|
|
|
|
HoverLinkIndicator {
|
|
id: linkIndicator
|
|
|
|
anchors {
|
|
bottom: parent.bottom
|
|
left: parent.left
|
|
right: parent.right
|
|
rightMargin: Kirigami.Units.largeSpacing
|
|
}
|
|
}
|
|
|
|
Shortcut {
|
|
sequence: "Ctrl+Shift+,"
|
|
onActivated: {
|
|
NeoChatSettingsView.open();
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: ShareHandler
|
|
function onTextChanged(): void {
|
|
if (root.connection && ShareHandler.text.length > 0) {
|
|
root.handleShare();
|
|
}
|
|
}
|
|
}
|
|
function handleShare(): void {
|
|
const dialog = root.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'ChooseRoomDialog'), {
|
|
connection: root.connection
|
|
}, {
|
|
title: i18nc("@title", "Share"),
|
|
width: Kirigami.Units.gridUnit * 25
|
|
})
|
|
dialog.chosen.connect(function(targetRoomId) {
|
|
RoomManager.resolveResource(targetRoomId)
|
|
ShareHandler.room = targetRoomId
|
|
dialog.closeDialog()
|
|
})
|
|
}
|
|
function showUserDetail(user, room) {
|
|
const dialog = Qt.createComponent("org.kde.neochat", "UserDetailDialog").createObject(root, {
|
|
room: room,
|
|
user: user,
|
|
connection: root.connection,
|
|
}) as UserDetailDialog;
|
|
// FIXME: The reason why we don't want the focusedWindowItem for the room null case (aka QR codes) is because it will parent it to the soon-to-be-destroyed window item.
|
|
// But this won't be a problem if we turn it into a Kirigami.Dialog or some other in-scene item, which it really should be.
|
|
if (room != null) {
|
|
dialog.parent = QmlUtils.focusedWindowItem(); // Kirigami Dialogs overwrite the parent, so we need to set it again
|
|
}
|
|
dialog.open();
|
|
}
|
|
|
|
function load() {
|
|
pageStack.replace(roomListComponent);
|
|
RoomManager.loadInitialRoom();
|
|
|
|
if (!Kirigami.Settings.isMobile) {
|
|
let roomPage = pageStack.push(Qt.createComponent('org.kde.neochat', 'RoomPage'));
|
|
roomPage.forceActiveFocus();
|
|
}
|
|
|
|
initialized = true;
|
|
}
|
|
}
|