Add bulk multi-photo upload to the desktop app

Mirror the Android bulk feature in the Qt uploader: choose several photos
at once, each a card with its own caption, date, and upload status, and
post the batch.

- Per-photo cards (PhotoItemWidget) in a scrollable list; retry re-posts
  only the failures.
- One upload per photo with a per-item UUID slug suffix so a batch posted
  in the same second cannot collide.
- Image prep runs off the UI thread via QtConcurrent so the window stays
  responsive.
- A "Simultaneous uploads" setting (1–8, default 3) caps how many photos
  are prepared/uploaded at once; the rest queue and fill freed slots.
This commit is contained in:
2026-09-26 10:17:18 +02:00
parent 1d81ec4511
commit a7783671f2
7 changed files with 387 additions and 105 deletions
+24 -8
View File
@@ -1,15 +1,18 @@
#pragma once
#include <QList>
#include <QMainWindow>
#include "settings.h"
#include "uploadclient.h"
class QDateEdit;
class QLabel;
class QLineEdit;
class QPushButton;
class QSpinBox;
class QStackedWidget;
class QVBoxLayout;
class PhotoItemWidget;
class MainWindow : public QMainWindow
{
@@ -25,8 +28,15 @@ private:
void showPost();
void saveAndTest();
void chooseImage();
void chooseImages();
void addItem(const QString &path);
void removeItem(PhotoItemWidget *item);
void clearItems();
void submit();
void pumpQueue(); // starts queued items up to the concurrency cap
void startItem(PhotoItemWidget *item);
int inFlightCount() const; // items currently preparing or uploading
void refreshPosting(); // updates the Post button + summary from item states
Settings m_settings;
@@ -36,18 +46,24 @@ private:
QLineEdit *m_baseUrl = nullptr;
QLineEdit *m_username = nullptr;
QLineEdit *m_password = nullptr;
QSpinBox *m_concurrency = nullptr;
QPushButton *m_saveButton = nullptr;
QPushButton *m_settingsBack = nullptr;
QLabel *m_settingsStatus = nullptr;
// Post page
QLabel *m_preview = nullptr;
QLineEdit *m_caption = nullptr;
QDateEdit *m_date = nullptr;
QPushButton *m_chooseButton = nullptr;
QVBoxLayout *m_itemsLayout = nullptr; // holds the PhotoItemWidgets
QList<PhotoItemWidget *> m_items;
QLabel *m_emptyHint = nullptr;
QPushButton *m_postButton = nullptr;
QLabel *m_postStatus = nullptr;
QLabel *m_postSummary = nullptr;
QLabel *m_lastPost = nullptr;
QString m_imagePath; // currently selected source image
// Bulk-post state: items waiting for a free upload slot, plus the batch's
// credentials captured once at submit time.
QList<PhotoItemWidget *> m_queue;
QString m_batchBaseUrl;
QString m_batchUsername;
QString m_batchPassword;
QString m_batchCacheDir;
};