Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
305 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_bloc/flutter_bloc.dart'; | ||
import 'package:genshindb/application/bloc.dart'; | ||
import 'package:genshindb/domain/assets.dart'; | ||
import 'package:genshindb/generated/l10n.dart'; | ||
import 'package:genshindb/presentation/materials/materials_page.dart'; | ||
|
||
import 'sliver_card_item.dart'; | ||
|
||
class SliverMaterialsCard extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
final theme = Theme.of(context); | ||
final s = S.of(context); | ||
return SliverCardItem( | ||
onClick: _gotoMaterialsPage, | ||
icon: Image.asset(Assets.getOtherMaterialPath('bag.png'), width: 60, height: 60, color: theme.accentColor), | ||
children: [ | ||
Text( | ||
s.checkAllMaterials, | ||
style: theme.textTheme.subtitle2, | ||
textAlign: TextAlign.center, | ||
), | ||
], | ||
); | ||
} | ||
|
||
Future<void> _gotoMaterialsPage(BuildContext context) async { | ||
context.read<MaterialsBloc>().add(const MaterialsEvent.init()); | ||
await Navigator.push(context, MaterialPageRoute(builder: (_) => MaterialsPage())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_bloc/flutter_bloc.dart'; | ||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; | ||
import 'package:genshindb/application/bloc.dart'; | ||
import 'package:genshindb/generated/l10n.dart'; | ||
import 'package:genshindb/presentation/shared/loading.dart'; | ||
import 'package:genshindb/presentation/shared/sliver_nothing_found.dart'; | ||
import 'package:genshindb/presentation/shared/sliver_page_filter.dart'; | ||
import 'package:genshindb/presentation/shared/sliver_scaffold_with_fab.dart'; | ||
import 'package:genshindb/presentation/shared/styles.dart'; | ||
|
||
import 'widgets/material_bottom_sheet.dart'; | ||
import 'widgets/material_card.dart'; | ||
|
||
class MaterialsPage extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
final s = S.of(context); | ||
final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait; | ||
return BlocBuilder<MaterialsBloc, MaterialsState>( | ||
builder: (context, state) { | ||
return state.map( | ||
loading: (_) => const Loading(), | ||
loaded: (state) => SafeArea( | ||
child: SliverScaffoldWithFab( | ||
appbar: AppBar(title: Text(s.materials)), | ||
slivers: [ | ||
SliverPageFilter( | ||
search: state.search, | ||
title: s.materials, | ||
onPressed: () => _showFiltersModal(context), | ||
searchChanged: (v) => context.read<MaterialsBloc>().add(MaterialsEvent.searchChanged(search: v)), | ||
), | ||
if (state.materials.isNotEmpty) | ||
SliverPadding( | ||
padding: Styles.edgeInsetHorizontal5, | ||
sliver: SliverStaggeredGrid.countBuilder( | ||
crossAxisCount: isPortrait ? 3 : 5, | ||
itemBuilder: (ctx, index) => MaterialCard.item(item: state.materials[index]), | ||
itemCount: state.materials.length, | ||
crossAxisSpacing: isPortrait ? 10 : 5, | ||
mainAxisSpacing: 5, | ||
staggeredTileBuilder: (int index) => const StaggeredTile.fit(1), | ||
), | ||
) | ||
else | ||
const SliverNothingFound(), | ||
], | ||
), | ||
), | ||
); | ||
}, | ||
); | ||
} | ||
|
||
Future<void> _showFiltersModal(BuildContext context) async { | ||
await showModalBottomSheet( | ||
context: context, | ||
shape: Styles.modalBottomSheetShape, | ||
isDismissible: true, | ||
isScrollControlled: true, | ||
builder: (_) => MaterialBottomSheet(), | ||
); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
lib/presentation/materials/widgets/material_bottom_sheet.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_bloc/flutter_bloc.dart'; | ||
import 'package:genshindb/application/bloc.dart'; | ||
import 'package:genshindb/domain/enums/enums.dart'; | ||
import 'package:genshindb/domain/enums/material_type.dart' as mat; | ||
import 'package:genshindb/generated/l10n.dart'; | ||
import 'package:genshindb/presentation/shared/common_bottom_sheet.dart'; | ||
import 'package:genshindb/presentation/shared/extensions/i18n_extensions.dart'; | ||
import 'package:genshindb/presentation/shared/genshin_db_icons.dart'; | ||
import 'package:genshindb/presentation/shared/item_popupmenu_filter.dart'; | ||
import 'package:genshindb/presentation/shared/loading.dart'; | ||
import 'package:genshindb/presentation/shared/rarity_rating.dart'; | ||
import 'package:genshindb/presentation/shared/sort_direction_popupmenu_filter.dart'; | ||
|
||
class MaterialBottomSheet extends StatelessWidget { | ||
final ignoredSubStats = [ | ||
mat.MaterialType.others, | ||
mat.MaterialType.expWeapon, | ||
mat.MaterialType.weaponPrimary, | ||
]; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final s = S.of(context); | ||
|
||
return CommonBottomSheet( | ||
titleIcon: GenshinDb.filter, | ||
title: s.filters, | ||
onOk: () { | ||
context.read<MaterialsBloc>().add(const MaterialsEvent.applyFilterChanges()); | ||
Navigator.pop(context); | ||
}, | ||
onCancel: () { | ||
context.read<MaterialsBloc>().add(const MaterialsEvent.cancelChanges()); | ||
Navigator.pop(context); | ||
}, | ||
child: BlocBuilder<MaterialsBloc, MaterialsState>( | ||
builder: (context, state) => state.map( | ||
loading: (_) => const Loading(), | ||
loaded: (state) => Column( | ||
crossAxisAlignment: CrossAxisAlignment.stretch, | ||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||
children: [ | ||
Text(s.rarity), | ||
RarityRating( | ||
rarity: state.rarity, | ||
onRated: (v) => context.read<MaterialsBloc>().add(MaterialsEvent.rarityChanged(v)), | ||
), | ||
Text(s.others), | ||
ButtonBar( | ||
alignment: MainAxisAlignment.spaceEvenly, | ||
children: [ | ||
ItemPopupMenuFilter<mat.MaterialType>( | ||
tooltipText: s.secondaryState, | ||
onSelected: (v) => context.read<MaterialsBloc>().add(MaterialsEvent.typeChanged(v)), | ||
selectedValue: state.tempType, | ||
values: mat.MaterialType.values.where((el) => !ignoredSubStats.contains(el)).toList(), | ||
itemText: (val) => s.translateMaterialType(val), | ||
icon: const Icon(GenshinDb.sliders_h, size: 18), | ||
), | ||
ItemPopupMenuFilter<MaterialFilterType>( | ||
tooltipText: s.sortBy, | ||
onSelected: (v) => context.read<MaterialsBloc>().add(MaterialsEvent.filterTypeChanged(v)), | ||
selectedValue: state.tempFilterType, | ||
values: MaterialFilterType.values, | ||
itemText: (val) => s.translateMaterialFilterType(val), | ||
), | ||
SortDirectionPopupMenuFilter( | ||
selectedSortDirection: state.tempSortDirectionType, | ||
onSelected: (v) => context.read<MaterialsBloc>().add(MaterialsEvent.sortDirectionTypeChanged(v)), | ||
) | ||
], | ||
), | ||
], | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:genshindb/domain/models/materials/material_card_model.dart'; | ||
import 'package:genshindb/presentation/shared/extensions/rarity_extensions.dart'; | ||
import 'package:genshindb/presentation/shared/gradient_card.dart'; | ||
import 'package:genshindb/presentation/shared/styles.dart'; | ||
import 'package:transparent_image/transparent_image.dart'; | ||
|
||
class MaterialCard extends StatelessWidget { | ||
final String keyName; | ||
final String name; | ||
final String image; | ||
final int rarity; | ||
final double imgWidth; | ||
final double imgHeight; | ||
final bool withoutDetails; | ||
final bool withElevation; | ||
final int quantity; | ||
|
||
const MaterialCard({ | ||
Key key, | ||
@required this.keyName, | ||
@required this.name, | ||
@required this.image, | ||
@required this.rarity, | ||
this.imgWidth = 70, | ||
this.imgHeight = 60, | ||
this.withElevation = true, | ||
}) : withoutDetails = false, | ||
quantity = -1, | ||
super(key: key); | ||
|
||
MaterialCard.item({ | ||
Key key, | ||
@required MaterialCardModel item, | ||
this.imgWidth = 70, | ||
this.imgHeight = 60, | ||
this.withElevation = true, | ||
}) : keyName = item.key, | ||
name = item.name, | ||
image = item.image, | ||
rarity = item.rarity, | ||
withoutDetails = false, | ||
quantity = -1, | ||
super(key: key); | ||
|
||
const MaterialCard.withoutDetails({ | ||
Key key, | ||
@required this.keyName, | ||
@required this.image, | ||
@required this.rarity, | ||
}) : name = null, | ||
imgWidth = 70, | ||
imgHeight = 60, | ||
withoutDetails = true, | ||
withElevation = false, | ||
quantity = -1, | ||
super(key: key); | ||
|
||
const MaterialCard.quantity({ | ||
Key key, | ||
@required this.keyName, | ||
@required this.image, | ||
@required this.rarity, | ||
@required this.quantity, | ||
}) : name = null, | ||
imgWidth = 70, | ||
imgHeight = 60, | ||
withoutDetails = true, | ||
withElevation = false, | ||
super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final theme = Theme.of(context); | ||
return InkWell( | ||
borderRadius: Styles.mainCardBorderRadius, | ||
onTap: () {}, | ||
child: GradientCard( | ||
clipBehavior: Clip.hardEdge, | ||
shape: Styles.mainCardShape, | ||
elevation: withElevation ? Styles.cardTenElevation : 0, | ||
gradient: rarity.getRarityGradient(), | ||
child: Padding( | ||
padding: withoutDetails ? Styles.edgeInsetAll5 : Styles.edgeInsetAll10, | ||
child: Column( | ||
children: [ | ||
FadeInImage( | ||
width: imgWidth, | ||
height: imgHeight, | ||
placeholder: MemoryImage(kTransparentImage), | ||
image: AssetImage(image), | ||
), | ||
if (quantity >= 0) Text('$quantity', style: theme.textTheme.subtitle2), | ||
if (!withoutDetails) | ||
Center( | ||
child: Tooltip( | ||
message: name, | ||
child: Text( | ||
name, | ||
textAlign: TextAlign.center, | ||
style: theme.textTheme.subtitle1.copyWith(fontWeight: FontWeight.bold, color: Colors.white), | ||
overflow: TextOverflow.ellipsis, | ||
), | ||
), | ||
), | ||
], | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} |