2018-10-30 20:01:13 +00:00
/ * *
* Copyright ( C ) 2018 Aleix Pol Gonzalez < aleixpol @ kde . org >
2018-12-16 00:26:44 +00:00
* Copyright ( C ) 2018 Nicolas Fella < nicolas . fella @ gmx . de >
* Copyright ( C ) 2018 Simon Redman < simon @ ergotech . com >
2018-10-30 20:01:13 +00:00
*
* This program 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 2 of
* the License or ( at your option ) version 3 or any later version
* accepted by the membership of KDE e . V . ( or its successor approved
* by the membership of KDE e . V . ) , which shall act as a proxy
* defined in Section 14 of version 3 of the license .
*
* This program 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
2019-03-23 16:29:26 +00:00
* along with this program . If not , see < https: //www.gnu.org/licenses/>.
2018-10-30 20:01:13 +00:00
* /
import QtQuick 2.1
2020-05-09 17:50:08 +01:00
import QtQuick . Controls 2.2 as Controls
2018-10-30 20:01:13 +00:00
import QtQuick . Layouts 1.1
import org . kde . people 1.0
import org . kde . kirigami 2.4 as Kirigami
import org . kde . kdeconnect . sms 1.0
2019-03-09 23:23:33 +00:00
import QtGraphicalEffects 1.0
2018-10-30 20:01:13 +00:00
Kirigami . ScrollablePage
{
id: page
2019-01-23 01:27:10 +00:00
property bool deviceConnected
property string deviceId
[SMS App] Allow passing a message via args
Summary:
Add --message option to kdeconnect-sms to pass a message. The user only needs to choose a recepient and the message will be sent. Useful for integration with 3rd party
apps, e.g. via Purpose
Test Plan:
kdeconnect-sms --message "Hello World", choose chat, message is sent
Click another chat, no message sent
kdeconnect-sms without args, no message sent
Reviewers: #kde_connect, sredman
Reviewed By: #kde_connect, sredman
Subscribers: andyholmes, sredman, apol, kdeconnect
Tags: #kde_connect
Differential Revision: https://phabricator.kde.org/D17292
2019-03-09 21:32:36 +00:00
// property QtObject device
property string conversationId
2019-07-19 16:29:28 +01:00
property bool isMultitarget
[SMS App] Allow passing a message via args
Summary:
Add --message option to kdeconnect-sms to pass a message. The user only needs to choose a recepient and the message will be sent. Useful for integration with 3rd party
apps, e.g. via Purpose
Test Plan:
kdeconnect-sms --message "Hello World", choose chat, message is sent
Click another chat, no message sent
kdeconnect-sms without args, no message sent
Reviewers: #kde_connect, sredman
Reviewed By: #kde_connect, sredman
Subscribers: andyholmes, sredman, apol, kdeconnect
Tags: #kde_connect
Differential Revision: https://phabricator.kde.org/D17292
2019-03-09 21:32:36 +00:00
property string initialMessage
2020-03-21 22:57:28 +00:00
property string otherParty
property string invalidId: "-1"
2018-10-30 20:01:13 +00:00
2019-07-21 12:16:11 +01:00
property bool isInitalized: false
2019-07-19 18:33:15 +01:00
property var conversationModel: ConversationModel {
deviceId: page . deviceId
threadId: page . conversationId
2020-03-21 22:57:28 +00:00
otherParty: page . otherParty
2019-07-29 21:12:32 +01:00
onLoadingFinished: {
page . isInitalized = true
}
2019-07-19 18:33:15 +01:00
}
property var addresses
2020-05-09 17:50:08 +01:00
title: SmsHelper . getTitleForAddresses ( addresses )
2018-10-30 20:01:13 +00:00
[SMS App] Allow passing a message via args
Summary:
Add --message option to kdeconnect-sms to pass a message. The user only needs to choose a recepient and the message will be sent. Useful for integration with 3rd party
apps, e.g. via Purpose
Test Plan:
kdeconnect-sms --message "Hello World", choose chat, message is sent
Click another chat, no message sent
kdeconnect-sms without args, no message sent
Reviewers: #kde_connect, sredman
Reviewed By: #kde_connect, sredman
Subscribers: andyholmes, sredman, apol, kdeconnect
Tags: #kde_connect
Differential Revision: https://phabricator.kde.org/D17292
2019-03-09 21:32:36 +00:00
Component.onCompleted: {
if ( initialMessage . length > 0 ) {
2019-03-18 21:56:01 +00:00
messageField . text = initialMessage ;
[SMS App] Allow passing a message via args
Summary:
Add --message option to kdeconnect-sms to pass a message. The user only needs to choose a recepient and the message will be sent. Useful for integration with 3rd party
apps, e.g. via Purpose
Test Plan:
kdeconnect-sms --message "Hello World", choose chat, message is sent
Click another chat, no message sent
kdeconnect-sms without args, no message sent
Reviewers: #kde_connect, sredman
Reviewed By: #kde_connect, sredman
Subscribers: andyholmes, sredman, apol, kdeconnect
Tags: #kde_connect
Differential Revision: https://phabricator.kde.org/D17292
2019-03-09 21:32:36 +00:00
initialMessage = ""
}
2020-03-21 22:57:28 +00:00
if ( conversationId == invalidId ) {
isInitalized = true
}
[SMS App] Allow passing a message via args
Summary:
Add --message option to kdeconnect-sms to pass a message. The user only needs to choose a recepient and the message will be sent. Useful for integration with 3rd party
apps, e.g. via Purpose
Test Plan:
kdeconnect-sms --message "Hello World", choose chat, message is sent
Click another chat, no message sent
kdeconnect-sms without args, no message sent
Reviewers: #kde_connect, sredman
Reviewed By: #kde_connect, sredman
Subscribers: andyholmes, sredman, apol, kdeconnect
Tags: #kde_connect
Differential Revision: https://phabricator.kde.org/D17292
2019-03-09 21:32:36 +00:00
}
2018-12-13 05:50:08 +00:00
/ * *
* Build a chat message which is representative of all chat messages
*
* In other words , one which I can use to get a reasonable height guess
* /
ChatMessage {
id: genericMessage
2019-07-27 11:02:24 +01:00
name: "Generic Sender"
2018-12-13 05:50:08 +00:00
messageBody: "Generic Message Body"
dateTime: new Date ( '2000-0-0' )
visible: false
enabled: false
}
2018-10-30 20:01:13 +00:00
ListView {
2018-12-13 05:50:08 +00:00
id: viewport
2018-10-30 20:01:13 +00:00
model: QSortFilterProxyModel {
id: model
sortOrder: Qt . AscendingOrder
sortRole: ConversationModel . DateRole
2019-07-19 18:33:15 +01:00
sourceModel: conversationModel
2018-10-30 20:01:13 +00:00
}
spacing: Kirigami . Units . largeSpacing
2019-07-21 12:16:11 +01:00
highlightMoveDuration: 0
2018-10-30 20:01:13 +00:00
2020-05-09 17:50:08 +01:00
Controls . BusyIndicator {
2019-07-21 18:27:08 +01:00
running: ! isInitalized
}
onContentHeightChanged: {
if ( viewport . contentHeight <= 0 ) {
return
}
if ( ! isInitalized ) {
2019-12-22 07:49:55 +00:00
// If we aren't initialized, we need to request enough messages to fill the view
2019-07-21 18:27:08 +01:00
// In order to do that, request one more message until we have enough
if ( viewport . contentHeight < viewport . height ) {
console . debug ( "Requesting another message to fill the screen" )
conversationModel . requestMoreMessages ( 1 )
} else {
2019-12-22 07:49:55 +00:00
// Finish initializing: Scroll to the bottom of the view
2019-07-21 18:27:08 +01:00
// View the most-recent message
viewport . forceLayout ( )
Qt . callLater ( viewport . positionViewAtEnd )
isInitalized = true
}
return
}
}
2018-10-30 20:01:13 +00:00
delegate: ChatMessage {
2019-07-27 11:02:24 +01:00
name: model . sender
2018-10-30 20:01:13 +00:00
messageBody: model . display
sentByMe: model . fromMe
dateTime: new Date ( model . date )
2018-12-13 05:50:08 +00:00
ListView.onAdd: {
2019-07-21 12:16:11 +01:00
if ( ! isInitalized ) {
return
}
2019-07-21 18:27:08 +01:00
if ( index == viewport . count - 1 ) {
2018-12-13 05:50:08 +00:00
// This message is being inserted at the newest position
// We want to scroll to show it if the user is "almost" looking at it
// Define some fudge area. If the message is being drawn offscreen but within
// this distance, we move to show it anyway.
// Selected to be genericMessage.height because that value scales for different
// font sizes / DPI / etc. -- Better ideas are welcome!
// Double the value works nicely
var offscreenFudge = 2 * genericMessage . height
var viewportYBottom = viewport . contentY + viewport . height
if ( y < viewportYBottom + genericMessage . height ) {
2019-07-21 12:16:11 +01:00
viewport . highlightMoveDuration = - 1
2018-12-13 05:50:08 +00:00
viewport . currentIndex = index
}
2019-07-21 18:27:08 +01:00
}
2018-12-13 05:50:08 +00:00
}
2019-07-27 11:02:24 +01:00
onMessageCopyRequested: {
2020-05-09 17:50:08 +01:00
SmsHelper . copyToClipboard ( message )
2019-07-27 11:02:24 +01:00
}
2018-10-30 20:01:13 +00:00
}
2018-12-13 05:50:08 +00:00
onMovementEnded: {
2019-07-21 12:16:11 +01:00
if ( ! isInitalized ) {
return
}
2018-12-13 05:50:08 +00:00
// Unset the highlightRangeMode if it was set previously
highlightRangeMode = ListView . ApplyRange
2019-07-21 12:16:11 +01:00
// If we have scrolled to the last message currently in the view, request some more
2018-12-13 05:50:08 +00:00
if ( atYBeginning ) {
// "Lock" the view to the message currently at the beginning of the view
// This prevents the view from snapping to the top of the messages we are about to request
currentIndex = 0 // Index 0 is the beginning of the view
preferredHighlightBegin = visibleArea . yPosition
preferredHighlightEnd = preferredHighlightBegin + currentItem . height
highlightRangeMode = ListView . StrictlyEnforceRange
2019-07-21 18:27:08 +01:00
highlightMoveDuration = 0
2018-12-13 05:50:08 +00:00
// Get more messages
2019-07-19 18:33:15 +01:00
conversationModel . requestMoreMessages ( )
2018-12-13 05:50:08 +00:00
}
}
2018-10-30 20:01:13 +00:00
}
2020-05-09 17:50:08 +01:00
footer: Controls . Pane {
2019-03-09 23:23:33 +00:00
id: sendingArea
2019-07-19 16:29:28 +01:00
enabled: page . deviceConnected && ! page . isMultitarget
2019-03-09 23:23:33 +00:00
layer.enabled: sendingArea . enabled
layer.effect: DropShadow {
verticalOffset: 1
color: Kirigami . Theme . disabledTextColor
samples: 20
spread: 0.3
}
Layout.fillWidth: true
padding: 0
wheelEnabled: true
background: Rectangle {
color: Kirigami . Theme . viewBackgroundColor
}
RowLayout {
anchors.fill: parent
2018-11-28 19:15:11 +00:00
2020-05-09 17:50:08 +01:00
Controls . ScrollView {
2018-11-28 19:15:11 +00:00
Layout.fillWidth: true
2020-04-24 01:22:36 +01:00
Layout.maximumHeight: page . height > 300 ? page . height / 3 : 2 * page . height / 3
contentWidth: page . width - sendButtonArea . width
clip: true
2020-05-09 17:50:08 +01:00
Controls.ScrollBar.horizontal.policy: Controls . ScrollBar . AlwaysOff
2020-04-24 01:22:36 +01:00
2020-05-09 17:50:08 +01:00
Controls . TextArea {
2020-04-24 01:22:36 +01:00
anchors.fill: parent
id: messageField
placeholderText: page . isMultitarget ? i18nd ( "kdeconnect-sms" , "Replying to multitarget messages is not supported" ) : i18nd ( "kdeconnect-sms" , "Compose message" )
wrapMode: TextArea . Wrap
topPadding: Kirigami . Units . gridUnit * 0.5
bottomPadding: topPadding
selectByMouse: true
topInset: height * 2 // This removes background (frame) of the TextArea. Setting `background: Item {}` would cause segfault.
Keys.onReturnPressed: {
if ( event . key === Qt . Key_Return ) {
if ( event . modifiers & Qt . ShiftModifier ) {
messageField . append ( "" )
} else {
sendButton . onClicked ( )
event . accepted = true
}
2019-03-09 23:23:33 +00:00
}
2018-11-28 19:15:11 +00:00
}
}
2018-10-30 20:01:13 +00:00
}
2020-05-09 17:50:08 +01:00
2020-03-22 18:47:12 +00:00
ColumnLayout {
2020-04-24 01:22:36 +01:00
id: sendButtonArea
2020-05-09 17:50:08 +01:00
Controls . ToolButton {
2020-03-22 18:47:12 +00:00
id: sendButton
Layout.preferredWidth: Kirigami . Units . gridUnit * 2
Layout.preferredHeight: Kirigami . Units . gridUnit * 2
padding: 0
Kirigami . Icon {
source: "document-send"
enabled: sendButton . enabled
isMask: true
smooth: true
anchors.centerIn: parent
width: Kirigami . Units . gridUnit * 1.5
height: width
2019-03-09 23:23:33 +00:00
}
2020-03-22 18:47:12 +00:00
onClicked: {
// don't send empty messages
if ( ! messageField . text . length ) {
return
}
2019-03-09 23:23:33 +00:00
2020-03-22 18:47:12 +00:00
// disable the button to prevent sending
// the same message several times
sendButton . enabled = false
2019-03-09 23:23:33 +00:00
2020-03-22 18:47:12 +00:00
// send the message
if ( page . conversationId == page . invalidId ) {
conversationModel . sendMessageWithoutConversation ( messageField . text , page . otherParty )
} else {
conversationModel . sendReplyToConversation ( messageField . text )
}
messageField . text = ""
2019-03-09 23:23:33 +00:00
2020-03-22 18:47:12 +00:00
// re-enable the button
sendButton . enabled = true
}
}
2020-05-09 17:50:08 +01:00
Controls . Label {
2020-03-22 18:47:12 +00:00
id: "charCount"
text: conversationModel . getCharCountInfo ( messageField . text )
visible: text . length > 0
2020-03-23 11:37:16 +00:00
Layout.minimumWidth: Math . max ( Layout . minimumWidth , width ) // Make this label only grow, never shrink
2019-03-09 23:23:33 +00:00
}
2018-10-30 20:01:13 +00:00
}
}
}
}