diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro
index c56af5b..1986a63 100644
--- a/harbour-fernschreiber.pro
+++ b/harbour-fernschreiber.pro
@@ -110,6 +110,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/messageContent/WebPagePreview.qml \
qml/js/debug.js \
qml/js/functions.js \
+ qml/pages/ActiveSessionsPage.qml \
qml/pages/ChatInformationPage.qml \
qml/pages/ChatPage.qml \
qml/pages/ChatSelectionPage.qml \
diff --git a/qml/js/functions.js b/qml/js/functions.js
index 762a301..8e52948 100644
--- a/qml/js/functions.js
+++ b/qml/js/functions.js
@@ -219,6 +219,10 @@ function getDateTimeTranslated(timestamp) {
return new Date(timestamp * 1000).toLocaleString();
}
+function getDateTimeTimepoint(timestamp) {
+ return Silica.Format.formatDate(new Date(timestamp * 1000), Silica.Formatter.TimepointRelative);
+}
+
function handleHtmlEntity(messageText, messageInsertions, originalString, replacementString) {
var nextIndex = -1;
while ((nextIndex = messageText.indexOf(originalString, nextIndex + 1)) > -1) {
diff --git a/qml/pages/AboutPage.qml b/qml/pages/AboutPage.qml
index 086cce2..d843d3f 100644
--- a/qml/pages/AboutPage.qml
+++ b/qml/pages/AboutPage.qml
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2020 Sebastian J. Wolf and other contributors
+ Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber.
@@ -232,7 +232,17 @@ Page {
}
Button {
- id: flickrTosButton
+ id: activeSessionsButton
+ text: qsTr("Active Sessions")
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("ActiveSessionsPage.qml"));
+ }
+ }
+
+ Button {
text: qsTr("Terms of Service")
anchors {
horizontalCenter: parent.horizontalCenter
@@ -243,7 +253,6 @@ Page {
}
Button {
- id: flickrPrivacyButton
text: qsTr("Privacy Policy")
anchors {
horizontalCenter: parent.horizontalCenter
diff --git a/qml/pages/ActiveSessionsPage.qml b/qml/pages/ActiveSessionsPage.qml
new file mode 100644
index 0000000..78ebd04
--- /dev/null
+++ b/qml/pages/ActiveSessionsPage.qml
@@ -0,0 +1,203 @@
+/*
+ Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
+
+ 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 .
+*/
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+import "../components"
+import "../js/twemoji.js" as Emoji
+import "../js/functions.js" as Functions
+
+Page {
+ id: activeSessionsPage
+ allowedOrientations: Orientation.All
+
+ property variant activeSessions;
+ property bool loaded : false;
+
+ Component.onCompleted: {
+ if (!activeSessions) {
+ tdLibWrapper.getActiveSessions();
+ } else {
+ activeSessionsPage.loaded = true;
+ }
+ }
+
+ Connections {
+ target: tdLibWrapper
+ onSessionsReceived: {
+ activeSessionsPage.activeSessions = sessions;
+ activeSessionsPage.loaded = true;
+ }
+ onOkReceived: {
+ if (request === "terminateSession") {
+ appNotification.show(qsTr("Session was terminated"));
+ activeSessionsPage.loaded = false;
+ tdLibWrapper.getActiveSessions();
+ }
+ }
+ }
+
+ SilicaFlickable {
+ id: activeSessionsFlickable
+ anchors.fill: parent
+
+ Column {
+ anchors.fill: parent
+
+ PageHeader {
+ id: activeSessionsHeader
+ title: qsTr("Active Sessions")
+ }
+
+ SilicaListView {
+ id: activeSessionsListView
+ width: parent.width
+ height: parent.height - activeSessionsHeader.height
+
+ clip: true
+
+ model: activeSessionsPage.activeSessions
+ delegate: ListItem {
+ id: activeSessionListItem
+ width: parent.width
+ contentHeight: activeSessionColumn.height + ( 2 * Theme.paddingMedium )
+
+ menu: ContextMenu {
+ hasContent: !modelData.is_current
+ MenuItem {
+ onClicked: {
+ var sessionId = modelData.id;
+ Remorse.itemAction(activeSessionListItem, qsTr("Terminating session"), function() { tdLibWrapper.terminateSession(sessionId); });
+ }
+ text: qsTr("Terminate Session")
+ }
+ }
+
+ Column {
+ id: activeSessionColumn
+ width: parent.width - ( 2 * Theme.horizontalPageMargin )
+ spacing: Theme.paddingSmall
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ Label {
+ width: parent.width
+ text: qsTr("This app")
+ font.pixelSize: Theme.fontSizeMedium
+ font.bold: true
+ visible: modelData.is_current
+ color: Theme.highlightColor
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ Label {
+ width: parent.width
+ text: modelData.application_name + " " + modelData.application_version
+ font.pixelSize: Theme.fontSizeMedium
+ font.bold: true
+ color: Theme.primaryColor
+ maximumLineCount: 1
+ elide: Text.ElideRight
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ Label {
+ width: parent.width
+ text: modelData.device_model + ", " + (modelData.platform + " " + modelData.system_version).trim()
+ font.pixelSize: Theme.fontSizeSmall
+ color: Theme.primaryColor
+ maximumLineCount: 1
+ truncationMode: TruncationMode.Fade
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ Label {
+ width: parent.width
+ text: qsTr("IP address: %1, origin: %2").arg(modelData.ip).arg(modelData.country)
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.secondaryColor
+ maximumLineCount: 1
+ truncationMode: TruncationMode.Fade
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ Label {
+ width: parent.width
+ text: qsTr("Active since: %1, last online: %2").arg(Functions.getDateTimeTimepoint(modelData.log_in_date)).arg(Functions.getDateTimeElapsed(modelData.last_active_date))
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.primaryColor
+ maximumLineCount: 1
+ truncationMode: TruncationMode.Fade
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+ }
+
+ Separator {
+ id: separator
+ anchors {
+ bottom: parent.bottom
+ }
+
+ width: parent.width
+ color: Theme.primaryColor
+ horizontalAlignment: Qt.AlignHCenter
+ }
+
+ }
+
+ VerticalScrollDecorator {}
+ }
+ }
+
+ Column {
+
+ opacity: visible ? 1 : 0
+ Behavior on opacity { FadeAnimation {} }
+ visible: !activeSessionsPage.loaded
+ width: parent.width
+ height: loadingLabel.height + loadingBusyIndicator.height + Theme.paddingMedium
+
+ spacing: Theme.paddingMedium
+ anchors.verticalCenter: parent.verticalCenter
+
+ InfoLabel {
+ id: loadingLabel
+ text: qsTr("Getting active sessions...")
+ }
+
+ BusyIndicator {
+ id: loadingBusyIndicator
+ anchors.horizontalCenter: parent.horizontalCenter
+ running: !activeSessionsPage.loaded
+ size: BusyIndicatorSize.Large
+ }
+ }
+
+ }
+}
+
diff --git a/src/tdlibreceiver.cpp b/src/tdlibreceiver.cpp
index d75f84e..4dde2f8 100644
--- a/src/tdlibreceiver.cpp
+++ b/src/tdlibreceiver.cpp
@@ -143,6 +143,7 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
handlers.insert("userPrivacySettingRules", &TDLibReceiver::processUserPrivacySettingRules);
handlers.insert("updateUserPrivacySettingRules", &TDLibReceiver::processUpdateUserPrivacySettingRules);
handlers.insert("updateMessageInteractionInfo", &TDLibReceiver::processUpdateMessageInteractionInfo);
+ handlers.insert("sessions", &TDLibReceiver::processSessions);
}
void TDLibReceiver::setActive(bool active)
@@ -638,3 +639,9 @@ void TDLibReceiver::processUpdateMessageInteractionInfo(const QVariantMap &recei
LOG("Message interaction info updated" << chatId << messageId);
emit messageInteractionInfoUpdated(chatId, messageId, receivedInformation.value(INTERACTION_INFO).toMap());
}
+
+void TDLibReceiver::processSessions(const QVariantMap &receivedInformation)
+{
+ QVariantList sessions = receivedInformation.value("sessions").toList();
+ emit sessionsReceived(sessions);
+}
diff --git a/src/tdlibreceiver.h b/src/tdlibreceiver.h
index 326499b..da090cf 100644
--- a/src/tdlibreceiver.h
+++ b/src/tdlibreceiver.h
@@ -99,6 +99,7 @@ signals:
void userPrivacySettingRulesUpdated(const QVariantMap &updatedRules);
void messageInteractionInfoUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &updatedInfo);
void okReceived(const QString &request);
+ void sessionsReceived(const QVariantList &sessions);
private:
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
@@ -171,6 +172,7 @@ private:
void processUserPrivacySettingRules(const QVariantMap &receivedInformation);
void processUpdateUserPrivacySettingRules(const QVariantMap &receivedInformation);
void processUpdateMessageInteractionInfo(const QVariantMap &receivedInformation);
+ void processSessions(const QVariantMap &receivedInformation);
};
#endif // TDLIBRECEIVER_H
diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp
index 1814e6a..09c3600 100644
--- a/src/tdlibwrapper.cpp
+++ b/src/tdlibwrapper.cpp
@@ -162,6 +162,7 @@ void TDLibWrapper::initializeTDLibReciever() {
connect(this->tdLibReceiver, SIGNAL(userPrivacySettingRulesUpdated(QVariantMap)), this, SLOT(handleUpdatedUserPrivacySettingRules(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(messageInteractionInfoUpdated(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageInteractionInfoUpdated(qlonglong, qlonglong, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(okReceived(QString)), this, SIGNAL(okReceived(QString)));
+ connect(this->tdLibReceiver, SIGNAL(sessionsReceived(QVariantList)), this, SIGNAL(sessionsReceived(QVariantList)));
this->tdLibReceiver->start();
}
@@ -1339,6 +1340,24 @@ void TDLibWrapper::changeStickerSet(const QString &stickerSetId, bool isInstalle
this->sendRequest(requestObject);
}
+void TDLibWrapper::getActiveSessions()
+{
+ LOG("Get active sessions");
+ QVariantMap requestObject;
+ requestObject.insert(_TYPE, "getActiveSessions");
+ this->sendRequest(requestObject);
+}
+
+void TDLibWrapper::terminateSession(const QString &sessionId)
+{
+ LOG("Terminate session" << sessionId);
+ QVariantMap requestObject;
+ requestObject.insert(_TYPE, "terminateSession");
+ requestObject.insert(_EXTRA, "terminateSession");
+ requestObject.insert("session_id", sessionId);
+ this->sendRequest(requestObject);
+}
+
void TDLibWrapper::searchEmoji(const QString &queryString)
{
LOG("Searching emoji" << queryString);
diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h
index 7cd4664..b69c7ec 100644
--- a/src/tdlibwrapper.h
+++ b/src/tdlibwrapper.h
@@ -222,6 +222,8 @@ public:
Q_INVOKABLE void setProfilePhoto(const QString &filePath);
Q_INVOKABLE void deleteProfilePhoto(const QString &profilePhotoId);
Q_INVOKABLE void changeStickerSet(const QString &stickerSetId, bool isInstalled);
+ Q_INVOKABLE void getActiveSessions();
+ Q_INVOKABLE void terminateSession(const QString &sessionId);
// Others (candidates for extraction ;))
Q_INVOKABLE void searchEmoji(const QString &queryString);
@@ -300,6 +302,7 @@ signals:
void userPrivacySettingUpdated(UserPrivacySetting setting, UserPrivacySettingRule rule);
void messageInteractionInfoUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &updatedInfo);
void okReceived(const QString &request);
+ void sessionsReceived(const QVariantList &sessions);
public slots:
void handleVersionDetected(const QString &version);
diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts
index 39beb6b..bffbad9 100644
--- a/translations/harbour-fernschreiber-de.ts
+++ b/translations/harbour-fernschreiber-de.ts
@@ -91,6 +91,45 @@
Abgemeldet
+
+
+ Aktive Sitzungen
+
+
+
+ ActiveSessionsPage
+
+
+ Erhalte aktive Sitzungen...
+
+
+
+ Aktive Sitzungen
+
+
+
+ Sitzung wurde beendet
+
+
+
+ Sitzung beenden
+
+
+
+ Diese App
+
+
+
+ IP-Adresse: %1, Herkunft: %2
+
+
+
+ Aktiv seit: %1, zuletzt online: %2
+
+
+
+ Beende Sitzung
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-en.ts b/translations/harbour-fernschreiber-en.ts
index 25436de..0804573 100644
--- a/translations/harbour-fernschreiber-en.ts
+++ b/translations/harbour-fernschreiber-en.ts
@@ -91,6 +91,45 @@
Logged out
+
+
+ Active Sessions
+
+
+
+ ActiveSessionsPage
+
+
+ Getting active sessions...
+
+
+
+ Active Sessions
+
+
+
+ Session was terminated
+
+
+
+ Terminate Session
+
+
+
+ This app
+
+
+
+ IP address: %1, origin: %2
+
+
+
+ Active since: %1, last online: %2
+
+
+
+ Terminating session
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts
index 41416d8..9aa015f 100644
--- a/translations/harbour-fernschreiber-es.ts
+++ b/translations/harbour-fernschreiber-es.ts
@@ -91,6 +91,45 @@
Desconectado
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts
index 22d88c6..0448443 100644
--- a/translations/harbour-fernschreiber-fi.ts
+++ b/translations/harbour-fernschreiber-fi.ts
@@ -91,6 +91,45 @@
Kirjattu ulos
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-hu.ts b/translations/harbour-fernschreiber-hu.ts
index 07c781e..38bbb94 100644
--- a/translations/harbour-fernschreiber-hu.ts
+++ b/translations/harbour-fernschreiber-hu.ts
@@ -91,6 +91,45 @@
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts
index 4df7d4e..7f55a66 100644
--- a/translations/harbour-fernschreiber-it.ts
+++ b/translations/harbour-fernschreiber-it.ts
@@ -91,6 +91,45 @@
Disconnesso
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts
index 6124a01..5737e95 100644
--- a/translations/harbour-fernschreiber-pl.ts
+++ b/translations/harbour-fernschreiber-pl.ts
@@ -91,6 +91,45 @@
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts
index 35c3a3d..bedfed8 100644
--- a/translations/harbour-fernschreiber-ru.ts
+++ b/translations/harbour-fernschreiber-ru.ts
@@ -91,6 +91,45 @@
Выход из аккаунта
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-sk.ts b/translations/harbour-fernschreiber-sk.ts
index cfd935f..008dae9 100644
--- a/translations/harbour-fernschreiber-sk.ts
+++ b/translations/harbour-fernschreiber-sk.ts
@@ -91,6 +91,45 @@
Odhlásený
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-sv.ts b/translations/harbour-fernschreiber-sv.ts
index 3976b92..4584c0c 100644
--- a/translations/harbour-fernschreiber-sv.ts
+++ b/translations/harbour-fernschreiber-sv.ts
@@ -91,6 +91,45 @@
Utloggad
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber-zh_CN.ts b/translations/harbour-fernschreiber-zh_CN.ts
index 3a496fd..8df1f65 100644
--- a/translations/harbour-fernschreiber-zh_CN.ts
+++ b/translations/harbour-fernschreiber-zh_CN.ts
@@ -91,6 +91,45 @@
已登出
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator
diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts
index 178e268..0c16ca6 100644
--- a/translations/harbour-fernschreiber.ts
+++ b/translations/harbour-fernschreiber.ts
@@ -91,6 +91,45 @@
+
+
+
+
+
+
+ ActiveSessionsPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BackgroundProgressIndicator