Move QML files to src/qml and don't use internal qml modules
This commit is contained in:
475
src/qml/main.qml
Normal file
475
src/qml/main.qml
Normal file
@@ -0,0 +1,475 @@
|
||||
// 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 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ApplicationWindow {
|
||||
id: root
|
||||
|
||||
property int columnWidth: Kirigami.Units.gridUnit * 13
|
||||
|
||||
minimumWidth: Kirigami.Units.gridUnit * 15
|
||||
minimumHeight: Kirigami.Units.gridUnit * 15
|
||||
|
||||
visible: false // Will be overridden in Component.onCompleted
|
||||
wideScreen: width > columnWidth * 5
|
||||
|
||||
pageStack.initialPage: LoadingPage {}
|
||||
pageStack.globalToolBar.canContainHandles: true
|
||||
|
||||
property bool roomListLoaded: false
|
||||
|
||||
property RoomPage roomPage
|
||||
|
||||
Connections {
|
||||
target: root.quitAction
|
||||
function onTriggered() {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: Kirigami.Settings.hasPlatformMenuBar && !Kirigami.Settings.isMobile
|
||||
source: Qt.resolvedUrl("qrc:/GlobalMenu.qml")
|
||||
}
|
||||
|
||||
// This timer allows to batch update the window size change to reduce
|
||||
// the io load and also work around the fact that x/y/width/height are
|
||||
// changed when loading the page and overwrite the saved geometry from
|
||||
// the previous session.
|
||||
Timer {
|
||||
id: saveWindowGeometryTimer
|
||||
interval: 1000
|
||||
onTriggered: Controller.saveWindowGeometry()
|
||||
}
|
||||
|
||||
Connections {
|
||||
id: saveWindowGeometryConnections
|
||||
enabled: false // Disable on startup to avoid writing wrong values if the window is hidden
|
||||
target: root
|
||||
|
||||
function onClosing() { Controller.saveWindowGeometry(); }
|
||||
function onWidthChanged() { saveWindowGeometryTimer.restart(); }
|
||||
function onHeightChanged() { saveWindowGeometryTimer.restart(); }
|
||||
function onXChanged() { saveWindowGeometryTimer.restart(); }
|
||||
function onYChanged() { saveWindowGeometryTimer.restart(); }
|
||||
}
|
||||
|
||||
|
||||
Loader {
|
||||
id: quickView
|
||||
active: !Kirigami.Settings.isMobile
|
||||
sourceComponent: QuickSwitcher { }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: RoomManager
|
||||
|
||||
function onPushRoom(room, event) {
|
||||
root.roomPage = pageStack.push("qrc:/RoomPage.qml");
|
||||
root.roomPage.forceActiveFocus();
|
||||
if (event.length > 0) {
|
||||
roomPage.goToEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
function onReplaceRoom(room, event) {
|
||||
const roomItem = pageStack.get(pageStack.depth - 1);
|
||||
pageStack.currentIndex = pageStack.depth - 1;
|
||||
root.roomPage.forceActiveFocus();
|
||||
if (event.length > 0) {
|
||||
roomItem.goToEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
function goToEvent(event) {
|
||||
if (event.length > 0) {
|
||||
roomItem.goToEvent(event);
|
||||
}
|
||||
roomItem.forceActiveFocus();
|
||||
}
|
||||
|
||||
function onPushWelcomePage() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
function onOpenRoomInNewWindow(room) {
|
||||
const secondayWindow = roomWindow.createObject(applicationWindow(), {currentRoom: room});
|
||||
secondayWiroomWindowndow.width = root.width - pageStack.get(0).width;
|
||||
secondayWindow.show();
|
||||
}
|
||||
|
||||
function onShowUserDetail(user) {
|
||||
const roomItem = pageStack.get(pageStack.depth - 1);
|
||||
roomItem.showUserDetail(user);
|
||||
}
|
||||
|
||||
function onAskDirectChatConfirmation(user) {
|
||||
askDirectChatConfirmationComponent.createObject(QQC2.ApplicationWindow.overlay, {
|
||||
user: user,
|
||||
}).open();
|
||||
}
|
||||
|
||||
function onWarning(title, message) {
|
||||
if (RoomManager.currentRoom) {
|
||||
const roomItem = pageStack.get(pageStack.depth - 1);
|
||||
roomItem.warning(title, message);
|
||||
} else {
|
||||
showPassiveNotification(i18n("Warning: %1", message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pushReplaceLayer(page, args) {
|
||||
if (pageStack.layers.depth === 2) {
|
||||
pageStack.layers.replace(page, args);
|
||||
} else {
|
||||
pageStack.layers.push(page, args);
|
||||
}
|
||||
}
|
||||
|
||||
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: Config.autoRoomInfoDrawer
|
||||
|
||||
// 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 (Config.autoRoomInfoDrawer) {
|
||||
drawerOpen = !modal && drawerUserState
|
||||
dim = false
|
||||
}
|
||||
}
|
||||
enabled: RoomManager.hasOpenRoom && pageStack.layers.depth < 2 && pageStack.depth < 3
|
||||
handleVisible: enabled && pageStack.layers.depth < 2 && pageStack.depth < 3 && (root.wideScreen || pageStack.currentIndex > 0)
|
||||
}
|
||||
|
||||
readonly property int defaultPageWidth: Kirigami.Units.gridUnit * 17
|
||||
readonly property int minPageWidth: Kirigami.Units.gridUnit * 10
|
||||
readonly property int collapsedPageWidth: Kirigami.Units.gridUnit * 3 - Kirigami.Units.smallSpacing * 3
|
||||
readonly property bool shouldUseSidebars: RoomManager.hasOpenRoom && (Config.roomListPageWidth > minPageWidth ? root.width >= Kirigami.Units.gridUnit * 35 : root.width > Kirigami.Units.gridUnit * 27) && roomListLoaded
|
||||
readonly property int pageWidth: {
|
||||
if (Config.roomListPageWidth === -1) {
|
||||
return defaultPageWidth;
|
||||
} else if (Config.roomListPageWidth < minPageWidth) {
|
||||
return collapsedPageWidth;
|
||||
} else {
|
||||
return Config.roomListPageWidth;
|
||||
}
|
||||
}
|
||||
|
||||
pageStack.defaultColumnWidth: pageWidth
|
||||
pageStack.globalToolBar.style: Kirigami.ApplicationHeaderStyle.ToolBar
|
||||
pageStack.globalToolBar.showNavigationButtons: pageStack.currentIndex > 0 ? Kirigami.ApplicationHeaderStyle.ShowBackButton : 0
|
||||
pageStack.columnView.columnResizeMode: shouldUseSidebars ? Kirigami.ColumnView.FixedColumns : Kirigami.ColumnView.SingleColumn
|
||||
|
||||
MouseArea {
|
||||
visible: root.pageStack.wideMode
|
||||
z: 500
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
x: root.pageStack.defaultColumnWidth - (width / 2)
|
||||
width: 2
|
||||
|
||||
property int _lastX: -1
|
||||
enabled: !Kirigami.Settings.isMobile
|
||||
|
||||
cursorShape: !Kirigami.Settings.isMobile ? Qt.SplitHCursor : undefined
|
||||
|
||||
onPressed: _lastX = mouseX
|
||||
onReleased: Config.save();
|
||||
|
||||
onPositionChanged: {
|
||||
if (_lastX == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mouse.x > _lastX) {
|
||||
// we moved to the right
|
||||
if (Config.roomListPageWidth === root.collapsedPageWidth && root.pageWidth + (mouse.x - _lastX) >= root.minPageWidth) {
|
||||
// Here we get back directly to a more wide mode.
|
||||
Config.roomListPageWidth = root.minPageWidth;
|
||||
if (root.width < Kirigami.Units.gridUnit * 35) {
|
||||
root.width = Kirigami.Units.gridUnit * 35;
|
||||
}
|
||||
} else if (Config.roomListPageWidth !== root.collapsedPageWidth) {
|
||||
// Increase page width
|
||||
Config.roomListPageWidth = Math.min(root.defaultPageWidth, root.pageWidth + (mouse.x - _lastX));
|
||||
}
|
||||
} else if (mouse.x < _lastX) {
|
||||
const tmpWidth = root.pageWidth - (_lastX - mouse.x);
|
||||
|
||||
if (tmpWidth < root.minPageWidth) {
|
||||
Config.roomListPageWidth = root.collapsedPageWidth;
|
||||
} else {
|
||||
Config.roomListPageWidth = tmpWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
globalDrawer: Kirigami.GlobalDrawer {
|
||||
property bool hasLayer
|
||||
contentItem.implicitWidth: columnWidth
|
||||
isMenu: true
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
text: i18n("Explore rooms")
|
||||
icon.name: "compass"
|
||||
onTriggered: pushReplaceLayer("qrc:/JoinRoomPage.qml", {connection: Controller.activeConnection})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Explore Rooms") && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Start a Chat")
|
||||
icon.name: "irc-join-channel"
|
||||
onTriggered: pushReplaceLayer("qrc:/StartChatPage.qml", {connection: Controller.activeConnection})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Create a Room")
|
||||
icon.name: "irc-join-channel"
|
||||
onTriggered: {
|
||||
let dialog = createRoomDialog.createObject(root.overlay);
|
||||
dialog.open();
|
||||
}
|
||||
shortcut: StandardKey.New
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Configure NeoChat...")
|
||||
icon.name: "settings-configure"
|
||||
onTriggered: pageStack.pushDialogLayer("qrc:/SettingsPage.qml", {}, {
|
||||
title: i18n("Configure")
|
||||
})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Configure NeoChat...")
|
||||
shortcut: StandardKey.Preferences
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Logout")
|
||||
icon.name: "list-remove-user"
|
||||
enabled: Controller.accountCount > 0
|
||||
onTriggered: Controller.logout(Controller.activeConnection, true)
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Quit")
|
||||
icon.name: "gtk-quit"
|
||||
shortcut: StandardKey.Quit
|
||||
onTriggered: Qt.quit()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
Controller.setBlur(pageStack, Config.blur && !Config.compactLayout);
|
||||
if (Config.minimizeToSystemTrayOnStartup && !Kirigami.Settings.isMobile && Controller.supportSystemTray && Config.systemTray) {
|
||||
restoreWindowGeometryConnections.enabled = true; // To restore window size and position
|
||||
} else {
|
||||
visible = true;
|
||||
saveWindowGeometryConnections.enabled = true;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: Config
|
||||
function onBlurChanged() {
|
||||
Controller.setBlur(pageStack, Config.blur && !Config.compactLayout);
|
||||
}
|
||||
function onCompactLayoutChanged() {
|
||||
Controller.setBlur(pageStack, Config.blur && !Config.compactLayout);
|
||||
}
|
||||
}
|
||||
|
||||
// blur effect
|
||||
color: Config.blur && !Config.compactLayout ? "transparent" : Kirigami.Theme.backgroundColor
|
||||
|
||||
// we need to apply the translucency effect separately on top of the color
|
||||
background: Rectangle {
|
||||
color: Config.blur && !Config.compactLayout ? Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 1 - Config.transparency) : "transparent"
|
||||
}
|
||||
|
||||
Component {
|
||||
id: roomListComponent
|
||||
RoomListPage {
|
||||
id: roomList
|
||||
|
||||
Connections {
|
||||
target: root.roomPage
|
||||
function onSwitchRoomUp() {
|
||||
roomList.goToPreviousRoom();
|
||||
}
|
||||
function onSwitchRoomDown() {
|
||||
roomList.goToNextRoom();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: AccountRegistry
|
||||
function onRowsRemoved() {
|
||||
if (AccountRegistry.rowCount() === 0) {
|
||||
RoomManager.reset();
|
||||
pageStack.clear();
|
||||
roomListLoaded = false;
|
||||
pageStack.push("qrc:/WelcomePage.qml");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Controller
|
||||
|
||||
function onInitiated() {
|
||||
if (Controller.accountCount === 0) {
|
||||
pageStack.replace("qrc:/WelcomePage.qml", {});
|
||||
} else if (!roomListLoaded) {
|
||||
pageStack.replace(roomListComponent, {
|
||||
activeConnection: Controller.activeConnection
|
||||
});
|
||||
roomListLoaded = true;
|
||||
RoomManager.loadInitialRoom();
|
||||
}
|
||||
}
|
||||
|
||||
function onGlobalErrorOccured(error, detail) {
|
||||
showPassiveNotification(i18n("%1: %2", error, detail));
|
||||
}
|
||||
|
||||
function onUserConsentRequired(url) {
|
||||
consentSheet.url = url
|
||||
consentSheet.open()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
id: restoreWindowGeometryConnections
|
||||
enabled: false
|
||||
target: root
|
||||
|
||||
function onVisibleChanged() {
|
||||
if (!visible) {
|
||||
return;
|
||||
}
|
||||
Controller.restoreWindowGeometry(root);
|
||||
restoreWindowGeometryConnections.enabled = false; // Only restore window geometry for the first time
|
||||
saveWindowGeometryConnections.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: keyVerificationDialogComponent
|
||||
KeyVerificationDialog { }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Controller.activeConnection
|
||||
function onDirectChatAvailable(directChat) {
|
||||
RoomManager.enterRoom(Controller.activeConnection.room(directChat.id));
|
||||
}
|
||||
function onNewKeyVerificationSession(session) {
|
||||
applicationWindow().pageStack.pushDialogLayer(keyVerificationDialogComponent, {
|
||||
session: session,
|
||||
}, {
|
||||
title: i18nc("@title:window", "Session Verification")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: consentSheet
|
||||
|
||||
property string url: ""
|
||||
|
||||
title: i18n("User consent")
|
||||
|
||||
QQC2.Label {
|
||||
id: label
|
||||
|
||||
text: i18n("Your homeserver requires you to agree to its terms and conditions before being able to use it. Please click the button below to read them.")
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
}
|
||||
footer: QQC2.Button {
|
||||
text: i18n("Open")
|
||||
onClicked: UrlHelper.openUrl(consentSheet.url)
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: createRoomDialog
|
||||
|
||||
CreateRoomDialog {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: roomWindow
|
||||
RoomWindow {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: userDialog
|
||||
UserDetailDialog {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: askDirectChatConfirmationComponent
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: askDirectChatConfirmation
|
||||
required property var user;
|
||||
|
||||
parent: QQC2.ApplicationWindow.overlay
|
||||
title: i18n("Start a chat")
|
||||
contentItem: QQC2.Label {
|
||||
text: i18n("Do you want to start a chat with %1?", user.displayName)
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
footer: QQC2.DialogButtonBox {
|
||||
standardButtons: QQC2.DialogButtonBox.Ok | QQC2.DialogButtonBox.Cancel
|
||||
onAccepted: {
|
||||
user.requestDirectChat();
|
||||
askDirectChatConfirmation.close();
|
||||
}
|
||||
onRejected: askDirectChatConfirmation.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Item hoverLinkIndicator: QQC2.Control {
|
||||
parent: overlay.parent
|
||||
property string text
|
||||
opacity: linkText.text.length > 0 ? 1 : 0
|
||||
|
||||
z: 20
|
||||
x: 0
|
||||
y: parent.height - implicitHeight
|
||||
contentItem: QQC2.Label {
|
||||
id: linkText
|
||||
text: parent.text.startsWith("https://matrix.to/") ? "" : parent.text
|
||||
}
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
background: Rectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user