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
|
res.qrc
|
||||||
|
|
||||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
# 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
|
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||||
QML_DESIGNER_IMPORT_PATH =
|
QML_DESIGNER_IMPORT_PATH =
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
</categories>
|
</categories>
|
||||||
<url type="homepage">https://gitlab.com/b0/matrique</url>
|
<url type="homepage">https://gitlab.com/b0/matrique</url>
|
||||||
<url type="bugtracker">https://gitlab.com/b0/matrique/issues</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_rating type="oars-1.0">
|
||||||
<content_attribute id="social-chat">intense</content_attribute>
|
<content_attribute id="social-chat">intense</content_attribute>
|
||||||
<content_attribute id="social-audio">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 2.2
|
||||||
import QtQuick.Controls.Material 2.2
|
import QtQuick.Controls.Material 2.2
|
||||||
import Qt.labs.settings 1.0
|
import Qt.labs.settings 1.0
|
||||||
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
import "qrc:/qml/component"
|
import "qrc:/qml/component"
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
|
@ -76,7 +78,7 @@ Page {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
implicitHeight: 48
|
implicitHeight: 48
|
||||||
|
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||||
border.color: parent.activeFocus ? Material.accent : "transparent"
|
border.color: parent.activeFocus ? Material.accent : "transparent"
|
||||||
border.width: 2
|
border.width: 2
|
||||||
}
|
}
|
||||||
|
@ -96,7 +98,7 @@ Page {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
implicitHeight: 48
|
implicitHeight: 48
|
||||||
|
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||||
border.color: parent.activeFocus ? Material.accent : "transparent"
|
border.color: parent.activeFocus ? Material.accent : "transparent"
|
||||||
border.width: 2
|
border.width: 2
|
||||||
}
|
}
|
||||||
|
@ -117,7 +119,7 @@ Page {
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
implicitHeight: 48
|
implicitHeight: 48
|
||||||
|
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||||
border.color: parent.activeFocus ? Material.accent : "transparent"
|
border.color: parent.activeFocus ? Material.accent : "transparent"
|
||||||
border.width: 2
|
border.width: 2
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ Settings {
|
||||||
property bool asyncMessageDelegate
|
property bool asyncMessageDelegate
|
||||||
property bool richText
|
property bool richText
|
||||||
property bool pressAndHold
|
property bool pressAndHold
|
||||||
|
property bool rearrangeByActivity
|
||||||
|
|
||||||
property bool darkTheme
|
property bool darkTheme
|
||||||
property bool miniMode
|
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.Controls 2.2
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import Matrique 0.1
|
import Matrique 0.1
|
||||||
import MatriqueSettings 0.1
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
import "qrc:/qml/form"
|
import "qrc:/qml/form"
|
||||||
|
|
||||||
|
@ -14,10 +14,8 @@ Page {
|
||||||
RoomListModel {
|
RoomListModel {
|
||||||
id: roomListModel
|
id: roomListModel
|
||||||
|
|
||||||
onRoomAdded: MatriqueSettings.lazyLoad ? {} : room.getPreviousContent(20)
|
onRoomAdded: if (!MSettings.lazyLoad) room.getPreviousContent(20)
|
||||||
onNewMessage: window.active ? {} : matriqueController.showMessage(roomName, content, icon)
|
onNewMessage: if (!window.active) matriqueController.showMessage(roomName, content, icon)
|
||||||
|
|
||||||
onDataChanged: roomListForm.rawCurrentIndex = -1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
@ -28,13 +26,11 @@ Page {
|
||||||
id: roomListForm
|
id: roomListForm
|
||||||
|
|
||||||
Layout.fillHeight: true
|
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.minimumWidth: 80
|
||||||
Layout.maximumWidth: 360
|
Layout.maximumWidth: 360
|
||||||
|
|
||||||
listModel: roomListModel
|
listModel: roomListModel
|
||||||
|
|
||||||
onEnterRoom: roomForm.currentRoom = currentRoom
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RoomForm {
|
RoomForm {
|
||||||
|
@ -42,6 +38,8 @@ Page {
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: 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 2.2
|
||||||
import QtQuick.Controls.Material 2.2
|
import QtQuick.Controls.Material 2.2
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
import "component"
|
import "component"
|
||||||
import "form"
|
import "form"
|
||||||
|
@ -9,24 +10,133 @@ import "form"
|
||||||
Page {
|
Page {
|
||||||
property var connection
|
property var connection
|
||||||
|
|
||||||
SettingAccountForm {
|
Page {
|
||||||
id: accountForm
|
id: accountForm
|
||||||
parent: null
|
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
|
id: generalForm
|
||||||
parent: null
|
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
|
id: appearanceForm
|
||||||
parent: null
|
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 {
|
RowLayout {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Material.elevation: 10
|
|
||||||
Layout.preferredWidth: 240
|
Layout.preferredWidth: 240
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
@ -57,6 +167,7 @@ Page {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: "About"
|
text: "About"
|
||||||
|
onClicked: pushToStack(aboutForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import MatriqueSettings 0.1
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
signal primaryClicked()
|
signal primaryClicked()
|
||||||
signal secondaryClicked()
|
signal secondaryClicked()
|
||||||
|
|
||||||
propagateComposedEvents: true
|
acceptedButtons: MSettings.pressAndHold ? Qt.LeftButton : (Qt.LeftButton | Qt.RightButton)
|
||||||
acceptedButtons: MatriqueSettings.pressAndHold ? Qt.LeftButton : (Qt.LeftButton | Qt.RightButton)
|
|
||||||
onClicked: mouse.button == Qt.RightButton ? secondaryClicked() : primaryClicked()
|
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 source: ""
|
||||||
property string displayText: ""
|
property string displayText: ""
|
||||||
readonly property bool showImage: source
|
readonly property bool showImage: source
|
||||||
readonly property bool showInitial: !showImage && displayText
|
readonly property bool showInitial: !showImage && displayText || avatar.status != Image.Ready
|
||||||
|
|
||||||
id: item
|
id: item
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInitials(text) {
|
function getInitials(text) {
|
||||||
|
if (!text) return "N"
|
||||||
return text.toUpperCase().replace(/[^a-zA-Z- ]/g, "").match(/\b\w/g);
|
return text.toUpperCase().replace(/[^a-zA-Z- ]/g, "").match(/\b\w/g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtQuick.Controls 2.2
|
import QtQuick.Controls 2.2
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Controls.Material 2.2
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property alias icon: iconText.text
|
property alias icon: iconText.text
|
||||||
property var color: Material.theme == Material.Light ? "black" : "white"
|
property var color: MSettings.darkTheme ? "white" : "black"
|
||||||
|
|
||||||
id: item
|
id: item
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,11 @@ import QtQuick 2.9
|
||||||
import QtQuick.Controls 2.2
|
import QtQuick.Controls 2.2
|
||||||
import QtQuick.Controls.Material 2.2
|
import QtQuick.Controls.Material 2.2
|
||||||
import Matrique 0.1
|
import Matrique 0.1
|
||||||
import MatriqueSettings 0.1
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
readonly property bool hidden: marks === EventStatus.Redacted || marks === EventStatus.Hidden
|
readonly property bool hidden: marks === EventStatus.Redacted || marks === EventStatus.Hidden
|
||||||
|
readonly property color background: MSettings.darkTheme ? "#242424" : "lightgrey"
|
||||||
readonly property bool darkTheme: Material.theme == Material.Dark
|
|
||||||
readonly property color background: darkTheme ? "#242424" : "lightgrey"
|
|
||||||
|
|
||||||
readonly property bool sentByMe: author === currentRoom.localUser
|
readonly property bool sentByMe: author === currentRoom.localUser
|
||||||
readonly property bool isState: eventType === "state" || eventType === "emote"
|
readonly property bool isState: eventType === "state" || eventType === "emote"
|
||||||
|
|
||||||
|
@ -24,13 +21,15 @@ Item {
|
||||||
|
|
||||||
AutoMouseArea {
|
AutoMouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onSecondaryClicked: Qt.createComponent("MessageContextMenu.qml").createObject(this)
|
|
||||||
|
propagateComposedEvents: true
|
||||||
|
onSecondaryClicked: Qt.createComponent("qrc:/qml/menu/MessageContextMenu.qml").createObject(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: delegateLoader
|
id: delegateLoader
|
||||||
|
|
||||||
asynchronous: MatriqueSettings.asyncMessageDelegate
|
asynchronous: MSettings.asyncMessageDelegate
|
||||||
|
|
||||||
source: {
|
source: {
|
||||||
if (eventType == "redaction" || hidden) return ""
|
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 2.2
|
||||||
import QtQuick.Controls.Material 2.2
|
import QtQuick.Controls.Material 2.2
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import MatriqueSettings 0.1
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
property bool flat: false
|
property bool flat: false
|
||||||
|
@ -46,7 +46,7 @@ Rectangle {
|
||||||
|
|
||||||
wrapMode: Label.Wrap
|
wrapMode: Label.Wrap
|
||||||
linkColor: darkBackground ? "white" : Material.accent
|
linkColor: darkBackground ? "white" : Material.accent
|
||||||
textFormat: MatriqueSettings.richText ? Text.RichText : Text.StyledText
|
textFormat: MSettings.richText ? Text.RichText : Text.StyledText
|
||||||
onLinkActivated: Qt.openUrlExternally(link)
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,16 @@ import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Controls.Material 2.2
|
import QtQuick.Controls.Material 2.2
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
import Matrique 0.1
|
import Matrique 0.1
|
||||||
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
import "qrc:/qml/component"
|
import "qrc:/qml/component"
|
||||||
import "qrc:/js/md.js" as Markdown
|
import "qrc:/js/md.js" as Markdown
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: item
|
|
||||||
property var currentRoom: null
|
property var currentRoom: null
|
||||||
|
|
||||||
|
id: item
|
||||||
|
|
||||||
Drawer {
|
Drawer {
|
||||||
id: roomDrawer
|
id: roomDrawer
|
||||||
|
|
||||||
|
@ -114,7 +117,7 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 80
|
Layout.preferredHeight: 80
|
||||||
|
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -293,6 +296,26 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 80
|
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 {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
@ -320,7 +343,8 @@ Item {
|
||||||
|
|
||||||
text: currentRoom ? currentRoom.cachedInput : ""
|
text: currentRoom ? currentRoom.cachedInput : ""
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
currentRoom.isTyping = true
|
timeoutTimer.restart()
|
||||||
|
repeatTimer.start()
|
||||||
currentRoom.cachedInput = text
|
currentRoom.cachedInput = text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +356,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolTip.visible: currentRoom && currentRoom.hasUsersTyping
|
ToolTip.visible: currentRoom && currentRoom.hasUsersTyping
|
||||||
|
@ -395,7 +419,7 @@ Item {
|
||||||
|
|
||||||
contentItem: MaterialIcon { icon: "\ue24e" }
|
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()
|
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 QtQml.Models 2.3
|
||||||
import Matrique 0.1
|
import Matrique 0.1
|
||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
import MatriqueSettings 0.1
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
import "qrc:/qml/component"
|
import "qrc:/qml/component"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property alias listModel: roomListProxyModel.sourceModel
|
property alias listModel: roomListProxyModel.sourceModel
|
||||||
property alias rawCurrentIndex: listView.currentIndex
|
property var enteredRoom: null
|
||||||
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()
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -33,7 +29,7 @@ Item {
|
||||||
width: parent.width - 18
|
width: parent.width - 18
|
||||||
height: 36
|
height: 36
|
||||||
color: "white"
|
color: "white"
|
||||||
leftPadding: mini ? 4 : 32
|
leftPadding: MSettings.miniMode ? 4 : 32
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
bottomPadding: 0
|
bottomPadding: 0
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
@ -45,13 +41,13 @@ Item {
|
||||||
icon: "\ue8b6"
|
icon: "\ue8b6"
|
||||||
color: "white"
|
color: "white"
|
||||||
|
|
||||||
width: mini ? parent.width : parent.height
|
width: MSettings.miniMode ? parent.width : parent.height
|
||||||
height: parent.height
|
height: parent.height
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
visible: !mini
|
visible: !MSettings.miniMode
|
||||||
text: "Search"
|
text: "Search"
|
||||||
color: "white"
|
color: "white"
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
|
@ -66,11 +62,11 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
|
color: MSettings.darkTheme ? "#242424" : "#eaeaea"
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
z: 10
|
z: 10
|
||||||
text: mini ? "Empty" : "Here? No, not here."
|
text: MSettings.miniMode ? "Empty" : "Here? No, not here."
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: listView.count === 0
|
visible: listView.count === 0
|
||||||
}
|
}
|
||||||
|
@ -98,6 +94,7 @@ Item {
|
||||||
sorters: [
|
sorters: [
|
||||||
RoleSorter { roleName: "category" },
|
RoleSorter { roleName: "category" },
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
|
enabled: MSettings.rearrangeByActivity
|
||||||
roleName: "unreadCount"
|
roleName: "unreadCount"
|
||||||
sortOrder: Qt.DescendingOrder
|
sortOrder: Qt.DescendingOrder
|
||||||
},
|
},
|
||||||
|
@ -111,34 +108,26 @@ Item {
|
||||||
|
|
||||||
model: roomListProxyModel
|
model: roomListProxyModel
|
||||||
|
|
||||||
highlight: Rectangle {
|
|
||||||
color: Material.accent
|
|
||||||
opacity: 0.2
|
|
||||||
}
|
|
||||||
highlightMoveDuration: 250
|
|
||||||
highlightResizeDuration: 0
|
|
||||||
|
|
||||||
currentIndex: -1
|
currentIndex: -1
|
||||||
|
|
||||||
boundsBehavior: Flickable.DragOverBounds
|
boundsBehavior: Flickable.DragOverBounds
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar { id: scrollBar }
|
ScrollBar.vertical: ScrollBar { id: scrollBar }
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Rectangle {
|
||||||
|
id: swipeDelegate
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 80
|
height: 80
|
||||||
|
|
||||||
|
color: currentRoom === enteredRoom ? Material.background : "transparent"
|
||||||
|
|
||||||
AutoMouseArea {
|
AutoMouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
onPressed: listView.currentIndex = index
|
onSecondaryClicked: Qt.createComponent("qrc:/qml/menu/RoomContextMenu.qml").createObject(this)
|
||||||
onSecondaryClicked: roomListMenu.popup()
|
onPrimaryClicked: category === RoomType.Invited ? inviteDialog.open() : enteredRoom = currentRoom
|
||||||
onPrimaryClicked: category === RoomType.Invited ? inviteDialog.open() : enterRoom()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolTip.visible: mini && hovered
|
|
||||||
ToolTip.text: name
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 4
|
width: 4
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
@ -186,6 +175,9 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ToolTip.visible: MSettings.miniMode && hovered
|
||||||
|
ToolTip.text: name
|
||||||
}
|
}
|
||||||
|
|
||||||
section.property: "display"
|
section.property: "display"
|
||||||
|
@ -195,13 +187,13 @@ Item {
|
||||||
height: 24
|
height: 24
|
||||||
text: section
|
text: section
|
||||||
color: "grey"
|
color: "grey"
|
||||||
leftPadding: mini ? undefined : 16
|
leftPadding: MSettings.miniMode ? undefined : 16
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: mini ? Text.AlignHCenter : undefined
|
horizontalAlignment: MSettings.miniMode ? Text.AlignHCenter : undefined
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Material.theme == Material.Light ? "#dbdbdb" : "#363636"
|
color: MSettings.darkTheme ? "#363636" : "#dbdbdb"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,32 +214,6 @@ Item {
|
||||||
onAccepted: currentRoom.acceptInvitation()
|
onAccepted: currentRoom.acceptInvitation()
|
||||||
onRejected: currentRoom.forget()
|
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.Controls 2.2
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Controls.Material 2.2
|
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 QtGraphicalEffects 1.0
|
||||||
import Matrique 0.1
|
import Matrique 0.1
|
||||||
import MatriqueSettings 0.1
|
import Matrique.Settings 0.1
|
||||||
|
|
||||||
import "component"
|
import "component"
|
||||||
import "form"
|
import "form"
|
||||||
|
@ -21,9 +21,9 @@ ApplicationWindow {
|
||||||
minimumHeight: 480
|
minimumHeight: 480
|
||||||
title: qsTr("Matrique")
|
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 homeserver: matriqueController.homeserver
|
||||||
property alias userID: matriqueController.userID
|
property alias userID: matriqueController.userID
|
||||||
property alias token: matriqueController.token
|
property alias token: matriqueController.token
|
||||||
|
@ -80,10 +80,11 @@ ApplicationWindow {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
SideNav {
|
Rectangle {
|
||||||
id: sideNav
|
id: sideNav
|
||||||
Layout.preferredWidth: 80
|
Layout.preferredWidth: 80
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
color: Material.accent
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -96,7 +97,7 @@ ApplicationWindow {
|
||||||
anchors.margins: 15
|
anchors.margins: 15
|
||||||
|
|
||||||
source: matriqueController.isLogin ? connection.localUser && connection.localUser.avatarUrl ? "image://mxc/" + connection.localUser.avatarUrl : "" : "qrc:/asset/img/avatar.png"
|
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
|
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/Login.qml</file>
|
||||||
<file>qml/main.qml</file>
|
<file>qml/main.qml</file>
|
||||||
<file>qml/component/ImageStatus.qml</file>
|
<file>qml/component/ImageStatus.qml</file>
|
||||||
<file>qml/component/SideNav.qml</file>
|
|
||||||
<file>qml/form/RoomForm.qml</file>
|
<file>qml/form/RoomForm.qml</file>
|
||||||
<file>qml/Room.qml</file>
|
<file>qml/Room.qml</file>
|
||||||
<file>qml/component/SideNavButton.qml</file>
|
<file>qml/component/SideNavButton.qml</file>
|
||||||
|
@ -24,19 +23,15 @@
|
||||||
<file>qml/form/RoomListForm.qml</file>
|
<file>qml/form/RoomListForm.qml</file>
|
||||||
<file>qml/component/AudioBubble.qml</file>
|
<file>qml/component/AudioBubble.qml</file>
|
||||||
<file>qml/Setting.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/TextDelegate.qml</file>
|
||||||
<file>qml/component/MessageContextMenu.qml</file>
|
|
||||||
<file>qml/form/SettingGeneralForm.qml</file>
|
|
||||||
<file>qml/component/EmojiPicker.qml</file>
|
<file>qml/component/EmojiPicker.qml</file>
|
||||||
<file>qml/component/EmojiButton.qml</file>
|
<file>qml/component/EmojiButton.qml</file>
|
||||||
<file>qml/component/AutoImage.qml</file>
|
<file>qml/component/AutoImage.qml</file>
|
||||||
<file>asset/img/icon.ico</file>
|
<file>asset/img/icon.ico</file>
|
||||||
<file>asset/img/icon.icns</file>
|
<file>asset/img/icon.icns</file>
|
||||||
<file>qml/component/AutoMouseArea.qml</file>
|
<file>qml/component/AutoMouseArea.qml</file>
|
||||||
<file>qml/MatriqueSettings/MatriqueSettings.qml</file>
|
<file>qml/MatriqueSettings.qml</file>
|
||||||
<file>qml/MatriqueSettings/qmldir</file>
|
<file>qml/menu/MessageContextMenu.qml</file>
|
||||||
<file>qml/MatriqueSettings/plugins.qmltypes</file>
|
<file>qml/menu/RoomContextMenu.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "emojimodel.h"
|
#include "emojimodel.h"
|
||||||
#include "imageprovider.h"
|
#include "imageprovider.h"
|
||||||
|
#include "matriqueroom.h"
|
||||||
#include "messageeventmodel.h"
|
#include "messageeventmodel.h"
|
||||||
#include "room.h"
|
#include "room.h"
|
||||||
#include "roomlistmodel.h"
|
#include "roomlistmodel.h"
|
||||||
#include "matriqueroom.h"
|
|
||||||
|
|
||||||
#include "csapi/joining.h"
|
#include "csapi/joining.h"
|
||||||
#include "csapi/leaving.h"
|
#include "csapi/leaving.h"
|
||||||
|
@ -28,6 +28,7 @@ int main(int argc, char *argv[]) {
|
||||||
qRegisterMetaType<MatriqueRoom *>("MatriqueRoom*");
|
qRegisterMetaType<MatriqueRoom *>("MatriqueRoom*");
|
||||||
qRegisterMetaType<User *>("User*");
|
qRegisterMetaType<User *>("User*");
|
||||||
qRegisterMetaType<MessageEventType>("MessageEventType");
|
qRegisterMetaType<MessageEventType>("MessageEventType");
|
||||||
|
qRegisterMetaType<MatriqueRoom *>("MatriqueRoom");
|
||||||
|
|
||||||
qmlRegisterType<Controller>("Matrique", 0, 1, "Controller");
|
qmlRegisterType<Controller>("Matrique", 0, 1, "Controller");
|
||||||
qmlRegisterType<RoomListModel>("Matrique", 0, 1, "RoomListModel");
|
qmlRegisterType<RoomListModel>("Matrique", 0, 1, "RoomListModel");
|
||||||
|
@ -36,9 +37,10 @@ int main(int argc, char *argv[]) {
|
||||||
qmlRegisterUncreatableType<RoomMessageEvent>("Matrique", 0, 1,
|
qmlRegisterUncreatableType<RoomMessageEvent>("Matrique", 0, 1,
|
||||||
"RoomMessageEvent", "ENUM");
|
"RoomMessageEvent", "ENUM");
|
||||||
qmlRegisterUncreatableType<RoomType>("Matrique", 0, 1, "RoomType", "ENUM");
|
qmlRegisterUncreatableType<RoomType>("Matrique", 0, 1, "RoomType", "ENUM");
|
||||||
|
qmlRegisterSingletonType(QUrl("qrc:/qml/MatriqueSettings.qml"),
|
||||||
|
"Matrique.Settings", 0, 1, "MSettings");
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
engine.addImportPath("qrc:/qml");
|
|
||||||
|
|
||||||
ImageProvider *m_provider = new ImageProvider();
|
ImageProvider *m_provider = new ImageProvider();
|
||||||
|
|
||||||
|
|
|
@ -12,25 +12,7 @@
|
||||||
|
|
||||||
MatriqueRoom::MatriqueRoom(Connection* connection, QString roomId,
|
MatriqueRoom::MatriqueRoom(Connection* connection, QString roomId,
|
||||||
JoinState joinState)
|
JoinState joinState)
|
||||||
: Room(connection, std::move(roomId), 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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void MatriqueRoom::chooseAndUploadFile() {
|
void MatriqueRoom::chooseAndUploadFile() {
|
||||||
auto localFile = QFileDialog::getOpenFileUrl(Q_NULLPTR, tr("Save File as"));
|
auto localFile = QFileDialog::getOpenFileUrl(Q_NULLPTR, tr("Save File as"));
|
||||||
|
@ -88,7 +70,7 @@ QString MatriqueRoom::getUsersTyping() {
|
||||||
for (User* user : users) {
|
for (User* user : users) {
|
||||||
usersTypingStr += user->displayname() + " ";
|
usersTypingStr += user->displayname() + " ";
|
||||||
}
|
}
|
||||||
usersTypingStr += users.count() == 1 ? "is" : "are";
|
usersTypingStr += users.count() < 2 ? "is" : "are";
|
||||||
usersTypingStr += " typing.";
|
usersTypingStr += " typing.";
|
||||||
return usersTypingStr;
|
return usersTypingStr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@ using namespace QMatrixClient;
|
||||||
|
|
||||||
class MatriqueRoom : public Room {
|
class MatriqueRoom : public Room {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(
|
|
||||||
bool isTyping READ isTyping WRITE setIsTyping NOTIFY isTypingChanged)
|
|
||||||
Q_PROPERTY(bool hasUsersTyping READ hasUsersTyping NOTIFY typingChanged)
|
Q_PROPERTY(bool hasUsersTyping READ hasUsersTyping NOTIFY typingChanged)
|
||||||
Q_PROPERTY(QString usersTyping READ getUsersTyping NOTIFY typingChanged)
|
Q_PROPERTY(QString usersTyping READ getUsersTyping NOTIFY typingChanged)
|
||||||
Q_PROPERTY(QString cachedInput READ cachedInput WRITE setCachedInput NOTIFY
|
Q_PROPERTY(QString cachedInput READ cachedInput WRITE setCachedInput NOTIFY
|
||||||
|
@ -20,15 +18,6 @@ class MatriqueRoom : public Room {
|
||||||
explicit MatriqueRoom(Connection* connection, QString roomId,
|
explicit MatriqueRoom(Connection* connection, QString roomId,
|
||||||
JoinState joinState = {});
|
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; }
|
const QString& cachedInput() const { return m_cachedInput; }
|
||||||
void setCachedInput(const QString& input) {
|
void setCachedInput(const QString& input) {
|
||||||
if (input != m_cachedInput) {
|
if (input != m_cachedInput) {
|
||||||
|
@ -44,15 +33,11 @@ class MatriqueRoom : public Room {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_cachedInput;
|
QString m_cachedInput;
|
||||||
bool m_isTyping;
|
|
||||||
QTimer* m_timeoutTimer = new QTimer();
|
|
||||||
QTimer* m_repeatTimer = new QTimer();
|
|
||||||
|
|
||||||
QString getMIME(const QUrl& fileUrl) const;
|
QString getMIME(const QUrl& fileUrl) const;
|
||||||
void postFile(const QUrl& localFile, const QUrl& mxcUrl);
|
void postFile(const QUrl& localFile, const QUrl& mxcUrl);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void isTypingChanged();
|
|
||||||
void cachedInputChanged();
|
void cachedInputChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -153,6 +153,7 @@ QVariant RoomListModel::data(const QModelIndex& index, int role) const {
|
||||||
}
|
}
|
||||||
if (role == UnreadCountRole) return room->unreadCount();
|
if (role == UnreadCountRole) return room->unreadCount();
|
||||||
if (role == LastEventRole) return room->lastEvent();
|
if (role == LastEventRole) return room->lastEvent();
|
||||||
|
if (role == CurrentRoomRole) return QVariant::fromValue(room);
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,5 +185,6 @@ QHash<int, QByteArray> RoomListModel::roleNames() const {
|
||||||
roles[CategoryRole] = "category";
|
roles[CategoryRole] = "category";
|
||||||
roles[UnreadCountRole] = "unreadCount";
|
roles[UnreadCountRole] = "unreadCount";
|
||||||
roles[LastEventRole] = "lastEvent";
|
roles[LastEventRole] = "lastEvent";
|
||||||
|
roles[CurrentRoomRole] = "currentRoom";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@ class RoomListModel : public QAbstractListModel {
|
||||||
TopicRole,
|
TopicRole,
|
||||||
CategoryRole,
|
CategoryRole,
|
||||||
UnreadCountRole,
|
UnreadCountRole,
|
||||||
LastEventRole
|
LastEventRole,
|
||||||
|
CurrentRoomRole,
|
||||||
};
|
};
|
||||||
|
|
||||||
RoomListModel(QObject* parent = 0);
|
RoomListModel(QObject* parent = 0);
|
||||||
|
|
Loading…
Reference in New Issue