Handle display of messageLocation

resolves #36
This commit is contained in:
John Gibbon 2020-09-28 22:58:11 +02:00
parent 5fa2a1200f
commit b58e33b2a4
14 changed files with 252 additions and 0 deletions

View file

@ -24,6 +24,7 @@ SOURCES += src/harbour-fernschreiber.cpp \
src/dbusadaptor.cpp \
src/dbusinterface.cpp \
src/notificationmanager.cpp \
src/processlauncher.cpp \
src/tdlibreceiver.cpp \
src/tdlibwrapper.cpp
@ -32,6 +33,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/DocumentPreview.qml \
qml/components/ImagePreview.qml \
qml/components/InReplyToRow.qml \
qml/components/LocationPreview.qml \
qml/components/WebPagePreview.qml \
qml/js/functions.js \
qml/pages/ChatPage.qml \
@ -99,6 +101,7 @@ HEADERS += \
src/dbusadaptor.h \
src/dbusinterface.h \
src/notificationmanager.h \
src/processlauncher.h \
src/tdlibreceiver.h \
src/tdlibsecrets.h \
src/tdlibwrapper.h

View file

@ -0,0 +1,120 @@
/*
Copyright (C) 2020 Sebastian J. Wolf
This file is part of Fernschreiber.
Fernschreiber 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.
Fernschreiber 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 Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.5
import QtGraphicalEffects 1.0
import Sailfish.Silica 1.0
Item {
id: imagePreviewItem
property variant locationData;
property int chatId;
property variant pictureFileInformation;
Component.onCompleted: {
updatePicture();
}
function updatePicture() {
if (locationData) {
tdLibWrapper.getMapThumbnailFile(chatId, locationData.latitude, locationData.longitude, Math.round(imagePreviewItem.width), Math.round(imagePreviewItem.height));
}
}
Connections {
target: tdLibWrapper
onFileUpdated: {
// we do not have a way of knowing if this is the correct file, so we have to guess the first new one should be right.
if(!imagePreviewItem.pictureFileInformation) {
imagePreviewItem.pictureFileInformation = fileInformation;
tdLibWrapper.downloadFile(imagePreviewItem.pictureFileInformation.id);
} else if(imagePreviewItem.pictureFileInformation && fileInformation.id === imagePreviewItem.pictureFileInformation.id) {
imagePreviewItem.pictureFileInformation = fileInformation;
singleImage.source = fileInformation.local.path;
}
}
}
AppNotification {
id: imageNotification
}
Image {
id: singleImage
width: parent.width - Theme.paddingSmall
height: parent.height - Theme.paddingSmall
anchors.centerIn: parent
fillMode: Image.PreserveAspectCrop
autoTransform: true
asynchronous: true
visible: status === Image.Ready
opacity: status === Image.Ready ? 1 : 0
Behavior on opacity { NumberAnimation {} }
Item {
anchors.centerIn: parent
width: markerImage.width
height: markerImage.height * 1.75 // 0.875 (vertical pin point) * 2
Image {
id: markerImage
source: 'image://theme/icon-m-location'
}
DropShadow {
anchors.fill: markerImage
horizontalOffset: 3
verticalOffset: 3
radius: 8.0
samples: 17
color: Theme.colorScheme ? Theme.lightPrimaryColor : Theme.darkPrimaryColor
source: markerImage
}
}
MouseArea {
anchors.fill: parent
onClicked: {
if(!processLauncher.launchProgram('harbour-pure-maps', ["geo:"+locationData.latitude+","+locationData.longitude])) {
imageNotification.show(qsTr("Install Pure Maps to inspect this location."));
}
}
Rectangle {
anchors.fill: parent
color: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
opacity: parent.pressed ? 1.0 : 0.0
}
}
}
Image {
id: imageLoadingBackgroundImage
source: "../../images/background-" + ( Theme.colorScheme ? "black" : "white" ) + "-small.png"
anchors {
centerIn: parent
}
width: parent.width - Theme.paddingMedium
height: parent.height - Theme.paddingMedium
visible: singleImage.status !== Image.Ready
asynchronous: true
fillMode: Image.PreserveAspectFit
opacity: 0.15
}
}

View file

@ -484,6 +484,7 @@ Page {
videoPreviewLoader.active = (( display.content['@type'] === "messageVideo" ) || ( display.content['@type'] === "messageAnimation" ));
audioPreviewLoader.active = (( display.content['@type'] === "messageVoiceNote" ) || ( display.content['@type'] === "messageAudio" ));
documentPreviewLoader.active = ( display.content['@type'] === "messageDocument" );
locationPreviewLoader.active = ( display.content['@type'] === "messageLocation" )
}
}
@ -716,7 +717,25 @@ Page {
width: parent.width
sourceComponent: documentPreviewComponent
}
Component {
id: locationPreviewComponent
LocationPreview {
id: messageLocationPreview
width: parent.width
height: parent.width * 2 / 3
chatId: display.id
locationData: ( display.content['@type'] === "messageLocation" ) ? display.content.location : ""
visible: display.content['@type'] === "messageLocation"
}
}
Loader {
id: locationPreviewLoader
active: false
asynchronous: true
width: parent.width
sourceComponent: locationPreviewComponent
}
Timer {
id: messageDateUpdater
interval: 60000

View file

@ -34,6 +34,7 @@
#include "chatmodel.h"
#include "notificationmanager.h"
#include "dbusadaptor.h"
#include "processlauncher.h"
int main(int argc, char *argv[])
{
@ -58,6 +59,9 @@ int main(int argc, char *argv[])
NotificationManager notificationManager(tdLibWrapper);
context->setContextProperty("notificationManager", &notificationManager);
ProcessLauncher processLauncher;
context->setContextProperty("processLauncher", &processLauncher);
view->setSource(SailfishApp::pathTo("qml/harbour-fernschreiber.qml"));
view->show();
return app->exec();

18
src/processlauncher.cpp Normal file
View file

@ -0,0 +1,18 @@
#include "processlauncher.h"
#define LOG(x) qDebug() << "[ProcessLauncher]" << x
ProcessLauncher::ProcessLauncher(QObject *parent) : QObject(parent)
{
}
bool ProcessLauncher::launchProgram(const QString &program, const QStringList &arguments)
{
QString executablePath = QStandardPaths::findExecutable(program);
if(executablePath == "") {
LOG("[ProcessLauncher] Program " + program + "not found");
return false;
}
QProcess *externalProcess = new QProcess(this);
return externalProcess->startDetached(program, arguments);
}

22
src/processlauncher.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef PROCESSLAUNCHER_H
#define PROCESSLAUNCHER_H
#include <QObject>
#include <QProcess>
#include <QStandardPaths>
#include <QDebug>
class ProcessLauncher : public QObject
{
Q_OBJECT
public:
explicit ProcessLauncher(QObject *parent = nullptr);
Q_INVOKABLE bool launchProgram(const QString &program, const QStringList &arguments);
signals:
public slots:
};
#endif // PROCESSLAUNCHER_H

View file

@ -360,6 +360,29 @@ void TDLibWrapper::deleteMessages(const QString &chatId, const QVariantList mess
this->sendRequest(requestObject);
}
void TDLibWrapper::getMapThumbnailFile(const QString &chatId, const double &latitude, const double &longitude, const int &width, const int &height)
{
qDebug() << "[TDLibWrapper] getting Map Thumbnail File " << chatId;
QVariantMap location;
location.insert("latitude", latitude);
location.insert("longitude", longitude);
// ensure dimensions are in bounds (16 - 1024)
int boundsWidth = std::min(std::max(width, 16), 1024);
int boundsHeight = std::min(std::max(height, 16), 1024);
QVariantMap requestObject;
requestObject.insert("@type", "getMapThumbnailFile");
requestObject.insert("location", location);
requestObject.insert("zoom", 17); //13-20
requestObject.insert("width", boundsWidth);
requestObject.insert("height", boundsHeight);
requestObject.insert("scale", 1); // 1-3
requestObject.insert("chat_id", chatId);
this->sendRequest(requestObject);
}
QVariantMap TDLibWrapper::getUserInformation()
{
return this->userInformation;

View file

@ -99,6 +99,7 @@ public:
Q_INVOKABLE void setChatNotificationSettings(const QString &chatId, const QVariantMap &notificationSettings);
Q_INVOKABLE void editMessageText(const QString &chatId, const QString &messageId, const QString &message);
Q_INVOKABLE void deleteMessages(const QString &chatId, const QVariantList messageIds);
Q_INVOKABLE void getMapThumbnailFile(const QString &chatId, const double &latitude, const double &longitude, const int &width, const int &height);
signals:
void versionDetected(const QString &version);

View file

@ -289,6 +289,13 @@
<translation>Bitte geben Sie Ihr Passwort ein:</translation>
</message>
</context>
<context>
<name>LocationPreview</name>
<message>
<source>Install Pure Maps to inspect this location.</source>
<translation>Installieren Sie Pure Maps, um diesen Ort zu erkunden</translation>
</message>
</context>
<context>
<name>NotificationManager</name>
<message>

View file

@ -289,6 +289,13 @@
<translation>Por favor, introducir el código:</translation>
</message>
</context>
<context>
<name>LocationPreview</name>
<message>
<source>Install Pure Maps to inspect this location.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NotificationManager</name>
<message>

View file

@ -289,6 +289,13 @@
<translation>Kérlek add meg a jelszavad:</translation>
</message>
</context>
<context>
<name>LocationPreview</name>
<message>
<source>Install Pure Maps to inspect this location.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NotificationManager</name>
<message>

View file

@ -289,6 +289,13 @@
<translation>Wprowadź hasło:</translation>
</message>
</context>
<context>
<name>LocationPreview</name>
<message>
<source>Install Pure Maps to inspect this location.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NotificationManager</name>
<message>

View file

@ -289,6 +289,13 @@
<translation></translation>
</message>
</context>
<context>
<name>LocationPreview</name>
<message>
<source>Install Pure Maps to inspect this location.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NotificationManager</name>
<message>

View file

@ -289,6 +289,13 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>LocationPreview</name>
<message>
<source>Install Pure Maps to inspect this location.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NotificationManager</name>
<message>