diff --git a/qml/Room.qml b/qml/Room.qml
index 4269082..99494a5 100644
--- a/qml/Room.qml
+++ b/qml/Room.qml
@@ -6,6 +6,7 @@ import Spectral 0.1
import Spectral.Settings 0.1
import "form"
+import "component"
Page {
property alias connection: roomListModel.connection
@@ -16,46 +17,37 @@ Page {
RoomListModel {
id: roomListModel
- onRoomAdded: room.getPreviousContent(20)
onNewMessage: if (!window.active) spectralController.showMessage(roomName, content, icon)
}
- Rectangle {
+ RowLayout {
anchors.fill: parent
- color: MSettings.darkTheme ? "#323232" : "#f3f3f3"
+ spacing: 0
- RowLayout {
- anchors.fill: parent
+ RoomListForm {
+ Layout.fillHeight: true
+ Layout.preferredWidth: MSettings.miniMode ? 64 : page.width * 0.35
+ Layout.minimumWidth: 64
+ Layout.maximumWidth: 360
- spacing: 0
+ id: roomListForm
- RoomListForm {
- Layout.fillHeight: true
- Layout.preferredWidth: MSettings.miniMode ? 64 : page.width * 0.35
- Layout.minimumWidth: 64
- Layout.maximumWidth: 360
+ listModel: roomListModel
- id: roomListForm
-
- listModel: roomListModel
+ layer.enabled: true
+ layer.effect: ElevationEffect {
+ elevation: 2
}
+ }
- Rectangle {
- Layout.preferredWidth: 1
- Layout.fillHeight: true
+ RoomForm {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
- color: MSettings.darkTheme ? "#363636" : "#ececec"
- }
+ id: roomForm
- RoomForm {
- Layout.fillWidth: true
- Layout.fillHeight: true
-
- id: roomForm
-
- currentRoom: roomListForm.enteredRoom
- }
+ currentRoom: roomListForm.enteredRoom
}
}
}
diff --git a/qml/Setting.qml b/qml/Setting.qml
index d5b1ade..fb11a9f 100644
--- a/qml/Setting.qml
+++ b/qml/Setting.qml
@@ -41,8 +41,6 @@ Page {
width: accountSettingsListView.width
height: 64
- clip: true
-
Row {
anchors.fill: parent
anchors.margins: 8
@@ -239,11 +237,17 @@ Page {
Rectangle {
width: 240
height: parent.height
+ z: 10
id: settingDrawer
color: MSettings.darkTheme ? "#323232" : "#f3f3f3"
+ layer.enabled: true
+ layer.effect: ElevationEffect {
+ elevation: 4
+ }
+
Column {
anchors.fill: parent
diff --git a/qml/component/ElevationEffect.qml b/qml/component/ElevationEffect.qml
new file mode 100644
index 0000000..ca2a4c6
--- /dev/null
+++ b/qml/component/ElevationEffect.qml
@@ -0,0 +1,145 @@
+import QtQuick 2.9
+import QtGraphicalEffects 1.0
+
+/*!
+ An effect for standard Material Design elevation shadows
+ */
+Item {
+ id: effect
+
+ property variant source
+
+ property int elevation: 0
+
+ // Shadow details follow Material Design (taken from Angular Material)
+ readonly property var _shadows: [
+ [{offset: 0, blur: 0, spread: 0},
+ {offset: 0, blur: 0, spread: 0},
+ {offset: 0, blur: 0, spread: 0}],
+
+ [{offset: 1, blur: 3, spread: 0},
+ {offset: 1, blur: 1, spread: 0},
+ {offset: 2, blur: 1, spread: -1}],
+
+ [{offset: 1, blur: 5, spread: 0},
+ {offset: 2, blur: 2, spread: 0},
+ {offset: 3, blur: 1, spread: -2}],
+
+ [{offset: 1, blur: 8, spread: 0},
+ {offset: 3, blur: 4, spread: 0},
+ {offset: 3, blur: 3, spread: -2}],
+
+ [{offset: 2, blur: 4, spread: -1},
+ {offset: 4, blur: 5, spread: 0},
+ {offset: 1, blur: 10, spread: 0}],
+
+ [{offset: 3, blur: 5, spread: -1},
+ {offset: 5, blur: 8, spread: 0},
+ {offset: 1, blur: 14, spread: 0}],
+
+ [{offset: 3, blur: 5, spread: -1},
+ {offset: 6, blur: 10, spread: 0},
+ {offset: 1, blur: 18, spread: 0}],
+
+ [{offset: 4, blur: 5, spread: -2},
+ {offset: 7, blur: 10, spread: 1},
+ {offset: 2, blur: 16, spread: 1}],
+
+ [{offset: 5, blur: 5, spread: -3},
+ {offset: 8, blur: 10, spread: 1},
+ {offset: 3, blur: 14, spread: 2}],
+
+ [{offset: 5, blur: 6, spread: -3},
+ {offset: 9, blur: 12, spread: 1},
+ {offset: 3, blur: 16, spread: 2}],
+
+ [{offset: 6, blur: 6, spread: -3},
+ {offset: 10, blur: 14, spread: 1},
+ {offset: 4, blur: 18, spread: 3}],
+
+ [{offset: 6, blur: 7, spread: -4},
+ {offset: 11, blur: 15, spread: 1},
+ {offset: 4, blur: 20, spread: 3}],
+
+ [{offset: 7, blur: 8, spread: -4},
+ {offset: 12, blur: 17, spread: 2},
+ {offset: 5, blur: 22, spread: 4}],
+
+ [{offset: 7, blur: 8, spread: -4},
+ {offset: 13, blur: 19, spread: 2},
+ {offset: 5, blur: 24, spread: 4}],
+
+ [{offset: 7, blur: 9, spread: -4},
+ {offset: 14, blur: 21, spread: 2},
+ {offset: 5, blur: 26, spread: 4}],
+
+ [{offset: 8, blur: 9, spread: -5},
+ {offset: 15, blur: 22, spread: 2},
+ {offset: 6, blur: 28, spread: 5}],
+
+ [{offset: 8, blur: 10, spread: -5},
+ {offset: 16, blur: 24, spread: 2},
+ {offset: 6, blur: 30, spread: 5}],
+
+ [{offset: 8, blur: 11, spread: -5},
+ {offset: 17, blur: 26, spread: 2},
+ {offset: 6, blur: 32, spread: 5}],
+
+ [{offset: 9, blur: 11, spread: -5},
+ {offset: 18, blur: 28, spread: 2},
+ {offset: 7, blur: 34, spread: 6}],
+
+ [{offset: 9, blur: 12, spread: -6},
+ {offset: 19, blur: 29, spread: 2},
+ {offset: 7, blur: 36, spread: 6}],
+
+ [{offset: 10, blur: 13, spread: -6},
+ {offset: 20, blur: 31, spread: 3},
+ {offset: 8, blur: 38, spread: 7}],
+
+ [{offset: 10, blur: 13, spread: -6},
+ {offset: 21, blur: 33, spread: 3},
+ {offset: 8, blur: 40, spread: 7}],
+
+ [{offset: 10, blur: 14, spread: -6},
+ {offset: 22, blur: 35, spread: 3},
+ {offset: 8, blur: 42, spread: 7}],
+
+ [{offset: 11, blur: 14, spread: -7},
+ {offset: 23, blur: 36, spread: 3},
+ {offset: 9, blur: 44, spread: 8}],
+
+ [{offset: 11, blur: 15, spread: -7},
+ {offset: 24, blur: 38, spread: 3},
+ {offset: 9, blur: 46, spread: 8}]
+ ]
+
+ readonly property var _shadowColors: [
+ Qt.rgba(0,0,0, 0.2),
+ Qt.rgba(0,0,0, 0.14),
+ Qt.rgba(0,0,0, 0.12)
+ ]
+
+ Repeater {
+ model: _shadows[elevation]
+
+ delegate: RectangularGlow {
+ anchors {
+ centerIn: parent
+ verticalCenterOffset: modelData.offset
+ }
+
+ width: parent.width + 2 * modelData.spread
+ height: parent.height + 2 * modelData.spread
+ glowRadius: modelData.blur/2
+ spread: 0.05
+ color: _shadowColors[index]
+ cornerRadius: modelData.blur + (effect.source.radius || 0)
+ }
+ }
+
+ ShaderEffect {
+ anchors.fill: parent
+ property alias source: effect.source;
+ }
+}
diff --git a/qml/component/GenericBubble.qml b/qml/component/GenericBubble.qml
index 18761f9..90613ab 100644
--- a/qml/component/GenericBubble.qml
+++ b/qml/component/GenericBubble.qml
@@ -8,7 +8,6 @@ Control {
property bool colored: false
readonly property bool darkBackground: highlighted ? true : MSettings.darkTheme
- readonly property color backgroundColor: MSettings.darkTheme ? "#242424" : "lightgrey"
padding: 12
@@ -22,5 +21,12 @@ Control {
}
}
- background: Rectangle { color: colored ? Material.accent : highlighted ? Material.primary : backgroundColor }
+ background: Rectangle {
+ color: colored ? Material.accent : highlighted ? Material.primary : Material.background
+
+ layer.enabled: true
+ layer.effect: ElevationEffect {
+ elevation: 2
+ }
+ }
}
diff --git a/qml/component/RoomDrawer.qml b/qml/component/RoomDrawer.qml
index 5a97ad6..d4f40a0 100644
--- a/qml/component/RoomDrawer.qml
+++ b/qml/component/RoomDrawer.qml
@@ -101,6 +101,8 @@ Drawer {
Layout.fillWidth: true
Layout.fillHeight: true
+ id: userListView
+
clip: true
boundsBehavior: Flickable.DragOverBounds
@@ -109,48 +111,58 @@ Drawer {
room: roomDrawer.room
}
- delegate: SwipeDelegate {
- width: parent.width
- height: 48
+ delegate: Column {
+ property bool expanded: false
- RowLayout {
- anchors.fill: parent
- anchors.margins: 8
- spacing: 12
+ ItemDelegate {
+ width: userListView.width
+ height: 48
- ImageItem {
- Layout.preferredWidth: height
- Layout.fillHeight: true
+ RowLayout {
+ anchors.fill: parent
+ anchors.margins: 8
+ spacing: 12
- image: avatar
- hint: name
+ ImageItem {
+ Layout.preferredWidth: height
+ Layout.fillHeight: true
+
+ image: avatar
+ hint: name
+ }
+
+ Label {
+ Layout.fillWidth: true
+
+ text: name
+ }
}
- Label {
+ onClicked: expanded = !expanded
+ }
+
+ ColumnLayout {
+ width: parent.width - 32
+ height: expanded ? implicitHeight : 0
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ spacing: 0
+
+ clip: true
+
+ Button {
Layout.fillWidth: true
- text: name
- }
- }
+ text: "Kick"
+ highlighted: true
- swipe.right: Rectangle {
- width: parent.height
- height: parent.height
- anchors.right: parent.right
-
- color: Material.accent
-
- MaterialIcon {
- anchors.fill: parent
-
- icon: "\ue8fb"
- color: "white"
+ onClicked: room.kickMember(userId)
}
- SwipeDelegate.onClicked: room.kickMember(userId)
+ Behavior on height {
+ PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
+ }
}
-
- onClicked: inputField.insert(inputField.cursorPosition, name)
}
ScrollBar.vertical: ScrollBar {}
diff --git a/qml/form/RoomForm.qml b/qml/form/RoomForm.qml
index ea9b76a..9fd91c0 100644
--- a/qml/form/RoomForm.qml
+++ b/qml/form/RoomForm.qml
@@ -5,9 +5,10 @@ import QtQuick.Controls.Material 2.2
import QtGraphicalEffects 1.0
import Spectral 0.1
import Spectral.Settings 0.1
+import SortFilterProxyModel 0.2
-import "qrc:/qml/component"
-import "qrc:/qml/menu"
+import "../component"
+import "../menu"
import "qrc:/js/md.js" as Markdown
import "qrc:/js/util.js" as Util
@@ -16,6 +17,11 @@ Item {
id: item
+ MessageEventModel {
+ id: messageEventModel
+ room: currentRoom
+ }
+
RoomDrawer {
width: Math.min(item.width * 0.7, 480)
height: item.height
@@ -25,7 +31,7 @@ Item {
room: currentRoom
}
- Pane {
+ Control {
anchors.fill: parent
padding: 0
@@ -47,6 +53,11 @@ Item {
color: Material.accent
+ layer.enabled: true
+ layer.effect: ElevationEffect {
+ elevation: 2
+ }
+
ItemDelegate {
anchors.fill: parent
@@ -69,7 +80,6 @@ Item {
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
- Layout.alignment: Qt.AlignHCenter
visible: parent.width > 64
@@ -113,7 +123,6 @@ Item {
id: messageListView
- clip: true
displayMarginBeginning: 40
displayMarginEnd: 40
verticalLayoutDirection: ListView.BottomToTop
@@ -124,26 +133,27 @@ Item {
cacheBuffer: 200
- model: MessageEventModel {
- id: messageEventModel
- room: currentRoom
+ model: SortFilterProxyModel {
+ id: sortedRoomListModel
+
+ sourceModel: messageEventModel
+
+ filters: ExpressionFilter {
+ expression: marks !== 0x08 && marks !== 0x10
+ }
}
delegate: ColumnLayout {
- readonly property bool hidden: marks === EventStatus.Redacted || marks === EventStatus.Hidden
-
width: parent.width
- height: hidden ? -8 : undefined
id: delegateColumn
- clip: true
spacing: 8
Label {
Layout.alignment: Qt.AlignHCenter
- visible: section !== aboveSection && !hidden
+ visible: section !== aboveSection
text: section
color: "white"
@@ -316,168 +326,191 @@ Item {
}
}
- RowLayout {
+ Item {
Layout.fillWidth: true
- Layout.preferredHeight: 48
- Layout.margins: 16
+ Layout.preferredHeight: 40
+ }
- spacing: 0
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 40
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
- ItemDelegate {
- Layout.preferredWidth: 48
- Layout.preferredHeight: 48
+ color: Material.background
- contentItem: MaterialIcon { icon: "\ue226" }
+ Rectangle {
+ anchors.verticalCenter: parent.top
+ width: parent.width
+ height: 48
- onClicked: currentRoom.chooseAndUploadFile()
- }
+ color: MSettings.darkTheme ? "#303030" : "#fafafa"
- ScrollView {
- Layout.fillWidth: true
- Layout.preferredHeight: 48
-
- ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
-
- clip: true
-
- TextArea {
- property real progress: 0
-
- id: inputField
-
- wrapMode: Text.Wrap
- placeholderText: "Send a Message"
- leftPadding: 16
- topPadding: 0
- bottomPadding: 0
- selectByMouse: true
- verticalAlignment: TextEdit.AlignVCenter
-
- text: currentRoom ? currentRoom.cachedInput : ""
-
- onTextChanged: {
- timeoutTimer.restart()
- repeatTimer.start()
- currentRoom.cachedInput = text
- }
-
- background: Rectangle { color: MSettings.darkTheme ? "#282828" : "#eaeaea" }
-
- ToolTip.visible: currentRoom && currentRoom.hasUsersTyping
- ToolTip.text: currentRoom ? currentRoom.usersTyping : ""
-
- Keys.onReturnPressed: {
- if (event.modifiers & Qt.ShiftModifier) {
- inputField.insert(inputField.cursorPosition, "\n")
- } else {
- inputField.postMessage(inputField.text)
- inputField.text = ""
- }
- }
-
- 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)
- }
-
- function postMessage(text) {
- if (text.trim().length === 0) { return }
- if(!currentRoom) { return }
-
- var PREFIX_ME = '/me '
- var PREFIX_NOTICE = '/notice '
- var PREFIX_RAINBOW = '/rainbow '
- var PREFIX_HTML = '/html '
- var PREFIX_MARKDOWN = '/md '
-
- var replyRe = new RegExp("^> <(.*)><(.*)> (.*)\n\n(.*)")
- if (text.match(replyRe)) {
- var matches = text.match(replyRe)
- currentRoom.sendReply(matches[1], matches[2], matches[3], matches[4])
- return
- }
-
- if (text.indexOf(PREFIX_ME) === 0) {
- text = text.substr(PREFIX_ME.length)
- currentRoom.postMessage(text, RoomMessageEvent.Emote)
- return
- }
- if (text.indexOf(PREFIX_NOTICE) === 0) {
- text = text.substr(PREFIX_NOTICE.length)
- currentRoom.postMessage(text, RoomMessageEvent.Notice)
- return
- }
- if (text.indexOf(PREFIX_RAINBOW) === 0) {
- text = text.substr(PREFIX_RAINBOW.length)
-
- var parsedText = ""
- var rainbowColor = ["#ff2b00", "#ff5500", "#ff8000", "#ffaa00", "#ffd500", "#ffff00", "#d4ff00", "#aaff00", "#80ff00", "#55ff00", "#2bff00", "#00ff00", "#00ff2b", "#00ff55", "#00ff80", "#00ffaa", "#00ffd5", "#00ffff", "#00d4ff", "#00aaff", "#007fff", "#0055ff", "#002bff", "#0000ff", "#2a00ff", "#5500ff", "#7f00ff", "#aa00ff", "#d400ff", "#ff00ff", "#ff00d4", "#ff00aa", "#ff0080", "#ff0055", "#ff002b", "#ff0000"]
- for (var i = 0; i < text.length; i++) {
- parsedText = parsedText + "" + text.charAt(i) + ""
- }
- currentRoom.postHtmlMessage(text, parsedText, RoomMessageEvent.Text)
- return
- }
- if (text.indexOf(PREFIX_HTML) === 0) {
- text = text.substr(PREFIX_HTML.length)
- var re = new RegExp("<.*?>")
- var plainText = text.replace(re, "")
- currentRoom.postHtmlMessage(plainText, text, RoomMessageEvent.Text)
- return
- }
- if (text.indexOf(PREFIX_MARKDOWN) === 0) {
- text = text.substr(PREFIX_MARKDOWN.length)
- var parsedText = Markdown.markdown_parser(text)
- currentRoom.postHtmlMessage(text, parsedText, RoomMessageEvent.Text)
- return
- }
-
- currentRoom.postPlainText(text)
- }
+ layer.enabled: true
+ layer.effect: ElevationEffect {
+ elevation: 2
}
- }
- ItemDelegate {
- Layout.preferredWidth: 48
- Layout.preferredHeight: 48
+ RowLayout {
+ anchors.fill: parent
- id: emojiButton
+ spacing: 0
- contentItem: MaterialIcon { icon: "\ue24e" }
+ ItemDelegate {
+ Layout.preferredWidth: 48
+ Layout.preferredHeight: 48
- background: Rectangle { color: MSettings.darkTheme ? "#282828" : "#eaeaea" }
+ contentItem: MaterialIcon { icon: "\ue226" }
- onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.open()
+ onClicked: currentRoom.chooseAndUploadFile()
+ }
- EmojiPicker {
- x: window.width - 370
- y: window.height - 400
+ ScrollView {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 48
- width: 360
- height: 320
+ ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
- id: emojiPicker
+ clip: true
- parent: ApplicationWindow.overlay
+ TextArea {
+ property real progress: 0
- Material.elevation: 2
+ id: inputField
- textArea: inputField
+ wrapMode: Text.Wrap
+ placeholderText: "Send a Message"
+ leftPadding: 16
+ topPadding: 0
+ bottomPadding: 0
+ selectByMouse: true
+ verticalAlignment: TextEdit.AlignVCenter
+
+ text: currentRoom ? currentRoom.cachedInput : ""
+
+ background: Item {}
+
+ onTextChanged: {
+ timeoutTimer.restart()
+ repeatTimer.start()
+ currentRoom.cachedInput = text
+ }
+
+ ToolTip.visible: currentRoom && currentRoom.hasUsersTyping
+ ToolTip.text: currentRoom ? currentRoom.usersTyping : ""
+
+ Keys.onReturnPressed: {
+ if (event.modifiers & Qt.ShiftModifier) {
+ inputField.insert(inputField.cursorPosition, "\n")
+ } else {
+ inputField.postMessage(inputField.text)
+ inputField.text = ""
+ }
+ }
+
+ 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)
+ }
+
+ function postMessage(text) {
+ if (text.trim().length === 0) { return }
+ if(!currentRoom) { return }
+
+ var PREFIX_ME = '/me '
+ var PREFIX_NOTICE = '/notice '
+ var PREFIX_RAINBOW = '/rainbow '
+ var PREFIX_HTML = '/html '
+ var PREFIX_MARKDOWN = '/md '
+
+ var replyRe = new RegExp("^> <(.*)><(.*)> (.*)\n\n(.*)")
+ if (text.match(replyRe)) {
+ var matches = text.match(replyRe)
+ currentRoom.sendReply(matches[1], matches[2], matches[3], matches[4])
+ return
+ }
+
+ if (text.indexOf(PREFIX_ME) === 0) {
+ text = text.substr(PREFIX_ME.length)
+ currentRoom.postMessage(text, RoomMessageEvent.Emote)
+ return
+ }
+ if (text.indexOf(PREFIX_NOTICE) === 0) {
+ text = text.substr(PREFIX_NOTICE.length)
+ currentRoom.postMessage(text, RoomMessageEvent.Notice)
+ return
+ }
+ if (text.indexOf(PREFIX_RAINBOW) === 0) {
+ text = text.substr(PREFIX_RAINBOW.length)
+
+ var parsedText = ""
+ var rainbowColor = ["#ff2b00", "#ff5500", "#ff8000", "#ffaa00", "#ffd500", "#ffff00", "#d4ff00", "#aaff00", "#80ff00", "#55ff00", "#2bff00", "#00ff00", "#00ff2b", "#00ff55", "#00ff80", "#00ffaa", "#00ffd5", "#00ffff", "#00d4ff", "#00aaff", "#007fff", "#0055ff", "#002bff", "#0000ff", "#2a00ff", "#5500ff", "#7f00ff", "#aa00ff", "#d400ff", "#ff00ff", "#ff00d4", "#ff00aa", "#ff0080", "#ff0055", "#ff002b", "#ff0000"]
+ for (var i = 0; i < text.length; i++) {
+ parsedText = parsedText + "" + text.charAt(i) + ""
+ }
+ currentRoom.postHtmlMessage(text, parsedText, RoomMessageEvent.Text)
+ return
+ }
+ if (text.indexOf(PREFIX_HTML) === 0) {
+ text = text.substr(PREFIX_HTML.length)
+ var re = new RegExp("<.*?>")
+ var plainText = text.replace(re, "")
+ currentRoom.postHtmlMessage(plainText, text, RoomMessageEvent.Text)
+ return
+ }
+ if (text.indexOf(PREFIX_MARKDOWN) === 0) {
+ text = text.substr(PREFIX_MARKDOWN.length)
+ var parsedText = Markdown.markdown_parser(text)
+ currentRoom.postHtmlMessage(text, parsedText, RoomMessageEvent.Text)
+ return
+ }
+
+ currentRoom.postPlainText(text)
+ }
+ }
+ }
+
+ ItemDelegate {
+ Layout.preferredWidth: 48
+ Layout.preferredHeight: 48
+
+ id: emojiButton
+
+ contentItem: MaterialIcon { icon: "\ue24e" }
+
+ onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.open()
+
+ EmojiPicker {
+ x: window.width - 370
+ y: window.height - 400
+
+ width: 360
+ height: 320
+
+ id: emojiPicker
+
+ parent: ApplicationWindow.overlay
+
+ Material.elevation: 2
+
+ textArea: inputField
+ }
+ }
}
}
}
diff --git a/qml/form/RoomListForm.qml b/qml/form/RoomListForm.qml
index a6e192a..f290d6e 100644
--- a/qml/form/RoomListForm.qml
+++ b/qml/form/RoomListForm.qml
@@ -8,18 +8,18 @@ import Spectral 0.1
import SortFilterProxyModel 0.2
import Spectral.Settings 0.1
-import "qrc:/qml/component"
-import "qrc:/qml/menu"
+import "../component"
+import "../menu"
import "qrc:/js/util.js" as Util
-Item {
+Rectangle {
property alias listModel: sortedRoomListModel.sourceModel
property int filter: 0
property var enteredRoom: null
- Label {
- z: 10
+ color: MSettings.darkTheme ? "#323232" : "#f3f3f3"
+ Label {
text: MSettings.miniMode ? "Empty" : "Here? No, not here."
anchors.centerIn: parent
visible: listView.count === 0
@@ -41,7 +41,13 @@ Item {
bottomPadding: 0
placeholderText: "Search..."
- background: Rectangle { color: MSettings.darkTheme ? "#303030" : "#fafafa" }
+ background: Rectangle {
+ color: MSettings.darkTheme ? "#303030" : "#fafafa"
+ layer.enabled: true
+ layer.effect: ElevationEffect {
+ elevation: searchField.focus ? 2 : 1
+ }
+ }
Shortcut {
sequence: StandardKey.Find
diff --git a/res.qrc b/res.qrc
index 716c908..0289272 100644
--- a/res.qrc
+++ b/res.qrc
@@ -30,5 +30,6 @@
qml/component/AutoLabel.qml
qml/component/RoomDrawer.qml
js/util.js
+ qml/component/ElevationEffect.qml
diff --git a/src/messageeventmodel.cpp b/src/messageeventmodel.cpp
index 1c1f30f..8f2bb5e 100644
--- a/src/messageeventmodel.cpp
+++ b/src/messageeventmodel.cpp
@@ -13,6 +13,10 @@
#include
#include // for qmlRegisterType()
+static QString parseAvatarUrl(QUrl url) {
+ return url.host() + "/" + url.path();
+}
+
QHash MessageEventModel::roleNames() const {
QHash roles = QAbstractItemModel::roleNames();
roles[EventTypeRole] = "eventType";
@@ -330,11 +334,12 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
if (e.hasTextContent() && e.mimeType().name() != "text/plain") {
static const QRegExp userPillRegExp(
- "(.*)");
- static const QRegExp replyToRegExp(
- "In reply to");
- return QString(static_cast(e.content())->body)
- .replace(userPillRegExp, "\\2").replace(replyToRegExp, "");
+ "(.*)");
+ QString formattedStr(
+ static_cast(e.content())->body);
+ formattedStr.replace(userPillRegExp,
+ "\\1");
+ return formattedStr;
}
if (e.hasFileContent()) {
auto fileCaption = e.content()->fileInfo()->originalName;