1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-09-02 05:03:38 +02:00

chatview: add toast on file saved

Change-Id: Ie3ab68213f9337d5124eda4f989fb23c0e084d64
GitLab: #1027
This commit is contained in:
Sébastien Blin 2023-04-07 14:14:54 -04:00
parent 4d8b006c34
commit 53374b7ded
9 changed files with 36 additions and 288 deletions

View file

@ -37,9 +37,7 @@ ContextMenuAutoLoader {
canTrigger: root.transferId !== ""
itemName: JamiStrings.saveFile
onClicked: {
MessagesAdapter.copyToDownloads(root.transferId, root.transferName);
}
onClicked: MessagesAdapter.copyToDownloads(root.transferId, root.transferName)
},
GeneralMenuItem {
id: openLocation

View file

@ -295,6 +295,7 @@ Item {
property string layoutSettings: qsTr("Layout settings")
property string tileScreenshot: qsTr("Take tile screenshot")
property string screenshotTaken: qsTr("Screenshot saved to %1")
property string fileSaved: qsTr("File saved to %1")
//advanced information
property string renderersInformation: qsTr("Renderers information")

View file

@ -1,110 +0,0 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt.labs.platform
import Qt5Compat.GraphicalEffects
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
import "../../settingsview/components"
Component {
id: root
Rectangle {
id: dataTransferRect
clip: true
width: (contentWidth - spacingLength) / numberElementsPerRow
height: width
color: "transparent"
ColumnLayout {
anchors.fill: parent
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
Text {
id: myText
text: TransferName
color: JamiTheme.textColor
elide: Text.ElideRight
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
}
Rectangle {
Layout.preferredHeight: parent.height - myText.height - JamiTheme.swarmDetailsPageDocumentsMargins
Layout.preferredWidth: parent.width
Layout.rightMargin: JamiTheme.swarmDetailsPageDocumentsMargins
Layout.bottomMargin: JamiTheme.swarmDetailsPageDocumentsMargins
color: "transparent"
Rectangle {
id: rectContent
anchors.fill: parent
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
color: "transparent"
border.color: themeColor
border.width: 2
radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
layer.enabled: true
ResponsiveImage {
id: paperClipImage
source: JamiResources.link_black_24dp_svg
width: parent.width / 2
height: parent.height / 2
anchors.centerIn: parent
color: JamiTheme.textColor
MouseArea {
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
onEntered: {
cursorShape = Qt.PointingHandCursor;
}
onClicked: function (mouse) {
if (mouse.button === Qt.RightButton) {
ctxMenu.x = mouse.x;
ctxMenu.y = mouse.y;
ctxMenu.openMenu();
} else {
Qt.openUrlExternally(new Url("file://" + Body));
}
}
}
SBSContextMenu {
id: ctxMenu
msgId: Id
location: Body
transferId: Id
transferName: TransferName
}
}
}
}
}
}
}

View file

@ -1,161 +0,0 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt.labs.platform
import Qt5Compat.GraphicalEffects
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
import "../../settingsview/components"
Component {
id: root
Rectangle {
id: localMediaRect
width: (flickableWidth - spacingLength) / numberElementsPerRow
height: width
color: "transparent"
ColumnLayout {
anchors.fill: parent
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
Text {
id: mediaName
text: TransferName
color: JamiTheme.textColor
elide: Text.ElideRight
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
}
Rectangle {
Layout.preferredHeight: parent.height - mediaName.height - JamiTheme.swarmDetailsPageDocumentsMargins
Layout.preferredWidth: parent.width
Layout.rightMargin: JamiTheme.swarmDetailsPageDocumentsMargins
Layout.bottomMargin: JamiTheme.swarmDetailsPageDocumentsMargins
color: "transparent"
Rectangle {
id: rectContent
anchors.fill: parent
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
color: themeColor
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Item {
width: localMediaCompLoader.width
height: localMediaCompLoader.height
Rectangle {
anchors.centerIn: parent
width: localMediaCompLoader.width
height: localMediaCompLoader.height
radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
}
}
}
Loader {
id: localMediaCompLoader
property var mediaInfo: MessagesAdapter.getMediaInfo(Body)
anchors.fill: parent
anchors.margins: 2
sourceComponent: {
if (mediaInfo.isImage || mediaInfo.isAnimatedImage)
return imageMediaComp;
else if (WITH_WEBENGINE)
return avMediaComp;
}
Component {
id: avMediaComp
Loader {
Component.onCompleted: {
var qml = WITH_WEBENGINE ? "qrc:/webengine/VideoPreview.qml" : "qrc:/nowebengine/VideoPreview.qml";
setSource(qml, {
"isVideo": mediaInfo.isVideo,
"html": mediaInfo.html
});
}
property real msgRadius: 20
}
}
Component {
id: imageMediaComp
Image {
id: fileImage
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: "file://" + Body
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Item {
width: fileImage.width
height: fileImage.height
Rectangle {
anchors.centerIn: parent
width: fileImage.width
height: fileImage.height
radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
}
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
onEntered: {
cursorShape = Qt.PointingHandCursor;
}
onClicked: function (mouse) {
if (mouse.button === Qt.RightButton) {
ctxMenu.x = mouse.x;
ctxMenu.y = mouse.y;
ctxMenu.openMenu();
} else {
MessagesAdapter.openUrl(fileImage.source);
}
}
}
SBSContextMenu {
id: ctxMenu
msgId: Id
location: Body
transferId: Id
transferName: TransferName
}
}
}
}
}
}
}
}
}

View file

@ -156,6 +156,16 @@ JamiListView {
}
}
ToastManager {
id: toastManager
anchors.fill: parent
function instantiateToast(dest) {
instantiate(JamiStrings.fileSaved.arg(dest), 1000, 400)
}
}
Connections {
target: CurrentConversation
function onScrollTo(id) {
@ -253,6 +263,10 @@ JamiListView {
root.loadMoreMsgsIfNeeded()
}
}
function onFileCopied(dest) {
toastManager.instantiateToast(dest)
}
}
ScrollToBottomButton {

View file

@ -254,12 +254,16 @@ void
MessagesAdapter::copyToDownloads(const QString& interactionId, const QString& displayName)
{
auto downloadDir = lrcInstance_->accountModel().downloadDirectory;
if (auto accInfo = &lrcInstance_->getCurrentAccountInfo())
accInfo->dataTransferModel->copyTo(lrcInstance_->get_currentAccountId(),
lrcInstance_->get_selectedConvUid(),
interactionId,
downloadDir,
displayName);
if (auto accInfo = &lrcInstance_->getCurrentAccountInfo()) {
auto dest = accInfo->dataTransferModel->copyTo(lrcInstance_->get_currentAccountId(),
lrcInstance_->get_selectedConvUid(),
interactionId,
downloadDir,
displayName);
if (!dest.isEmpty()) {
Q_EMIT fileCopied(dest);
}
}
}
void

View file

@ -77,6 +77,7 @@ Q_SIGNALS:
void previewInformationToQML(QString messageId, QStringList previewInformation);
void moreMessagesLoaded(qint32 loadingRequestId);
void timestampUpdated();
void fileCopied(const QString& dest);
protected:
Q_INVOKABLE bool isDocument(const interaction::Type& type);

View file

@ -72,11 +72,11 @@ public:
const QString& fileId,
const QString& filePath = {});
void copyTo(const QString& accountId,
const QString& convId,
const QString& interactionId,
const QString& destPath,
const QString& displayName);
QString copyTo(const QString& accountId,
const QString& convId,
const QString& interactionId,
const QString& destPath,
const QString& displayName);
void cancel(const QString& accountId, const QString& conversationId, const QString& fileId);

View file

@ -166,7 +166,7 @@ DataTransferModel::download(const QString& accountId,
ConfigurationManager::instance().downloadFile(accountId, convId, interactionId, fileId, path);
}
void
QString
DataTransferModel::copyTo(const QString& accountId,
const QString& convId,
const QString& interactionId,
@ -176,7 +176,7 @@ DataTransferModel::copyTo(const QString& accountId,
auto fileId = getFileIdFromInteractionId(interactionId);
if (fileId.isEmpty()) {
qWarning() << "Cannot find any file for " << interactionId;
return;
return {};
}
QString path;
qlonglong total, progress;
@ -186,7 +186,7 @@ DataTransferModel::copyTo(const QString& accountId,
auto src = QFile(path);
auto srcfi = QFileInfo(path);
if (!src.exists())
return;
return {};
auto filename = displayName;
if (displayName.isEmpty())
@ -198,6 +198,7 @@ DataTransferModel::copyTo(const QString& accountId,
if (!dir.exists())
dir.mkpath(".");
src.copy(dest);
return dest;
}
void