diff --git a/tools/chatgui/src/avatars/avatargallery.cpp b/tools/chatgui/src/avatars/avatargallery.cpp index 5f7b3e29..c3dae276 100644 --- a/tools/chatgui/src/avatars/avatargallery.cpp +++ b/tools/chatgui/src/avatars/avatargallery.cpp @@ -17,21 +17,29 @@ public: explicit Gallery(AvatarManager* source) : manager(source) { setAttribute(Qt::WA_DeleteOnClose); resize(850,720); setWindowTitle(text("Avatars")); auto* layout = new QVBoxLayout(this); viewer = new ImageViewerWindow(this); layout->addWidget(viewer,1); + viewer->setPlaceholder(text("Loading original…")); status = new QLabel(this); status->setAlignment(Qt::AlignCenter); layout->addWidget(status); + retry = new QPushButton(text("Retry"),this); retry->hide(); layout->addWidget(retry); + connect(retry,&QPushButton::clicked,this,[this] { retry->hide(); if (manager) manager->retryGallery(); }); auto* strip = new QHBoxLayout; strip->addStretch(); previous = new QPushButton("←",this); strip->addWidget(previous); + previous->setObjectName("avatarPrevious"); for (int i=0;i<5;i++) { previews[i] = new QPushButton(this); previews[i]->setFixedSize(64,64); previews[i]->setIconSize({56,56}); + previews[i]->setObjectName(QString("avatarPreview%1").arg(i)); if (i==2) previews[i]->setStyleSheet("border: 2px solid #77aaff;"); strip->addWidget(previews[i]); connect(previews[i], &QPushButton::clicked, this, [this,i] { move(i-2); }); } next = new QPushButton("→",this); strip->addWidget(next); strip->addStretch(); layout->addLayout(strip); + next->setObjectName("avatarNext"); connect(previous, &QPushButton::clicked, this, [this] { move(-1); }); connect(next, &QPushButton::clicked, this, [this] { move(1); }); connect(new QShortcut(QKeySequence(Qt::Key_Left),this), &QShortcut::activated, this, [this] { move(-1); }); connect(new QShortcut(QKeySequence(Qt::Key_Right),this), &QShortcut::activated, this, [this] { move(1); }); connect(viewer, &ImageViewerWindow::closed, this, &QDialog::close); connect(manager, &AvatarManager::galleryChanged, this, [this] { refresh(); }); - connect(manager, &AvatarManager::galleryError, status, &QLabel::setText); + connect(manager, &AvatarManager::galleryError, this, [this](const QString& error) { + status->setText(error); viewer->setPlaceholder(error); retry->setVisible(manager && !manager->galleryCurrent().isEmpty()); + }); connect(manager, &QObject::destroyed, this, &QDialog::close); auto* timer = new QTimer(this); timer->setInterval(2000); connect(timer,&QTimer::timeout,this,[this] { refresh(); }); timer->start(); } @@ -40,7 +48,7 @@ public: if (!manager) return; const auto files=manager->gallery(); const int index=files.indexOf(selected)+delta; if (index<0 || index>=files.size()) return; - selected=files[index]; displayed=0; refresh(); + selected=files[index]; displayed=0; retry->hide(); viewer->setPlaceholder(text("Loading original…")); refresh(); } void refresh() { if (!manager) return; @@ -51,15 +59,17 @@ public: const bool full=!image.isNull(); if (!full) image=manager->galleryImage(selected); if (image.cacheKey()!=displayed) { viewer->loadImage(image); displayed=image.cacheKey(); } if (full) status->setText(QString("%1 / %2").arg(index+1).arg(files.size())); - else if (!image.isNull()) status->setText(text("Loading original…")); + else if (!retry->isVisible()) status->setText(text("Loading original…")); for (int i=0;i<5;i++) { const int item=index+i-2; const bool valid=item>=0 && itemsetEnabled(valid); - previews[i]->setIcon(valid ? QIcon(QPixmap::fromImage(manager->galleryImage(files[item]))) : QIcon()); + const QImage thumbnail=valid ? manager->galleryImage(files[item]) : QImage(); + previews[i]->setIcon(QIcon(QPixmap::fromImage(thumbnail))); + previews[i]->setText(valid && thumbnail.isNull() ? QStringLiteral("…") : QString()); } } private: QPointer manager; ImageViewerWindow* viewer; QLabel* status; - QPushButton *previews[5], *previous, *next; QString selected; qint64 displayed=0; + QPushButton *previews[5], *previous, *next, *retry; QString selected; qint64 displayed=0; }; QPointer active; } diff --git a/tools/chatgui/src/avatars/avatarmanager.cpp b/tools/chatgui/src/avatars/avatarmanager.cpp index 96ba1b97..ce47469d 100644 --- a/tools/chatgui/src/avatars/avatarmanager.cpp +++ b/tools/chatgui/src/avatars/avatarmanager.cpp @@ -219,6 +219,12 @@ QImage AvatarManager::galleryImage(const QString& hash, bool original) { Ref ref = m_galleryRef; ref.hash = hash; return fetch(ref, original, true); } +void AvatarManager::retryGallery() { + for (const auto& hash : m_gallery) { m_retry.remove(hash); m_retry.remove(hash + ":original"); } + if (!m_listId) { m_catalog.clear(); m_listRetries = 0; listGallery(); } + emit galleryChanged(); +} + QImage AvatarManager::defaultImage() const { auto* image = m_images.object(m_defaultHash); return image ? *image : QImage(); } diff --git a/tools/chatgui/src/avatars/avatarmanager.h b/tools/chatgui/src/avatars/avatarmanager.h index 018ee369..f4deb04a 100644 --- a/tools/chatgui/src/avatars/avatarmanager.h +++ b/tools/chatgui/src/avatars/avatarmanager.h @@ -29,6 +29,7 @@ public: void uploadDefault(const QString& source, quint64 server, const QRectF& crop = {}); void openGallery(const QString& channel, quint64 owner); void closeGallery(); + void retryGallery(); QStringList gallery() const { return m_gallery; } QString galleryCurrent() const { return m_galleryRef.hash; } QImage galleryImage(const QString& hash, bool original = false);