feat: send images - UNSAFE -

Sends images but does not clean metadata nor limits file size
This commit is contained in:
Richard Ramos 2020-07-20 13:04:33 -04:00 committed by Iuri Matias
parent 1b71e36b48
commit a32a156651
10 changed files with 223 additions and 16 deletions

View File

@ -108,6 +108,10 @@ QtObject:
self.status.chat.resendMessage(messageId)
self.messageList[chatId].resetTimeOut(messageId)
proc sendImage*(self: ChatsView, imagePath: string) {.slot.} =
let image = replace(imagePath, "file://", "")
self.status.chat.sendImage(self.activeChannel.id, image)
proc activeChannelChanged*(self: ChatsView) {.signal.}
proc userNameOrAlias*(self: ChatsView, pubKey: string): string {.slot.} =

View File

@ -218,6 +218,13 @@ proc sendMessage*(self: ChatModel, chatId: string, msg: string, replyTo: string
for msg in messages:
self.events.emit("sendingMessage", MessageArgs(id: msg.id, channel: msg.chatId))
proc sendImage*(self: ChatModel, chatId: string, image: string) =
var response = status_chat.sendImageMessage(chatId, image)
var (chats, messages) = self.processChatUpdate(parseJson(response))
self.events.emit("chatUpdate", ChatUpdateArgs(messages: messages, chats: chats, contacts: @[]))
for msg in messages:
self.events.emit("sendingMessage", MessageArgs(id: msg.id, channel: msg.chatId))
proc addStickerToRecent*(self: ChatModel, sticker: Sticker, save: bool = false) =
self.recentStickers.insert(sticker, 0)
self.recentStickers = self.recentStickers.deduplicate()

View File

@ -83,6 +83,16 @@ proc sendChatMessage*(chatId: string, msg: string, replyTo: string): string =
}
])
proc sendImageMessage*(chatId: string, image: string): string =
callPrivateRPC("sendChatMessage".prefix, %* [
{
"chatId": chatId,
"contentType": ContentType.Image.int,
"imagePath": image,
"text": "Update to latest version to see a nice image here!"
}
])
proc sendStickerMessage*(chatId: string, sticker: Sticker): string =
callPrivateRPC("sendChatMessage".prefix, %* [
{

View File

@ -10,7 +10,12 @@ import "./data"
StackLayout {
id: chatColumnLayout
property int chatGroupsListViewCount: 0
property bool isReply: false
property bool isImage: false
property bool isExtendedInput: isReply || isImage
property var appSettings
property bool isConnected: false
Layout.fillHeight: true
@ -19,6 +24,25 @@ StackLayout {
currentIndex: chatsModel.activeChannelIndex > -1 && chatGroupsListViewCount > 0 ? 0 : 1
function showReplyArea(){
isReply = true;
isImage = false;
replyAreaContainer.setup()
}
function showImageArea(imagePath){
isImage = true;
isReply = false;
sendImageArea.image = imagePath[0];
}
function hideExtendedArea(){
isImage = false;
isReply = false;
replyAreaContainer.setup();
sendImageArea.image = "";
}
ColumnLayout {
spacing: 0
@ -130,10 +154,7 @@ StackLayout {
Action {
//% "Reply to"
text: qsTrId("reply-to")
onTriggered: {
isReply = true;
replyAreaContainer.setup()
}
onTriggered: showReplyArea()
}
}
@ -166,7 +187,7 @@ StackLayout {
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.fillWidth: true
Layout.preferredWidth: parent.width
height: !isReply ? 70 : 140
height: !isExtendedInput ? 70 : 140
Layout.preferredHeight: height
SuggestionBox {
@ -205,10 +226,27 @@ StackLayout {
visible: isReply
}
SendImageArea {
id: sendImageArea
visible: isImage
}
ChatInput {
id: chatInput
height: 40
anchors.top: !isReply ? inputArea.top : replyAreaContainer.bottom
anchors.top: {
if(!isExtendedInput){
return inputArea.top;
}
if(isReply){
return replyAreaContainer.bottom;
}
if(isImage){
return sendImageArea.bottom;
}
}
anchors.topMargin: 4
anchors.left: parent.left
anchors.right: parent.right

View File

@ -15,7 +15,7 @@ Item {
Button {
id: chatSendBtn
visible: txtData.length > 0
visible: txtData.length > 0 || chatColumn.isImage
width: 30
height: 30
text: ""
@ -23,8 +23,15 @@ Item {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
onClicked: {
chatsModel.sendMessage(txtData.text, chatColumn.isReply ? SelectedMessage.messageId : "")
txtData.text = ""
if(chatColumn.isImage){
chatsModel.sendImage(sendImageArea.image);
chatColumn.hideExtendedArea();
}
if(txtData.text.trim() > 0){
chatsModel.sendMessage(txtData.text, chatColumn.isReply ? SelectedMessage.messageId : "")
txtData.text = "";
}
}
background: Rectangle {
color: parent.enabled ? Style.current.blue : Style.current.grey
@ -45,7 +52,11 @@ Item {
id: emojiIconContainer
width: emojiIcon.width + chatButtonsContainer.iconPadding * 2
height: emojiIcon.height + chatButtonsContainer.iconPadding * 2
anchors.right: txtData.length == 0 ? stickerIconContainer.left : chatSendBtn.left
anchors.right: {
if(stickerIconContainer.visible) return stickerIconContainer.left;
if(imageIconContainer.visible) return imageIconContainer.left;
return chatSendBtn.left;
}
anchors.rightMargin: Style.current.padding - chatButtonsContainer.iconPadding * 2
anchors.verticalCenter: parent.verticalCenter
radius: Style.current.radius
@ -91,11 +102,11 @@ Item {
property bool hovered: false
id: stickerIconContainer
visible: txtData.length == 0
visible: !chatColumn.isExtendedInput && txtData.length == 0
width: emojiIcon.width + chatButtonsContainer.iconPadding * 2
height: emojiIcon.height + chatButtonsContainer.iconPadding * 2
anchors.right: parent.right
anchors.rightMargin: Style.current.padding - chatButtonsContainer.iconPadding
anchors.right: imageIconContainer.visible ? imageIconContainer.left : parent.right
anchors.rightMargin: Style.current.padding - chatButtonsContainer.iconPadding * (imageIconContainer.visible ? 2 : 1)
anchors.verticalCenter: parent.verticalCenter
radius: Style.current.radius
color: hovered ? Style.current.lightBlue : Style.current.transparent
@ -136,6 +147,50 @@ Item {
}
}
Rectangle {
property bool hovered: false
visible: !chatColumn.isExtendedInput && (chatsModel.activeChannel.chatType === Constants.chatTypePrivateGroupChat || chatsModel.activeChannel.chatType === Constants.chatTypeOneToOne)
id: imageIconContainer
width: emojiIcon.width + chatButtonsContainer.iconPadding * 2
height: emojiIcon.height + chatButtonsContainer.iconPadding * 2
anchors.right: chatSendBtn.visible ? chatSendBtn.left : parent.right
anchors.rightMargin: Style.current.padding - chatButtonsContainer.iconPadding
anchors.verticalCenter: parent.verticalCenter
radius: Style.current.radius
color: hovered ? Style.current.lightBlue : Style.current.transparent
Image {
id: imageIcon
width: 20
height: 20
fillMode: Image.PreserveAspectFit
source: "../../../img/images_icon.svg"
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
ColorOverlay {
anchors.fill: imageIcon
source: imageIcon
color: imageIconContainer.hovered ? Style.current.blue : Style.current.transparent
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: {
imageIconContainer.hovered = true
}
onExited: {
imageIconContainer.hovered = false
}
onClicked: {
imageDialog.open();
}
}
}
StickersPopup {
id: stickersPopup
width: 360

View File

@ -2,6 +2,7 @@ import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtMultimedia 5.13
import QtQuick.Dialogs 1.0
import "../components"
import "../../../../shared"
import "../../../../imports"
@ -34,6 +35,10 @@ Rectangle {
function onEnter(event){
if (event.modifiers === Qt.NoModifier && (event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
if(chatColumn.isImage){
chatsModel.sendImage(sendImageArea.image);
chatColumn.hideExtendedArea();
}
if(txtData.text.trim().length > 0){
let msg = interpretMessage(txtData.text.trim())
@ -46,6 +51,22 @@ Rectangle {
}
}
FileDialog {
id: imageDialog
title: qsTr("Please choose an image")
folder: shortcuts.pictures
nameFilters: [
qsTr("Image files (*.jpg *.jpeg *.png)")
]
onAccepted: {
chatColumn.showImageArea(imageDialog.fileUrls);
txtData.forceActiveFocus();
}
onRejected: {
chatColumn.hideExtendedArea();
}
}
ScrollView {
id: scrollView
anchors.bottom: parent.bottom

View File

@ -9,7 +9,7 @@ Item {
property string userName: "Jotaro Kujo"
property string message: "That's right. We're friends... Of justice, that is."
property string plainText: "That's right. We're friends... Of justice, that is."
property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="
property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQAQMAAAC6caSPAAAABlBMVEXMzMz////TjRV2AAAAAWJLR0QB/wIt3gAAACpJREFUGBntwYEAAAAAw6D7Uw/gCtUAAAAAAAAAAAAAAAAAAAAAAAAAgBNPsAABAjKCqQAAAABJRU5ErkJggg=="
property bool isCurrentUser: false
property string timestamp: "1234567"
property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v"

View File

@ -63,8 +63,7 @@ Rectangle {
closeButton.color = Style.current.grey
}
onClicked: {
reset();
chatColumn.isReply = false;
chatColumn.hideExtendedArea()
}
}
}

View File

@ -0,0 +1,69 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../../imports"
import "../../../../shared"
import "./"
Rectangle {
id: sendImageArea
height: 70
property string image: ""
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
color: "#00000000"
Rectangle {
id: closeButton
height: 32
width: 32
anchors.top: parent.top
anchors.topMargin: Style.current.padding
anchors.rightMargin: Style.current.padding
anchors.right: parent.right
radius: 8
SVGImage {
id: closeModalImg
source: "../../../../shared/img/close.svg"
width: 25
height: 25
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
MouseArea {
id: closeImageArea
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onExited: {
closeButton.color = Style.current.white
}
onEntered: {
closeButton.color = Style.current.grey
}
onClicked: {
chatColumn.hideExtendedArea();
}
}
}
Image {
id: chatImage
width: 36
height: 36
anchors.topMargin: 20
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.top: parent.top
fillMode: Image.PreserveAspectFit
source: image
mipmap: true
smooth: false
antialiasing: true
}
}

View File

@ -0,0 +1,4 @@
<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.5 6.5C16.5 8.15685 15.1569 9.5 13.5 9.5C11.8431 9.5 10.5 8.15685 10.5 6.5C10.5 4.84315 11.8431 3.5 13.5 3.5C15.1569 3.5 16.5 4.84315 16.5 6.5ZM15 6.5C15 7.32843 14.3284 8 13.5 8C12.6716 8 12 7.32843 12 6.5C12 5.67157 12.6716 5 13.5 5C14.3284 5 15 5.67157 15 6.5Z" fill="#939BA1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 0C1.79086 0 0 1.79086 0 4V14C0 16.2091 1.79086 18 4 18H16C18.2091 18 20 16.2091 20 14V4C20 1.79086 18.2091 0 16 0H4ZM16 1.5H4C2.61929 1.5 1.5 2.61929 1.5 4V7.23223C1.5 7.67768 2.03857 7.90077 2.35355 7.58579L3.76256 6.17678C4.44598 5.49336 5.55402 5.49336 6.23744 6.17678L16.3181 16.2575C16.4372 16.3765 16.6094 16.4311 16.7695 16.3793C17.7737 16.0548 18.5 15.1122 18.5 14V4C18.5 2.61929 17.3807 1.5 16 1.5ZM1.53033 10.5303C1.51153 10.5491 1.5 10.5742 1.5 10.6008V14C1.5 15.3807 2.61929 16.5 4 16.5H13.2322C13.6777 16.5 13.9008 15.9614 13.5858 15.6464L5.17678 7.23744C5.07914 7.1398 4.92085 7.13981 4.82322 7.23744L1.53033 10.5303Z" fill="#939BA1"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB