Skip to content

Commit f61733e

Browse files
authored
feat(widgets): add master data loading and build info widget (#167)
* feat(migrate_custom_widget):created master data loading and build info widget * feat(migrate_custom_widget):created constant svg strings * feat(migrate_custom_widget):created constant svg strings
1 parent 48917c6 commit f61733e

File tree

8 files changed

+302
-0
lines changed

8 files changed

+302
-0
lines changed

assets/svg/check.svg

Lines changed: 4 additions & 0 deletions
Loading

assets/svg/check_mark_rounded.svg

Lines changed: 21 additions & 0 deletions
Loading

lib/src/constants/svgs.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class Svgs {
2+
Svgs._();
3+
4+
static const _basePath = 'assets/svg';
5+
6+
static const String checkSvg = '$_basePath/check.svg';
7+
static const String checkMarkRounded = '$_basePath/check_mark_rounded.svg';
8+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import 'package:flutter/material.dart';
2+
3+
class BuildInfoWidget extends StatelessWidget {
4+
final Future<String> Function() getBuildNumber;
5+
final Future<String> Function() getBuildVersion;
6+
7+
const BuildInfoWidget({
8+
Key? key,
9+
required this.getBuildNumber,
10+
required this.getBuildVersion,
11+
}) : super(key: key);
12+
13+
@override
14+
Widget build(BuildContext context) {
15+
return FutureBuilder<List<String>>(
16+
future: Future.wait([
17+
getBuildNumber(),
18+
getBuildVersion(),
19+
]),
20+
builder: (context, snapshot) {
21+
if (snapshot.connectionState == ConnectionState.done &&
22+
snapshot.hasData &&
23+
snapshot.data != null) {
24+
final buildNumber = snapshot.data![0];
25+
final buildVersion = snapshot.data![1];
26+
27+
return Column(
28+
crossAxisAlignment: CrossAxisAlignment.start,
29+
children: [
30+
Text(
31+
'Build: $buildNumber',
32+
style: const TextStyle(
33+
fontSize: 18,
34+
fontWeight: FontWeight.bold,
35+
),
36+
),
37+
const SizedBox(height: 12),
38+
Text(
39+
'v$buildVersion',
40+
style: const TextStyle(
41+
fontSize: 18,
42+
fontWeight: FontWeight.bold,
43+
),
44+
),
45+
],
46+
);
47+
} else {
48+
return const SizedBox.shrink();
49+
}
50+
},
51+
);
52+
}
53+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'package:flutter/material.dart';
2+
3+
@immutable
4+
class DataLoadingProgress {
5+
const DataLoadingProgress._({
6+
required this.progress,
7+
});
8+
9+
factory DataLoadingProgress.dynamic(int value) {
10+
return DataLoadingProgress._(
11+
progress: value,
12+
);
13+
}
14+
factory DataLoadingProgress.initial() {
15+
return DataLoadingProgress._(
16+
progress: 0,
17+
);
18+
}
19+
factory DataLoadingProgress.started() {
20+
return DataLoadingProgress._(
21+
progress: 25,
22+
);
23+
}
24+
25+
factory DataLoadingProgress.half() {
26+
return DataLoadingProgress._(
27+
progress: 50,
28+
);
29+
}
30+
31+
factory DataLoadingProgress.almostDone() {
32+
return DataLoadingProgress._(
33+
progress: 85,
34+
);
35+
}
36+
37+
factory DataLoadingProgress.done() {
38+
return DataLoadingProgress._(
39+
progress: 100,
40+
);
41+
}
42+
43+
factory DataLoadingProgress.error([String? reason]) {
44+
return DataLoadingProgress._(
45+
progress: 0,
46+
);
47+
}
48+
49+
factory DataLoadingProgress.debugError(String message) {
50+
return DataLoadingProgress._(
51+
progress: 0,
52+
);
53+
}
54+
final int progress;
55+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import 'package:fa_flutter_ui_kit/fa_flutter_ui_kit.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter_svg/flutter_svg.dart';
4+
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
5+
6+
import '../../../constants/svgs.dart';
7+
import '../../../utils/log_utils.dart';
8+
9+
enum apiStatus {
10+
pending,
11+
success,
12+
failed,
13+
}
14+
15+
/// * [dataProgressStream] : it used for get stream for show animatedLoader
16+
/// * [entityStatusStream] : it should be Map<String,apiStatus> for display all entity name
17+
/// * [kText] : all translated text should be write in list with correct index to display
18+
class DataLoadingProgressWidget extends StatelessWidget {
19+
final Stream<DataLoadingProgress> dataProgressStream;
20+
final Stream<Map<String, apiStatus>> entityStatusStream;
21+
final ItemScrollController scrollController;
22+
final List? kTexts;
23+
final bool? hideScrollList;
24+
final void Function(int count) onScrollTrigger;
25+
26+
const DataLoadingProgressWidget({
27+
Key? key,
28+
required this.dataProgressStream,
29+
required this.entityStatusStream,
30+
required this.scrollController,
31+
required this.onScrollTrigger,
32+
this.hideScrollList = false,
33+
this.kTexts = const [
34+
"Fetching data",
35+
"Please wait while we fetch the data."
36+
],
37+
}) : super(key: key);
38+
39+
@override
40+
Widget build(BuildContext context) {
41+
return Column(
42+
children: [
43+
/// Progress Bar
44+
StreamBuilder<DataLoadingProgress>(
45+
stream: dataProgressStream,
46+
builder: (_, snapshot) {
47+
final progress = snapshot.data?.progress ?? 0;
48+
return AnimatedLoader(
49+
baseColor: Colors.amber,
50+
highlightColor: Colors.grey[300] ?? Colors.grey,
51+
progress: progress,
52+
);
53+
},
54+
),
55+
56+
const SizedBox(height: 10),
57+
58+
/// Heading Text
59+
Padding(
60+
padding: const EdgeInsets.symmetric(horizontal: 50),
61+
child: Text(
62+
kTexts?[0],
63+
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
64+
),
65+
),
66+
67+
const SizedBox(height: 10),
68+
69+
/// Sub Text
70+
Padding(
71+
padding: const EdgeInsets.symmetric(horizontal: 50),
72+
child: Text(
73+
kTexts?[1],
74+
style: const TextStyle(fontSize: 14),
75+
),
76+
),
77+
78+
/// Entity Status List
79+
if (hideScrollList == false)
80+
StreamBuilder<Map<String, apiStatus>>(
81+
stream: entityStatusStream,
82+
builder: (_, snapshot) {
83+
final mapData = snapshot.data ?? {};
84+
final entries = mapData.entries.toList();
85+
86+
try {
87+
if (entries.length > 3) {
88+
onScrollTrigger(entries.length);
89+
}
90+
} catch (e, s) {
91+
logger.e(e, s);
92+
}
93+
94+
return Container(
95+
height: 200,
96+
margin: const EdgeInsets.symmetric(vertical: 25),
97+
child: Center(
98+
child: ScrollConfiguration(
99+
behavior: NoGlowScrollBehavior(),
100+
child: ScrollablePositionedList.builder(
101+
shrinkWrap: true,
102+
itemScrollController: scrollController,
103+
itemCount: entries.length,
104+
physics: const NeverScrollableScrollPhysics(),
105+
itemBuilder: (context, index) {
106+
if (index < 0 || index >= entries.length) {
107+
return Container();
108+
}
109+
final model = entries[index].key;
110+
final status = entries[index].value;
111+
112+
final entityName = model;
113+
114+
return Padding(
115+
padding: const EdgeInsets.only(
116+
top: 10, bottom: 10, left: 50),
117+
child: Row(
118+
children: [
119+
if (status == apiStatus.success ||
120+
status == apiStatus.pending)
121+
SvgPicture.asset(
122+
status == apiStatus.success
123+
? Svgs.checkSvg
124+
: Svgs.checkMarkRounded,
125+
height: 20,
126+
width: 20,
127+
package: 'fa_flutter_ui_kit',
128+
)
129+
// status == apiStatus.error
130+
else
131+
Icon(
132+
Icons.replay_outlined,
133+
),
134+
const SizedBox(width: 5),
135+
Text('Fetching ${entityName.toString()}'),
136+
],
137+
),
138+
);
139+
},
140+
),
141+
),
142+
),
143+
);
144+
},
145+
),
146+
],
147+
);
148+
}
149+
}
150+
151+
class NoGlowScrollBehavior extends ScrollBehavior {
152+
@override
153+
Widget buildOverscrollIndicator(
154+
BuildContext context, Widget child, ScrollableDetails details) {
155+
return child;
156+
}
157+
}

lib/src/widgets/common/index.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ export 'animating_location_pin.dart';
22
export 'app_logo.dart';
33
export 'base_scaffold.dart';
44
export 'bottom_action_button.dart';
5+
export 'buid_info_widget.dart';
56
export 'common_progress_dialog.dart';
67
export 'company_logo.dart';
78
export 'custom_app_bar.dart';
9+
export 'data_loading_progress/data_loading_progress.dart';
10+
export 'data_loading_progress/data_loading_progress_widget.dart';
811
export 'dotted_divider.dart';
912
export 'empty_data_widget.dart';
1013
export 'error/index.dart';

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ flutter:
4242
- assets/images/
4343
- assets/flare/
4444
- assets/data/
45+
- assets/svg/
4546

4647
fonts:
4748
- family: Trueno

0 commit comments

Comments
 (0)