Bump version to 2.15.0 and tweak email UI

Release bump to 2.15.0 across the project (build.gradle, tauri.conf.json, AUR PKGBUILDs, and test simulation appVersion). Rearranged and documented Mailbox OAuth properties in ApplicationProperties (added @since 2.15.x). Email inbox UI/UX improvements: resized/connect panel styling, added close button, swapped icon, improved spacing and text, adjusted connect dialog open/close logic and demo message fallback, and updated related i18n keys (removed obsolete firstSetup key).
This commit is contained in:
Ludy87
2026-08-24 19:48:42 +02:00
parent 48246eb577
commit af1c212459
10 changed files with 71 additions and 44 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Maintainer: Stirling PDF Inc <contact@stirlingpdf.com>
pkgname=stirling-pdf-desktop
pkgver=2.14.3
pkgver=2.15.0
pkgrel=1
pkgdesc="Locally hosted, web-based PDF manipulation tool (Tauri desktop app, official Stirling PDF Inc build)"
arch=('x86_64')
+1 -1
View File
@@ -1,6 +1,6 @@
# Maintainer: Stirling PDF Inc <contact@stirlingpdf.com>
pkgname=stirling-pdf-server-bin
pkgver=2.14.3
pkgver=2.15.0
pkgrel=1
pkgdesc="Locally hosted, web-based PDF manipulation tool (server JAR, prebuilt)"
arch=('any')
@@ -83,18 +83,6 @@ public class ApplicationProperties {
private Cluster cluster = new Cluster();
private Policies policies = new Policies();
@Data
public static class Mailbox {
private Gmail gmail = new Gmail();
@Data
public static class Gmail {
private String clientId = "";
@ToString.Exclude private String clientSecret = "";
private String redirectUri = "";
}
}
@Bean
public PropertySource<?> dynamicYamlPropertySource(ConfigurableEnvironment environment)
throws IOException {
@@ -1429,6 +1417,23 @@ public class ApplicationProperties {
private Boolean sslCheckServerIdentity;
}
/**
* OAuth configuration for external mailbox providers.
*
* @since 2.15.x
*/
@Data
public static class Mailbox {
private Gmail gmail = new Gmail();
@Data
public static class Gmail {
private String clientId = "";
@ToString.Exclude private String clientSecret = "";
private String redirectUri = "";
}
}
/**
* Telegram bot configuration properties.
*
+1 -1
View File
@@ -108,7 +108,7 @@ springBoot {
allprojects {
group = 'stirling.software'
version = '2.14.3'
version = '2.15.0'
configurations.configureEach {
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
@@ -3705,7 +3705,6 @@ connectTitle = "Connect mailbox"
demoBody = "Attachments can be transferred directly into the Stirling PDF workspace after download."
download = "Import"
eyebrow = "File sources"
firstSetup = "First step"
folders = "Mailbox"
inbox = "Inbox"
message = "Message"
+1 -1
View File
@@ -2,7 +2,7 @@
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Stirling PDF",
"mainBinaryName": "Stirling-PDF",
"version": "2.14.3",
"version": "2.15.0",
"identifier": "stirling.pdf.dev",
"build": {
"frontendDist": "../dist",
@@ -534,31 +534,36 @@
background: color-mix(in srgb, var(--c-bg) 88%, transparent);
}
.email-connect-panel {
width: min(26rem, 100%);
padding: 2rem;
position: relative;
width: min(30rem, 100%);
padding: 2.25rem 2.25rem 1.75rem;
border: 1px solid var(--c-border);
border-radius: 0.5rem;
background: var(--c-surface);
box-shadow: 0 1.25rem 3rem rgb(0 0 0 / 16%);
text-align: center;
}
.email-connect-close {
position: absolute;
top: 0.65rem;
right: 0.65rem;
}
.email-connect-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 3rem;
height: 3rem;
margin-bottom: 0.85rem;
border-radius: 0.75rem;
color: var(--c-text-on-primary);
background: var(--c-primary);
width: auto;
height: auto;
margin-bottom: 1.15rem;
color: var(--c-text-muted);
font-size: 2.25rem;
}
.email-connect-panel h2 {
margin-top: 0.35rem;
font-size: 1.35rem;
font-size: 1.45rem;
}
.email-connect-panel p {
margin: 0.7rem 0 1.25rem;
max-width: 24rem;
margin: 0.75rem auto 1.5rem;
color: var(--c-text-muted);
font-size: 0.82rem;
line-height: 1.55;
@@ -566,6 +571,7 @@
.email-provider-actions {
display: grid;
gap: 0.55rem;
margin-top: 0.25rem;
}
.email-connect-panel small {
display: block;
@@ -13,6 +13,7 @@ import {
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import AttachFileIcon from "@mui/icons-material/AttachFile";
import CloudDownloadOutlinedIcon from "@mui/icons-material/CloudDownloadOutlined";
import CloseIcon from "@mui/icons-material/Close";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutlined";
import EmailOutlinedIcon from "@mui/icons-material/EmailOutlined";
import InboxOutlinedIcon from "@mui/icons-material/InboxOutlined";
@@ -148,6 +149,9 @@ export default function EmailInboxPage() {
const [accountConnected, setAccountConnected] = useState(
searchParams.get("gmail") === "connected",
);
const [connectDialogOpen, setConnectDialogOpen] = useState(
searchParams.get("gmail") !== "connected",
);
const [accountEmail, setAccountEmail] = useState(DEMO_ACCOUNT.email);
const [accountProvider, setAccountProvider] = useState<Provider>(
searchParams.get("gmail") === "connected" ? "Gmail" : DEMO_ACCOUNT.provider,
@@ -205,6 +209,7 @@ export default function EmailInboxPage() {
let active = true;
if (connectedFromCallback) {
setAccountConnected(true);
setConnectDialogOpen(false);
setSearchParams({}, { replace: true });
}
apiClient
@@ -214,6 +219,7 @@ export default function EmailInboxPage() {
.then(({ data }) => {
if (!active) return;
setAccountConnected(data.connected || connectedFromCallback);
setConnectDialogOpen(!data.connected && !connectedFromCallback);
setMailboxConfirmed(data.connected);
if (data.email) setAccountEmail(data.email);
if (data.provider) setAccountProvider(data.provider);
@@ -222,6 +228,7 @@ export default function EmailInboxPage() {
.catch(() => {
if (active) {
setAccountConnected(false);
setConnectDialogOpen(true);
setMailboxConfirmed(false);
}
});
@@ -291,9 +298,13 @@ export default function EmailInboxPage() {
};
useEffect(() => {
setMessages([]);
setNextPageToken(null);
if (mailboxConfirmed) void loadMessages();
if (mailboxConfirmed) {
setMessages([]);
void loadMessages();
} else {
setMessages(DEMO_MESSAGES);
}
}, [
mailboxConfirmed,
selectedFolder,
@@ -437,6 +448,7 @@ export default function EmailInboxPage() {
try {
await apiClient.delete("/api/v1/email/gmail/connection");
setAccountConnected(false);
setConnectDialogOpen(true);
setMailboxConfirmed(false);
setMessages([]);
setNextPageToken(null);
@@ -548,7 +560,7 @@ export default function EmailInboxPage() {
<ActionIcon
variant="tertiary"
aria-label={t("email.connectAccount", "Konto verbinden")}
onClick={() => setAccountConnected(true)}
onClick={() => setConnectDialogOpen(true)}
>
<LinkIcon fontSize="small" />
</ActionIcon>
@@ -915,14 +927,19 @@ export default function EmailInboxPage() {
</section>
</div>
{!accountConnected && (
{!accountConnected && connectDialogOpen && (
<div className="email-connect-overlay">
<div className="email-connect-panel">
<span className="email-connect-icon">
<LinkIcon />
</span>
<span className="email-page-eyebrow">
{t("email.firstSetup", "Erster Schritt")}
<ActionIcon
className="email-connect-close"
variant="tertiary"
aria-label={t("email.closeConnectDialog", "Close")}
onClick={() => setConnectDialogOpen(false)}
>
<CloseIcon fontSize="small" />
</ActionIcon>
<span className="email-connect-icon" aria-hidden="true">
<EmailOutlinedIcon />
</span>
<h2>{t("email.connectTitle", "Connect mailbox")}</h2>
<p>
@@ -938,7 +955,7 @@ export default function EmailInboxPage() {
onClick={() => void connectAccount()}
leftSection={<EmailOutlinedIcon fontSize="small" />}
>
Gmail verbinden
{t("email.connectGmail", "Connect Gmail")}
</Button>
</div>
<small>
@@ -958,14 +975,14 @@ export default function EmailInboxPage() {
centered
>
<TextInput
label={t("email.displayName", "Anzeigename")}
label={t("email.displayName", "Display name")}
description={t(
"email.displayNameHint",
"This name is displayed instead of the email address in the mailbox.",
)}
value={draftDisplayName}
onChange={(event) => setDraftDisplayName(event.currentTarget.value)}
placeholder={t("email.displayNamePlaceholder", "z. B. Peter Lustig")}
placeholder={t("email.displayNamePlaceholder", "e.g. Peter Example")}
autoFocus
/>
{accountConnected && (
@@ -981,9 +998,9 @@ export default function EmailInboxPage() {
)}
<div className="email-settings-actions">
<Button variant="secondary" onClick={() => setSettingsOpen(false)}>
{t("email.cancel", "Abbrechen")}
{t("email.cancel", "Cancel")}
</Button>
<Button onClick={saveSettings}>{t("email.save", "Speichern")}</Button>
<Button onClick={saveSettings}>{t("email.save", "Save")}</Button>
</div>
</Modal>
</main>
@@ -38,7 +38,7 @@ const FREE_LICENSE_INFO: LicenseInfo = {
const BASE_NO_LOGIN_CONFIG: AppConfig = {
enableAnalytics: true,
appVersion: "2.14.3",
appVersion: "2.15.0",
serverCertificateEnabled: false,
enableAlphaFunctionality: false,
serverPort: 8080,
@@ -48,7 +48,7 @@ const FREE_LICENSE_INFO: LicenseInfo = {
const BASE_NO_LOGIN_CONFIG: AppConfig = {
enableAnalytics: true,
appVersion: "2.14.3",
appVersion: "2.15.0",
serverCertificateEnabled: false,
enableAlphaFunctionality: false,
enableDesktopInstallSlide: true,