A native Qt6/C++ desktop client for the gallery's POST /upload API, in desktop/ with its own flake (kept separate from the Go server module the same way android/ is). Single-photo parity with the Android app: - multipart upload with preemptive HTTP Basic auth and retry-aware outcome classification (uploadclient) - JPEG/PNG metadata stripped byte-for-byte to drop embedded GPS, EXIF orientation baked in, and a quality/scale valve for the 20M nginx cap; HEIC decodes via the qtimageformats plugin (imageprep) - base URL / username in QSettings, password in the system keychain via qtkeychain; https required and a trailing /upload stripped (settings) - settings and post screens in a QStackedWidget (mainwindow) Native Wayland or xcb is selected at runtime. Bulk upload, EXIF capture-date prefill, and moving image prep off the UI thread are left as follow-ups.
53 lines
1.6 KiB
C++
53 lines
1.6 KiB
C++
#pragma once
|
|
|
|
#include <QDateTime>
|
|
#include <QSettings>
|
|
#include <QString>
|
|
|
|
// Persists the non-secret settings (base URL, username, last post) in a
|
|
// QSettings INI under ~/.config, and the password in the system keychain
|
|
// (libsecret / kwallet via QtKeychain). The password never lands on disk in the
|
|
// clear, mirroring the Android app's Keystore sealing.
|
|
class Settings
|
|
{
|
|
public:
|
|
struct LastPost {
|
|
QString slug;
|
|
QString url;
|
|
QString caption;
|
|
QDateTime postedAt;
|
|
bool valid() const { return !slug.isEmpty(); }
|
|
};
|
|
|
|
Settings();
|
|
|
|
QString baseUrl() const;
|
|
void setBaseUrl(const QString &value);
|
|
|
|
QString username() const;
|
|
void setUsername(const QString &value);
|
|
|
|
// Keychain access is synchronous here (a local event loop): the app does
|
|
// nothing until the credential is in hand, and there is no background retry
|
|
// worker as on Android that would need it off the UI thread.
|
|
QString readPassword() const;
|
|
void writePassword(const QString &value) const;
|
|
|
|
bool isConfigured() const;
|
|
|
|
LastPost lastPost() const;
|
|
void setLastPost(const LastPost &value);
|
|
|
|
// Returns an error message, or an empty string when the URL is usable.
|
|
// https is required: Basic auth would otherwise send the password in the
|
|
// clear.
|
|
static QString validateBaseUrl(const QString &raw);
|
|
|
|
// Trims trailing slashes and a trailing "/upload" (the endpoint path a user
|
|
// pasting the upload URL would leave on — the client appends it itself).
|
|
static QString normalizeBaseUrl(const QString &raw);
|
|
|
|
private:
|
|
mutable QSettings m_settings;
|
|
};
|