Skip to content

Commit 3d946fd

Browse files
committed
Add app scaffold
1 parent bb535a3 commit 3d946fd

File tree

9 files changed

+434
-7
lines changed

9 files changed

+434
-7
lines changed

lib/app_scaffolds/app.dart

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
part of devspace;
2+
3+
4+
5+
6+
typedef CreateRouterConfig = RouterConfig<Object> Function(BuildContext context);
7+
8+
9+
10+
class _GeneratedAppData {
11+
12+
final RouterConfig<Object> routerConfig;
13+
14+
const _GeneratedAppData({
15+
required this.routerConfig,
16+
});
17+
}
18+
19+
class App extends StatelessWidget {
20+
21+
final StringBuilder buildTitle;
22+
final ThemeBuilder buildTheme;
23+
final String translationsFolder;
24+
final Locale fallbackLocale;
25+
final List<Locale> supportedLocales;
26+
final List<Glue<GlueComponent>> globalGlues;
27+
final ContextLoader loadApp;
28+
final CreateRouterConfig createRouterConfig;
29+
30+
const App({
31+
super.key,
32+
required this.buildTitle,
33+
required this.buildTheme,
34+
this.translationsFolder = 'assets/translations',
35+
this.fallbackLocale = const Locale('en', 'US'),
36+
required this.supportedLocales,
37+
required this.globalGlues,
38+
required this.loadApp,
39+
required this.createRouterConfig,
40+
});
41+
42+
@override
43+
Widget build(BuildContext context)
44+
{
45+
return AppLoader<_GeneratedAppData>(
46+
loadApp: _loadApp,
47+
buildApp: (context, data) => _AppWidget(
48+
buildTitle: buildTitle,
49+
buildTheme: buildTheme,
50+
generatedData: data,
51+
translationsFolder: translationsFolder,
52+
fallbackLocale: fallbackLocale,
53+
supportedLocales: supportedLocales,
54+
globalGlues: globalGlues,
55+
),
56+
);
57+
}
58+
59+
Future<_GeneratedAppData?> _loadApp(BuildContext context) async
60+
{
61+
WidgetsFlutterBinding.ensureInitialized();
62+
await EasyLocalization.ensureInitialized();
63+
64+
if (!context.mounted) return null;
65+
66+
await loadApp(context);
67+
68+
await MyService.ensureAllReady();
69+
70+
if (!context.mounted) return null;
71+
72+
return _GeneratedAppData(
73+
routerConfig: createRouterConfig(context),
74+
);
75+
76+
}
77+
}
78+
79+
80+
81+
82+
83+
class _AppWidget extends StatelessWidget {
84+
85+
final StringBuilder buildTitle;
86+
final ThemeBuilder buildTheme;
87+
final _GeneratedAppData? generatedData;
88+
final String translationsFolder;
89+
final Locale fallbackLocale;
90+
final List<Locale> supportedLocales;
91+
final List<Glue<GlueComponent>> globalGlues;
92+
93+
_AppWidget({
94+
required this.buildTitle,
95+
required this.buildTheme,
96+
required this.generatedData,
97+
required this.translationsFolder,
98+
required this.fallbackLocale,
99+
required this.supportedLocales,
100+
required this.globalGlues,
101+
});
102+
103+
final Key _keyGlues = GlobalKey();
104+
// final GlobalKey<NavigatorState> _shellNavigatorKey = GlobalKey<NavigatorState>();
105+
106+
@override
107+
Widget build(BuildContext context)
108+
{
109+
return EasyLocalization(
110+
path: translationsFolder,
111+
supportedLocales: supportedLocales,
112+
fallbackLocale: fallbackLocale,
113+
child: InsertGlues(
114+
key: _keyGlues,
115+
glues: globalGlues,
116+
child: Builder(builder: (context) => MaterialApp.router(
117+
localizationsDelegates: context.localizationDelegates,
118+
supportedLocales: context.supportedLocales,
119+
locale: context.locale,
120+
routerConfig: generatedData?.routerConfig,
121+
title: buildTitle(context),
122+
// showPerformanceOverlay: true,
123+
theme: buildTheme(context),
124+
)),
125+
),
126+
);
127+
}
128+
129+
}

lib/app_scaffolds/app_loader.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
part of devspace;
2+
3+
typedef ContextLoader = Future<void> Function(BuildContext context);
4+
typedef LoadApp<T> = Future<T?> Function(BuildContext context);
5+
typedef AppBuilder<T> = Widget Function(BuildContext context, T? data);
6+
7+
class AppLoader<T> extends StatefulWidget {
8+
9+
final WidgetBuilder? buildLoading;
10+
final AppBuilder<T> buildApp;
11+
final LoadApp<T> loadApp;
12+
13+
const AppLoader({
14+
super.key,
15+
this.buildLoading,
16+
required this.buildApp,
17+
required this.loadApp,
18+
});
19+
20+
@override
21+
State<AppLoader> createState() => _AppLoaderState<T>();
22+
}
23+
24+
class _AppLoaderState<T> extends State<AppLoader<T>> {
25+
26+
bool _loaded = false;
27+
T? _data;
28+
29+
@override
30+
void initState()
31+
{
32+
_loadApp();
33+
super.initState();
34+
}
35+
36+
Future<void> _loadApp() async
37+
{
38+
T? data = await widget.loadApp(context);
39+
40+
41+
setState(()
42+
{
43+
_data = data;
44+
_loaded = true;
45+
});
46+
}
47+
48+
@override
49+
Widget build(BuildContext context)
50+
{
51+
if (!_loaded)
52+
{
53+
return widget.buildLoading?.call(context) ?? const SizedBox.shrink();
54+
}
55+
56+
return widget.buildApp(context, _data);
57+
}
58+
}

0 commit comments

Comments
 (0)