Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 32-improve-app-metadata
  • master
  • Release_0.0.10_10
  • Release_0.0.11_11
  • Release_0.0.12_12
  • Release_0.0.13_13
  • Release_0.0.14_14
  • Release_0.0.15_15
  • Release_0.0.16_16
  • Release_0.0.17_17
  • Release_0.0.18_18
  • Release_0.0.19_19
  • Release_0.0.20_20
  • Release_0.0.21_21
  • Release_0.0.22_22
  • Release_0.0.23_23
  • Release_0.0.24_24
  • Release_0.0.25_25
  • Release_0.0.26_26
  • Release_0.0.2_2
  • Release_0.0.3_3
  • Release_0.0.4_4
  • Release_0.0.5_5
  • Release_0.0.6_6
  • Release_0.0.7_7
  • Release_0.0.8_8
  • Release_0.0.9_9
  • Release_0.1.0_27
  • Release_0.1.1_28
  • Release_0.1.2_29
  • Release_0.2.0_30
  • Release_0.2.1_31
  • Release_0.3.0_32
  • Release_0.3.1_33
  • Release_0.4.0_34
  • Release_0.4.1_35
  • Release_0.4.2_36
  • Release_0.5.0_37
  • Release_0.6.0_38
  • Release_0.7.0_39
  • Release_0.8.0_40
  • Release_0.8.1_41
  • Release_0.8.2_42
  • Release_0.9.0_43
  • Release_0.9.1_44
45 results

Target

Select target project
  • android/org.benoitharrault.sortgame
1 result
Select Git revision
  • 32-improve-app-metadata
  • master
  • Release_0.0.10_10
  • Release_0.0.11_11
  • Release_0.0.12_12
  • Release_0.0.13_13
  • Release_0.0.14_14
  • Release_0.0.15_15
  • Release_0.0.16_16
  • Release_0.0.17_17
  • Release_0.0.18_18
  • Release_0.0.19_19
  • Release_0.0.20_20
  • Release_0.0.21_21
  • Release_0.0.22_22
  • Release_0.0.23_23
  • Release_0.0.24_24
  • Release_0.0.25_25
  • Release_0.0.26_26
  • Release_0.0.2_2
  • Release_0.0.3_3
  • Release_0.0.4_4
  • Release_0.0.5_5
  • Release_0.0.6_6
  • Release_0.0.7_7
  • Release_0.0.8_8
  • Release_0.0.9_9
  • Release_0.1.0_27
  • Release_0.1.1_28
  • Release_0.1.2_29
  • Release_0.2.0_30
  • Release_0.2.1_31
  • Release_0.3.0_32
  • Release_0.3.1_33
  • Release_0.4.0_34
  • Release_0.4.1_35
  • Release_0.4.2_36
  • Release_0.5.0_37
  • Release_0.6.0_38
  • Release_0.7.0_39
  • Release_0.8.0_40
  • Release_0.8.1_41
  • Release_0.8.2_42
  • Release_0.9.0_43
  • Release_0.9.1_44
45 results
Show changes
Showing
with 2273 additions and 90 deletions
......@@ -16,10 +16,9 @@ ICON_SIZE=192
# Game images
AVAILABLE_GAME_IMAGES="
"
# Settings images
AVAILABLES_GAME_SETTINGS="
button_back
button_start
placeholder
"
#######################################################
......@@ -64,19 +63,6 @@ function build_icon() {
optipng ${OPTIPNG_OPTIONS} ${TARGET}
}
function build_settings_icons() {
INPUT_STRING="$1"
SETTING_NAME="$(echo "${INPUT_STRING}" | cut -d":" -f1)"
SETTING_VALUES="$(echo "${INPUT_STRING}" | cut -d":" -f2 | tr "," " ")"
for SETTING_VALUE in ${SETTING_VALUES}
do
SETTING_CODE="${SETTING_NAME}_${SETTING_VALUE}"
build_icon ${CURRENT_DIR}/${SETTING_CODE}.svg ${ASSETS_DIR}/icons/${SETTING_CODE}.png
done
}
#######################################################
# Create output folders
......@@ -90,9 +76,3 @@ for GAME_IMAGE in ${AVAILABLE_GAME_IMAGES}
do
build_icon ${CURRENT_DIR}/${GAME_IMAGE}.svg ${ASSETS_DIR}/icons/${GAME_IMAGE}.png
done
# build settings images
for GAME_SETTING in ${AVAILABLES_GAME_SETTINGS}
do
build_settings_icons "${GAME_SETTING}"
done
#! /bin/bash
# Check dependencies
command -v inkscape >/dev/null 2>&1 || { echo >&2 "I require inkscape but it's not installed. Aborting."; exit 1; }
command -v scour >/dev/null 2>&1 || { echo >&2 "I require scour but it's not installed. Aborting."; exit 1; }
command -v optipng >/dev/null 2>&1 || { echo >&2 "I require optipng but it's not installed. Aborting."; exit 1; }
command -v convert >/dev/null 2>&1 || { echo >&2 "I require convert (imagemagick) but it's not installed. Aborting."; exit 1; }
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
BASE_DIR="$(dirname "${CURRENT_DIR}")"
SOURCE="${CURRENT_DIR}/icon.svg"
OPTIPNG_OPTIONS="-preserve -quiet -o7"
# optimize svg
cp ${SOURCE} ${SOURCE}.tmp
scour \
--remove-descriptive-elements \
--enable-id-stripping \
--enable-viewboxing \
--enable-comment-stripping \
--nindent=4 \
-i ${SOURCE}.tmp \
-o ${SOURCE}
rm ${SOURCE}.tmp
# build icons
function build_icon() {
ICON_SIZE="$1"
TARGET="$2"
TARGET_PNG="${TARGET}.png"
inkscape \
--export-width=${ICON_SIZE} \
--export-height=${ICON_SIZE} \
--export-filename=${TARGET_PNG} \
${SOURCE}
optipng ${OPTIPNG_OPTIONS} ${TARGET_PNG}
}
build_icon 72 ${BASE_DIR}/android/app/src/main/res/mipmap-hdpi/ic_launcher
build_icon 48 ${BASE_DIR}/android/app/src/main/res/mipmap-mdpi/ic_launcher
build_icon 96 ${BASE_DIR}/android/app/src/main/res/mipmap-xhdpi/ic_launcher
build_icon 144 ${BASE_DIR}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher
build_icon 192 ${BASE_DIR}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x=".44662" y=".89101" width="92.772" height="91.894" ry="11.689" fill="#e41578" stroke="#fff" stroke-width=".238"/><path d="m59.387 71.362c1.1248 1.1302 4.0012 1.1302 4.0012 0v-45.921c0-1.1316-2.8832-1.1316-4.0121 0l-37.693 20.918c-1.1289 1.1248-1.1479 2.9551-0.02171 4.084z" fill="#fefeff" stroke="#930e4e" stroke-linecap="round" stroke-linejoin="round" stroke-width="8.257"/><path d="m57.857 68.048c0.96243 0.96706 3.4236 0.96706 3.4236 0v-39.292c0-0.96825-2.467-0.96825-3.4329 0l-32.252 17.898c-0.96594 0.96243-0.9822 2.5285-0.01858 3.4945z" fill="#fefeff" stroke="#feffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="4.314"/></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x=".44662" y=".89101" width="92.772" height="91.894" ry="11.689" fill="#49a1ee" stroke="#fff" stroke-width=".238"/><path d="m34.852 25.44c-1.1248-1.1302-4.0012-1.1302-4.0012 0v45.921c0 1.1316 2.8832 1.1316 4.0121 0l37.693-20.918c1.1289-1.1248 1.1479-2.9551 0.02171-4.084z" fill="#fefeff" stroke="#105ca1" stroke-linecap="round" stroke-linejoin="round" stroke-width="8.257"/><path d="m36.382 28.754c-0.96243-0.96706-3.4236-0.96706-3.4236 0v39.292c0 0.96825 2.467 0.96825 3.4329 0l32.252-17.898c0.96594-0.96243 0.9822-2.5285 0.01858-3.4945z" fill="#fefeff" stroke="#feffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="4.314"/></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"/>
import 'package:sortgame/data/fetch_data_helper.dart';
import 'package:sortgame/utils/tools.dart';
class DefaultGameSettings {
static const List<String> availableParameters = [
'itemsCount',
'theme',
];
static const int itemsCountValueLow = 5;
static const int itemsCountValueMedium = 10;
static const int itemsCountValueHigh = 15;
static const int itemsCountValueVeryHigh = 20;
static const int defaultItemsCountValue = itemsCountValueMedium;
static const List<int> allowedItemsCountValues = [
itemsCountValueLow,
itemsCountValueMedium,
itemsCountValueHigh,
itemsCountValueVeryHigh,
];
static const int defaultThemeValue = 0;
static List<int> getAvailableValues(String parameterCode) {
switch (parameterCode) {
case 'itemsCount':
return DefaultGameSettings.allowedItemsCountValues;
}
switch (parameterCode) {
case 'theme':
final int count = FetchDataHelper().getThemes().length;
return List<int>.generate(count, (i) => i);
}
printlog('Did not find any available value for game parameter "$parameterCode".');
return [];
}
}
import 'package:sortgame/utils/tools.dart';
class DefaultGlobalSettings {
static const List<String> availableParameters = [];
static List<int> getAvailableValues(String parameterCode) {
printlog('Did not find any available value for global parameter "$parameterCode".');
return [];
}
}
import 'package:flutter/material.dart';
/// Colors from Tailwind CSS (v3.0) - June 2022
///
/// https://tailwindcss.com/docs/customizing-colors
const int _primaryColor = 0xFF6366F1;
const MaterialColor primarySwatch = MaterialColor(_primaryColor, <int, Color>{
50: Color(0xFFEEF2FF), // indigo-50
100: Color(0xFFE0E7FF), // indigo-100
200: Color(0xFFC7D2FE), // indigo-200
300: Color(0xFFA5B4FC), // indigo-300
400: Color(0xFF818CF8), // indigo-400
500: Color(_primaryColor), // indigo-500
600: Color(0xFF4F46E5), // indigo-600
700: Color(0xFF4338CA), // indigo-700
800: Color(0xFF3730A3), // indigo-800
900: Color(0xFF312E81), // indigo-900
});
const int _textColor = 0xFF64748B;
const MaterialColor textSwatch = MaterialColor(_textColor, <int, Color>{
50: Color(0xFFF8FAFC), // slate-50
100: Color(0xFFF1F5F9), // slate-100
200: Color(0xFFE2E8F0), // slate-200
300: Color(0xFFCBD5E1), // slate-300
400: Color(0xFF94A3B8), // slate-400
500: Color(_textColor), // slate-500
600: Color(0xFF475569), // slate-600
700: Color(0xFF334155), // slate-700
800: Color(0xFF1E293B), // slate-800
900: Color(0xFF0F172A), // slate-900
});
const Color errorColor = Color(0xFFDC2626); // red-600
final ColorScheme lightColorScheme = ColorScheme.light(
primary: primarySwatch.shade500,
secondary: primarySwatch.shade500,
onSecondary: Colors.white,
error: errorColor,
background: textSwatch.shade200,
onBackground: textSwatch.shade500,
onSurface: textSwatch.shade500,
surface: textSwatch.shade50,
surfaceVariant: Colors.white,
shadow: textSwatch.shade900.withOpacity(.1),
);
final ColorScheme darkColorScheme = ColorScheme.dark(
primary: primarySwatch.shade500,
secondary: primarySwatch.shade500,
onSecondary: Colors.white,
error: errorColor,
background: const Color(0xFF171724),
onBackground: textSwatch.shade400,
onSurface: textSwatch.shade300,
surface: const Color(0xFF262630),
surfaceVariant: const Color(0xFF282832),
shadow: textSwatch.shade900.withOpacity(.2),
);
final ThemeData lightTheme = ThemeData(
colorScheme: lightColorScheme,
fontFamily: 'Nunito',
textTheme: TextTheme(
displayLarge: TextStyle(
color: textSwatch.shade700,
fontFamily: 'Nunito',
),
displayMedium: TextStyle(
color: textSwatch.shade600,
fontFamily: 'Nunito',
),
displaySmall: TextStyle(
color: textSwatch.shade500,
fontFamily: 'Nunito',
),
headlineLarge: TextStyle(
color: textSwatch.shade700,
fontFamily: 'Nunito',
),
headlineMedium: TextStyle(
color: textSwatch.shade600,
fontFamily: 'Nunito',
),
headlineSmall: TextStyle(
color: textSwatch.shade500,
fontFamily: 'Nunito',
),
titleLarge: TextStyle(
color: textSwatch.shade700,
fontFamily: 'Nunito',
),
titleMedium: TextStyle(
color: textSwatch.shade600,
fontFamily: 'Nunito',
),
titleSmall: TextStyle(
color: textSwatch.shade500,
fontFamily: 'Nunito',
),
bodyLarge: TextStyle(
color: textSwatch.shade700,
fontFamily: 'Nunito',
),
bodyMedium: TextStyle(
color: textSwatch.shade600,
fontFamily: 'Nunito',
),
bodySmall: TextStyle(
color: textSwatch.shade500,
fontFamily: 'Nunito',
),
labelLarge: TextStyle(
color: textSwatch.shade700,
fontFamily: 'Nunito',
),
labelMedium: TextStyle(
color: textSwatch.shade600,
fontFamily: 'Nunito',
),
labelSmall: TextStyle(
color: textSwatch.shade500,
fontFamily: 'Nunito',
),
),
);
final ThemeData darkTheme = lightTheme.copyWith(
colorScheme: darkColorScheme,
textTheme: TextTheme(
displayLarge: TextStyle(
color: textSwatch.shade200,
fontFamily: 'Nunito',
),
displayMedium: TextStyle(
color: textSwatch.shade300,
fontFamily: 'Nunito',
),
displaySmall: TextStyle(
color: textSwatch.shade400,
fontFamily: 'Nunito',
),
headlineLarge: TextStyle(
color: textSwatch.shade200,
fontFamily: 'Nunito',
),
headlineMedium: TextStyle(
color: textSwatch.shade300,
fontFamily: 'Nunito',
),
headlineSmall: TextStyle(
color: textSwatch.shade400,
fontFamily: 'Nunito',
),
titleLarge: TextStyle(
color: textSwatch.shade200,
fontFamily: 'Nunito',
),
titleMedium: TextStyle(
color: textSwatch.shade300,
fontFamily: 'Nunito',
),
titleSmall: TextStyle(
color: textSwatch.shade400,
fontFamily: 'Nunito',
),
bodyLarge: TextStyle(
color: textSwatch.shade200,
fontFamily: 'Nunito',
),
bodyMedium: TextStyle(
color: textSwatch.shade300,
fontFamily: 'Nunito',
),
bodySmall: TextStyle(
color: textSwatch.shade400,
fontFamily: 'Nunito',
),
labelLarge: TextStyle(
color: textSwatch.shade200,
fontFamily: 'Nunito',
),
labelMedium: TextStyle(
color: textSwatch.shade300,
fontFamily: 'Nunito',
),
labelSmall: TextStyle(
color: textSwatch.shade400,
fontFamily: 'Nunito',
),
),
);
final ThemeData appTheme = darkTheme;
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:sortgame/models/game.dart';
import 'package:sortgame/models/settings_game.dart';
import 'package:sortgame/models/settings_global.dart';
part 'game_state.dart';
class GameCubit extends HydratedCubit<GameState> {
GameCubit()
: super(GameState(
currentGame: Game.createNull(),
));
void updateState(Game game) {
emit(GameState(
currentGame: game,
));
}
void refresh() {
final Game game = Game(
items: state.currentGame.items,
gameSettings: state.currentGame.gameSettings,
globalSettings: state.currentGame.globalSettings,
isRunning: state.currentGame.isRunning,
isFinished: state.currentGame.isFinished,
position: state.currentGame.position,
score: state.currentGame.score,
);
updateState(game);
}
void quitGame() {
state.currentGame.updateGameIsRunning(false);
refresh();
}
void increasePosition() {
if (state.currentGame.position < state.currentGame.items.length) {
state.currentGame.increasePosition();
} else {
state.currentGame.updateGameIsFinished(true);
}
refresh();
}
void increaseScore(int increment) {
state.currentGame.increaseScore(increment);
refresh();
}
void startNewGame({
required GameSettings gameSettings,
required GlobalSettings globalSettings,
}) {
Game newGame = Game.createNew(
gameSettings: gameSettings,
globalSettings: globalSettings,
);
newGame.dump();
updateState(newGame);
refresh();
}
@override
GameState? fromJson(Map<String, dynamic> json) {
Game currentGame = json['currentGame'] as Game;
return GameState(
currentGame: currentGame,
);
}
@override
Map<String, dynamic>? toJson(GameState state) {
return <String, dynamic>{
'currentGame': state.currentGame.toJson(),
};
}
}
part of 'game_cubit.dart';
@immutable
class GameState extends Equatable {
const GameState({
required this.currentGame,
});
final Game currentGame;
@override
List<dynamic> get props => <dynamic>[
currentGame,
];
Map<String, dynamic> get values => <String, dynamic>{
'currentGame': currentGame,
};
}
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:sortgame/models/settings_game.dart';
import 'package:sortgame/utils/tools.dart';
part 'settings_game_state.dart';
class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
GameSettingsCubit() : super(GameSettingsState(settings: GameSettings.createDefault()));
void setValues({
int? itemsCount,
int? theme,
}) {
emit(
GameSettingsState(
settings: GameSettings(
itemsCount: itemsCount ?? state.settings.itemsCount,
theme: theme ?? state.settings.theme,
),
),
);
}
int getParameterValue(String code) {
switch (code) {
case 'itemsCount':
return GameSettings.getItemsCountValueFromUnsafe(state.settings.itemsCount);
case 'theme':
return GameSettings.getThemeValueFromUnsafe(state.settings.theme);
}
return 0;
}
void setParameterValue(String code, int value) {
printlog('GameSettingsCubit.setParameterValue');
printlog('code: $code / value: $value');
int itemsCount = code == 'itemsCount' ? value : getParameterValue('itemsCount');
int theme = code == 'theme' ? value : getParameterValue('theme');
setValues(
itemsCount: itemsCount,
theme: theme,
);
}
@override
GameSettingsState? fromJson(Map<String, dynamic> json) {
int itemsCount = json['itemsCount'] as int;
int theme = json['theme'] as int;
return GameSettingsState(
settings: GameSettings(
itemsCount: itemsCount,
theme: theme,
),
);
}
@override
Map<String, dynamic>? toJson(GameSettingsState state) {
return <String, dynamic>{
'itemsCount': state.settings.itemsCount,
'theme': state.settings.theme,
};
}
}
part of 'settings_game_cubit.dart';
@immutable
class GameSettingsState extends Equatable {
const GameSettingsState({
required this.settings,
});
final GameSettings settings;
@override
List<dynamic> get props => <dynamic>[
settings,
];
Map<String, dynamic> get values => <String, dynamic>{
'settings': settings,
};
}
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:sortgame/models/settings_global.dart';
import 'package:sortgame/utils/tools.dart';
part 'settings_global_state.dart';
class GlobalSettingsCubit extends HydratedCubit<GlobalSettingsState> {
GlobalSettingsCubit() : super(GlobalSettingsState(settings: GlobalSettings.createDefault()));
void setValues() {
emit(
GlobalSettingsState(
settings: GlobalSettings(),
),
);
}
int getParameterValue(String code) {
switch (code) {}
return 0;
}
void setParameterValue(String code, int value) {
printlog('GlobalSettingsCubit.setParameterValue');
printlog('code: $code / value: $value');
setValues();
}
@override
GlobalSettingsState? fromJson(Map<String, dynamic> json) {
return GlobalSettingsState(
settings: GlobalSettings(),
);
}
@override
Map<String, dynamic>? toJson(GlobalSettingsState state) {
return <String, dynamic>{};
}
}
part of 'settings_global_cubit.dart';
@immutable
class GlobalSettingsState extends Equatable {
const GlobalSettingsState({
required this.settings,
});
final GlobalSettings settings;
@override
List<dynamic> get props => <dynamic>[
settings,
];
Map<String, dynamic> get values => <String, dynamic>{
'settings': settings,
};
}
import 'package:sortgame/data/game_data.dart';
import 'package:sortgame/models/data/category.dart';
import 'package:sortgame/models/data/game_item.dart';
import 'package:sortgame/models/data/game_theme.dart';
import 'package:sortgame/models/data/item.dart';
import 'package:sortgame/models/settings_game.dart';
import 'package:sortgame/utils/tools.dart';
class FetchDataHelper {
FetchDataHelper();
final List<Category> _categories = [];
List<Category> get categories => _categories;
final List<Item> _items = [];
List<Item> get items => _items;
final List<GameTheme> _themes = [];
List<GameTheme> get themes => _themes;
final List<GameItem> _mapping = [];
Category getCategory(String code) {
return _categories.firstWhere((category) => (category.key == code));
}
void init() {
try {
const gameData = GameData.data;
final Map<String, String> emojis = {};
final Map<String, dynamic> rawResources = gameData['resources'] as Map<String, dynamic>;
final Map<String, String> rawEmojis = rawResources['categories'] as Map<String, String>;
rawEmojis.forEach((categoryCode, emoji) {
emojis[categoryCode] = emoji;
});
final List<dynamic> rawCategories = gameData['categories'] as List<dynamic>;
for (var rawElement in rawCategories) {
final categoryCode = rawElement.toString();
_categories.add(Category(
key: categoryCode,
text: categoryCode,
emoji: emojis[categoryCode] ?? '',
));
}
final Map<String, dynamic> rawThemes = gameData['themes'] as Map<String, dynamic>;
rawThemes.forEach((code, rawCategories) {
final List<Category> categories = [];
for (var rawElement in rawCategories) {
final category = getCategory(rawElement.toString());
categories.add(category);
}
_themes.add(GameTheme(code: code, categories: categories));
});
final List<dynamic> rawItems = gameData['items'] as List<dynamic>;
for (var rawElement in rawItems) {
final element = rawElement.toString();
_items.add(Item(key: element, text: element));
}
final Map<String, dynamic> rawMapping = gameData['mapping'] as Map<String, dynamic>;
final Map<String, dynamic> rawMappingItems = rawMapping['items'] as Map<String, dynamic>;
rawMappingItems.forEach(
(String itemName, itemMappings) {
final List<String> rawIsCategories = [];
for (var category in itemMappings['is'] as List<dynamic>) {
rawIsCategories.add(category.toString());
}
final List<String> rawIsNotCategories = [];
for (var category in itemMappings['isnot'] as List<dynamic>) {
rawIsNotCategories.add(category.toString());
}
_mapping.add(GameItem(
item: Item(
key: itemName,
text: itemName,
),
isCategory: rawIsCategories.map((String code) => getCategory(code)).toList(),
isNotCategory: rawIsNotCategories.map((String code) => getCategory(code)).toList(),
));
},
);
} catch (e) {
printlog("$e");
}
}
List<GameItem> getItems(GameSettings gameSettings) {
if (_mapping.isEmpty) {
init();
}
final int count = gameSettings.itemsCount;
final int theme = gameSettings.theme;
List<GameItem> items = _mapping;
// Remove unwanted categories if theme is selected
if (theme != 0) {
final GameTheme gameTheme = _themes[theme];
for (GameItem item in items) {
item.isCategory.removeWhere((Category category) =>
(!gameTheme.categories.map((Category c) => c.key).contains(category.key)));
item.isNotCategory.removeWhere((Category category) =>
(!gameTheme.categories.map((Category c) => c.key).contains(category.key)));
}
}
// Remove items without enough data
items.removeWhere((GameItem gameItem) =>
(gameItem.isCategory.isEmpty || gameItem.isNotCategory.isEmpty));
items.shuffle();
return items.take(count).toList();
}
List<GameTheme> getThemes() {
if (_themes.isEmpty) {
init();
}
return _themes.toList();
}
GameTheme getTheme(int themeIndex) {
if (_themes.isEmpty) {
init();
}
return _themes[themeIndex];
}
}
This diff is collapsed.
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';
import 'provider/data.dart';
import 'screens/home.dart';
import 'package:sortgame/config/theme.dart';
import 'package:sortgame/cubit/game_cubit.dart';
import 'package:sortgame/cubit/settings_game_cubit.dart';
import 'package:sortgame/cubit/settings_global_cubit.dart';
import 'package:sortgame/ui/skeleton.dart';
void main() => runApp(MyApp());
void main() async {
// Initialize packages
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
final Directory tmpDir = await getTemporaryDirectory();
Hive.init(tmpDir.toString());
HydratedBloc.storage = await HydratedStorage.build(
storageDirectory: tmpDir,
);
runApp(
EasyLocalization(
path: 'assets/translations',
supportedLocales: const <Locale>[
Locale('en'),
Locale('fr'),
],
fallbackLocale: const Locale('en'),
useFallbackTranslations: true,
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => Data(),
child: Consumer<Data>(builder: (context, data, child) {
return MaterialApp(
return MultiBlocProvider(
providers: [
BlocProvider<GameCubit>(create: (context) => GameCubit()),
BlocProvider<GlobalSettingsCubit>(create: (context) => GlobalSettingsCubit()),
BlocProvider<GameSettingsCubit>(create: (context) => GameSettingsCubit()),
],
child: MaterialApp(
title: 'SortGame',
theme: appTheme,
home: const SkeletonScreen(),
// Localization stuff
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(),
routes: {
Home.id: (context) => Home(),
},
);
}),
);
}
}
class Category {
final String key;
final String text;
final String emoji;
const Category({
required this.key,
required this.text,
required this.emoji,
});
Map<String, dynamic> toJson() {
return {
'key': key,
'text': text,
'emoji': emoji,
};
}
@override
String toString() {
return toJson().toString();
}
}
import 'package:sortgame/models/data/category.dart';
import 'package:sortgame/models/data/item.dart';
class GameItem {
final Item item;
final List<Category> isCategory;
final List<Category> isNotCategory;
GameItem({
required this.item,
required this.isCategory,
required this.isNotCategory,
});
@override
String toString() {
return '$GameItem(${toJson()})';
}
Map<String, dynamic>? toJson() {
return <String, dynamic>{
'item': item.toJson(),
'isCategory': isCategory.toString(),
'isNotCategory': isNotCategory.toString(),
};
}
}
import 'package:sortgame/models/data/category.dart';
class GameTheme {
final String code;
final List<Category> categories;
GameTheme({
required this.code,
required this.categories,
});
@override
String toString() {
return '$GameTheme(${toJson()})';
}
Map<String, dynamic>? toJson() {
return <String, dynamic>{
'code': code,
'categories': categories.toString(),
};
}
}