From 9e8038b1b6a980188307ef1b2bc2a7c2118bb3a5 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 8 Nov 2020 06:00:13 +0200 Subject: [PATCH] Added TDLibFile and optimized ProfileThumbnail Profile images seem to be loading significantly faster after moving file fetching logic to the native code and removing the artificial delay. TDLibFile is a generic object which can hopefully be used elsewhere as an efficient replacement for JavaScript. --- harbour-fernschreiber.pro | 2 + qml/components/ChatListViewItem.qml | 2 - qml/components/ProfileThumbnail.qml | 71 +----- qml/pages/OverviewPage.qml | 1 - src/harbour-fernschreiber.cpp | 8 +- src/stickermanager.cpp | 2 +- src/tdlibfile.cpp | 367 ++++++++++++++++++++++++++++ src/tdlibfile.h | 159 ++++++++++++ src/tdlibwrapper.cpp | 2 +- src/tdlibwrapper.h | 2 +- 10 files changed, 549 insertions(+), 67 deletions(-) create mode 100644 src/tdlibfile.cpp create mode 100644 src/tdlibfile.h diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro index 3e22d53..1a6994a 100644 --- a/harbour-fernschreiber.pro +++ b/harbour-fernschreiber.pro @@ -29,6 +29,7 @@ SOURCES += src/harbour-fernschreiber.cpp \ src/notificationmanager.cpp \ src/processlauncher.cpp \ src/stickermanager.cpp \ + src/tdlibfile.cpp \ src/tdlibreceiver.cpp \ src/tdlibwrapper.cpp @@ -141,6 +142,7 @@ HEADERS += \ src/notificationmanager.h \ src/processlauncher.h \ src/stickermanager.h \ + src/tdlibfile.h \ src/tdlibreceiver.h \ src/tdlibsecrets.h \ src/tdlibwrapper.h diff --git a/qml/components/ChatListViewItem.qml b/qml/components/ChatListViewItem.qml index aed1bf5..7b8838c 100644 --- a/qml/components/ChatListViewItem.qml +++ b/qml/components/ChatListViewItem.qml @@ -7,9 +7,7 @@ import "../js/functions.js" as Functions PhotoTextsListItem { id: listItem pictureThumbnail { -// forceElementUpdate: overviewPage.chatListCreated photoData: photo_small -// replacementStringHint: primaryText.text } property int ownUserId property url emojiBase: "../js/emoji/" diff --git a/qml/components/ProfileThumbnail.qml b/qml/components/ProfileThumbnail.qml index 34383e6..38e6ba1 100644 --- a/qml/components/ProfileThumbnail.qml +++ b/qml/components/ProfileThumbnail.qml @@ -19,14 +19,14 @@ import QtQuick 2.6 import QtGraphicalEffects 1.0 import Sailfish.Silica 1.0 +import WerkWolf.Fernschreiber 1.0 Item { id: profileThumbnail - property var photoData; + property alias photoData: file.fileInformation property string replacementStringHint: "X" - property bool forceElementUpdate: false property int radius: width / 2 property int imageStatus: -1 @@ -46,52 +46,10 @@ Item { return replacementStringHint; } - function updatePicture() { - profileImageLoader.active = false; - replacementThumbnailItem.visible = true; - if (typeof photoData === "object") { - if (photoData.local.is_downloading_completed) { - profileImageLoader.active = true; - replacementThumbnailItem.visible = false; - } else { - tdLibWrapper.downloadFile(photoData.id); - } - } - } - - Timer { - id: updatePictureTimer - interval: 500 - running: false - repeat: false - onTriggered: { - updatePicture(); - } - } - - Component.onCompleted: { - updatePictureTimer.start(); - } - - onPhotoDataChanged: { - if (profileThumbnail.forceElementUpdate) { - updatePictureTimer.stop(); - updatePictureTimer.start(); - } - } - - Connections { - target: tdLibWrapper - onFileUpdated: { - if (typeof photoData !== "undefined" && fileId === photoData.id) { - console.log("File updated, completed? " + fileInformation.local.is_downloading_completed); - if (fileInformation.local.is_downloading_completed) { - photoData = fileInformation; - profileImageLoader.active = true; - replacementThumbnailItem.visible = false; - } - } - } + TDLibFile { + id: file + tdlib: tdLibWrapper + autoLoad: true } Component { @@ -99,13 +57,16 @@ Item { Item { width: parent.width height: width + visible: opacity > 0 + opacity: singleImage.status === Image.Ready ? 1 : 0 + Behavior on opacity { FadeAnimation {} } Image { id: singleImage width: parent.width - Theme.paddingSmall height: parent.height - Theme.paddingSmall anchors.centerIn: parent - source: profileThumbnail.photoData.local.path + source: file.path fillMode: Image.PreserveAspectCrop autoTransform: true asynchronous: true @@ -126,30 +87,25 @@ Item { } OpacityMask { - id: maskedThumbnail source: singleImage maskSource: profileThumbnailMask anchors.fill: singleImage - visible: singleImage.status === Image.Ready ? true : false - opacity: singleImage.status === Image.Ready ? 1 : 0 - Behavior on opacity { NumberAnimation {} } } } } Loader { id: profileImageLoader - active: false + active: file.isDownloadingCompleted asynchronous: true width: parent.width sourceComponent: profileImageComponent } Item { - id: replacementThumbnailItem width: parent.width - Theme.paddingSmall height: parent.height - Theme.paddingSmall - visible: true + visible: !profileImageLoader.item || !profileImageLoader.item.visible Rectangle { id: replacementThumbnailBackground @@ -160,14 +116,11 @@ Item { } Text { - id: replacementThumbnailText anchors.centerIn: replacementThumbnailBackground text: getReplacementString() color: Theme.primaryColor font.bold: true font.pixelSize: ( profileThumbnail.height >= Theme.itemSizeSmall ) ? Theme.fontSizeLarge : Theme.fontSizeMedium } - } - } diff --git a/qml/pages/OverviewPage.qml b/qml/pages/OverviewPage.qml index f9d181a..c749c7a 100644 --- a/qml/pages/OverviewPage.qml +++ b/qml/pages/OverviewPage.qml @@ -227,7 +227,6 @@ Page { model: chatListModel delegate: ChatListViewItem { - pictureThumbnail.forceElementUpdate: overviewPage.chatListCreated ownUserId: overviewPage.ownUserId onClicked: { diff --git a/src/harbour-fernschreiber.cpp b/src/harbour-fernschreiber.cpp index a17c420..09bdbee 100644 --- a/src/harbour-fernschreiber.cpp +++ b/src/harbour-fernschreiber.cpp @@ -30,6 +30,7 @@ #include #include "appsettings.h" +#include "tdlibfile.h" #include "tdlibwrapper.h" #include "chatlistmodel.h" #include "chatmodel.h" @@ -45,13 +46,16 @@ int main(int argc, char *argv[]) QQmlContext *context = view.data()->rootContext(); + const char *uri = "WerkWolf.Fernschreiber"; + qmlRegisterType(uri, 1, 0, "TDLibFile"); + AppSettings *appSettings = new AppSettings(view.data()); context->setContextProperty("appSettings", appSettings); - qmlRegisterUncreatableType("WerkWolf.Fernschreiber", 1, 0, "AppSettings", QString()); + qmlRegisterUncreatableType(uri, 1, 0, "AppSettings", QString()); TDLibWrapper *tdLibWrapper = new TDLibWrapper(view.data()); context->setContextProperty("tdLibWrapper", tdLibWrapper); - qmlRegisterUncreatableType("WerkWolf.Fernschreiber", 1, 0, "TelegramAPI", QString()); + qmlRegisterUncreatableType(uri, 1, 0, "TelegramAPI", QString()); DBusAdaptor *dBusAdaptor = tdLibWrapper->getDBusAdaptor(); context->setContextProperty("dBusAdaptor", dBusAdaptor); diff --git a/src/stickermanager.cpp b/src/stickermanager.cpp index 92b63f6..fc6b593 100644 --- a/src/stickermanager.cpp +++ b/src/stickermanager.cpp @@ -124,7 +124,7 @@ void StickerManager::handleStickerSetReceived(const QVariantMap &stickerSet) QVariantMap thumbnailFile = singleSticker.value("thumbnail").toMap().value("photo").toMap(); QVariantMap thumbnailLocalFile = thumbnailFile.value("local").toMap(); if (!thumbnailLocalFile.value("is_downloading_completed").toBool()) { - tdLibWrapper->downloadFile(thumbnailFile.value("id").toString()); + tdLibWrapper->downloadFile(thumbnailFile.value("id").toInt()); this->reloadNeeded = true; } } diff --git a/src/tdlibfile.cpp b/src/tdlibfile.cpp new file mode 100644 index 0000000..7e98979 --- /dev/null +++ b/src/tdlibfile.cpp @@ -0,0 +1,367 @@ +/* + Copyright (C) 2020 Slava Monich at al. + + 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 . +*/ + +#include "tdlibfile.h" +#include + +#define LOG(x) qDebug() << "[TDLibFile]" << x + +namespace { + const QString ID("id"); + const QString EXPECTED_SIZE("expected_size"); + const QString SIZE("size"); + const QString LOCAL("local"); + const QString CAN_BE_DELETED("can_be_deleted"); + const QString CAN_BE_DOWNLOADED("can_be_downloaded"); + const QString DOWNLOAD_OFFSET("download_offset"); + const QString DOWNLOADED_PREFIX_SIZE("downloaded_prefix_size"); + const QString DOWNLOADED_SIZE("downloaded_size"); + const QString IS_DOWNLODING_ACTIVE("is_downloading_active"); + const QString IS_DOWNLODING_COMPELETED("is_downloading_completed"); + const QString PATH("path"); + const QString REMOTE("remote"); + const QString IS_UPLOADING_ACTIVE("is_uploading_active"); + const QString IS_UPLOADING_COMPLETED("is_uploading_completed"); + const QString UNIQUE_ID("unique_id"); + const QString UPLOADED_SIZE("uploaded_size"); + + const QString _TYPE("@type"); + const QString TYPE_FILE("file"); + const QString TYPE_LOCAL_FILE("localFile"); + const QString TYPE_REMOTE_FILE("remoteFile"); +} + +// s(SignalName,signalName) +#define QUEUED_SIGNALS(s) \ + s(TdLib,tdlib) \ + s(FileInfo,fileInfo) \ + s(AutoLoad,autoLoad) \ + s(Id,id) \ + s(ExpectedSize,expectedSize) \ + s(Size,size) \ + s(Path,path) \ + s(DownloadOffset,downloadOffset) \ + s(DownloadedPrefixSize,downloadedPrefixSize) \ + s(DownloadedSize,downloadedSize) \ + s(CanBeDeleted,canBeDeleted) \ + s(CanBeDownloaded,canBeDownloaded) \ + s(DownloadingActive,downloadingActive) \ + s(DownloadingCompleted,downloadingCompleted) \ + s(RemoteId,remoteId) \ + s(UniqueId,uniqueId) \ + s(UploadedSize,uploadedSize) \ + s(UploadingActive,uploadingActive) \ + s(UploadingCompleted,uploadingCompleted) + +typedef void (TDLibFile::*TDLibFileSignalEmitter)(); +enum TDLibFileSignal { + #define SIGNAL_ENUM_(Name,name) Signal##Name##Changed, + QUEUED_SIGNALS(SIGNAL_ENUM_) + #undef SIGNAL_ENUM_ + SignalCount +}; + +TDLibFile::TDLibFile() +{ + init(); +} + +TDLibFile::TDLibFile(TDLibWrapper *tdlib) +{ + init(); + updateTDLibWrapper(tdlib); + // Reset queued signals + firstQueuedSignal = SignalCount; + queuedSignals = 0; +} + +TDLibFile::TDLibFile(TDLibWrapper *tdlib, const QVariantMap &fileInfo) +{ + init(); + updateTDLibWrapper(tdlib); + updateFileInfo(fileInfo); + // Reset queued signals + firstQueuedSignal = SignalCount; + queuedSignals = 0; +} + +void TDLibFile::init() +{ + tdLibWrapper = Q_NULLPTR; + queuedSignals = 0; + firstQueuedSignal = SignalCount; + autoLoad = false; + id = 0; + expected_size = 0; + size = 0; + download_offset = 0; + downloaded_prefix_size = 0; + downloaded_size = 0; + can_be_deleted = false; + can_be_downloaded = false; + is_downloading_active = false; + is_downloading_completed = false; + uploaded_size = 0; + is_uploading_active = false; + is_uploading_completed = false; +} + +void TDLibFile::queueSignal(uint signal) +{ + const uint signalBit = 1 << signal; + if (queuedSignals) { + queuedSignals |= signalBit; + if (firstQueuedSignal > signal) { + firstQueuedSignal = signal; + } + } else { + queuedSignals = signalBit; + firstQueuedSignal = signal; + } +} + +void TDLibFile::emitQueuedSignals() +{ + static const TDLibFileSignalEmitter emitSignal[] = { + #define SIGNAL_EMITTER_(Name,name) &TDLibFile::name##Changed, + QUEUED_SIGNALS(SIGNAL_EMITTER_) + #undef SIGNAL_EMITTER_ + }; + if (queuedSignals) { + // Reset first queued signal before emitting the signals. + // Signal handlers may emit new signals. + uint i = firstQueuedSignal; + firstQueuedSignal = SignalCount; + for (; i < SignalCount && queuedSignals; i++) { + const uint signalBit = 1 << i; + if (queuedSignals & signalBit) { + queuedSignals &= ~signalBit; + emit (this->*(emitSignal[i]))(); + } + } + } +} + +void TDLibFile::setTDLibWrapper(QObject* obj) +{ + updateTDLibWrapper(qobject_cast(obj)); + emitQueuedSignals(); +} + +void TDLibFile::updateTDLibWrapper(TDLibWrapper* tdlib) +{ + if (tdlib != tdLibWrapper) { + if (tdLibWrapper) { + tdLibWrapper->disconnect(this); + } + tdLibWrapper = tdlib; + if (tdlib) { + connect(tdlib, SIGNAL(fileUpdated(int,QVariantMap)), SLOT(handleFileUpdated(int,QVariantMap))); + if (autoLoad) { + load(); + } + } + queueSignal(SignalTdLibChanged); + } +} + +void TDLibFile::setAutoLoad(bool enableAutoLoad) +{ + if (autoLoad != enableAutoLoad) { + autoLoad = enableAutoLoad; + queueSignal(SignalAutoLoadChanged); + if (autoLoad) { + load(); + } + emitQueuedSignals(); + } +} + +bool TDLibFile::load() +{ + if (id && tdLibWrapper && !is_downloading_active && !is_downloading_completed && can_be_downloaded) { + tdLibWrapper->downloadFile(id); + return true; + } + return false; +} + +void TDLibFile::setFileInfo(const QVariantMap &fileInfo) +{ + updateFileInfo(fileInfo); + if (autoLoad) { + load(); + } + emitQueuedSignals(); +} + +void TDLibFile::handleFileUpdated(int fileId, const QVariantMap &fileInfo) +{ + if (id == fileId) { + LOG("File" << fileId << "updated"); + setFileInfo(fileInfo); + emitQueuedSignals(); + } +} + +/* +{ + "@type": "file", + "expected_size": 0, + "id": 12, + "size": 0, + "local": { + "@type": "localFile", + "can_be_deleted": false, + "can_be_downloaded": true, + "download_offset": 0, + "downloaded_prefix_size": 0, + "downloaded_size": 0, + "is_downloading_active": true, + "is_downloading_completed": false, + "path": "" + }, + "remote": { + "@type": "remoteFile", + "id": "AQADAgATXYBrly4AAwIAA2E2itkW____9UdPDiSysLQ4fwIAARgE", + "is_uploading_active": false, + "is_uploading_completed": true, + "unique_id": "AQADXYBrly4AAzh_AgAB", + "uploaded_size": 0 + } +} +*/ + +void TDLibFile::updateFileInfo(const QVariantMap &file) +{ + if (file.value(_TYPE).toString() == TYPE_FILE) { + QString s; + qlonglong ll; + bool b, fileChanged = false; + int i = file.value(ID).toInt(); + if (id != i) { + id = i; + fileChanged = true; + queueSignal(SignalIdChanged); + } + ll = file.value(EXPECTED_SIZE).toLongLong(); + if (expected_size != ll) { + expected_size = ll; + fileChanged = true; + queueSignal(SignalExpectedSizeChanged); + } + ll = file.value(SIZE).toLongLong(); + if (size != ll) { + size = ll; + fileChanged = true; + queueSignal(SignalSizeChanged); + } + + const QVariantMap local(file.value(LOCAL).toMap()); + if (local.value(_TYPE).toString() == TYPE_LOCAL_FILE) { + ll = local.value(DOWNLOAD_OFFSET).toLongLong(); + if (download_offset != ll) { + download_offset = ll; + fileChanged = true; + queueSignal(SignalDownloadOffsetChanged); + } + ll = local.value(DOWNLOADED_PREFIX_SIZE).toLongLong(); + if (downloaded_prefix_size != ll) { + downloaded_prefix_size = ll; + fileChanged = true; + queueSignal(SignalDownloadedPrefixSizeChanged); + } + ll = local.value(DOWNLOADED_SIZE).toLongLong(); + if (downloaded_size != ll) { + downloaded_size = ll; + fileChanged = true; + queueSignal(SignalDownloadedSizeChanged); + } + b = local.value(CAN_BE_DELETED).toBool(); + if (can_be_deleted != b) { + can_be_deleted = b; + fileChanged = true; + queueSignal(SignalCanBeDeletedChanged); + } + b = local.value(CAN_BE_DOWNLOADED).toBool(); + if (can_be_downloaded != b) { + can_be_downloaded = b; + fileChanged = true; + queueSignal(SignalCanBeDownloadedChanged); + } + b = local.value(IS_DOWNLODING_ACTIVE).toBool(); + if (is_downloading_active != b) { + is_downloading_active = b; + fileChanged = true; + queueSignal(SignalDownloadingActiveChanged); + } + b = local.value(IS_DOWNLODING_COMPELETED).toBool(); + if (is_downloading_completed != b) { + is_downloading_completed = b; + fileChanged = true; + queueSignal(SignalDownloadingCompletedChanged); + } + s = local.value(PATH).toString(); + if (path != s) { + path = s; + fileChanged = true; + queueSignal(SignalPathChanged); + } + } + + const QVariantMap remote(file.value(REMOTE).toMap()); + if (remote.value(_TYPE).toString() == TYPE_REMOTE_FILE) { + ll = file.value(UPLOADED_SIZE).toLongLong(); + if (uploaded_size != ll) { + uploaded_size = ll; + fileChanged = true; + queueSignal(SignalUploadedSizeChanged); + } + b = file.value(IS_UPLOADING_ACTIVE).toBool(); + if (is_uploading_active != b) { + is_uploading_active = b; + fileChanged = true; + queueSignal(SignalUploadingActiveChanged); + } + b = file.value(IS_UPLOADING_COMPLETED).toBool(); + if (is_uploading_completed != b) { + is_uploading_completed = b; + fileChanged = true; + queueSignal(SignalUploadingCompletedChanged); + } + s = local.value(ID).toString(); + if (remote_id != s) { + remote_id = s; + fileChanged = true; + queueSignal(SignalRemoteIdChanged); + } + s = local.value(UNIQUE_ID).toString(); + if (unique_id != s) { + unique_id = s; + fileChanged = true; + queueSignal(SignalUniqueIdChanged); + } + } + + if (fileChanged) { + infoMap = file; + queueSignal(SignalFileInfoChanged); + } + } +} diff --git a/src/tdlibfile.h b/src/tdlibfile.h new file mode 100644 index 0000000..9a16af4 --- /dev/null +++ b/src/tdlibfile.h @@ -0,0 +1,159 @@ +/* + Copyright (C) 2020 Slava Monich at al. + + 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 . +*/ + +#ifndef TDLIBFILE_H +#define TDLIBFILE_H + +#include "tdlibwrapper.h" + +class TDLibFile : public QObject +{ + Q_OBJECT + Q_PROPERTY(QObject* tdlib READ getTDLibWrapper WRITE setTDLibWrapper NOTIFY tdlibChanged) + Q_PROPERTY(QVariantMap fileInformation READ getFileInfo WRITE setFileInfo NOTIFY fileInfoChanged) + Q_PROPERTY(bool autoLoad READ isAutoLoad WRITE setAutoLoad NOTIFY autoLoadChanged) + Q_PROPERTY(int fileId READ getId NOTIFY idChanged) + Q_PROPERTY(qlonglong expectedSize READ getExpectedSize NOTIFY expectedSizeChanged) + Q_PROPERTY(qlonglong size READ getSize NOTIFY sizeChanged) + Q_PROPERTY(QString path READ getPath NOTIFY pathChanged) + Q_PROPERTY(qlonglong downloadOffset READ getDownloadOffset NOTIFY downloadOffsetChanged) + Q_PROPERTY(qlonglong downloadedPrefixSize READ getDownloadedPrefixSize NOTIFY downloadedPrefixSizeChanged) + Q_PROPERTY(qlonglong downloadedSize READ getDownloadedSize NOTIFY downloadedSizeChanged) + Q_PROPERTY(bool canBeDeleted READ canBeDeleted NOTIFY canBeDeletedChanged) + Q_PROPERTY(bool canBeDownloaded READ canBeDownloaded NOTIFY canBeDownloadedChanged) + Q_PROPERTY(bool isDownloadingActive READ isDownloadingActive NOTIFY downloadingActiveChanged) + Q_PROPERTY(bool isDownloadingCompleted READ isDownloadingCompleted NOTIFY downloadingCompletedChanged) + Q_PROPERTY(QString remoteId READ getRemoteId NOTIFY remoteIdChanged) + Q_PROPERTY(QString uniqueId READ getUniqueId NOTIFY uniqueIdChanged) + Q_PROPERTY(qlonglong uploadedSize READ getUploadedSize NOTIFY uploadedSizeChanged) + Q_PROPERTY(bool isUploadingActive READ isUploadingActive NOTIFY uploadingActiveChanged) + Q_PROPERTY(bool isUploadingCompleted READ isUploadingCompleted NOTIFY uploadingCompletedChanged) + +public: + TDLibFile(); + TDLibFile(TDLibWrapper *tdlib); + TDLibFile(TDLibWrapper *tdlib, const QVariantMap &fileInfo); + + TDLibWrapper *getTDLibWrapper() const; + void setTDLibWrapper(QObject* obj); + + const QVariantMap &getFileInfo() const; + void setFileInfo(const QVariantMap &fileInfo); + + bool isAutoLoad() const; + void setAutoLoad(bool autoLoad); + + int getId() const; + qlonglong getExpectedSize() const; + qlonglong getSize() const; + const QString &getPath() const; + qlonglong getDownloadOffset() const; + qlonglong getDownloadedPrefixSize() const; + qlonglong getDownloadedSize() const; + bool canBeDeleted() const; + bool canBeDownloaded() const; + bool isDownloadingActive() const; + bool isDownloadingCompleted() const; + const QString &getRemoteId() const; + const QString &getUniqueId() const; + qlonglong getUploadedSize() const; + bool isUploadingActive() const; + bool isUploadingCompleted() const; + + Q_INVOKABLE bool load(); + +signals: + void tdlibChanged(); + void fileInfoChanged(); + void autoLoadChanged(); + void idChanged(); + void expectedSizeChanged(); + void sizeChanged(); + void pathChanged(); + void downloadOffsetChanged(); + void downloadedPrefixSizeChanged(); + void downloadedSizeChanged(); + void canBeDeletedChanged(); + void canBeDownloadedChanged(); + void downloadingActiveChanged(); + void downloadingCompletedChanged(); + void remoteIdChanged(); + void uniqueIdChanged(); + void uploadedSizeChanged(); + void uploadingActiveChanged(); + void uploadingCompletedChanged(); + +private slots: + void handleFileUpdated(int fileId, const QVariantMap &fileInfo); + +private: + void init(); + void updateTDLibWrapper(TDLibWrapper* tdlib); + void updateFileInfo(const QVariantMap &fileInfo); + void queueSignal(uint signal); + void emitQueuedSignals(); + +private: + TDLibWrapper *tdLibWrapper; + uint queuedSignals; + uint firstQueuedSignal; + bool autoLoad; + // file + QVariantMap infoMap; + int id; + qlonglong expected_size; + qlonglong size; + // localFile + QString path; + qlonglong download_offset; + qlonglong downloaded_prefix_size; + qlonglong downloaded_size; + bool can_be_deleted; + bool can_be_downloaded; + bool is_downloading_active; + bool is_downloading_completed; + // remoteFile + QString remote_id; + QString unique_id; + qlonglong uploaded_size; + bool is_uploading_active; + bool is_uploading_completed; +}; + +inline TDLibWrapper *TDLibFile::getTDLibWrapper() const { return tdLibWrapper; } +inline const QVariantMap &TDLibFile::getFileInfo() const { return infoMap; } +inline bool TDLibFile::isAutoLoad() const { return autoLoad; } +inline int TDLibFile::getId() const { return id; } +inline qlonglong TDLibFile::getExpectedSize() const { return expected_size; } +inline qlonglong TDLibFile::getSize() const { return size; } +inline const QString &TDLibFile::getPath() const { return path; } +inline qlonglong TDLibFile::getDownloadOffset() const { return download_offset; } +inline qlonglong TDLibFile::getDownloadedPrefixSize() const { return downloaded_prefix_size; } +inline qlonglong TDLibFile::getDownloadedSize() const { return downloaded_size; } +inline bool TDLibFile::canBeDeleted() const { return can_be_deleted; } +inline bool TDLibFile::canBeDownloaded() const { return can_be_downloaded; } +inline bool TDLibFile::isDownloadingActive() const { return is_downloading_active; } +inline bool TDLibFile::isDownloadingCompleted() const { return is_downloading_completed; } +inline const QString &TDLibFile::getRemoteId() const { return remote_id; } +inline const QString &TDLibFile::getUniqueId() const { return unique_id; } +inline qlonglong TDLibFile::getUploadedSize() const { return uploaded_size; } +inline bool TDLibFile::isUploadingActive() const { return is_uploading_active; } +inline bool TDLibFile::isUploadingCompleted() const { return is_uploading_completed; } + +#endif // TDLIBFILE_H diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp index 5932bcc..0c99272 100644 --- a/src/tdlibwrapper.cpp +++ b/src/tdlibwrapper.cpp @@ -206,7 +206,7 @@ void TDLibWrapper::getChats() this->sendRequest(requestObject); } -void TDLibWrapper::downloadFile(const QString &fileId) +void TDLibWrapper::downloadFile(int fileId) { LOG("Downloading file " << fileId); QVariantMap requestObject; diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h index e0bca30..93d1702 100644 --- a/src/tdlibwrapper.h +++ b/src/tdlibwrapper.h @@ -112,7 +112,7 @@ public: Q_INVOKABLE void setAuthenticationPassword(const QString &authenticationPassword); Q_INVOKABLE void registerUser(const QString &firstName, const QString &lastName); Q_INVOKABLE void getChats(); - Q_INVOKABLE void downloadFile(const QString &fileId); + Q_INVOKABLE void downloadFile(int fileId); Q_INVOKABLE void openChat(const QString &chatId); Q_INVOKABLE void closeChat(const QString &chatId); Q_INVOKABLE void joinChat(const QString &chatId);