FlutterFlow custom code.
(minus the code)
+ Custom widgets and actions, expertly crafted, fully reviewed and +ready to deploy to your project in one click.
+ +diff --git a/app.js b/app.js index 2a520a6..5503148 100644 --- a/app.js +++ b/app.js @@ -9621,7 +9621,7 @@ function initExactShell() { mobile.addEventListener("change", order); } -function setGenerationStageVisible(visible) { +function setGenerationStageVisible(visible, { preservePanel = false } = {}) { const stage = document.getElementById("generation-stage"); if (!stage) return; const hero = document.getElementById("hero"); @@ -9632,6 +9632,9 @@ function setGenerationStageVisible(visible) { stage.classList.add("is-active"); } else { cancelPipelineMorph(); + // Returning to the composer retires the Home restoration marker, even + // after a run has settled. Only navigation preserves a hidden panel. + if (!preservePanel) document.getElementById("main-stage-container")?.classList.remove("visible"); document.body.classList.remove("results-fullscreen", "results-with-sidebar"); stage.classList.remove("is-active"); stage.inert = true; @@ -9705,6 +9708,7 @@ function switchView(view, pushState = true, moveFocus = true) { } else { document.getElementById("results-view")?.classList.remove("visible"); document.getElementById("ready-state")?.classList.remove("hidden"); + document.getElementById("main-stage-container")?.classList.remove("visible"); } } } @@ -9729,10 +9733,16 @@ function switchView(view, pushState = true, moveFocus = true) { }); // Generation overlay only belongs to the home surface. - if (view !== "home") setGenerationStageVisible(false); + if (view !== "home") setGenerationStageVisible(false, { preservePanel: true }); else { const stage = document.getElementById("main-stage-container"); - if (stage && stage.classList.contains("visible")) setGenerationStageVisible(true); + if (stage && stage.classList.contains("visible")) { + // Navigation hides the surface, not the retained result or selected tab. + if (document.getElementById("results-view")?.classList.contains("visible")) { + document.body.classList.add("results-fullscreen", "results-with-sidebar"); + } + setGenerationStageVisible(true); + } } if (pushState) { diff --git a/dist/assets/index-CrZGgSTH.js b/dist/assets/index-vWxoLxnc.js similarity index 99% rename from dist/assets/index-CrZGgSTH.js rename to dist/assets/index-vWxoLxnc.js index a9ff094..3782cd6 100644 --- a/dist/assets/index-CrZGgSTH.js +++ b/dist/assets/index-vWxoLxnc.js @@ -325,4 +325,4 @@ Error: ${g} `}).join(""),i.onclick=s=>{const o=s.target.closest(".artifact-tab");o?.dataset?.artifactId&&Tc(o.dataset.artifactId)},Ud()),e&&e.classList.add("visible")}function Ud(){const t=document.getElementById("bundle-strip");!t||t.dataset.tabKeyboard==="bound"||(t.dataset.tabKeyboard="bound",t.addEventListener("keydown",e=>{if(e.defaultPrevented)return;const n=[document.getElementById("results-summary-tab"),...Array.from(document.querySelectorAll("#artifact-tabs .artifact-tab"))].filter(Boolean);if(!n.length||!n.includes(document.activeElement))return;let i=-1;const r=n.indexOf(document.activeElement);if(e.key==="ArrowRight")i=(r+1)%n.length;else if(e.key==="ArrowLeft")i=(r-1+n.length)%n.length;else if(e.key==="Home")i=0;else if(e.key==="End")i=n.length-1;else return;e.preventDefault();const s=n[i];if(!s)return;if(s.id==="results-summary-tab")fg();else{const a=s.dataset.artifactId;a&&Tc(a)}const o=s.id==="results-summary-tab"?document.getElementById("results-summary-tab"):document.querySelector(`#artifact-tabs .artifact-tab[data-artifact-id="${s.dataset.artifactId}"]`);o&&o.focus()}))}function Pr(){document.body.classList.add("results-fullscreen"),document.body.classList.add("results-with-sidebar");const t=document.getElementById("results-view"),e=document.getElementById("results-code-output"),n=document.getElementById("results-audit-output"),i=document.getElementById("results-summary-detail"),r=document.getElementById("artifact-results-split"),s=Hb(),o=fc();if(i&&(i.setAttribute("role","tabpanel"),i.setAttribute("aria-labelledby","results-summary-tab")),r){r.setAttribute("role","tabpanel");const a=s?.artifacts?.find(l=>l.id===_.selectedArtifactId);r.setAttribute("aria-labelledby",a?`artifact-tab-${a.id}`:"results-summary-tab")}zb(s),Gb(s),e&&(e.textContent=""),e&&(e.replaceChildren(),o.split(` -`).forEach((a,l)=>{const u=document.createElement("span");u.className="code-line",u.innerHTML=lp(a),!Ob()&&_.resultsViewMode==="file"&&(u.classList.add("is-in"),u.style.setProperty("--d",`${l*10}ms`),u.addEventListener("animationend",()=>u.classList.remove("is-in"),{once:!0})),e.appendChild(u)})),n&&(n.innerHTML=Vb(s)),i&&i.classList.toggle("hidden",_.resultsViewMode!=="summary"),r&&r.classList.toggle("hidden",_.resultsViewMode!=="file"),t&&t.classList.add("visible")}function Fr(t,e){const n=document.getElementById("main-stage-container"),i=E0(n),r=document.body.classList.contains("results-fullscreen");Ar(),document.getElementById("pipeline-progress")?.classList.remove("visible"),Wt(!0),_.selectedArtifactId||(_.selectedArtifactId=_i(_.artifactBundle).id),_.resultsViewMode="summary",document.body.classList.add("results-fullscreen");const s=document.getElementById("step3-output");s&&(s.textContent=""),Pr(),vn(),Kb(),r||up(i,n,["#bundle-strip",".summary-heading",".review-summary-text",".summary-spec",".review-score-column",".results-action-bar"].map(o=>document.querySelector(o)),{results:!0})}function Kb(){const t=document.getElementById("btn-feedback-up"),e=document.getElementById("btn-feedback-down"),n=document.getElementById("results-feedback-status");t&&(t.className="feedback-btn",t.setAttribute("aria-pressed","false"),t.disabled=!1,t.removeAttribute("aria-disabled")),e&&(e.className="feedback-btn",e.setAttribute("aria-pressed","false"),e.disabled=!1,e.removeAttribute("aria-disabled")),n&&(n.textContent=""),El=!1}function Tc(t){_.selectedArtifactId=t,_.resultsViewMode="file",Pr()}function fg(){_.resultsViewMode="summary",Pr()}function Yb(){const t=document.getElementById("btn-copy-results"),e=document.getElementById("results-copy-status"),n=fc(),i=(r,s)=>{e&&(e.textContent=r,e.classList.toggle("ok",!!s),e.classList.toggle("fail",!s))};if(!navigator.clipboard?.writeText){i("Copying isn't supported in this browser.",!1);return}navigator.clipboard.writeText(n).then(()=>{if(i("Copied to clipboard",!0),t){t.classList.add("copied");const r=t.querySelector("span");if(r){const s=r.textContent;r.textContent="Copied!",setTimeout(()=>{t.classList.remove("copied"),r.textContent=s},2e3)}}}).catch(()=>{i("Clipboard permission was denied. Select the code to copy it manually.",!1)})}let El=!1;async function Jb(t){const e=document.getElementById("btn-feedback-up"),n=document.getElementById("btn-feedback-down"),i=document.getElementById("results-feedback-status");if(!e||!n||El)return;const r=l=>{i&&(i.textContent="",i.offsetWidth,i.textContent=l)},s=l=>{El=l,[e,n].forEach(u=>{u.disabled=l,u.setAttribute("aria-disabled",String(l))})},o=t==="up"?"thumbsUp":"thumbsDown";s(!0),r("Submitting review feedback…");const a={type:o,code:_.step2Result,input:_.step1Result};try{const l=await Ec(a.type,a.code,a.input);if(!l||l.success!==!0){s(!1),r("Review feedback could not be sent. Tap again to retry.");return}e.classList.toggle("active-up",t==="up"),n.classList.toggle("active-down",t==="down"),e.setAttribute("aria-pressed",String(t==="up")),n.setAttribute("aria-pressed",String(t==="down")),s(!1),r("Review feedback saved.")}catch{s(!1),r("Review feedback could not be sent. Tap again to retry.")}}function Zb(){const t=document.getElementById("error-input-panel");if(t){t.classList.remove("hidden"),t.style.display="flex";const e=document.getElementById("ff-error-paste-input");e&&setTimeout(()=>e.focus(),100)}}function hg(){const t=document.getElementById("error-input-panel");t&&(t.classList.add("hidden"),t.style.display="none")}function Xb(){const t=document.getElementById("shell-stage"),e=document.getElementById("main-stage-container"),n=e?.querySelector(".pipeline-prompt-recap"),i=window.matchMedia("(max-width: 920px)"),r=()=>t?.style.setProperty("--fit",Math.min(1,document.documentElement.clientWidth/1920)),s=()=>{if(!n)return;const o=n.contains(document.activeElement)?document.activeElement:null;i.matches?e.appendChild(n):e.prepend(n),o?.focus({preventScroll:!0})};r(),s(),window.addEventListener("resize",r),i.addEventListener("change",s)}function Wt(t){const e=document.getElementById("generation-stage");if(!e)return;const n=document.getElementById("hero");n&&(n.hidden=t,n.inert=t),t?(e.hidden=!1,e.inert=!1,e.classList.add("is-active")):(An(),document.body.classList.remove("results-fullscreen","results-with-sidebar"),e.classList.remove("is-active"),e.inert=!0,e.hidden=!0)}function pg(){const t=H.isVerified&&!!H.email,e=he.tier||"free",n=t&&ki(),i=!t||Ht(),s=n?"Checking…":i?Ul[e]||"Free":"—",o=document.getElementById("topbar-plan");o&&(o.textContent=s);const a=document.getElementById("topbar-avatar");a&&(a.textContent=(H.email||"?")[0].toUpperCase()),xc();const l=document.getElementById("plans-free-current");l&&l.classList.toggle("hidden",e!=="free"||!i);const u=document.getElementById("plans-checkout-btn-professional");if(u){const d=e==="professional"&&i;u.disabled=d,u.textContent=d?"Current plan":"Subscribe"}const c=document.getElementById("plans-checkout-btn-power");if(c){const d=e==="power"&&i;c.disabled=d,c.textContent=d?"Current plan":"Subscribe"}}function Qb(){pg();const t=document.getElementById("credits-modal");t&&Ke(t)}function eE(t){if(t&&t.target!==t.currentTarget)return;const e=document.getElementById("credits-modal");e&&Ye(e)}function gg(t,e=!0,n=!0){if(t=["home","account","plans"].includes(t)?t:"home",document.body.dataset.shellView=t,t!=="home"&&(An(),ec?.cancelTyping?.(),_.isRunning&&(og(),Gp(),_.isRunning=!1,Gs(!1),Ci(),_.artifactBundle?Pr():(document.getElementById("results-view")?.classList.remove("visible"),document.getElementById("ready-state")?.classList.remove("hidden")))),document.querySelectorAll(".view[data-view]").forEach(r=>{r.dataset.view===t?(r.hidden=!1,r.removeAttribute("inert"),requestAnimationFrame(()=>{r.classList.add("is-active"),n&&r.focus({preventScroll:!0})})):(r.classList.remove("is-active"),r.setAttribute("inert","true"),setTimeout(()=>{r.classList.contains("is-active")||(r.hidden=!0)},260))}),t!=="home")Wt(!1);else{const r=document.getElementById("main-stage-container");r&&r.classList.contains("visible")&&Wt(!0)}if(e){const r=t==="home"?"":`#${t}`;window.location.hash!==r&&window.history.pushState({view:t},"",r||"#")}}let Hd=!1;function Mc(){const t=window.location.hash.replace(/^#/,"");gg(t||"home",!1,Hd),Hd=!0}window.addEventListener("popstate",t=>{Mc()});window.addEventListener("hashchange",()=>{Mc()});window.copyResultsCode=Yb;window.selectArtifact=Tc;window.selectResultsSummary=fg;window.submitResultsFeedback=Jb;window.showErrorInputPanel=Zb;window.hideErrorInputPanel=hg;window.setGenerationStageVisible=Wt;window.switchView=gg;window.selectPipelineStage=Lb;window.editPipelinePrompt=bl;window.retryPipelineRun=ug;window.openCreditsModal=Qb;window.closeCreditsModal=eE; +`).forEach((a,l)=>{const u=document.createElement("span");u.className="code-line",u.innerHTML=lp(a),!Ob()&&_.resultsViewMode==="file"&&(u.classList.add("is-in"),u.style.setProperty("--d",`${l*10}ms`),u.addEventListener("animationend",()=>u.classList.remove("is-in"),{once:!0})),e.appendChild(u)})),n&&(n.innerHTML=Vb(s)),i&&i.classList.toggle("hidden",_.resultsViewMode!=="summary"),r&&r.classList.toggle("hidden",_.resultsViewMode!=="file"),t&&t.classList.add("visible")}function Fr(t,e){const n=document.getElementById("main-stage-container"),i=E0(n),r=document.body.classList.contains("results-fullscreen");Ar(),document.getElementById("pipeline-progress")?.classList.remove("visible"),Wt(!0),_.selectedArtifactId||(_.selectedArtifactId=_i(_.artifactBundle).id),_.resultsViewMode="summary",document.body.classList.add("results-fullscreen");const s=document.getElementById("step3-output");s&&(s.textContent=""),Pr(),vn(),Kb(),r||up(i,n,["#bundle-strip",".summary-heading",".review-summary-text",".summary-spec",".review-score-column",".results-action-bar"].map(o=>document.querySelector(o)),{results:!0})}function Kb(){const t=document.getElementById("btn-feedback-up"),e=document.getElementById("btn-feedback-down"),n=document.getElementById("results-feedback-status");t&&(t.className="feedback-btn",t.setAttribute("aria-pressed","false"),t.disabled=!1,t.removeAttribute("aria-disabled")),e&&(e.className="feedback-btn",e.setAttribute("aria-pressed","false"),e.disabled=!1,e.removeAttribute("aria-disabled")),n&&(n.textContent=""),El=!1}function Tc(t){_.selectedArtifactId=t,_.resultsViewMode="file",Pr()}function fg(){_.resultsViewMode="summary",Pr()}function Yb(){const t=document.getElementById("btn-copy-results"),e=document.getElementById("results-copy-status"),n=fc(),i=(r,s)=>{e&&(e.textContent=r,e.classList.toggle("ok",!!s),e.classList.toggle("fail",!s))};if(!navigator.clipboard?.writeText){i("Copying isn't supported in this browser.",!1);return}navigator.clipboard.writeText(n).then(()=>{if(i("Copied to clipboard",!0),t){t.classList.add("copied");const r=t.querySelector("span");if(r){const s=r.textContent;r.textContent="Copied!",setTimeout(()=>{t.classList.remove("copied"),r.textContent=s},2e3)}}}).catch(()=>{i("Clipboard permission was denied. Select the code to copy it manually.",!1)})}let El=!1;async function Jb(t){const e=document.getElementById("btn-feedback-up"),n=document.getElementById("btn-feedback-down"),i=document.getElementById("results-feedback-status");if(!e||!n||El)return;const r=l=>{i&&(i.textContent="",i.offsetWidth,i.textContent=l)},s=l=>{El=l,[e,n].forEach(u=>{u.disabled=l,u.setAttribute("aria-disabled",String(l))})},o=t==="up"?"thumbsUp":"thumbsDown";s(!0),r("Submitting review feedback…");const a={type:o,code:_.step2Result,input:_.step1Result};try{const l=await Ec(a.type,a.code,a.input);if(!l||l.success!==!0){s(!1),r("Review feedback could not be sent. Tap again to retry.");return}e.classList.toggle("active-up",t==="up"),n.classList.toggle("active-down",t==="down"),e.setAttribute("aria-pressed",String(t==="up")),n.setAttribute("aria-pressed",String(t==="down")),s(!1),r("Review feedback saved.")}catch{s(!1),r("Review feedback could not be sent. Tap again to retry.")}}function Zb(){const t=document.getElementById("error-input-panel");if(t){t.classList.remove("hidden"),t.style.display="flex";const e=document.getElementById("ff-error-paste-input");e&&setTimeout(()=>e.focus(),100)}}function hg(){const t=document.getElementById("error-input-panel");t&&(t.classList.add("hidden"),t.style.display="none")}function Xb(){const t=document.getElementById("shell-stage"),e=document.getElementById("main-stage-container"),n=e?.querySelector(".pipeline-prompt-recap"),i=window.matchMedia("(max-width: 920px)"),r=()=>t?.style.setProperty("--fit",Math.min(1,document.documentElement.clientWidth/1920)),s=()=>{if(!n)return;const o=n.contains(document.activeElement)?document.activeElement:null;i.matches?e.appendChild(n):e.prepend(n),o?.focus({preventScroll:!0})};r(),s(),window.addEventListener("resize",r),i.addEventListener("change",s)}function Wt(t,{preservePanel:e=!1}={}){const n=document.getElementById("generation-stage");if(!n)return;const i=document.getElementById("hero");i&&(i.hidden=t,i.inert=t),t?(n.hidden=!1,n.inert=!1,n.classList.add("is-active")):(An(),e||document.getElementById("main-stage-container")?.classList.remove("visible"),document.body.classList.remove("results-fullscreen","results-with-sidebar"),n.classList.remove("is-active"),n.inert=!0,n.hidden=!0)}function pg(){const t=H.isVerified&&!!H.email,e=he.tier||"free",n=t&&ki(),i=!t||Ht(),s=n?"Checking…":i?Ul[e]||"Free":"—",o=document.getElementById("topbar-plan");o&&(o.textContent=s);const a=document.getElementById("topbar-avatar");a&&(a.textContent=(H.email||"?")[0].toUpperCase()),xc();const l=document.getElementById("plans-free-current");l&&l.classList.toggle("hidden",e!=="free"||!i);const u=document.getElementById("plans-checkout-btn-professional");if(u){const d=e==="professional"&&i;u.disabled=d,u.textContent=d?"Current plan":"Subscribe"}const c=document.getElementById("plans-checkout-btn-power");if(c){const d=e==="power"&&i;c.disabled=d,c.textContent=d?"Current plan":"Subscribe"}}function Qb(){pg();const t=document.getElementById("credits-modal");t&&Ke(t)}function eE(t){if(t&&t.target!==t.currentTarget)return;const e=document.getElementById("credits-modal");e&&Ye(e)}function gg(t,e=!0,n=!0){if(t=["home","account","plans"].includes(t)?t:"home",document.body.dataset.shellView=t,t!=="home"&&(An(),ec?.cancelTyping?.(),_.isRunning&&(og(),Gp(),_.isRunning=!1,Gs(!1),Ci(),_.artifactBundle?Pr():(document.getElementById("results-view")?.classList.remove("visible"),document.getElementById("ready-state")?.classList.remove("hidden"),document.getElementById("main-stage-container")?.classList.remove("visible")))),document.querySelectorAll(".view[data-view]").forEach(r=>{r.dataset.view===t?(r.hidden=!1,r.removeAttribute("inert"),requestAnimationFrame(()=>{r.classList.add("is-active"),n&&r.focus({preventScroll:!0})})):(r.classList.remove("is-active"),r.setAttribute("inert","true"),setTimeout(()=>{r.classList.contains("is-active")||(r.hidden=!0)},260))}),t!=="home")Wt(!1,{preservePanel:!0});else{const r=document.getElementById("main-stage-container");r&&r.classList.contains("visible")&&(document.getElementById("results-view")?.classList.contains("visible")&&document.body.classList.add("results-fullscreen","results-with-sidebar"),Wt(!0))}if(e){const r=t==="home"?"":`#${t}`;window.location.hash!==r&&window.history.pushState({view:t},"",r||"#")}}let Hd=!1;function Mc(){const t=window.location.hash.replace(/^#/,"");gg(t||"home",!1,Hd),Hd=!0}window.addEventListener("popstate",t=>{Mc()});window.addEventListener("hashchange",()=>{Mc()});window.copyResultsCode=Yb;window.selectArtifact=Tc;window.selectResultsSummary=fg;window.submitResultsFeedback=Jb;window.showErrorInputPanel=Zb;window.hideErrorInputPanel=hg;window.setGenerationStageVisible=Wt;window.switchView=gg;window.selectPipelineStage=Lb;window.editPipelinePrompt=bl;window.retryPipelineRun=ug;window.openCreditsModal=Qb;window.closeCreditsModal=eE; diff --git a/dist/index.html b/dist/index.html index 8e2e158..a61883f 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1994,11 +1994,6 @@ } .pipeline-view h3 { font-size: 25px; - /* The longest phase title ("Understanding your prompt") measures - ~304px at this size, past the 298px content column, so it wrapped - to two lines and pushed every later section down 30px. Tightening - tracking keeps the phase title to the canonical single line. */ - letter-spacing: -0.045em; } .pipeline-progress .pipeline-glyph.logo-loop { margin-bottom: 16px; } .pipeline-prompt-recap { @@ -3310,7 +3305,7 @@ .send.is-busy .send-spin { animation: none; opacity: 0.6; } } - +
diff --git a/e2e/fixtures/canonicalReference.js b/e2e/fixtures/canonicalReference.js new file mode 100644 index 0000000..1a58840 --- /dev/null +++ b/e2e/fixtures/canonicalReference.js @@ -0,0 +1,34 @@ +import { readFileSync } from 'node:fs'; +import { createHash } from 'node:crypto'; +import { applyDefaultRoutes } from './apiFixtures.js'; + +// Byte-identical, test-only snapshot of the user's authoritative HTML. Never +// derive this oracle from app markup/CSS or replace its render-affecting assets. +function pinnedFile(path, sha256, contentType) { + const body = readFileSync(new URL(path, import.meta.url)); + if (createHash('sha256').update(body).digest('hex') !== sha256) { + throw new Error(`Canonical reference hash mismatch: ${path}`); + } + return { body, contentType }; +} + +const assets = { + '/': pinnedFile('./custom-code-connect-hero.html', '548e628fe94f2b5e647cb4849fbc3200b43dcead60ea53c076f0085aca8917dc', 'text/html'), + '/fonts/Delight-VF.ttf': pinnedFile('../../fonts/Delight-VF.ttf', 'c034c57b430cc5e394eb6d1a88655c694a98c8f32ee888255f41964f58c19075', 'font/ttf'), + '/assets/flutterflow-icon.svg': pinnedFile('../../public/assets/flutterflow-icon.svg', 'b3d33379c329ac9aff23d80c002103a149625aa8cc0a850451915d1289fc6a98', 'image/svg+xml'), +}; + +export async function openCanonicalReference(page, viewport) { + await page.setViewportSize(viewport); + await page.emulateMedia({ reducedMotion:'no-preference' }); + await applyDefaultRoutes(page); + // This origin is fulfilled entirely in-process: no reference server or live + // API is needed. Unknown requests still reach the hermetic route guard. + const origin = 'http://localhost:5432'; + await page.route(`${origin}/**`, route => { + const asset = assets[new URL(route.request().url()).pathname]; + return asset ? route.fulfill(asset) : route.fallback(); + }); + await page.goto(origin); + await page.evaluate(() => document.fonts.ready); +} diff --git a/e2e/fixtures/custom-code-connect-hero.html b/e2e/fixtures/custom-code-connect-hero.html new file mode 100644 index 0000000..04a85a2 --- /dev/null +++ b/e2e/fixtures/custom-code-connect-hero.html @@ -0,0 +1,2537 @@ + + + + +