Add Animated images to chat and notifications.

Higher chat bubbles when thumbnails can be shown.
This commit is contained in:
Julien Wadel 2022-05-12 19:58:07 +02:00
parent a8339bebc3
commit 33afd2a17a
5 changed files with 117 additions and 71 deletions

View file

@ -527,3 +527,11 @@ bool Utils::isMe(const QString& address){
bool Utils::isMe(const std::shared_ptr<const linphone::Address>& address){ bool Utils::isMe(const std::shared_ptr<const linphone::Address>& address){
return address ? CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(address) : false; return address ? CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(address) : false;
} }
bool Utils::isAnimatedImage(const QString& path){
QFileInfo info(path);
if( !info.exists())
return false;
QImageReader reader(path);
return reader.supportsAnimation() && reader.imageCount() > 1;
}

View file

@ -60,6 +60,7 @@ public:
Q_INVOKABLE static QString getDisplayName(const QString& address); Q_INVOKABLE static QString getDisplayName(const QString& address);
Q_INVOKABLE static QString toString(const LinphoneEnums::TunnelMode& mode); Q_INVOKABLE static QString toString(const LinphoneEnums::TunnelMode& mode);
Q_INVOKABLE static bool isMe(const QString& address); Q_INVOKABLE static bool isMe(const QString& address);
Q_INVOKABLE static bool isAnimatedImage(const QString& path);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static inline QString coreStringToAppString (const std::string &str) { static inline QString coreStringToAppString (const std::string &str) {

View file

@ -9,6 +9,7 @@ import Linphone.Styles 1.0
import Utils 1.0 import Utils 1.0
import Units 1.0 import Units 1.0
import ColorsList 1.0 import ColorsList 1.0
import UtilsCpp 1.0
// ============================================================================= // =============================================================================
// TODO : into Loader // TODO : into Loader
@ -51,7 +52,7 @@ Row {
property string thumbnail : mainRow.contentModel ? mainRow.contentModel.thumbnail : '' property string thumbnail : mainRow.contentModel ? mainRow.contentModel.thumbnail : ''
color: 'transparent' color: 'transparent'
height: ChatStyle.entry.message.file.height height: thumbnail ? ChatStyle.entry.message.file.heightWithThumbnail : ChatStyle.entry.message.file.height
width: mainRow.width width: mainRow.width
radius: ChatStyle.entry.message.radius radius: ChatStyle.entry.message.radius
@ -77,8 +78,20 @@ Row {
mipmap: SettingsModel.mipmapEnabled mipmap: SettingsModel.mipmapEnabled
source: mainRow.contentModel.thumbnail source: mainRow.contentModel.thumbnail
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
sourceSize.width: 100 //sourceSize.width: 200
sourceSize.height: 100 //sourceSize.height: 100
}
}
Component {
id: animatedImage
AnimatedImage {
id: animatedImageSource
mipmap: SettingsModel.mipmapEnabled
source: 'file:/'+mainRow.contentModel.filePath
fillMode: Image.PreserveAspectFit
//width: 200
//height: 100
} }
} }
@ -105,9 +118,13 @@ Row {
id: thumbnailProvider id: thumbnailProvider
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: parent.height Layout.preferredWidth: parent.height*4/3
sourceComponent: (mainRow.contentModel ? (mainRow.contentModel.thumbnail ? thumbnailImage : extension ): undefined) sourceComponent: (mainRow.contentModel ?
(mainRow.contentModel.wasDownloaded && UtilsCpp.isAnimatedImage(mainRow.contentModel.filePath)
? animatedImage
: (mainRow.contentModel.thumbnail ? thumbnailImage : extension )
) : undefined)
ScaleAnimator { ScaleAnimator {
id: thumbnailProviderAnimator id: thumbnailProviderAnimator

View file

@ -6,73 +6,92 @@ import Linphone 1.0
import Linphone.Styles 1.0 import Linphone.Styles 1.0
import Utils 1.0 import Utils 1.0
import UtilsCpp 1.0
// ============================================================================= // =============================================================================
Notification { Notification {
id: notification id: notification
icon: 'file_sign' icon: 'file_sign'
overrodeHeight: NotificationReceivedFileMessageStyle.overrodeHeight overrodeHeight: NotificationReceivedFileMessageStyle.overrodeHeight
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
readonly property string fileUri: notificationData && notificationData.fileUri || '' readonly property string fileUri: notificationData && notificationData.fileUri || ''
readonly property string imageUri: notificationData && notificationData.imageUri || '' readonly property string imageUri: notificationData && notificationData.imageUri || ''
property string systemFileUri: Utils.getUriFromSystemPath(notification.fileUri)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
Loader {
active: Boolean(notification.fileUri) Loader {
anchors { active: Boolean(notification.fileUri)
fill: parent anchors {
fill: parent
leftMargin: NotificationReceivedFileMessageStyle.leftMargin
rightMargin: NotificationReceivedFileMessageStyle.rightMargin leftMargin: NotificationReceivedFileMessageStyle.leftMargin
} rightMargin: NotificationReceivedFileMessageStyle.rightMargin
}
sourceComponent: RowLayout {
anchors.fill: parent sourceComponent: RowLayout {
spacing: NotificationReceivedFileMessageStyle.spacing anchors.fill: parent
spacing: NotificationReceivedFileMessageStyle.spacing
Text {
Layout.fillWidth: true Text {
Layout.fillWidth: true
color: NotificationReceivedFileMessageStyle.fileName.color
elide: Text.ElideRight color: NotificationReceivedFileMessageStyle.fileName.color
font.pointSize: NotificationReceivedFileMessageStyle.fileName.pointSize elide: Text.ElideRight
text: Utils.basename(notification.fileUri) font.pointSize: NotificationReceivedFileMessageStyle.fileName.pointSize
visible:!image.visible text: Utils.basename(notification.fileUri)
} visible:!normalImage.visible && !animatedImage.visible
Image{ }
id:image Loader{
mipmap: SettingsModel.mipmapEnabled Layout.fillHeight: true
Layout.fillHeight: true Layout.fillWidth: true
Layout.fillWidth: true
fillMode: Image.PreserveAspectFit sourceComponent: notification.fileUri && UtilsCpp.isAnimatedImage(notification.fileUri) ? animatedImage : normalImage
source: (imageUri ?"image://external/"+notification.imageUri : '') active: fileUri || imageUri
visible: image.status == Image.Ready Component{
} id: normalImage
Image{
Text { id:image
Layout.preferredWidth: NotificationReceivedFileMessageStyle.fileSize.width mipmap: SettingsModel.mipmapEnabled
fillMode: Image.PreserveAspectFit
color: NotificationReceivedFileMessageStyle.fileSize.color source: (imageUri ?"image://external/"+notification.imageUri : '')
elide: Text.ElideRight visible: image.status == Image.Ready
font.pointSize: NotificationReceivedFileMessageStyle.fileSize.pointSize }
horizontalAlignment: Text.AlignRight }
text: Utils.formatSize(notification.notificationData.fileSize) Component{
} id: animatedImage
} AnimatedImage{
id:image
MouseArea { mipmap: SettingsModel.mipmapEnabled
anchors.fill: parent fillMode: Image.PreserveAspectFit
source: (systemFileUri ? systemFileUri: '')
onClicked: notification._close(function () { }
var uri = Utils.getUriFromSystemPath(notification.fileUri) }
if (!Qt.openUrlExternally(uri)) { }
Qt.openUrlExternally(Utils.dirname(uri))
} Text {
}) Layout.preferredWidth: NotificationReceivedFileMessageStyle.fileSize.width
}
} color: NotificationReceivedFileMessageStyle.fileSize.color
elide: Text.ElideRight
font.pointSize: NotificationReceivedFileMessageStyle.fileSize.pointSize
horizontalAlignment: Text.AlignRight
text: Utils.formatSize(notification.notificationData.fileSize)
}
}
MouseArea {
anchors.fill: parent
onClicked: notification._close(function () {
if (!Qt.openUrlExternally(systemFileUri)) {
Qt.openUrlExternally(Utils.dirname(systemFileUri))
}
})
}
}
} }

View file

@ -183,6 +183,7 @@ QtObject {
property QtObject file: QtObject { property QtObject file: QtObject {
property int height: 64 property int height: 64
property int heightWithThumbnail: 200
property int iconSize: 18 property int iconSize: 18
property int margins: 8 property int margins: 8
property int spacing: 8 property int spacing: 8