A lot of improvements.
Fix laggish RoomListView when dragging. Remove per-room timer and add timer in RoomForm. Remove singleton module and use file as singleton. Minor UI tweak in RoomListView. Pass room to RoomListView via "currentRoom" delegate property and remove RoomListForm-wide currentRoom. Put menu files in a separate folder. Show initial image in ImageStatus when avatar is not loaded. Add about page. Merge all setting pages into Setting.qml. Add option to rearrange rooms by activity. Add option to use RichText parser. Add document url.
This commit is contained in:
parent
391473e559
commit
cfa8043596
|
@ -32,7 +32,7 @@ RESOURCES += \
|
|||
res.qrc
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH += qml/MatriqueSettings
|
||||
QML_IMPORT_PATH =
|
||||
|
||||
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
QML_DESIGNER_IMPORT_PATH =
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
</categories>
|
||||
<url type="homepage">https://gitlab.com/b0/matrique</url>
|
||||
<url type="bugtracker">https://gitlab.com/b0/matrique/issues</url>
|
||||
<url type="help">https://doc.matrique.encom.eu.org</url>
|
||||
<content_rating type="oars-1.0">
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
<content_attribute id="social-audio">intense</content_attribute>
|
||||
|
|
|
@ -4,6 +4,8 @@ import QtGraphicalEffects 1.0
|
|||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import Qt.labs.settings 1.0
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
import "qrc:/qml/component"
|
||||
|
||||
Page {
|
||||
|
@ -76,7 +78,7 @@ Page {
|
|||
background: Rectangle {
|
||||
implicitHeight: 48
|
||||
|
||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
||||
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||
border.color: parent.activeFocus ? Material.accent : "transparent"
|
||||
border.width: 2
|
||||
}
|
||||
|
@ -96,7 +98,7 @@ Page {
|
|||
background: Rectangle {
|
||||
implicitHeight: 48
|
||||
|
||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
||||
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||
border.color: parent.activeFocus ? Material.accent : "transparent"
|
||||
border.width: 2
|
||||
}
|
||||
|
@ -117,7 +119,7 @@ Page {
|
|||
background: Rectangle {
|
||||
implicitHeight: 48
|
||||
|
||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
||||
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||
border.color: parent.activeFocus ? Material.accent : "transparent"
|
||||
border.width: 2
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ Settings {
|
|||
property bool asyncMessageDelegate
|
||||
property bool richText
|
||||
property bool pressAndHold
|
||||
property bool rearrangeByActivity
|
||||
|
||||
property bool darkTheme
|
||||
property bool miniMode
|
|
@ -1,26 +0,0 @@
|
|||
import QtQuick.tooling 1.2
|
||||
|
||||
// This file describes the plugin-supplied types contained in the library.
|
||||
// It is used for QML tooling purposes only.
|
||||
//
|
||||
// This file was auto-generated by:
|
||||
// 'qmlplugindump -nonrelocatable MatriqueSettings 0.1 qml/'
|
||||
|
||||
Module {
|
||||
dependencies: ["Qt.labs.settings 1.0", "QtQuick 2.9"]
|
||||
Component {
|
||||
prototype: "QQmlSettings"
|
||||
name: "MatriqueSettings 0.1"
|
||||
exports: ["MatriqueSettings 0.1"]
|
||||
exportMetaObjectRevisions: [1]
|
||||
isComposite: true
|
||||
isCreatable: false
|
||||
isSingleton: true
|
||||
Property { name: "lazyLoad"; type: "bool" }
|
||||
Property { name: "asyncMessageDelegate"; type: "bool" }
|
||||
Property { name: "richText"; type: "bool" }
|
||||
Property { name: "pressAndHold"; type: "bool" }
|
||||
Property { name: "darkTheme"; type: "bool" }
|
||||
Property { name: "miniMode"; type: "bool" }
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
module MatriqueSettings
|
||||
singleton MatriqueSettings 0.1 MatriqueSettings.qml
|
14
qml/Room.qml
14
qml/Room.qml
|
@ -2,7 +2,7 @@ import QtQuick 2.9
|
|||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import Matrique 0.1
|
||||
import MatriqueSettings 0.1
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
import "qrc:/qml/form"
|
||||
|
||||
|
@ -14,10 +14,8 @@ Page {
|
|||
RoomListModel {
|
||||
id: roomListModel
|
||||
|
||||
onRoomAdded: MatriqueSettings.lazyLoad ? {} : room.getPreviousContent(20)
|
||||
onNewMessage: window.active ? {} : matriqueController.showMessage(roomName, content, icon)
|
||||
|
||||
onDataChanged: roomListForm.rawCurrentIndex = -1
|
||||
onRoomAdded: if (!MSettings.lazyLoad) room.getPreviousContent(20)
|
||||
onNewMessage: if (!window.active) matriqueController.showMessage(roomName, content, icon)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
@ -28,13 +26,11 @@ Page {
|
|||
id: roomListForm
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: MatriqueSettings.miniMode ? 80 : page.width * 0.35
|
||||
Layout.preferredWidth: MSettings.miniMode ? 80 : page.width * 0.35
|
||||
Layout.minimumWidth: 80
|
||||
Layout.maximumWidth: 360
|
||||
|
||||
listModel: roomListModel
|
||||
|
||||
onEnterRoom: roomForm.currentRoom = currentRoom
|
||||
}
|
||||
|
||||
RoomForm {
|
||||
|
@ -42,6 +38,8 @@ Page {
|
|||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
currentRoom: roomListForm.enteredRoom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
119
qml/Setting.qml
119
qml/Setting.qml
|
@ -2,6 +2,7 @@ import QtQuick 2.9
|
|||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
import "component"
|
||||
import "form"
|
||||
|
@ -9,24 +10,133 @@ import "form"
|
|||
Page {
|
||||
property var connection
|
||||
|
||||
SettingAccountForm {
|
||||
Page {
|
||||
id: accountForm
|
||||
parent: null
|
||||
|
||||
padding: 64
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Layout.preferredHeight: 60
|
||||
|
||||
ImageStatus {
|
||||
Layout.preferredWidth: height
|
||||
Layout.fillHeight: true
|
||||
|
||||
source: matriqueController.isLogin ? connection.localUser && connection.localUser.avatarUrl ? "image://mxc/" + connection.localUser.avatarUrl : "" : "qrc:/asset/img/avatar.png"
|
||||
displayText: matriqueController.isLogin && connection.localUser.displayName ? connection.localUser.displayName : ""
|
||||
}
|
||||
|
||||
SettingGeneralForm {
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Label {
|
||||
font.pointSize: 18
|
||||
text: matriqueController.isLogin ? connection.localUser.displayName : ""
|
||||
}
|
||||
|
||||
Label {
|
||||
font.pointSize: 12
|
||||
text: matriqueController.isLogin ? connection.localUser.id : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Logout"
|
||||
highlighted: true
|
||||
|
||||
onClicked: {
|
||||
matriqueController.logout()
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Page {
|
||||
id: generalForm
|
||||
parent: null
|
||||
Column {
|
||||
Switch {
|
||||
text: "Lazy load at initial sync"
|
||||
checked: MSettings.lazyLoad
|
||||
onCheckedChanged: MSettings.lazyLoad = checked
|
||||
}
|
||||
Switch {
|
||||
text: "Force loading message delegates asynchronously"
|
||||
checked: MSettings.asyncMessageDelegate
|
||||
onCheckedChanged: MSettings.asyncMessageDelegate = checked
|
||||
}
|
||||
Switch {
|
||||
text: "Use RichText instead of StyledText"
|
||||
checked: MSettings.richText
|
||||
onCheckedChanged: MSettings.richText = checked
|
||||
}
|
||||
Switch {
|
||||
text: "Use press and hold instead of right click"
|
||||
checked: MSettings.pressAndHold
|
||||
onCheckedChanged: MSettings.pressAndHold = checked
|
||||
}
|
||||
Switch {
|
||||
text: "Rearrange rooms by activity"
|
||||
checked: MSettings.rearrangeByActivity
|
||||
onCheckedChanged: MSettings.rearrangeByActivity = checked
|
||||
}
|
||||
|
||||
SettingAppearanceForm {
|
||||
Button {
|
||||
text: "Invoke GC"
|
||||
highlighted: true
|
||||
onClicked: gc()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Page {
|
||||
id: appearanceForm
|
||||
parent: null
|
||||
Column {
|
||||
Switch {
|
||||
text: "Dark theme"
|
||||
checked: MSettings.darkTheme
|
||||
onCheckedChanged: MSettings.darkTheme = checked
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: "Mini Room List"
|
||||
checked: MSettings.miniMode
|
||||
onCheckedChanged: MSettings.miniMode = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Page {
|
||||
id: aboutForm
|
||||
parent: null
|
||||
|
||||
padding: 64
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 16
|
||||
Image {
|
||||
Layout.preferredWidth: 64
|
||||
Layout.preferredHeight: 64
|
||||
|
||||
source: "qrc:/asset/img/icon.png"
|
||||
}
|
||||
Label {
|
||||
text: "Matrique, an IM client for the Matrix protocol."
|
||||
}
|
||||
Label {
|
||||
text: "Released under GNU General Public License, version 3."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
Material.elevation: 10
|
||||
Layout.preferredWidth: 240
|
||||
Layout.fillHeight: true
|
||||
|
||||
|
@ -57,6 +167,7 @@ Page {
|
|||
Layout.fillWidth: true
|
||||
|
||||
text: "About"
|
||||
onClicked: pushToStack(aboutForm)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import QtQuick 2.9
|
||||
import MatriqueSettings 0.1
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
MouseArea {
|
||||
signal primaryClicked()
|
||||
signal secondaryClicked()
|
||||
|
||||
propagateComposedEvents: true
|
||||
acceptedButtons: MatriqueSettings.pressAndHold ? Qt.LeftButton : (Qt.LeftButton | Qt.RightButton)
|
||||
acceptedButtons: MSettings.pressAndHold ? Qt.LeftButton : (Qt.LeftButton | Qt.RightButton)
|
||||
onClicked: mouse.button == Qt.RightButton ? secondaryClicked() : primaryClicked()
|
||||
onPressAndHold: MatriqueSettings.pressAndHold ? secondaryClicked() : {}
|
||||
onPressAndHold: MSettings.pressAndHold ? secondaryClicked() : {}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ Item {
|
|||
property string source: ""
|
||||
property string displayText: ""
|
||||
readonly property bool showImage: source
|
||||
readonly property bool showInitial: !showImage && displayText
|
||||
readonly property bool showInitial: !showImage && displayText || avatar.status != Image.Ready
|
||||
|
||||
id: item
|
||||
|
||||
|
@ -55,6 +55,7 @@ Item {
|
|||
}
|
||||
|
||||
function getInitials(text) {
|
||||
if (!text) return "N"
|
||||
return text.toUpperCase().replace(/[^a-zA-Z- ]/g, "").match(/\b\w/g);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
Item {
|
||||
property alias icon: iconText.text
|
||||
property var color: Material.theme == Material.Light ? "black" : "white"
|
||||
property var color: MSettings.darkTheme ? "white" : "black"
|
||||
|
||||
id: item
|
||||
|
||||
|
|
|
@ -2,14 +2,11 @@ import QtQuick 2.9
|
|||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import Matrique 0.1
|
||||
import MatriqueSettings 0.1
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
Item {
|
||||
readonly property bool hidden: marks === EventStatus.Redacted || marks === EventStatus.Hidden
|
||||
|
||||
readonly property bool darkTheme: Material.theme == Material.Dark
|
||||
readonly property color background: darkTheme ? "#242424" : "lightgrey"
|
||||
|
||||
readonly property color background: MSettings.darkTheme ? "#242424" : "lightgrey"
|
||||
readonly property bool sentByMe: author === currentRoom.localUser
|
||||
readonly property bool isState: eventType === "state" || eventType === "emote"
|
||||
|
||||
|
@ -24,13 +21,15 @@ Item {
|
|||
|
||||
AutoMouseArea {
|
||||
anchors.fill: parent
|
||||
onSecondaryClicked: Qt.createComponent("MessageContextMenu.qml").createObject(this)
|
||||
|
||||
propagateComposedEvents: true
|
||||
onSecondaryClicked: Qt.createComponent("qrc:/qml/menu/MessageContextMenu.qml").createObject(this)
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: delegateLoader
|
||||
|
||||
asynchronous: MatriqueSettings.asyncMessageDelegate
|
||||
asynchronous: MSettings.asyncMessageDelegate
|
||||
|
||||
source: {
|
||||
if (eventType == "redaction" || hidden) return ""
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
Rectangle {
|
||||
color: Material.accent
|
||||
}
|
|
@ -2,7 +2,7 @@ import QtQuick 2.9
|
|||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import MatriqueSettings 0.1
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
Rectangle {
|
||||
property bool flat: false
|
||||
|
@ -46,7 +46,7 @@ Rectangle {
|
|||
|
||||
wrapMode: Label.Wrap
|
||||
linkColor: darkBackground ? "white" : Material.accent
|
||||
textFormat: MatriqueSettings.richText ? Text.RichText : Text.StyledText
|
||||
textFormat: MSettings.richText ? Text.RichText : Text.StyledText
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,16 @@ import QtQuick.Layouts 1.3
|
|||
import QtQuick.Controls.Material 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import Matrique 0.1
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
import "qrc:/qml/component"
|
||||
import "qrc:/js/md.js" as Markdown
|
||||
|
||||
Item {
|
||||
id: item
|
||||
property var currentRoom: null
|
||||
|
||||
id: item
|
||||
|
||||
Drawer {
|
||||
id: roomDrawer
|
||||
|
||||
|
@ -114,7 +117,7 @@ Item {
|
|||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 80
|
||||
|
||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
||||
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
@ -185,7 +188,7 @@ Item {
|
|||
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
|
||||
model: MessageEventModel{
|
||||
model: MessageEventModel {
|
||||
id: messageEventModel
|
||||
room: currentRoom
|
||||
}
|
||||
|
@ -293,6 +296,26 @@ Item {
|
|||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 80
|
||||
|
||||
Timer {
|
||||
id: timeoutTimer
|
||||
|
||||
repeat: false
|
||||
interval: 2000
|
||||
onTriggered: {
|
||||
repeatTimer.stop()
|
||||
currentRoom.sendTypingNotification(false)
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: repeatTimer
|
||||
|
||||
repeat: true
|
||||
interval: 5000
|
||||
triggeredOnStart: true
|
||||
onTriggered: currentRoom.sendTypingNotification(true)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
@ -320,7 +343,8 @@ Item {
|
|||
|
||||
text: currentRoom ? currentRoom.cachedInput : ""
|
||||
onTextChanged: {
|
||||
currentRoom.isTyping = true
|
||||
timeoutTimer.restart()
|
||||
repeatTimer.start()
|
||||
currentRoom.cachedInput = text
|
||||
}
|
||||
|
||||
|
@ -332,7 +356,7 @@ Item {
|
|||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
||||
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||
}
|
||||
|
||||
ToolTip.visible: currentRoom && currentRoom.hasUsersTyping
|
||||
|
@ -395,7 +419,7 @@ Item {
|
|||
|
||||
contentItem: MaterialIcon { icon: "\ue24e" }
|
||||
|
||||
background: Rectangle { color: Material.theme == Material.Light ? "#eaeaea" : "#242424" }
|
||||
background: Rectangle { color: MSettings.darkTheme ? "#242424" : "#eaeaea" }
|
||||
|
||||
onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.open()
|
||||
|
||||
|
@ -417,4 +441,6 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentRoomChanged: if (currentRoom && currentRoom.timelineSize === 0) currentRoom.getPreviousContent(20)
|
||||
}
|
||||
|
|
|
@ -6,17 +6,13 @@ import QtQuick.Controls.Material 2.2
|
|||
import QtQml.Models 2.3
|
||||
import Matrique 0.1
|
||||
import SortFilterProxyModel 0.2
|
||||
import MatriqueSettings 0.1
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
import "qrc:/qml/component"
|
||||
|
||||
Item {
|
||||
property alias listModel: roomListProxyModel.sourceModel
|
||||
property alias rawCurrentIndex: listView.currentIndex
|
||||
readonly property int currentIndex: roomListProxyModel.mapToSource(listView.currentIndex)
|
||||
readonly property var currentRoom: currentIndex != -1 ? listModel.roomAt(currentIndex) : null
|
||||
readonly property bool mini: MatriqueSettings.miniMode // Used as an indicator of whether the listform should be displayed as "Mini mode".
|
||||
signal enterRoom()
|
||||
property var enteredRoom: null
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
@ -33,7 +29,7 @@ Item {
|
|||
width: parent.width - 18
|
||||
height: 36
|
||||
color: "white"
|
||||
leftPadding: mini ? 4 : 32
|
||||
leftPadding: MSettings.miniMode ? 4 : 32
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
anchors.centerIn: parent
|
||||
|
@ -45,13 +41,13 @@ Item {
|
|||
icon: "\ue8b6"
|
||||
color: "white"
|
||||
|
||||
width: mini ? parent.width : parent.height
|
||||
width: MSettings.miniMode ? parent.width : parent.height
|
||||
height: parent.height
|
||||
}
|
||||
|
||||
Label {
|
||||
height: parent.height
|
||||
visible: !mini
|
||||
visible: !MSettings.miniMode
|
||||
text: "Search"
|
||||
color: "white"
|
||||
font.pointSize: 12
|
||||
|
@ -66,11 +62,11 @@ Item {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
||||
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||
|
||||
Label {
|
||||
z: 10
|
||||
text: mini ? "Empty" : "Here? No, not here."
|
||||
text: MSettings.miniMode ? "Empty" : "Here? No, not here."
|
||||
anchors.centerIn: parent
|
||||
visible: listView.count === 0
|
||||
}
|
||||
|
@ -98,6 +94,7 @@ Item {
|
|||
sorters: [
|
||||
RoleSorter { roleName: "category" },
|
||||
RoleSorter {
|
||||
enabled: MSettings.rearrangeByActivity
|
||||
roleName: "unreadCount"
|
||||
sortOrder: Qt.DescendingOrder
|
||||
},
|
||||
|
@ -111,34 +108,26 @@ Item {
|
|||
|
||||
model: roomListProxyModel
|
||||
|
||||
highlight: Rectangle {
|
||||
color: Material.accent
|
||||
opacity: 0.2
|
||||
}
|
||||
highlightMoveDuration: 250
|
||||
highlightResizeDuration: 0
|
||||
|
||||
currentIndex: -1
|
||||
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
|
||||
ScrollBar.vertical: ScrollBar { id: scrollBar }
|
||||
|
||||
delegate: Item {
|
||||
delegate: Rectangle {
|
||||
id: swipeDelegate
|
||||
width: parent.width
|
||||
height: 80
|
||||
|
||||
color: currentRoom === enteredRoom ? Material.background : "transparent"
|
||||
|
||||
AutoMouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onPressed: listView.currentIndex = index
|
||||
onSecondaryClicked: roomListMenu.popup()
|
||||
onPrimaryClicked: category === RoomType.Invited ? inviteDialog.open() : enterRoom()
|
||||
onSecondaryClicked: Qt.createComponent("qrc:/qml/menu/RoomContextMenu.qml").createObject(this)
|
||||
onPrimaryClicked: category === RoomType.Invited ? inviteDialog.open() : enteredRoom = currentRoom
|
||||
}
|
||||
|
||||
ToolTip.visible: mini && hovered
|
||||
ToolTip.text: name
|
||||
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: parent.height
|
||||
|
@ -186,6 +175,9 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToolTip.visible: MSettings.miniMode && hovered
|
||||
ToolTip.text: name
|
||||
}
|
||||
|
||||
section.property: "display"
|
||||
|
@ -195,13 +187,13 @@ Item {
|
|||
height: 24
|
||||
text: section
|
||||
color: "grey"
|
||||
leftPadding: mini ? undefined : 16
|
||||
leftPadding: MSettings.miniMode ? undefined : 16
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: mini ? Text.AlignHCenter : undefined
|
||||
horizontalAlignment: MSettings.miniMode ? Text.AlignHCenter : undefined
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Material.theme == Material.Light ? "#dbdbdb" : "#363636"
|
||||
color: MSettings.darkTheme ? "#363636" : "#dbdbdb"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,32 +214,6 @@ Item {
|
|||
onAccepted: currentRoom.acceptInvitation()
|
||||
onRejected: currentRoom.forget()
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: roomListMenu
|
||||
|
||||
MenuItem {
|
||||
text: "Favourite"
|
||||
checkable: true
|
||||
checked: currentRoom && currentRoom.isFavourite
|
||||
onTriggered: currentRoom.isFavourite ? currentRoom.removeTag("m.favourite") : currentRoom.addTag("m.favourite", "1")
|
||||
}
|
||||
MenuItem {
|
||||
text: "Deprioritize"
|
||||
checkable: true
|
||||
checked: currentRoom && currentRoom.isLowPriority
|
||||
onTriggered: currentRoom.isLowPriority ? currentRoom.removeTag("m.lowpriority") : currentRoom.addTag("m.lowpriority", "1")
|
||||
}
|
||||
MenuSeparator {}
|
||||
MenuItem {
|
||||
text: "Mark as Read"
|
||||
onTriggered: currentRoom.markAllMessagesAsRead()
|
||||
}
|
||||
MenuItem {
|
||||
text: "Leave Room"
|
||||
onTriggered: currentRoom.forget()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import "qrc:/qml/component"
|
||||
|
||||
Page {
|
||||
padding: 64
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Layout.preferredHeight: 60
|
||||
|
||||
ImageStatus {
|
||||
Layout.preferredWidth: height
|
||||
Layout.fillHeight: true
|
||||
|
||||
source: matriqueController.isLogin ? connection.localUser && connection.localUser.avatarUrl ? "image://mxc/" + connection.localUser.avatarUrl : "" : "qrc:/asset/img/avatar.png"
|
||||
displayText: matriqueController.isLogin && connection.localUser.displayName ? connection.localUser.displayName : "N"
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Label {
|
||||
font.pointSize: 18
|
||||
text: matriqueController.isLogin ? connection.localUser.displayName : ""
|
||||
}
|
||||
|
||||
Label {
|
||||
font.pointSize: 12
|
||||
text: matriqueController.isLogin ? connection.localUser.id : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Logout"
|
||||
highlighted: true
|
||||
|
||||
onClicked: {
|
||||
matriqueController.logout()
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import MatriqueSettings 0.1
|
||||
|
||||
Page {
|
||||
Column {
|
||||
Switch {
|
||||
id: themeSwitch
|
||||
text: "Dark theme"
|
||||
checked: MatriqueSettings.darkTheme
|
||||
onCheckedChanged: MatriqueSettings.darkTheme = checked
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: miniModeSwitch
|
||||
text: "Mini Room List"
|
||||
checked: MatriqueSettings.miniMode
|
||||
onCheckedChanged: MatriqueSettings.miniMode = checked
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import MatriqueSettings 0.1
|
||||
|
||||
Page {
|
||||
Column {
|
||||
Switch {
|
||||
id: lazyLoadSwitch
|
||||
text: "Lazy load at initial sync"
|
||||
checked: MatriqueSettings.lazyLoad
|
||||
onCheckedChanged: MatriqueSettings.lazyLoad = checked
|
||||
}
|
||||
Switch {
|
||||
id: asyncMessageDelegateSwitch
|
||||
text: "Force loading message delegates asynchronously"
|
||||
checked: MatriqueSettings.asyncMessageDelegate
|
||||
onCheckedChanged: MatriqueSettings.asyncMessageDelegate = checked
|
||||
}
|
||||
Switch {
|
||||
id: richTextSwitch
|
||||
text: "Use RichText instead of StyledText"
|
||||
checked: MatriqueSettings.richText
|
||||
onCheckedChanged: MatriqueSettings.richText = checked
|
||||
}
|
||||
Switch {
|
||||
id: pressAndHoldSwitch
|
||||
text: "Use press and hold instead of right click"
|
||||
checked: MatriqueSettings.pressAndHold
|
||||
onCheckedChanged: MatriqueSettings.pressAndHold = checked
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Invoke GC"
|
||||
highlighted: true
|
||||
onClicked: gc()
|
||||
}
|
||||
}
|
||||
}
|
13
qml/main.qml
13
qml/main.qml
|
@ -2,10 +2,10 @@ import QtQuick 2.9
|
|||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.2
|
||||
import Qt.labs.settings 1.0 as Labs
|
||||
import Qt.labs.settings 1.0
|
||||
import QtGraphicalEffects 1.0
|
||||
import Matrique 0.1
|
||||
import MatriqueSettings 0.1
|
||||
import Matrique.Settings 0.1
|
||||
|
||||
import "component"
|
||||
import "form"
|
||||
|
@ -21,9 +21,9 @@ ApplicationWindow {
|
|||
minimumHeight: 480
|
||||
title: qsTr("Matrique")
|
||||
|
||||
Material.theme: MatriqueSettings.darkTheme ? Material.Dark : Material.Light
|
||||
Material.theme: MSettings.darkTheme ? Material.Dark : Material.Light
|
||||
|
||||
Labs.Settings {
|
||||
Settings {
|
||||
property alias homeserver: matriqueController.homeserver
|
||||
property alias userID: matriqueController.userID
|
||||
property alias token: matriqueController.token
|
||||
|
@ -80,10 +80,11 @@ ApplicationWindow {
|
|||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
SideNav {
|
||||
Rectangle {
|
||||
id: sideNav
|
||||
Layout.preferredWidth: 80
|
||||
Layout.fillHeight: true
|
||||
color: Material.accent
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
@ -96,7 +97,7 @@ ApplicationWindow {
|
|||
anchors.margins: 15
|
||||
|
||||
source: matriqueController.isLogin ? connection.localUser && connection.localUser.avatarUrl ? "image://mxc/" + connection.localUser.avatarUrl : "" : "qrc:/asset/img/avatar.png"
|
||||
displayText: matriqueController.isLogin && connection.localUser.displayName ? connection.localUser.displayName : "N"
|
||||
displayText: matriqueController.isLogin && connection.localUser.displayName ? connection.localUser.displayName : ""
|
||||
}
|
||||
|
||||
page: roomPage
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
|
||||
Menu {
|
||||
id: roomListMenu
|
||||
|
||||
MenuItem {
|
||||
text: "Favourite"
|
||||
checkable: true
|
||||
checked: currentRoom && currentRoom.isFavourite
|
||||
onTriggered: currentRoom.isFavourite ? currentRoom.removeTag("m.favourite") : currentRoom.addTag("m.favourite", "1")
|
||||
}
|
||||
MenuItem {
|
||||
text: "Deprioritize"
|
||||
checkable: true
|
||||
checked: currentRoom && currentRoom.isLowPriority
|
||||
onTriggered: currentRoom.isLowPriority ? currentRoom.removeTag("m.lowpriority") : currentRoom.addTag("m.lowpriority", "1")
|
||||
}
|
||||
MenuSeparator {}
|
||||
MenuItem {
|
||||
text: "Mark as Read"
|
||||
onTriggered: currentRoom.markAllMessagesAsRead()
|
||||
}
|
||||
MenuItem {
|
||||
text: "Leave Room"
|
||||
onTriggered: currentRoom.forget()
|
||||
}
|
||||
|
||||
Component.onCompleted: popup()
|
||||
onClosed: roomListMenu.destroy()
|
||||
}
|
11
res.qrc
11
res.qrc
|
@ -7,7 +7,6 @@
|
|||
<file>qml/Login.qml</file>
|
||||
<file>qml/main.qml</file>
|
||||
<file>qml/component/ImageStatus.qml</file>
|
||||
<file>qml/component/SideNav.qml</file>
|
||||
<file>qml/form/RoomForm.qml</file>
|
||||
<file>qml/Room.qml</file>
|
||||
<file>qml/component/SideNavButton.qml</file>
|
||||
|
@ -24,19 +23,15 @@
|
|||
<file>qml/form/RoomListForm.qml</file>
|
||||
<file>qml/component/AudioBubble.qml</file>
|
||||
<file>qml/Setting.qml</file>
|
||||
<file>qml/form/SettingAccountForm.qml</file>
|
||||
<file>qml/form/SettingAppearanceForm.qml</file>
|
||||
<file>qml/component/TextDelegate.qml</file>
|
||||
<file>qml/component/MessageContextMenu.qml</file>
|
||||
<file>qml/form/SettingGeneralForm.qml</file>
|
||||
<file>qml/component/EmojiPicker.qml</file>
|
||||
<file>qml/component/EmojiButton.qml</file>
|
||||
<file>qml/component/AutoImage.qml</file>
|
||||
<file>asset/img/icon.ico</file>
|
||||
<file>asset/img/icon.icns</file>
|
||||
<file>qml/component/AutoMouseArea.qml</file>
|
||||
<file>qml/MatriqueSettings/MatriqueSettings.qml</file>
|
||||
<file>qml/MatriqueSettings/qmldir</file>
|
||||
<file>qml/MatriqueSettings/plugins.qmltypes</file>
|
||||
<file>qml/MatriqueSettings.qml</file>
|
||||
<file>qml/menu/MessageContextMenu.qml</file>
|
||||
<file>qml/menu/RoomContextMenu.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
#include "controller.h"
|
||||
#include "emojimodel.h"
|
||||
#include "imageprovider.h"
|
||||
#include "matriqueroom.h"
|
||||
#include "messageeventmodel.h"
|
||||
#include "room.h"
|
||||
#include "roomlistmodel.h"
|
||||
#include "matriqueroom.h"
|
||||
|
||||
#include "csapi/joining.h"
|
||||
#include "csapi/leaving.h"
|
||||
|
@ -28,6 +28,7 @@ int main(int argc, char *argv[]) {
|
|||
qRegisterMetaType<MatriqueRoom *>("MatriqueRoom*");
|
||||
qRegisterMetaType<User *>("User*");
|
||||
qRegisterMetaType<MessageEventType>("MessageEventType");
|
||||
qRegisterMetaType<MatriqueRoom *>("MatriqueRoom");
|
||||
|
||||
qmlRegisterType<Controller>("Matrique", 0, 1, "Controller");
|
||||
qmlRegisterType<RoomListModel>("Matrique", 0, 1, "RoomListModel");
|
||||
|
@ -36,9 +37,10 @@ int main(int argc, char *argv[]) {
|
|||
qmlRegisterUncreatableType<RoomMessageEvent>("Matrique", 0, 1,
|
||||
"RoomMessageEvent", "ENUM");
|
||||
qmlRegisterUncreatableType<RoomType>("Matrique", 0, 1, "RoomType", "ENUM");
|
||||
qmlRegisterSingletonType(QUrl("qrc:/qml/MatriqueSettings.qml"),
|
||||
"Matrique.Settings", 0, 1, "MSettings");
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.addImportPath("qrc:/qml");
|
||||
|
||||
ImageProvider *m_provider = new ImageProvider();
|
||||
|
||||
|
|
|
@ -12,25 +12,7 @@
|
|||
|
||||
MatriqueRoom::MatriqueRoom(Connection* connection, QString roomId,
|
||||
JoinState joinState)
|
||||
: Room(connection, std::move(roomId), joinState) {
|
||||
m_timeoutTimer->setSingleShot(true);
|
||||
m_timeoutTimer->setInterval(2000);
|
||||
m_repeatTimer->setInterval(5000);
|
||||
connect(m_timeoutTimer, &QTimer::timeout, [=] { setIsTyping(false); });
|
||||
connect(m_repeatTimer, &QTimer::timeout,
|
||||
[=] { sendTypingNotification(true); });
|
||||
connect(this, &MatriqueRoom::isTypingChanged, [=] {
|
||||
if (m_isTyping) {
|
||||
m_timeoutTimer->start();
|
||||
m_repeatTimer->start();
|
||||
sendTypingNotification(true);
|
||||
} else {
|
||||
m_timeoutTimer->stop();
|
||||
m_repeatTimer->stop();
|
||||
sendTypingNotification(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
: Room(connection, std::move(roomId), joinState) {}
|
||||
|
||||
void MatriqueRoom::chooseAndUploadFile() {
|
||||
auto localFile = QFileDialog::getOpenFileUrl(Q_NULLPTR, tr("Save File as"));
|
||||
|
@ -88,7 +70,7 @@ QString MatriqueRoom::getUsersTyping() {
|
|||
for (User* user : users) {
|
||||
usersTypingStr += user->displayname() + " ";
|
||||
}
|
||||
usersTypingStr += users.count() == 1 ? "is" : "are";
|
||||
usersTypingStr += users.count() < 2 ? "is" : "are";
|
||||
usersTypingStr += " typing.";
|
||||
return usersTypingStr;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ using namespace QMatrixClient;
|
|||
|
||||
class MatriqueRoom : public Room {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(
|
||||
bool isTyping READ isTyping WRITE setIsTyping NOTIFY isTypingChanged)
|
||||
Q_PROPERTY(bool hasUsersTyping READ hasUsersTyping NOTIFY typingChanged)
|
||||
Q_PROPERTY(QString usersTyping READ getUsersTyping NOTIFY typingChanged)
|
||||
Q_PROPERTY(QString cachedInput READ cachedInput WRITE setCachedInput NOTIFY
|
||||
|
@ -20,15 +18,6 @@ class MatriqueRoom : public Room {
|
|||
explicit MatriqueRoom(Connection* connection, QString roomId,
|
||||
JoinState joinState = {});
|
||||
|
||||
bool isTyping() { return m_isTyping; }
|
||||
void setIsTyping(bool isTyping) {
|
||||
if (isTyping) m_timeoutTimer->start();
|
||||
if (isTyping != m_isTyping) {
|
||||
m_isTyping = isTyping;
|
||||
emit isTypingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
const QString& cachedInput() const { return m_cachedInput; }
|
||||
void setCachedInput(const QString& input) {
|
||||
if (input != m_cachedInput) {
|
||||
|
@ -44,15 +33,11 @@ class MatriqueRoom : public Room {
|
|||
|
||||
private:
|
||||
QString m_cachedInput;
|
||||
bool m_isTyping;
|
||||
QTimer* m_timeoutTimer = new QTimer();
|
||||
QTimer* m_repeatTimer = new QTimer();
|
||||
|
||||
QString getMIME(const QUrl& fileUrl) const;
|
||||
void postFile(const QUrl& localFile, const QUrl& mxcUrl);
|
||||
|
||||
signals:
|
||||
void isTypingChanged();
|
||||
void cachedInputChanged();
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -153,6 +153,7 @@ QVariant RoomListModel::data(const QModelIndex& index, int role) const {
|
|||
}
|
||||
if (role == UnreadCountRole) return room->unreadCount();
|
||||
if (role == LastEventRole) return room->lastEvent();
|
||||
if (role == CurrentRoomRole) return QVariant::fromValue(room);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
@ -184,5 +185,6 @@ QHash<int, QByteArray> RoomListModel::roleNames() const {
|
|||
roles[CategoryRole] = "category";
|
||||
roles[UnreadCountRole] = "unreadCount";
|
||||
roles[LastEventRole] = "lastEvent";
|
||||
roles[CurrentRoomRole] = "currentRoom";
|
||||
return roles;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ class RoomListModel : public QAbstractListModel {
|
|||
TopicRole,
|
||||
CategoryRole,
|
||||
UnreadCountRole,
|
||||
LastEventRole
|
||||
LastEventRole,
|
||||
CurrentRoomRole,
|
||||
};
|
||||
|
||||
RoomListModel(QObject* parent = 0);
|
||||
|
|
Loading…
Reference in New Issue