Skip to content

Commit e6d4762

Browse files
authored
Clean up update dialog UI and fix desktop external links (Stirling-Tools#6727)
1 parent 3456316 commit e6d4762

10 files changed

Lines changed: 78 additions & 50 deletions

File tree

.github/aur/stirling-pdf-desktop/PKGBUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Maintainer: Stirling PDF Inc <contact@stirlingpdf.com>
22
pkgname=stirling-pdf-desktop
3-
pkgver=2.12.0
3+
pkgver=2.13.0
44
pkgrel=1
55
pkgdesc="Locally hosted, web-based PDF manipulation tool (Tauri desktop app, official Stirling PDF Inc build)"
66
arch=('x86_64')

.github/aur/stirling-pdf-server-bin/PKGBUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Maintainer: Stirling PDF Inc <contact@stirlingpdf.com>
22
pkgname=stirling-pdf-server-bin
3-
pkgver=2.12.0
3+
pkgver=2.13.0
44
pkgrel=1
55
pkgdesc="Locally hosted, web-based PDF manipulation tool (server JAR, prebuilt)"
66
arch=('any')

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ springBoot {
7878

7979
allprojects {
8080
group = 'stirling.software'
81-
version = '2.12.0'
81+
version = '2.13.0'
8282

8383
configurations.configureEach {
8484
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"

frontend/editor/public/locales/en-US/translation.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7712,8 +7712,6 @@ allReleases = "All Releases"
77127712
breaking = "Breaking"
77137713
breakingChanges = "Breaking Changes"
77147714
breakingChangesDefault = "This version contains breaking changes."
7715-
breakingChangesDetected = "Breaking Changes Detected"
7716-
breakingChangesMessage = "Some versions contain breaking changes. Please review the migration guides below before updating."
77177715
close = "Close"
77187716
closeModal = "Close update modal"
77197717
current = "Current Version"

frontend/editor/src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
33
"productName": "Stirling-PDF",
4-
"version": "2.12.0",
4+
"version": "2.13.0",
55
"identifier": "stirling.pdf.dev",
66
"build": {
77
"frontendDist": "../dist",

frontend/editor/src/core/components/shared/UpdateModal.tsx

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
MachineInfo,
2525
} from "@app/services/updateService";
2626
import { Z_INDEX_OVER_CONFIG_MODAL } from "@app/styles/zIndex";
27+
import { openExternal } from "@app/platform/openExternal";
2728
import WarningAmberIcon from "@mui/icons-material/WarningAmber";
2829
import OpenInNewIcon from "@mui/icons-material/OpenInNew";
2930
import DownloadIcon from "@mui/icons-material/Download";
@@ -36,6 +37,19 @@ import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
3637
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
3738
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
3839

40+
/**
41+
* Best-effort Tauri detection without importing `@tauri-apps/api` into the
42+
* core bundle (which must stay runnable on plain web). Tauri v2 injects
43+
* `__TAURI_INTERNALS__` before any user code runs. Mirrors UpdateStartupPopup.
44+
*/
45+
function isRunningInTauri(): boolean {
46+
if (typeof window === "undefined") return false;
47+
return (
48+
typeof (window as unknown as { __TAURI_INTERNALS__?: unknown })
49+
.__TAURI_INTERNALS__ !== "undefined"
50+
);
51+
}
52+
3953
export type DesktopInstallState =
4054
| "idle"
4155
| "downloading"
@@ -197,6 +211,20 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
197211
onClose();
198212
};
199213

214+
// External links (release notes, migration guides, download fallback) use
215+
// real anchors so they open a new tab on web. Inside Tauri the webview traps
216+
// target="_blank", so on desktop we intercept and hand the URL to the OS
217+
// browser via the platform seam. stopPropagation keeps links nested in the
218+
// clickable version-history rows from toggling the row.
219+
const handleExternalLink =
220+
(url: string) => (e: React.MouseEvent<HTMLElement>) => {
221+
e.stopPropagation();
222+
if (isRunningInTauri()) {
223+
e.preventDefault();
224+
void openExternal(url);
225+
}
226+
};
227+
200228
// Sort versions newest first, skip the latest (already shown in header)
201229
const sortedVersions = fullUpdateInfo?.new_versions
202230
? [...fullUpdateInfo.new_versions].sort((a, b) =>
@@ -323,11 +351,25 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
323351
</Group>
324352
</Box>
325353

326-
{/* Priority badge + recommendation — compact single line */}
354+
{/* Priority badge + recommendation — compact single line. When the
355+
update contains breaking changes we surface a compact inline
356+
chip here rather than a separate full-width orange banner; the
357+
specific per-version detail lives in Version History below. */}
327358
<Group gap="sm" align="center" px={4}>
328359
<Badge color={priorityColor} variant="filled" size="lg" radius="sm">
329360
{getPriorityLabel(updateSummary.max_priority)}
330361
</Badge>
362+
{updateSummary.any_breaking && (
363+
<Badge
364+
color="orange"
365+
variant="light"
366+
size="lg"
367+
radius="sm"
368+
leftSection={<WarningAmberIcon style={{ fontSize: 14 }} />}
369+
>
370+
{t("update.breaking", "Breaking")}
371+
</Badge>
372+
)}
331373
<Text size="sm" c="dimmed" style={{ flex: 1 }}>
332374
{updateSummary.recommended_action ||
333375
t(
@@ -362,6 +404,7 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
362404
href={WINDOWS_INSTALL_DOCS_URL}
363405
target="_blank"
364406
rel="noopener noreferrer"
407+
onClick={handleExternalLink(WINDOWS_INSTALL_DOCS_URL)}
365408
>
366409
{t(
367410
"desktopUpdate.blocked.docsLink",
@@ -402,6 +445,9 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
402445
component="a"
403446
href={`https://github.com/Stirling-Tools/Stirling-PDF/releases/tag/v${updateSummary.latest_version}`}
404447
target="_blank"
448+
onClick={handleExternalLink(
449+
`https://github.com/Stirling-Tools/Stirling-PDF/releases/tag/v${updateSummary.latest_version}`,
450+
)}
405451
c="blue"
406452
style={{
407453
textDecoration: "none",
@@ -418,6 +464,9 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
418464
component="a"
419465
href="https://github.com/Stirling-Tools/Stirling-PDF/releases"
420466
target="_blank"
467+
onClick={handleExternalLink(
468+
"https://github.com/Stirling-Tools/Stirling-PDF/releases",
469+
)}
421470
c="dimmed"
422471
style={{
423472
textDecoration: "none",
@@ -433,25 +482,6 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
433482
</Group>
434483
</Box>
435484

436-
{/* Breaking changes */}
437-
{updateSummary.any_breaking && (
438-
<Alert
439-
variant="light"
440-
color="orange"
441-
radius="md"
442-
icon={<WarningAmberIcon style={{ fontSize: 18 }} />}
443-
title={t(
444-
"update.breakingChangesDetected",
445-
"Breaking Changes Detected",
446-
)}
447-
>
448-
{t(
449-
"update.breakingChangesMessage",
450-
"Some versions contain breaking changes. Please review the migration guides below before updating.",
451-
)}
452-
</Alert>
453-
)}
454-
455485
{/* Migration guides */}
456486
{updateSummary.migration_guides &&
457487
updateSummary.migration_guides.length > 0 && (
@@ -505,6 +535,7 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
505535
component="a"
506536
href={guide.url}
507537
target="_blank"
538+
onClick={handleExternalLink(guide.url)}
508539
variant="default"
509540
size="xs"
510541
rightSection={
@@ -603,7 +634,9 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
603634
variant="subtle"
604635
size="xs"
605636
px={6}
606-
onClick={(e) => e.stopPropagation()}
637+
onClick={handleExternalLink(
638+
`https://github.com/Stirling-Tools/Stirling-PDF/releases/tag/v${version.version}`,
639+
)}
607640
rightSection={
608641
<OpenInNewIcon style={{ fontSize: 11 }} />
609642
}
@@ -673,6 +706,10 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
673706
version.compatibility.migration_guide_url
674707
}
675708
target="_blank"
709+
onClick={handleExternalLink(
710+
version.compatibility
711+
.migration_guide_url ?? "",
712+
)}
676713
variant="light"
677714
color="orange"
678715
size="xs"
@@ -844,6 +881,7 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
844881
component="a"
845882
href={downloadUrl}
846883
target="_blank"
884+
onClick={handleExternalLink(downloadUrl)}
847885
variant="default"
848886
radius="md"
849887
size="md"
@@ -884,6 +922,7 @@ const UpdateModal: React.FC<UpdateModalProps> = ({
884922
component="a"
885923
href={downloadUrl}
886924
target="_blank"
925+
onClick={handleExternalLink(downloadUrl)}
887926
color="blue"
888927
radius="md"
889928
size="lg"

frontend/editor/src/core/components/shared/config/configSections/GeneralSection.tsx

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
ActionIcon,
1515
Button,
1616
Badge,
17-
Alert,
1817
} from "@mantine/core";
1918
import { useTranslation } from "react-i18next";
2019
import { usePreferences } from "@app/contexts/PreferencesContext";
@@ -459,26 +458,6 @@ const GeneralSection: React.FC<GeneralSectionProps> = ({
459458
/>
460459
</Stack>
461460
)}
462-
463-
{updateSummary?.any_breaking && (
464-
<Alert
465-
color="orange"
466-
title={t(
467-
"update.breakingChangesDetected",
468-
"Breaking Changes Detected",
469-
)}
470-
styles={{
471-
title: { fontWeight: 600 },
472-
}}
473-
>
474-
<Text size="sm">
475-
{t(
476-
"update.breakingChangesMessage",
477-
"Some versions contain breaking changes. Please review the migration guides before updating.",
478-
)}
479-
</Text>
480-
</Alert>
481-
)}
482461
</Stack>
483462
</Paper>
484463
)}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* core/web implementation of the @app/platform/openExternal seam.
3+
*
4+
* The OSS / self-hosted web build runs in a normal browser, so an external URL
5+
* just opens in a new tab. The desktop (Tauri) and saas leaves shadow this with
6+
* their own platform/openExternal.ts. This lives in core/ so the seam also
7+
* resolves for the core and proprietary build variants - whose `@app/*` maps to
8+
* src/core - since shared components (e.g. UpdateModal) import it.
9+
*/
10+
export const openExternal = async (url: string): Promise<void> => {
11+
window.open(url, "_blank", "noopener,noreferrer");
12+
};

frontend/editor/src/core/testing/serverExperienceSimulations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const FREE_LICENSE_INFO: LicenseInfo = {
3838

3939
const BASE_NO_LOGIN_CONFIG: AppConfig = {
4040
enableAnalytics: true,
41-
appVersion: "2.12.0",
41+
appVersion: "2.13.0",
4242
serverCertificateEnabled: false,
4343
enableAlphaFunctionality: false,
4444
serverPort: 8080,

frontend/editor/src/proprietary/testing/serverExperienceSimulations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const FREE_LICENSE_INFO: LicenseInfo = {
4848

4949
const BASE_NO_LOGIN_CONFIG: AppConfig = {
5050
enableAnalytics: true,
51-
appVersion: "2.12.0",
51+
appVersion: "2.13.0",
5252
serverCertificateEnabled: false,
5353
enableAlphaFunctionality: false,
5454
enableDesktopInstallSlide: true,

0 commit comments

Comments
 (0)