diff --git a/kirigami-icons.qrc b/kirigami-icons.qrc
index 505228b..f257fc1 100644
--- a/kirigami-icons.qrc
+++ b/kirigami-icons.qrc
@@ -1,58 +1,58 @@
3rdparty/breeze-icons/icons/index.theme
3rdparty/breeze-icons/icons/actions/22/application-menu.svg
3rdparty/breeze-icons/icons/actions/22/bookmark-remove.svg
3rdparty/breeze-icons/icons/actions/22/document-decrypt.svg
3rdparty/breeze-icons/icons/actions/22/contact-new.svg
3rdparty/breeze-icons/icons/actions/22/dialog-close.svg
3rdparty/breeze-icons/icons/actions/22/folder-sync.svg
3rdparty/breeze-icons/icons/actions/22/go-next.svg
3rdparty/breeze-icons/icons/actions/22/go-previous.svg
3rdparty/breeze-icons/icons/actions/22/go-up.svg
3rdparty/breeze-icons/icons/actions/22/handle-left.svg
3rdparty/breeze-icons/icons/actions/22/handle-right.svg
3rdparty/breeze-icons/icons/actions/22/help-about.svg
3rdparty/breeze-icons/icons/actions/22/mail-invitation.svg
3rdparty/breeze-icons/icons/actions/22/overflow-menu.svg
3rdparty/breeze-icons/icons/actions/22/system-shutdown.svg
3rdparty/breeze-icons/icons/actions/22/view-list-icons.svg
- 3rdparty/breeze-icons/icons/actions/22/go-parent-folder.svg
+ 3rdparty/breeze-icons/icons/actions/22/go-parent-folder.svg
3rdparty/breeze-icons/icons/places/22/folder.svg
3rdparty/breeze-icons/icons/mimetypes/22/text-x-plain.svg
3rdparty/breeze-icons/icons/actions/22/tab-close.svg
3rdparty/breeze-icons/icons/actions/22/password-show-on.svg
3rdparty/breeze-icons/icons/actions/22/password-show-off.svg
3rdparty/breeze-icons/icons/actions/22/settings-configure.svg
3rdparty/breeze-icons/icons/actions/22/lock.svg
+
+
+ 3rdparty/breeze-icons/icons/emotes/22/face-smile.svg
+
3rdparty/breeze-icons/icons/actions/16/document-send.svg
3rdparty/breeze-icons/icons/actions/symbolic/document-send-symbolic.svg
3rdparty/breeze-icons/icons/actions/symbolic/go-next-symbolic.svg
3rdparty/breeze-icons/icons/actions/symbolic/go-previous-symbolic.svg
3rdparty/breeze-icons/icons/actions/symbolic/edit-symbolic.svg
3rdparty/breeze-icons/icons/mimetypes/64/image-jpeg.svg
3rdparty/breeze-icons/icons/mimetypes/64/video-mp4.svg
3rdparty/breeze-icons/icons/mimetypes/64/x-office-document.svg
3rdparty/breeze-icons/icons/mimetypes/64/audio-mp3.svg
3rdparty/breeze-icons/icons/mimetypes/22/text-x-plain.svg
-
-
- 3rdparty/breeze-icons/icons/preferences/32/preferences-desktop-emoticons.svg
-
diff --git a/src/qml/ChatPage.qml b/src/qml/ChatPage.qml
index 3d618aa..26bd97e 100644
--- a/src/qml/ChatPage.qml
+++ b/src/qml/ChatPage.qml
@@ -1,361 +1,361 @@
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2019 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see .
*/
import QtQuick 2.6
import QtQuick.Controls 2.0 as Controls
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.2 as Kirigami
import QtGraphicalEffects 1.0
import im.kaidan.kaidan 1.0
import EmojiModel 0.1
import "elements"
Kirigami.ScrollablePage {
property string chatName
property bool isWritingSpoiler
property string messageToCorrect
title: chatName
keyboardNavigationEnabled: true
actions.contextualActions: [
Kirigami.Action {
visible: !isWritingSpoiler
iconSource: "password-show-off"
text: qsTr("Send a spoiler message")
onTriggered: isWritingSpoiler = true
}
]
SendMediaSheet {
id: sendMediaSheet
}
FileChooser {
id: fileChooser
title: qsTr("Select a file")
onAccepted: {
sendMediaSheet.jid = kaidan.messageModel.chatPartner
sendMediaSheet.fileUrl = fileUrl
sendMediaSheet.open()
}
}
function openFileDialog(filterName, filter) {
fileChooser.filterName = filterName
fileChooser.filter = filter
fileChooser.open()
mediaDrawer.close()
}
Kirigami.OverlayDrawer {
id: mediaDrawer
edge: Qt.BottomEdge
height: Kirigami.Units.gridUnit * 8
contentItem: RowLayout {
id: content
Layout.alignment: Qt.AlignHCenter
Layout.fillHeight: true
IconButton {
buttonText: qsTr("Image")
iconSource: "image-jpeg"
onClicked: openFileDialog("Images", "*.jpg *.jpeg *.png *.gif")
Layout.alignment: Qt.AlignHCenter
}
IconButton {
buttonText: qsTr("Video")
iconSource: "video-mp4"
onClicked: openFileDialog("Videos", "*.mp4 *.mkv *.avi *.webm")
Layout.alignment: Qt.AlignHCenter
}
IconButton {
buttonText: qsTr("Audio")
iconSource: "audio-mp3"
onClicked: openFileDialog("Audio files", "*.mp3 *.wav *.flac *.ogg *.m4a *.mka")
Layout.alignment: Qt.AlignHCenter
}
IconButton {
buttonText: qsTr("Document")
iconSource: "x-office-document"
onClicked: openFileDialog("Documents", "*.doc *.docx *.odt")
Layout.alignment: Qt.AlignHCenter
}
IconButton {
buttonText: qsTr("Other file")
iconSource: "text-x-plain"
onClicked: openFileDialog("All files", "*")
Layout.alignment: Qt.AlignHCenter
}
}
}
background: Image {
id: bgimage
source: kaidan.utils.getResourcePath("images/chat.png")
anchors.fill: parent
fillMode: Image.Tile
horizontalAlignment: Image.AlignLeft
verticalAlignment: Image.AlignTop
}
// Chat
ListView {
verticalLayoutDirection: ListView.BottomToTop
spacing: Kirigami.Units.smallSpacing * 2
// connect the database
model: kaidan.messageModel
delegate: ChatMessage {
msgId: model.id
sender: model.sender
sentByMe: model.sentByMe
messageBody: model.body
dateTime: new Date(model.timestamp)
isRead: model.isDelivered
name: chatName
mediaType: model.mediaType
mediaGetUrl: model.mediaUrl
mediaLocation: model.mediaLocation
edited: model.isEdited
isSpoiler: model.isSpoiler
isShowingSpoiler: false
spoilerHint: model.spoilerHint
onMessageEditRequested: {
messageToCorrect = id
messageField.text = body
messageField.state = "edit"
}
}
}
// Message Writing
footer: Controls.Pane {
id: sendingArea
layer.enabled: sendingArea.enabled
layer.effect: DropShadow {
verticalOffset: 1
color: Kirigami.Theme.disabledTextColor
samples: 20
spread: 0.3
cached: true // element is static
}
padding: 0
wheelEnabled: true
background: Rectangle {
color: Kirigami.Theme.backgroundColor
}
RowLayout {
anchors.fill: parent
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
Controls.ToolButton {
id: attachButton
visible: kaidan.uploadServiceFound
Layout.preferredWidth: Kirigami.Units.gridUnit * 3
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
padding: 0
Kirigami.Icon {
source: "document-send-symbolic"
isMask: true
smooth: true
anchors.centerIn: parent
width: Kirigami.Units.gridUnit * 2
height: width
}
onClicked: {
if (Kirigami.Settings.isMobile)
mediaDrawer.open()
else
openFileDialog("All files", "(*)")
}
}
ColumnLayout {
Layout.minimumHeight: messageField.height + Kirigami.Units.smallSpacing * 2
Layout.fillWidth: true
spacing: 0
RowLayout {
visible: isWritingSpoiler
Controls.TextArea {
id: spoilerHintField
Layout.fillWidth: true
placeholderText: qsTr("Spoiler hint")
wrapMode: Controls.TextArea.Wrap
selectByMouse: true
background: Item {}
}
Controls.ToolButton {
Layout.preferredWidth: Kirigami.Units.gridUnit * 1.5
Layout.preferredHeight: Kirigami.Units.gridUnit * 1.5
padding: 0
Kirigami.Icon {
source: "tab-close"
smooth: true
anchors.centerIn: parent
width: Kirigami.Units.gridUnit * 1.5
height: width
}
onClicked: {
isWritingSpoiler = false
spoilerHintField.text = ""
}
}
}
Kirigami.Separator {
visible: isWritingSpoiler
Layout.fillWidth: true
}
Controls.TextArea {
id: messageField
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
placeholderText: qsTr("Compose message")
wrapMode: Controls.TextArea.Wrap
selectByMouse: true
background: Item {}
state: "compose"
states: [
State {
name: "compose"
},
State {
name: "edit"
}
]
Keys.onReturnPressed: {
if (event.key === Qt.Key_Return) {
if (event.modifiers & Qt.ControlModifier) {
messageField.append("")
} else {
sendButton.onClicked()
event.accepted = true
}
}
}
}
}
EmojiPicker {
x: -width + parent.width
y: -height - 16
width: Kirigami.Units.gridUnit * 20
height: Kirigami.Units.gridUnit * 15
id: emojiPicker
model: EmojiProxyModel {
group: Emoji.People
sourceModel: EmojiModel {}
}
textArea: messageField
}
Controls.ToolButton {
id: emojiPickerButton
Layout.preferredWidth: Kirigami.Units.gridUnit * 3
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
padding: 0
Kirigami.Icon {
- source: "preferences-desktop-emoticons"
+ source: "face-smile"
enabled: sendButton.enabled
isMask: false
smooth: true
anchors.centerIn: parent
width: Kirigami.Units.gridUnit * 2
height: width
}
onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.open()
}
Controls.ToolButton {
id: sendButton
Layout.preferredWidth: Kirigami.Units.gridUnit * 3
Layout.preferredHeight: Kirigami.Units.gridUnit * 3
padding: 0
Kirigami.Icon {
source: {
if (messageField.state == "compose")
return "document-send"
else if (messageField.state == "edit")
return "edit-symbolic"
}
enabled: sendButton.enabled
isMask: true
smooth: true
anchors.centerIn: parent
width: Kirigami.Units.gridUnit * 2
height: width
}
onClicked: {
// don't send empty messages
if (!messageField.text.length) {
return
}
// disable the button to prevent sending
// the same message several times
sendButton.enabled = false
// send the message
if (messageField.state == "compose") {
kaidan.sendMessage(
kaidan.messageModel.chatPartner,
messageField.text,
isWritingSpoiler,
spoilerHintField.text
)
} else if (messageField.state == "edit") {
kaidan.correctMessage(
kaidan.messageModel.chatPartner,
messageToCorrect,
messageField.text
)
}
// clean up the text fields
messageField.text = ""
messageField.state = "compose"
spoilerHintField.text = ""
isWritingSpoiler = false
// reenable the button
sendButton.enabled = true
}
}
}
}
}