From 330ba740efadbb8c306849ff0f5e1f0f2e0c73ee Mon Sep 17 00:00:00 2001 From: Efrain Date: Sun, 17 Jan 2021 20:42:12 -0500 Subject: [PATCH] The note in the artifacts page now shows some images --- lib/common/assets.dart | 22 +++ lib/common/enums/artifact_type.dart | 7 + lib/common/enums/material_type.dart | 1 + lib/ui/pages/elements_page.dart | 6 +- .../artifacts/artifact_bottom_sheet.dart | 102 +++++-------- .../widgets/artifacts/artifact_info_card.dart | 11 +- .../character_ascention_materials.dart | 2 +- .../characters/character_bottom_sheet.dart | 138 ++++++++---------- ...acter_detail_ascention_materials_card.dart | 6 +- .../character_detail_passive_card.dart | 2 +- ...etail_talent_ascention_materials_card.dart | 4 +- lib/ui/widgets/common/bottom_sheet_title.dart | 2 +- lib/ui/widgets/common/bullet_list.dart | 38 +++-- .../widgets/common/common_bottom_sheet.dart | 60 ++++++++ lib/ui/widgets/common/increment_button.dart | 55 +++++++ lib/ui/widgets/common/nothing_found.dart | 4 +- .../widgets/common/nothing_found_column.dart | 23 +++ lib/ui/widgets/common/rarity_rating.dart | 7 +- .../widgets/common/sliver_nothing_found.dart | 9 +- .../widgets/weapons/weapon_bottom_sheet.dart | 124 +++++++--------- ...eapon_detail_ascention_materials_card.dart | 2 +- 21 files changed, 374 insertions(+), 251 deletions(-) create mode 100644 lib/common/enums/artifact_type.dart create mode 100644 lib/ui/widgets/common/common_bottom_sheet.dart create mode 100644 lib/ui/widgets/common/increment_button.dart create mode 100644 lib/ui/widgets/common/nothing_found_column.dart diff --git a/lib/common/assets.dart b/lib/common/assets.dart index 2403dde8d..0d987d0bd 100644 --- a/lib/common/assets.dart +++ b/lib/common/assets.dart @@ -2,6 +2,7 @@ import 'enums/app_language_type.dart'; import 'enums/element_type.dart'; import 'enums/material_type.dart'; import 'enums/weapon_type.dart'; +import 'enums/artifact_type.dart'; class Assets { static String dbPath = 'assets/db'; @@ -37,6 +38,7 @@ class Assets { static String weaponBasePath = '$itemsBasePath/weapon'; static String weaponPrimaryBasePath = '$itemsBasePath/weapon_primary'; static String currencyBasePath = '$itemsBasePath/currency'; + static String othersBasePath = '$itemsBasePath/others'; static String getArtifactPath(String name) => '$artifactsBasePath/$name'; static String getCharacterPath(String name) => '$charactersBasePath/$name'; @@ -57,6 +59,7 @@ class Assets { static String getWeaponMaterialPath(String name) => '$weaponBasePath/$name'; static String getWeaponPrimaryMaterialPath(String name) => '$weaponPrimaryBasePath/$name'; static String getCurrencyMaterialPath(String name) => '$currencyBasePath/$name'; + static String getOtherMaterialPath(String name) => '$othersBasePath/$name'; static String getMaterialPath(String name, MaterialType type) { switch (type) { @@ -76,6 +79,8 @@ class Assets { return getWeaponMaterialPath(name); case MaterialType.weaponPrimary: return getWeaponPrimaryMaterialPath(name); + case MaterialType.others: + return getOtherMaterialPath(name); default: throw Exception('Invalid material type = $type'); } @@ -135,4 +140,21 @@ class Assets { static ElementType getElementTypeFromPath(String path) { return ElementType.values.firstWhere((type) => getElementPathFromType(type) == path); } + + static String getArtifactPathFromType(ArtifactType type) { + switch (type) { + case ArtifactType.clock: + return getMaterialPath('clock.png', MaterialType.others); + case ArtifactType.crown: + return getMaterialPath('crown.png', MaterialType.others); + case ArtifactType.flower: + return getMaterialPath('flower.png', MaterialType.others); + case ArtifactType.goblet: + return getMaterialPath('goblet.png', MaterialType.others); + case ArtifactType.plume: + return getMaterialPath('plume.png', MaterialType.others); + default: + throw Exception('Invalid artifact type = $type'); + } + } } diff --git a/lib/common/enums/artifact_type.dart b/lib/common/enums/artifact_type.dart new file mode 100644 index 000000000..8bfa743e7 --- /dev/null +++ b/lib/common/enums/artifact_type.dart @@ -0,0 +1,7 @@ +enum ArtifactType { + flower, + plume, + clock, + goblet, + crown, +} diff --git a/lib/common/enums/material_type.dart b/lib/common/enums/material_type.dart index 9d8865c5e..e78b88d90 100644 --- a/lib/common/enums/material_type.dart +++ b/lib/common/enums/material_type.dart @@ -7,4 +7,5 @@ enum MaterialType { weapon, weaponPrimary, currency, + others, } diff --git a/lib/ui/pages/elements_page.dart b/lib/ui/pages/elements_page.dart index fe33cebe5..a226a7ab7 100644 --- a/lib/ui/pages/elements_page.dart +++ b/lib/ui/pages/elements_page.dart @@ -27,7 +27,7 @@ class ElementsPage extends StatelessWidget { s.elementalDebuffs, style: theme.textTheme.subtitle1.copyWith(fontWeight: FontWeight.bold), ), - Text(s.elementalDebuffsExplainded) + Text(s.elementalDebuffsExplained) ], ), ), @@ -41,7 +41,7 @@ class ElementsPage extends StatelessWidget { s.elementalReactions, style: theme.textTheme.subtitle1.copyWith(fontWeight: FontWeight.bold), ), - Text(s.elementalReactionsExplainded), + Text(s.elementalReactionsExplained), ]), ), ), @@ -54,7 +54,7 @@ class ElementsPage extends StatelessWidget { s.elementalResonances, style: theme.textTheme.subtitle1.copyWith(fontWeight: FontWeight.bold), ), - Text(s.elemetalResonancesExplanined), + Text(s.elementalResonancesExplained), ]), ), ), diff --git a/lib/ui/widgets/artifacts/artifact_bottom_sheet.dart b/lib/ui/widgets/artifacts/artifact_bottom_sheet.dart index 9749484c1..538df13e1 100644 --- a/lib/ui/widgets/artifacts/artifact_bottom_sheet.dart +++ b/lib/ui/widgets/artifacts/artifact_bottom_sheet.dart @@ -5,83 +5,59 @@ import '../../../bloc/bloc.dart'; import '../../../common/enums/artifact_filter_type.dart'; import '../../../common/extensions/i18n_extensions.dart'; import '../../../common/genshin_db_icons.dart'; -import '../../../common/styles.dart'; import '../../../generated/l10n.dart'; -import '../common/bottom_sheet_title.dart'; +import '../common/common_bottom_sheet.dart'; import '../common/item_popupmenu_filter.dart'; import '../common/loading.dart'; -import '../common/modal_sheet_separator.dart'; import '../common/rarity_rating.dart'; import '../common/sort_direction_popupmenu_filter.dart'; class ArtifactBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = Theme.of(context); final s = S.of(context); - return SingleChildScrollView( - padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), - child: Container( - margin: Styles.modalBottomSheetContainerMargin, - padding: Styles.modalBottomSheetContainerPadding, - child: BlocBuilder( - builder: (context, state) { - return state.map( - loading: (_) => const Loading(), - loaded: (state) => Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ModalSheetSeparator(), - BottomSheetTitle(icon: GenshinDb.filter, title: s.filters), - Text(s.rarity), - RarityRating( - rarity: state.rarity, - onRated: (v) => context.read().add(ArtifactsEvent.rarityChanged(v)), - ), - Text(s.others), - ButtonBar( - alignment: MainAxisAlignment.spaceEvenly, - children: [ - ItemPopupMenuFilter( - tooltipText: s.sortBy, - onSelected: (v) => - context.read().add(ArtifactsEvent.artifactFilterTypeChanged(v)), - selectedValue: state.tempArtifactFilterType, - values: ArtifactFilterType.values, - itemText: (val) => s.translateArtifactFilterType(val), - ), - SortDirectionPopupMenuFilter( - selectedSortDirection: state.tempSortDirectionType, - onSelected: (v) => - context.read().add(ArtifactsEvent.sortDirectionTypeChanged(v)), - ) - ], + return CommonBottomSheet( + titleIcon: GenshinDb.filter, + title: s.filters, + onOk: () { + context.read().add(const ArtifactsEvent.applyFilterChanges()); + Navigator.pop(context); + }, + onCancel: () { + context.read().add(const ArtifactsEvent.cancelChanges()); + Navigator.pop(context); + }, + child: BlocBuilder( + 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().add(ArtifactsEvent.rarityChanged(v)), + ), + Text(s.others), + ButtonBar( + alignment: MainAxisAlignment.spaceEvenly, + children: [ + ItemPopupMenuFilter( + tooltipText: s.sortBy, + onSelected: (v) => context.read().add(ArtifactsEvent.artifactFilterTypeChanged(v)), + selectedValue: state.tempArtifactFilterType, + values: ArtifactFilterType.values, + itemText: (val) => s.translateArtifactFilterType(val), ), - ButtonBar( - buttonPadding: const EdgeInsets.symmetric(horizontal: 10), - children: [ - OutlineButton( - onPressed: () { - context.read().add(const ArtifactsEvent.cancelChanges()); - Navigator.pop(context); - }, - child: Text(s.cancel, style: TextStyle(color: theme.primaryColor)), - ), - RaisedButton( - color: theme.primaryColor, - onPressed: () { - context.read().add(const ArtifactsEvent.applyFilterChanges()); - Navigator.pop(context); - }, - child: Text(s.ok), - ) - ], + SortDirectionPopupMenuFilter( + selectedSortDirection: state.tempSortDirectionType, + onSelected: (v) => context.read().add(ArtifactsEvent.sortDirectionTypeChanged(v)), ) ], ), - ); - }, + ], + ), ), ), ); diff --git a/lib/ui/widgets/artifacts/artifact_info_card.dart b/lib/ui/widgets/artifacts/artifact_info_card.dart index 89e428ad1..c2b2c7756 100644 --- a/lib/ui/widgets/artifacts/artifact_info_card.dart +++ b/lib/ui/widgets/artifacts/artifact_info_card.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import '../../../common/assets.dart'; +import '../../../common/enums/artifact_type.dart'; import '../../../common/enums/element_type.dart'; import '../../../common/enums/stat_type.dart'; import '../../../common/extensions/i18n_extensions.dart'; @@ -47,7 +49,14 @@ class ArtifactInfoCard extends StatelessWidget { final panel = ItemExpansionPanel( title: s.note, - body: BulletList(items: considerations), + body: BulletList( + items: considerations, + iconResolver: (index) => Image.asset( + Assets.getArtifactPathFromType(ArtifactType.values[index]), + width: 24, + height: 24, + ), + ), icon: const Icon(Icons.info_outline), isCollapsed: isCollapsed, expansionCallback: expansionCallback, diff --git a/lib/ui/widgets/characters/character_ascention_materials.dart b/lib/ui/widgets/characters/character_ascention_materials.dart index 2aa911beb..45eaf63a7 100644 --- a/lib/ui/widgets/characters/character_ascention_materials.dart +++ b/lib/ui/widgets/characters/character_ascention_materials.dart @@ -24,7 +24,7 @@ class CharacterAscentionMaterials extends StatelessWidget { ) .toList(); return Tooltip( - message: s.ascentionMaterials, + message: s.ascensionMaterials, child: Wrap( alignment: WrapAlignment.spaceEvenly, crossAxisAlignment: WrapCrossAlignment.center, diff --git a/lib/ui/widgets/characters/character_bottom_sheet.dart b/lib/ui/widgets/characters/character_bottom_sheet.dart index 5488573c0..a77a059d8 100644 --- a/lib/ui/widgets/characters/character_bottom_sheet.dart +++ b/lib/ui/widgets/characters/character_bottom_sheet.dart @@ -6,13 +6,11 @@ import '../../../common/enums/character_filter_type.dart'; import '../../../common/enums/item_status_type.dart'; import '../../../common/extensions/i18n_extensions.dart'; import '../../../common/genshin_db_icons.dart'; -import '../../../common/styles.dart'; import '../../../generated/l10n.dart'; -import '../common/bottom_sheet_title.dart'; +import '../common/common_bottom_sheet.dart'; import '../common/elements_button_bar.dart'; import '../common/item_popupmenu_filter.dart'; import '../common/loading.dart'; -import '../common/modal_sheet_separator.dart'; import '../common/rarity_rating.dart'; import '../common/sort_direction_popupmenu_filter.dart'; import '../common/weapons_button_bar.dart'; @@ -22,90 +20,68 @@ class CharacterBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = Theme.of(context); final s = S.of(context); - - return SingleChildScrollView( - padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), - child: Container( - margin: Styles.modalBottomSheetContainerMargin, - padding: Styles.modalBottomSheetContainerPadding, - child: BlocBuilder( - builder: (context, state) { - return state.map( - loading: (_) => const Loading(), - loaded: (state) => Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ModalSheetSeparator(), - BottomSheetTitle(icon: GenshinDb.filter, title: s.filters), - Text(s.elements), - ElementsButtonBar( - selectedValues: state.tempElementTypes, - onClick: (v) => context.read().add(CharactersEvent.elementTypeChanged(v)), - ), - Text(s.weapons), - WeaponsButtonBar( - selectedValues: state.tempWeaponTypes, - onClick: (v) => context.read().add(CharactersEvent.weaponTypeChanged(v)), - ), - Text(s.rarity), - RarityRating( - rarity: state.rarity, - onRated: (v) => context.read().add(CharactersEvent.rarityChanged(v)), + return CommonBottomSheet( + titleIcon: GenshinDb.filter, + title: s.filters, + onOk: () { + context.read().add(const CharactersEvent.applyFilterChanges()); + Navigator.pop(context); + }, + onCancel: () { + context.read().add(const CharactersEvent.cancelChanges()); + Navigator.pop(context); + }, + child: BlocBuilder( + builder: (context, state) => state.map( + loading: (_) => const Loading(), + loaded: (state) => Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text(s.elements), + ElementsButtonBar( + selectedValues: state.tempElementTypes, + onClick: (v) => context.read().add(CharactersEvent.elementTypeChanged(v)), + ), + Text(s.weapons), + WeaponsButtonBar( + selectedValues: state.tempWeaponTypes, + onClick: (v) => context.read().add(CharactersEvent.weaponTypeChanged(v)), + ), + Text(s.rarity), + RarityRating( + rarity: state.rarity, + onRated: (v) => context.read().add(CharactersEvent.rarityChanged(v)), + ), + Text(s.others), + ButtonBar( + alignment: MainAxisAlignment.spaceEvenly, + children: [ + ItemPopupMenuFilter( + tooltipText: '${s.released} / ${s.brandNew} / ${s.comingSoon}', + values: ItemStatusType.values, + selectedValue: state.tempStatusType, + onSelected: (v) => context.read().add(CharactersEvent.itemStatusChanged(v)), + icon: const Icon(GenshinDb.sliders_h, size: 18), + itemText: (val) => s.translateReleasedUnreleasedType(val), ), - Text(s.others), - ButtonBar( - alignment: MainAxisAlignment.spaceEvenly, - children: [ - ItemPopupMenuFilter( - tooltipText: '${s.released} / ${s.brandNew} / ${s.comingSoon}', - values: ItemStatusType.values, - selectedValue: state.tempStatusType, - onSelected: (v) => context.read().add(CharactersEvent.itemStatusChanged(v)), - icon: const Icon(GenshinDb.sliders_h, size: 18), - itemText: (val) => s.translateReleasedUnreleasedType(val), - ), - ItemPopupMenuFilter( - tooltipText: s.sortBy, - values: CharacterFilterType.values, - selectedValue: state.tempCharacterFilterType, - onSelected: (v) => - context.read().add(CharactersEvent.characterFilterTypeChanged(v)), - itemText: (val) => s.translateCharacterFilterType(val), - ), - SortDirectionPopupMenuFilter( - selectedSortDirection: state.tempSortDirectionType, - onSelected: (v) => - context.read().add(CharactersEvent.sortDirectionTypeChanged(v)), - ) - ], + ItemPopupMenuFilter( + tooltipText: s.sortBy, + values: CharacterFilterType.values, + selectedValue: state.tempCharacterFilterType, + onSelected: (v) => + context.read().add(CharactersEvent.characterFilterTypeChanged(v)), + itemText: (val) => s.translateCharacterFilterType(val), ), - ButtonBar( - buttonPadding: const EdgeInsets.symmetric(horizontal: 10), - children: [ - OutlineButton( - onPressed: () { - context.read().add(const CharactersEvent.cancelChanges()); - Navigator.pop(context); - }, - child: Text(s.cancel, style: TextStyle(color: theme.primaryColor)), - ), - RaisedButton( - color: theme.primaryColor, - onPressed: () { - context.read().add(const CharactersEvent.applyFilterChanges()); - Navigator.pop(context); - }, - child: Text(s.ok), - ) - ], + SortDirectionPopupMenuFilter( + selectedSortDirection: state.tempSortDirectionType, + onSelected: (v) => context.read().add(CharactersEvent.sortDirectionTypeChanged(v)), ) ], ), - ); - }, + ], + ), ), ), ); diff --git a/lib/ui/widgets/characters/character_detail_ascention_materials_card.dart b/lib/ui/widgets/characters/character_detail_ascention_materials_card.dart index ac043b0db..9ada4b60a 100644 --- a/lib/ui/widgets/characters/character_detail_ascention_materials_card.dart +++ b/lib/ui/widgets/characters/character_detail_ascention_materials_card.dart @@ -57,18 +57,18 @@ class CharacterDetailAscentionMaterialsCard extends StatelessWidget { ), ], ), - ...ascentionMaterials.map((e) => _buildAscentionRow(e)).toList(), + ...ascentionMaterials.map((e) => _buildAscensionRow(e)).toList(), ], ), ); return ItemDescriptionDetail( - title: s.ascentionMaterials, + title: s.ascensionMaterials, body: body, textColor: elementType.getElementColorFromContext(context), ); } - TableRow _buildAscentionRow(CharacterFileAscentionMaterialModel model) { + TableRow _buildAscensionRow(CharacterFileAscentionMaterialModel model) { final materials = model.materials .map( (m) => WrappedAscentionMaterial(image: m.fullImagePath, quantity: m.quantity), diff --git a/lib/ui/widgets/characters/character_detail_passive_card.dart b/lib/ui/widgets/characters/character_detail_passive_card.dart index df0325445..9bcec463e 100644 --- a/lib/ui/widgets/characters/character_detail_passive_card.dart +++ b/lib/ui/widgets/characters/character_detail_passive_card.dart @@ -33,7 +33,7 @@ class CharacterDetailPassiveCard extends StatelessWidget { Widget _buildPassiveCard(CharacterPassiveTalentModel model, BuildContext context) { final s = S.of(context); final theme = Theme.of(context); - final unlockedAt = model.unlockedAt >= 1 ? s.unclockedAtAscentionLevelX(model.unlockedAt) : s.unlockedAutomatically; + final unlockedAt = model.unlockedAt >= 1 ? s.unlockedAtAscensionLevelX(model.unlockedAt) : s.unlockedAutomatically; return Card( elevation: Styles.cardTenElevation, margin: Styles.edgeInsetAll5, diff --git a/lib/ui/widgets/characters/character_detail_talent_ascention_materials_card.dart b/lib/ui/widgets/characters/character_detail_talent_ascention_materials_card.dart index d6653940e..108f8b083 100644 --- a/lib/ui/widgets/characters/character_detail_talent_ascention_materials_card.dart +++ b/lib/ui/widgets/characters/character_detail_talent_ascention_materials_card.dart @@ -31,14 +31,14 @@ class CharacterDetailTalentAscentionMaterialsCard extends StatelessWidget { Widget build(BuildContext context) { final s = S.of(context); if (talentAscentionMaterials.isNotEmpty) { - return _buildTableCard(s.talentsAscention, talentAscentionMaterials, context); + return _buildTableCard(s.talentsAscension, talentAscentionMaterials, context); } return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ ...multiTalentAscentionMaterials - .map((e) => _buildTableCard(s.talentAscentionX(e.number), e.materials, context)) + .map((e) => _buildTableCard(s.talentAscensionX(e.number), e.materials, context)) .toList() ], ); diff --git a/lib/ui/widgets/common/bottom_sheet_title.dart b/lib/ui/widgets/common/bottom_sheet_title.dart index 20ded49ae..f22ec1b52 100644 --- a/lib/ui/widgets/common/bottom_sheet_title.dart +++ b/lib/ui/widgets/common/bottom_sheet_title.dart @@ -24,7 +24,7 @@ class BottomSheetTitle extends StatelessWidget { Expanded( child: Container( margin: const EdgeInsets.only(left: 5), - child: Text(title, style: theme.textTheme.headline6), + child: Text(title, style: theme.textTheme.headline6, overflow: TextOverflow.ellipsis), ), ), ], diff --git a/lib/ui/widgets/common/bullet_list.dart b/lib/ui/widgets/common/bullet_list.dart index 50a87e13d..4bd34bd96 100644 --- a/lib/ui/widgets/common/bullet_list.dart +++ b/lib/ui/widgets/common/bullet_list.dart @@ -1,12 +1,18 @@ import 'package:flutter/material.dart'; +import '../../../common/extensions/iterable_extensions.dart'; import '../../../common/styles.dart'; class BulletList extends StatelessWidget { final List items; + final Widget icon; + final Widget Function(int) iconResolver; + const BulletList({ Key key, @required this.items, + this.icon = const Icon(Icons.fiber_manual_record, size: 15), + this.iconResolver, }) : super(key: key); @override @@ -14,20 +20,26 @@ class BulletList extends StatelessWidget { final theme = Theme.of(context); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, - children: items - .map( - (e) => ListTile( - dense: true, - contentPadding: const EdgeInsets.only(left: 10), - visualDensity: const VisualDensity(vertical: -4), - leading: const Icon(Icons.fiber_manual_record, size: 15), - title: Transform.translate( - offset: Styles.listItemWithIconOffset, - child: Text(e, style: theme.textTheme.bodyText2.copyWith(fontSize: 11)), - ), + children: items.mapIndex( + (e, index) { + var leading = icon; + if (iconResolver != null) { + leading = iconResolver(index); + } + assert(leading != null); + + return ListTile( + dense: true, + contentPadding: const EdgeInsets.only(left: 10), + visualDensity: const VisualDensity(vertical: -4), + leading: leading, + title: Transform.translate( + offset: Styles.listItemWithIconOffset, + child: Text(e, style: theme.textTheme.bodyText2.copyWith(fontSize: 11)), ), - ) - .toList(), + ); + }, + ).toList(), ); } } diff --git a/lib/ui/widgets/common/common_bottom_sheet.dart b/lib/ui/widgets/common/common_bottom_sheet.dart new file mode 100644 index 000000000..0180d256e --- /dev/null +++ b/lib/ui/widgets/common/common_bottom_sheet.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; + +import '../../../common/styles.dart'; +import '../../../generated/l10n.dart'; +import 'bottom_sheet_title.dart'; +import 'modal_sheet_separator.dart'; + +class CommonBottomSheet extends StatelessWidget { + final String title; + final IconData titleIcon; + final Widget child; + final Function onOk; + final Function onCancel; + final double iconSize; + + const CommonBottomSheet({ + Key key, + @required this.title, + @required this.titleIcon, + @required this.onOk, + this.onCancel, + @required this.child, + this.iconSize = 25, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final s = S.of(context); + final theme = Theme.of(context); + return SingleChildScrollView( + child: Container( + margin: Styles.modalBottomSheetContainerMargin, + padding: Styles.modalBottomSheetContainerPadding, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ModalSheetSeparator(), + BottomSheetTitle(icon: titleIcon, title: title, iconSize: iconSize), + child, + ButtonBar( + buttonPadding: const EdgeInsets.symmetric(horizontal: 10), + children: [ + OutlineButton( + onPressed: () => onCancel != null ? onCancel() : Navigator.pop(context), + child: Text(s.cancel, style: TextStyle(color: theme.primaryColor)), + ), + RaisedButton( + color: theme.primaryColor, + onPressed: () => onOk(), + child: Text(s.ok), + ) + ], + ) + ], + ), + ), + ); + } +} diff --git a/lib/ui/widgets/common/increment_button.dart b/lib/ui/widgets/common/increment_button.dart new file mode 100644 index 000000000..5e5b1f9c4 --- /dev/null +++ b/lib/ui/widgets/common/increment_button.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; + +import '../../../common/styles.dart'; + +class IncrementButton extends StatelessWidget { + final String title; + final int value; + final bool incrementIsDisabled; + final bool decrementIsDisabled; + final Function(int) onMinus; + final Function(int) onAdd; + + const IncrementButton({ + Key key, + @required this.title, + @required this.value, + @required this.onMinus, + @required this.onAdd, + this.incrementIsDisabled = false, + this.decrementIsDisabled = false, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + margin: Styles.edgeInsetVertical5, + child: Column( + children: [ + Text(title), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: const EdgeInsets.only(right: 10), + child: IconButton( + icon: const Icon(Icons.exposure_minus_1_outlined), + onPressed: decrementIsDisabled ? null : () => onMinus(value - 1), + ), + ), + Text('$value'), + Container( + margin: const EdgeInsets.only(left: 10), + child: IconButton( + color: Colors.red, + icon: const Icon(Icons.exposure_plus_1_outlined), + onPressed: incrementIsDisabled ? null : () => onAdd(value + 1), + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/ui/widgets/common/nothing_found.dart b/lib/ui/widgets/common/nothing_found.dart index b612f8f0c..099e743d8 100644 --- a/lib/ui/widgets/common/nothing_found.dart +++ b/lib/ui/widgets/common/nothing_found.dart @@ -4,10 +4,12 @@ import '../../../generated/l10n.dart'; class NothingFound extends StatelessWidget { final String msg; + final IconData icon; final EdgeInsets padding; const NothingFound({ this.msg, + this.icon = Icons.info, this.padding = const EdgeInsets.only(bottom: 30, right: 20, left: 20), }); @@ -22,7 +24,7 @@ class NothingFound extends StatelessWidget { child: Column( children: [ Icon( - Icons.info, + icon, color: theme.primaryColor, size: 60, ), diff --git a/lib/ui/widgets/common/nothing_found_column.dart b/lib/ui/widgets/common/nothing_found_column.dart new file mode 100644 index 000000000..e9c2cc9a7 --- /dev/null +++ b/lib/ui/widgets/common/nothing_found_column.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +import 'nothing_found.dart'; + +class NothingFoundColumn extends StatelessWidget { + final String msg; + final IconData icon; + final EdgeInsets padding; + + const NothingFoundColumn({ + this.msg, + this.icon = Icons.info, + this.padding = const EdgeInsets.only(bottom: 30, right: 20, left: 20), + }); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [NothingFound(msg: msg, icon: icon, padding: padding)], + ); + } +} diff --git a/lib/ui/widgets/common/rarity_rating.dart b/lib/ui/widgets/common/rarity_rating.dart index 78b3a4377..5c0956d52 100644 --- a/lib/ui/widgets/common/rarity_rating.dart +++ b/lib/ui/widgets/common/rarity_rating.dart @@ -3,12 +3,16 @@ import 'package:smooth_star_rating/smooth_star_rating.dart'; class RarityRating extends StatelessWidget { final int rarity; + final int stars; + final double size; final Function(int) onRated; const RarityRating({ Key key, @required this.rarity, @required this.onRated, + this.size = 35.0, + this.stars = 5, }) : super(key: key); @override @@ -19,8 +23,9 @@ class RarityRating extends StatelessWidget { rating: rarity.toDouble(), allowHalfRating: false, onRated: (v) => onRated(v.toInt()), - size: 35.0, + size: size, color: Colors.yellow, + starCount: stars, borderColor: theme.brightness == Brightness.dark ? Colors.white : Colors.black, ), ); diff --git a/lib/ui/widgets/common/sliver_nothing_found.dart b/lib/ui/widgets/common/sliver_nothing_found.dart index 617914756..2f4fda606 100644 --- a/lib/ui/widgets/common/sliver_nothing_found.dart +++ b/lib/ui/widgets/common/sliver_nothing_found.dart @@ -1,18 +1,15 @@ import 'package:flutter/material.dart'; -import 'nothing_found.dart'; +import 'nothing_found_column.dart'; class SliverNothingFound extends StatelessWidget { const SliverNothingFound(); @override Widget build(BuildContext context) { - return SliverFillRemaining( + return const SliverFillRemaining( hasScrollBody: false, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [NothingFound()], - ), + child: NothingFoundColumn(), ); } } diff --git a/lib/ui/widgets/weapons/weapon_bottom_sheet.dart b/lib/ui/widgets/weapons/weapon_bottom_sheet.dart index d49af4e24..be07c9c26 100644 --- a/lib/ui/widgets/weapons/weapon_bottom_sheet.dart +++ b/lib/ui/widgets/weapons/weapon_bottom_sheet.dart @@ -6,12 +6,10 @@ import '../../../common/enums/stat_type.dart'; import '../../../common/enums/weapon_filter_type.dart'; import '../../../common/extensions/i18n_extensions.dart'; import '../../../common/genshin_db_icons.dart'; -import '../../../common/styles.dart'; import '../../../generated/l10n.dart'; -import '../common/bottom_sheet_title.dart'; +import '../common/common_bottom_sheet.dart'; import '../common/item_popupmenu_filter.dart'; import '../common/loading.dart'; -import '../common/modal_sheet_separator.dart'; import '../common/rarity_rating.dart'; import '../common/sort_direction_popupmenu_filter.dart'; import '../common/weapons_button_bar.dart'; @@ -20,83 +18,63 @@ class WeaponBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { final s = S.of(context); - final theme = Theme.of(context); final ignoredSubStats = [StatType.atk, StatType.critAtk, StatType.critRate, StatType.physDmgBonus]; - return SingleChildScrollView( - padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), - child: Container( - margin: Styles.modalBottomSheetContainerMargin, - padding: Styles.modalBottomSheetContainerPadding, - child: BlocBuilder( - builder: (context, state) { - return state.map( - loading: (_) => const Loading(), - loaded: (state) => Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ModalSheetSeparator(), - BottomSheetTitle(icon: GenshinDb.filter, title: s.filters), - Text(s.type), - WeaponsButtonBar( - selectedValues: state.tempWeaponTypes, - onClick: (v) => context.read().add(WeaponsEvent.weaponTypeChanged(v)), - ), - Text(s.rarity), - RarityRating( - rarity: state.rarity, - onRated: (v) => context.read().add(WeaponsEvent.rarityChanged(v)), + return CommonBottomSheet( + titleIcon: GenshinDb.filter, + title: s.filters, + onOk: () { + context.read().add(const WeaponsEvent.applyFilterChanges()); + Navigator.pop(context); + }, + onCancel: () { + context.read().add(const WeaponsEvent.cancelChanges()); + Navigator.pop(context); + }, + child: BlocBuilder( + builder: (context, state) => state.map( + loading: (_) => const Loading(), + loaded: (state) => Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text(s.type), + WeaponsButtonBar( + selectedValues: state.tempWeaponTypes, + onClick: (v) => context.read().add(WeaponsEvent.weaponTypeChanged(v)), + ), + Text(s.rarity), + RarityRating( + rarity: state.rarity, + onRated: (v) => context.read().add(WeaponsEvent.rarityChanged(v)), + ), + Text(s.others), + ButtonBar( + alignment: MainAxisAlignment.spaceEvenly, + children: [ + ItemPopupMenuFilter( + tooltipText: s.secondaryState, + onSelected: (v) => context.read().add(WeaponsEvent.weaponSubStatTypeChanged(v)), + selectedValue: state.tempWeaponSubStatType, + values: StatType.values.where((el) => !ignoredSubStats.contains(el)).toList(), + itemText: (val) => s.translateStatTypeWithoutValue(val), + icon: const Icon(GenshinDb.sliders_h, size: 18), ), - Text(s.others), - ButtonBar( - alignment: MainAxisAlignment.spaceEvenly, - children: [ - ItemPopupMenuFilter( - tooltipText: s.secondaryState, - onSelected: (v) => context.read().add(WeaponsEvent.weaponSubStatTypeChanged(v)), - selectedValue: state.tempWeaponSubStatType, - values: StatType.values.where((el) => !ignoredSubStats.contains(el)).toList(), - itemText: (val) => s.translateStatTypeWithoutValue(val), - icon: const Icon(GenshinDb.sliders_h, size: 18), - ), - ItemPopupMenuFilter( - tooltipText: s.sortBy, - onSelected: (v) => context.read().add(WeaponsEvent.weaponFilterTypeChanged(v)), - selectedValue: state.tempWeaponFilterType, - values: WeaponFilterType.values, - itemText: (val) => s.translateWeaponFilterType(val), - ), - SortDirectionPopupMenuFilter( - selectedSortDirection: state.tempSortDirectionType, - onSelected: (v) => context.read().add(WeaponsEvent.sortDirectionTypeChanged(v)), - ) - ], + ItemPopupMenuFilter( + tooltipText: s.sortBy, + onSelected: (v) => context.read().add(WeaponsEvent.weaponFilterTypeChanged(v)), + selectedValue: state.tempWeaponFilterType, + values: WeaponFilterType.values, + itemText: (val) => s.translateWeaponFilterType(val), ), - ButtonBar( - buttonPadding: const EdgeInsets.symmetric(horizontal: 10), - children: [ - OutlineButton( - onPressed: () { - context.read().add(const WeaponsEvent.cancelChanges()); - Navigator.pop(context); - }, - child: Text(s.cancel, style: TextStyle(color: theme.primaryColor)), - ), - RaisedButton( - color: theme.primaryColor, - onPressed: () { - context.read().add(const WeaponsEvent.applyFilterChanges()); - Navigator.pop(context); - }, - child: Text(s.ok), - ) - ], + SortDirectionPopupMenuFilter( + selectedSortDirection: state.tempSortDirectionType, + onSelected: (v) => context.read().add(WeaponsEvent.sortDirectionTypeChanged(v)), ) ], ), - ); - }, + ], + ), ), ), ); diff --git a/lib/ui/widgets/weapons/weapon_detail_ascention_materials_card.dart b/lib/ui/widgets/weapons/weapon_detail_ascention_materials_card.dart index f4bc3d5ec..097d20416 100644 --- a/lib/ui/widgets/weapons/weapon_detail_ascention_materials_card.dart +++ b/lib/ui/widgets/weapons/weapon_detail_ascention_materials_card.dart @@ -51,7 +51,7 @@ class WeaponDetailAscentionMaterialsCard extends StatelessWidget { ], ), ); - return ItemDescriptionDetail(title: s.ascentionMaterials, body: body, textColor: rarityColor); + return ItemDescriptionDetail(title: s.ascensionMaterials, body: body, textColor: rarityColor); } TableRow _buildStatProgressionRow(WeaponFileAscentionMaterial model) {