diff --git a/build.gradle b/build.gradle index 3dba68daa..a0d198c3a 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,8 @@ plugins { import com.github.jk1.license.render.* import org.gradle.internal.os.OperatingSystem +import org.panteleyev.jpackage.ImageType + import java.nio.file.Files import java.time.Year @@ -43,9 +45,19 @@ bootJar { enabled = false } +// Configure main class for the root project +springBoot { + mainClass = 'stirling.software.SPDF.SPDFApplication' +} + +repositories { + mavenCentral() + maven { url = 'https://build.shibboleth.net/maven/releases' } +} + allprojects { group = 'stirling.software' - version = '1.0.1' + version = '1.0.2' configurations.configureEach { exclude group: 'commons-logging', module: 'commons-logging' @@ -53,7 +65,6 @@ allprojects { } } - tasks.register('writeVersion') { def propsFile = file("$projectDir/common/src/main/resources/version.properties") def propsDir = propsFile.parentFile @@ -200,6 +211,14 @@ openApi { waitTimeInSeconds = 60 // Increase the wait time to 60 seconds } +// Configure the forked spring boot run task to properly delegate to the stirling-pdf module +tasks.named('forkedSpringBootRun') { + dependsOn ':stirling-pdf:bootRun' + doFirst { + println "Delegating forkedSpringBootRun to :stirling-pdf:bootRun" + } +} + //0.11.5 to 2024.11.5 static def getMacVersion(String version) { def currentYear = Year.now().getValue() @@ -251,7 +270,7 @@ jpackage { winUpgradeUuid = "2a43ed0c-b8c2-40cf-89e1-751129b87641" // Unique identifier for updates winHelpUrl = "https://github.com/Stirling-Tools/Stirling-PDF" winUpdateUrl = "https://github.com/Stirling-Tools/Stirling-PDF/releases" - type = "exe" + type = ImageType.EXE installDir = "C:/Program Files/Stirling-PDF" } @@ -259,7 +278,7 @@ jpackage { mac { appVersion = getMacVersion(project.version.toString()) icon = layout.projectDirectory.file("stirling-pdf/src/main/resources/static/favicon.icns") - type = "dmg" + type = ImageType.DMG macPackageIdentifier = "Stirling PDF" macPackageName = "Stirling PDF" macAppCategory = "public.app-category.productivity" @@ -281,7 +300,7 @@ jpackage { linux { appVersion = project.version icon = layout.projectDirectory.file("stirling-pdf/src/main/resources/static/favicon.png") - type = "deb" // Can also use "rpm" for Red Hat-based systems + type = ImageType.DEB // Can also use "rpm" for Red Hat-based systems // Debian package configuration //linuxPackageName = "stirlingpdf" @@ -514,6 +533,14 @@ swaggerhubUpload { } dependencies { + implementation project(':stirling-pdf') + implementation project(':common') + if (System.getenv('DISABLE_ADDITIONAL_FEATURES') != 'true' + || (project.hasProperty('DISABLE_ADDITIONAL_FEATURES') + && System.getProperty('DISABLE_ADDITIONAL_FEATURES') != 'true')) { + implementation project(':proprietary') + } + testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.12.2' } diff --git a/common/src/main/java/stirling/software/common/configuration/AppConfig.java b/common/src/main/java/stirling/software/common/configuration/AppConfig.java index 02614584b..b983769a8 100644 --- a/common/src/main/java/stirling/software/common/configuration/AppConfig.java +++ b/common/src/main/java/stirling/software/common/configuration/AppConfig.java @@ -21,6 +21,7 @@ import org.springframework.core.env.Environment; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; +import org.springframework.util.ClassUtils; import org.thymeleaf.spring6.SpringTemplateEngine; import lombok.Getter; @@ -148,23 +149,11 @@ public class AppConfig { } @Bean(name = "activeSecurity") - public boolean activeSecurity() { - String disableAdditionalFeatures = env.getProperty("DISABLE_ADDITIONAL_FEATURES"); - - if (disableAdditionalFeatures != null) { - // DISABLE_ADDITIONAL_FEATURES=true means security OFF, so return false - // DISABLE_ADDITIONAL_FEATURES=false means security ON, so return true - return !Boolean.parseBoolean(disableAdditionalFeatures); - } - - return env.getProperty("DOCKER_ENABLE_SECURITY", Boolean.class, true); - } - - @Bean(name = "missingActiveSecurity") - @ConditionalOnMissingClass( - "stirling.software.proprietary.security.configuration.SecurityConfiguration") public boolean missingActiveSecurity() { - return true; + return ClassUtils.isPresent( + "stirling.software.proprietary.security.configuration.SecurityConfiguration", + this.getClass().getClassLoader() + ); } @Bean(name = "directoryFilter") diff --git a/stirling-pdf/build.gradle b/stirling-pdf/build.gradle index 7014d25fe..0974a0577 100644 --- a/stirling-pdf/build.gradle +++ b/stirling-pdf/build.gradle @@ -146,5 +146,10 @@ bootJar { } } +// Configure main class for Spring Boot +springBoot { + mainClass = 'stirling.software.SPDF.SPDFApplication' +} + bootJar.dependsOn ':common:jar' bootJar.dependsOn ':proprietary:jar' diff --git a/stirling-pdf/src/main/resources/static/css/fileSelect.css b/stirling-pdf/src/main/resources/static/css/fileSelect.css index 88bef91d5..8a305e4b8 100644 --- a/stirling-pdf/src/main/resources/static/css/fileSelect.css +++ b/stirling-pdf/src/main/resources/static/css/fileSelect.css @@ -98,6 +98,61 @@ font-weight: bold; } +/* Responsive text sizing for drag & drop area */ +#fileInputText { + font-size: 16px; + font-weight: bold; + color: var(--md-sys-color-on-surface); + max-width: 100%; + padding: 0 10px; + box-sizing: border-box; +} + +/* Progressive font size reduction for high zoom levels */ +@media only screen and (max-width: 1280px) { + #fileInputText { + font-size: 15px; + } +} + +@media only screen and (max-width: 960px) { + #fileInputText { + font-size: 14px; + } +} + +@media only screen and (max-width: 768px) { + #fileInputText { + font-size: 13px; + } +} + +@media only screen and (max-width: 640px) { + #fileInputText { + font-size: 12px; + } +} + +@media only screen and (max-width: 480px) { + #fileInputText { + font-size: 11px; + line-height: 1.3; + } +} + +@media only screen and (max-width: 384px) { + #fileInputText { + font-size: 10px; + line-height: 1.4; + } + + /* Also scale the container at ultra-high zoom */ + .input-container { + height: 130px; + padding: 5px; + } +} + .file-input-btn { display: inline-block; diff --git a/stirling-pdf/src/main/resources/static/css/multi-tool.css b/stirling-pdf/src/main/resources/static/css/multi-tool.css index 92d7699b2..0f104be14 100644 --- a/stirling-pdf/src/main/resources/static/css/multi-tool.css +++ b/stirling-pdf/src/main/resources/static/css/multi-tool.css @@ -1,8 +1,11 @@ +/* Base Container Styles */ .multi-tool-container { - max-width: 95vw; - margin: 0 auto; + max-width: 100vw; + margin: 0; + padding: 0 20px; } +/* Form Elements */ label { text-align: left; display: block; @@ -17,6 +20,7 @@ label { flex-grow: 5; } +/* Action Bar Styles */ .mt-action-bar { display: flex; gap: 10px; @@ -28,16 +32,17 @@ label { padding: 1.25rem; border-radius: 2rem; margin: 0px 25px; - justify-content:center; + justify-content: center; } - -.mt-action-bar>* { +.mt-action-bar > * { padding-bottom: 0.5rem; } + .mt-file-uploader { - width:100% + width: 100%; } + .mt-action-bar svg, .mt-action-btn svg { width: 20px; @@ -50,20 +55,21 @@ label { gap: 10px; } +/* Action Button Styles */ .mt-action-btn { - position: sticky; - bottom: 10%; - margin: auto; - margin-bottom: 25px; + position: fixed; + bottom: 80px; + left: 50%; + transform: translateX(-50%); border-radius: 2rem; z-index: 12; - background-color: var(--md-sys-color-surface-container-low) ; + background-color: var(--md-sys-color-surface-container-low); display: flex; gap: 10px; - padding: 12px 0px 0px; width: fit-content; justify-content: center; - padding: 10px 20px + padding: 10px 20px; + transition: all 0.3s ease-in-out; } .mt-action-btn .btn { @@ -71,68 +77,132 @@ label { height: 3.5rem; border-radius: 20px; padding: 0; + position: relative; } +/* Card and Container Styles */ .bg-card { background-color: var(--md-sys-color-surface-5); border-radius: 3rem; - padding: 25px 0; + padding: 15px 0; + margin-left: 55px; + margin-right: 20px; + display: flex; + flex-direction: column; + align-items: stretch; } #pages-container-wrapper { width: 100%; display: flex; - flex-direction: column; - padding: 1rem; + justify-content: center; + padding: 0.75rem; border-radius: 25px; min-height: 275px; - margin: 0 0 30px 0; + margin: 0 0 20px 0; } #pages-container { - margin: 0 auto; - width: 95%; - font-size: 0; + display: inline-flex; + flex-wrap: wrap; + gap: 20px; + justify-content: flex-start; + width: fit-content; + max-width: 100%; } -/* width */ +/* Scrollbar Styles */ #pages-container-wrapper::-webkit-scrollbar { width: 10px; height: 10px; } -/* Track */ #pages-container-wrapper::-webkit-scrollbar-track { background: var(--scroll-bar-color); } -/* Handle */ #pages-container-wrapper::-webkit-scrollbar-thumb { border-radius: 10px; background: var(--scroll-bar-thumb); } -/* Handle on hover */ #pages-container-wrapper::-webkit-scrollbar-thumb:hover { background: var(--scroll-bar-thumb-hover); } - +/* Page Container Base Styles */ .page-container { display: inline-block; list-style-type: none; - width: 250px; - height: 250px; + width: 260px; + height: 260px; line-height: 50px; - margin: 15px 25px; + margin-top: 15px; box-sizing: border-box; text-align: center; aspect-ratio: 1; position: relative; user-select: none; - transition: width 1s linear; + transition: width 0.3s ease-in-out; } +/* Responsive Page Container Sizes */ +@media only screen and (max-width: 480px) { + .page-container { + width: calc(100vw - 90px); + height: calc(100vw - 90px); + max-width: 300px; + max-height: 300px; + margin: 5px auto; + } + #pages-container { gap: 10px; } +} + +@media only screen and (min-width: 481px) and (max-width: 768px) { + .page-container { + width: calc((100vw - 120px - 12px) / 2); + height: calc((100vw - 120px - 12px) / 2); + max-width: 250px; + max-height: 250px; + margin: 6px; + } + #pages-container { gap: 12px; } +} + +@media only screen and (min-width: 769px) and (max-width: 1199px) { + .page-container { + width: calc((100vw - 140px - 45px) / 3); + height: calc((100vw - 140px - 45px) / 3); + max-width: 220px; + max-height: 220px; + margin: 7px; + } + #pages-container { gap: 15px; } +} + +@media only screen and (min-width: 1200px) and (max-width: 1280px) { + .page-container { + width: calc((100vw - 160px - 60px) / 4); + height: calc((100vw - 160px - 60px) / 4); + max-width: 200px; + max-height: 200px; + margin: 8px; + } + #pages-container { gap: 17px; } +} + +@media only screen and (min-width: 1281px) { + .page-container { + width: calc((100vw - 180px - 80px) / 5); + height: calc((100vw - 180px - 80px) / 5); + max-width: 190px; + max-height: 190px; + margin: 10px; + } + #pages-container { gap: 20px; } +} + +/* Split Page Styles */ .page-container.split-before { border-left: 1px dashed var(--md-sys-color-on-surface); padding-left: -1px; @@ -146,56 +216,35 @@ label { display: none; } - +/* RTL Language Support */ .page-container:last-child:lang(ar), -/* Arabic */ .page-container:last-child:lang(he), -/* Hebrew */ .page-container:last-child:lang(fa), -/* Persian */ .page-container:last-child:lang(ur), -/* Urdu */ .page-container:last-child:lang(ckb), -/* Sorani Kurdish */ .page-container:last-child:lang(ks), -/* Kashmiri */ .page-container:last-child:lang(kk), -/* Kazakh */ .page-container:last-child:lang(uz), -/* Uzbek */ .page-container:last-child:lang(ky), -/* Kyrgyz */ .page-container:last-child:lang(bal), -/* Baluchi */ .page-container:last-child:lang(dv), -/* Divehi */ .page-container:last-child:lang(ps), -/* Pashto */ .page-container:last-child:lang(sdg), -/* Southern Kurdish */ .page-container:last-child:lang(syr), -/* Syriac */ .page-container:last-child:lang(mzn), -/* Mazanderani */ .page-container:last-child:lang(tgl), -/* Tagalog */ .page-container:last-child:lang(pnb), -/* Western Punjabi */ .page-container:last-child:lang(ug), -/* Uyghur */ .page-container:last-child:lang(nqo), -/* N'Ko */ -.page-container:last-child:lang(bqi) - -/* Bakhtiari */ - { +.page-container:last-child:lang(bqi) { margin-left: auto !important; margin-right: 0 !important; } +/* Page Image Styles */ .page-container img { - max-width: calc(100% - 15px); - max-height: calc(100% - 15px); + max-width: calc(100% - 8px); + max-height: calc(100% - 8px); display: block; position: absolute; left: 50%; @@ -206,10 +255,7 @@ label { transition: rotate 0.3s; } -#add-pdf-button { - margin: 0 auto; -} - +/* Page Number Styles */ .page-number { position: absolute; top: 5px; @@ -224,14 +270,20 @@ label { font-weight: 450; } +/* Tool Header and Button Styles */ .tool-header { - margin: 0.5rem 1rem 2rem; + margin: 0.5rem 1rem 1rem; } #select-pages-button { opacity: 0.5; } +#add-pdf-button { + margin: 0 auto; +} + +/* Selected Pages Container Styles */ .selected-pages-container { background-color: var(--md-sys-color-surface); border-radius: 16px; @@ -247,12 +299,42 @@ label { margin-bottom: 10px; } +.selected-pages-header { + margin-bottom: 15px; +} + +.selected-pages-header h5 { + margin: 0 0 8px 0 !important; + font-size: 1.1rem; + font-weight: 600; + color: var(--md-sys-color-on-surface); +} + +.selected-pages-header #csv-input { + width: 100%; + height: 2.5rem; + border-radius: 8px; + border: 1px solid var(--md-sys-color-outline); + background-color: var(--md-sys-color-surface); + color: var(--md-sys-color-on-surface); + padding: 0 12px; + font-size: 0.95rem; +} + +.selected-pages-header #csv-input:focus { + outline: none; + border-color: var(--md-sys-color-primary); + box-shadow: 0 0 0 2px rgba(var(--md-sys-color-primary-rgb), 0.2); +} + +/* Pages List Styles */ .pages-list { display: flex; flex-wrap: wrap; gap: 10px; padding: 0; list-style: none; + min-height: 0; max-height: 10rem; overflow: auto; } @@ -293,12 +375,251 @@ label { font-size: medium; } -.btn { - position: relative; +/* Zoom Level Responsive Styles */ +@media only screen and (min-width: 2000px) { + .mt-action-btn { + gap: 12px; + padding: 12px 24px; + border-radius: 2.5rem; + } + .mt-action-btn .btn { + width: 4rem; + height: 4rem; + border-radius: 22px; + } + .mt-action-btn .btn .material-symbols-rounded { + font-size: 1.7rem; + } } -@media only screen and (max-width: 767px) { #pages-container { width:300px; } } -@media only screen and (min-width: 768px) and (max-width: 991px) { #pages-container { width: 600px; } } -@media only screen and (min-width: 992px) and (max-width: 1199px) { #pages-container { width: 900px; } } -@media only screen and (min-width: 1200px) and (max-width: 1399px) { #pages-container { width: 900px; } } -@media only screen and (min-width: 1399px) { #pages-container { width: 1200px; } } \ No newline at end of file +@media only screen and (min-width: 2560px) { + .mt-action-btn { + gap: 15px; + padding: 15px 30px; + border-radius: 3rem; + } + .mt-action-btn .btn { + width: 5rem; + height: 5rem; + border-radius: 28px; + } + .mt-action-btn .btn .material-symbols-rounded { + font-size: 2.1rem; + } +} + +@media only screen and (min-width: 3840px) { + .mt-action-btn { + gap: 20px; + padding: 20px 40px; + border-radius: 4rem; + } + .mt-action-btn .btn { + width: 7rem; + height: 7rem; + border-radius: 40px; + } + .mt-action-btn .btn .material-symbols-rounded { + font-size: 3rem; + } +} + +@media only screen and (min-width: 7680px) { + .mt-action-btn { + gap: 40px; + padding: 40px 80px; + border-radius: 8rem; + } + .mt-action-btn .btn { + width: 14rem; + height: 14rem; + border-radius: 80px; + } + .mt-action-btn .btn .material-symbols-rounded { + font-size: 6rem; + } +} + +/* Zoom-responsive Sidebar Styles */ +@media only screen and (max-width: 1280px) { + .container { + position: relative; + } + + .mt-action-btn { + position: fixed !important; + left: 10px !important; + top: 80px !important; + bottom: 20px !important; + margin: 0 !important; + transform: none !important; + border-radius: 16px !important; + background-color: var(--md-sys-color-surface-container-low); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + backdrop-filter: blur(8px); + display: flex !important; + flex-direction: column !important; + align-items: center !important; + justify-content: center !important; + height: calc(100vh - 100px) !important; + overflow-y: auto !important; + scrollbar-width: none !important; + -ms-overflow-style: none !important; + z-index: 12; + width: 70px !important; + gap: 8px !important; + padding: 12px 8px !important; + box-sizing: border-box !important; + } + + .mt-action-btn:has(.btn:nth-last-child(n+7)) { + justify-content: flex-start !important; + } + + .mt-action-btn::-webkit-scrollbar { + display: none !important; + } + + .mt-action-btn .btn { + width: 48px !important; + height: 48px !important; + border-radius: 12px !important; + padding: 0 !important; + margin: 0 !important; + flex-shrink: 0; + font-size: 16px !important; + box-sizing: border-box !important; + } + + .mt-action-btn .btn .material-symbols-rounded { + font-size: 20px !important; + line-height: 1 !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; + width: 100% !important; + height: 100% !important; + font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24 !important; + } + + .multi-tool-container { + margin-left: 0 !important; + max-width: 100% !important; + } + + .mt-action-bar { + margin-left: 25px !important; + margin-right: 25px !important; + } + + .mt-action-btn:not(:has(*:nth-child(6))) { + justify-content: center !important; + } +} + +/* Mobile and High Zoom Responsive Styles */ +@media only screen and (max-width: 960px) { + .mt-action-btn { + left: 8px !important; + top: 75px !important; + bottom: 15px !important; + height: calc(100vh - 90px) !important; + } +} + +@media only screen and (max-width: 768px) { + .mt-action-btn { + left: 5px !important; + width: 60px !important; + top: calc(var(--navbar-height, 60px) + 10px) !important; + bottom: 10px !important; + height: calc(100vh - var(--navbar-height, 60px) - 20px) !important; + } + + .mt-action-btn .btn { + width: 40px !important; + height: 40px !important; + box-sizing: border-box !important; + } + + .mt-action-btn .btn .material-symbols-rounded { + font-size: 16px !important; + } + + #pages-container { + margin: 0 auto !important; + display: flex !important; + flex-wrap: wrap !important; + justify-content: center !important; + width: 100% !important; + } + + .page-container { + width: calc(100vw - 55px) !important; + height: calc(100vw - 60px) !important; + max-width: 350px !important; + max-height: 350px !important; + margin: 5px auto !important; + } +} + +@media only screen and (max-width: 480px) { + .mt-action-btn { + left: 2px !important; + top: calc(var(--navbar-height, 60px) + 5px) !important; + bottom: 5px !important; + height: calc(100vh - var(--navbar-height, 60px) - 10px) !important; + width: 50px !important; + gap: 6px !important; + padding: 10px 6px !important; + } + + .mt-action-btn .btn { + width: 32px !important; + height: 32px !important; + border-radius: 10px !important; + box-sizing: border-box !important; + } + + .mt-action-btn .btn .material-symbols-rounded { + font-size: 14px !important; + } +} + +@media only screen and (max-width: 384px) { + .mt-action-btn { + left: 2px !important; + top: calc(var(--navbar-height, 60px) + 5px) !important; + bottom: 5px !important; + height: calc(100vh - var(--navbar-height, 60px) - 10px) !important; + width: 40px !important; + gap: 4px !important; + padding: 8px 4px !important; + } + + .mt-action-btn .btn { + width: 28px !important; + height: 28px !important; + border-radius: 8px !important; + box-sizing: border-box !important; + } + + .mt-action-btn .btn .material-symbols-rounded { + font-size: 12px !important; + } + + .page-container { + width: calc(100vw - 55px) !important; + height: calc(100vw - 60px) !important; + max-width: 280px !important; + max-height: 280px !important; + margin: 3px auto !important; + } + + .page-container img { + max-width: calc(100% - 4px) !important; + max-height: calc(100% - 4px) !important; + } +} + + diff --git a/stirling-pdf/src/main/resources/static/css/navbar.css b/stirling-pdf/src/main/resources/static/css/navbar.css index 4e562bc3b..cf5bba667 100644 --- a/stirling-pdf/src/main/resources/static/css/navbar.css +++ b/stirling-pdf/src/main/resources/static/css/navbar.css @@ -63,6 +63,79 @@ transform: translateY(-2px); } +/* Responsive navbar brand - prevent hamburger from wrapping */ +.navbar-brand { + display: flex !important; + align-items: center; + gap: 8px; + min-width: 0; /* Allow shrinking */ +} + +.navbar-brand .icon-text { + font-size: 1.5rem; + font-weight: bold; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Progressive text shrinking to prevent hamburger wrap */ +@media only screen and (max-width: 480px) { + .navbar-brand .icon-text { + font-size: 1.3rem; + } + + .main-icon { + width: 32px; + height: 32px; + } +} + +@media only screen and (max-width: 420px) { + .navbar-brand .icon-text { + font-size: 1.1rem; + } + + .main-icon { + width: 28px; + height: 28px; + } +} + +@media only screen and (max-width: 380px) { + .navbar-brand .icon-text { + font-size: 1rem; + } + + .main-icon { + width: 24px; + height: 24px; + } +} + +@media only screen and (max-width: 340px) { + .navbar-brand .icon-text { + font-size: 0.9rem; + } + + .main-icon { + width: 20px; + height: 20px; + } +} + +/* Ultra-small screens - hide text, keep icon */ +@media only screen and (max-width: 320px) { + .navbar-brand .icon-text { + display: none; + } + + .main-icon { + width: 24px; + height: 24px; + } +} + .nav-icon { vertical-align: middle; font-size: 2rem !important; diff --git a/stirling-pdf/src/main/resources/static/js/downloader.js b/stirling-pdf/src/main/resources/static/js/downloader.js index 301b0411b..42ba0c357 100644 --- a/stirling-pdf/src/main/resources/static/js/downloader.js +++ b/stirling-pdf/src/main/resources/static/js/downloader.js @@ -2,6 +2,13 @@ if (window.isDownloadScriptInitialized) return; // Prevent re-execution window.isDownloadScriptInitialized = true; + // Global PDF processing count tracking for survey system + window.incrementPdfProcessingCount = function() { + let pdfProcessingCount = parseInt(localStorage.getItem('pdfProcessingCount') || '0'); + pdfProcessingCount++; + localStorage.setItem('pdfProcessingCount', pdfProcessingCount.toString()); + }; + const { pdfPasswordPrompt, multipleInputsForSingleRequest, @@ -312,6 +319,11 @@ pdf_pages: pageCount, }); } + + // Increment PDF processing count for survey tracking + if (success && typeof window.incrementPdfProcessingCount === 'function') { + window.incrementPdfProcessingCount(); + } } } diff --git a/stirling-pdf/src/main/resources/static/js/multitool/PdfContainer.js b/stirling-pdf/src/main/resources/static/js/multitool/PdfContainer.js index 90d130b2f..125801a0a 100644 --- a/stirling-pdf/src/main/resources/static/js/multitool/PdfContainer.js +++ b/stirling-pdf/src/main/resources/static/js/multitool/PdfContainer.js @@ -271,6 +271,11 @@ class PdfContainer { pdf_pages: pageCount, }); } + + // Increment PDF processing count for survey tracking + if (success && typeof window.incrementPdfProcessingCount === 'function') { + window.incrementPdfProcessingCount(); + } } catch { } } diff --git a/stirling-pdf/src/main/resources/static/js/pages/home.js b/stirling-pdf/src/main/resources/static/js/pages/home.js index bb1e1ad4a..a2673ef6c 100644 --- a/stirling-pdf/src/main/resources/static/js/pages/home.js +++ b/stirling-pdf/src/main/resources/static/js/pages/home.js @@ -66,19 +66,16 @@ document.addEventListener('DOMContentLoaded', function () { const dontShowAgain = document.getElementById('dontShowAgain'); const takeSurveyButton = document.getElementById('takeSurvey'); - const viewThresholds = [5, 10, 15, 22, 30, 50, 75, 100, 150, 200]; + const pdfProcessingThresholds = [8, 15, 22, 35, 50, 75, 100, 150]; - // Check if survey version changed and reset page views if it did + // Check if survey version changed and reset PDF processing count if it did const storedVersion = localStorage.getItem('surveyVersion'); if (storedVersion && storedVersion !== surveyVersion) { - localStorage.setItem('pageViews', '0'); + localStorage.setItem('pdfProcessingCount', '0'); localStorage.setItem('surveyVersion', surveyVersion); } - let pageViews = parseInt(localStorage.getItem('pageViews') || '0'); - - pageViews++; - localStorage.setItem('pageViews', pageViews.toString()); + let pdfProcessingCount = parseInt(localStorage.getItem('pdfProcessingCount') || '0'); function shouldShowSurvey() { if(!window.showSurvey) { @@ -90,11 +87,11 @@ document.addEventListener('DOMContentLoaded', function () { } // If survey version changed and we hit a threshold, show the survey - if (localStorage.getItem('surveyVersion') !== surveyVersion && viewThresholds.includes(pageViews)) { + if (localStorage.getItem('surveyVersion') !== surveyVersion && pdfProcessingThresholds.includes(pdfProcessingCount)) { return true; } - return viewThresholds.includes(pageViews); + return pdfProcessingThresholds.includes(pdfProcessingCount); } if (shouldShowSurvey()) { diff --git a/stirling-pdf/src/main/resources/templates/fragments/common.html b/stirling-pdf/src/main/resources/templates/fragments/common.html index 1bda883d2..d873fd7a1 100644 --- a/stirling-pdf/src/main/resources/templates/fragments/common.html +++ b/stirling-pdf/src/main/resources/templates/fragments/common.html @@ -35,7 +35,7 @@ const browserZoom = currentDPR / systemDPR; // Counter-scale to maintain same visual size - const isMobile = window.innerWidth <= 768 || /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + const isMobile = window.innerWidth <= 768 && /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); let baseScale = isMobile ? 3 : (isHighDPI ? 2.2 : 1.1); // Prioritize mobile scaling over high DPI const navScale = baseScale / currentDPR; // Dropdowns at 80% (20% smaller) @@ -81,6 +81,12 @@ console.log('DPR:', currentDPR, 'isHighDPI:', isHighDPI, 'baseScale:', baseScale, 'navScale:', navScale, 'effective width:', effectiveWidth); } + // Set CSS custom property for mobile navbar scaling (for sidebar positioning) + // Use the ACTUAL scaled height, not a fixed assumption + const baseHeight = 60; + const actualScaledHeight = baseHeight * navScale; + document.documentElement.style.setProperty('--navbar-height', `${actualScaledHeight}px`); + setTimeout(() => { const dropdowns = document.querySelectorAll('.dropdown-menu'); dropdowns.forEach(dropdown => { @@ -379,10 +385,10 @@ Browse