🎉 New Year Sale is LIVE! Use code NEWYEAR25 for 25% OFF | Free Shipping on orders above ₹999

Search
Shopping Cart

Your cart is empty

Continue Shopping
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring
  • SKU: K-rose gold projector
  • Availability: in stock Many in stock Out of stock You can purchase this product but it's out of stock

Maizic Smarthome Rose 2X Android Smart Projector | 13.0 OS | 950S Chip | Native 800P, Supports 1080P & 4K | 4D & Auto Keystone | Netflix, Prime, Wi-Fi, Bluetooth | Screen Mirroring

Rs. 3,599.00 Rs. 7,959.00
Tax included. Shipping calculated at checkout.
DESCRIPTION

Shop Maizic Rose 2X Smart Projector with Android 13, 800P Native, 4K Support, Auto Keystone, Netflix, Prime, WiFi, Bluetooth & Screen Mirroring.

  • Native 800P Resolution with 1080p & 4K Decoding Support: Delivers sharp, high-contrast visuals with a native resolution of 1280x800 pixels, enhanced by hardware decoding capabilities for Full HD (1920x1080) and Ultra HD 4K (3840x2160) content. Ideal for large-screen entertainment without visual distortion.
  • Advanced 950S Smart Chipset + Android 13.0 OS: Powered by the 950S Quad-Core ARM Cortex-A53 processor and the latest Android 13.0, ensuring smoother UI navigation, faster app launch times, better app compatibility, and more secure system updates.
  • Automatic Keystone Correction + 4D Manual Adjustment: Equipped with smart auto-keystone correction (vertical), plus 4D digital keystone calibration (±45° horizontal and vertical), enabling distortion-free image alignment even in corner or angled placements.
  • 180° Rotating Integrated Stand: Features an adjustable mechanical stand built into the housing, offering 180-degree tilt range for ceiling, wall, or rear projection. Offers unmatched flexibility without external mounts or tripods.
  • Dual-Band WiFi (2.4GHz & 5GHz) + Bluetooth Connectivity: Stream lag-free on both WiFi bands, with stronger throughput and lower interference. Bluetooth 4.2 allows seamless pairing with external Bluetooth speakers, headphones, gamepads, or input devices.
  • Built-In OTT Apps: Netflix, Prime Video, YouTube & More: Pre-installed certified apps provide native access to popular streaming platforms. No need for third-party dongles—stream straight from the projector with just Wi-Fi.
  • Multi-Platform Wireless Screen Mirroring: Compatible with Miracast, DLNA, and AirPlay protocols, allowing screen casting from Android smartphones, iPhones, Windows laptops, or tablets—perfect for mobile gaming, office presentations, and education apps.
  • 1-Year Warranty: Built with premium-grade components, passive cooling vents, and low-noise fans. Comes with 1-year manufacturer warranty, backed by Maizic Smarthome after-sales support and service network.
ADDITIONAL INFORMATION

RELATED PRODUCTS

Buy on WhatsApp

Complete Your Setup

Add a compatible memory card and save with our exclusive bundle deal

Best Value
Maizic smarthomes 32GB Class 10 MicroSD Memory Card | High-Speed UHS-I SDXC Card with Adapter | Full HD Video, Photo & App Storage for Smartphones, Tablets, Action Cameras, CCTV & More

Maizic smarthomes 32GB Class 10 MicroSD Memory Card | High-Speed UHS-I SDXC Card with Adapter | Full HD Video, Photo & App Storage for Smartphones, Tablets, Action Cameras, CCTV & More

Maizic 128GB Class 10 MicroSD Memory Card is your perfect...

Regular: Rs. 349.00

Bundle: Rs. 348.99

Save Rs. 0.01

UNiTECH 64GB MicroSD Card – UHS-I SDXC with Adapter | High-Speed, Full HD, Waterproof, Shockproof | For Smartphones, Tablets, CCTV & Action Cams

UNiTECH 64GB MicroSD Card – UHS-I SDXC with Adapter | High-Speed, Full HD, Waterproof, Shockproof | For Smartphones, Tablets, CCTV & Action Cams

Upgrade your device storage with the UNiTECH 64GB UHS-I M...

Regular: Rs. 999.00

Bundle: Rs. 998.99

Save Rs. 0.01

UNiTECH 128GB MicroSD Card – UHS-I SDXC with Adapter | High-Speed, Full HD, Waterproof, Shockproof | For Smartphones, Tablets, CCTV & Action Cams

UNiTECH 128GB MicroSD Card – UHS-I SDXC with Adapter | High-Speed, Full HD, Waterproof, Shockproof | For Smartphones, Tablets, CCTV & Action Cams

Upgrade your device storage with the UNiTECH 128GB UHS-I ...

Regular: Rs. 1,699.00

Bundle: Rs. 1,698.99

Save Rs. 0.01

Bundle Total: Rs. 3,599.00

You Save: Rs. 0.00

BACK TO TOP
", defaultCountry, geoCountries.includes(defaultCountry) ); return geoCountries.includes(defaultCountry); }; const startOTPObserverIfEligible = async () => { const shouldRunOTP = await checkDefaultCountry(); if (shouldRunOTP) { codkLog("observePreOrderOTPEnabled running"); observePreOrderOTPEnabled(); } else { codkLog("OTP observer skipped due to geo restrictions."); enableNormalCheckout(); } }; try { console.log( "%c████████████ COD King 2 ████████████", "font-weight: bold; font-size: 14px; background: red; color: white; padding: 4px 8px; border-radius: 4px;" ); disableNormalCheckout(); setTimeout(async function () { codkLog("before calling setting from extension"); let settings; const settingsChanged = sessionStorage.getItem("codk_settings_changed"); const settingsStr = sessionStorage.getItem("settingSession"); if (settingsChanged || !settingsStr) { if (settingsChanged) { sessionStorage.removeItem("codk_settings_changed"); codkLog("Metafield changed - calling fetchSettings() to update settingSession"); } const response = await fetchSettings(); if (response) { const newSettings = codkMapSettingsToCamel({ ...response, routeUrl: ROUTE_URL.replace(/\/$/, ""), shopDomain: window.Shopify.shop, }); sessionStorage.setItem("settingSession", JSON.stringify(newSettings)); startOTPObserverIfEligible(); if (newSettings?.partialPaymentEnabled === true) { callPartialRuleSets(); callPartialDummyVariantId(); } settings = newSettings; } else { codkLog("Failed to load settings from server."); enableNormalCheckout(); return; } } else { settings = JSON.parse(settingsStr); const needsMigration = settings && !("enablePreOrderOtp" in settings) && "enable_pre_order_otp" in settings; if (needsMigration) { const migratedSettings = codkMapSettingsToCamel(settings); sessionStorage.setItem( "settingSession", JSON.stringify(migratedSettings) ); settings = migratedSettings; } startOTPObserverIfEligible(); if (settings?.partialPaymentEnabled === true) { const ruleSets = JSON.parse(sessionStorage.getItem("ruleSets")); if (!ruleSets) { callPartialRuleSets(); } const variantId = sessionStorage.getItem("partialDummyVariantId"); if (!variantId) { callPartialDummyVariantId(); } } } if (settings?.partialPaymentEnabled === true) { initProductHiding(); } loadScript(); }, 10); } catch (e) { codkLog("Error Loading OTP Box, Please reach out to us via chat bubble"); enableNormalCheckout(); } })(); }; const initSvelteApp = function(buttonBlocking, settings) { window.codkInitSvelteApp = () => initSvelteApp(buttonBlocking, settings); if (typeof window.codkingRouteUrl === 'undefined' || !window.codkingRouteUrl || window.codkingRouteUrl.trim() === '') { console.error("❌ ROUTE_URL is empty in initSvelteApp!"); if (buttonBlocking) buttonBlocking.removeButtonListeners(); return; } const ROUTE_URL = window.codkingRouteUrl; const DEBUG = false; const codkLog = (msg, ...args) => { if (DEBUG) console.log(`[notifik_svelte.liquid] ${msg}`, ...args); }; codkLog("***************************** notifik_svelte.liquid loaded (SKELETON) *****************************"); codkLog("✅ web_ux_version is 2, initializing Svelte app"); if (!buttonBlocking) { console.error("❌ buttonBlocking not provided to initSvelteApp!"); return; } const isMobile = () => { const viewportWidth = window.parent && window.parent !== window ? window.parent.innerWidth : window.innerWidth; return viewportWidth <= 640; }; const showIframe = (iframe) => { if (!iframe) return; iframe.setAttribute('data-visible', 'true'); try { if (!window.codkOtpModalOpen) { const parentWindow = window.parent || window; parentWindow.dispatchEvent(new Event("codking:otpModalOpened")); window.codkOtpModalOpen = true; codkLog("📣 Dispatched codking:otpModalOpened"); const hideCartDrawerFallback = function() { try { const cartDrawerLayouts = getCartDrawerLayouts(); for (const selector of cartDrawerLayouts) { try { const element = document.querySelector(selector); if (!element) continue; const elementAny = element; if (typeof elementAny.close === "function") { try { elementAny.close(); codkLog(" 🔒 Fallback: Closed via " + selector + ".close()"); return true; } catch (e) { codkLog(" ⚠️ Fallback: " + selector + ".close() failed:", e); } } const dialog = element.querySelector("dialog[open]"); if (dialog) { try { dialog.close(); dialog.removeAttribute("open"); codkLog(" 🔒 Fallback: Closed dialog inside " + selector); return true; } catch (e) { codkLog(" ⚠️ Fallback: Failed to close dialog in " + selector + ":", e); } } if (element.tagName === "DIALOG" && element.hasAttribute("open")) { try { element.close(); element.removeAttribute("open"); codkLog(" 🔒 Fallback: Closed dialog " + selector); return true; } catch (e) { codkLog(" ⚠️ Fallback: Failed to close dialog " + selector + ":", e); } } } catch (e) { codkLog(" ⚠️ Fallback: Invalid selector " + selector + ":", e); } } return false; } catch (e) { codkLog("⚠️ Fallback hide failed:", e); return false; } }; hideCartDrawerFallback(); const tryHideDrawer = function(attempt) { try { if (typeof parentWindow.codkingHideDrawer === "function") { parentWindow.codkingHideDrawer(); codkLog("📣 Called codkingHideDrawer() directly"); return; } } catch (e) {} if ((attempt || 0) < 40) { setTimeout(function() { tryHideDrawer((attempt || 0) + 1); }, 50); } }; tryHideDrawer(0); } } catch (e) { } codkLog("✅ Iframe shown (CSS from Svelte)"); }; const hideIframe = (iframe) => { if (!iframe) return; iframe.setAttribute('data-visible', 'false'); try { if (window.codkOtpModalOpen) { (window.parent || window).dispatchEvent(new Event("codking:otpModalClosed")); window.codkOtpModalOpen = false; codkLog("📣 Dispatched codking:otpModalClosed"); } } catch (e) { } codkLog("✅ Iframe hidden (CSS from Svelte)"); }; if (!window.codkIframeDestroyListenerAdded) { window.codkIframeDestroyListenerAdded = true; window.addEventListener('message', (event) => { if ( event.data && typeof event.data === 'object' && event.data.type === 'CODK_REQUEST_META_ATTRIBUTION' ) { try { var targetIframe = document.getElementById('codk-full-modal-svelte'); if (!targetIframe || !targetIframe.contentWindow) return; if (event.source !== targetIframe.contentWindow) return; var payload = (typeof window.codkGetMetaClickData === 'function') ? window.codkGetMetaClickData() : {}; targetIframe.contentWindow.postMessage( { type: 'CODK_SET_META_ATTRIBUTION', payload: payload }, '*' ); } catch (e) {} return; } if ( event.data && typeof event.data === 'object' && event.data.type === 'CODK_DESTROY_IFRAME' ) { const iframeId = event.data.iframeId || 'codk-full-modal-svelte'; const targetIframe = document.getElementById(iframeId); if (targetIframe && targetIframe.parentNode) { codkLog("🧹 Removing iframe via CODK_DESTROY_IFRAME message:", iframeId); targetIframe.parentNode.removeChild(targetIframe); try { if (window.codkOtpModalOpen) { (window.parent || window).dispatchEvent(new Event("codking:otpModalClosed")); window.codkOtpModalOpen = false; codkLog("📣 Dispatched codking:otpModalClosed (destroy)"); } } catch (e) { } } else { codkLog("ℹ️ CODK_DESTROY_IFRAME: iframe not found (maybe already removed)", iframeId); } const wrapper = document.getElementById('codk-modal-wrapper'); if (wrapper) { wrapper.setAttribute('data-visible', 'false'); wrapper.style.display = 'none'; } iframe = null; window.codkSvelteInitialized = false; window.codkingSvelteReady = false; window.codkSvelteAppMounted = false; window.codkModalShowingSpinner = false; setTimeout(() => { iframe = ensureIframe(); if (typeof window.codkInitSvelteApp === "function") { window.codkInitSvelteApp(); } }, 50); return; } if ( event.data && typeof event.data === 'object' && event.data.type === 'CODK_REDIRECT_TO_CHECKOUT' ) { codkLog("🚀 Received CODK_REDIRECT_TO_CHECKOUT message"); if (typeof enableNormalCheckout === "function") { enableNormalCheckout(); } try { window.location.href = "/checkout"; } catch (redirectError) { console.warn("[app-embed.liquid] ⚠️ Parent redirect failed:", redirectError); } return; } }); } const ensureIframe = () => { let iframeElement = document.getElementById('codk-full-modal-svelte'); if (!iframeElement) { iframeElement = document.createElement('iframe'); iframeElement.id = 'codk-full-modal-svelte'; iframeElement.setAttribute('data-visible', 'false'); document.body.appendChild(iframeElement); codkLog("✅ Iframe created (CSS handled by Svelte)", { isMobile: isMobile() }); } else { codkLog("⏸️ Iframe already exists - reusing existing iframe"); } return iframeElement; }; let iframe = ensureIframe(); if (window.codkSvelteInitialized) { codkLog("⏸️ Svelte app already initialized - skipping duplicate initialization"); } else { window.codkSvelteInitialized = true; const initializeSvelteApp = () => { try { if (iframe.contentWindow && iframe.contentWindow.codkingSvelteReady) { codkLog("⏸️ Svelte app already ready in iframe - skipping initialization"); return; } try { const iframeDoc = iframe.contentWindow.document; if (iframeDoc && iframeDoc.body) { const existingScript = iframeDoc.querySelector('script[type="module"][src*="notifik_svelte"]'); if (existingScript) { codkLog("⏸️ Script tag already exists in iframe - skipping initialization (app may be loading)"); return; } } } catch (e) { codkLog("⚠️ Could not check iframe document (may not be ready yet):", e.message); } codkLog("🚀 Initializing iframe with Svelte app..."); const iframeDoc = iframe.contentWindow.document; iframeDoc.open(); const bodyStyle = isMobile() ? 'margin:0;padding:0;background:transparent;height:100vh;' : 'margin:0;padding:0;background:transparent;height:auto;min-height:100%;'; const htmlStyle = isMobile() ? 'background:transparent;height:100%;' : 'background:transparent;height:auto;min-height:100%;'; window.codkSvelteAppMounted = false; var SVELTE_JS_URL = "https://cdn.shopify.com/s/files/1/0743/3119/3628/files/svellte_production_js.js?v=1780136295"; var SVELTE_CSS_URL = "https://cdn.shopify.com/s/files/1/0743/3119/3628/files/svelte_production_css.css?v=1780136286"; iframeDoc.write( '' + '' + 'COD King OTP' + '' + '' + '
' + '<\/scr' + 'ipt>' + '' ); iframeDoc.close(); codkLog("✅ Svelte app initialized and loading in background"); codkLog("🔗 JS URL: " + SVELTE_JS_URL); } catch (error) { codkLog("❌ ERROR initializing Svelte:", error); } }; window.codkReinitSvelteIframe = function() { var f = document.getElementById('codk-full-modal-svelte'); if (!f || !f.contentWindow) return; window.codkSvelteAppMounted = false; var cacheBust = '_ri=' + Date.now(); try { var doc = f.contentWindow.document; doc.open(); var bodyStyle = isMobile() ? 'margin:0;padding:0;background:transparent;height:100vh;' : 'margin:0;padding:0;background:transparent;height:auto;min-height:100%;'; var htmlStyle = isMobile() ? 'background:transparent;height:100%;' : 'background:transparent;height:auto;min-height:100%;'; var SVELTE_JS_URL = "https://cdn.shopify.com/s/files/1/0743/3119/3628/files/svellte_production_js.js?v=1780136295"; var SVELTE_CSS_URL = "https://cdn.shopify.com/s/files/1/0743/3119/3628/files/svelte_production_css.css?v=1780136286"; var jsSep = SVELTE_JS_URL.indexOf('?') === -1 ? '?' : '&'; var cssSep = SVELTE_CSS_URL.indexOf('?') === -1 ? '?' : '&'; doc.write('COD King OTP<\/head>
<\/div><\/scr' + 'ipt><\/body><\/html>'); doc.close(); codkLog("✅ Iframe reinitialized - Svelte script reloading (cache-bust: " + cacheBust + ")"); } catch (e) { codkLog("❌ Error reinitializing iframe:", e); } }; codkLog("🚀 Pre-loading Svelte app on page load..."); initializeSvelteApp(); } window.addEventListener('codking-svelte-ready', () => { codkLog("✅ Svelte app is ready!"); }); if (!window.__codkPageshowListenerAdded) { window.__codkPageshowListenerAdded = true; window.addEventListener('pageshow', function(event) { if (!event.persisted) return; codkLog("🔄 Page restored from bfcache - checking Svelte status..."); document.body.style.overflow = ''; document.body.style.position = ''; document.body.style.width = ''; document.body.style.top = ''; var currentIframe = document.getElementById('codk-full-modal-svelte'); var svelteWorking = false; try { svelteWorking = currentIframe && currentIframe.contentWindow && currentIframe.contentWindow.appStore && window.codkingSvelteReady; } catch (e) {} if (svelteWorking) { codkLog("✅ Svelte still functional after bfcache restore"); hideIframe(currentIframe); return; } codkLog("⚠️ Svelte not functional after bfcache restore - performing full reinit..."); if (currentIframe && currentIframe.parentNode) { currentIframe.parentNode.removeChild(currentIframe); } iframe = null; window.codkSvelteInitialized = false; window.codkingSvelteReady = false; window.codkSvelteAppMounted = false; window.codkModalShowingSpinner = false; window.codkOtpModalOpen = false; iframe = ensureIframe(); try { var iframeDoc = iframe.contentWindow.document; var cacheBust = '_bfc=' + Date.now(); var bodyStyle = isMobile() ? 'margin:0;padding:0;background:transparent;height:100vh;' : 'margin:0;padding:0;background:transparent;height:auto;min-height:100%;'; var htmlStyle = isMobile() ? 'background:transparent;height:100%;' : 'background:transparent;height:auto;min-height:100%;'; window.codkSvelteAppMounted = false; iframeDoc.open(); iframeDoc.write( '' + '' + 'COD King OTP' + '' + '
' + '<\/scr' + 'ipt>' + '' ); iframeDoc.close(); window.codkSvelteInitialized = true; codkLog("✅ Fresh Svelte initialization triggered after bfcache restore (cache-bust: " + cacheBust + ")"); } catch (e) { codkLog("❌ Error during bfcache Svelte reinit:", e); } }); } let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { const iframe = document.getElementById('codk-full-modal-svelte'); if (iframe && iframe.getAttribute('data-visible') === 'true') { const mobile = isMobile(); if (mobile) { try { if (iframe.contentWindow && iframe.contentWindow.document) { iframe.contentWindow.document.documentElement.style.height = '100%'; iframe.contentWindow.document.body.style.height = '100vh'; } } catch (e) { } } else { try { if (iframe.contentWindow && iframe.contentWindow.document) { iframe.contentWindow.document.documentElement.style.height = 'auto'; iframe.contentWindow.document.documentElement.style.minHeight = '100%'; iframe.contentWindow.document.body.style.height = 'auto'; iframe.contentWindow.document.body.style.minHeight = '100%'; } } catch (e) { } } codkLog("✅ Iframe document styles updated on resize", { isMobile: mobile, viewportWidth: window.innerWidth }); } }, 150); }); codkLog("🔵 TDD Phase 1: Adding button blocking..."); const showSpinner = function() { iframe = iframe || document.getElementById('codk-full-modal-svelte'); if (!iframe) { codkLog("❌ Iframe missing when trying to show spinner. Reinitializing..."); window.codkSvelteInitialized = false; if (typeof window.codkInitSvelteApp === "function") { window.codkInitSvelteApp(); } return; } if (!iframe.contentWindow || !iframe.contentWindow.document) { codkLog("⚠️ Iframe document unavailable. Reinitializing..."); window.codkSvelteInitialized = false; if (typeof window.codkInitSvelteApp === "function") { window.codkInitSvelteApp(); } return; } codkLog("🔵 TDD Phase 2: Showing spinner (Svelte already loading in background)..."); window.codkModalShowingSpinner = true; window.codkSvelteAppMounted = false; const iframeDoc = iframe.contentWindow.document; const appDiv = iframeDoc.getElementById('app'); if (appDiv) { appDiv.innerHTML = '' + '
' + '' + '
' + '
Loading...
' + '
'; codkLog("✅ Spinner injected into #app (Svelte keeps loading in background)"); } else { codkLog("❌ #app div not found!"); } window.codkScrollY = window.scrollY || 0; document.body.style.overflow = 'hidden'; document.body.style.position = 'fixed'; document.body.style.width = '100%'; document.body.style.top = '-' + window.codkScrollY + 'px'; const mobile = isMobile(); if (mobile) { try { if (iframe.contentWindow && iframe.contentWindow.document) { iframe.contentWindow.document.documentElement.style.height = '100%'; iframe.contentWindow.document.body.style.height = '100vh'; } } catch (e) { } } else { try { if (iframe.contentWindow && iframe.contentWindow.document) { iframe.contentWindow.document.documentElement.style.height = 'auto'; iframe.contentWindow.document.documentElement.style.minHeight = '100%'; iframe.contentWindow.document.body.style.height = 'auto'; iframe.contentWindow.document.body.style.minHeight = '100%'; } } catch (e) { } } showIframe(iframe); codkLog("✅ Spinner shown!"); }; const updateMessage = function(message) { codkLog("🔵 TDD Phase 3: Updating message to:", message); if (!iframe || !iframe.contentWindow) { codkLog("⚠️ Iframe or contentWindow not available (e.g. during redirect), skipping update"); return; } const iframeDoc = iframe.contentWindow.document; const messageEl = iframeDoc.querySelector('.message'); if (messageEl) { messageEl.innerHTML = message; codkLog("✅ Message updated!"); } else { codkLog("❌ Message element not found!"); } }; const checkSvelteStatus = function() { codkLog("🔵 TDD Phase 3: Checking if Svelte is ready..."); if (window.codkingSvelteReady) { codkLog("✅ Svelte is ready!"); updateMessage(""); } else { codkLog("⏳ Svelte is NOT ready yet, keeping Loading... message"); } }; const clearSpinner = function() { window.codkModalShowingSpinner = false; codkLog("🔵 Clearing spinner HTML..."); try { if (!iframe || !iframe.contentWindow) { codkLog("⚠️ Iframe or contentWindow not available (e.g. during redirect), skipping clearSpinner"); return; } const iframeDoc = iframe.contentWindow.document; const appDiv = iframeDoc.getElementById('app'); if (appDiv) { const spinnerContainer = appDiv.querySelector('.container'); const spinnerStyle = iframeDoc.querySelector('style'); const svelteMounted = iframe.contentWindow && iframe.contentWindow.appStore; if (spinnerContainer) { codkLog("⚠️ Spinner container still present", { svelteMounted: !!svelteMounted, appDivChildren: appDiv.children.length }); if (!svelteMounted) { codkLog("⚠️ Svelte not mounted yet, clearing spinner to allow mount..."); appDiv.innerHTML = ''; codkLog("✅ Spinner cleared - Svelte can now mount"); } else { codkLog("✅ Svelte is mounted, removing spinner container only..."); spinnerContainer.remove(); codkLog("✅ Spinner container removed"); } } if (spinnerStyle && spinnerStyle.textContent.includes('.container')) { spinnerStyle.remove(); codkLog("✅ Spinner style tag removed"); } const computedStyle = iframeDoc.defaultView.getComputedStyle(appDiv); if (computedStyle.position === 'fixed' && computedStyle.zIndex === '999999') { appDiv.style.cssText = ''; codkLog("✅ #app spinner styles reset"); } if (!spinnerContainer && !spinnerStyle) { codkLog("✅ Spinner already cleared by Svelte"); } } else { codkLog("⚠️ #app div not found"); } } catch (error) { codkLog("⚠️ Error clearing spinner:", error); } }; window.addEventListener('codking-svelte-ready', function() { codkLog("🎉 TDD Phase 3: Received 'codking-svelte-ready' event!"); requestAnimationFrame(function() { clearSpinner(); setTimeout(function() { clearSpinner(); }, 50); }); }); const closeModal = function(isManualClose = true) { window.codkModalShowingSpinner = false; if (window.codkSvelteReadyPollId) { clearInterval(window.codkSvelteReadyPollId); window.codkSvelteReadyPollId = null; } codkLog("🔵 ========== CLOSING MODAL ==========", { isManualClose }); const iframeElement = document.getElementById('codk-full-modal-svelte'); if (!iframeElement) { codkLog("❌ CRITICAL: iframe element not found!"); return; } if (iframeElement !== iframe) { codkLog("⚠️ WARNING: iframe variable doesn't match DOM element!"); } const scrollY = window.codkScrollY || 0; codkLog("🔵 Saved scroll position:", scrollY); codkLog("🔵 Hiding iframe (CSS from Svelte)..."); hideIframe(iframe); document.body.style.removeProperty('overflow'); document.body.style.removeProperty('position'); document.body.style.removeProperty('width'); document.body.style.removeProperty('top'); document.body.style.removeProperty('height'); if (document.documentElement) { document.documentElement.style.removeProperty('overflow'); document.documentElement.style.removeProperty('position'); document.documentElement.style.removeProperty('width'); document.documentElement.style.removeProperty('height'); } codkLog("🔵 Body styles cleared"); if (scrollY > 0) { window.scrollTo(0, scrollY); codkLog("🔵 Scrolled to:", scrollY); } else { window.scrollTo(0, 0); codkLog("🔵 Scrolled to top"); } try { if (iframe && iframe.contentWindow && iframe.contentWindow.appStore) { setTimeout(function() { iframe.contentWindow.appStore.update(function(state) { return { ...state, isOpen: false }; }); codkLog("✅ Svelte modal state updated to closed"); }, 0); } } catch (error) { codkLog("⚠️ Could not update Svelte store:", error); } if (typeof window.codkIsProcessing !== 'undefined') { window.codkIsProcessing = false; } window.codkScrollY = 0; codkLog("✅ ========== MODAL CLOSE COMPLETE =========="); }; window.addEventListener('message', function(event) { codkLog("🔵 Received message from iframe:", event.data, event.origin); var closeModalMessage = event.data === 'codk-close-modal' || (Array.isArray(event.data) && event.data[0] === 'codk-close-modal'); if (closeModalMessage) { if (window.codkModalShowingSpinner === true) { codkLog("⏳ Ignoring 'codk-close-modal' while spinner is showing (Svelte not ready yet) - keeps modal open on Safari/redirect"); return; } codkLog("✅ Received 'codk-close-modal' message - calling closeModal()"); closeModal(true); return; } if (event.data && typeof event.data === 'object' && event.data.type === 'codking:reattachButtonBlock') { if (buttonBlocking && typeof buttonBlocking.observeButtons === 'function') { buttonBlocking.observeButtons(); codkLog("✅ Re-attached button block listeners (cart drawer mutation from Svelte)"); } return; } if (event.data && typeof event.data === 'object' && !Array.isArray(event.data) && event.data.type === 'codk-iframe-height') { const iframe = document.getElementById('codk-full-modal-svelte'); if (iframe && iframe.getAttribute('data-visible') === 'true' && !event.data.isMobile) { const height = event.data.height; const maxHeight = Math.min(height, window.innerHeight * 0.9); iframe.style.height = maxHeight + 'px'; codkLog("✅ Updated iframe height from content:", { contentHeight: height, appliedHeight: maxHeight, viewportHeight: window.innerHeight }); } return; } if (Array.isArray(event.data) && event.data.length >= 1 && (event.data[0] === 'null' || event.data[0] == null)) { return; } codkLog("ℹ️ Ignoring message (not recognized):", event.data); }); if (!window.__codkScrollYDefined) { let _codkScrollY = 0; Object.defineProperty(window, 'codkScrollY', { get: function() { return _codkScrollY; }, set: function(value) { _codkScrollY = value; }, configurable: true }); window.__codkScrollYDefined = true; } function isShopifyBuyNowButton(buttonElement) { if (!buttonElement) { return false; } const productButtonSelectors = COD_BUTTON_SELECTORS.BUY_NOW; const isBuyNowButton = productButtonSelectors.some(function(selector) { return buttonElement.matches(selector); }); const isBuyNowClass = buttonElement.classList.contains("shopify-payment-button__button") && buttonElement.classList.contains( "shopify-payment-button__button--unbranded" ); const parentElement = buttonElement.closest("shopify-buy-it-now-button"); const hasBuyNowAttributes = parentElement && parentElement.hasAttribute("access-token") && parentElement.hasAttribute("buyer-country") && parentElement.hasAttribute("buyer-currency"); return isBuyNowButton || isBuyNowClass || hasBuyNowAttributes; } function resolveShopifyBuyNowButtonFromClick(clickedButton) { if (!clickedButton || typeof clickedButton.closest !== "function") { return null; } // Any click inside Shopify's custom element (including inner overlays) var host = clickedButton.closest("shopify-buy-it-now-button"); if (host) { var innerBtn = host.querySelector("button.shopify-payment-button__button") || host.querySelector("button[class*='shopify-payment-button__button']"); if (innerBtn && isShopifyBuyNowButton(innerBtn)) { return innerBtn; } } // Optional: some themes (e.g. TPO) add .tpo-buy-it-now-btn — most shops do not. // When absent, the user clicks the real button and checkShopifyBuyNowButtons() // returns true on the first isShopifyBuyNowButton(clickedButton) check. // TPO overlay sits as sibling of shopify-accelerated-checkout, so querySelector // from the overlay never finds the
tag 4. Save. Done. HOW IT WORKS: • Appears 7 seconds after page load • Shows only ONCE per user (uses localStorage) • Email capture required before spin • Generates a unique discount code shown on win • Auto-copies code to clipboard • Mobile responsive (wheel scales down on small screens) ⚠️ DISCOUNT CODES: The codes shown (SPIN10, SPIN15, etc.) must be CREATED MANUALLY in: Shopify Admin → Discounts → Create discount → set code name to match. ========================================================= -->