mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-26 13:08:48 +03:00
Add "open in external program" action
This commit is contained in:
parent
049278bc35
commit
c569ab24bc
3 changed files with 39 additions and 8 deletions
|
@ -124,6 +124,12 @@ Page {
|
||||||
text: qsTr("Save as")
|
text: qsTr("Save as")
|
||||||
onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId)
|
onTriggered: TimelineManager.timeline.saveMedia(messageContextMenu.eventId)
|
||||||
}
|
}
|
||||||
|
MenuItem {
|
||||||
|
visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker
|
||||||
|
height: visible ? implicitHeight : 0
|
||||||
|
text: qsTr("Open in external program")
|
||||||
|
onTriggered: TimelineManager.timeline.openMedia(messageContextMenu.eventId)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
|
#include <QDesktopServices>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
@ -1073,6 +1074,14 @@ TimelineModel::addPendingMessage(mtx::events::collections::TimelineEvents event)
|
||||||
std::visit(SendMessageVisitor{this}, event);
|
std::visit(SendMessageVisitor{this}, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineModel::openMedia(QString eventId)
|
||||||
|
{
|
||||||
|
cacheMedia(eventId, [](QString filename) {
|
||||||
|
QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TimelineModel::saveMedia(QString eventId) const
|
TimelineModel::saveMedia(QString eventId) const
|
||||||
{
|
{
|
||||||
|
@ -1149,7 +1158,7 @@ TimelineModel::saveMedia(QString eventId) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimelineModel::cacheMedia(QString eventId)
|
TimelineModel::cacheMedia(QString eventId, std::function<void(const QString)> callback)
|
||||||
{
|
{
|
||||||
mtx::events::collections::TimelineEvents *event = events.get(eventId.toStdString(), "");
|
mtx::events::collections::TimelineEvents *event = events.get(eventId.toStdString(), "");
|
||||||
if (!event)
|
if (!event)
|
||||||
|
@ -1169,12 +1178,13 @@ TimelineModel::cacheMedia(QString eventId)
|
||||||
|
|
||||||
QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix();
|
QString suffix = QMimeDatabase().mimeTypeForName(mimeType).preferredSuffix();
|
||||||
|
|
||||||
const auto url = mxcUrl.toStdString();
|
const auto url = mxcUrl.toStdString();
|
||||||
|
const auto name = QString(mxcUrl).remove("mxc://");
|
||||||
QFileInfo filename(QString("%1/media_cache/%2.%3")
|
QFileInfo filename(QString("%1/media_cache/%2.%3")
|
||||||
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
|
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
|
||||||
.arg(QString(mxcUrl).remove("mxc://"))
|
.arg(name)
|
||||||
.arg(suffix));
|
.arg(suffix));
|
||||||
if (QDir::cleanPath(filename.path()) != filename.path()) {
|
if (QDir::cleanPath(name) != name) {
|
||||||
nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url);
|
nhlog::net()->warn("mxcUrl '{}' is not safe, not downloading file", url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1183,15 +1193,18 @@ TimelineModel::cacheMedia(QString eventId)
|
||||||
|
|
||||||
if (filename.isReadable()) {
|
if (filename.isReadable()) {
|
||||||
emit mediaCached(mxcUrl, filename.filePath());
|
emit mediaCached(mxcUrl, filename.filePath());
|
||||||
|
if (callback) {
|
||||||
|
callback(filename.filePath());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
http::client()->download(
|
http::client()->download(
|
||||||
url,
|
url,
|
||||||
[this, mxcUrl, filename, url, encryptionInfo](const std::string &data,
|
[this, callback, mxcUrl, filename, url, encryptionInfo](const std::string &data,
|
||||||
const std::string &,
|
const std::string &,
|
||||||
const std::string &,
|
const std::string &,
|
||||||
mtx::http::RequestErr err) {
|
mtx::http::RequestErr err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
nhlog::net()->warn("failed to retrieve image {}: {} {}",
|
nhlog::net()->warn("failed to retrieve image {}: {} {}",
|
||||||
url,
|
url,
|
||||||
|
@ -1213,6 +1226,10 @@ TimelineModel::cacheMedia(QString eventId)
|
||||||
|
|
||||||
file.write(QByteArray(temp.data(), (int)temp.size()));
|
file.write(QByteArray(temp.data(), (int)temp.size()));
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
callback(filename.filePath());
|
||||||
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
nhlog::ui()->warn("Error while saving file to: {}", e.what());
|
nhlog::ui()->warn("Error while saving file to: {}", e.what());
|
||||||
}
|
}
|
||||||
|
@ -1221,6 +1238,12 @@ TimelineModel::cacheMedia(QString eventId)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineModel::cacheMedia(QString eventId)
|
||||||
|
{
|
||||||
|
cacheMedia(eventId, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg)
|
TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -218,8 +218,10 @@ public:
|
||||||
Q_INVOKABLE void redactEvent(QString id);
|
Q_INVOKABLE void redactEvent(QString id);
|
||||||
Q_INVOKABLE int idToIndex(QString id) const;
|
Q_INVOKABLE int idToIndex(QString id) const;
|
||||||
Q_INVOKABLE QString indexToId(int index) const;
|
Q_INVOKABLE QString indexToId(int index) const;
|
||||||
|
Q_INVOKABLE void openMedia(QString eventId);
|
||||||
Q_INVOKABLE void cacheMedia(QString eventId);
|
Q_INVOKABLE void cacheMedia(QString eventId);
|
||||||
Q_INVOKABLE bool saveMedia(QString eventId) const;
|
Q_INVOKABLE bool saveMedia(QString eventId) const;
|
||||||
|
void cacheMedia(QString eventId, std::function<void(const QString filename)> callback);
|
||||||
|
|
||||||
std::vector<::Reaction> reactions(const std::string &event_id)
|
std::vector<::Reaction> reactions(const std::string &event_id)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue