refactor: move icon state to SettingsUserViewBloc

This commit is contained in:
Ian Su 2022-08-03 00:28:21 +08:00
parent 634170a86e
commit 7fc9a085c5
2 changed files with 31 additions and 35 deletions

View File

@ -35,6 +35,9 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
); );
}); });
}, },
updateUserIcon: (String icon) {
emit(state.copyWith(icon: icon));
},
); );
}); });
} }
@ -62,6 +65,7 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
class SettingsUserEvent with _$SettingsUserEvent { class SettingsUserEvent with _$SettingsUserEvent {
const factory SettingsUserEvent.initial() = _Initial; const factory SettingsUserEvent.initial() = _Initial;
const factory SettingsUserEvent.updateUserName(String name) = _UpdateUserName; const factory SettingsUserEvent.updateUserName(String name) = _UpdateUserName;
const factory SettingsUserEvent.updateUserIcon(String icon) = _UpdateUserIcon;
const factory SettingsUserEvent.didReceiveUserProfile(UserProfilePB newUserProfile) = _DidReceiveUserProfile; const factory SettingsUserEvent.didReceiveUserProfile(UserProfilePB newUserProfile) = _DidReceiveUserProfile;
} }
@ -70,10 +74,12 @@ class SettingsUserState with _$SettingsUserState {
const factory SettingsUserState({ const factory SettingsUserState({
required UserProfilePB userProfile, required UserProfilePB userProfile,
required Either<Unit, String> successOrFailure, required Either<Unit, String> successOrFailure,
required String icon,
}) = _SettingsUserState; }) = _SettingsUserState;
factory SettingsUserState.initial(UserProfilePB userProfile) => SettingsUserState( factory SettingsUserState.initial(UserProfilePB userProfile) => SettingsUserState(
userProfile: userProfile, userProfile: userProfile,
successOrFailure: left(unit), successOrFailure: left(unit),
icon: 'page',
); );
} }

View File

@ -20,7 +20,7 @@ class SettingsUserView extends StatelessWidget {
builder: (context, state) => SingleChildScrollView( builder: (context, state) => SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [_renderUserNameInput(context), const VSpace(20), const _CurrentIcon()], children: [_renderUserNameInput(context), const VSpace(20), _renderCurrentIcon(context)],
), ),
), ),
), ),
@ -31,6 +31,11 @@ class SettingsUserView extends StatelessWidget {
String name = context.read<SettingsUserViewBloc>().state.userProfile.name; String name = context.read<SettingsUserViewBloc>().state.userProfile.name;
return _UserNameInput(name); return _UserNameInput(name);
} }
Widget _renderCurrentIcon(BuildContext context) {
String icon = context.read<SettingsUserViewBloc>().state.icon;
return _CurrentIcon(icon);
}
} }
class _UserNameInput extends StatelessWidget { class _UserNameInput extends StatelessWidget {
@ -53,25 +58,17 @@ class _UserNameInput extends StatelessWidget {
} }
} }
class _CurrentIcon extends StatefulWidget { class _CurrentIcon extends StatelessWidget {
const _CurrentIcon({Key? key}) : super(key: key); final String icon;
const _CurrentIcon(this.icon, {Key? key}) : super(key: key);
@override
State<_CurrentIcon> createState() => _CurrentIconState();
}
class _CurrentIconState extends State<_CurrentIcon> {
String iconName = 'page';
_setIcon(String name) {
setState(() {
iconName = name;
});
Navigator.of(context).pop();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_setIcon(String icon) {
context.read<SettingsUserViewBloc>().add(SettingsUserEvent.updateUserIcon(icon));
Navigator.of(context).pop();
}
return Material( return Material(
color: Colors.transparent, color: Colors.transparent,
child: GestureDetector( child: GestureDetector(
@ -97,7 +94,7 @@ class _CurrentIconState extends State<_CurrentIcon> {
child: Container( child: Container(
margin: const EdgeInsets.all(5.0), margin: const EdgeInsets.all(5.0),
decoration: BoxDecoration(border: Border.all(color: Colors.grey)), decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
child: svgWithSize('emoji/$iconName', const Size(60, 60)), child: svgWithSize('emoji/$icon', const Size(60, 60)),
)), )),
])), ])),
); );
@ -108,36 +105,30 @@ class IconGallery extends StatelessWidget {
final Function setIcon; final Function setIcon;
const IconGallery(this.setIcon, {Key? key}) : super(key: key); const IconGallery(this.setIcon, {Key? key}) : super(key: key);
Future<List<String>> _getIconNames(BuildContext context) async { Future<List<String>> _getIcons(BuildContext context) async {
// >> To get paths you need these 2 lines
final manifestContent = await DefaultAssetBundle.of(context).loadString('AssetManifest.json'); final manifestContent = await DefaultAssetBundle.of(context).loadString('AssetManifest.json');
final Map<String, dynamic> manifestMap = json.decode(manifestContent); final Map<String, dynamic> manifestMap = json.decode(manifestContent);
// >> To get paths you need these 2 lines
final iconNames = manifestMap.keys final icons = manifestMap.keys
.where((String key) => key.startsWith('assets/images/emoji/') && key.endsWith('.svg')) .where((String key) => key.startsWith('assets/images/emoji/') && key.endsWith('.svg'))
.map((String key) => key.split('/').last.split('.').first) .map((String key) => key.split('/').last.split('.').first)
.toList(); .toList();
debugPrint(iconNames.toString()); return icons;
return iconNames;
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<List<String>>( return FutureBuilder<List<String>>(
future: _getIconNames(context), future: _getIcons(context),
builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) { builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
return GridView.count( return GridView.count(
primary: false,
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 5, crossAxisCount: 5,
children: (snapshot.data ?? []).map((String iconName) { children: (snapshot.data ?? []).map((String icon) {
return IconOption(iconName, 50.0, setIcon); return IconOption(icon, setIcon);
}).toList(), }).toList(),
); );
} else { } else {
@ -151,11 +142,10 @@ class IconGallery extends StatelessWidget {
} }
class IconOption extends StatelessWidget { class IconOption extends StatelessWidget {
final String iconName; final String icon;
final double size;
final Function setIcon; final Function setIcon;
IconOption(this.iconName, this.size, this.setIcon, {Key? key}) : super(key: ValueKey(iconName)); IconOption(this.icon, this.setIcon, {Key? key}) : super(key: ValueKey(icon));
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -163,9 +153,9 @@ class IconOption extends StatelessWidget {
color: Colors.transparent, color: Colors.transparent,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
setIcon(iconName); setIcon(icon);
}, },
child: svgWidget('emoji/$iconName'), child: svgWidget('emoji/$icon'),
), ),
); );
} }