mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Show some previews in upload window
This commit is contained in:
parent
830f4d4942
commit
dbd2bebe6c
9 changed files with 104 additions and 7 deletions
1
resources/icons/ui/image.svg
Normal file
1
resources/icons/ui/image.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg width="512" height="512" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M17.75 3A3.25 3.25 0 0 1 21 6.25v11.5A3.25 3.25 0 0 1 17.75 21H6.25A3.25 3.25 0 0 1 3 17.75V6.25A3.25 3.25 0 0 1 6.25 3h11.5Zm.58 16.401-5.805-5.686a.75.75 0 0 0-.966-.071l-.084.07-5.807 5.687c.182.064.378.099.582.099h11.5c.203 0 .399-.035.58-.099l-5.805-5.686L18.33 19.4ZM17.75 4.5H6.25A1.75 1.75 0 0 0 4.5 6.25v11.5c0 .208.036.408.103.594l5.823-5.701a2.25 2.25 0 0 1 3.02-.116l.128.116 5.822 5.702c.067-.186.104-.386.104-.595V6.25a1.75 1.75 0 0 0-1.75-1.75Zm-2.498 2a2.252 2.252 0 1 1 0 4.504 2.252 2.252 0 0 1 0-4.504Zm0 1.5a.752.752 0 1 0 0 1.504.752.752 0 0 0 0-1.504Z" fill="#212121"/></svg>
|
After Width: | Height: | Size: 704 B |
1
resources/icons/ui/music.svg
Normal file
1
resources/icons/ui/music.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg width="512" height="512" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19.698 2.148A.75.75 0 0 1 20 2.75v13.5a.764.764 0 0 1-.004.079 3.5 3.5 0 1 1-1.496-2.702V7.758l-8.5 2.55v7.942a.756.756 0 0 1-.004.079A3.5 3.5 0 1 1 8.5 15.627V5.75a.75.75 0 0 1 .534-.718l10-3a.75.75 0 0 1 .664.116ZM10 8.742l8.5-2.55V3.758L10 6.308v2.434ZM6.5 16.5a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm8 0a2 2 0 1 0 4 0 2 2 0 0 0-4 0Z" fill="#212121"/></svg>
|
After Width: | Height: | Size: 458 B |
1
resources/icons/ui/video-file.svg
Normal file
1
resources/icons/ui/video-file.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg width="512" height="512" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M6.25 4h11.5a3.25 3.25 0 0 1 3.245 3.066L21 7.25v9.5a3.25 3.25 0 0 1-3.066 3.245L17.75 20H6.25a3.25 3.25 0 0 1-3.245-3.066L3 16.75v-9.5a3.25 3.25 0 0 1 3.066-3.245L6.25 4h11.5-11.5Zm11.5 1.5H6.25a1.75 1.75 0 0 0-1.744 1.606L4.5 7.25v9.5a1.75 1.75 0 0 0 1.606 1.744l.144.006h11.5a1.75 1.75 0 0 0 1.744-1.607l.006-.143v-9.5a1.75 1.75 0 0 0-1.607-1.744L17.75 5.5Zm-7.697 4.085a.5.5 0 0 1 .587-.256l.084.033 4.382 2.19a.5.5 0 0 1 .076.848l-.076.047-4.382 2.191a.5.5 0 0 1-.716-.357L10 14.19V9.809a.5.5 0 0 1 .053-.224Z" fill="#212121"/></svg>
|
After Width: | Height: | Size: 645 B |
1
resources/icons/ui/zip.svg
Normal file
1
resources/icons/ui/zip.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg width="512" height="512" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9.49 4.402A2.25 2.25 0 0 0 8.208 4H4.25l-.154.005A2.25 2.25 0 0 0 2 6.25v11.5l.005.154A2.25 2.25 0 0 0 4.25 20h15.5l.154-.005A2.25 2.25 0 0 0 22 17.75v-9l-.005-.154-.017-.158A2.25 2.25 0 0 0 19.75 6.5h-7.728L9.647 4.521l-.156-.119ZM13.498 8v2.245c0 .414.335.75.75.75h.75v1.003h-.25a.75.75 0 0 0 0 1.5h.25v1.5h-.25a.75.75 0 0 0 0 1.5h.25V18.5H4.25l-.102-.007a.75.75 0 0 1-.648-.743v-7.251l4.707.001.196-.009a2.25 2.25 0 0 0 1.244-.512L12.021 8h1.476Zm3 10h.25a.75.75 0 0 0 0-1.5h-.25V15h.25a.75.75 0 0 0 0-1.5h-.25v-2.505h.75a.75.75 0 0 0 .75-.75V8h1.753l.102.007a.75.75 0 0 1 .648.743v9l-.007.102a.75.75 0 0 1-.743.648h-3.253V18Zm0-10v1.495h-1.5V8h1.5ZM4.25 5.5h3.957l.104.007a.75.75 0 0 1 .376.167l1.891 1.575-1.89 1.577-.086.061A.75.75 0 0 1 8.207 9L3.5 8.999V6.25l.007-.102A.75.75 0 0 1 4.25 5.5Z" fill="#212121"/></svg>
|
After Width: | Height: | Size: 931 B |
|
@ -124,10 +124,76 @@ Item {
|
||||||
color: Nheko.theme.separator
|
color: Nheko.theme.separator
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
|
||||||
text: "Send files " + (room ? room.input.uploads.length : 0)
|
Page {
|
||||||
|
id: uploadPopup
|
||||||
visible: room && room.input.uploads.length > 0
|
visible: room && room.input.uploads.length > 0
|
||||||
onClicked: room.input.acceptUploads()
|
Layout.preferredHeight: 200
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
padding: Nheko.paddingMedium
|
||||||
|
|
||||||
|
contentItem: ListView {
|
||||||
|
id: uploadsList
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
orientation: ListView.Horizontal
|
||||||
|
width: Math.min(contentWidth, parent.width)
|
||||||
|
model: room ? room.input.uploads : undefined
|
||||||
|
spacing: Nheko.paddingMedium
|
||||||
|
|
||||||
|
delegate: Pane {
|
||||||
|
padding: Nheko.paddingSmall
|
||||||
|
height: uploadPopup.availableHeight - buttons.height
|
||||||
|
width: uploadPopup.availableHeight - buttons.height
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Nheko.colors.window
|
||||||
|
radius: Nheko.paddingMedium
|
||||||
|
}
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
Image {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
sourceSize.height: height
|
||||||
|
sourceSize.width: width
|
||||||
|
|
||||||
|
property string typeStr: switch(modelData.mediaType) {
|
||||||
|
case MediaUpload.Video: return "video-file";
|
||||||
|
case MediaUpload.Audio: return "music";
|
||||||
|
case MediaUpload.Image: return "image";
|
||||||
|
default: return "zip";
|
||||||
|
}
|
||||||
|
source: "image://colorimage/:/icons/icons/ui/"+typeStr+".svg?" + Nheko.colors.buttonText
|
||||||
|
}
|
||||||
|
MatrixTextField {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: modelData.filename
|
||||||
|
onTextEdited: modelData.filename = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: DialogButtonBox {
|
||||||
|
id: buttons
|
||||||
|
|
||||||
|
standardButtons: DialogButtonBox.Cancel
|
||||||
|
Button {
|
||||||
|
text: qsTr("Upload %n file(s)", "", (room ? room.input.uploads.length : 0))
|
||||||
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||||
|
}
|
||||||
|
onAccepted: room.input.acceptUploads()
|
||||||
|
onRejected: room.input.declineUploads()
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Nheko.colors.base
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationWarning {
|
NotificationWarning {
|
||||||
|
|
|
@ -58,7 +58,7 @@ Item {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: thumbnailUrl.replace("mxc://", "image://MxcImage/") + "?scale"
|
source: thumbnailUrl ? thumbnailUrl.replace("mxc://", "image://MxcImage/") + "?scale" : ""
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,10 @@
|
||||||
<file>icons/ui/volume-off-indicator.svg</file>
|
<file>icons/ui/volume-off-indicator.svg</file>
|
||||||
<file>icons/ui/volume-up.svg</file>
|
<file>icons/ui/volume-up.svg</file>
|
||||||
<file>icons/ui/world.svg</file>
|
<file>icons/ui/world.svg</file>
|
||||||
|
<file>icons/ui/music.svg</file>
|
||||||
|
<file>icons/ui/image.svg</file>
|
||||||
|
<file>icons/ui/zip.svg</file>
|
||||||
|
<file>icons/ui/video-file.svg</file>
|
||||||
<file>icons/emoji-categories/activity.svg</file>
|
<file>icons/emoji-categories/activity.svg</file>
|
||||||
<file>icons/emoji-categories/flags.svg</file>
|
<file>icons/emoji-categories/flags.svg</file>
|
||||||
<file>icons/emoji-categories/foods.svg</file>
|
<file>icons/emoji-categories/foods.svg</file>
|
||||||
|
|
|
@ -251,6 +251,8 @@ MainWindow::registerQmlTypes()
|
||||||
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
|
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
|
||||||
qmlRegisterUncreatableType<emoji::Emoji>(
|
qmlRegisterUncreatableType<emoji::Emoji>(
|
||||||
"im.nheko.EmojiModel", 1, 0, "Emoji", QStringLiteral("Used by emoji models"));
|
"im.nheko.EmojiModel", 1, 0, "Emoji", QStringLiteral("Used by emoji models"));
|
||||||
|
qmlRegisterUncreatableType<MediaUpload>(
|
||||||
|
"im.nheko", 1, 0, "MediaUpload", QStringLiteral("MediaUploads can not be created in Qml"));
|
||||||
qmlRegisterUncreatableMetaObject(emoji::staticMetaObject,
|
qmlRegisterUncreatableMetaObject(emoji::staticMetaObject,
|
||||||
"im.nheko.EmojiModel",
|
"im.nheko.EmojiModel",
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -53,11 +53,11 @@ class MediaUpload : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
// Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged)
|
// Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged)
|
||||||
// Q_PROPERTY(MediaType mediaType READ type NOTIFY mediaTypeChanged)
|
Q_PROPERTY(int mediaType READ type NOTIFY mediaTypeChanged)
|
||||||
// // https://stackoverflow.com/questions/33422265/pass-qimage-to-qml/68554646#68554646
|
// // https://stackoverflow.com/questions/33422265/pass-qimage-to-qml/68554646#68554646
|
||||||
// Q_PROPERTY(QUrl thumbnail READ thumbnail NOTIFY thumbnailChanged)
|
// Q_PROPERTY(QUrl thumbnail READ thumbnail NOTIFY thumbnailChanged)
|
||||||
// Q_PROPERTY(QString humanSize READ humanSize NOTIFY huSizeChanged)
|
// Q_PROPERTY(QString humanSize READ humanSize NOTIFY huSizeChanged)
|
||||||
// Q_PROPERTY(QString filename READ filename NOTIFY filenameChanged)
|
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
|
||||||
// Q_PROPERTY(QString mimetype READ mimetype NOTIFY mimetypeChanged)
|
// Q_PROPERTY(QString mimetype READ mimetype NOTIFY mimetypeChanged)
|
||||||
// Q_PROPERTY(int height READ height NOTIFY heightChanged)
|
// Q_PROPERTY(int height READ height NOTIFY heightChanged)
|
||||||
// Q_PROPERTY(int width READ width NOTIFY widthChanged)
|
// Q_PROPERTY(int width READ width NOTIFY widthChanged)
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
Video,
|
Video,
|
||||||
Audio,
|
Audio,
|
||||||
};
|
};
|
||||||
Q_ENUM(MediaType);
|
Q_ENUM(MediaType)
|
||||||
|
|
||||||
explicit MediaUpload(std::unique_ptr<QIODevice> data,
|
explicit MediaUpload(std::unique_ptr<QIODevice> data,
|
||||||
QString mimetype,
|
QString mimetype,
|
||||||
|
@ -81,6 +81,17 @@ public:
|
||||||
bool encrypt,
|
bool encrypt,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
[[nodiscard]] int type() const
|
||||||
|
{
|
||||||
|
if (mimeClass_ == u"video")
|
||||||
|
return MediaType::Video;
|
||||||
|
else if (mimeClass_ == u"audio")
|
||||||
|
return MediaType::Audio;
|
||||||
|
else if (mimeClass_ == u"image")
|
||||||
|
return MediaType::Image;
|
||||||
|
else
|
||||||
|
return MediaType::File;
|
||||||
|
}
|
||||||
[[nodiscard]] QString url() const { return url_; }
|
[[nodiscard]] QString url() const { return url_; }
|
||||||
[[nodiscard]] QString mimetype() const { return mimetype_; }
|
[[nodiscard]] QString mimetype() const { return mimetype_; }
|
||||||
[[nodiscard]] QString mimeClass() const { return mimeClass_; }
|
[[nodiscard]] QString mimeClass() const { return mimeClass_; }
|
||||||
|
@ -102,9 +113,19 @@ public:
|
||||||
QString thumbnailUrl() const { return thumbnailUrl_; }
|
QString thumbnailUrl() const { return thumbnailUrl_; }
|
||||||
[[nodiscard]] uint64_t thumbnailSize() const { return thumbnailSize_; }
|
[[nodiscard]] uint64_t thumbnailSize() const { return thumbnailSize_; }
|
||||||
|
|
||||||
|
void setFilename(QString fn)
|
||||||
|
{
|
||||||
|
if (fn != originalFilename_) {
|
||||||
|
originalFilename_ = std::move(fn);
|
||||||
|
emit filenameChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void uploadComplete(MediaUpload *self, QString url);
|
void uploadComplete(MediaUpload *self, QString url);
|
||||||
void uploadFailed(MediaUpload *self);
|
void uploadFailed(MediaUpload *self);
|
||||||
|
void filenameChanged();
|
||||||
|
void mediaTypeChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void startUpload();
|
void startUpload();
|
||||||
|
|
Loading…
Reference in a new issue