From 0e50be2d8d5a47b5c5a058b81cce8a67d4092957 Mon Sep 17 00:00:00 2001 From: Junjun Deng Date: Sun, 18 May 2025 21:04:21 +0800 Subject: [PATCH 1/9] feat: add promo banner --- public/index.html | 15 ++++++ public/scripts/main.js | 4 +- public/scripts/promo-banner.js | 52 +++++++++++++++++++ public/styles/promo-banner.css | 92 ++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 public/scripts/promo-banner.js create mode 100644 public/styles/promo-banner.css diff --git a/public/index.html b/public/index.html index 5896dfc..b7a15aa 100644 --- a/public/index.html +++ b/public/index.html @@ -42,6 +42,21 @@ + +
+
+
+ 🧠 Build your AI second brain with Rabrain – Save articles, voice memos, and build your knowledge base +
+ Try for Free + +
+
+
diff --git a/public/scripts/main.js b/public/scripts/main.js index 4883642..a5454a3 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -7,13 +7,15 @@ class PairDrop { this.$headerInstallBtn = $('install'); this.deferredStyles = [ - "styles/styles-deferred.css" + "styles/styles-deferred.css", + "styles/promo-banner.css" ]; this.deferredScripts = [ "scripts/browser-tabs-connector.js", "scripts/util.js", "scripts/network.js", "scripts/ui.js", + "scripts/promo-banner.js", "scripts/libs/heic2any.min.js", "scripts/libs/no-sleep.min.js", "scripts/libs/qr-code.min.js", diff --git a/public/scripts/promo-banner.js b/public/scripts/promo-banner.js new file mode 100644 index 0000000..c71f7db --- /dev/null +++ b/public/scripts/promo-banner.js @@ -0,0 +1,52 @@ +/** + * Promotional banner functionality + * Handles banner appearance, theme switching, and user preferences + */ +(function() { + // Wait for DOM to be fully loaded + document.addEventListener('DOMContentLoaded', function() { + const banner = document.getElementById('promo-banner'); + const closeButton = document.getElementById('promo-banner-close'); + + // Check if user has previously dismissed the banner + const bannerDismissed = localStorage.getItem('promo-banner-dismissed'); + + if (bannerDismissed === 'true') { + banner.classList.add('hidden'); + } else { + // Set initial theme + setThemeClass(); + + // Listen for theme changes + const themeObserver = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.attributeName === 'class') { + setThemeClass(); + } + }); + }); + + // Start observing the document body for class changes (theme changes) + themeObserver.observe(document.body, { attributes: true }); + + // Handle close button click + closeButton.addEventListener('click', function() { + banner.classList.add('hidden'); + localStorage.setItem('promo-banner-dismissed', 'true'); + }); + } + + // Set appropriate theme class based on body class + function setThemeClass() { + // Remove existing theme classes + banner.classList.remove('light-theme', 'dark-theme'); + + // Check if body has dark-theme class + if (document.body.classList.contains('dark-theme')) { + banner.classList.add('dark-theme'); + } else { + banner.classList.add('light-theme'); + } + } + }); +})(); diff --git a/public/styles/promo-banner.css b/public/styles/promo-banner.css new file mode 100644 index 0000000..3c1cd40 --- /dev/null +++ b/public/styles/promo-banner.css @@ -0,0 +1,92 @@ +/* Styles for the promotional banner */ +.promo-banner { + display: flex; + justify-content: center; + align-items: center; + padding: 8px 16px; + width: 100%; + box-sizing: border-box; + transition: all 0.3s ease; + z-index: 1000; + font-size: 14px; +} + +.promo-banner-content { + display: flex; + align-items: center; + justify-content: center; + flex-grow: 1; + gap: 12px; + max-width: 1200px; + text-align: center; +} + +.promo-banner-text { + flex-grow: 1; +} + +.promo-banner-cta { + white-space: nowrap; + padding: 6px 12px; + border-radius: 4px; + text-decoration: none; + font-weight: 500; + transition: all 0.2s ease; +} + +.promo-banner-close { + background: none; + border: none; + cursor: pointer; + padding: 4px; + display: flex; + align-items: center; + justify-content: center; + margin-left: 12px; + opacity: 0.7; + transition: opacity 0.2s ease; +} + +.promo-banner-close:hover { + opacity: 1; +} + +/* Light theme styles */ +.promo-banner.light-theme { + background-color: #f0f4ff; + color: #333; + border-bottom: 1px solid #e0e0ff; +} + +.promo-banner.light-theme .promo-banner-cta { + background-color: #3367d6; + color: white; +} + +.promo-banner.light-theme .promo-banner-cta:hover { + background-color: #2a58c3; +} + +/* Dark theme styles */ +.promo-banner.dark-theme { + background-color: #262b3d; + color: #e8eaed; + border-bottom: 1px solid #3a3f55; +} + +.promo-banner.dark-theme .promo-banner-cta { + background-color: #4285f4; + color: white; +} + +.promo-banner.dark-theme .promo-banner-cta:hover { + background-color: #5c9aff; +} + +/* Hidden state */ +.promo-banner.hidden { + max-height: 0; + padding: 0; + overflow: hidden; + border: none; +} \ No newline at end of file From 984b8aedf2cb5a1c971f4b8241c2444f0dbe6446 Mon Sep 17 00:00:00 2001 From: Junjun Deng Date: Sun, 18 May 2025 22:55:43 +0800 Subject: [PATCH 2/9] feat: update banner style --- public/styles/promo-banner.css | 101 ++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 39 deletions(-) diff --git a/public/styles/promo-banner.css b/public/styles/promo-banner.css index 3c1cd40..06a2769 100644 --- a/public/styles/promo-banner.css +++ b/public/styles/promo-banner.css @@ -1,37 +1,49 @@ /* Styles for the promotional banner */ .promo-banner { display: flex; - justify-content: center; - align-items: center; - padding: 8px 16px; width: 100%; - box-sizing: border-box; + background-color: var(--primary-color); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); transition: all 0.3s ease; - z-index: 1000; font-size: 14px; + margin: 0 0 8px 0; + position: relative; + z-index: 10; } .promo-banner-content { display: flex; align-items: center; - justify-content: center; - flex-grow: 1; - gap: 12px; + padding: 10px 16px; + width: 100%; max-width: 1200px; - text-align: center; + margin: 0 auto; + flex-wrap: wrap; } .promo-banner-text { - flex-grow: 1; + flex: 1; + margin-right: 16px; + line-height: 1.4; + color: white; + min-width: 200px; } .promo-banner-cta { white-space: nowrap; padding: 6px 12px; - border-radius: 4px; + border-radius: 6px; text-decoration: none; font-weight: 500; + margin: 4px 16px 4px 0; transition: all 0.2s ease; + background-color: white; + color: var(--primary-color); +} + +.promo-banner-cta:hover { + background-color: rgba(255, 255, 255, 0.9); + /* transform: translateY(-1px); */ } .promo-banner-close { @@ -42,51 +54,62 @@ display: flex; align-items: center; justify-content: center; - margin-left: 12px; - opacity: 0.7; + border-radius: 50%; + opacity: 0.8; transition: opacity 0.2s ease; + color: white; } .promo-banner-close:hover { opacity: 1; + background-color: rgba(255, 255, 255, 0.1); } /* Light theme styles */ .promo-banner.light-theme { - background-color: #f0f4ff; - color: #333; - border-bottom: 1px solid #e0e0ff; -} - -.promo-banner.light-theme .promo-banner-cta { - background-color: #3367d6; - color: white; -} - -.promo-banner.light-theme .promo-banner-cta:hover { - background-color: #2a58c3; + background-color: #4285f4; + background-image: linear-gradient(135deg, #4285f4, #5c9aff); } /* Dark theme styles */ .promo-banner.dark-theme { - background-color: #262b3d; - color: #e8eaed; - border-bottom: 1px solid #3a3f55; + background-color: #4285f4; + background-image: linear-gradient(135deg, #4285f4, #3367d6); } -.promo-banner.dark-theme .promo-banner-cta { - background-color: #4285f4; - color: white; +/* Hidden state */ +.promo-banner.hidden { + display: none; } -.promo-banner.dark-theme .promo-banner-cta:hover { - background-color: #5c9aff; +/* Responsive styles */ +@media (max-width: 768px) { + .promo-banner-content { + padding: 10px 12px; + } + + .promo-banner-text { + font-size: 13px; + } } -/* Hidden state */ -.promo-banner.hidden { - max-height: 0; - padding: 0; - overflow: hidden; - border: none; +@media (max-width: 600px) { + .promo-banner-content { + flex-direction: column; + align-items: flex-start; + } + + .promo-banner-text { + margin-bottom: 8px; + } + + .promo-banner-cta { + margin: 0 auto 0 0; + } + + .promo-banner-close { + position: absolute; + top: 8px; + right: 8px; + } } \ No newline at end of file From 9ac7322ba89440f453582c00d30861875a0c3f83 Mon Sep 17 00:00:00 2001 From: Junjun Deng Date: Sun, 18 May 2025 23:18:17 +0800 Subject: [PATCH 3/9] fix: loading banner script --- public/scripts/promo-banner.js | 85 ++++++++++++++++------------------ 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/public/scripts/promo-banner.js b/public/scripts/promo-banner.js index c71f7db..3de6e0a 100644 --- a/public/scripts/promo-banner.js +++ b/public/scripts/promo-banner.js @@ -2,51 +2,48 @@ * Promotional banner functionality * Handles banner appearance, theme switching, and user preferences */ -(function() { - // Wait for DOM to be fully loaded - document.addEventListener('DOMContentLoaded', function() { - const banner = document.getElementById('promo-banner'); - const closeButton = document.getElementById('promo-banner-close'); - - // Check if user has previously dismissed the banner - const bannerDismissed = localStorage.getItem('promo-banner-dismissed'); - - if (bannerDismissed === 'true') { +(function () { + const banner = document.getElementById('promo-banner'); + const closeButton = document.getElementById('promo-banner-close'); + + // Check if user has previously dismissed the banner + const bannerDismissed = localStorage.getItem('promo-banner-dismissed'); + + if (bannerDismissed === 'true') { + banner.classList.add('hidden'); + } else { + // Set initial theme + setThemeClass(); + + // Listen for theme changes + const themeObserver = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + if (mutation.attributeName === 'class') { + setThemeClass(); + } + }); + }); + + // Start observing the document body for class changes (theme changes) + themeObserver.observe(document.body, { attributes: true }); + + // Handle close button click + closeButton.addEventListener('click', function () { banner.classList.add('hidden'); + localStorage.setItem('promo-banner-dismissed', 'true'); + }); + } + + // Set appropriate theme class based on body class + function setThemeClass() { + // Remove existing theme classes + banner.classList.remove('light-theme', 'dark-theme'); + + // Check if body has dark-theme class + if (document.body.classList.contains('dark-theme')) { + banner.classList.add('dark-theme'); } else { - // Set initial theme - setThemeClass(); - - // Listen for theme changes - const themeObserver = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - if (mutation.attributeName === 'class') { - setThemeClass(); - } - }); - }); - - // Start observing the document body for class changes (theme changes) - themeObserver.observe(document.body, { attributes: true }); - - // Handle close button click - closeButton.addEventListener('click', function() { - banner.classList.add('hidden'); - localStorage.setItem('promo-banner-dismissed', 'true'); - }); - } - - // Set appropriate theme class based on body class - function setThemeClass() { - // Remove existing theme classes - banner.classList.remove('light-theme', 'dark-theme'); - - // Check if body has dark-theme class - if (document.body.classList.contains('dark-theme')) { - banner.classList.add('dark-theme'); - } else { - banner.classList.add('light-theme'); - } + banner.classList.add('light-theme'); } - }); + } })(); From 986186da38fe1600a188b60509e914307f12fef9 Mon Sep 17 00:00:00 2001 From: Junjun Deng Date: Sun, 18 May 2025 23:28:14 +0800 Subject: [PATCH 4/9] feat: add promo banner styles and script to service worker cache --- public/service-worker.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/service-worker.js b/public/service-worker.js index e1f4f45..8d86216 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -6,6 +6,7 @@ const relativePathsToCache = [ 'manifest.json', 'styles/styles-main.css', 'styles/styles-deferred.css', + 'styles/promo-banner.css', 'scripts/browser-tabs-connector.js', 'scripts/localization.js', 'scripts/main.js', @@ -14,6 +15,7 @@ const relativePathsToCache = [ 'scripts/ui.js', 'scripts/ui-main.js', 'scripts/util.js', + 'scripts/promo-banner.js', 'scripts/worker/canvas-worker.js', 'scripts/libs/heic2any.min.js', 'scripts/libs/no-sleep.min.js', From 86afe91966f8ae3f4710888f8c69679cef8d5cdc Mon Sep 17 00:00:00 2001 From: lilac Date: Thu, 9 Oct 2025 21:49:55 +0800 Subject: [PATCH 5/9] feat: update promo banner content and styles for Vita AI --- public/index.html | 4 ++-- public/styles/promo-banner.css | 37 ++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/public/index.html b/public/index.html index b7a15aa..48a4600 100644 --- a/public/index.html +++ b/public/index.html @@ -46,9 +46,9 @@
- 🧠 Build your AI second brain with Rabrain – Save articles, voice memos, and build your knowledge base + 🤖 Hire an AI QA Engineer that never sleeps – Automate your testing with Vita AI's autonomous agents
-
Try for Free + Get Early Access