Skip to content

Commit

Permalink
1.8.0 - Variety of improvements (#160)
Browse files Browse the repository at this point in the history
* adding route analytics

* showing no image if game has empty image url

* showing blank in the wheel spinner when game doesn't have image url

* adding include expansions filter

* fixing an issue with importing games after it has been added to the hive storage

* updating checkbox styles. Reducing memory used when loading player images

* adding average score precision setting
  • Loading branch information
mkieres authored Jan 2, 2023
1 parent ca21df6 commit ec592ff
Show file tree
Hide file tree
Showing 31 changed files with 599 additions and 151 deletions.
1 change: 1 addition & 0 deletions board_games_companion/lib/common/analytics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Analytics {
static const String logPlaythrough = 'log_playthough';
static const String importBggPlays = 'import_bgg_plays';
static const String openGamesPlaylist = 'open_games_playlist';
static const String selectRandomGame = 'select_random_game';

static const String routeName = 'route_name';

Expand Down
5 changes: 4 additions & 1 deletion board_games_companion/lib/common/app_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class AppText {
static const playthroughsStatisticsPagePlayerCountChartLegendFormatPlural = '%i players';

static const playthroughsGameSettingsWinningConditionSectionTitle = 'Winning Condition';
static const playthroughsGameSettingsScoreSectionTitle = 'Score';
static const playthroughsGameSettingsWinningConditionHighestScore = 'Highest score';
static const playthroughsGameSettingsWinningConditionLowestScore = 'Lowest score';

Expand Down Expand Up @@ -134,7 +135,8 @@ class AppText {
static const editPlaythroughNotesHeaderTitle = 'Notes';
static const editPlaythroughPagePlayedOnSectionTitle = 'Played on';
static const editPlaythroughPageDurationSectionTitle = 'Duration';
static const editPlaythroughPageScoresSectionTitle = 'Scores';
static const editPlaythroughPageScoreSectionTitle = 'Score';
static const editPlaythroughPageScoreSectionAverageScorePrecisionText = 'Average score precision';
static const editPlaythroughPageDeleteConfirmationDialogTitle =
'Are you sure you want to delete this playthrough?';
static const editPlaythroughPageUnsavedChangesDialogTitle = "You didn't save your changes.";
Expand Down Expand Up @@ -214,6 +216,7 @@ class AppText {
static const playsPageSelectGameTabTitle = 'Select Game';
static const playsPageGameSpinnerFilterSectionTitle = 'Filters';
static const playsPageGameSpinnerCollectionsFilter = 'Collections';
static const playsPageGameSpinnerExpansionsFilter = 'Include expansions?';
static const playsPageGameSpinnerSpinButtonText = 'Spin';
static const playsPageGameSpinnerSelectedGamePlayButtonText = 'Play';
static const playsPageGameSpinnerSelectedGameSpinAgainButtonText = 'Spin Again';
Expand Down
2 changes: 1 addition & 1 deletion board_games_companion/lib/common/dimensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Dimensions {
static const int edgeNumberOfHexagon = 6;

static const double defaultPlayerAvatarSize = 150;
static const double smallPlayerAvatarSize = 100;
static const Size smallPlayerAvatarSize = Size(100, 100);
static const double smallPlayerAvatarWithScoreSize = 140;
static const double searchResultsPlayerAvatarSize = 80;

Expand Down
4 changes: 2 additions & 2 deletions board_games_companion/lib/extensions/route_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension RouteExtensions on Route {
case SettingsPage.pageRoute:
return 'Settings';
default:
return 'Undefined';
return settings.name ?? 'Undefined';
}
}

Expand All @@ -52,7 +52,7 @@ extension RouteExtensions on Route {
case SettingsPage.pageRoute:
return 'SettingsPage';
default:
return 'Undefined';
return settings.name ?? 'Undefined';
}
}
}
3 changes: 2 additions & 1 deletion board_games_companion/lib/injectable.config.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions board_games_companion/lib/models/board_game_statistics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class BoardGameStatistics {

double? averageScore;

int averageScorePrecision = 0;

double? averageNumberOfPlayers;

List<Tuple2<Player, String>>? topScoreres;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import '../../common/hive_boxes.dart';
part 'board_game_settings.freezed.dart';
part 'board_game_settings.g.dart';

/// Settings for a board game
///
/// [averageScorePrecision] represents the number of decimal digits.
@freezed
class BoardGameSettings with _$BoardGameSettings {
@HiveType(typeId: HiveBoxes.boardGameSettingsTypeId, adapterName: 'BoardGameSettingsAdapter')
const factory BoardGameSettings({
@Default(GameWinningCondition.HighestScore) @HiveField(1) GameWinningCondition winningCondition,
@Default(0) @HiveField(2) int averageScorePrecision,
}) = _BoardGameSettings;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ mixin _$BoardGameSettings {
@HiveField(1)
GameWinningCondition get winningCondition =>
throw _privateConstructorUsedError;
@HiveField(2)
int get averageScorePrecision => throw _privateConstructorUsedError;

@JsonKey(ignore: true)
$BoardGameSettingsCopyWith<BoardGameSettings> get copyWith =>
Expand All @@ -30,7 +32,9 @@ abstract class $BoardGameSettingsCopyWith<$Res> {
factory $BoardGameSettingsCopyWith(
BoardGameSettings value, $Res Function(BoardGameSettings) then) =
_$BoardGameSettingsCopyWithImpl<$Res>;
$Res call({@HiveField(1) GameWinningCondition winningCondition});
$Res call(
{@HiveField(1) GameWinningCondition winningCondition,
@HiveField(2) int averageScorePrecision});
}

/// @nodoc
Expand All @@ -45,12 +49,17 @@ class _$BoardGameSettingsCopyWithImpl<$Res>
@override
$Res call({
Object? winningCondition = freezed,
Object? averageScorePrecision = freezed,
}) {
return _then(_value.copyWith(
winningCondition: winningCondition == freezed
? _value.winningCondition
: winningCondition // ignore: cast_nullable_to_non_nullable
as GameWinningCondition,
averageScorePrecision: averageScorePrecision == freezed
? _value.averageScorePrecision
: averageScorePrecision // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
Expand All @@ -62,7 +71,9 @@ abstract class _$$_BoardGameSettingsCopyWith<$Res>
$Res Function(_$_BoardGameSettings) then) =
__$$_BoardGameSettingsCopyWithImpl<$Res>;
@override
$Res call({@HiveField(1) GameWinningCondition winningCondition});
$Res call(
{@HiveField(1) GameWinningCondition winningCondition,
@HiveField(2) int averageScorePrecision});
}

/// @nodoc
Expand All @@ -79,12 +90,17 @@ class __$$_BoardGameSettingsCopyWithImpl<$Res>
@override
$Res call({
Object? winningCondition = freezed,
Object? averageScorePrecision = freezed,
}) {
return _then(_$_BoardGameSettings(
winningCondition: winningCondition == freezed
? _value.winningCondition
: winningCondition // ignore: cast_nullable_to_non_nullable
as GameWinningCondition,
averageScorePrecision: averageScorePrecision == freezed
? _value.averageScorePrecision
: averageScorePrecision // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
Expand All @@ -96,17 +112,21 @@ class __$$_BoardGameSettingsCopyWithImpl<$Res>
adapterName: 'BoardGameSettingsAdapter')
class _$_BoardGameSettings implements _BoardGameSettings {
const _$_BoardGameSettings(
{@HiveField(1)
this.winningCondition = GameWinningCondition.HighestScore});
{@HiveField(1) this.winningCondition = GameWinningCondition.HighestScore,
@HiveField(2) this.averageScorePrecision = 0});

@override
@JsonKey()
@HiveField(1)
final GameWinningCondition winningCondition;
@override
@JsonKey()
@HiveField(2)
final int averageScorePrecision;

@override
String toString() {
return 'BoardGameSettings(winningCondition: $winningCondition)';
return 'BoardGameSettings(winningCondition: $winningCondition, averageScorePrecision: $averageScorePrecision)';
}

@override
Expand All @@ -115,12 +135,16 @@ class _$_BoardGameSettings implements _BoardGameSettings {
(other.runtimeType == runtimeType &&
other is _$_BoardGameSettings &&
const DeepCollectionEquality()
.equals(other.winningCondition, winningCondition));
.equals(other.winningCondition, winningCondition) &&
const DeepCollectionEquality()
.equals(other.averageScorePrecision, averageScorePrecision));
}

@override
int get hashCode => Object.hash(
runtimeType, const DeepCollectionEquality().hash(winningCondition));
runtimeType,
const DeepCollectionEquality().hash(winningCondition),
const DeepCollectionEquality().hash(averageScorePrecision));

@JsonKey(ignore: true)
@override
Expand All @@ -131,13 +155,16 @@ class _$_BoardGameSettings implements _BoardGameSettings {

abstract class _BoardGameSettings implements BoardGameSettings {
const factory _BoardGameSettings(
{@HiveField(1) final GameWinningCondition winningCondition}) =
_$_BoardGameSettings;
{@HiveField(1) final GameWinningCondition winningCondition,
@HiveField(2) final int averageScorePrecision}) = _$_BoardGameSettings;

@override
@HiveField(1)
GameWinningCondition get winningCondition;
@override
@HiveField(2)
int get averageScorePrecision;
@override
@JsonKey(ignore: true)
_$$_BoardGameSettingsCopyWith<_$_BoardGameSettings> get copyWith =>
throw _privateConstructorUsedError;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -394,14 +394,15 @@ class _PlayerScoreTileState extends State<_PlayerScoreTile> {
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: Dimensions.standardSpacing),
child: SizedBox(
height: Dimensions.smallPlayerAvatarSize,
height: Dimensions.smallPlayerAvatarSize.height,
child: Row(
children: <Widget>[
SizedBox(
height: Dimensions.smallPlayerAvatarSize,
width: Dimensions.smallPlayerAvatarSize,
height: Dimensions.smallPlayerAvatarSize.height,
width: Dimensions.smallPlayerAvatarSize.width,
child: PlayerAvatar(
widget.playerScore.player,
player: widget.playerScore.player,
avatarImageSize: Dimensions.smallPlayerAvatarSize,
playerHeroIdSuffix: widget.playthroughId,
),
),
Expand Down
4 changes: 2 additions & 2 deletions board_games_companion/lib/pages/home/home_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ abstract class _HomeViewModelBase with Store {
final PlaysViewModel playthroughsHistoryViewModel;

static const Map<int, Tuple2<String, String>> _screenViewByTabIndex = {
0: Tuple2<String, String>('Games', 'GamesPage'),
0: Tuple2<String, String>('Collections', 'CollectionsPage'),
1: Tuple2<String, String>('Search', 'SearchBoardGamesPage'),
2: Tuple2<String, String>('Games History', 'PlaythroughsHistoryPage'),
2: Tuple2<String, String>('Plays', 'PlaysPage'),
3: Tuple2<String, String>('Players', 'PlayersPage'),
};

Expand Down
18 changes: 16 additions & 2 deletions board_games_companion/lib/pages/players/players_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ class _Players extends StatelessWidget {
Widget build(BuildContext context) {
players.sort((a, b) => a.name!.compareTo(b.name!));

final playerAvatarSize = MediaQuery.of(context).size.width / _numberOfPlayerColumns;

return SliverPadding(
padding: const EdgeInsets.all(Dimensions.standardSpacing),
sliver: SliverGrid.count(
Expand All @@ -290,7 +292,12 @@ class _Players extends StatelessWidget {
mainAxisSpacing: Dimensions.standardSpacing,
children: [
for (var player in players)
_Player(player: player, onPlayerTap: onPlayerTap, isEditMode: isEditMode),
_Player(
player: player,
onPlayerTap: onPlayerTap,
isEditMode: isEditMode,
avatarImageSize: Size(playerAvatarSize, playerAvatarSize),
),
],
),
);
Expand All @@ -303,12 +310,15 @@ class _Player extends StatefulWidget {
required this.player,
required this.onPlayerTap,
required this.isEditMode,
required this.avatarImageSize,
}) : super(key: key);

final Player player;
final PlayerTapped onPlayerTap;
final bool isEditMode;

final Size avatarImageSize;

@override
State<_Player> createState() => _PlayerState();
}
Expand All @@ -320,7 +330,11 @@ class _PlayerState extends State<_Player> {
Widget build(BuildContext context) {
return Stack(
children: [
PlayerAvatar(widget.player, onTap: () => _onTap()),
PlayerAvatar(
player: widget.player,
avatarImageSize: widget.avatarImageSize,
onTap: () => _onTap(),
),
if (widget.isEditMode)
Align(
alignment: Alignment.topRight,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ part 'game_spinner_filters.freezed.dart';
class GameSpinnerFilters with _$GameSpinnerFilters {
const factory GameSpinnerFilters({
required Set<CollectionType> collections,
required bool includeExpansions,
}) = _GameSpinnerFilters;

const GameSpinnerFilters._();
Expand Down
Loading

0 comments on commit ec592ff

Please sign in to comment.