diff --git a/android/app/build.gradle b/android/app/build.gradle index 5d527ab7..9c65b2ca 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.moimob.drinkable" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 14400 - versionName "1.44.0" + versionCode 14401 + versionName "1.44.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/fastlane/metadata/android/en-US/changelogs/14401.txt b/fastlane/metadata/android/en-US/changelogs/14401.txt new file mode 100644 index 00000000..5bc21644 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/14401.txt @@ -0,0 +1,2 @@ +• Added 4 new cocktails +• Added 1 new ingredient \ No newline at end of file diff --git a/src/data/cocktail-data.ts b/src/data/cocktail-data.ts index f19ad080..1b113750 100644 --- a/src/data/cocktail-data.ts +++ b/src/data/cocktail-data.ts @@ -2528,5 +2528,67 @@ const cocktails: StaticCocktail[] = [ { amount: '60', ingredientId: '86', unit: Unit.DASH } ], tags: [] + }, + { + id: '184', + imageSrc: 'images/sherry_eggnog.jpg', + isImagePortrait: false, + translation: 'sherry-eggnog', + category: DrinkCategory.Cocktail, + ingredientGroups: [ + { amount: '60', ingredientId: '158', unit: Unit.ML }, + { amount: '1', ingredientId: '16', unit: Unit.TSP }, + { amount: '1', ingredientId: '114', unit: '' }, + { amount: '120', ingredientId: '77', unit: Unit.ML }, + { amount: '', ingredientId: '141', unit: '' } + ], + tags: [Tag.Christmas] + }, + { + id: '185', + imageSrc: 'images/hot_toddy.jpg', + isImagePortrait: false, + translation: 'hot-toddy', + category: DrinkCategory.Cocktail, + ingredientGroups: [ + { amount: '60', ingredientId: '52', unit: Unit.ML }, + { amount: '15', ingredientId: '115', unit: Unit.ML }, + { amount: '150', ingredientId: '91', unit: Unit.ML }, + { amount: '1', ingredientId: '103', unit: '' }, + { amount: '1', ingredientId: '105', unit: '' }, + { amount: '2', ingredientId: '102', unit: '' } + ], + tags: [Tag.Christmas] + }, + { + id: '186', + imageSrc: 'images/winter_rita.jpg', + isImagePortrait: false, + translation: 'winter-rita', + category: DrinkCategory.Cocktail, + ingredientGroups: [ + { amount: '60', ingredientId: '18', unit: Unit.ML }, + { amount: '7.5', ingredientId: '36', unit: Unit.ML }, + { amount: '30', ingredientId: '2', unit: Unit.ML }, + { amount: '15', ingredientId: '64', unit: Unit.ML }, + { amount: '15', ingredientId: '3', unit: Unit.ML }, + { amount: '', ingredientId: '46', unit: '' } + ], + tags: [Tag.Christmas] + }, + { + id: '187', + imageSrc: 'images/the_galah.jpg', + isImagePortrait: false, + translation: 'the-galah', + category: DrinkCategory.Cocktail, + ingredientGroups: [ + { amount: '30', ingredientId: '54', unit: Unit.ML }, + { amount: '30', ingredientId: '36', unit: Unit.ML }, + { amount: '15', ingredientId: '143', unit: Unit.ML }, + { amount: '15', ingredientId: '2', unit: Unit.ML }, + { amount: '90', ingredientId: '26', unit: Unit.ML } + ], + tags: [] } ]; diff --git a/src/data/ingredient-data.ts b/src/data/ingredient-data.ts index 673e61bb..d2956595 100644 --- a/src/data/ingredient-data.ts +++ b/src/data/ingredient-data.ts @@ -219,12 +219,13 @@ const currentIngredients: StaticIngredient[] = [ { id: '147', translation: 'cream-liqueur', spiritType: SpiritType.None, abv: 17, replacementIds: ['108'] }, { id: '148', translation: 'limoncello-di-capri', spiritType: SpiritType.None, abv: 30, replacementIds: ['51'] }, { id: '149', translation: 'dooleys', spiritType: SpiritType.None, abv: 17 }, - { id: '150', translation: 'creme-de-banana', spiritType: SpiritType.None, abv: 17 }, + // 150 is removed due to duplicate { id: '151', translation: 'hard-cider', spiritType: SpiritType.None, abv: 4 }, { id: '152', translation: 'gammel-dansk', spiritType: SpiritType.None, abv: 38 }, { id: '153', translation: 'calvados', spiritType: SpiritType.CognacBrandy, abv: 42, replacementIds: ['65'] }, { id: '154', translation: 'wheat-beer', spiritType: SpiritType.None, abv: 5 }, { id: '155', translation: 'apple-schnapps', spiritType: SpiritType.None, abv: 18 }, { id: '156', translation: '7-up', spiritType: SpiritType.None, replacementIds: ['45'] }, - { id: '157', translation: 'passion-fruit-syrup', spiritType: SpiritType.None } + { id: '157', translation: 'passion-fruit-syrup', spiritType: SpiritType.None }, + { id: '158', translation: 'sherry', spiritType: SpiritType.None, abv: 17 } ]; diff --git a/src/locales/en/cocktails.json b/src/locales/en/cocktails.json index 5ca03cac..585608a6 100644 --- a/src/locales/en/cocktails.json +++ b/src/locales/en/cocktails.json @@ -181,5 +181,9 @@ "mulled-wine": "Mulled Wine", "captain-kidds-punch": "Captain Kidd’s Punch", "pure-passion": "Pure Passion", - "old-cuban": "Old Cuban" + "old-cuban": "Old Cuban", + "sherry-eggnog": "Sherry Eggnog", + "hot-toddy": "Hot Toddy", + "winter-rita": "Winter Rita", + "the-galah": "The Galah" } diff --git a/src/locales/en/ingredients.json b/src/locales/en/ingredients.json index c6bf8ca4..f3086f00 100644 --- a/src/locales/en/ingredients.json +++ b/src/locales/en/ingredients.json @@ -154,5 +154,6 @@ "wheat-beer": "Wheat Beer", "apple-schnapps": "Apple Schnapps", "7-up": "7 Up", - "passion-fruit-syrup": "Passion Fruit Syrup" + "passion-fruit-syrup": "Passion Fruit Syrup", + "sherry": "Sherry" } diff --git a/src/locales/en/instructions.json b/src/locales/en/instructions.json index e5428aa1..58d0dac0 100644 --- a/src/locales/en/instructions.json +++ b/src/locales/en/instructions.json @@ -181,5 +181,9 @@ "mulled-wine": "Simmer 3 cups water with, sugar, cloves, cinnamon sticks, and lemon peel in a stainless steel pot for 10 minutes.\nAdd wine heat to a 'coffee temperature' (DO NOT BOIL) then add the brandy.", "captain-kidds-punch": "Mix all ingredients together in a shaker and strain into a collins glass.\nUse Caribbean dark Rum for a sweeter taste. Top with nutmeg", "pure-passion": "Mix up all ingredients with a cocktail stirrer and serve with crushed ice with mint and edible flour if available.", - "old-cuban": "Shake a handful of mint, white rum, sugar syrup, lime juice and 2 dashes angostura bitters with ice. Double strain into a glass and top with prosecco." + "old-cuban": "Shake a handful of mint, white rum, sugar syrup, lime juice and 2 dashes angostura bitters with ice. Double strain into a glass and top with prosecco.", + "sherry-eggnog": "Shake sherry, powdered sugar, and egg with ice and strain into a collins glass.\nFill with milk and stir.\nSprinkle nutmeg on top and serve.", + "hot-toddy": "STEP 1 Whisk the whisky and honey together and split between 2 heatproof glasses. Add half of the cinnamon stick to each, then top up with boiling water.\n\nSTEP 2 Add a splash of lemon juice to each, then taste and add more to your preference. Finish each with a slice of lemon, studded with a clove, and serve immediately.", + "winter-rita": "Salt rim.\nCombine all ingredients, shake with ice, and strain over fresh ice.", + "the-galah": "Mix together the alcoholic portions and top with Pineapple and Lime juice." } diff --git a/src/services/local-storage-service.ts b/src/services/local-storage-service.ts index 5a7867a9..5005b269 100644 --- a/src/services/local-storage-service.ts +++ b/src/services/local-storage-service.ts @@ -31,6 +31,15 @@ export class LocalStorageService { await this.addDefaultIngredientList([]); } + // 2023-11-27 - Remove Ingredient 150 due to duplication + if (this._ingredientLists.flatMap(x => x.ingredients).find(x => x === '150') !== undefined) { + this._ingredientLists.forEach(x => { + x.ingredients = x.ingredients.filter(y => y !== '150'); + }); + + this.updateIngredientLists(this._ingredientLists); + } + const messuarementSystem = await this.getFromLocalStorage(StorageKey.MessuarementSystem, false); this._messuarementSystem = messuarementSystem !== null ? messuarementSystem : MessuarementSystem.Imperial; @@ -56,10 +65,11 @@ export class LocalStorageService { const shoppingLists = await this.getFromLocalStorage(StorageKey.ShoppingLists); this._shoppingLists = shoppingLists !== null ? shoppingLists : []; - - await this.migrateFavoriteCocktails(); } + /** + * Migration made 2023-09-06. Remove after 6 months? + */ private async migrateSavedIngredients() { const savedIngredientsStorageKey: StorageKey = StorageKey.SavedIngredients; @@ -85,30 +95,6 @@ export class LocalStorageService { await this.updateIngredientLists([ingredientList]); } - private async migrateFavoriteCocktails() { - const keyExists = await this.keyExists(StorageKey.FavoriteCocktails); - - if (keyExists) { - const favoriteResponse = await this.getFromLocalStorage(StorageKey.FavoriteCocktails); - const favoriteCocktails = favoriteResponse !== null ? favoriteResponse.map(String) : []; - - favoriteCocktails.forEach((element: string) => { - const cocktailInformation = this._cocktailInformation.find(x => x.id === element); - if (cocktailInformation !== undefined) { - cocktailInformation.isFavorite = true; - } else { - this._cocktailInformation.push({ - id: element, - isFavorite: true - }); - } - }); - - await this.updateCocktailInformation(this._cocktailInformation); - await Preferences.remove({ key: StorageKey.FavoriteCocktails }); - } - } - public async updateCocktails(cocktails: Cocktail[]) { // No not save alocholInformation to LocalStorage // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -307,10 +293,6 @@ export enum StorageKey { */ SavedIngredients = 'saved-ingredients', MessuarementSystem = 'messuarement-system', - /** - * @deprecated FavoriteCocktails have been replaced with CocktailInformation - */ - FavoriteCocktails = 'favorite-cocktails', WidgetOrder = 'widget-order', Cocktails = 'cocktails', Ingredients = 'ingredients', diff --git a/static/images/hot_toddy.jpg b/static/images/hot_toddy.jpg new file mode 100644 index 00000000..214623ff Binary files /dev/null and b/static/images/hot_toddy.jpg differ diff --git a/static/images/sherry_eggnog.jpg b/static/images/sherry_eggnog.jpg new file mode 100644 index 00000000..3d259e0f Binary files /dev/null and b/static/images/sherry_eggnog.jpg differ diff --git a/static/images/the_galah.jpg b/static/images/the_galah.jpg new file mode 100644 index 00000000..516ea3b3 Binary files /dev/null and b/static/images/the_galah.jpg differ diff --git a/static/images/winter_rita.jpg b/static/images/winter_rita.jpg new file mode 100644 index 00000000..403f1311 Binary files /dev/null and b/static/images/winter_rita.jpg differ diff --git a/tests/data/cocktail-data.test.ts b/tests/data/cocktail-data.test.ts index 3eb47fac..660d0615 100644 --- a/tests/data/cocktail-data.test.ts +++ b/tests/data/cocktail-data.test.ts @@ -10,6 +10,14 @@ describe('getStaticCocktails', () => { expect(ids.length).toBe([...new Set(ids)].length); }); + test('translation keys should not include duplicates', () => { + const ingredients = getStaticCocktails(); + + const names = ingredients.map(x => x.translation); + + expect(names.length).toBe([...new Set(names)].length); + }); + test('IBA Cocktails should include a secondary IBA tag', () => { const cocktails = getStaticCocktails(); diff --git a/tests/data/ingredient-data.test.ts b/tests/data/ingredient-data.test.ts index 6e287a0c..ed75ed26 100644 --- a/tests/data/ingredient-data.test.ts +++ b/tests/data/ingredient-data.test.ts @@ -9,4 +9,12 @@ describe('getStaticIngredients', () => { expect(ids.length).toBe([...new Set(ids)].length); }); + + test('translation keys should not include duplicates', () => { + const ingredients = getStaticIngredients(); + + const names = ingredients.map(x => x.translation); + + expect(names.length).toBe([...new Set(names)].length); + }); }); diff --git a/tests/services/local-storage-service.test.ts b/tests/services/local-storage-service.test.ts index 38185166..01be6e2b 100644 --- a/tests/services/local-storage-service.test.ts +++ b/tests/services/local-storage-service.test.ts @@ -1,4 +1,3 @@ -import { CocktailInformation } from 'domain/entities/cocktail-information'; import { LocalStorageService, StorageKey } from 'services/local-storage-service'; import { expect } from '@jest/globals'; import { IngredientList } from 'domain/entities/ingredient-list'; @@ -57,54 +56,6 @@ describe('LocalStorageService', () => { expect(result).toStrictEqual(['1', '2', '3']); }); - test('Initialize - Migrate from FavoriteCocktails', async () => { - const key = 'CapacitorStorage.favorite-cocktails'; - window.localStorage.setItem(key, JSON.stringify(['1', '2', '3'])); - await sut.initialize(); - - const cocktailInformation = JSON.parse( - window.localStorage.getItem('CapacitorStorage.cocktail-information') - ) as CocktailInformation[]; - - expect(cocktailInformation.length).toBe(3); - - for (let i = 1; i < cocktailInformation.length; i++) { - const element = cocktailInformation[i - 1]; - expect(element.id).toBe(i.toString()); - expect(element.isFavorite).toBe(true); - } - - expect(window.localStorage.getItem(key)).toBeNull(); - }); - - test('Initialize - Migrate from FavoriteCocktails - existing rating', async () => { - const key = 'CapacitorStorage.favorite-cocktails'; - const informationKey = 'CapacitorStorage.cocktail-information'; - - window.localStorage.setItem(key, JSON.stringify(['1', '2', '3'])); - window.localStorage.setItem( - informationKey, - JSON.stringify([ - { - id: '1', - rating: 5 - } - ]) - ); - - await sut.initialize(); - - const cocktailInformation = JSON.parse( - window.localStorage.getItem('CapacitorStorage.cocktail-information') - ) as CocktailInformation[]; - - expect(cocktailInformation.length).toBe(3); - expect(window.localStorage.getItem(key)).toBeNull(); - expect(cocktailInformation[0].rating).toBeTruthy(); - expect(cocktailInformation[1].rating).toBeUndefined(); - expect(cocktailInformation[2].rating).toBeUndefined(); - }); - test('Initialize - Migrate from Saved Ingredients', async () => { const key = 'CapacitorStorage.saved-ingredients'; @@ -123,4 +74,23 @@ describe('LocalStorageService', () => { expect(ingredientLists[0].id).toBe(0); expect(ingredientLists[0].name).toBe('My Bar'); }); + + test('Initialize - Remove Ingredient with id 150', async () => { + const key = 'CapacitorStorage.' + StorageKey.IngredientLists; + + window.localStorage.setItem( + key, + JSON.stringify([ + { name: 'My Bar', ingredients: ['1', '150'] }, + { name: 'Test', ingredients: ['150', '2'] } + ]) + ); + + await sut.initialize(); + + const ingredientLists = JSON.parse(window.localStorage.getItem(key)) as IngredientList[]; + expect(ingredientLists.length).toBe(2); + expect(ingredientLists[0].ingredients).toEqual(['1']); + expect(ingredientLists[1].ingredients).toEqual(['2']); + }); });