[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"technologies":3,"\u002Fopen-source\u002Fflutter-progress-dialog":167},[4,10,15,21,26,32,38,43,48,53,58,63,68,73,77,82,87,92,97,103,108,113,118,123,128,133,138,143,147,152,157,162],{"title":5,"description":6,"slug":7,"category":8,"icon":9},"Android","Every app we ship reaches Android — platform APIs, background execution, permissions, and the store requirements that come with them.","android","framework","logos:android-icon",{"title":11,"description":12,"slug":13,"category":8,"icon":14},"Angular","The front-end framework we work in when a product is already Angular — a batteries-included structure that suits large, long-lived apps.","angular","logos:angular-icon",{"title":16,"description":17,"slug":18,"category":19,"icon":20},"Dart","The language every Flutter app we ship is written in — sound null safety, real pattern matching, and a compiler that targets native and the web.","dart","language","logos:dart",{"title":22,"description":23,"slug":24,"category":8,"icon":25},"Django","The Python framework we use when a product needs an admin, auth and a real data model on day one rather than a hand-rolled service.","django","logos:django-icon",{"title":27,"description":28,"slug":29,"category":30,"icon":31},"Docker","Every service we build ships as a container, so what runs on a laptop, in CI and in production is one artefact rather than three of them.","docker","infrastructure","logos:docker-icon",{"title":33,"description":34,"slug":35,"category":36,"icon":37},"Fastlane","The release automation behind our mobile work — signing, builds and store uploads run from CI instead of from one engineer's laptop on release day.","fastlane","tools","logos:fastlane",{"title":39,"description":40,"slug":41,"category":8,"icon":42},"Flutter","Our primary mobile stack since 2018 — one Dart codebase shipping to iOS, Android, web and desktop without a separate team per platform.","flutter","logos:flutter",{"title":44,"description":45,"slug":46,"category":36,"icon":47},"Git","Every project we touch lives in Git — reviewed pull requests, CI on every branch, and a history that still makes sense months later.","git","logos:git-icon",{"title":49,"description":50,"slug":51,"category":19,"icon":52},"Go","Our backend language for real-time APIs and services under load — small binaries, fast builds, and concurrency that stays readable.","go","logos:gopher",{"title":54,"description":55,"slug":56,"category":30,"icon":57},"Google Cloud","The cloud our production workloads run on — managed Kubernetes, storage and networking, without hand-built servers nobody wants to maintain.","gcp","logos:google-cloud",{"title":59,"description":60,"slug":61,"category":36,"icon":62},"Gradle","The build system every Android release goes through — product flavours, signing configs, and the dependency wiring under a Flutter app.","gradle","logos:gradle",{"title":64,"description":65,"slug":66,"category":30,"icon":67},"Helm","How we package a Kubernetes deployment — service, config, secrets and ingress as one versioned unit that can be promoted and rolled back.","helm","logos:helm",{"title":69,"description":70,"slug":71,"category":19,"icon":72},"Kotlin","What we reach for when a Flutter app needs real Android underneath it — platform channels, background work, and native SDK integrations.","kotlin","logos:kotlin-icon",{"title":74,"description":75,"slug":76,"category":8,"icon":72},"Kotlin Multiplatform","Sharing business logic across iOS and Android while each platform keeps its own native UI — the alternative when Flutter is not the right fit.","kmp",{"title":78,"description":79,"slug":80,"category":30,"icon":81},"Kubernetes","How we run services in production — Helm-packaged deployments, rollouts that can be rolled back, and scaling that does not need a person at 3am.","kubernetes","logos:kubernetes",{"title":83,"description":84,"slug":85,"category":30,"icon":86},"NATS","Lightweight messaging between services — publish\u002Fsubscribe and request\u002Freply without the operational weight of a full broker cluster.","nats","logos:nats-icon",{"title":88,"description":89,"slug":90,"category":8,"icon":91},"Nuxt","Vue with server rendering, routing and SEO handled — how we build marketing sites and web apps that must be fast and indexable on first load.","nuxt","logos:nuxt-icon",{"title":93,"description":94,"slug":95,"category":19,"icon":96},"PHP","Where we work with an existing PHP backend — extending it, integrating with it, and building the mobile and web clients it has to serve.","php","logos:php",{"title":98,"description":99,"slug":100,"category":101,"icon":102},"PostgreSQL","Our default database — the one we reach for unless a product gives us a specific reason not to, from schema design through to index tuning.","postgres","database","logos:postgresql",{"title":104,"description":105,"slug":106,"category":19,"icon":107},"Python","Our language for backends, data work and AI integrations — including the Python bindings we ship for our own Rust tooling.","python","logos:python",{"title":109,"description":110,"slug":111,"category":8,"icon":112},"React","The front-end library we work in when a product is already React — components, hooks, and the ecosystem that has grown around them.","react","logos:react",{"title":114,"description":115,"slug":116,"category":101,"icon":117},"Redis","Where we put data that has to be fast and can be rebuilt — caches, sessions, rate limits, and the queues behind a product's slow paths.","redis","logos:redis",{"title":119,"description":120,"slug":121,"category":19,"icon":122},"Ruby","The language our mobile release automation is written in — Fastlane lanes, custom actions, and the CI glue that ships builds to the stores.","ruby","logos:ruby",{"title":124,"description":125,"slug":126,"category":19,"icon":127},"Rust","Where we go when performance and correctness both matter — document rendering, CLI tooling, and services that have to stay fast and predictable.","rust","simple-icons:rust",{"title":129,"description":130,"slug":131,"category":101,"icon":132},"SQLite","The database that ships inside the app — local caches, offline-first storage, and anything that still has to work with no network.","sqlite","logos:sqlite",{"title":134,"description":135,"slug":136,"category":8,"icon":137},"Strapi","A headless CMS we reach for when editors need to own the content — a real admin and a clean API, without building either from scratch.","strapi","logos:strapi-icon",{"title":139,"description":140,"slug":141,"category":19,"icon":142},"Swift","What we reach for when a Flutter app needs real iOS underneath it — platform channels, native SDK integrations, widgets and App Clips.","swift","logos:swift",{"title":144,"description":145,"slug":146,"category":8,"icon":142},"SwiftUI","Apple's UI framework, where we build the native surfaces a Flutter app cannot own — widgets, App Clips, extensions and system integrations.","swiftui",{"title":148,"description":149,"slug":150,"category":8,"icon":151},"Tailwind CSS","How we style every front end we build — utility classes and design tokens instead of a stylesheet that only ever grows and is never deleted.","tailwind","logos:tailwindcss-icon",{"title":153,"description":154,"slug":155,"category":19,"icon":156},"TypeScript","The default for everything we write for the browser and for Node services — types that catch integration bugs before they reach a review.","typescript","logos:typescript-icon",{"title":158,"description":159,"slug":160,"category":8,"icon":161},"Vue","Our front-end framework for admin panels, merchant dashboards and product web apps that have to stay maintainable for years, not sprints.","vue","logos:vue",{"title":163,"description":164,"slug":165,"category":36,"icon":166},"Whisper","OpenAI's open-source speech recognition model — the transcription engine behind voice input, running as both a backend service and on-device in the app.","whisper","simple-icons:openai",{"id":168,"title":169,"body":170,"description":594,"extension":595,"links":596,"meta":600,"metaDescription":601,"metaTitle":602,"navigation":476,"ogDescription":603,"path":604,"repository":605,"seo":609,"slug":608,"stem":610,"technologies":611,"updated":612,"__hash__":613,"stats":614},"open_source_en\u002Fopen-source\u002Fflutter-progress-dialog.md","Flutter Future Progress Dialog",{"type":171,"value":172,"toc":582},"minimark",[173,178,182,185,188,204,208,223,231,234,238,308,312,317,323,327,333,337,346,350,353,357,360,387,393,548,563,574,578],[174,175,177],"h2",{"id":176},"the-problem","The Problem",[179,180,181],"p",{},"Most Flutter apps need to run tasks that take a few seconds — fetching data from an API, uploading a file, or processing a payment. During that wait the user stares at a frozen screen with no indication that anything is happening. They tap the button again, trigger duplicate requests, or assume the app has crashed.",[179,183,184],{},"The standard solution is to manually manage a loading state: flip a boolean, show a spinner, await the future, hide the spinner, then handle the result or error. That logic ends up duplicated across dozens of screens with subtle differences each time.",[179,186,187],{},"Common pain points include:",[189,190,191,195,198,201],"ul",{},[192,193,194],"li",{},"Boilerplate loading-state management repeated in every screen",[192,196,197],{},"Users tapping buttons multiple times because there is no visual feedback",[192,199,200],{},"Dismissed dialogs that leave orphaned futures still running in the background",[192,202,203],{},"Inconsistent error handling — some screens catch exceptions, others crash silently",[174,205,207],{"id":206},"how-flutter_future_progress_dialog-solves-it","How flutter_future_progress_dialog Solves It",[179,209,210,214,215,218,219,222],{},[211,212,213],"code",{},"flutter_future_progress_dialog"," replaces all of that boilerplate with a single function call. Pass your async task in, and the package shows a non-dismissible progress dialog, waits for the result, closes the dialog, and hands you back a type-safe result — either ",[211,216,217],{},"Success"," with the value or ",[211,220,221],{},"Failure"," with the error.",[179,224,225],{},[226,227],"img",{"alt":228,"src":229,"style":230},"Flutter progress dialog demo on iPhone","\u002Fopen-source\u002Fflutter-progress-dialog\u002Fflutter_progress_dialog.gif","max-height: 600px; height: auto; width: auto;",[179,232,233],{},"Error handling is built into the result type, so you never forget to catch an exception.",[174,235,237],{"id":236},"what-it-supports","What It Supports",[189,239,240,251,260,269,279,300],{},[192,241,242,246,247,250],{},[243,244,245],"strong",{},"Material dialog"," — ",[211,248,249],{},"showProgressDialog"," displays a standard Material circular progress indicator",[192,252,253,246,256,259],{},[243,254,255],{},"Cupertino dialog",[211,257,258],{},"showCupertinoProgressDialog"," shows an iOS-styled activity indicator",[192,261,262,246,265,268],{},[243,263,264],{},"Adaptive dialog",[211,266,267],{},"showAdaptiveProgressDialog"," picks the right style for the current platform automatically",[192,270,271,274,275,278],{},[243,272,273],{},"Custom dialog UI"," — pass a ",[211,276,277],{},"builder"," to replace the default indicator with any widget you need",[192,280,281,246,284,287,288,290,291,293,294,290,297],{},[243,282,283],{},"Type-safe results",[211,285,286],{},"ProgressDialogResult\u003CT>"," is a sealed class with ",[211,289,217],{}," and ",[211,292,221],{}," variants, supporting pattern matching and convenience methods like ",[211,295,296],{},"unwrap()",[211,298,299],{},"map()",[192,301,302,246,305,307],{},[243,303,304],{},"Error capture",[211,306,221],{}," includes both the error object and the stack trace",[174,309,311],{"id":310},"real-world-use-cases","Real-World Use Cases",[313,314,316],"h3",{"id":315},"payment-processing","Payment processing",[179,318,319,320,322],{},"A checkout screen calls a payment gateway API. Without a progress dialog, users tap \"Pay\" again when nothing seems to happen — causing duplicate charges. With ",[211,321,249],{},", the dialog stays on screen and blocks interaction until the gateway responds, and your code pattern-matches the result to navigate to a confirmation or error screen.",[313,324,326],{"id":325},"file-uploads","File uploads",[179,328,329,330,332],{},"A document scanner uploads images to a server. The upload can take several seconds on slow connections. Wrapping the upload in ",[211,331,267],{}," gives users immediate visual feedback and ensures the dialog matches the platform — Material on Android, Cupertino on iOS.",[313,334,336],{"id":335},"form-submissions","Form submissions",[179,338,339,340,342,343,345],{},"A multi-step form sends data to a backend on the final step. Using the progress dialog prevents double-submission and gives you a clean ",[211,341,217],{},"\u002F",[211,344,221],{}," result to decide whether to show a success screen or an inline error message.",[313,347,349],{"id":348},"background-data-sync","Background data sync",[179,351,352],{},"A CRM app syncs local changes with a remote server. A custom builder can show a branded loading animation instead of the default spinner, keeping the user experience consistent with the rest of the app.",[174,354,356],{"id":355},"getting-started","Getting Started",[179,358,359],{},"Install the package:",[361,362,367],"pre",{"className":363,"code":364,"language":365,"meta":366,"style":366},"language-shell shiki shiki-themes material-theme-lighter github-light github-dark","flutter pub add flutter_future_progress_dialog\n","shell","",[211,368,369],{"__ignoreMap":366},[370,371,374,377,381,384],"span",{"class":372,"line":373},"line",1,[370,375,41],{"class":376},"sbgvK",[370,378,380],{"class":379},"s_sjI"," pub",[370,382,383],{"class":379}," add",[370,385,386],{"class":379}," flutter_future_progress_dialog\n",[179,388,389,390,392],{},"Then call ",[211,391,249],{}," with your async task:",[361,394,397],{"className":395,"code":396,"language":18,"meta":366,"style":366},"language-dart shiki shiki-themes material-theme-lighter github-light github-dark","final result = await showProgressDialog(\n  context: context,\n  future: () => fetchData(),\n);\n\nswitch (result) {\n  case Success(:final value):\n    \u002F\u002F Use the value\n  case Failure(:final error):\n    \u002F\u002F Handle the error\n}\n",[211,398,399,424,440,462,471,478,487,510,517,536,542],{"__ignoreMap":366},[370,400,401,405,409,413,417,421],{"class":372,"line":373},[370,402,404],{"class":403},"sbsja","final",[370,406,408],{"class":407},"su5hD"," result ",[370,410,412],{"class":411},"smGrS","=",[370,414,416],{"class":415},"sVHd0"," await",[370,418,420],{"class":419},"sGLFI"," showProgressDialog",[370,422,423],{"class":407},"(\n",[370,425,427,430,433,436],{"class":372,"line":426},2,[370,428,429],{"class":407},"  context",[370,431,432],{"class":411},":",[370,434,435],{"class":407}," context",[370,437,439],{"class":438},"sP7_E",",\n",[370,441,443,446,448,451,454,457,460],{"class":372,"line":442},3,[370,444,445],{"class":407},"  future",[370,447,432],{"class":411},[370,449,450],{"class":407}," () ",[370,452,453],{"class":411},"=>",[370,455,456],{"class":419}," fetchData",[370,458,459],{"class":407},"()",[370,461,439],{"class":438},[370,463,465,468],{"class":372,"line":464},4,[370,466,467],{"class":407},")",[370,469,470],{"class":438},";\n",[370,472,474],{"class":372,"line":473},5,[370,475,477],{"emptyLinePlaceholder":476},true,"\n",[370,479,481,484],{"class":372,"line":480},6,[370,482,483],{"class":415},"switch",[370,485,486],{"class":407}," (result) {\n",[370,488,490,493,497,500,502,504,507],{"class":372,"line":489},7,[370,491,492],{"class":415},"  case",[370,494,496],{"class":495},"sZMiF"," Success",[370,498,499],{"class":407},"(",[370,501,432],{"class":411},[370,503,404],{"class":403},[370,505,506],{"class":407}," value)",[370,508,509],{"class":411},":\n",[370,511,513],{"class":372,"line":512},8,[370,514,516],{"class":515},"sutJx","    \u002F\u002F Use the value\n",[370,518,520,522,525,527,529,531,534],{"class":372,"line":519},9,[370,521,492],{"class":415},[370,523,524],{"class":495}," Failure",[370,526,499],{"class":407},[370,528,432],{"class":411},[370,530,404],{"class":403},[370,532,533],{"class":407}," error)",[370,535,509],{"class":411},[370,537,539],{"class":372,"line":538},10,[370,540,541],{"class":515},"    \u002F\u002F Handle the error\n",[370,543,545],{"class":372,"line":544},11,[370,546,547],{"class":407},"}\n",[179,549,550,551,553,554,556,557,559,560,562],{},"Three dialog functions are available: ",[211,552,249],{}," (Material), ",[211,555,258],{}," (Cupertino), and ",[211,558,267],{}," (platform-automatic). All accept an optional ",[211,561,277],{}," parameter for custom UI.",[179,564,565,566,573],{},"A complete working example is available in the ",[567,568,572],"a",{"href":569,"rel":570},"https:\u002F\u002Fgithub.com\u002Fnerdy-pro\u002Fflutter-progress-dialog\u002Ftree\u002Fmain\u002Fexample",[571],"nofollow","example directory",".",[575,576],"questions",{":items":577},"[{\"title\":\"Can the user dismiss the dialog manually?\",\"text\":\"No. The dialog is non-dismissible by default, which prevents orphaned futures and duplicate submissions. The dialog closes automatically when the async task completes.\"},{\"title\":\"What happens if the future throws an exception?\",\"text\":\"The dialog closes and the result is returned as a Failure containing the error and stack trace. Your code can pattern-match on the result to handle errors without try-catch blocks.\"},{\"title\":\"Does it work on both Android and iOS?\",\"text\":\"Yes. Use showProgressDialog for Material style, showCupertinoProgressDialog for iOS style, or showAdaptiveProgressDialog to automatically match the host platform.\"},{\"title\":\"Can I customize the loading indicator?\",\"text\":\"Yes. Pass a builder parameter to any of the three dialog functions to replace the default progress indicator with your own widget — a branded animation, a message, or any other Flutter widget.\"},{\"title\":\"How does the result type work?\",\"text\":\"ProgressDialogResult\u003CT> is a sealed class with two variants: Success\u003CT> containing the returned value, and Failure\u003CT> containing the error and stack trace. You can use Dart pattern matching, or convenience methods like isSuccess, isError, unwrap(), and map().\"}]",[579,580,581],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}",{"title":366,"searchDepth":426,"depth":426,"links":583},[584,585,586,587,593],{"id":176,"depth":426,"text":177},{"id":206,"depth":426,"text":207},{"id":236,"depth":426,"text":237},{"id":310,"depth":426,"text":311,"children":588},[589,590,591,592],{"id":315,"depth":442,"text":316},{"id":325,"depth":442,"text":326},{"id":335,"depth":442,"text":336},{"id":348,"depth":442,"text":349},{"id":355,"depth":426,"text":356},"A Flutter package that shows a progress dialog during async operations and returns the result — with Material, Cupertino, and adaptive styles built in.","md",[597],{"type":598,"url":599},"pub_dev","https:\u002F\u002Fpub.dev\u002Fpackages\u002Fflutter_future_progress_dialog",{},"A lightweight Flutter package that shows a progress dialog during async work and returns the result — Material, Cupertino, and adaptive styles included.","Flutter Progress Dialog for Async Tasks","Await the work, show the dialog, get the result back. A small Flutter package for the progress indicator you keep rewriting by hand.","\u002Fopen-source\u002Fflutter-progress-dialog",{"type":606,"company":607,"name":608},"github","nerdy-pro","flutter-progress-dialog",{"title":169,"description":594},"open-source\u002Fflutter-progress-dialog",[41,18],"2026-03-17","LieLMR921XfNOqSzlDXeQ-Vf7FRsfb1qPbj-qm6rXLQ",{"forks":615,"stars":426,"contributors":616,"last_release":627,"issues":615,"has_contribution_guide":628,"license":629,"last_updated":630,"watchers":426},0,[617,622],{"login":618,"profile_url":619,"avatar_url":620,"contributions":621},"thenixan","https:\u002F\u002Fgithub.com\u002Fthenixan","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F3602098?v=4",100,{"login":623,"profile_url":624,"avatar_url":625,"contributions":626},"OleksandrFedyay","https:\u002F\u002Fgithub.com\u002FOleksandrFedyay","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F17413471?v=4",33,"v2.0.0",false,"MIT","2026-08-19T17:15:57Z"]