Browse Source

fix(webview): eliminate stale HTML caching, fix bootstrap locale routing, add client error logging bridge, and remove overlay barrier on mobile

staging
parent
commit
e90d78a2d3
  1. 12
      next.config.ts
  2. 2
      src/app/globals.css
  3. 27
      src/app/layout.tsx
  4. 18
      src/app/request-accepted/request-accepted-client.tsx

12
next.config.ts

@ -86,12 +86,20 @@ const nextConfig: NextConfig = {
], ],
}, },
{ {
// Application HTML shell – App Shell + Stale-While-Revalidate pattern for instant WebView rendering
// Application HTML pages – must never serve stale HTML so hashed JS chunks match current deployment
source: "/:path((?!api/|_next/|fonts/|assets/).*)", source: "/:path((?!api/|_next/|fonts/|assets/).*)",
headers: [ headers: [
{ {
key: "Cache-Control", key: "Cache-Control",
value: "public, max-age=0, stale-while-revalidate=86400",
value: "no-store, no-cache, must-revalidate, max-age=0",
},
{
key: "Pragma",
value: "no-cache",
},
{
key: "Expires",
value: "0",
}, },
], ],
}, },

2
src/app/globals.css

@ -265,6 +265,8 @@ a,
label, label,
[role="button"] { [role="button"] {
touch-action: manipulation; touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
pointer-events: auto;
} }
input, input,

27
src/app/layout.tsx

@ -304,9 +304,10 @@ export default async function RootLayout({
document.cookie = 'habib_language=' + encodeURIComponent(String(code)) + '; Path=/; Max-Age=31536000; SameSite=Lax' + secure; document.cookie = 'habib_language=' + encodeURIComponent(String(code)) + '; Path=/; Max-Age=31536000; SameSite=Lax' + secure;
root.lang = String(code); root.lang = String(code);
root.dir = (locale.isRTL || locale.isRtl || locale.is_rtl) ? 'rtl' : 'ltr'; root.dir = (locale.isRTL || locale.isRtl || locale.is_rtl) ? 'rtl' : 'ltr';
var knownLocales = ['fa', 'ar', 'en', 'ur', 'tr', 'ru', 'fr', 'es', 'de', 'id', 'bn', 'hi', 'pt', 'ha', 'sw', 'uz', 'az', 'tg', 'ks', 'zh', 'da', 'he', 'gu', 'ul'];
var segments = window.location.pathname.split('/'); var segments = window.location.pathname.split('/');
var currentCode = segments[1]; var currentCode = segments[1];
if (currentCode && currentCode !== String(code)) {
if (currentCode && knownLocales.indexOf(currentCode) !== -1 && currentCode !== String(code)) {
root.dataset.webBootstrap = 'pending'; root.dataset.webBootstrap = 'pending';
segments[1] = String(code); segments[1] = String(code);
window.location.replace(segments.join('/') + window.location.search + window.location.hash); window.location.replace(segments.join('/') + window.location.search + window.location.hash);
@ -317,6 +318,28 @@ export default async function RootLayout({
window.dispatchEvent(new CustomEvent('habib:bootstrap-ready', { detail: config })); window.dispatchEvent(new CustomEvent('habib:bootstrap-ready', { detail: config }));
} }
// Global Error Forwarding to Flutter Native Log Channel
function forwardErrorToFlutter(type, err) {
try {
var message = '[WEB_ERROR] ' + type + ': ' + (err && (err.stack || err.message || String(err)) || 'Unknown error');
console.error(message);
if (window.HabibApp && window.HabibApp.postMessage) {
window.HabibApp.postMessage(JSON.stringify({
action: 'client_log',
message: message
}));
}
} catch (e) {}
}
window.addEventListener('error', function(event) {
forwardErrorToFlutter('Runtime Error', event.error || event.message);
});
window.addEventListener('unhandledrejection', function(event) {
forwardErrorToFlutter('Unhandled Rejection', event.reason);
});
if (window.__HABIB_BOOTSTRAP__) { if (window.__HABIB_BOOTSTRAP__) {
apply(window.__HABIB_BOOTSTRAP__); apply(window.__HABIB_BOOTSTRAP__);
} }
@ -415,7 +438,7 @@ export default async function RootLayout({
var msg = '[WEB_DEEP_LIFECYCLE] [' + Date.now() + '] Event: ' + name + ' | visibility: ' + document.visibilityState + ' | hasFocus: ' + document.hasFocus() + ' | bodyBg: ' + bodyBg + ' | htmlBg: ' + htmlBg + (detail ? ' | ' + JSON.stringify(detail) : ''); var msg = '[WEB_DEEP_LIFECYCLE] [' + Date.now() + '] Event: ' + name + ' | visibility: ' + document.visibilityState + ' | hasFocus: ' + document.hasFocus() + ' | bodyBg: ' + bodyBg + ' | htmlBg: ' + htmlBg + (detail ? ' | ' + JSON.stringify(detail) : '');
console.log(msg); console.log(msg);
if (window.HabibApp && window.HabibApp.postMessage) { if (window.HabibApp && window.HabibApp.postMessage) {
window.HabibApp.postMessage(JSON.stringify({ action: 'debug_log', message: msg }));
window.HabibApp.postMessage(JSON.stringify({ action: 'client_log', message: msg }));
} }
} catch (e) {} } catch (e) {}
} }

18
src/app/request-accepted/request-accepted-client.tsx

@ -972,25 +972,7 @@ export default function RequestAcceptedClient() {
onGetAdvisor={openAdvisors} onGetAdvisor={openAdvisors}
/> />
<section className="pointer-events-none fixed bottom-0 left-1/2 z-20 w-full max-w-[834px] -translate-x-1/2 bg-[#F5F5F5]">
<div
style={{ paddingBottom: "calc(20px + var(--safe-bottom))" }}
className="pointer-events-auto px-[17px] md:px-8 pt-3"
>
<div className="flex items-center justify-center w-full gap-1 rounded-[11px] bg-[#DBDBDB] py-3.5">
<Image
src="/assets/images/material-symbols_lock.svg"
width={24}
height={24}
alt="lock"
/>
<h2 className="group-14 leading-none font-semibold text-[#747474]">
{t["Profile is locked"]}
</h2>
</div>
</div>
</section>
</div> </div>
</div> </div>
</main> </main>

Loading…
Cancel
Save