From bf53f3af7959217c5bf4e6c5e3cbc04e7c56bc1b Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 20 Feb 2025 14:40:22 +0900 Subject: [PATCH 1/8] Localize text and register mise tasks --- .../analysis_view/nutrient_condition_box.dart | 3 +- lib/l10n/arbs/intl_en.arb | 9 + lib/l10n/arbs/intl_ko.arb | 9 + lib/l10n/gen/messages_all_locales.dart | 10 +- lib/l10n/gen/messages_en.dart | 302 +++++++++--------- lib/l10n/gen/messages_ko.dart | 9 +- lib/l10n/l10ns.dart | 30 +- mise.toml | 10 +- 8 files changed, 222 insertions(+), 160 deletions(-) diff --git a/lib/farm_page/edit_farm_set/components/analysis_view/nutrient_condition_box.dart b/lib/farm_page/edit_farm_set/components/analysis_view/nutrient_condition_box.dart index 4b446e9..db2713d 100644 --- a/lib/farm_page/edit_farm_set/components/analysis_view/nutrient_condition_box.dart +++ b/lib/farm_page/edit_farm_set/components/analysis_view/nutrient_condition_box.dart @@ -124,8 +124,7 @@ class NutrientConditionBox extends StatelessWidget { phrases += [ FittedBox( child: Text( - // TODO: Localize this string - '각 성장마다 선택한 비료를 $countOfNeededFertilizer번 사용해야 합니다.', + L10ns.of(context).nutrientConditionBox.secondaryText(countOfNeededFertilizer), style: TextStyle( fontFamily: FontFamily.pretendard, fontSize: 14, diff --git a/lib/l10n/arbs/intl_en.arb b/lib/l10n/arbs/intl_en.arb index cfab62b..0049718 100644 --- a/lib/l10n/arbs/intl_en.arb +++ b/lib/l10n/arbs/intl_en.arb @@ -1,6 +1,15 @@ { "@@last_modified": "2025-02-06T14:22:32.438287", "@@locale": "en", + + "L10nsNutrientConditionBoxContext_secondaryText": "You need to use the selected fertilizer {countOfNeededFertilizer} times for each growth.", + "@L10nsNutrientConditionBoxContext_secondaryText": { + "description": "It is a secondary text of nutrient condition box.", + "type": "text", + "placeholders": { + "countOfNeededFertilizer": {} + } + }, "L10nsRecipeListContext_toastMessage": "The recipe is already registered.", "@L10nsRecipeListContext_toastMessage": { "description": "It's showed up when a duplicated recipe card is registered to list.", diff --git a/lib/l10n/arbs/intl_ko.arb b/lib/l10n/arbs/intl_ko.arb index 3932889..fc33d69 100644 --- a/lib/l10n/arbs/intl_ko.arb +++ b/lib/l10n/arbs/intl_ko.arb @@ -1,6 +1,15 @@ { "@@last_modified": "2025-02-06T14:22:32.438287", "@@locale": "ko", + + "L10nsNutrientConditionBoxContext_secondaryText": "각 성장마다 선택한 비료를 {countOfNeededFertilizer}번 사용해야 합니다.", + "@L10nsNutrientConditionBoxContext_secondaryText": { + "description": "It is a secondary text of nutrient condition box.", + "type": "text", + "placeholders": { + "countOfNeededFertilizer": {} + } + }, "L10nsRecipeListContext_toastMessage": "이미 등록되어 있는 레시피입니다.", "@L10nsRecipeListContext_toastMessage": { "description": "It's showed up when a duplicated recipe card is registered to list.", diff --git a/lib/l10n/gen/messages_all_locales.dart b/lib/l10n/gen/messages_all_locales.dart index 4f66014..fac1193 100644 --- a/lib/l10n/gen/messages_all_locales.dart +++ b/lib/l10n/gen/messages_all_locales.dart @@ -15,11 +15,13 @@ import 'package:intl/src/intl_helpers.dart'; import 'messages_en.dart' as messages_en; import 'messages_ko.dart' as messages_ko; +import 'messages_messages.dart' as messages_messages; typedef Future LibraryLoader(); Map _deferredLibraries = { 'en': () => Future.value(null), 'ko': () => Future.value(null), + 'messages': () => Future.value(null), }; MessageLookupByLibrary? _findExact(String localeName) { @@ -28,6 +30,8 @@ MessageLookupByLibrary? _findExact(String localeName) { return messages_en.messages; case 'ko': return messages_ko.messages; + case 'messages': + return messages_messages.messages; default: return null; } @@ -35,14 +39,14 @@ MessageLookupByLibrary? _findExact(String localeName) { /// User programs should call this before using [localeName] for messages. Future initializeMessages(String? localeName) async { - final availableLocale = Intl.verifiedLocale( + var availableLocale = Intl.verifiedLocale( localeName, (locale) => _deferredLibraries[locale] != null, onFailure: (_) => null); if (availableLocale == null) { return Future.value(false); } - final lib = _deferredLibraries[availableLocale]; + var lib = _deferredLibraries[availableLocale]; await (lib == null ? Future.value(false) : lib()); initializeInternalMessageLookup(() => CompositeMessageLookup()); messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); @@ -58,7 +62,7 @@ bool _messagesExistFor(String locale) { } MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { - final actualLocale = Intl.verifiedLocale(locale, _messagesExistFor, + var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); if (actualLocale == null) return null; return _findExact(actualLocale); diff --git a/lib/l10n/gen/messages_en.dart b/lib/l10n/gen/messages_en.dart index aa039f5..9a1056d 100644 --- a/lib/l10n/gen/messages_en.dart +++ b/lib/l10n/gen/messages_en.dart @@ -14,159 +14,171 @@ import 'package:intl/message_lookup_by_library.dart'; final messages = MessageLookup(); -typedef String? MessageIfAbsent( - String? messageStr, List? args); +typedef String? MessageIfAbsent(String? messageStr, List? args); class MessageLookup extends MessageLookupByLibrary { @override String get localeName => 'en'; - static m0(seasonsText) => "Becomes a giant crop in the ${seasonsText}!"; + static m0(countOfNeededFertilizer) => + "You need to use the selected fertilizer ${countOfNeededFertilizer} times for each growth."; + + static m1(seasonsText) => "Becomes a giant crop in the ${seasonsText}!"; @override final Map messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { - 'L10nsRecipeListContext_toastMessage': MessageLookupByLibrary.simpleMessage('The recipe is already registered.'), - 'add': MessageLookupByLibrary.simpleMessage('Add'), - 'asparagus_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Tubular Seeds'), - 'asparagussoup_name': MessageLookupByLibrary.simpleMessage('Asparagus Soup'), - 'autumn': MessageLookupByLibrary.simpleMessage('Autumn'), - 'back_dialog_message': MessageLookupByLibrary.simpleMessage('You will lose what you are editing.'), - 'back_dialog_title': MessageLookupByLibrary.simpleMessage('Do you want to leave?'), - 'baconeggs_name': MessageLookupByLibrary.simpleMessage('Bacon and Eggs'), - 'bananajuice_name': MessageLookupByLibrary.simpleMessage('Banana Shake'), - 'bananapop_name': MessageLookupByLibrary.simpleMessage('Banana Pop'), - 'barnaclepita_name': MessageLookupByLibrary.simpleMessage('Barnacle Pita'), - 'barnaclestuffedfishhead_name': MessageLookupByLibrary.simpleMessage('Stuffed Fish Heads'), - 'barnaclesushi_name': MessageLookupByLibrary.simpleMessage('Barnacle Nigiri'), - 'barnaclinguine_name': MessageLookupByLibrary.simpleMessage('Barnacle Linguine'), - 'basic': MessageLookupByLibrary.simpleMessage('Basic'), - 'batnosehat_name': MessageLookupByLibrary.simpleMessage('Milkmade Hat'), - 'beefalofeed_name': MessageLookupByLibrary.simpleMessage('Steamed Twigs'), - 'beefalotreat_name': MessageLookupByLibrary.simpleMessage('Beefalo Treats'), - 'bonestew_name': MessageLookupByLibrary.simpleMessage('Meaty Stew'), - 'bunnystew_name': MessageLookupByLibrary.simpleMessage('Bunny Stew'), - 'butterflymuffin': MessageLookupByLibrary.simpleMessage('Butter Muffin'), - 'butterflymuffin_name': MessageLookupByLibrary.simpleMessage('Butter Muffin'), - 'californiaroll_name': MessageLookupByLibrary.simpleMessage('California Roll'), - 'cancel': MessageLookupByLibrary.simpleMessage('Cancel'), - 'carrot_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Oblong Seeds'), - 'ceviche_name': MessageLookupByLibrary.simpleMessage('Ceviche'), - 'compost': MessageLookupByLibrary.simpleMessage('Compost'), - 'compostwrap': MessageLookupByLibrary.simpleMessage('Compost Wrap'), - 'confirm': MessageLookupByLibrary.simpleMessage('Confirm'), - 'corn_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Clustered Seeds'), - 'crops': MessageLookupByLibrary.simpleMessage('Crops'), - 'delete': MessageLookupByLibrary.simpleMessage('Delete'), - 'dense': MessageLookupByLibrary.simpleMessage('Dense'), - 'done': MessageLookupByLibrary.simpleMessage('Done'), - 'dragonfruit_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Bulbous Seeds'), - 'dragonpie_name': MessageLookupByLibrary.simpleMessage('Dragonpie'), - 'durian_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Brittle Seed Pods'), - 'dustmeringue_name': MessageLookupByLibrary.simpleMessage('Amberosia'), - 'edit': MessageLookupByLibrary.simpleMessage('Edit'), - 'eggplant_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Swirly Seeds'), - 'family_condition_satisfying_text': MessageLookupByLibrary.simpleMessage('All crops satisfy family conditions!'), - 'family_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('Some crops don\'t satisfy the family condition.'), - 'family_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('At least four crops must be adjacent.'), - 'fertilizer': MessageLookupByLibrary.simpleMessage('Bucket-o-poop'), - 'fertilizer_selection_tooltip': MessageLookupByLibrary.simpleMessage('If you have multiple farms, assume that the same fertilizer is used for all of them.'), - 'fertilizers': MessageLookupByLibrary.simpleMessage('Fertilizers'), - 'figatoni_name': MessageLookupByLibrary.simpleMessage('Figatoni'), - 'figkabab_name': MessageLookupByLibrary.simpleMessage('Figkabab'), - 'fishsticks_name': MessageLookupByLibrary.simpleMessage('Fishsticks'), - 'fishtacos_name': MessageLookupByLibrary.simpleMessage('Fish Tacos'), - 'flowersalad_name': MessageLookupByLibrary.simpleMessage('Flower Salad'), - 'frogglebunwich_name': MessageLookupByLibrary.simpleMessage('Froggle Bunwich'), - 'frognewton_name': MessageLookupByLibrary.simpleMessage('Figgy Frogwich'), - 'frozenbananadaiquiri_name': MessageLookupByLibrary.simpleMessage('Frozen Banana Daiquiri'), - 'fruitmedley_name': MessageLookupByLibrary.simpleMessage('Fruit Medley'), - 'garlic_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Seed Pods'), - 'giant_crop': MessageLookupByLibrary.simpleMessage('Giant Crop'), - 'glommerfuel': MessageLookupByLibrary.simpleMessage('Glommer\'s Goop'), - 'growthFormula': MessageLookupByLibrary.simpleMessage('Growth Formula'), - 'guacamole_name': MessageLookupByLibrary.simpleMessage('Guacamole'), - 'guano': MessageLookupByLibrary.simpleMessage('Guano'), - 'hide': MessageLookupByLibrary.simpleMessage('Hide'), - 'honeyham_name': MessageLookupByLibrary.simpleMessage('Honey Ham'), - 'honeynuggets_name': MessageLookupByLibrary.simpleMessage('Honey Nuggets'), - 'hotchili_name': MessageLookupByLibrary.simpleMessage('Spicy Chili'), - 'icecream_name': MessageLookupByLibrary.simpleMessage('Ice Cream'), - 'jammypreserves_name': MessageLookupByLibrary.simpleMessage('Fist Full of Jam'), - 'jellybean_name': MessageLookupByLibrary.simpleMessage('Jellybeans'), - 'justeggs_name': MessageLookupByLibrary.simpleMessage('Plain Omelette'), - 'kabobs_name': MessageLookupByLibrary.simpleMessage('Kabobs'), - 'koalefig_trunk_name': MessageLookupByLibrary.simpleMessage('Fig-Stuffed Trunk'), - 'leafloaf_name': MessageLookupByLibrary.simpleMessage('Leafy Meatloaf'), - 'leafymeatburger_name': MessageLookupByLibrary.simpleMessage('Veggie Burger'), - 'leafymeatsouffle_name': MessageLookupByLibrary.simpleMessage('Jelly Salad'), - 'lobsterbisque_name': MessageLookupByLibrary.simpleMessage('Wobster Bisque'), - 'lobsterdinner_name': MessageLookupByLibrary.simpleMessage('Wobster Dinner'), - 'mandrakesoup_name': MessageLookupByLibrary.simpleMessage('Mandrake Soup'), - 'manure': MessageLookupByLibrary.simpleMessage('Manure'), - 'mashedpotatoes_name': MessageLookupByLibrary.simpleMessage('Creamy Potato Purée'), - 'meatballs_name': MessageLookupByLibrary.simpleMessage('Meatballs'), - 'meatysalad_name': MessageLookupByLibrary.simpleMessage('Beefy Greens'), - 'menu_cook': MessageLookupByLibrary.simpleMessage('Cook'), - 'menu_farm': MessageLookupByLibrary.simpleMessage('Farm'), - 'mix': MessageLookupByLibrary.simpleMessage('Mix'), - 'monsterlasagna_name': MessageLookupByLibrary.simpleMessage('Monster Lasagna'), - 'name': MessageLookupByLibrary.simpleMessage('name'), - 'no_crops_message': MessageLookupByLibrary.simpleMessage('There are no crops placed.'), - 'nutrient_condition_satisfying_first_text': MessageLookupByLibrary.simpleMessage('Balanced nutrients!'), - 'nutrient_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('The nutrients are not balanced.'), - 'nutrient_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('Plant complementary crops or choose the right fertilizer.'), - 'onion_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Pointy Seeds'), - 'pepper_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Lumpy Seeds'), - 'pepperpopper_name': MessageLookupByLibrary.simpleMessage('Stuffed Pepper Poppers'), - 'perogies_name': MessageLookupByLibrary.simpleMessage('Pierogi'), - 'pomegranate_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Windblown Seeds'), - 'poop': MessageLookupByLibrary.simpleMessage('Manure'), - 'potato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Fluffy Seeds'), - 'potatotornado_name': MessageLookupByLibrary.simpleMessage('Fancy Spiralled Tubers'), - 'powcake_name': MessageLookupByLibrary.simpleMessage('Powdercake'), - 'pumpkin_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Sharp Seeds'), - 'pumpkincookie_name': MessageLookupByLibrary.simpleMessage('Pumpkin Cookie'), - 'ratatouille_name': MessageLookupByLibrary.simpleMessage('Ratatouille'), - 'recipe_list_guide_message': MessageLookupByLibrary.simpleMessage('Drag and drop a recipe card.'), - 'reverse_dense': MessageLookupByLibrary.simpleMessage('Dense(flip)'), - 'rottenegg': MessageLookupByLibrary.simpleMessage('Rotten Egg'), - 'salsa_name': MessageLookupByLibrary.simpleMessage('Salsa Fresca'), - 'seafoodgumbo_name': MessageLookupByLibrary.simpleMessage('Seafood Gumbo'), - 'season': MessageLookupByLibrary.simpleMessage('Season'), - 'seasonConditionSatisfyingText': m0, - 'season_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('There are no seasons to be a giant crop.'), - 'season_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('Compose the farm with crops sharing a season.'), - 'seeds': MessageLookupByLibrary.simpleMessage('Seeds'), - 'show': MessageLookupByLibrary.simpleMessage('Show'), - 'show_hidden_items': MessageLookupByLibrary.simpleMessage('Show hidden items'), - 'show_seeds_alias': MessageLookupByLibrary.simpleMessage('Show seeds alias'), - 'shroombait_name': MessageLookupByLibrary.simpleMessage('Stuffed Night Cap'), - 'shroomcake_name': MessageLookupByLibrary.simpleMessage('Mushy Cake'), - 'soil_amender': MessageLookupByLibrary.simpleMessage('Growth Formula Starter'), - 'spoiled_fish': MessageLookupByLibrary.simpleMessage('Spoiled Fish'), - 'spoiled_fish_small': MessageLookupByLibrary.simpleMessage('Spoiled Fish Morsel'), - 'spoiled_food': MessageLookupByLibrary.simpleMessage('Rot'), - 'spring': MessageLookupByLibrary.simpleMessage('Spring'), - 'stuffedeggplant_name': MessageLookupByLibrary.simpleMessage('Stuffed Eggplant'), - 'suitable_seasons': MessageLookupByLibrary.simpleMessage('Suitable Seasons'), - 'summer': MessageLookupByLibrary.simpleMessage('Summer'), - 'surfnturf_name': MessageLookupByLibrary.simpleMessage('Surf \'n\' Turf'), - 'sweettea_name': MessageLookupByLibrary.simpleMessage('Soothing Tea'), - 'taffy_name': MessageLookupByLibrary.simpleMessage('Taffy'), - 'talleggs_name': MessageLookupByLibrary.simpleMessage('Tall Scotch Eggs'), - 'tomato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Spiky Seeds'), - 'trailmix_name': MessageLookupByLibrary.simpleMessage('Trail Mix'), - 'treegrowthsolution': MessageLookupByLibrary.simpleMessage('Tree Jam'), - 'turkeydinner_name': MessageLookupByLibrary.simpleMessage('Turkey Dinner'), - 'unagi_name': MessageLookupByLibrary.simpleMessage('Unagi'), - 'veggieomlet_name': MessageLookupByLibrary.simpleMessage('Breakfast Skillet'), - 'vegstinger_name': MessageLookupByLibrary.simpleMessage('Vegetable Stinger'), - 'waffles_name': MessageLookupByLibrary.simpleMessage('Waffles'), - 'watermelon_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Square Seeds'), - 'watermelonicle_name': MessageLookupByLibrary.simpleMessage('Melonsicle'), - 'wetgoop_name': MessageLookupByLibrary.simpleMessage('Wet Goop'), - 'winter': MessageLookupByLibrary.simpleMessage('Winter') - }; + 'L10nsNutrientConditionBoxContext_secondaryText': m0, + 'L10nsRecipeListContext_toastMessage': + MessageLookupByLibrary.simpleMessage('The recipe is already registered.'), + 'add': MessageLookupByLibrary.simpleMessage('Add'), + 'asparagus_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Tubular Seeds'), + 'asparagussoup_name': MessageLookupByLibrary.simpleMessage('Asparagus Soup'), + 'autumn': MessageLookupByLibrary.simpleMessage('Autumn'), + 'back_dialog_message': MessageLookupByLibrary.simpleMessage('You will lose what you are editing.'), + 'back_dialog_title': MessageLookupByLibrary.simpleMessage('Do you want to leave?'), + 'baconeggs_name': MessageLookupByLibrary.simpleMessage('Bacon and Eggs'), + 'bananajuice_name': MessageLookupByLibrary.simpleMessage('Banana Shake'), + 'bananapop_name': MessageLookupByLibrary.simpleMessage('Banana Pop'), + 'barnaclepita_name': MessageLookupByLibrary.simpleMessage('Barnacle Pita'), + 'barnaclestuffedfishhead_name': MessageLookupByLibrary.simpleMessage('Stuffed Fish Heads'), + 'barnaclesushi_name': MessageLookupByLibrary.simpleMessage('Barnacle Nigiri'), + 'barnaclinguine_name': MessageLookupByLibrary.simpleMessage('Barnacle Linguine'), + 'basic': MessageLookupByLibrary.simpleMessage('Basic'), + 'batnosehat_name': MessageLookupByLibrary.simpleMessage('Milkmade Hat'), + 'beefalofeed_name': MessageLookupByLibrary.simpleMessage('Steamed Twigs'), + 'beefalotreat_name': MessageLookupByLibrary.simpleMessage('Beefalo Treats'), + 'bonestew_name': MessageLookupByLibrary.simpleMessage('Meaty Stew'), + 'bunnystew_name': MessageLookupByLibrary.simpleMessage('Bunny Stew'), + 'butterflymuffin': MessageLookupByLibrary.simpleMessage('Butter Muffin'), + 'butterflymuffin_name': MessageLookupByLibrary.simpleMessage('Butter Muffin'), + 'californiaroll_name': MessageLookupByLibrary.simpleMessage('California Roll'), + 'cancel': MessageLookupByLibrary.simpleMessage('Cancel'), + 'carrot_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Oblong Seeds'), + 'ceviche_name': MessageLookupByLibrary.simpleMessage('Ceviche'), + 'compost': MessageLookupByLibrary.simpleMessage('Compost'), + 'compostwrap': MessageLookupByLibrary.simpleMessage('Compost Wrap'), + 'confirm': MessageLookupByLibrary.simpleMessage('Confirm'), + 'corn_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Clustered Seeds'), + 'crops': MessageLookupByLibrary.simpleMessage('Crops'), + 'delete': MessageLookupByLibrary.simpleMessage('Delete'), + 'dense': MessageLookupByLibrary.simpleMessage('Dense'), + 'done': MessageLookupByLibrary.simpleMessage('Done'), + 'dragonfruit_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Bulbous Seeds'), + 'dragonpie_name': MessageLookupByLibrary.simpleMessage('Dragonpie'), + 'durian_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Brittle Seed Pods'), + 'dustmeringue_name': MessageLookupByLibrary.simpleMessage('Amberosia'), + 'edit': MessageLookupByLibrary.simpleMessage('Edit'), + 'eggplant_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Swirly Seeds'), + 'family_condition_satisfying_text': + MessageLookupByLibrary.simpleMessage('All crops satisfy family conditions!'), + 'family_condition_unsatisfying_first_text': + MessageLookupByLibrary.simpleMessage('Some crops don\'t satisfy the family condition.'), + 'family_condition_unsatisfying_secondary_text': + MessageLookupByLibrary.simpleMessage('At least four crops must be adjacent.'), + 'fertilizer': MessageLookupByLibrary.simpleMessage('Bucket-o-poop'), + 'fertilizer_selection_tooltip': MessageLookupByLibrary.simpleMessage( + 'If you have multiple farms, assume that the same fertilizer is used for all of them.'), + 'fertilizers': MessageLookupByLibrary.simpleMessage('Fertilizers'), + 'figatoni_name': MessageLookupByLibrary.simpleMessage('Figatoni'), + 'figkabab_name': MessageLookupByLibrary.simpleMessage('Figkabab'), + 'fishsticks_name': MessageLookupByLibrary.simpleMessage('Fishsticks'), + 'fishtacos_name': MessageLookupByLibrary.simpleMessage('Fish Tacos'), + 'flowersalad_name': MessageLookupByLibrary.simpleMessage('Flower Salad'), + 'frogglebunwich_name': MessageLookupByLibrary.simpleMessage('Froggle Bunwich'), + 'frognewton_name': MessageLookupByLibrary.simpleMessage('Figgy Frogwich'), + 'frozenbananadaiquiri_name': MessageLookupByLibrary.simpleMessage('Frozen Banana Daiquiri'), + 'fruitmedley_name': MessageLookupByLibrary.simpleMessage('Fruit Medley'), + 'garlic_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Seed Pods'), + 'giant_crop': MessageLookupByLibrary.simpleMessage('Giant Crop'), + 'glommerfuel': MessageLookupByLibrary.simpleMessage('Glommer\'s Goop'), + 'growthFormula': MessageLookupByLibrary.simpleMessage('Growth Formula'), + 'guacamole_name': MessageLookupByLibrary.simpleMessage('Guacamole'), + 'guano': MessageLookupByLibrary.simpleMessage('Guano'), + 'hide': MessageLookupByLibrary.simpleMessage('Hide'), + 'honeyham_name': MessageLookupByLibrary.simpleMessage('Honey Ham'), + 'honeynuggets_name': MessageLookupByLibrary.simpleMessage('Honey Nuggets'), + 'hotchili_name': MessageLookupByLibrary.simpleMessage('Spicy Chili'), + 'icecream_name': MessageLookupByLibrary.simpleMessage('Ice Cream'), + 'jammypreserves_name': MessageLookupByLibrary.simpleMessage('Fist Full of Jam'), + 'jellybean_name': MessageLookupByLibrary.simpleMessage('Jellybeans'), + 'justeggs_name': MessageLookupByLibrary.simpleMessage('Plain Omelette'), + 'kabobs_name': MessageLookupByLibrary.simpleMessage('Kabobs'), + 'koalefig_trunk_name': MessageLookupByLibrary.simpleMessage('Fig-Stuffed Trunk'), + 'leafloaf_name': MessageLookupByLibrary.simpleMessage('Leafy Meatloaf'), + 'leafymeatburger_name': MessageLookupByLibrary.simpleMessage('Veggie Burger'), + 'leafymeatsouffle_name': MessageLookupByLibrary.simpleMessage('Jelly Salad'), + 'lobsterbisque_name': MessageLookupByLibrary.simpleMessage('Wobster Bisque'), + 'lobsterdinner_name': MessageLookupByLibrary.simpleMessage('Wobster Dinner'), + 'mandrakesoup_name': MessageLookupByLibrary.simpleMessage('Mandrake Soup'), + 'manure': MessageLookupByLibrary.simpleMessage('Manure'), + 'mashedpotatoes_name': MessageLookupByLibrary.simpleMessage('Creamy Potato Purée'), + 'meatballs_name': MessageLookupByLibrary.simpleMessage('Meatballs'), + 'meatysalad_name': MessageLookupByLibrary.simpleMessage('Beefy Greens'), + 'menu_cook': MessageLookupByLibrary.simpleMessage('Cook'), + 'menu_farm': MessageLookupByLibrary.simpleMessage('Farm'), + 'mix': MessageLookupByLibrary.simpleMessage('Mix'), + 'monsterlasagna_name': MessageLookupByLibrary.simpleMessage('Monster Lasagna'), + 'name': MessageLookupByLibrary.simpleMessage('name'), + 'no_crops_message': MessageLookupByLibrary.simpleMessage('There are no crops placed.'), + 'nutrient_condition_satisfying_first_text': MessageLookupByLibrary.simpleMessage('Balanced nutrients!'), + 'nutrient_condition_unsatisfying_first_text': + MessageLookupByLibrary.simpleMessage('The nutrients are not balanced.'), + 'nutrient_condition_unsatisfying_secondary_text': + MessageLookupByLibrary.simpleMessage('Plant complementary crops or choose the right fertilizer.'), + 'onion_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Pointy Seeds'), + 'pepper_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Lumpy Seeds'), + 'pepperpopper_name': MessageLookupByLibrary.simpleMessage('Stuffed Pepper Poppers'), + 'perogies_name': MessageLookupByLibrary.simpleMessage('Pierogi'), + 'pomegranate_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Windblown Seeds'), + 'poop': MessageLookupByLibrary.simpleMessage('Manure'), + 'potato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Fluffy Seeds'), + 'potatotornado_name': MessageLookupByLibrary.simpleMessage('Fancy Spiralled Tubers'), + 'powcake_name': MessageLookupByLibrary.simpleMessage('Powdercake'), + 'pumpkin_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Sharp Seeds'), + 'pumpkincookie_name': MessageLookupByLibrary.simpleMessage('Pumpkin Cookie'), + 'ratatouille_name': MessageLookupByLibrary.simpleMessage('Ratatouille'), + 'recipe_list_guide_message': MessageLookupByLibrary.simpleMessage('Drag and drop a recipe card.'), + 'reverse_dense': MessageLookupByLibrary.simpleMessage('Dense(flip)'), + 'rottenegg': MessageLookupByLibrary.simpleMessage('Rotten Egg'), + 'salsa_name': MessageLookupByLibrary.simpleMessage('Salsa Fresca'), + 'seafoodgumbo_name': MessageLookupByLibrary.simpleMessage('Seafood Gumbo'), + 'season': MessageLookupByLibrary.simpleMessage('Season'), + 'seasonConditionSatisfyingText': m1, + 'season_condition_unsatisfying_first_text': + MessageLookupByLibrary.simpleMessage('There are no seasons to be a giant crop.'), + 'season_condition_unsatisfying_secondary_text': + MessageLookupByLibrary.simpleMessage('Compose the farm with crops sharing a season.'), + 'seeds': MessageLookupByLibrary.simpleMessage('Seeds'), + 'show': MessageLookupByLibrary.simpleMessage('Show'), + 'show_hidden_items': MessageLookupByLibrary.simpleMessage('Show hidden items'), + 'show_seeds_alias': MessageLookupByLibrary.simpleMessage('Show seeds alias'), + 'shroombait_name': MessageLookupByLibrary.simpleMessage('Stuffed Night Cap'), + 'shroomcake_name': MessageLookupByLibrary.simpleMessage('Mushy Cake'), + 'soil_amender': MessageLookupByLibrary.simpleMessage('Growth Formula Starter'), + 'spoiled_fish': MessageLookupByLibrary.simpleMessage('Spoiled Fish'), + 'spoiled_fish_small': MessageLookupByLibrary.simpleMessage('Spoiled Fish Morsel'), + 'spoiled_food': MessageLookupByLibrary.simpleMessage('Rot'), + 'spring': MessageLookupByLibrary.simpleMessage('Spring'), + 'stuffedeggplant_name': MessageLookupByLibrary.simpleMessage('Stuffed Eggplant'), + 'suitable_seasons': MessageLookupByLibrary.simpleMessage('Suitable Seasons'), + 'summer': MessageLookupByLibrary.simpleMessage('Summer'), + 'surfnturf_name': MessageLookupByLibrary.simpleMessage('Surf \'n\' Turf'), + 'sweettea_name': MessageLookupByLibrary.simpleMessage('Soothing Tea'), + 'taffy_name': MessageLookupByLibrary.simpleMessage('Taffy'), + 'talleggs_name': MessageLookupByLibrary.simpleMessage('Tall Scotch Eggs'), + 'tomato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Spiky Seeds'), + 'trailmix_name': MessageLookupByLibrary.simpleMessage('Trail Mix'), + 'treegrowthsolution': MessageLookupByLibrary.simpleMessage('Tree Jam'), + 'turkeydinner_name': MessageLookupByLibrary.simpleMessage('Turkey Dinner'), + 'unagi_name': MessageLookupByLibrary.simpleMessage('Unagi'), + 'veggieomlet_name': MessageLookupByLibrary.simpleMessage('Breakfast Skillet'), + 'vegstinger_name': MessageLookupByLibrary.simpleMessage('Vegetable Stinger'), + 'waffles_name': MessageLookupByLibrary.simpleMessage('Waffles'), + 'watermelon_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Square Seeds'), + 'watermelonicle_name': MessageLookupByLibrary.simpleMessage('Melonsicle'), + 'wetgoop_name': MessageLookupByLibrary.simpleMessage('Wet Goop'), + 'winter': MessageLookupByLibrary.simpleMessage('Winter') + }; } diff --git a/lib/l10n/gen/messages_ko.dart b/lib/l10n/gen/messages_ko.dart index 66b5705..ead9785 100644 --- a/lib/l10n/gen/messages_ko.dart +++ b/lib/l10n/gen/messages_ko.dart @@ -21,13 +21,16 @@ class MessageLookup extends MessageLookupByLibrary { @override String get localeName => 'ko'; - static m0(seasonsText) => "${seasonsText}에 거대 작물이 됩니다!"; + static m0(countOfNeededFertilizer) => "각 성장마다 선택한 비료를 ${countOfNeededFertilizer}번 사용해야 합니다."; + + static m1(seasonsText) => "${seasonsText}에 거대 작물이 됩니다!"; @override final Map messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { - 'L10nsRecipeListContext_toastMessage': MessageLookupByLibrary.simpleMessage('이미 등록되어 있는 레시피입니다.'), + 'L10nsNutrientConditionBoxContext_secondaryText': m0, + 'L10nsRecipeListContext_toastMessage': MessageLookupByLibrary.simpleMessage('이미 등록되어 있는 레시피입니다.'), 'add': MessageLookupByLibrary.simpleMessage('추가'), 'asparagus_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('관모양 씨앗'), 'asparagussoup_name': MessageLookupByLibrary.simpleMessage('아스파라거스 수프'), @@ -135,7 +138,7 @@ class MessageLookup extends MessageLookupByLibrary { 'salsa_name': MessageLookupByLibrary.simpleMessage('살사 프레스카'), 'seafoodgumbo_name': MessageLookupByLibrary.simpleMessage('해산물 검보'), 'season': MessageLookupByLibrary.simpleMessage('계절'), - 'seasonConditionSatisfyingText': m0, + 'seasonConditionSatisfyingText': m1, 'season_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('거대 작물이 될 수 있는 계절이 없습니다.'), 'season_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('같은 계절의 작물들로 밭을 구성하세요.'), 'seeds': MessageLookupByLibrary.simpleMessage('씨앗'), diff --git a/lib/l10n/l10ns.dart b/lib/l10n/l10ns.dart index 2a42670..ed62f16 100644 --- a/lib/l10n/l10ns.dart +++ b/lib/l10n/l10ns.dart @@ -21,7 +21,7 @@ class _L10nsDelegate extends LocalizationsDelegate { } class L10ns { - L10ns(this.localeName); + L10ns._(this.localeName); static const LocalizationsDelegate delegate = _L10nsDelegate(); @@ -44,7 +44,7 @@ class L10ns { final String localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { - return L10ns(localeName); + return L10ns._(localeName); }); } @@ -65,10 +65,10 @@ class L10ns { } String localized(String key) { - return strings[key] as String; + return _strings[key] as String; } - Map get strings => { + Map get _strings => { "recipe_list_guide_message": Intl.message( "recipe_list_guide_message", locale: localeName, @@ -345,10 +345,10 @@ class L10ns { "winter", locale: localeName, ), - ...recipeNames, + ..._recipeNames, }; - Map get recipeNames => { + Map get _recipeNames => { "dustmeringue_name": Intl.message( "dustmeringue_name", locale: localeName, @@ -634,6 +634,8 @@ class L10ns { extension L10nsContextualizing on L10ns { L10nsRecipeListContext get recipeList => L10nsRecipeListContext(localeName); + + L10nsNutrientConditionBoxContext get nutrientConditionBox => L10nsNutrientConditionBoxContext(localeName); } class L10nsRecipeListContext { @@ -650,3 +652,19 @@ class L10nsRecipeListContext { ); } } + +class L10nsNutrientConditionBoxContext { + const L10nsNutrientConditionBoxContext(this.localeName); + + final String localeName; + + String secondaryText(int countOfNeededFertilizer) { + return Intl.message( + 'You need to use the selected fertilizer $countOfNeededFertilizer times for each growth.', + name: 'L10nsNutrientConditionBoxContext_secondaryText', + desc: 'It is a secondary text of nutrient condition box.', + args: [countOfNeededFertilizer], + locale: localeName, + ); + } +} diff --git a/mise.toml b/mise.toml index a9ea6be..b9fd634 100644 --- a/mise.toml +++ b/mise.toml @@ -14,4 +14,12 @@ git push [tasks.run-web-release] description = 'Run for web server with given ip-address on release. | [ip_address]' -run = 'flutter run -d web-server --web-hostname {{arg()}} --web-port 8080 --release' \ No newline at end of file +run = 'flutter run -d web-server --web-hostname {{arg()}} --web-port 8080 --release' + +[tasks.extract_to_arb] +description = 'Generate a `.arb` file from `l10ns.dart`' +run = 'dart run intl_translation:extract_to_arb --output-dir lib/l10n/arbs lib/l10n/l10ns.dart' + +[tasks.generate_from_arb] +description = 'Generate message lookup classes from `.arb` translation files' +run = 'dart run intl_translation:generate_from_arb lib/l10n/l10ns.dart lib/l10n/arbs/intl_*.arb --output-dir=lib/l10n/gen --no-use-deferred-loading' From e7b80bd033bb3f66078e731b0d9498cc02010fa5 Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 20 Feb 2025 17:34:17 +0900 Subject: [PATCH 2/8] Add a tooltip in the footer of `FarmCard` --- .../recipe_card/default_recipe_card.dart | 2 +- .../recipe_card/detail_recipe_card.dart | 2 +- .../recipe_card/simple_recipe_card.dart | 2 +- .../farm_grid/farm_card/farm_card.dart | 42 ++- lib/l10n/arbs/intl_en.arb | 9 + lib/l10n/arbs/intl_ko.arb | 9 + lib/l10n/gen/messages_en.dart | 306 +++++++++--------- lib/l10n/gen/messages_ko.dart | 11 +- lib/l10n/l10ns.dart | 23 ++ lib/utils/etc.dart | 39 ++- mise.toml | 5 +- pubspec.lock | 2 +- pubspec.yaml | 1 + test/utils_test.dart | 25 ++ 14 files changed, 295 insertions(+), 183 deletions(-) create mode 100644 test/utils_test.dart diff --git a/lib/cook_page/recipe_card/default_recipe_card.dart b/lib/cook_page/recipe_card/default_recipe_card.dart index 01ade2a..ac59af1 100644 --- a/lib/cook_page/recipe_card/default_recipe_card.dart +++ b/lib/cook_page/recipe_card/default_recipe_card.dart @@ -35,7 +35,7 @@ class DefaultRecipeCard extends StatelessWidget { mainAxisSize: MainAxisSize.min, spacing: spacing, children: [ - _TitleBox(keepKoreanWord(L10ns.of(context).localized('${recipe.code}_name'))), + _TitleBox(L10ns.of(context).localized('${recipe.code}_name').untruncatedKoreanByNewline), Image.asset( 'assets/images/items/${recipe.assetName}.png', width: imageSize, diff --git a/lib/cook_page/recipe_card/detail_recipe_card.dart b/lib/cook_page/recipe_card/detail_recipe_card.dart index 0f5b286..618c681 100644 --- a/lib/cook_page/recipe_card/detail_recipe_card.dart +++ b/lib/cook_page/recipe_card/detail_recipe_card.dart @@ -35,7 +35,7 @@ class DetailRecipeCard extends StatelessWidget { mainAxisSize: MainAxisSize.min, spacing: spacing, children: [ - _TitleBox(keepKoreanWord(L10ns.of(context).localized('${recipe.code}_name'))), + _TitleBox(L10ns.of(context).localized('${recipe.code}_name').untruncatedKoreanByNewline), Image.asset( 'assets/images/items/${recipe.assetName}.png', width: imageSize, diff --git a/lib/cook_page/recipe_card/simple_recipe_card.dart b/lib/cook_page/recipe_card/simple_recipe_card.dart index b117647..d56ace7 100644 --- a/lib/cook_page/recipe_card/simple_recipe_card.dart +++ b/lib/cook_page/recipe_card/simple_recipe_card.dart @@ -33,7 +33,7 @@ class SimpleRecipeCard extends StatelessWidget { mainAxisSize: MainAxisSize.min, spacing: spacing, children: [ - _TitleBox(keepKoreanWord(L10ns.of(context).localized('${recipe.code}_name'))), + _TitleBox(L10ns.of(context).localized('${recipe.code}_name').untruncatedKoreanByNewline), Image.asset( 'assets/images/items/${recipe.assetName}.png', width: imageSize, diff --git a/lib/farm_page/farm_grid/farm_card/farm_card.dart b/lib/farm_page/farm_grid/farm_card/farm_card.dart index 214017a..9383c6c 100644 --- a/lib/farm_page/farm_grid/farm_card/farm_card.dart +++ b/lib/farm_page/farm_grid/farm_card/farm_card.dart @@ -61,8 +61,14 @@ class _FarmCardFooter extends StatelessWidget { Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; final model = context.watch(); - final fertilizerAsset = model.linkedFertilizer?.fertilizer.assetName; - final fertilizerAmount = model.linkedFertilizer?.amount; + + final linkedFertilizer = model.linkedFertilizer; + + if (linkedFertilizer == null) { + return const SizedBox(); + } + + final fertilizerName = L10ns.of(context).localized(linkedFertilizer.fertilizer.code); return Container( height: 44, @@ -70,22 +76,24 @@ class _FarmCardFooter extends StatelessWidget { padding: const EdgeInsets.all(4), color: colorScheme.surfaceContainerHighest, child: Center( - // TODO: Wrap below Row with Tooltip. - child: Row( - spacing: 4, - mainAxisSize: MainAxisSize.min, - children: [ - Image( - image: AssetImage('assets/images/items/$fertilizerAsset.png'), - ), - Text( - 'x $fertilizerAmount', - style: const TextStyle( - fontFamily: FontFamily.pretendard, - fontSize: 14, + child: Tooltip( + message: L10ns.of(context).farmCard.footerFertilizerTooltip(fertilizerName, linkedFertilizer.amount), + child: Row( + spacing: 4, + mainAxisSize: MainAxisSize.min, + children: [ + Image( + image: AssetImage('assets/images/items/${linkedFertilizer.fertilizer.assetName}.png'), ), - ), - ], + Text( + 'x ${linkedFertilizer.amount}', + style: const TextStyle( + fontFamily: FontFamily.pretendard, + fontSize: 14, + ), + ), + ], + ), ), ), ); diff --git a/lib/l10n/arbs/intl_en.arb b/lib/l10n/arbs/intl_en.arb index 0049718..7d294b2 100644 --- a/lib/l10n/arbs/intl_en.arb +++ b/lib/l10n/arbs/intl_en.arb @@ -2,6 +2,15 @@ "@@last_modified": "2025-02-06T14:22:32.438287", "@@locale": "en", + "L10nsFarmCardContext_footerFertilizerTooltip": "You need to use {fertilizerName} {countOfNeededFertilizer} times for each growth to get giant crops.", + "@L10nsFarmCardContext_footerFertilizerTooltip": { + "description": "It is a tooltip message of the fertilizer in farm card's footer.", + "type": "text", + "placeholders": { + "fertilizerName": {}, + "countOfNeededFertilizer": {} + } + }, "L10nsNutrientConditionBoxContext_secondaryText": "You need to use the selected fertilizer {countOfNeededFertilizer} times for each growth.", "@L10nsNutrientConditionBoxContext_secondaryText": { "description": "It is a secondary text of nutrient condition box.", diff --git a/lib/l10n/arbs/intl_ko.arb b/lib/l10n/arbs/intl_ko.arb index fc33d69..61650c3 100644 --- a/lib/l10n/arbs/intl_ko.arb +++ b/lib/l10n/arbs/intl_ko.arb @@ -2,6 +2,15 @@ "@@last_modified": "2025-02-06T14:22:32.438287", "@@locale": "ko", + "L10nsFarmCardContext_footerFertilizerTooltip": "거대 작물이 되려면 각 성장마다 {fertilizerName} {countOfNeededFertilizer}번 사용해야 합니다.", + "@L10nsFarmCardContext_footerFertilizerTooltip": { + "description": "It is a tooltip message of the fertilizer in farm card's footer.", + "type": "text", + "placeholders": { + "fertilizerName": {}, + "countOfNeededFertilizer": {} + } + }, "L10nsNutrientConditionBoxContext_secondaryText": "각 성장마다 선택한 비료를 {countOfNeededFertilizer}번 사용해야 합니다.", "@L10nsNutrientConditionBoxContext_secondaryText": { "description": "It is a secondary text of nutrient condition box.", diff --git a/lib/l10n/gen/messages_en.dart b/lib/l10n/gen/messages_en.dart index 9a1056d..3eed6c9 100644 --- a/lib/l10n/gen/messages_en.dart +++ b/lib/l10n/gen/messages_en.dart @@ -14,171 +14,165 @@ import 'package:intl/message_lookup_by_library.dart'; final messages = MessageLookup(); -typedef String? MessageIfAbsent(String? messageStr, List? args); +typedef String? MessageIfAbsent( + String? messageStr, List? args); class MessageLookup extends MessageLookupByLibrary { @override String get localeName => 'en'; - static m0(countOfNeededFertilizer) => - "You need to use the selected fertilizer ${countOfNeededFertilizer} times for each growth."; + static m0(fertilizerName, countOfNeededFertilizer) => "You need to use ${fertilizerName} ${countOfNeededFertilizer} times for each growth to get giant crops."; - static m1(seasonsText) => "Becomes a giant crop in the ${seasonsText}!"; + static m1(countOfNeededFertilizer) => "You need to use the selected fertilizer ${countOfNeededFertilizer} times for each growth."; + + static m2(seasonsText) => "Becomes a giant crop in the ${seasonsText}!"; @override final Map messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { - 'L10nsNutrientConditionBoxContext_secondaryText': m0, - 'L10nsRecipeListContext_toastMessage': - MessageLookupByLibrary.simpleMessage('The recipe is already registered.'), - 'add': MessageLookupByLibrary.simpleMessage('Add'), - 'asparagus_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Tubular Seeds'), - 'asparagussoup_name': MessageLookupByLibrary.simpleMessage('Asparagus Soup'), - 'autumn': MessageLookupByLibrary.simpleMessage('Autumn'), - 'back_dialog_message': MessageLookupByLibrary.simpleMessage('You will lose what you are editing.'), - 'back_dialog_title': MessageLookupByLibrary.simpleMessage('Do you want to leave?'), - 'baconeggs_name': MessageLookupByLibrary.simpleMessage('Bacon and Eggs'), - 'bananajuice_name': MessageLookupByLibrary.simpleMessage('Banana Shake'), - 'bananapop_name': MessageLookupByLibrary.simpleMessage('Banana Pop'), - 'barnaclepita_name': MessageLookupByLibrary.simpleMessage('Barnacle Pita'), - 'barnaclestuffedfishhead_name': MessageLookupByLibrary.simpleMessage('Stuffed Fish Heads'), - 'barnaclesushi_name': MessageLookupByLibrary.simpleMessage('Barnacle Nigiri'), - 'barnaclinguine_name': MessageLookupByLibrary.simpleMessage('Barnacle Linguine'), - 'basic': MessageLookupByLibrary.simpleMessage('Basic'), - 'batnosehat_name': MessageLookupByLibrary.simpleMessage('Milkmade Hat'), - 'beefalofeed_name': MessageLookupByLibrary.simpleMessage('Steamed Twigs'), - 'beefalotreat_name': MessageLookupByLibrary.simpleMessage('Beefalo Treats'), - 'bonestew_name': MessageLookupByLibrary.simpleMessage('Meaty Stew'), - 'bunnystew_name': MessageLookupByLibrary.simpleMessage('Bunny Stew'), - 'butterflymuffin': MessageLookupByLibrary.simpleMessage('Butter Muffin'), - 'butterflymuffin_name': MessageLookupByLibrary.simpleMessage('Butter Muffin'), - 'californiaroll_name': MessageLookupByLibrary.simpleMessage('California Roll'), - 'cancel': MessageLookupByLibrary.simpleMessage('Cancel'), - 'carrot_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Oblong Seeds'), - 'ceviche_name': MessageLookupByLibrary.simpleMessage('Ceviche'), - 'compost': MessageLookupByLibrary.simpleMessage('Compost'), - 'compostwrap': MessageLookupByLibrary.simpleMessage('Compost Wrap'), - 'confirm': MessageLookupByLibrary.simpleMessage('Confirm'), - 'corn_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Clustered Seeds'), - 'crops': MessageLookupByLibrary.simpleMessage('Crops'), - 'delete': MessageLookupByLibrary.simpleMessage('Delete'), - 'dense': MessageLookupByLibrary.simpleMessage('Dense'), - 'done': MessageLookupByLibrary.simpleMessage('Done'), - 'dragonfruit_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Bulbous Seeds'), - 'dragonpie_name': MessageLookupByLibrary.simpleMessage('Dragonpie'), - 'durian_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Brittle Seed Pods'), - 'dustmeringue_name': MessageLookupByLibrary.simpleMessage('Amberosia'), - 'edit': MessageLookupByLibrary.simpleMessage('Edit'), - 'eggplant_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Swirly Seeds'), - 'family_condition_satisfying_text': - MessageLookupByLibrary.simpleMessage('All crops satisfy family conditions!'), - 'family_condition_unsatisfying_first_text': - MessageLookupByLibrary.simpleMessage('Some crops don\'t satisfy the family condition.'), - 'family_condition_unsatisfying_secondary_text': - MessageLookupByLibrary.simpleMessage('At least four crops must be adjacent.'), - 'fertilizer': MessageLookupByLibrary.simpleMessage('Bucket-o-poop'), - 'fertilizer_selection_tooltip': MessageLookupByLibrary.simpleMessage( - 'If you have multiple farms, assume that the same fertilizer is used for all of them.'), - 'fertilizers': MessageLookupByLibrary.simpleMessage('Fertilizers'), - 'figatoni_name': MessageLookupByLibrary.simpleMessage('Figatoni'), - 'figkabab_name': MessageLookupByLibrary.simpleMessage('Figkabab'), - 'fishsticks_name': MessageLookupByLibrary.simpleMessage('Fishsticks'), - 'fishtacos_name': MessageLookupByLibrary.simpleMessage('Fish Tacos'), - 'flowersalad_name': MessageLookupByLibrary.simpleMessage('Flower Salad'), - 'frogglebunwich_name': MessageLookupByLibrary.simpleMessage('Froggle Bunwich'), - 'frognewton_name': MessageLookupByLibrary.simpleMessage('Figgy Frogwich'), - 'frozenbananadaiquiri_name': MessageLookupByLibrary.simpleMessage('Frozen Banana Daiquiri'), - 'fruitmedley_name': MessageLookupByLibrary.simpleMessage('Fruit Medley'), - 'garlic_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Seed Pods'), - 'giant_crop': MessageLookupByLibrary.simpleMessage('Giant Crop'), - 'glommerfuel': MessageLookupByLibrary.simpleMessage('Glommer\'s Goop'), - 'growthFormula': MessageLookupByLibrary.simpleMessage('Growth Formula'), - 'guacamole_name': MessageLookupByLibrary.simpleMessage('Guacamole'), - 'guano': MessageLookupByLibrary.simpleMessage('Guano'), - 'hide': MessageLookupByLibrary.simpleMessage('Hide'), - 'honeyham_name': MessageLookupByLibrary.simpleMessage('Honey Ham'), - 'honeynuggets_name': MessageLookupByLibrary.simpleMessage('Honey Nuggets'), - 'hotchili_name': MessageLookupByLibrary.simpleMessage('Spicy Chili'), - 'icecream_name': MessageLookupByLibrary.simpleMessage('Ice Cream'), - 'jammypreserves_name': MessageLookupByLibrary.simpleMessage('Fist Full of Jam'), - 'jellybean_name': MessageLookupByLibrary.simpleMessage('Jellybeans'), - 'justeggs_name': MessageLookupByLibrary.simpleMessage('Plain Omelette'), - 'kabobs_name': MessageLookupByLibrary.simpleMessage('Kabobs'), - 'koalefig_trunk_name': MessageLookupByLibrary.simpleMessage('Fig-Stuffed Trunk'), - 'leafloaf_name': MessageLookupByLibrary.simpleMessage('Leafy Meatloaf'), - 'leafymeatburger_name': MessageLookupByLibrary.simpleMessage('Veggie Burger'), - 'leafymeatsouffle_name': MessageLookupByLibrary.simpleMessage('Jelly Salad'), - 'lobsterbisque_name': MessageLookupByLibrary.simpleMessage('Wobster Bisque'), - 'lobsterdinner_name': MessageLookupByLibrary.simpleMessage('Wobster Dinner'), - 'mandrakesoup_name': MessageLookupByLibrary.simpleMessage('Mandrake Soup'), - 'manure': MessageLookupByLibrary.simpleMessage('Manure'), - 'mashedpotatoes_name': MessageLookupByLibrary.simpleMessage('Creamy Potato Purée'), - 'meatballs_name': MessageLookupByLibrary.simpleMessage('Meatballs'), - 'meatysalad_name': MessageLookupByLibrary.simpleMessage('Beefy Greens'), - 'menu_cook': MessageLookupByLibrary.simpleMessage('Cook'), - 'menu_farm': MessageLookupByLibrary.simpleMessage('Farm'), - 'mix': MessageLookupByLibrary.simpleMessage('Mix'), - 'monsterlasagna_name': MessageLookupByLibrary.simpleMessage('Monster Lasagna'), - 'name': MessageLookupByLibrary.simpleMessage('name'), - 'no_crops_message': MessageLookupByLibrary.simpleMessage('There are no crops placed.'), - 'nutrient_condition_satisfying_first_text': MessageLookupByLibrary.simpleMessage('Balanced nutrients!'), - 'nutrient_condition_unsatisfying_first_text': - MessageLookupByLibrary.simpleMessage('The nutrients are not balanced.'), - 'nutrient_condition_unsatisfying_secondary_text': - MessageLookupByLibrary.simpleMessage('Plant complementary crops or choose the right fertilizer.'), - 'onion_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Pointy Seeds'), - 'pepper_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Lumpy Seeds'), - 'pepperpopper_name': MessageLookupByLibrary.simpleMessage('Stuffed Pepper Poppers'), - 'perogies_name': MessageLookupByLibrary.simpleMessage('Pierogi'), - 'pomegranate_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Windblown Seeds'), - 'poop': MessageLookupByLibrary.simpleMessage('Manure'), - 'potato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Fluffy Seeds'), - 'potatotornado_name': MessageLookupByLibrary.simpleMessage('Fancy Spiralled Tubers'), - 'powcake_name': MessageLookupByLibrary.simpleMessage('Powdercake'), - 'pumpkin_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Sharp Seeds'), - 'pumpkincookie_name': MessageLookupByLibrary.simpleMessage('Pumpkin Cookie'), - 'ratatouille_name': MessageLookupByLibrary.simpleMessage('Ratatouille'), - 'recipe_list_guide_message': MessageLookupByLibrary.simpleMessage('Drag and drop a recipe card.'), - 'reverse_dense': MessageLookupByLibrary.simpleMessage('Dense(flip)'), - 'rottenegg': MessageLookupByLibrary.simpleMessage('Rotten Egg'), - 'salsa_name': MessageLookupByLibrary.simpleMessage('Salsa Fresca'), - 'seafoodgumbo_name': MessageLookupByLibrary.simpleMessage('Seafood Gumbo'), - 'season': MessageLookupByLibrary.simpleMessage('Season'), - 'seasonConditionSatisfyingText': m1, - 'season_condition_unsatisfying_first_text': - MessageLookupByLibrary.simpleMessage('There are no seasons to be a giant crop.'), - 'season_condition_unsatisfying_secondary_text': - MessageLookupByLibrary.simpleMessage('Compose the farm with crops sharing a season.'), - 'seeds': MessageLookupByLibrary.simpleMessage('Seeds'), - 'show': MessageLookupByLibrary.simpleMessage('Show'), - 'show_hidden_items': MessageLookupByLibrary.simpleMessage('Show hidden items'), - 'show_seeds_alias': MessageLookupByLibrary.simpleMessage('Show seeds alias'), - 'shroombait_name': MessageLookupByLibrary.simpleMessage('Stuffed Night Cap'), - 'shroomcake_name': MessageLookupByLibrary.simpleMessage('Mushy Cake'), - 'soil_amender': MessageLookupByLibrary.simpleMessage('Growth Formula Starter'), - 'spoiled_fish': MessageLookupByLibrary.simpleMessage('Spoiled Fish'), - 'spoiled_fish_small': MessageLookupByLibrary.simpleMessage('Spoiled Fish Morsel'), - 'spoiled_food': MessageLookupByLibrary.simpleMessage('Rot'), - 'spring': MessageLookupByLibrary.simpleMessage('Spring'), - 'stuffedeggplant_name': MessageLookupByLibrary.simpleMessage('Stuffed Eggplant'), - 'suitable_seasons': MessageLookupByLibrary.simpleMessage('Suitable Seasons'), - 'summer': MessageLookupByLibrary.simpleMessage('Summer'), - 'surfnturf_name': MessageLookupByLibrary.simpleMessage('Surf \'n\' Turf'), - 'sweettea_name': MessageLookupByLibrary.simpleMessage('Soothing Tea'), - 'taffy_name': MessageLookupByLibrary.simpleMessage('Taffy'), - 'talleggs_name': MessageLookupByLibrary.simpleMessage('Tall Scotch Eggs'), - 'tomato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Spiky Seeds'), - 'trailmix_name': MessageLookupByLibrary.simpleMessage('Trail Mix'), - 'treegrowthsolution': MessageLookupByLibrary.simpleMessage('Tree Jam'), - 'turkeydinner_name': MessageLookupByLibrary.simpleMessage('Turkey Dinner'), - 'unagi_name': MessageLookupByLibrary.simpleMessage('Unagi'), - 'veggieomlet_name': MessageLookupByLibrary.simpleMessage('Breakfast Skillet'), - 'vegstinger_name': MessageLookupByLibrary.simpleMessage('Vegetable Stinger'), - 'waffles_name': MessageLookupByLibrary.simpleMessage('Waffles'), - 'watermelon_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Square Seeds'), - 'watermelonicle_name': MessageLookupByLibrary.simpleMessage('Melonsicle'), - 'wetgoop_name': MessageLookupByLibrary.simpleMessage('Wet Goop'), - 'winter': MessageLookupByLibrary.simpleMessage('Winter') - }; + 'L10nsFarmCardContext_footerFertilizerTooltip': m0, + 'L10nsNutrientConditionBoxContext_secondaryText': m1, + 'L10nsRecipeListContext_toastMessage': MessageLookupByLibrary.simpleMessage('The recipe is already registered.'), + 'add': MessageLookupByLibrary.simpleMessage('Add'), + 'asparagus_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Tubular Seeds'), + 'asparagussoup_name': MessageLookupByLibrary.simpleMessage('Asparagus Soup'), + 'autumn': MessageLookupByLibrary.simpleMessage('Autumn'), + 'back_dialog_message': MessageLookupByLibrary.simpleMessage('You will lose what you are editing.'), + 'back_dialog_title': MessageLookupByLibrary.simpleMessage('Do you want to leave?'), + 'baconeggs_name': MessageLookupByLibrary.simpleMessage('Bacon and Eggs'), + 'bananajuice_name': MessageLookupByLibrary.simpleMessage('Banana Shake'), + 'bananapop_name': MessageLookupByLibrary.simpleMessage('Banana Pop'), + 'barnaclepita_name': MessageLookupByLibrary.simpleMessage('Barnacle Pita'), + 'barnaclestuffedfishhead_name': MessageLookupByLibrary.simpleMessage('Stuffed Fish Heads'), + 'barnaclesushi_name': MessageLookupByLibrary.simpleMessage('Barnacle Nigiri'), + 'barnaclinguine_name': MessageLookupByLibrary.simpleMessage('Barnacle Linguine'), + 'basic': MessageLookupByLibrary.simpleMessage('Basic'), + 'batnosehat_name': MessageLookupByLibrary.simpleMessage('Milkmade Hat'), + 'beefalofeed_name': MessageLookupByLibrary.simpleMessage('Steamed Twigs'), + 'beefalotreat_name': MessageLookupByLibrary.simpleMessage('Beefalo Treats'), + 'bonestew_name': MessageLookupByLibrary.simpleMessage('Meaty Stew'), + 'bunnystew_name': MessageLookupByLibrary.simpleMessage('Bunny Stew'), + 'butterflymuffin': MessageLookupByLibrary.simpleMessage('Butter Muffin'), + 'butterflymuffin_name': MessageLookupByLibrary.simpleMessage('Butter Muffin'), + 'californiaroll_name': MessageLookupByLibrary.simpleMessage('California Roll'), + 'cancel': MessageLookupByLibrary.simpleMessage('Cancel'), + 'carrot_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Oblong Seeds'), + 'ceviche_name': MessageLookupByLibrary.simpleMessage('Ceviche'), + 'compost': MessageLookupByLibrary.simpleMessage('Compost'), + 'compostwrap': MessageLookupByLibrary.simpleMessage('Compost Wrap'), + 'confirm': MessageLookupByLibrary.simpleMessage('Confirm'), + 'corn_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Clustered Seeds'), + 'crops': MessageLookupByLibrary.simpleMessage('Crops'), + 'delete': MessageLookupByLibrary.simpleMessage('Delete'), + 'dense': MessageLookupByLibrary.simpleMessage('Dense'), + 'done': MessageLookupByLibrary.simpleMessage('Done'), + 'dragonfruit_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Bulbous Seeds'), + 'dragonpie_name': MessageLookupByLibrary.simpleMessage('Dragonpie'), + 'durian_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Brittle Seed Pods'), + 'dustmeringue_name': MessageLookupByLibrary.simpleMessage('Amberosia'), + 'edit': MessageLookupByLibrary.simpleMessage('Edit'), + 'eggplant_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Swirly Seeds'), + 'family_condition_satisfying_text': MessageLookupByLibrary.simpleMessage('All crops satisfy family conditions!'), + 'family_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('Some crops don\'t satisfy the family condition.'), + 'family_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('At least four crops must be adjacent.'), + 'fertilizer': MessageLookupByLibrary.simpleMessage('Bucket-o-poop'), + 'fertilizer_selection_tooltip': MessageLookupByLibrary.simpleMessage('If you have multiple farms, assume that the same fertilizer is used for all of them.'), + 'fertilizers': MessageLookupByLibrary.simpleMessage('Fertilizers'), + 'figatoni_name': MessageLookupByLibrary.simpleMessage('Figatoni'), + 'figkabab_name': MessageLookupByLibrary.simpleMessage('Figkabab'), + 'fishsticks_name': MessageLookupByLibrary.simpleMessage('Fishsticks'), + 'fishtacos_name': MessageLookupByLibrary.simpleMessage('Fish Tacos'), + 'flowersalad_name': MessageLookupByLibrary.simpleMessage('Flower Salad'), + 'frogglebunwich_name': MessageLookupByLibrary.simpleMessage('Froggle Bunwich'), + 'frognewton_name': MessageLookupByLibrary.simpleMessage('Figgy Frogwich'), + 'frozenbananadaiquiri_name': MessageLookupByLibrary.simpleMessage('Frozen Banana Daiquiri'), + 'fruitmedley_name': MessageLookupByLibrary.simpleMessage('Fruit Medley'), + 'garlic_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Seed Pods'), + 'giant_crop': MessageLookupByLibrary.simpleMessage('Giant Crop'), + 'glommerfuel': MessageLookupByLibrary.simpleMessage('Glommer\'s Goop'), + 'growthFormula': MessageLookupByLibrary.simpleMessage('Growth Formula'), + 'guacamole_name': MessageLookupByLibrary.simpleMessage('Guacamole'), + 'guano': MessageLookupByLibrary.simpleMessage('Guano'), + 'hide': MessageLookupByLibrary.simpleMessage('Hide'), + 'honeyham_name': MessageLookupByLibrary.simpleMessage('Honey Ham'), + 'honeynuggets_name': MessageLookupByLibrary.simpleMessage('Honey Nuggets'), + 'hotchili_name': MessageLookupByLibrary.simpleMessage('Spicy Chili'), + 'icecream_name': MessageLookupByLibrary.simpleMessage('Ice Cream'), + 'jammypreserves_name': MessageLookupByLibrary.simpleMessage('Fist Full of Jam'), + 'jellybean_name': MessageLookupByLibrary.simpleMessage('Jellybeans'), + 'justeggs_name': MessageLookupByLibrary.simpleMessage('Plain Omelette'), + 'kabobs_name': MessageLookupByLibrary.simpleMessage('Kabobs'), + 'koalefig_trunk_name': MessageLookupByLibrary.simpleMessage('Fig-Stuffed Trunk'), + 'leafloaf_name': MessageLookupByLibrary.simpleMessage('Leafy Meatloaf'), + 'leafymeatburger_name': MessageLookupByLibrary.simpleMessage('Veggie Burger'), + 'leafymeatsouffle_name': MessageLookupByLibrary.simpleMessage('Jelly Salad'), + 'lobsterbisque_name': MessageLookupByLibrary.simpleMessage('Wobster Bisque'), + 'lobsterdinner_name': MessageLookupByLibrary.simpleMessage('Wobster Dinner'), + 'mandrakesoup_name': MessageLookupByLibrary.simpleMessage('Mandrake Soup'), + 'manure': MessageLookupByLibrary.simpleMessage('Manure'), + 'mashedpotatoes_name': MessageLookupByLibrary.simpleMessage('Creamy Potato Purée'), + 'meatballs_name': MessageLookupByLibrary.simpleMessage('Meatballs'), + 'meatysalad_name': MessageLookupByLibrary.simpleMessage('Beefy Greens'), + 'menu_cook': MessageLookupByLibrary.simpleMessage('Cook'), + 'menu_farm': MessageLookupByLibrary.simpleMessage('Farm'), + 'mix': MessageLookupByLibrary.simpleMessage('Mix'), + 'monsterlasagna_name': MessageLookupByLibrary.simpleMessage('Monster Lasagna'), + 'name': MessageLookupByLibrary.simpleMessage('name'), + 'no_crops_message': MessageLookupByLibrary.simpleMessage('There are no crops placed.'), + 'nutrient_condition_satisfying_first_text': MessageLookupByLibrary.simpleMessage('Balanced nutrients!'), + 'nutrient_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('The nutrients are not balanced.'), + 'nutrient_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('Plant complementary crops or choose the right fertilizer.'), + 'onion_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Pointy Seeds'), + 'pepper_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Lumpy Seeds'), + 'pepperpopper_name': MessageLookupByLibrary.simpleMessage('Stuffed Pepper Poppers'), + 'perogies_name': MessageLookupByLibrary.simpleMessage('Pierogi'), + 'pomegranate_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Windblown Seeds'), + 'poop': MessageLookupByLibrary.simpleMessage('Manure'), + 'potato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Fluffy Seeds'), + 'potatotornado_name': MessageLookupByLibrary.simpleMessage('Fancy Spiralled Tubers'), + 'powcake_name': MessageLookupByLibrary.simpleMessage('Powdercake'), + 'pumpkin_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Sharp Seeds'), + 'pumpkincookie_name': MessageLookupByLibrary.simpleMessage('Pumpkin Cookie'), + 'ratatouille_name': MessageLookupByLibrary.simpleMessage('Ratatouille'), + 'recipe_list_guide_message': MessageLookupByLibrary.simpleMessage('Drag and drop a recipe card.'), + 'reverse_dense': MessageLookupByLibrary.simpleMessage('Dense(flip)'), + 'rottenegg': MessageLookupByLibrary.simpleMessage('Rotten Egg'), + 'salsa_name': MessageLookupByLibrary.simpleMessage('Salsa Fresca'), + 'seafoodgumbo_name': MessageLookupByLibrary.simpleMessage('Seafood Gumbo'), + 'season': MessageLookupByLibrary.simpleMessage('Season'), + 'seasonConditionSatisfyingText': m2, + 'season_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('There are no seasons to be a giant crop.'), + 'season_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('Compose the farm with crops sharing a season.'), + 'seeds': MessageLookupByLibrary.simpleMessage('Seeds'), + 'show': MessageLookupByLibrary.simpleMessage('Show'), + 'show_hidden_items': MessageLookupByLibrary.simpleMessage('Show hidden items'), + 'show_seeds_alias': MessageLookupByLibrary.simpleMessage('Show seeds alias'), + 'shroombait_name': MessageLookupByLibrary.simpleMessage('Stuffed Night Cap'), + 'shroomcake_name': MessageLookupByLibrary.simpleMessage('Mushy Cake'), + 'soil_amender': MessageLookupByLibrary.simpleMessage('Growth Formula Starter'), + 'spoiled_fish': MessageLookupByLibrary.simpleMessage('Spoiled Fish'), + 'spoiled_fish_small': MessageLookupByLibrary.simpleMessage('Spoiled Fish Morsel'), + 'spoiled_food': MessageLookupByLibrary.simpleMessage('Rot'), + 'spring': MessageLookupByLibrary.simpleMessage('Spring'), + 'stuffedeggplant_name': MessageLookupByLibrary.simpleMessage('Stuffed Eggplant'), + 'suitable_seasons': MessageLookupByLibrary.simpleMessage('Suitable Seasons'), + 'summer': MessageLookupByLibrary.simpleMessage('Summer'), + 'surfnturf_name': MessageLookupByLibrary.simpleMessage('Surf \'n\' Turf'), + 'sweettea_name': MessageLookupByLibrary.simpleMessage('Soothing Tea'), + 'taffy_name': MessageLookupByLibrary.simpleMessage('Taffy'), + 'talleggs_name': MessageLookupByLibrary.simpleMessage('Tall Scotch Eggs'), + 'tomato_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Spiky Seeds'), + 'trailmix_name': MessageLookupByLibrary.simpleMessage('Trail Mix'), + 'treegrowthsolution': MessageLookupByLibrary.simpleMessage('Tree Jam'), + 'turkeydinner_name': MessageLookupByLibrary.simpleMessage('Turkey Dinner'), + 'unagi_name': MessageLookupByLibrary.simpleMessage('Unagi'), + 'veggieomlet_name': MessageLookupByLibrary.simpleMessage('Breakfast Skillet'), + 'vegstinger_name': MessageLookupByLibrary.simpleMessage('Vegetable Stinger'), + 'waffles_name': MessageLookupByLibrary.simpleMessage('Waffles'), + 'watermelon_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('Square Seeds'), + 'watermelonicle_name': MessageLookupByLibrary.simpleMessage('Melonsicle'), + 'wetgoop_name': MessageLookupByLibrary.simpleMessage('Wet Goop'), + 'winter': MessageLookupByLibrary.simpleMessage('Winter') + }; } diff --git a/lib/l10n/gen/messages_ko.dart b/lib/l10n/gen/messages_ko.dart index ead9785..e44ba83 100644 --- a/lib/l10n/gen/messages_ko.dart +++ b/lib/l10n/gen/messages_ko.dart @@ -21,15 +21,18 @@ class MessageLookup extends MessageLookupByLibrary { @override String get localeName => 'ko'; - static m0(countOfNeededFertilizer) => "각 성장마다 선택한 비료를 ${countOfNeededFertilizer}번 사용해야 합니다."; + static m0(fertilizerName, countOfNeededFertilizer) => "거대 작물이 되려면 각 성장마다 ${fertilizerName} ${countOfNeededFertilizer}번 사용해야 합니다."; - static m1(seasonsText) => "${seasonsText}에 거대 작물이 됩니다!"; + static m1(countOfNeededFertilizer) => "각 성장마다 선택한 비료를 ${countOfNeededFertilizer}번 사용해야 합니다."; + + static m2(seasonsText) => "${seasonsText}에 거대 작물이 됩니다!"; @override final Map messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { - 'L10nsNutrientConditionBoxContext_secondaryText': m0, + 'L10nsFarmCardContext_footerFertilizerTooltip': m0, + 'L10nsNutrientConditionBoxContext_secondaryText': m1, 'L10nsRecipeListContext_toastMessage': MessageLookupByLibrary.simpleMessage('이미 등록되어 있는 레시피입니다.'), 'add': MessageLookupByLibrary.simpleMessage('추가'), 'asparagus_seeds_assumed_name': MessageLookupByLibrary.simpleMessage('관모양 씨앗'), @@ -138,7 +141,7 @@ class MessageLookup extends MessageLookupByLibrary { 'salsa_name': MessageLookupByLibrary.simpleMessage('살사 프레스카'), 'seafoodgumbo_name': MessageLookupByLibrary.simpleMessage('해산물 검보'), 'season': MessageLookupByLibrary.simpleMessage('계절'), - 'seasonConditionSatisfyingText': m1, + 'seasonConditionSatisfyingText': m2, 'season_condition_unsatisfying_first_text': MessageLookupByLibrary.simpleMessage('거대 작물이 될 수 있는 계절이 없습니다.'), 'season_condition_unsatisfying_secondary_text': MessageLookupByLibrary.simpleMessage('같은 계절의 작물들로 밭을 구성하세요.'), 'seeds': MessageLookupByLibrary.simpleMessage('씨앗'), diff --git a/lib/l10n/l10ns.dart b/lib/l10n/l10ns.dart index ed62f16..ffdfec1 100644 --- a/lib/l10n/l10ns.dart +++ b/lib/l10n/l10ns.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:intl/intl.dart'; +import '../utils/etc.dart'; import 'gen/messages_all.dart'; class _L10nsDelegate extends LocalizationsDelegate { @@ -636,6 +637,8 @@ extension L10nsContextualizing on L10ns { L10nsRecipeListContext get recipeList => L10nsRecipeListContext(localeName); L10nsNutrientConditionBoxContext get nutrientConditionBox => L10nsNutrientConditionBoxContext(localeName); + + L10nsFarmCardContext get farmCard => L10nsFarmCardContext(localeName); } class L10nsRecipeListContext { @@ -668,3 +671,23 @@ class L10nsNutrientConditionBoxContext { ); } } + +class L10nsFarmCardContext { + const L10nsFarmCardContext(this.localeName); + + final String localeName; + + String footerFertilizerTooltip(String fertilizerName, int countOfNeededFertilizer) { + if (localeName == 'ko') { + fertilizerName = fertilizerName.postpositioned('을', '를'); + } + + return Intl.message( + 'You need to use $fertilizerName $countOfNeededFertilizer times for each growth to get giant crops.', + name: 'L10nsFarmCardContext_footerFertilizerTooltip', + desc: 'It is a tooltip message of the fertilizer in farm card\'s footer.', + args: [fertilizerName, countOfNeededFertilizer], + locale: localeName, + ); + } +} diff --git a/lib/utils/etc.dart b/lib/utils/etc.dart index baaefa4..50a0993 100644 --- a/lib/utils/etc.dart +++ b/lib/utils/etc.dart @@ -1,4 +1,6 @@ -String keepKoreanWord(String text) { +// import 'package:characters/characters.dart'; + +String _keepKoreanWord(String text) { final RegExp emoji = RegExp(r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])'); String fullText = ''; @@ -10,3 +12,38 @@ String keepKoreanWord(String text) { } return fullText; } + +extension KoreanString on String { + String get untruncatedKoreanByNewline { + return _keepKoreanWord(this); + } + + /// Returns a Korean word with the appropriate postposition appended according to the final consonant. + /// + /// [finalConsonantPostposition] and [noneFinalConsonantPostposition] are a pair of postpositions + /// that can be followed by a Korean word like '이/가', '을/를', '은/는'. + /// + /// [finalConsonantPostposition] is a postposition used when a given Korean word has a final consonant, like '이', '을', and '은'. + /// Meanwhile, [noneFinalConsonantPostposition] is used when it doesn’t, like '가', '를', and '는'. + /// + /// ``` + /// final s = '나'.postpositioned('은', '는') // '나는' + /// final o = '사과'.postpositioned('을', '를') // '사과를' + /// '$s $o 먹었다.' // '나는 사과를 먹었다.' + /// ``` + String postpositioned(String finalConsonantPostposition, String noneFinalConsonantPostposition) { + final lastCharUnicode = runes.last; + + if (lastCharUnicode < 0xAC00 || lastCharUnicode > 0xD7A3) { + throw StateError('The last character of the string is not a Korean.'); + } + + final finalConsonant = (lastCharUnicode - 0xAC00) % 28; + + if (finalConsonant == 0) { + return this + noneFinalConsonantPostposition; + } else { + return this + finalConsonantPostposition; + } + } +} diff --git a/mise.toml b/mise.toml index b9fd634..e61d1b0 100644 --- a/mise.toml +++ b/mise.toml @@ -18,7 +18,10 @@ run = 'flutter run -d web-server --web-hostname {{arg()}} --web-port 8080 --rele [tasks.extract_to_arb] description = 'Generate a `.arb` file from `l10ns.dart`' -run = 'dart run intl_translation:extract_to_arb --output-dir lib/l10n/arbs lib/l10n/l10ns.dart' +run = ''' +dart run intl_translation:extract_to_arb --output-dir lib/l10n/arbs lib/l10n/l10ns.dart +open -a /Applications/Visual\ Studio\ Code.app lib/l10n/arbs/intl_messages.arb +''' [tasks.generate_from_arb] description = 'Generate message lookup classes from `.arb` translation files' diff --git a/pubspec.lock b/pubspec.lock index e8f09c2..254f90f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -111,7 +111,7 @@ packages: source: hosted version: "8.9.3" characters: - dependency: transitive + dependency: "direct main" description: name: characters sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" diff --git a/pubspec.yaml b/pubspec.yaml index 3b1212d..93e7c3d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,6 +54,7 @@ dependencies: intl_translation: ^0.20.0 styled_text: ^8.1.0 toastification: ^2.3.0 + characters: ^1.3.0 dev_dependencies: flutter_test: diff --git a/test/utils_test.dart b/test/utils_test.dart new file mode 100644 index 0000000..efd2599 --- /dev/null +++ b/test/utils_test.dart @@ -0,0 +1,25 @@ +import 'package:dst_helper/utils/etc.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Test postposition with Korean word', () { + test('Test the example in the docs comments', () { + final s = '나'.postpositioned('은', '는'); + final o = '사과'.postpositioned('을', '를'); + + expect('$s $o 먹었다.', '나는 사과를 먹었다.'); + }); + + test('Test final consonant postposition', () { + expect('대한민국'.postpositioned('은', '는'), '대한민국은'); + expect('세종대왕님'.postpositioned('이', '가'), '세종대왕님이'); + expect('한글'.postpositioned('을', '를'), '한글을'); + }); + + test('Test none final consonant postposition', () { + expect('나'.postpositioned('은', '는'), '나는'); + expect('누나'.postpositioned('이', '가'), '누나가'); + expect('사과'.postpositioned('을', '를'), '사과를'); + }); + }); +} From 8f199ec33e4ee25c0100773d4a5d563551e1a635 Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 20 Feb 2025 17:54:37 +0900 Subject: [PATCH 3/8] Update analysis options --- analysis_options.yaml | 6 +++++- lib/main.dart | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index e8b95b1..8febbaa 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -10,7 +10,10 @@ include: package:flutter_lints/flutter.yaml analyzer: - exclude: [lib/**.freezed.dart, lib/**.g.dart] + exclude: + - lib/**.freezed.dart + - lib/**.g.dart + - lib/l10n/gen linter: # The lint rules applied to this project can be customized in the @@ -29,6 +32,7 @@ linter: prefer_final_locals: true # prefer_final_parameters: true prefer_final_in_for_each: true + always_declare_return_types: true # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at diff --git a/lib/main.dart b/lib/main.dart index bcea5a4..6ad1fc0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -23,7 +23,7 @@ Future _clearPrefsIfNeeds() async { number: 15, ); - clearAndSet() async { + Future clearAndSet() async { await prefs.clear(); prefs.setInt('prefs_version', currentVersion.number); } From c3a31ef46942513d7e9046e0ec5df42c449072c2 Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 20 Feb 2025 17:56:52 +0900 Subject: [PATCH 4/8] Remove dead code --- lib/utils/etc.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/utils/etc.dart b/lib/utils/etc.dart index 50a0993..208cc9a 100644 --- a/lib/utils/etc.dart +++ b/lib/utils/etc.dart @@ -1,5 +1,3 @@ -// import 'package:characters/characters.dart'; - String _keepKoreanWord(String text) { final RegExp emoji = RegExp(r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])'); From e09ee11998e0636d00d9f80cb754f4d6f1a4962a Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 20 Feb 2025 22:22:42 +0900 Subject: [PATCH 5/8] Refactor side info box tags into a single `InfoBoxTag` component for maintainability --- .../side_info_box/crops_info_box.dart | 34 ------ .../side_info_box/fertilizers_info_box.dart | 34 ------ .../side_info_box/seeds_info_box.dart | 42 ------- .../side_info_box/side_info_box.dart | 109 +++++++++++++----- 4 files changed, 78 insertions(+), 141 deletions(-) diff --git a/lib/farm_page/side_info_box/crops_info_box.dart b/lib/farm_page/side_info_box/crops_info_box.dart index 98d0034..1f5baaf 100644 --- a/lib/farm_page/side_info_box/crops_info_box.dart +++ b/lib/farm_page/side_info_box/crops_info_box.dart @@ -148,40 +148,6 @@ class CropsInfoBox extends StatelessWidget { } } -class CropsInfoBoxTag extends StatelessWidget { - const CropsInfoBoxTag({ - super.key, - this.onPressed, - this.size = const Size(50, 50), - required this.color, - }); - - final Color color; - final Size size; - final void Function()? onPressed; - - @override - Widget build(BuildContext context) { - return Container( - width: size.width, - height: size.height, - decoration: BoxDecoration( - color: color, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(20), - bottomLeft: Radius.circular(20), - ), - boxShadow: kElevationToShadow[2], - ), - child: IconButton( - padding: const EdgeInsets.only(top: 4, bottom: 2), - onPressed: onPressed, - icon: Image.asset("assets/images/nutrients_manure_icon.png"), - ), - ); - } -} - class SeasonIndicator extends StatelessWidget { const SeasonIndicator({ super.key, diff --git a/lib/farm_page/side_info_box/fertilizers_info_box.dart b/lib/farm_page/side_info_box/fertilizers_info_box.dart index 3db6c19..c849ab0 100644 --- a/lib/farm_page/side_info_box/fertilizers_info_box.dart +++ b/lib/farm_page/side_info_box/fertilizers_info_box.dart @@ -210,37 +210,3 @@ class FertilizersInfoBox extends StatelessWidget { } } } - -class FertilizersInfoBoxTag extends StatelessWidget { - const FertilizersInfoBoxTag({ - super.key, - this.onPressed, - required this.size, - required this.color, - }); - - final Color color; - final Size size; - final void Function()? onPressed; - - @override - Widget build(BuildContext context) { - return Container( - width: size.width, - height: size.height, - decoration: BoxDecoration( - color: color, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(20), - bottomLeft: Radius.circular(20), - ), - boxShadow: kElevationToShadow[2], - ), - child: IconButton( - padding: const EdgeInsets.only(top: 4, bottom: 2), - onPressed: onPressed, - icon: Image.asset("assets/images/items/${Items.fertilizer.assetName}.png"), - ), - ); - } -} diff --git a/lib/farm_page/side_info_box/seeds_info_box.dart b/lib/farm_page/side_info_box/seeds_info_box.dart index 6dbc3d3..6f2d470 100644 --- a/lib/farm_page/side_info_box/seeds_info_box.dart +++ b/lib/farm_page/side_info_box/seeds_info_box.dart @@ -7,14 +7,11 @@ import '../../utils/font_family.dart'; enum SettingItem { displayingSeedName; - // displayingCropName; String description(BuildContext context) { switch (this) { case SettingItem.displayingSeedName: return L10ns.of(context).localized('show_seeds_alias'); - // case SettingItem.displayingCropName: - // return '작물 이름 표시'; } } } @@ -29,7 +26,6 @@ class SeedsInfoBox extends StatefulWidget { class _SeedsInfoBoxState extends State { final Map _settings = { SettingItem.displayingSeedName: false, - // SettingItem.displayingCropName: false, }; @override @@ -110,41 +106,3 @@ class _SeedsInfoBoxState extends State { ); } } - -class SeedsInfoBoxTag extends StatelessWidget { - const SeedsInfoBoxTag({ - super.key, - this.onPressed, - required this.size, - required this.color, - }); - - final Size size; - final Color color; - final void Function()? onPressed; - - @override - Widget build(BuildContext context) { - return Container( - width: size.width, - height: size.height, - decoration: BoxDecoration( - color: color, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(20), - bottomLeft: Radius.circular(20), - ), - boxShadow: kElevationToShadow[2], - ), - child: IconButton( - padding: const EdgeInsets.only(left: 10, right: 8, bottom: 3), - iconSize: 20, - onPressed: onPressed, - icon: Image.asset( - "assets/images/items/${Items.seeds.assetName}.png", - width: 50, - ), - ), - ); - } -} diff --git a/lib/farm_page/side_info_box/side_info_box.dart b/lib/farm_page/side_info_box/side_info_box.dart index ed426f5..f7e8203 100644 --- a/lib/farm_page/side_info_box/side_info_box.dart +++ b/lib/farm_page/side_info_box/side_info_box.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../../models/v2/item/items.dart'; import 'crops_info_box.dart'; import 'fertilizers_info_box.dart'; import 'seeds_info_box.dart'; @@ -9,32 +10,32 @@ enum SideInfoMenu { fertilizer, nutrients; - Widget tag(void Function() onPressed) { - return switch (this) { - SideInfoMenu.seed => SeedsInfoBoxTag( - size: SideInfoBox.tagSize, - onPressed: onPressed, - color: Colors.brown.shade400, - ), - SideInfoMenu.fertilizer => FertilizersInfoBoxTag( - size: SideInfoBox.tagSize, - onPressed: onPressed, - color: Colors.brown.shade200, - ), - SideInfoMenu.nutrients => CropsInfoBoxTag( - size: SideInfoBox.tagSize, - onPressed: onPressed, - color: Colors.orange.shade50, - ), - }; + Color get primaryColor { + switch (this) { + case SideInfoMenu.seed: + return Colors.brown.shade400; + case SideInfoMenu.fertilizer: + return Colors.brown.shade200; + case SideInfoMenu.nutrients: + return Colors.orange.shade50; + } + } + + EdgeInsets get imagePadding { + switch (this) { + case SideInfoMenu.seed: + return const EdgeInsets.only(left: 10, right: 8, bottom: 3); + case SideInfoMenu.fertilizer: + return const EdgeInsets.only(top: 4, bottom: 2); + case SideInfoMenu.nutrients: + return const EdgeInsets.only(top: 4, bottom: 2); + } } } class SideInfoBox extends StatefulWidget { const SideInfoBox({super.key}); - static const Size tagSize = Size(65, 52); - @override State createState() => _SideInfoBoxState(); } @@ -42,13 +43,7 @@ class SideInfoBox extends StatefulWidget { class _SideInfoBoxState extends State { List _sideInfoSelection = List.filled(SideInfoMenu.values.length, false); - int? get selectedIndex { - try { - return _sideInfoSelection.asMap().entries.singleWhere((e) => e.value == true).key; - } catch (_) { - return null; - } - } + int? get selectedIndex => _sideInfoSelection.indexWhere((e) => e == true); @override Widget build(BuildContext context) { @@ -59,16 +54,19 @@ class _SideInfoBoxState extends State { children: [ ...SideInfoMenu.values.asMap().entries.map((menu) => Container( margin: const EdgeInsets.only(top: 16), - child: menu.value.tag(() { - setState(() { + child: InfoBoxTag( + menu: menu.value, + onPressed: () => setState(() { if (_sideInfoSelection[menu.key] == true) { _sideInfoSelection[menu.key] = false; return; } _sideInfoSelection = List.filled(SideInfoMenu.values.length, false); _sideInfoSelection[menu.key] = true; - }); - }), + }), + color: menu.value.primaryColor, + imagePadding: menu.value.imagePadding, + ), )), ], ), @@ -114,3 +112,52 @@ class _SideInfoBoxState extends State { ); } } + +class InfoBoxTag extends StatelessWidget { + const InfoBoxTag({ + super.key, + required this.menu, + required this.color, + this.onPressed, + required this.imagePadding, + }); + + final SideInfoMenu menu; + final Color color; + final void Function()? onPressed; + final EdgeInsets imagePadding; + + static const size = Size(65, 52); + + @override + Widget build(BuildContext context) { + final AssetImage image; + + switch (menu) { + case SideInfoMenu.seed: + image = AssetImage('assets/images/items/${Items.seeds.assetName}.png'); + case SideInfoMenu.fertilizer: + image = AssetImage('assets/images/items/${Items.fertilizer.assetName}.png'); + case SideInfoMenu.nutrients: + image = const AssetImage('assets/images/nutrients_manure_icon.png'); + } + + return Container( + width: size.width, + height: size.height, + decoration: BoxDecoration( + color: color, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + bottomLeft: Radius.circular(20), + ), + boxShadow: kElevationToShadow[2], + ), + child: IconButton( + padding: imagePadding, + onPressed: onPressed, + icon: Image(image: image), + ), + ); + } +} From 41d2cb8965d698e0be549da8cc992414da0047ff Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 20 Feb 2025 23:06:15 +0900 Subject: [PATCH 6/8] Remove unnecessary spacing in the top bar layout --- lib/farm_page/farm_page.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/farm_page/farm_page.dart b/lib/farm_page/farm_page.dart index fe45238..e511256 100644 --- a/lib/farm_page/farm_page.dart +++ b/lib/farm_page/farm_page.dart @@ -95,7 +95,6 @@ class _TopBar extends StatelessWidget { children: [ _SeasonSelectionBox(), _NewButton(), - SizedBox(width: 50), _ShowAndHideCheckbox(), ], ), From de98ea67356303e2615f8bd37bd99989db3f0f2f Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 20 Feb 2025 23:46:33 +0900 Subject: [PATCH 7/8] Add vertical dividers --- .../edit_farm_set/farm_group_edit_window.dart | 106 ++++++++++-------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/lib/farm_page/edit_farm_set/farm_group_edit_window.dart b/lib/farm_page/edit_farm_set/farm_group_edit_window.dart index 56a7215..4f19c44 100644 --- a/lib/farm_page/edit_farm_set/farm_group_edit_window.dart +++ b/lib/farm_page/edit_farm_set/farm_group_edit_window.dart @@ -74,52 +74,66 @@ class _FarmGroupEditWindowState extends State { borderRadius: BorderRadius.circular(18.0), ), padding: const EdgeInsets.all(18.0), - child: Row( - spacing: 34, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Row( - spacing: 30, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - FertilizersInfoBox(), - CropsInfoBox(), - ], - ), - Column( - spacing: 34, - children: [ - const FarmGroupCanvas(), - ValueListenableBuilder( - valueListenable: controller.farmGroupModelNotifier, - builder: (context, value, child) => const AnalysisView()), - ], - ), - Column( - spacing: 30.0, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const _TitleTextField(), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 8, - children: [ - _buildFarmTypeSelectionBox(), - _buildFarmGroupTypeSelectionBox(), - ], - ), - CropSelectionSection(notifier: controller.selectedCropNotifier), - FertilizerSelectionSection(notifier: controller.selectedFertilizerNotifier), - const Row( - spacing: 20, - children: [ - _CancelButton(), - _OkButton(), - ], - ), - ], - ), - ], + child: IntrinsicHeight( + child: Row( + spacing: 20, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + spacing: 30, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const FertilizersInfoBox(), + VerticalDivider( + width: 1.0, + color: Colors.grey.shade300, + ), + const CropsInfoBox(), + ], + ), + VerticalDivider( + width: 1.0, + color: Colors.grey.shade300, + ), + Column( + spacing: 34, + children: [ + const FarmGroupCanvas(), + ValueListenableBuilder( + valueListenable: controller.farmGroupModelNotifier, + builder: (context, value, child) => const AnalysisView()), + ], + ), + VerticalDivider( + width: 1.0, + color: Colors.grey.shade300, + ), + Column( + spacing: 30.0, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const _TitleTextField(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 8, + children: [ + _buildFarmTypeSelectionBox(), + _buildFarmGroupTypeSelectionBox(), + ], + ), + CropSelectionSection(notifier: controller.selectedCropNotifier), + FertilizerSelectionSection(notifier: controller.selectedFertilizerNotifier), + const Row( + spacing: 20, + children: [ + _CancelButton(), + _OkButton(), + ], + ), + ], + ), + ], + ), ), ), ), From cc82a191f75a722815a08384fa7c44ae48fe3230 Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Fri, 21 Feb 2025 00:53:48 +0900 Subject: [PATCH 8/8] Make the overlay hidden when click the background --- .../fertilizer_selection_section.dart | 30 ++-- .../edit_farm_set/farm_group_edit_window.dart | 139 +++++++++--------- 2 files changed, 91 insertions(+), 78 deletions(-) diff --git a/lib/farm_page/edit_farm_set/components/fertilizer_selection_section.dart b/lib/farm_page/edit_farm_set/components/fertilizer_selection_section.dart index 9bcd129..e15fa46 100644 --- a/lib/farm_page/edit_farm_set/components/fertilizer_selection_section.dart +++ b/lib/farm_page/edit_farm_set/components/fertilizer_selection_section.dart @@ -30,10 +30,14 @@ class FertilizerSelectionSection extends StatelessWidget { FertilizerSelectionSection({ super.key, SelectedFertilizerNotifier? notifier, - }) : _notifier = notifier ?? SelectedFertilizerNotifier(null); + OverlayPortalController? overlayController, + }) : _overlayController = overlayController ?? OverlayPortalController(), + _notifier = notifier ?? SelectedFertilizerNotifier(null); final SelectedFertilizerNotifier _notifier; + final OverlayPortalController _overlayController; + @override Widget build(BuildContext context) { return Column( @@ -41,8 +45,11 @@ class FertilizerSelectionSection extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ const _FertilizerSelectionHeader(), - ChangeNotifierProvider.value( - value: _notifier, + MultiProvider( + providers: [ + ChangeNotifierProvider.value(value: _notifier), + Provider.value(value: _overlayController), + ], child: const _FertilizerSelectionBody(), ), ], @@ -230,9 +237,7 @@ class _GrowthFormulaButton extends StatefulWidget { } class _GrowthFormulaButtonState extends State<_GrowthFormulaButton> { - final _overlayController = OverlayPortalController(); - - Fertilizer _lastSelected = Items.growthFormulaStarter; + Fertilizer _lastSelectedFertilizer = Items.growthFormulaStarter; @override void initState() { @@ -243,7 +248,7 @@ class _GrowthFormulaButtonState extends State<_GrowthFormulaButton> { void _initLastSelectedFertilizer() { final initialValue = widget.initialValue; if (initialValue != null) { - _lastSelected = initialValue; + _lastSelectedFertilizer = initialValue; } } @@ -265,9 +270,10 @@ class _GrowthFormulaButtonState extends State<_GrowthFormulaButton> { @override Widget build(BuildContext context) { final selectedFertilizer = context.watch(); + final overlayController = context.read(); return OverlayPortal( - controller: _overlayController, + controller: overlayController, overlayChildBuilder: (context) { return Positioned( top: _computeOverlayOffset(context).dy, @@ -283,9 +289,9 @@ class _GrowthFormulaButtonState extends State<_GrowthFormulaButton> { fertilizer: fertilizer, onPressed: () { selectedFertilizer.apply(fertilizer); - _overlayController.hide(); + overlayController.hide(); setState(() { - _lastSelected = fertilizer; + _lastSelectedFertilizer = fertilizer; }); }, ); @@ -297,8 +303,8 @@ class _GrowthFormulaButtonState extends State<_GrowthFormulaButton> { ); }, child: _FertilizerIconButton( - fertilizer: _lastSelected, - onPressed: _overlayController.toggle, + fertilizer: _lastSelectedFertilizer, + onPressed: overlayController.toggle, ), ); } diff --git a/lib/farm_page/edit_farm_set/farm_group_edit_window.dart b/lib/farm_page/edit_farm_set/farm_group_edit_window.dart index 4f19c44..d4d1f1c 100644 --- a/lib/farm_page/edit_farm_set/farm_group_edit_window.dart +++ b/lib/farm_page/edit_farm_set/farm_group_edit_window.dart @@ -31,6 +31,7 @@ class FarmGroupEditWindow extends StatefulWidget { class _FarmGroupEditWindowState extends State { late final FarmGroupEditController controller; + final _overlayController = OverlayPortalController(); @override void initState() { @@ -67,72 +68,78 @@ class _FarmGroupEditWindowState extends State { Provider.value(value: this), ChangeNotifierProvider.value(value: controller), ], - child: FittedBox( - child: Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(18.0), - ), - padding: const EdgeInsets.all(18.0), - child: IntrinsicHeight( - child: Row( - spacing: 20, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - spacing: 30, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const FertilizersInfoBox(), - VerticalDivider( - width: 1.0, - color: Colors.grey.shade300, - ), - const CropsInfoBox(), - ], - ), - VerticalDivider( - width: 1.0, - color: Colors.grey.shade300, - ), - Column( - spacing: 34, - children: [ - const FarmGroupCanvas(), - ValueListenableBuilder( - valueListenable: controller.farmGroupModelNotifier, - builder: (context, value, child) => const AnalysisView()), - ], - ), - VerticalDivider( - width: 1.0, - color: Colors.grey.shade300, - ), - Column( - spacing: 30.0, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const _TitleTextField(), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 8, - children: [ - _buildFarmTypeSelectionBox(), - _buildFarmGroupTypeSelectionBox(), - ], - ), - CropSelectionSection(notifier: controller.selectedCropNotifier), - FertilizerSelectionSection(notifier: controller.selectedFertilizerNotifier), - const Row( - spacing: 20, - children: [ - _CancelButton(), - _OkButton(), - ], - ), - ], - ), - ], + child: GestureDetector( + onTap: () => _overlayController.hide(), + child: FittedBox( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(18.0), + ), + padding: const EdgeInsets.all(18.0), + child: IntrinsicHeight( + child: Row( + spacing: 20, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + spacing: 30, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const FertilizersInfoBox(), + VerticalDivider( + width: 1.0, + color: Colors.grey.shade300, + ), + const CropsInfoBox(), + ], + ), + VerticalDivider( + width: 1.0, + color: Colors.grey.shade300, + ), + Column( + spacing: 34, + children: [ + const FarmGroupCanvas(), + ValueListenableBuilder( + valueListenable: controller.farmGroupModelNotifier, + builder: (context, value, child) => const AnalysisView()), + ], + ), + VerticalDivider( + width: 1.0, + color: Colors.grey.shade300, + ), + Column( + spacing: 30.0, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const _TitleTextField(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 8, + children: [ + _buildFarmTypeSelectionBox(), + _buildFarmGroupTypeSelectionBox(), + ], + ), + CropSelectionSection(notifier: controller.selectedCropNotifier), + FertilizerSelectionSection( + notifier: controller.selectedFertilizerNotifier, + overlayController: _overlayController, + ), + const Row( + spacing: 20, + children: [ + _CancelButton(), + _OkButton(), + ], + ), + ], + ), + ], + ), ), ), ),