├── .prettierignore ├── fastlane ├── metadata │ └── android │ │ └── en-US │ │ ├── video.txt │ │ ├── changelogs │ │ ├── 12201.txt │ │ ├── 12101.txt │ │ ├── 13600.txt │ │ ├── 12701.txt │ │ ├── 13602.txt │ │ ├── 14402.txt │ │ ├── 14900.txt │ │ ├── 13301.txt │ │ ├── 13400.txt │ │ ├── 13601.txt │ │ ├── 15101.txt │ │ ├── 15700.txt │ │ ├── 13900.txt │ │ ├── 15300.txt │ │ ├── 12000.txt │ │ ├── 13700.txt │ │ ├── 13901.txt │ │ ├── 15701.txt │ │ ├── 14400.txt │ │ ├── 14401.txt │ │ ├── 15600.txt │ │ ├── 11100.txt │ │ ├── 11500.txt │ │ ├── 11400.txt │ │ ├── 11601.txt │ │ ├── 12600.txt │ │ ├── 14501.txt │ │ ├── 14600.txt │ │ ├── 15100.txt │ │ ├── 12300.txt │ │ ├── 15401.txt │ │ ├── 15000.txt │ │ ├── 11001.txt │ │ ├── 12200.txt │ │ ├── 12800.txt │ │ ├── 14201.txt │ │ ├── 14500.txt │ │ ├── 10807.txt │ │ ├── 11600.txt │ │ ├── 11002.txt │ │ ├── 11300.txt │ │ ├── 11901.txt │ │ ├── 14700.txt │ │ ├── 12400.txt │ │ ├── 14000.txt │ │ ├── 13500.txt │ │ ├── 11902.txt │ │ ├── 14800.txt │ │ ├── 10900.txt │ │ ├── 11800.txt │ │ ├── 12100.txt │ │ ├── 14300.txt │ │ ├── 11801.txt │ │ ├── 15200.txt │ │ ├── 10806.txt │ │ ├── 13000.txt │ │ ├── 15801.txt │ │ ├── 11000.txt │ │ ├── 11200.txt │ │ ├── 13300.txt │ │ ├── 12700.txt │ │ ├── 12500.txt │ │ ├── 13800.txt │ │ ├── 14200.txt │ │ ├── 15800.txt │ │ ├── 13100.txt │ │ ├── 14100.txt │ │ ├── 11700.txt │ │ ├── 12900.txt │ │ ├── 13200.txt │ │ ├── 15400.txt │ │ └── 15500.txt │ │ ├── title.txt │ │ ├── short_description.txt │ │ ├── images │ │ ├── icon.png │ │ ├── featureGraphic.png │ │ ├── phoneScreenshots │ │ │ ├── 1_en-US.png │ │ │ ├── 2_en-US.png │ │ │ ├── 3_en-US.png │ │ │ ├── 4_en-US.png │ │ │ ├── 5_en-US.png │ │ │ └── 6_en-US.png │ │ ├── tenInchScreenshots │ │ │ ├── 1_en-US.png │ │ │ ├── 2_en-US.png │ │ │ ├── 3_en-US.png │ │ │ ├── 4_en-US.png │ │ │ └── 5_en-US.png │ │ └── sevenInchScreenshots │ │ │ ├── 1_en-US.png │ │ │ ├── 2_en-US.png │ │ │ ├── 3_en-US.png │ │ │ ├── 4_en-US.png │ │ │ └── 5_en-US.png │ │ └── full_description.txt ├── Appfile ├── README.md └── Fastfile ├── cypress ├── support │ ├── e2e.ts │ ├── index.d.ts │ └── commands.ts ├── tsconfig.json └── e2e │ ├── home.cy.ts │ └── validation-helpers │ └── validate-cocktail.ts ├── tests ├── jest-setup.ts ├── data │ ├── ingredient-data.test.ts │ └── cocktail-data.test.ts ├── domain │ └── unit.test.ts ├── services │ └── local-storage-service.test.ts └── functions │ └── utils.test.ts ├── android ├── app │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── feature-graphic.png │ │ │ ├── res │ │ │ │ ├── drawable │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-hdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-mdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-xhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-hdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-mdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-xhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-xxhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-land-xxxhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-xxhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── drawable-port-xxxhdpi │ │ │ │ │ └── splash.png │ │ │ │ ├── values │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── xml │ │ │ │ │ ├── config.xml │ │ │ │ │ └── file_paths.xml │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ └── layout │ │ │ │ │ └── activity_main.xml │ │ │ ├── ic_launcher-playstore.png │ │ │ ├── assets │ │ │ │ ├── capacitor.config.json │ │ │ │ └── capacitor.plugins.json │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── moimob │ │ │ │ └── drinkable │ │ │ │ └── MainActivity.java │ │ ├── test │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── getcapacitor │ │ │ │ └── myapp │ │ │ │ └── ExampleUnitTest.java │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── getcapacitor │ │ │ └── myapp │ │ │ └── ExampleInstrumentedTest.java │ ├── capacitor.build.gradle │ └── proguard-rules.pro ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle ├── variables.gradle ├── capacitor.settings.gradle ├── build.gradle └── gradle.properties ├── .htmlhintrc ├── Gemfile ├── src ├── locales │ └── sv │ │ ├── cocktails.json │ │ └── instructions.json ├── components │ ├── widgets │ │ ├── season-explore │ │ │ ├── season.ts │ │ │ ├── get-active-season.ts │ │ │ └── season-explore.html │ │ ├── navigation-widget │ │ │ ├── navigation-widget.ts │ │ │ └── navigation-widget.html │ │ ├── add-ingredients │ │ │ ├── add-ingredients.scss │ │ │ └── add-ingredients.ts │ │ └── explore-section │ │ │ └── explore-section.scss │ ├── tag-component.html │ ├── icons │ │ ├── icon-menu.html │ │ ├── icon-add.html │ │ ├── icon-chevron-forward.html │ │ ├── icon-arrow-forward.html │ │ ├── icon-bookmark.html │ │ ├── icon-chevron-back.html │ │ ├── icon-checkmark.html │ │ ├── icon-close.html │ │ ├── icon-arrow-back.html │ │ ├── icon-ellipsis-vertical.html │ │ ├── icon-leaf.html │ │ ├── icon-pencil.html │ │ ├── icon-heart.html │ │ ├── icon-save.html │ │ ├── icon-refresh-outline.html │ │ ├── icon-reader.html │ │ ├── icon-clipboard.html │ │ ├── icon-mail.html │ │ ├── icon-wine.html │ │ ├── icon-person.html │ │ ├── icon-trash.html │ │ ├── icon-image.html │ │ ├── icon-repeat.html │ │ ├── icon-filter.html │ │ └── icon-settings.html │ ├── toast │ │ ├── toast-container.html │ │ └── toast-container.ts │ ├── copy-to-clipboard │ │ ├── copy-to-clipboard.html │ │ └── copy-to-clipboard.ts │ ├── navbar │ │ ├── navbar.html │ │ └── navbar.ts │ ├── dialogs │ │ ├── cocktail-dialog │ │ │ └── manage-ingredient-row.html │ │ ├── edit-tags-drawer.html │ │ └── edit-tags-drawer.ts │ └── cocktail-list-item.html ├── domain │ ├── models │ │ ├── key-value.ts │ │ ├── enum-translation-model.ts │ │ ├── swipe-navigation.ts │ │ └── alphabetical-group.ts │ ├── enums │ │ ├── messuarement-system.ts │ │ ├── widget.ts │ │ ├── drink-type-filter.ts │ │ ├── alcohol-level.ts │ │ ├── drink-category.ts │ │ ├── spirit-type.ts │ │ └── unit.ts │ └── entities │ │ ├── ingredient-list.ts │ │ ├── widget-order.ts │ │ ├── cocktail-tag.ts │ │ ├── cocktail-information.ts │ │ ├── ingredient.ts │ │ ├── setting-entity.ts │ │ └── cocktail.ts ├── resource.d.ts ├── app.html ├── modules │ ├── user │ │ ├── shopping-list │ │ │ ├── unshopped-count-value-converter.ts │ │ │ └── shopping-list-models.ts │ │ ├── cocktails │ │ │ ├── user-cocktails.html │ │ │ └── user-cocktails.ts │ │ ├── ingredient-substitutions │ │ │ ├── ingredient-substitutions.ts │ │ │ └── ingredient-substitutions.html │ │ ├── user-router.html │ │ ├── ingredient-lists │ │ │ ├── ingredient-lists.html │ │ │ └── ingredient-lists.ts │ │ ├── tags │ │ │ ├── user-tags.html │ │ │ └── user-tags.ts │ │ └── ingredients │ │ │ ├── user-ingredients.html │ │ │ └── user-ingredients.ts │ ├── ingredients │ │ ├── selected-ingredients-list-component.html │ │ ├── selected-ingredients-list-component.ts │ │ ├── ingredients.html │ │ ├── all-ingredients │ │ │ └── all-ingredients.ts │ │ └── search-ingredients │ │ │ └── search-ingredients.html │ ├── home │ │ ├── home.html │ │ ├── home-settings.html │ │ ├── home-router.ts │ │ └── home.ts │ └── cocktails │ │ ├── all-cocktails │ │ └── all-cocktails.html │ │ ├── dialogs │ │ └── manage-cocktail-row-dialog.html │ │ ├── cocktail-filter-component.html │ │ └── cocktails.html ├── services │ ├── dev-tools-service.ts │ ├── supabase-service.ts │ └── theme-service.ts └── data │ ├── languages.ts │ └── tags-data.ts ├── static ├── favicon.ico └── images │ ├── at&t.jpg │ ├── b_52.jpg │ ├── almeria.jpg │ ├── bellini.jpg │ ├── boxcar.jpg │ ├── bramble.jpg │ ├── casino.jpg │ ├── gimlet.jpg │ ├── gt_blue.jpg │ ├── mai_tai.jpg │ ├── mimosa.jpg │ ├── mojito.jpg │ ├── negroni.jpg │ ├── paloma.jpg │ ├── sangria.jpg │ ├── sazerac.jpg │ ├── sidecar.jpg │ ├── snowday.jpg │ ├── stinger.jpg │ ├── tschunk.png │ ├── tuxedo.jpg │ ├── vampiro.jpg │ ├── vesper.jpg │ ├── afterglow.jpg │ ├── alexander.jpg │ ├── algonquin.jpg │ ├── allegheny.jpg │ ├── almond_joy.jpg │ ├── americano.jpg │ ├── angel_face.png │ ├── aviation.jpg │ ├── balmoral.jpg │ ├── barracuda.png │ ├── bees_knees.jpg │ ├── blackthorn.jpg │ ├── bluebird.jpg │ ├── caipirinha.jpg │ ├── christmas.jpg │ ├── cuba_libre.jpg │ ├── daiquiri.jpg │ ├── foxy_lady.jpg │ ├── french75.jpg │ ├── gin_fizz.jpg │ ├── gin_sour.jpg │ ├── gin_tonic.jpg │ ├── godfather.jpg │ ├── grand_blue.jpg │ ├── greyhound.jpg │ ├── halloween.jpg │ ├── hot_shot.jpg │ ├── hot_toddy.jpg │ ├── kamikaze.jpg │ ├── last_word.jpg │ ├── manhattan.jpg │ ├── margarita.jpg │ ├── martinez.jpg │ ├── melon_sour.jpg │ ├── mint_julep.jpg │ ├── moranguito.jpg │ ├── no-image.png │ ├── old_cuban.jpg │ ├── orangeade.jpg │ ├── paradise.jpg │ ├── pegu_club.jpg │ ├── penicillin.jpg │ ├── pink_lady.jpg │ ├── pink_moon.jpg │ ├── pisco_sour.jpg │ ├── porto_flip.jpg │ ├── rusty_nail.jpg │ ├── sea_breeze.jpg │ ├── stone_sour.jpg │ ├── the_galah.jpg │ ├── tipperary.jpg │ ├── white_lady.jpg │ ├── zorbatini.jpg │ ├── apple_karate.jpg │ ├── belgian_blue.jpg │ ├── bloody_mary.jpg │ ├── bloody_punch.jpg │ ├── blue_lagoon.jpg │ ├── boulevardier.jpg │ ├── campari_beer.jpg │ ├── city_slicker.jpg │ ├── clover_club.jpg │ ├── cosmopolitan.jpg │ ├── dry_martini.jpg │ ├── gin_swizzle.jpg │ ├── golden_dream.jpg │ ├── grasshopper.jpg │ ├── irish_coffee.jpg │ ├── irish_spring.jpg │ ├── john_collins.jpg │ ├── kiwi_martini.jpg │ ├── mango_mojito.jpg │ ├── monkey_gland.jpg │ ├── moscow_mule.jpg │ ├── mulled_wine.jpg │ ├── orange_crush.jpg │ ├── paper_plane.jpg │ ├── pina_colada.jpg │ ├── pink_panther.jpg │ ├── placeholder.jpg │ ├── pure_passion.jpg │ ├── ruby_tuesday.jpg │ ├── screwdriver.jpg │ ├── simple_syrup.jpg │ ├── tequila_sour.jpg │ ├── tom_collins.jpg │ ├── vodka_lemon.jpg │ ├── vodka_tonic.jpg │ ├── whiskey_sour.jpg │ ├── winter_rita.jpg │ ├── yellow_bird.jpg │ ├── alabama_slammer.jpg │ ├── alfie_cocktail.jpg │ ├── alice_cocktail.jpg │ ├── amaretto_fizz.jpg │ ├── amaretto_rose.jpg │ ├── amaretto_sour.jpg │ ├── aperol_spritz.jpg │ ├── apple_highball.jpg │ ├── apple_slammer.jpg │ ├── black_margarita.png │ ├── black_russian.jpg │ ├── blue_margarita.jpg │ ├── bombay_cassis.jpg │ ├── bounty_hunter.jpg │ ├── casino_royale.jpg │ ├── corpse_reviver.jpg │ ├── dark_and_stormy.jpg │ ├── french_martini.jpg │ ├── halloween_punch.jpg │ ├── happy_skipper.jpg │ ├── havana_cocktail.jpg │ ├── mary_pickford.jpg │ ├── new_york_sour.jpg │ ├── old_fashioned.jpg │ ├── pumpkin_martini.jpg │ ├── sherry_eggnog.jpg │ ├── singapore_sling.jpg │ ├── sweet_and_sour.jpg │ ├── tequila_sunrise.jpg │ ├── the_philosopher.jpg │ ├── vermouth_cassis.jpg │ ├── white_russian.jpg │ ├── zizi_coin-coin.jpg │ ├── absolut_limousine.jpg │ ├── aquafaba_gin_fizz.png │ ├── autumn_garibaldi.jpg │ ├── banana_milk_shake.jpg │ ├── bermuda_highball.jpg │ ├── blueberry_mojito.jpg │ ├── brandy_alexander.jpg │ ├── english_highball.jpg │ ├── espresso_martini.jpg │ ├── french_connection.jpg │ ├── frozen_margarita.png │ ├── harvey_wallbanger.jpg │ ├── hemingway_special.jpg │ ├── hot_buttered_rum.jpg │ ├── imperial_cocktail.jpg │ ├── mountain_bramble.jpg │ ├── negroni_sbagliato.jpg │ ├── pornstar_martini.jpg │ ├── pumpkin_pie_spice.jpg │ ├── sex_on_the_beach.jpg │ ├── sloe_gin_cocktail.jpg │ ├── spritz_veneziano.jpg │ ├── tommys_margarita.jpg │ ├── valencia_cocktail.jpg │ ├── a_furlong_too_late.jpg │ ├── arizona_antifreeze.jpg │ ├── between_the_sheets.jpg │ ├── brave_bull_shooter.jpg │ ├── california_lemonade.jpg │ ├── california_root_beer.jpg │ ├── captain_kidds_punch.jpg │ ├── champagne_cocktail.jpg │ ├── cocktail_horses_neck.jpg │ ├── jack_rose_cocktail.jpg │ ├── lazy_coconut_paloma.jpg │ ├── long_island_ice_tea.jpg │ ├── mezcal_old_fashioned.jpg │ ├── russian_spring_punch.jpg │ ├── strawberry_daiquiri.jpg │ ├── white_wine_sangria.jpg │ ├── after_dinner_cocktail.jpg │ ├── elderflower_caipirinha.jpg │ ├── english_rose_cocktail.jpg │ ├── salted_toffee_martini.jpg │ ├── swedish_blueberry_shot.jpg │ ├── chocolate_black_russian.jpg │ ├── lemon_elderflower_spritzer.jpg │ └── simple_long_island_ice_tea.jpg ├── ios ├── App │ ├── App │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── splash.png │ │ │ │ └── Contents.json │ │ │ └── Splash.imageset │ │ │ │ ├── splash-2732x2732.png │ │ │ │ ├── splash-2732x2732-1.png │ │ │ │ ├── splash-2732x2732-2.png │ │ │ │ └── Contents.json │ │ └── Base.lproj │ │ │ └── Main.storyboard │ ├── App.xcodeproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ ├── App.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Podfile │ └── Podfile.lock └── .gitignore ├── postcss.config.js ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── capacitor.config.ts ├── cypress.config.ts ├── renovate.json ├── jest.config.ts ├── .claude └── settings.local.json ├── .prettierrc ├── index.ejs ├── .github └── workflows │ ├── stale.yml │ ├── ci.yml │ └── fastlane-internal.yml ├── tailwind.config.js ├── tsconfig.json ├── LICENSE.md ├── .gitignore └── .eslintrc.json /.prettierignore: -------------------------------------------------------------------------------- 1 | android -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cypress/support/e2e.ts: -------------------------------------------------------------------------------- 1 | require('./commands'); 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12201.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | Drinkable -------------------------------------------------------------------------------- /tests/jest-setup.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | -------------------------------------------------------------------------------- /android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep 3 | -------------------------------------------------------------------------------- /.htmlhintrc: -------------------------------------------------------------------------------- 1 | { 2 | "attr-no-duplication": true 3 | } 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12101.txt: -------------------------------------------------------------------------------- 1 | • Fixed Mai Tai recpie -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13600.txt: -------------------------------------------------------------------------------- 1 | • Added Shopping Lists -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12701.txt: -------------------------------------------------------------------------------- 1 | • Fixed German translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13602.txt: -------------------------------------------------------------------------------- 1 | • Updated italian translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14402.txt: -------------------------------------------------------------------------------- 1 | • Fixed issue with snowflakes -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14900.txt: -------------------------------------------------------------------------------- 1 | • Added backup functionality -------------------------------------------------------------------------------- /src/locales/sv/cocktails.json: -------------------------------------------------------------------------------- 1 | { 2 | "pink-panther": "Rosa Pantern" 3 | } 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13301.txt: -------------------------------------------------------------------------------- 1 | • Updated portuguese translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13400.txt: -------------------------------------------------------------------------------- 1 | • Added Notes section for Cocktails -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13601.txt: -------------------------------------------------------------------------------- 1 | • Updated portuguese translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15101.txt: -------------------------------------------------------------------------------- 1 | • Updated California Lemonade recipe -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15700.txt: -------------------------------------------------------------------------------- 1 | • Update android target api level -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13900.txt: -------------------------------------------------------------------------------- 1 | • Added more Halloween themed cocktails -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15300.txt: -------------------------------------------------------------------------------- 1 | • Added ingredient substitutions page -------------------------------------------------------------------------------- /static/images/at&t.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/at&t.jpg -------------------------------------------------------------------------------- /static/images/b_52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/b_52.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12000.txt: -------------------------------------------------------------------------------- 1 | • Added 4 new units. dash, splash, slice and wedge -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13700.txt: -------------------------------------------------------------------------------- 1 | • Added support for multiple lists of ingredients -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13901.txt: -------------------------------------------------------------------------------- 1 | • Fixed issue with 'Show only favorites' filter -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15701.txt: -------------------------------------------------------------------------------- 1 | • Fix issue with app being overlapped by system gui -------------------------------------------------------------------------------- /src/components/widgets/season-explore/season.ts: -------------------------------------------------------------------------------- 1 | export type Season = 'christmas' | 'halloween'; 2 | -------------------------------------------------------------------------------- /static/images/almeria.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/almeria.jpg -------------------------------------------------------------------------------- /static/images/bellini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bellini.jpg -------------------------------------------------------------------------------- /static/images/boxcar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/boxcar.jpg -------------------------------------------------------------------------------- /static/images/bramble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bramble.jpg -------------------------------------------------------------------------------- /static/images/casino.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/casino.jpg -------------------------------------------------------------------------------- /static/images/gimlet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/gimlet.jpg -------------------------------------------------------------------------------- /static/images/gt_blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/gt_blue.jpg -------------------------------------------------------------------------------- /static/images/mai_tai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mai_tai.jpg -------------------------------------------------------------------------------- /static/images/mimosa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mimosa.jpg -------------------------------------------------------------------------------- /static/images/mojito.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mojito.jpg -------------------------------------------------------------------------------- /static/images/negroni.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/negroni.jpg -------------------------------------------------------------------------------- /static/images/paloma.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/paloma.jpg -------------------------------------------------------------------------------- /static/images/sangria.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sangria.jpg -------------------------------------------------------------------------------- /static/images/sazerac.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sazerac.jpg -------------------------------------------------------------------------------- /static/images/sidecar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sidecar.jpg -------------------------------------------------------------------------------- /static/images/snowday.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/snowday.jpg -------------------------------------------------------------------------------- /static/images/stinger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/stinger.jpg -------------------------------------------------------------------------------- /static/images/tschunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/tschunk.png -------------------------------------------------------------------------------- /static/images/tuxedo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/tuxedo.jpg -------------------------------------------------------------------------------- /static/images/vampiro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/vampiro.jpg -------------------------------------------------------------------------------- /static/images/vesper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/vesper.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14400.txt: -------------------------------------------------------------------------------- 1 | • Added Christmas Season 2 | • Added Old Cuban Cocktail -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14401.txt: -------------------------------------------------------------------------------- 1 | • Added 4 new cocktails 2 | • Added 1 new ingredient -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15600.txt: -------------------------------------------------------------------------------- 1 | • Fix an issue where app does not work on older devices -------------------------------------------------------------------------------- /static/images/afterglow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/afterglow.jpg -------------------------------------------------------------------------------- /static/images/alexander.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/alexander.jpg -------------------------------------------------------------------------------- /static/images/algonquin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/algonquin.jpg -------------------------------------------------------------------------------- /static/images/allegheny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/allegheny.jpg -------------------------------------------------------------------------------- /static/images/almond_joy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/almond_joy.jpg -------------------------------------------------------------------------------- /static/images/americano.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/americano.jpg -------------------------------------------------------------------------------- /static/images/angel_face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/angel_face.png -------------------------------------------------------------------------------- /static/images/aviation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/aviation.jpg -------------------------------------------------------------------------------- /static/images/balmoral.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/balmoral.jpg -------------------------------------------------------------------------------- /static/images/barracuda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/barracuda.png -------------------------------------------------------------------------------- /static/images/bees_knees.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bees_knees.jpg -------------------------------------------------------------------------------- /static/images/blackthorn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/blackthorn.jpg -------------------------------------------------------------------------------- /static/images/bluebird.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bluebird.jpg -------------------------------------------------------------------------------- /static/images/caipirinha.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/caipirinha.jpg -------------------------------------------------------------------------------- /static/images/christmas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/christmas.jpg -------------------------------------------------------------------------------- /static/images/cuba_libre.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/cuba_libre.jpg -------------------------------------------------------------------------------- /static/images/daiquiri.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/daiquiri.jpg -------------------------------------------------------------------------------- /static/images/foxy_lady.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/foxy_lady.jpg -------------------------------------------------------------------------------- /static/images/french75.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/french75.jpg -------------------------------------------------------------------------------- /static/images/gin_fizz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/gin_fizz.jpg -------------------------------------------------------------------------------- /static/images/gin_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/gin_sour.jpg -------------------------------------------------------------------------------- /static/images/gin_tonic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/gin_tonic.jpg -------------------------------------------------------------------------------- /static/images/godfather.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/godfather.jpg -------------------------------------------------------------------------------- /static/images/grand_blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/grand_blue.jpg -------------------------------------------------------------------------------- /static/images/greyhound.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/greyhound.jpg -------------------------------------------------------------------------------- /static/images/halloween.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/halloween.jpg -------------------------------------------------------------------------------- /static/images/hot_shot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/hot_shot.jpg -------------------------------------------------------------------------------- /static/images/hot_toddy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/hot_toddy.jpg -------------------------------------------------------------------------------- /static/images/kamikaze.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/kamikaze.jpg -------------------------------------------------------------------------------- /static/images/last_word.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/last_word.jpg -------------------------------------------------------------------------------- /static/images/manhattan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/manhattan.jpg -------------------------------------------------------------------------------- /static/images/margarita.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/margarita.jpg -------------------------------------------------------------------------------- /static/images/martinez.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/martinez.jpg -------------------------------------------------------------------------------- /static/images/melon_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/melon_sour.jpg -------------------------------------------------------------------------------- /static/images/mint_julep.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mint_julep.jpg -------------------------------------------------------------------------------- /static/images/moranguito.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/moranguito.jpg -------------------------------------------------------------------------------- /static/images/no-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/no-image.png -------------------------------------------------------------------------------- /static/images/old_cuban.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/old_cuban.jpg -------------------------------------------------------------------------------- /static/images/orangeade.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/orangeade.jpg -------------------------------------------------------------------------------- /static/images/paradise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/paradise.jpg -------------------------------------------------------------------------------- /static/images/pegu_club.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pegu_club.jpg -------------------------------------------------------------------------------- /static/images/penicillin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/penicillin.jpg -------------------------------------------------------------------------------- /static/images/pink_lady.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pink_lady.jpg -------------------------------------------------------------------------------- /static/images/pink_moon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pink_moon.jpg -------------------------------------------------------------------------------- /static/images/pisco_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pisco_sour.jpg -------------------------------------------------------------------------------- /static/images/porto_flip.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/porto_flip.jpg -------------------------------------------------------------------------------- /static/images/rusty_nail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/rusty_nail.jpg -------------------------------------------------------------------------------- /static/images/sea_breeze.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sea_breeze.jpg -------------------------------------------------------------------------------- /static/images/stone_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/stone_sour.jpg -------------------------------------------------------------------------------- /static/images/the_galah.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/the_galah.jpg -------------------------------------------------------------------------------- /static/images/tipperary.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/tipperary.jpg -------------------------------------------------------------------------------- /static/images/white_lady.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/white_lady.jpg -------------------------------------------------------------------------------- /static/images/zorbatini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/zorbatini.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11100.txt: -------------------------------------------------------------------------------- 1 | • Added German translation 2 | • Added Italian translation -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11500.txt: -------------------------------------------------------------------------------- 1 | • Added French translation 2 | • Fixed a bug with page titles -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | Explore and create cocktails with ingredients from home. -------------------------------------------------------------------------------- /static/images/apple_karate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/apple_karate.jpg -------------------------------------------------------------------------------- /static/images/belgian_blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/belgian_blue.jpg -------------------------------------------------------------------------------- /static/images/bloody_mary.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bloody_mary.jpg -------------------------------------------------------------------------------- /static/images/bloody_punch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bloody_punch.jpg -------------------------------------------------------------------------------- /static/images/blue_lagoon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/blue_lagoon.jpg -------------------------------------------------------------------------------- /static/images/boulevardier.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/boulevardier.jpg -------------------------------------------------------------------------------- /static/images/campari_beer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/campari_beer.jpg -------------------------------------------------------------------------------- /static/images/city_slicker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/city_slicker.jpg -------------------------------------------------------------------------------- /static/images/clover_club.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/clover_club.jpg -------------------------------------------------------------------------------- /static/images/cosmopolitan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/cosmopolitan.jpg -------------------------------------------------------------------------------- /static/images/dry_martini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/dry_martini.jpg -------------------------------------------------------------------------------- /static/images/gin_swizzle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/gin_swizzle.jpg -------------------------------------------------------------------------------- /static/images/golden_dream.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/golden_dream.jpg -------------------------------------------------------------------------------- /static/images/grasshopper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/grasshopper.jpg -------------------------------------------------------------------------------- /static/images/irish_coffee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/irish_coffee.jpg -------------------------------------------------------------------------------- /static/images/irish_spring.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/irish_spring.jpg -------------------------------------------------------------------------------- /static/images/john_collins.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/john_collins.jpg -------------------------------------------------------------------------------- /static/images/kiwi_martini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/kiwi_martini.jpg -------------------------------------------------------------------------------- /static/images/mango_mojito.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mango_mojito.jpg -------------------------------------------------------------------------------- /static/images/monkey_gland.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/monkey_gland.jpg -------------------------------------------------------------------------------- /static/images/moscow_mule.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/moscow_mule.jpg -------------------------------------------------------------------------------- /static/images/mulled_wine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mulled_wine.jpg -------------------------------------------------------------------------------- /static/images/orange_crush.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/orange_crush.jpg -------------------------------------------------------------------------------- /static/images/paper_plane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/paper_plane.jpg -------------------------------------------------------------------------------- /static/images/pina_colada.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pina_colada.jpg -------------------------------------------------------------------------------- /static/images/pink_panther.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pink_panther.jpg -------------------------------------------------------------------------------- /static/images/placeholder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/placeholder.jpg -------------------------------------------------------------------------------- /static/images/pure_passion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pure_passion.jpg -------------------------------------------------------------------------------- /static/images/ruby_tuesday.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/ruby_tuesday.jpg -------------------------------------------------------------------------------- /static/images/screwdriver.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/screwdriver.jpg -------------------------------------------------------------------------------- /static/images/simple_syrup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/simple_syrup.jpg -------------------------------------------------------------------------------- /static/images/tequila_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/tequila_sour.jpg -------------------------------------------------------------------------------- /static/images/tom_collins.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/tom_collins.jpg -------------------------------------------------------------------------------- /static/images/vodka_lemon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/vodka_lemon.jpg -------------------------------------------------------------------------------- /static/images/vodka_tonic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/vodka_tonic.jpg -------------------------------------------------------------------------------- /static/images/whiskey_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/whiskey_sour.jpg -------------------------------------------------------------------------------- /static/images/winter_rita.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/winter_rita.jpg -------------------------------------------------------------------------------- /static/images/yellow_bird.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/yellow_bird.jpg -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | json_key_file("./fastlane/service-account-key.json") 2 | package_name("com.moimob.drinkable") 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11400.txt: -------------------------------------------------------------------------------- 1 | • Added Dutch translation 2 | • Added Ability to Rate cocktails -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11601.txt: -------------------------------------------------------------------------------- 1 | • Cocktail filter button now displays the number of active filters -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12600.txt: -------------------------------------------------------------------------------- 1 | • Added Portuguese language 2 | • Added fractional measurements -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14501.txt: -------------------------------------------------------------------------------- 1 | • Updated cocktail images 2 | • Updated cocktail dialog design -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14600.txt: -------------------------------------------------------------------------------- 1 | • You can now edit base recipes 2 | • Updated German translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15100.txt: -------------------------------------------------------------------------------- 1 | • Updated Chinese translations 2 | • Updated German translations -------------------------------------------------------------------------------- /static/images/alabama_slammer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/alabama_slammer.jpg -------------------------------------------------------------------------------- /static/images/alfie_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/alfie_cocktail.jpg -------------------------------------------------------------------------------- /static/images/alice_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/alice_cocktail.jpg -------------------------------------------------------------------------------- /static/images/amaretto_fizz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/amaretto_fizz.jpg -------------------------------------------------------------------------------- /static/images/amaretto_rose.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/amaretto_rose.jpg -------------------------------------------------------------------------------- /static/images/amaretto_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/amaretto_sour.jpg -------------------------------------------------------------------------------- /static/images/aperol_spritz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/aperol_spritz.jpg -------------------------------------------------------------------------------- /static/images/apple_highball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/apple_highball.jpg -------------------------------------------------------------------------------- /static/images/apple_slammer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/apple_slammer.jpg -------------------------------------------------------------------------------- /static/images/black_margarita.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/black_margarita.png -------------------------------------------------------------------------------- /static/images/black_russian.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/black_russian.jpg -------------------------------------------------------------------------------- /static/images/blue_margarita.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/blue_margarita.jpg -------------------------------------------------------------------------------- /static/images/bombay_cassis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bombay_cassis.jpg -------------------------------------------------------------------------------- /static/images/bounty_hunter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bounty_hunter.jpg -------------------------------------------------------------------------------- /static/images/casino_royale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/casino_royale.jpg -------------------------------------------------------------------------------- /static/images/corpse_reviver.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/corpse_reviver.jpg -------------------------------------------------------------------------------- /static/images/dark_and_stormy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/dark_and_stormy.jpg -------------------------------------------------------------------------------- /static/images/french_martini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/french_martini.jpg -------------------------------------------------------------------------------- /static/images/halloween_punch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/halloween_punch.jpg -------------------------------------------------------------------------------- /static/images/happy_skipper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/happy_skipper.jpg -------------------------------------------------------------------------------- /static/images/havana_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/havana_cocktail.jpg -------------------------------------------------------------------------------- /static/images/mary_pickford.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mary_pickford.jpg -------------------------------------------------------------------------------- /static/images/new_york_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/new_york_sour.jpg -------------------------------------------------------------------------------- /static/images/old_fashioned.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/old_fashioned.jpg -------------------------------------------------------------------------------- /static/images/pumpkin_martini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pumpkin_martini.jpg -------------------------------------------------------------------------------- /static/images/sherry_eggnog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sherry_eggnog.jpg -------------------------------------------------------------------------------- /static/images/singapore_sling.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/singapore_sling.jpg -------------------------------------------------------------------------------- /static/images/sweet_and_sour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sweet_and_sour.jpg -------------------------------------------------------------------------------- /static/images/tequila_sunrise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/tequila_sunrise.jpg -------------------------------------------------------------------------------- /static/images/the_philosopher.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/the_philosopher.jpg -------------------------------------------------------------------------------- /static/images/vermouth_cassis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/vermouth_cassis.jpg -------------------------------------------------------------------------------- /static/images/white_russian.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/white_russian.jpg -------------------------------------------------------------------------------- /static/images/zizi_coin-coin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/zizi_coin-coin.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12300.txt: -------------------------------------------------------------------------------- 1 | • Added Sangria 2 | • Added 3 ingredients. Red wine, cloves, cinnamon -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15401.txt: -------------------------------------------------------------------------------- 1 | • Fixed bug with data storage when user had more than two bars 2 | -------------------------------------------------------------------------------- /src/domain/models/key-value.ts: -------------------------------------------------------------------------------- 1 | export class KeyValue { 2 | public key: string; 3 | public value: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/resource.d.ts: -------------------------------------------------------------------------------- 1 | declare const PRODUCTION: boolean; 2 | declare const WEB: boolean; 3 | declare const STORE: string; 4 | -------------------------------------------------------------------------------- /static/images/absolut_limousine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/absolut_limousine.jpg -------------------------------------------------------------------------------- /static/images/aquafaba_gin_fizz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/aquafaba_gin_fizz.png -------------------------------------------------------------------------------- /static/images/autumn_garibaldi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/autumn_garibaldi.jpg -------------------------------------------------------------------------------- /static/images/banana_milk_shake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/banana_milk_shake.jpg -------------------------------------------------------------------------------- /static/images/bermuda_highball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/bermuda_highball.jpg -------------------------------------------------------------------------------- /static/images/blueberry_mojito.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/blueberry_mojito.jpg -------------------------------------------------------------------------------- /static/images/brandy_alexander.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/brandy_alexander.jpg -------------------------------------------------------------------------------- /static/images/english_highball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/english_highball.jpg -------------------------------------------------------------------------------- /static/images/espresso_martini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/espresso_martini.jpg -------------------------------------------------------------------------------- /static/images/french_connection.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/french_connection.jpg -------------------------------------------------------------------------------- /static/images/frozen_margarita.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/frozen_margarita.png -------------------------------------------------------------------------------- /static/images/harvey_wallbanger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/harvey_wallbanger.jpg -------------------------------------------------------------------------------- /static/images/hemingway_special.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/hemingway_special.jpg -------------------------------------------------------------------------------- /static/images/hot_buttered_rum.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/hot_buttered_rum.jpg -------------------------------------------------------------------------------- /static/images/imperial_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/imperial_cocktail.jpg -------------------------------------------------------------------------------- /static/images/mountain_bramble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mountain_bramble.jpg -------------------------------------------------------------------------------- /static/images/negroni_sbagliato.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/negroni_sbagliato.jpg -------------------------------------------------------------------------------- /static/images/pornstar_martini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pornstar_martini.jpg -------------------------------------------------------------------------------- /static/images/pumpkin_pie_spice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/pumpkin_pie_spice.jpg -------------------------------------------------------------------------------- /static/images/sex_on_the_beach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sex_on_the_beach.jpg -------------------------------------------------------------------------------- /static/images/sloe_gin_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/sloe_gin_cocktail.jpg -------------------------------------------------------------------------------- /static/images/spritz_veneziano.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/spritz_veneziano.jpg -------------------------------------------------------------------------------- /static/images/tommys_margarita.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/tommys_margarita.jpg -------------------------------------------------------------------------------- /static/images/valencia_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/valencia_cocktail.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15000.txt: -------------------------------------------------------------------------------- 1 | • Added ability to restore backup without accessing files in the filesystem -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /static/images/a_furlong_too_late.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/a_furlong_too_late.jpg -------------------------------------------------------------------------------- /static/images/arizona_antifreeze.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/arizona_antifreeze.jpg -------------------------------------------------------------------------------- /static/images/between_the_sheets.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/between_the_sheets.jpg -------------------------------------------------------------------------------- /static/images/brave_bull_shooter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/brave_bull_shooter.jpg -------------------------------------------------------------------------------- /static/images/california_lemonade.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/california_lemonade.jpg -------------------------------------------------------------------------------- /static/images/california_root_beer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/california_root_beer.jpg -------------------------------------------------------------------------------- /static/images/captain_kidds_punch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/captain_kidds_punch.jpg -------------------------------------------------------------------------------- /static/images/champagne_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/champagne_cocktail.jpg -------------------------------------------------------------------------------- /static/images/cocktail_horses_neck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/cocktail_horses_neck.jpg -------------------------------------------------------------------------------- /static/images/jack_rose_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/jack_rose_cocktail.jpg -------------------------------------------------------------------------------- /static/images/lazy_coconut_paloma.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/lazy_coconut_paloma.jpg -------------------------------------------------------------------------------- /static/images/long_island_ice_tea.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/long_island_ice_tea.jpg -------------------------------------------------------------------------------- /static/images/mezcal_old_fashioned.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/mezcal_old_fashioned.jpg -------------------------------------------------------------------------------- /static/images/russian_spring_punch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/russian_spring_punch.jpg -------------------------------------------------------------------------------- /static/images/strawberry_daiquiri.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/strawberry_daiquiri.jpg -------------------------------------------------------------------------------- /static/images/white_wine_sangria.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/white_wine_sangria.jpg -------------------------------------------------------------------------------- /android/app/src/main/feature-graphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/feature-graphic.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11001.txt: -------------------------------------------------------------------------------- 1 | • Add better sorting for "1 missing ingredient" tab 2 | • Update navbar styling -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12200.txt: -------------------------------------------------------------------------------- 1 | • Added Sinhala language 2 | • Added app store variable for the contact form -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12800.txt: -------------------------------------------------------------------------------- 1 | • Added Cocktail Tags 2 | • Added Korean language 3 | • Added Chinese language -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14201.txt: -------------------------------------------------------------------------------- 1 | • Increased long press timings to avoid issue that dialog opens on scroll 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14500.txt: -------------------------------------------------------------------------------- 1 | • Added more cocktails 2 | • Fixed issues with long press 3 | • Minor UI fixes -------------------------------------------------------------------------------- /static/images/after_dinner_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/after_dinner_cocktail.jpg -------------------------------------------------------------------------------- /static/images/elderflower_caipirinha.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/elderflower_caipirinha.jpg -------------------------------------------------------------------------------- /static/images/english_rose_cocktail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/english_rose_cocktail.jpg -------------------------------------------------------------------------------- /static/images/salted_toffee_martini.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/salted_toffee_martini.jpg -------------------------------------------------------------------------------- /static/images/swedish_blueberry_shot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/swedish_blueberry_shot.jpg -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/10807.txt: -------------------------------------------------------------------------------- 1 | • Added Swedish language 2 | • Fixed a bug with text not showing in selection menu -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11600.txt: -------------------------------------------------------------------------------- 1 | • Added simple syrup & sweet and sour recipe 2 | • Added snowflakes during december -------------------------------------------------------------------------------- /static/images/chocolate_black_russian.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/chocolate_black_russian.jpg -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11002.txt: -------------------------------------------------------------------------------- 1 | • bug fixed causing "1 missing ingredient" tab displaying cocktails containing 1 ingredient -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11300.txt: -------------------------------------------------------------------------------- 1 | • Added Spanish translation 2 | • Added Catalan translation 3 | • Added Swipe Navigation -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11901.txt: -------------------------------------------------------------------------------- 1 | • Added more cocktails 🍸 2 | • Added Russian language 3 | • Added Polish language 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14700.txt: -------------------------------------------------------------------------------- 1 | • Updated UI toast design 2 | • Updated new york sour recipe 3 | • Added tschunk cocktail -------------------------------------------------------------------------------- /src/domain/enums/messuarement-system.ts: -------------------------------------------------------------------------------- 1 | export enum MessuarementSystem { 2 | Imperial = 'Imperial', 3 | Metric = 'Metric' 4 | } 5 | -------------------------------------------------------------------------------- /static/images/lemon_elderflower_spritzer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/lemon_elderflower_spritzer.jpg -------------------------------------------------------------------------------- /static/images/simple_long_island_ice_tea.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/static/images/simple_long_island_ice_tea.jpg -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12400.txt: -------------------------------------------------------------------------------- 1 | • Added Naviation Widget to the Home page 2 | • Added a button that clears all active filters -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14000.txt: -------------------------------------------------------------------------------- 1 | • Last selected bar will now load when restaring the app 2 | 3 | • Updated swedish translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const tailwindcss = require('tailwindcss'); 2 | module.exports = { 3 | plugins: ['postcss-preset-env', tailwindcss] 4 | }; 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13500.txt: -------------------------------------------------------------------------------- 1 | • Added Negroni Sbagliato cocktail 2 | • Fixed Espresso Martini recipe 3 | • Improved UI for tablets -------------------------------------------------------------------------------- /src/domain/entities/ingredient-list.ts: -------------------------------------------------------------------------------- 1 | export type IngredientList = { 2 | id: number; 3 | name: string; 4 | ingredients: string[]; 5 | }; 6 | -------------------------------------------------------------------------------- /src/domain/models/enum-translation-model.ts: -------------------------------------------------------------------------------- 1 | export class EnumTranslationModel { 2 | public value: T; 3 | public translation: string; 4 | } 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11902.txt: -------------------------------------------------------------------------------- 1 | • Fixed navigation issue with the From Ingredients widget 2 | • Fixed German ingredient translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14800.txt: -------------------------------------------------------------------------------- 1 | • Fixed Ingredient terminology 2 | • Updated German translations 3 | • Updated French translations 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/10900.txt: -------------------------------------------------------------------------------- 1 | • Major UI overhaul 2 | • Fixed a bug with the contact form showing an error even though the message was sent -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11800.txt: -------------------------------------------------------------------------------- 1 | • Added German translation for ingredients 2 | • Added option to filter Cocktails by a specific ingredient -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12100.txt: -------------------------------------------------------------------------------- 1 | • 3 new cocktails. Caipirinha, Elderflower Caipirinha and California Root Beer 2 | • 1 new ingredient. Cachaça -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14300.txt: -------------------------------------------------------------------------------- 1 | • Added option for users using the metric measurement system to select their preferred unit between ml and cl -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11801.txt: -------------------------------------------------------------------------------- 1 | • Fixed filter Cocktails by Ingredient to include substitute ingredients 2 | • Fixed issue with showing mocktails -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15200.txt: -------------------------------------------------------------------------------- 1 | • Added Hot Buttered Rum cocktail 2 | • Updated A Furlong Too Late recipe 3 | • Updated Absolut Limousine recipe -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/ios/App/App/Assets.xcassets/AppIcon.appiconset/splash.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/10806.txt: -------------------------------------------------------------------------------- 1 | • Added more cocktails 🍸 2 | • Added Mezcal ingredient 3 | • Added ability to submit your homemade cocktails for review. -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13000.txt: -------------------------------------------------------------------------------- 1 | • Cocktail instructions can now be translated 2 | • Updated Chinese translations 3 | • Updated Dutch translations 4 | -------------------------------------------------------------------------------- /src/domain/entities/widget-order.ts: -------------------------------------------------------------------------------- 1 | import { Widget } from 'domain/enums/widget'; 2 | 3 | export class WidgetOrder { 4 | widgetId: Widget; 5 | order: number; 6 | } 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15801.txt: -------------------------------------------------------------------------------- 1 | • New: Complete Chinese translations added for all app content 2 | • Improved: Translation tools and completeness checking scripts -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /src/domain/models/swipe-navigation.ts: -------------------------------------------------------------------------------- 1 | export type SwipeNavigation = { 2 | translation: string; 3 | vm: string; 4 | vmRef?: { 5 | bind(): void; 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #221e1c 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11000.txt: -------------------------------------------------------------------------------- 1 | • Minor UI fixes 2 | • Ingredient amount will now default be displayed in ML instead of CL when using metric 3 | • Added more cocktails 🍸 -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/tenInchScreenshots/4_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/tenInchScreenshots/4_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/tenInchScreenshots/5_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/tenInchScreenshots/5_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/sevenInchScreenshots/4_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/sevenInchScreenshots/4_en-US.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/sevenInchScreenshots/5_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MOIMOB/drinkable/HEAD/fastlane/metadata/android/en-US/images/sevenInchScreenshots/5_en-US.png -------------------------------------------------------------------------------- /src/domain/enums/widget.ts: -------------------------------------------------------------------------------- 1 | export enum Widget { 2 | ExploreSection = 0, 3 | IngredientWidget = 1, 4 | AddIngredients = 2, 5 | Navigation = 3, 6 | SeasonalCocktails = 4 7 | } 8 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11200.txt: -------------------------------------------------------------------------------- 1 | • Added more cocktails 🍸 2 | • Added Ingredient translations 3 | • Fixed Navbar styling 4 | • Add support for line breaks for cocktail description -------------------------------------------------------------------------------- /src/domain/entities/cocktail-tag.ts: -------------------------------------------------------------------------------- 1 | export type StaticTagModel = { 2 | id: string; 3 | translation: string; 4 | } 5 | 6 | export type TagModel = { 7 | name?: string; 8 | } & StaticTagModel; 9 | -------------------------------------------------------------------------------- /cypress/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["es5", "dom"], 5 | "types": ["cypress", "node"] 6 | }, 7 | "include": ["**/*.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13300.txt: -------------------------------------------------------------------------------- 1 | • Added 20 Cocktails 2 | • Added 11 Ingredients 3 | • Updated UI colors 4 | • Fixed an issue that caused rows to be hidden under the navigation bar for pages under Profile -> Manage -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12700.txt: -------------------------------------------------------------------------------- 1 | • Added toggle for home widget to change between Random and New Cocktails 2 | • Added 17 more cocktails 🍸 3 | • Added 9 more ingredients 4 | • Minor fixes for portuguese translation -------------------------------------------------------------------------------- /ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12500.txt: -------------------------------------------------------------------------------- 1 | • Added Search and Filters to 'From Ingredients' tab 2 | • 3 new cocktails. White Sangria, Ruussian Spring Punch and French Martini 3 | • 4 new ingredients. Apple, Lemon, Lime, Raspberry Liqueur -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13800.txt: -------------------------------------------------------------------------------- 1 | • Added Halloween themed cocktails 2 | • Added Halloween widget on the home page 3 | • Added Halloween and Punch category 4 | • Added Godfather cocktail 5 | 6 | • Updated chinese translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14200.txt: -------------------------------------------------------------------------------- 1 | • You can now add or remove cocktails from favorites from the cocktail list. A new menu will appear after a long press the cocktail 2 | • Added more cocktails 3 | 4 | • Updated swedish translations -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | #141110 5 | #221e1c 6 | -------------------------------------------------------------------------------- /android/app/src/main/assets/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "com.moimob.drinkable", 3 | "appName": "Drinkable", 4 | "webDir": "dist", 5 | "backgroundColor": "#161314", 6 | "android": { 7 | "adjustMarginsForEdgeToEdge": "auto" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/components/tag-component.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15800.txt: -------------------------------------------------------------------------------- 1 | • New: Navigation now shows "Mocktails" when you're viewing only mocktails 2 | • Improved: Page titles and messages now match your drink filter selection 3 | • Enhanced: App now shows both cocktails and mocktails by default -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13100.txt: -------------------------------------------------------------------------------- 1 | • Cocktails now displays Alochol by Volume (ABV) 2 | • Added sort option for Alcohol Levels (None, Low, Medium, Strong) 3 | • It is now possibe to edit ABV and Spirit Type for Custom Ingredients 4 | • Updated Swedish translations -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | App/build 2 | App/Pods 3 | App/output 4 | App/App/public 5 | DerivedData 6 | xcuserdata 7 | 8 | # Cordova plugins for Capacitor 9 | capacitor-cordova-ios-plugins 10 | 11 | # Generated Config files 12 | App/App/capacitor.config.json 13 | App/App/config.xml 14 | -------------------------------------------------------------------------------- /cypress/support/index.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace Cypress { 2 | // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/consistent-type-definitions 3 | interface Chainable { 4 | dataCy(value: string | string[]): Chainable; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14100.txt: -------------------------------------------------------------------------------- 1 | • You can now add or remove ingredients from selected bar within a cocktail recipe. A new menu will appear after a long press the ingredient 2 | • Added more ingredients 3 | 4 | • Updated swedish translations 5 | • Updated german translations -------------------------------------------------------------------------------- /src/modules/user/shopping-list/unshopped-count-value-converter.ts: -------------------------------------------------------------------------------- 1 | import { ShoppingListIngredient } from './shopping-list-models'; 2 | 3 | export class UnshoppedCountValueConverter { 4 | toView(value: ShoppingListIngredient[]) { 5 | return value.filter(x => !x.shopped).length; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "behzad88.aurelia", 4 | "dbaeumer.vscode-eslint", 5 | "esbenp.prettier-vscode", 6 | "bradlc.vscode-tailwindcss", 7 | "brandonseydel.aurelia-tools", 8 | "wingrunr21.vscode-ruby" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11700.txt: -------------------------------------------------------------------------------- 1 | • Added cocktail ingredient substitutes. For example Triple sec could be substituted with Cointreau 2 | • Added Mocktails. It's currently hidden by default but there is a setting to activate it 3 | • Updated Cocktail list item design 4 | • Fixed missing translations -------------------------------------------------------------------------------- /ios/App/App.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12900.txt: -------------------------------------------------------------------------------- 1 | • Users can now create custom tags 2 | • Added profile page to easy manage custom made cocktails, ingredients and tags 3 | • Added Cocktails, Paper Plane and IBA version of Long Island Ice Tea 4 | • Cocktail names can now be translated 5 | • Updated portuguese translations -------------------------------------------------------------------------------- /ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13200.txt: -------------------------------------------------------------------------------- 1 | • Added cocktail, ingredient and instruction translations in Italian 2 | • Updated Pina Colada recipe 3 | • Updated cocktail instructions in English with line breaks 4 | • Updated Italian App translations 5 | • Fixed calculations of translation status percentage to be more accurate -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15400.txt: -------------------------------------------------------------------------------- 1 | • Updated many cocktails to align with IBA 2 | • Updated French translations 3 | • Removed Spritz veneziano cocktail due to dupliaction 4 | • Added egg white as substitute for aquafaba, and aquafaba as substitute for egg white as these generally serve the same purpose in cocktails -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "splash.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /cypress/support/commands.ts: -------------------------------------------------------------------------------- 1 | Cypress.Commands.add('dataCy', input => { 2 | if (typeof input === 'string') { 3 | return cy.get(`[data-cy=${input}]`); 4 | } 5 | 6 | const dataCySelectorArray = input.map(x => `[data-cy=${x}]`); 7 | const stringValue = dataCySelectorArray.join(' '); 8 | return cy.get(stringValue); 9 | }); 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Drinkable 4 | Drinkable 5 | com.moimob.drinkable 6 | com.moimob.drinkable 7 | -------------------------------------------------------------------------------- /capacitor.config.ts: -------------------------------------------------------------------------------- 1 | import { CapacitorConfig } from '@capacitor/cli'; 2 | 3 | const config: CapacitorConfig = { 4 | appId: 'com.moimob.drinkable', 5 | appName: 'Drinkable', 6 | webDir: 'dist', 7 | backgroundColor: '#161314', 8 | android: { 9 | adjustMarginsForEdgeToEdge: 'auto' 10 | } 11 | }; 12 | 13 | export default config; 14 | -------------------------------------------------------------------------------- /cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress'; 2 | 3 | export default defineConfig({ 4 | e2e: { 5 | setupNodeEvents() { 6 | // implement node event listeners here 7 | }, 8 | baseUrl: 'http://localhost:8080', 9 | viewportWidth: 414, 10 | viewportHeight: 736, 11 | video: false 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /src/components/icons/icon-menu.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/components/icons/icon-add.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/components/icons/icon-chevron-forward.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/domain/entities/cocktail-information.ts: -------------------------------------------------------------------------------- 1 | import { DrinkCategory } from 'domain/enums/drink-category'; 2 | import { IngredientGroup } from './cocktail'; 3 | 4 | export type CocktailInformation = { 5 | id: string; 6 | rating?: number; 7 | isFavorite?: boolean; 8 | notes?: string; 9 | category?: DrinkCategory; 10 | tags?: string[]; 11 | ingredientGroups?: IngredientGroup[]; 12 | }; 13 | -------------------------------------------------------------------------------- /android/app/src/main/assets/capacitor.plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pkg": "@capacitor/app", 4 | "classpath": "com.capacitorjs.plugins.app.AppPlugin" 5 | }, 6 | { 7 | "pkg": "@capacitor/clipboard", 8 | "classpath": "com.capacitorjs.plugins.clipboard.ClipboardPlugin" 9 | }, 10 | { 11 | "pkg": "@capacitor/preferences", 12 | "classpath": "com.capacitorjs.plugins.preferences.PreferencesPlugin" 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:base"], 3 | "packageRules": [ 4 | { 5 | "matchPaths": ["+(package.json)"], 6 | "matchPackagePatterns": ["*"], 7 | "matchUpdateTypes": ["minor", "patch"], 8 | "groupName": "all non-major dependencies", 9 | "groupSlug": "all-minor-patch" 10 | } 11 | ], 12 | "prConcurrentLimit": 5 13 | } 14 | -------------------------------------------------------------------------------- /src/components/toast/toast-container.html: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /src/components/icons/icon-arrow-forward.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/components/icons/icon-bookmark.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/components/icons/icon-chevron-back.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/components/copy-to-clipboard/copy-to-clipboard.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/icons/icon-checkmark.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/components/icons/icon-close.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/modules/user/shopping-list/shopping-list-models.ts: -------------------------------------------------------------------------------- 1 | export type ShoppingList = { 2 | id: number; 3 | name: string; 4 | ingredients: ShoppingListIngredient[]; 5 | }; 6 | 7 | export type ShoppingListIngredient = { 8 | id: string; 9 | shopped: boolean; 10 | }; 11 | 12 | export type CreateShoppingListRequest = Pick; 13 | export type UpdateShoppingListRequest = Partial & Required>; 14 | -------------------------------------------------------------------------------- /src/components/icons/icon-arrow-back.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/modules/ingredients/selected-ingredients-list-component.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'jest'; 2 | 3 | export default async (): Promise => { 4 | return { 5 | roots: ['/tests'], 6 | testMatch: ['**/__tests__/**/*.+(ts|tsx|js)', '**/?(*.)+(spec|test).+(ts|tsx|js)'], 7 | transform: { 8 | '^.+\\.(ts|tsx)$': 'ts-jest' 9 | }, 10 | testEnvironment: 'jsdom', 11 | moduleDirectories: ['node_modules', 'src'], 12 | setupFiles: ['./tests/jest-setup.ts'] 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/icons/icon-ellipsis-vertical.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/services/dev-tools-service.ts: -------------------------------------------------------------------------------- 1 | import { autoinject } from 'aurelia-framework'; 2 | 3 | @autoinject 4 | export class DevToolsService { 5 | public isDevelopment = false; 6 | 7 | constructor() { 8 | if (!PRODUCTION) { 9 | document.addEventListener('keydown', (event: KeyboardEvent) => { 10 | if (event.ctrlKey && event.key === '1') { 11 | this.isDevelopment = !this.isDevelopment; 12 | } 13 | }); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /android/variables.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minSdkVersion = 23 3 | compileSdkVersion = 35 4 | targetSdkVersion = 35 5 | androidxActivityVersion = '1.9.2' 6 | androidxAppCompatVersion = '1.7.0' 7 | androidxCoordinatorLayoutVersion = '1.2.0' 8 | androidxCoreVersion = '1.15.0' 9 | androidxFragmentVersion = '1.8.4' 10 | coreSplashScreenVersion = '1.0.1' 11 | androidxWebkitVersion = '1.12.1' 12 | junitVersion = '4.13.2' 13 | androidxJunitVersion = '1.2.1' 14 | androidxEspressoCoreVersion = '3.6.1' 15 | cordovaAndroidVersion = '10.1.1' 16 | } -------------------------------------------------------------------------------- /src/domain/enums/drink-type-filter.ts: -------------------------------------------------------------------------------- 1 | export enum DrinkTypeFilter { 2 | Both = 0, 3 | OnlyCocktails = 1, 4 | OnlyMocktails = 2 5 | } 6 | 7 | export function getDrinkTypeFilterTranslations() { 8 | return [ 9 | { value: DrinkTypeFilter.Both, translation: 'drink-type-filter.both' }, 10 | { value: DrinkTypeFilter.OnlyCocktails, translation: 'drink-type-filter.only-cocktails' }, 11 | { value: DrinkTypeFilter.OnlyMocktails, translation: 'drink-type-filter.only-mocktails' } 12 | ]; 13 | } -------------------------------------------------------------------------------- /.claude/settings.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": { 3 | "allow": [ 4 | "Bash(npm run lint:*)", 5 | "Bash(npm test)", 6 | "Bash(npm start:*)", 7 | "Bash(npm run build:web:*)", 8 | "Bash(find:*)", 9 | "Bash(git checkout:*)", 10 | "Bash(git add:*)", 11 | "Bash(npm run build:*)", 12 | "Bash(npx cypress run:*)", 13 | "Bash(npm run:*)", 14 | "Bash(npx tsc:*)", 15 | "Bash(npx eslint:*)", 16 | "Bash(git push:*)" 17 | ], 18 | "deny": [] 19 | } 20 | } -------------------------------------------------------------------------------- /android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | 14 | @Test 15 | public void addition_isCorrect() throws Exception { 16 | assertEquals(4, 2 + 2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/toast/toast-container.ts: -------------------------------------------------------------------------------- 1 | import { autoinject, computedFrom } from 'aurelia-framework'; 2 | import { ToastElement, ToastService } from './toast-service'; 3 | 4 | @autoinject 5 | export class ToastContainer { 6 | constructor(private toastService: ToastService) {} 7 | 8 | removeToast(toast: ToastElement) { 9 | this.toastService.removeToastElement(toast.id); 10 | } 11 | 12 | @computedFrom('toastService.toastElements') 13 | get toasts() { 14 | return this.toastService.toastElements; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "splash-2732x2732-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "splash-2732x2732-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "splash-2732x2732.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /src/locales/sv/instructions.json: -------------------------------------------------------------------------------- 1 | { 2 | "bloody-mary": "Rör försiktigt och häll alla ingredienser i ett highballglas. \nGarnera.", 3 | "gin-&-tonic": "Häll över gin och tonic i ett isfyllt highballglas. \nGarnera med en limeklyfta och servera.", 4 | "mojito": "Muddla myntablad med socker och limejuice. \nHäll över en svätt sodavatten och fyll glaset med krossad is. \nHäll på romen och toppa med sodavatten. \nGarnera och servera med ett sugrör.", 5 | "pink-panther": "Häll alla ingredienser i en shaker med is och skaka. Sila sedan över i ett glas." 6 | } 7 | -------------------------------------------------------------------------------- /src/components/icons/icon-leaf.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "pwa-chrome", 9 | "request": "launch", 10 | "name": "Launch Chrome against localhost", 11 | "url": "http://localhost:8080", 12 | "webRoot": "${workspaceFolder}" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /src/components/icons/icon-pencil.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/modules/user/cocktails/user-cocktails.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /src/modules/user/ingredient-substitutions/ingredient-substitutions.ts: -------------------------------------------------------------------------------- 1 | import { autoinject } from 'aurelia-framework'; 2 | import { IngredientSubstitutionModel } from 'domain/entities/ingredient'; 3 | import { IngredientService } from 'services/ingredient-service'; 4 | 5 | @autoinject() 6 | export class IngredientSubstitutes { 7 | public ingredients: IngredientSubstitutionModel[] = []; 8 | 9 | constructor(private ingredientService: IngredientService) {} 10 | 11 | activate() { 12 | this.ingredients = this.ingredientService.getIngredinetWithsubstitutions(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15500.txt: -------------------------------------------------------------------------------- 1 | • Added dirty martini 2 | • Major update to bloody punch 3 | • Remove cream soda cocktail 4 | • Updated instructions for barracuda, Belgian blue, bloody mary, blue-lagoon, boulevardier, bluebird instructions 5 | • Updated bees knees 6 | • Updated Bellini recipe 7 | • Updated Bermuda highball 8 | • Updated allegheny recipe 9 | • Updated between he sheets 10 | • Updated ingredients/method of black margarita 11 | • Updated blackthorn wording 12 | • Updated bombay cassis 13 | • Updated bounty hunter 14 | • Updated boxcar recipe 15 | • Updated bramble recipe -------------------------------------------------------------------------------- /src/components/widgets/navigation-widget/navigation-widget.ts: -------------------------------------------------------------------------------- 1 | import { autoinject } from 'aurelia-framework'; 2 | import { Router } from 'aurelia-router'; 3 | 4 | @autoinject 5 | export class NavigationWidget { 6 | constructor(private _router: Router) {} 7 | 8 | navigateToFavorites() { 9 | const params = { 10 | activeNavigationIndex: 0, 11 | filter: 'favorites' 12 | }; 13 | 14 | this._router.navigateToRoute('cocktails', params); 15 | } 16 | 17 | navigateToShoppingLists() { 18 | this._router.navigate('#/user/shopping-lists'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/components/icons/icon-heart.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/moimob/drinkable/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.moimob.drinkable; 2 | 3 | import android.os.Bundle; 4 | import android.webkit.WebView; 5 | import com.getcapacitor.BridgeActivity; 6 | 7 | public class MainActivity extends BridgeActivity { 8 | @Override 9 | public void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | } 12 | 13 | @Override 14 | public void onStart() { 15 | super.onStart(); 16 | WebView webview = getBridge().getWebView(); 17 | webview.setOverScrollMode(WebView.OVER_SCROLL_NEVER); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/capacitor.build.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | 3 | android { 4 | compileOptions { 5 | sourceCompatibility JavaVersion.VERSION_21 6 | targetCompatibility JavaVersion.VERSION_21 7 | } 8 | } 9 | 10 | apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 | dependencies { 12 | implementation project(':capacitor-app') 13 | implementation project(':capacitor-clipboard') 14 | implementation project(':capacitor-preferences') 15 | 16 | } 17 | 18 | 19 | if (hasProperty('postBuildExtras')) { 20 | postBuildExtras() 21 | } 22 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": true, 4 | "endOfLine": "lf", 5 | "htmlWhitespaceSensitivity": "css", 6 | "insertPragma": false, 7 | "printWidth": 120, 8 | "proseWrap": "preserve", 9 | "quoteProps": "as-needed", 10 | "requirePragma": false, 11 | "semi": true, 12 | "singleQuote": true, 13 | "tabWidth": 4, 14 | "trailingComma": "none", 15 | "useTabs": false, 16 | "bracketSameLine": true, 17 | "plugins": ["prettier-plugin-organize-attributes"], 18 | "attributeGroups": ["^repeat.for$", "^if.bind$", "^click.delegate$", "$DEFAULT", "^data-cy"] 19 | } 20 | -------------------------------------------------------------------------------- /src/components/copy-to-clipboard/copy-to-clipboard.ts: -------------------------------------------------------------------------------- 1 | import { autoinject, bindable } from 'aurelia-framework'; 2 | import { Clipboard } from '@capacitor/clipboard'; 3 | @autoinject 4 | export class CopyToClipboard { 5 | @bindable public name: string; 6 | public textCopied = false; 7 | 8 | async copyToClipboard() { 9 | if (this.textCopied) { 10 | return; 11 | } 12 | 13 | await Clipboard.write({ 14 | string: this.name 15 | }); 16 | 17 | this.textCopied = true; 18 | 19 | setTimeout(() => { 20 | this.textCopied = false; 21 | }, 3000); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/icons/icon-save.html: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/components/icons/icon-refresh-outline.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /android/capacitor.settings.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | include ':capacitor-android' 3 | project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') 4 | 5 | include ':capacitor-app' 6 | project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') 7 | 8 | include ':capacitor-clipboard' 9 | project(':capacitor-clipboard').projectDir = new File('../node_modules/@capacitor/clipboard/android') 10 | 11 | include ':capacitor-preferences' 12 | project(':capacitor-preferences').projectDir = new File('../node_modules/@capacitor/preferences/android') 13 | -------------------------------------------------------------------------------- /src/domain/enums/alcohol-level.ts: -------------------------------------------------------------------------------- 1 | import { EnumTranslationModel } from 'domain/models/enum-translation-model'; 2 | 3 | export enum AlcoholLevel { 4 | Unknown = 0, 5 | None = 1, 6 | Weak = 2, 7 | Medium = 3, 8 | Strong = 4 9 | } 10 | 11 | export function getAlcoholLevels(): EnumTranslationModel[] { 12 | return [ 13 | { value: AlcoholLevel.None, translation: 'alcohol-level.none' }, 14 | { value: AlcoholLevel.Weak, translation: 'alcohol-level.weak' }, 15 | { value: AlcoholLevel.Medium, translation: 'alcohol-level.medium' }, 16 | { value: AlcoholLevel.Strong, translation: 'alcohol-level.strong' } 17 | ]; 18 | } 19 | -------------------------------------------------------------------------------- /src/modules/user/user-router.html: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /src/services/supabase-service.ts: -------------------------------------------------------------------------------- 1 | import { createClient, SupabaseClient } from '@supabase/supabase-js'; 2 | import { ContactFormModel } from '@moimob/common'; 3 | 4 | export class SupabaseService { 5 | private client: SupabaseClient; 6 | 7 | constructor() { 8 | const supabaseUrl = 'https://raausfwxehchgttjcffm.supabase.co'; 9 | const supabaseKey = process.env.SUPABASE_KEY; 10 | if (supabaseKey && STORE !== 'fdroid') { 11 | this.client = createClient(supabaseUrl, supabaseKey); 12 | } 13 | } 14 | 15 | async createContactForm(data: ContactFormModel) { 16 | return await this.client.from('ContactForm').insert([data]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/icons/icon-reader.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /src/components/widgets/add-ingredients/add-ingredients.scss: -------------------------------------------------------------------------------- 1 | add-ingredients { 2 | display: block; 3 | margin: 1rem 1rem 0.25em; 4 | 5 | > h5 { 6 | padding-top: 0.25em; 7 | } 8 | .panel-wrapper { 9 | > div { 10 | padding: 0.75em; 11 | display: flex; 12 | align-items: center; 13 | position: relative; 14 | > svg { 15 | height: 2em; 16 | position: absolute; 17 | right: 0.5em; 18 | } 19 | } 20 | > div:active { 21 | filter: brightness(1.2); 22 | } 23 | > div:last-child { 24 | border-bottom: 0px; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/modules/home/home.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /tests/data/ingredient-data.test.ts: -------------------------------------------------------------------------------- 1 | import { getStaticIngredients } from 'data/ingredient-data'; 2 | import { expect } from '@jest/globals'; 3 | 4 | describe('getStaticIngredients', () => { 5 | test('Ids should not include duplicates', () => { 6 | const ingredients = getStaticIngredients(); 7 | 8 | const ids = ingredients.map(x => x.id); 9 | 10 | expect(ids.length).toBe([...new Set(ids)].length); 11 | }); 12 | 13 | test('translation keys should not include duplicates', () => { 14 | const ingredients = getStaticIngredients(); 15 | 16 | const names = ingredients.map(x => x.translation); 17 | 18 | expect(names.length).toBe([...new Set(names)].length); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /tests/domain/unit.test.ts: -------------------------------------------------------------------------------- 1 | import { getUnitsForImperial, getUnitsForMetric, Unit } from 'domain/enums/unit'; 2 | import { expect } from '@jest/globals'; 3 | 4 | describe('Unit Enum', () => { 5 | it('should return all values of the Unit enum', () => { 6 | const expectedUnits = Object.values(Unit); 7 | const imperialUnits = getUnitsForImperial(); 8 | const metricUnits = getUnitsForMetric(); 9 | 10 | expect(imperialUnits.length).toEqual(expectedUnits.length); 11 | expect(new Set(imperialUnits).size).toEqual(imperialUnits.length); 12 | 13 | expect(metricUnits.length).toEqual(expectedUnits.length); 14 | expect(new Set(metricUnits).size).toEqual(metricUnits.length); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/components/icons/icon-clipboard.html: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /src/domain/entities/ingredient.ts: -------------------------------------------------------------------------------- 1 | import { SpiritType } from 'domain/enums/spirit-type'; 2 | 3 | export class StaticIngredient { 4 | public id: string; 5 | public translation: string; 6 | public spiritType?: SpiritType; 7 | public abv?: number; 8 | public recipeId?: string; 9 | public replacementIds?: string[]; 10 | } 11 | 12 | export class Ingredient extends StaticIngredient { 13 | public name: string; 14 | } 15 | 16 | export class ManageIngredientModel extends Ingredient { 17 | public isActive: boolean; 18 | } 19 | 20 | export type IngredientSubstitutionModel = Ingredient & { 21 | substitutions: string[]; 22 | }; 23 | 24 | export class CreatedIngredientModel extends Ingredient { 25 | public usedInCocktailNames: string[]; 26 | } 27 | -------------------------------------------------------------------------------- /src/components/icons/icon-mail.html: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /src/components/icons/icon-wine.html: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/components/widgets/navigation-widget/navigation-widget.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /src/data/languages.ts: -------------------------------------------------------------------------------- 1 | export function getLanguages() { 2 | return languages; 3 | } 4 | 5 | const languages = [ 6 | { value: undefined, name: 'English' }, 7 | { value: 'pr', name: 'Persian' }, 8 | { value: 'de', name: 'Deutsch' }, 9 | { value: 'sv', name: 'Svenska' }, 10 | { value: 'it', name: 'Italiano' }, 11 | { value: 'es', name: 'Español' }, 12 | { value: 'ca', name: 'Català' }, 13 | { value: 'nl', name: 'Nederlands' }, 14 | { value: 'fr', name: 'Français' }, 15 | { value: 'ru', name: 'Русский' }, 16 | { value: 'pl', name: 'Polski' }, 17 | { value: 'pt-BR', name: 'Português do Brasil' }, 18 | { value: 'si', name: 'සිංහල (Sinhala)' }, 19 | { value: 'kr', name: '한국어' }, 20 | { value: 'zh', name: '简体中文' } 21 | ] as const; 22 | -------------------------------------------------------------------------------- /src/components/icons/icon-person.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /src/domain/enums/drink-category.ts: -------------------------------------------------------------------------------- 1 | import { EnumTranslationModel } from 'domain/models/enum-translation-model'; 2 | 3 | export enum DrinkCategory { 4 | Cocktail = 0, 5 | Shot = 1, 6 | Other = 2, 7 | Ingredient = 3, 8 | Mocktail = 4 9 | } 10 | 11 | export function getDrinkCategories(): EnumTranslationModel[] { 12 | return [ 13 | { value: DrinkCategory.Cocktail, translation: 'drink-category.cocktail' }, 14 | { value: DrinkCategory.Shot, translation: 'drink-category.shot' }, 15 | { value: DrinkCategory.Other, translation: 'drink-category.other' }, 16 | { value: DrinkCategory.Ingredient, translation: 'drink-category.ingredient' }, 17 | { value: DrinkCategory.Mocktail, translation: 'drink-category.mocktail' } 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /src/domain/models/alphabetical-group.ts: -------------------------------------------------------------------------------- 1 | export class AlphabeticalGroup { 2 | constructor( 3 | public letter: string, 4 | public items: T[] 5 | ) {} 6 | } 7 | 8 | export function ToAlphabeticalGroup(items: T[], property = 'name'): AlphabeticalGroup[] { 9 | const letters = [...new Set(items.map(x => x[property]?.charAt(0)?.toLowerCase()).filter(x => x !== undefined))]; 10 | 11 | const group: AlphabeticalGroup[] = []; 12 | 13 | letters.forEach(element => { 14 | group.push( 15 | new AlphabeticalGroup( 16 | element, 17 | items.filter(x => x[property]?.charAt(0)?.toLowerCase() === element) 18 | ) 19 | ); 20 | }); 21 | 22 | return group.sort((a, b) => a.letter.localeCompare(b.letter)); 23 | } 24 | -------------------------------------------------------------------------------- /src/components/icons/icon-trash.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:8.11.0' 10 | classpath 'com.google.gms:google-services:4.4.2' 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20" 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | apply from: "variables.gradle" 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | mavenCentral() 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/components/widgets/season-explore/get-active-season.ts: -------------------------------------------------------------------------------- 1 | import { Season } from './season'; 2 | 3 | /** 4 | * Returns the active season based on the current date. 5 | * @param today - The current date. 6 | * @returns The active season, or null if no season is active. 7 | */ 8 | export function getActiveSeason(today: Date): Season { 9 | const month = today.getMonth() + 1; 10 | const day = today.getDate(); 11 | 12 | // Check if it's Halloween season (October 15th to November 7th) 13 | if ((month === 10 && day >= 15) || (month === 11 && day <= 7)) { 14 | return 'halloween'; 15 | } 16 | 17 | // Check if it's Christmas season (November 15th to January 7th) 18 | if ((month === 11 && day >= 15) || month === 12 || (month === 1 && day <= 7)) { 19 | return 'christmas'; 20 | } 21 | 22 | return null; 23 | } 24 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /src/components/icons/icon-image.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /src/modules/ingredients/selected-ingredients-list-component.ts: -------------------------------------------------------------------------------- 1 | import { autoinject } from 'aurelia-framework'; 2 | import { Router } from 'aurelia-router'; 3 | import { LocalStorageService } from 'services/local-storage-service'; 4 | 5 | @autoinject 6 | export class SelectedIngredientsListComponent { 7 | public ingredientListName: string; 8 | public showSelectedIngredientList = false; 9 | 10 | constructor( 11 | private _localStorageService: LocalStorageService, 12 | private _router: Router 13 | ) {} 14 | 15 | bind() { 16 | this.ingredientListName = this._localStorageService.getIngredientList().name; 17 | this.showSelectedIngredientList = this._localStorageService.getIngredientLists().length > 1; 18 | } 19 | 20 | navigateToUserPage() { 21 | this._router.navigateToRoute('user'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | ## fastlane documentation 2 | 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ```sh 8 | xcode-select --install 9 | ``` 10 | 11 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 12 | 13 | # Available Actions 14 | 15 | ## Android 16 | 17 | ### android internal 18 | 19 | ```sh 20 | [bundle exec] fastlane android internal 21 | ``` 22 | 23 | Submits release to Internal Testing 24 | 25 | --- 26 | 27 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 28 | 29 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 30 | 31 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 32 | -------------------------------------------------------------------------------- /index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Drinkable 6 | 7 | 8 | 9 | 10 | 16 | 17 | <% if (htmlWebpackPlugin.options.metadata.store === 'appstore') { %> 18 | 24 | <% } %> 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/domain/enums/spirit-type.ts: -------------------------------------------------------------------------------- 1 | import { EnumTranslationModel } from 'domain/models/enum-translation-model'; 2 | 3 | export enum SpiritType { 4 | None = 0, 5 | Gin = 1, 6 | Vodka = 2, 7 | Rum = 3, 8 | WiskeyScotch = 4, 9 | Tequila = 5, 10 | CognacBrandy = 6 11 | } 12 | 13 | export function getSpiritTypeFilters(): EnumTranslationModel[] { 14 | return [ 15 | { value: SpiritType.Gin, translation: 'spirit-type.gin' }, 16 | { value: SpiritType.Vodka, translation: 'spirit-type.vodka' }, 17 | { value: SpiritType.Rum, translation: 'spirit-type.rum' }, 18 | { value: SpiritType.Tequila, translation: 'spirit-type.tequila' }, 19 | { value: SpiritType.WiskeyScotch, translation: 'spirit-type.whiskey-scotch' }, 20 | { value: SpiritType.CognacBrandy, translation: 'spirit-type.cognac-brandy' } 21 | ]; 22 | } 23 | -------------------------------------------------------------------------------- /src/modules/home/home-settings.html: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/modules/user/cocktails/user-cocktails.ts: -------------------------------------------------------------------------------- 1 | import { DialogService } from 'aurelia-dialog'; 2 | import { autoinject } from 'aurelia-framework'; 3 | import { CocktailDialog } from 'components/dialogs/cocktail-dialog/cocktail-dialog'; 4 | import { Cocktail } from 'domain/entities/cocktail'; 5 | import { CocktailService } from 'services/cocktail-service'; 6 | 7 | @autoinject 8 | export class UserCocktails { 9 | public cocktails = []; 10 | 11 | constructor( 12 | private cocktailService: CocktailService, 13 | private dialogService: DialogService 14 | ) {} 15 | 16 | bind() { 17 | this.cocktails = this.cocktailService.getCreatedCocktails(); 18 | } 19 | 20 | openDialog(cocktail: Cocktail) { 21 | this.dialogService.open({ viewModel: CocktailDialog, model: cocktail, lock: false }).whenClosed(() => { 22 | this.bind(); 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/icons/icon-repeat.html: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. 2 | # 3 | # You can adjust the behavior by modifying this file. 4 | # For more information, see: 5 | # https://github.com/actions/stale 6 | name: Mark stale issues and pull requests 7 | 8 | on: 9 | schedule: 10 | - cron: '29 5 * * *' 11 | 12 | jobs: 13 | stale: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | issues: write 17 | pull-requests: write 18 | 19 | steps: 20 | - uses: actions/stale@v5 21 | with: 22 | repo-token: ${{ secrets.GITHUB_TOKEN }} 23 | stale-issue-message: 'Stale issue message' 24 | stale-pr-message: 'Stale pull request message' 25 | stale-issue-label: 'no-issue-activity' 26 | stale-pr-label: 'no-pr-activity' 27 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ['./src/**/*.{html,ts}'], 4 | theme: { 5 | extend: {} 6 | }, 7 | daisyui: { 8 | themes: [ 9 | { 10 | mytheme: { 11 | primary: '#dc2626', 12 | secondary: '#b91c1c', 13 | accent: '#0891b2', 14 | neutral: 'hsl(12, 6%, 18%)', 15 | 'base-100': '#221e1c', 16 | 'base-200': 'hsl(20, 10%, 9%)', 17 | 'base-300': '#161314', 18 | info: '#2dd4bf', 19 | success: '#84cc16', 20 | warning: '#fbbf24', 21 | error: '#ef4444' 22 | } 23 | }, 24 | 'autumn' 25 | ], 26 | logs: false 27 | }, 28 | plugins: [require('daisyui')] 29 | }; 30 | -------------------------------------------------------------------------------- /android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import android.content.Context; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | import androidx.test.platform.app.InstrumentationRegistry; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * @see Testing documentation 15 | */ 16 | @RunWith(AndroidJUnit4.class) 17 | public class ExampleInstrumentedTest { 18 | 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 23 | 24 | assertEquals("com.getcapacitor.app", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ios/App/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers' 2 | 3 | platform :ios, '14.0' 4 | use_frameworks! 5 | 6 | # workaround to avoid Xcode caching of Pods that requires 7 | # Product -> Clean Build Folder after new Cordova plugins installed 8 | # Requires CocoaPods 1.6 or newer 9 | install! 'cocoapods', :disable_input_output_paths => true 10 | 11 | def capacitor_pods 12 | pod 'Capacitor', :path => '../../node_modules/@capacitor/ios' 13 | pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' 14 | pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app' 15 | pod 'CapacitorClipboard', :path => '../../node_modules/@capacitor/clipboard' 16 | pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences' 17 | end 18 | 19 | target 'App' do 20 | capacitor_pods 21 | # Add your Pods here 22 | end 23 | 24 | post_install do |installer| 25 | assertDeploymentTarget(installer) 26 | end 27 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | default_platform(:android) 2 | 3 | platform :android do 4 | desc "Submits release to Production" 5 | lane :production do 6 | gradle(task: "clean", project_dir: 'android/') 7 | 8 | sh("echo $RELEASE_KEYSTORE > ./../android/release.jks.base64 9 | base64 -d ./../android/release.jks.base64 > ./../android/keystore.jks") 10 | 11 | sh("echo $SERVICE_ACCOUNT_KEY > ./service-account-key.base64 12 | base64 -d ./service-account-key.base64 > ./service-account-key.json") 13 | 14 | gradle( 15 | task: 'bundle', 16 | build_type: 'Release', 17 | project_dir: 'android/', 18 | print_command: false 19 | ) 20 | 21 | sh("jarsigner -keystore ./../android/keystore.jks -storepass $RELEASE_KEYSTORE_PASSWORD -signedjar ./../android/app/build/outputs/bundle/release/app-release.aab ./../android/app/build/outputs/bundle/release/app-release.aab key0") 22 | 23 | upload_to_play_store(track: 'production') 24 | 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /src/components/navbar/navbar.html: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/modules/cocktails/all-cocktails/all-cocktails.html: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /cypress/e2e/home.cy.ts: -------------------------------------------------------------------------------- 1 | describe('Home', () => { 2 | it('Navigate to Favorites', () => { 3 | window.localStorage.setItem('CapacitorStorage.messuarement-system', 'Metric'); 4 | cy.visit('#/'); 5 | 6 | cy.get('header').should('contain.text', 'Home'); 7 | cy.url().should('include', `home-router`); 8 | 9 | cy.dataCy('navigate-favorites').click(); 10 | 11 | cy.get('header').should('contain.text', 'Cocktails'); 12 | cy.url().should('include', `cocktails`); 13 | }); 14 | 15 | it('Navigate to Shopping Lists', () => { 16 | window.localStorage.setItem('CapacitorStorage.messuarement-system', 'Metric'); 17 | cy.visit('#/'); 18 | 19 | cy.get('header').should('contain.text', 'Home'); 20 | cy.url().should('include', `home-router`); 21 | 22 | cy.dataCy('navigate-shopping-lists').click(); 23 | 24 | cy.get('header').should('contain.text', 'Profile'); 25 | cy.url().should('include', `shopping-lists`); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 16 | 20 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # AndroidX package structure to make it clearer which packages are bundled with the 20 | # Android operating system, and which are packaged with your app's APK 21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 22 | android.useAndroidX=true 23 | 24 | -------------------------------------------------------------------------------- /src/domain/entities/setting-entity.ts: -------------------------------------------------------------------------------- 1 | import { DrinkTypeFilter } from '../enums/drink-type-filter'; 2 | 3 | export class SettingEntity { 4 | drinkTypeFilter: DrinkTypeFilter; 5 | language?: string; 6 | exploreWidgetState?: number; 7 | lastSelectedIngredientListId?: number; 8 | preferCl?: boolean; 9 | 10 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 11 | constructor(data?: any) { 12 | // Migration logic: if old data has showMocktails but no drinkTypeFilter 13 | if (data && data.showMocktails !== undefined && data.drinkTypeFilter === undefined) { 14 | this.drinkTypeFilter = data.showMocktails ? DrinkTypeFilter.Both : DrinkTypeFilter.OnlyCocktails; 15 | } else { 16 | this.drinkTypeFilter = data?.drinkTypeFilter ?? DrinkTypeFilter.Both; 17 | } 18 | 19 | this.language = data?.language; 20 | this.exploreWidgetState = data?.exploreWidgetState; 21 | this.lastSelectedIngredientListId = data?.lastSelectedIngredientListId; 22 | this.preferCl = data?.preferCl; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "skipLibCheck": true, 6 | "removeComments": true, 7 | "resolveJsonModule": true, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "sourceMap": true, 11 | "target": "es6", 12 | "moduleResolution": "node", 13 | "baseUrl": "src", 14 | "allowSyntheticDefaultImports": true, 15 | "esModuleInterop": true, 16 | "noUncheckedIndexedAccess": true, 17 | 18 | // When all of this is uncommented, remove and use: strict: true instead 19 | // "alwaysStrict": true, 20 | // "strictNullChecks": true, 21 | // "strictPropertyInitialization": true, 22 | "strictBindCallApply": true, 23 | "strictFunctionTypes": true, 24 | // "noImplicitAny": true, 25 | "noImplicitThis": true, 26 | "useUnknownInCatchVariables": true 27 | }, 28 | 29 | "include": ["src", "tests", "capacitor.config.ts", "jest.config.ts", "cypress.config.ts"] 30 | } 31 | -------------------------------------------------------------------------------- /ios/App/App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/modules/user/ingredient-lists/ingredient-lists.html: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | branches: [main] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: Validate Fastlane 15 | uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2 16 | with: 17 | usePlayStoreLocales: true 18 | 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: 22.x 23 | 24 | - name: Install app dependencies 25 | run: npm ci 26 | 27 | - name: Build Web 28 | run: npm run build 29 | 30 | - name: Run Web tests 31 | run: npm t 32 | 33 | - name: Capacitor update 34 | run: npx cap update 35 | 36 | - name: Capacitor copy 37 | run: npx cap copy 38 | 39 | - name: Cypress.io 40 | uses: cypress-io/github-action@v6.7.2 41 | with: 42 | start: npm start 43 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Anton Gustafsson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/domain/enums/unit.ts: -------------------------------------------------------------------------------- 1 | export enum Unit { 2 | FLOZ = 'fl oz', 3 | TSP = 'tsp', 4 | CL = 'cl', 5 | None = '', 6 | G = 'g', 7 | TBSP = 'tbsp', 8 | ML = 'ml', 9 | DL = 'dl', 10 | CUP = 'cup', 11 | DASH = 'dash', 12 | SPLASH = 'splash', 13 | SLICE = 'slice', 14 | WEDGE = 'wedge' 15 | } 16 | 17 | export function getUnitsForImperial(): Unit[] { 18 | return [ 19 | Unit.None, 20 | Unit.FLOZ, 21 | Unit.TSP, 22 | Unit.TBSP, 23 | Unit.CUP, 24 | Unit.DASH, 25 | Unit.SPLASH, 26 | Unit.SLICE, 27 | Unit.WEDGE, 28 | //Metric 29 | Unit.CL, 30 | Unit.ML, 31 | Unit.DL, 32 | Unit.G 33 | ]; 34 | } 35 | 36 | export function getUnitsForMetric(): Unit[] { 37 | return [ 38 | Unit.None, 39 | Unit.ML, 40 | Unit.CL, 41 | Unit.DL, 42 | Unit.TSP, 43 | Unit.TBSP, 44 | Unit.G, 45 | Unit.DASH, 46 | Unit.SPLASH, 47 | Unit.SLICE, 48 | Unit.WEDGE, 49 | //Imperial 50 | Unit.FLOZ, 51 | Unit.CUP 52 | ]; 53 | } 54 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | Drinkable is an app which help you find cocktails that you could make today with ingredients from home. You can also explore new great cocktails to make. The app will always let you know what ingredents is missing. 2 | 3 | Features: 4 | - Includes 150+ cocktails and 150+ ingredients. 5 | - Also includes Shots, Mocktails and Cocktail Ingredients. 6 | - Available in 10+ languages. 7 | - Ability to create your own cocktails, ingredients and tags in the app. 8 | - Lets you know what cocktails you can make with the ingredients you have at home. 9 | - 1 missing ingredient list. So you can easily pick up that last item and make a new cocktail. 10 | - Save favorite cocktails. 11 | - Rate cocktails with stars from zero to five. 12 | - Supports both Imperial and Metric measurement system. 13 | - Offline support, this app will work even if you dont have internet connection. 14 | - Simple User Interface. 15 | - Open source, code is avaliable on Github. 16 | 17 | Please reach out to anton@moimob.com if you have any questions or wish for a specific cocktail or feature to be added. 18 | 19 | Hope you enjoy these delicious cocktails! -------------------------------------------------------------------------------- /src/data/tags-data.ts: -------------------------------------------------------------------------------- 1 | import { StaticTagModel, TagModel } from 'domain/entities/cocktail-tag'; 2 | 3 | export enum Tag { 4 | IBA = '1', 5 | FormerIBA = '2', 6 | TheUnforgettables = '3', 7 | ContemporaryClassics = '4', 8 | NewEraDrinks = '5', 9 | Halloween = '6', 10 | Punch = '7', 11 | Christmas = '8' 12 | } 13 | 14 | const tags: StaticTagModel[] = [ 15 | { id: Tag.IBA, translation: 'tag-list.iba' }, 16 | { id: Tag.FormerIBA, translation: 'tag-list.former-iba' }, 17 | { id: Tag.TheUnforgettables, translation: 'tag-list.the-unforgettables' }, 18 | { id: Tag.ContemporaryClassics, translation: 'tag-list.contemporary-classics' }, 19 | { id: Tag.NewEraDrinks, translation: 'tag-list.new-era-drinks' }, 20 | { id: Tag.Punch, translation: 'tag-list.punch' }, 21 | { id: Tag.Halloween, translation: 'tag-list.halloween' }, 22 | { id: Tag.Christmas, translation: 'tag-list.christmas' } 23 | ]; 24 | 25 | export function getTags() { 26 | return tags; 27 | } 28 | 29 | export function getTagsFromIds(ids: string[]): TagModel[] { 30 | return ids?.map(id => tags.find(tag => tag.id === id)).filter(x => x !== undefined); 31 | } 32 | -------------------------------------------------------------------------------- /src/modules/user/tags/user-tags.html: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # You may want to customise this file depending on your Operating System 3 | # and the editor that you use. 4 | # 5 | # We recommend that you use a Global Gitignore for files that are not related 6 | # to the project. (https://help.github.com/articles/ignoring-files/#create-a-global-gitignore) 7 | 8 | # OS 9 | # 10 | # Ref: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore 11 | # Ref: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore 12 | # Ref: https://github.com/github/gitignore/blob/master/Global/Linux.gitignore 13 | .DS_STORE 14 | Thumbs.db 15 | 16 | # Editors 17 | # 18 | # Ref: https://github.com/github/gitignore/blob/master/Global 19 | # Ref: https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore 20 | # Ref: https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore 21 | .idea 22 | .chrome 23 | /*.log 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | 30 | # Dependencies 31 | node_modules 32 | 33 | # Compiled files 34 | /src/environment.ts 35 | /dist 36 | .env 37 | /coverage 38 | 39 | /fastlane/report.xml 40 | -------------------------------------------------------------------------------- /src/components/dialogs/cocktail-dialog/manage-ingredient-row.html: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /src/components/widgets/explore-section/explore-section.scss: -------------------------------------------------------------------------------- 1 | explore-section { 2 | display: block; 3 | margin: 1rem 1rem 0.25em; 4 | transition: all 0.2s ease; 5 | 6 | .box-wrapper { 7 | display: flex; 8 | overflow-x: scroll; 9 | padding-bottom: 0.25em; 10 | > div { 11 | margin-right: 0.75em; 12 | margin-left: 0.75em; 13 | display: flex; 14 | width: 4.5em; 15 | > img { 16 | min-width: 4.5em; 17 | height: 4.5em; 18 | object-fit: cover; 19 | border-radius: 50%; 20 | } 21 | > h6 { 22 | align-self: center; 23 | font-size: 1em; 24 | font-weight: 500; 25 | padding-bottom: 0.5em; 26 | padding-top: 0.25em; 27 | text-align: center; 28 | width: 100%; 29 | overflow: hidden; 30 | white-space: nowrap; 31 | font-size: 0.85em; 32 | text-overflow: ellipsis; 33 | } 34 | .svg-wrapper { 35 | display: flex; 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/components/cocktail-list-item.html: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /src/components/widgets/season-explore/season-explore.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /src/modules/home/home-router.ts: -------------------------------------------------------------------------------- 1 | import { RouterConfiguration, Router } from 'aurelia-router'; 2 | import { PLATFORM } from 'aurelia-framework'; 3 | 4 | export class HomeRouter { 5 | public router: Router; 6 | public isHomeTab = true; 7 | 8 | public toggleNavigation() { 9 | this.router.navigateToRoute(this.isHomeTab ? 'home-settings' : 'home'); 10 | this.isHomeTab = !this.isHomeTab; 11 | } 12 | 13 | public configureRouter(config: RouterConfiguration, router: Router): void { 14 | config.map([ 15 | { 16 | route: [''], 17 | name: 'home', 18 | moduleId: PLATFORM.moduleName('./home'), 19 | nav: false, 20 | title: 'Home' 21 | }, 22 | { 23 | route: ['home-settings'], 24 | name: 'home-settings', 25 | moduleId: PLATFORM.moduleName('./home-settings'), 26 | nav: false, 27 | title: 'Home Settings' 28 | } 29 | ]); 30 | this.router = router; 31 | } 32 | 33 | activate(_, __, navigationInstruction) { 34 | this.isHomeTab = !(navigationInstruction.params.childRoute === 'home-settings'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/modules/ingredients/ingredients.html: -------------------------------------------------------------------------------- 1 | 28 | -------------------------------------------------------------------------------- /src/services/theme-service.ts: -------------------------------------------------------------------------------- 1 | export class ThemeService { 2 | private storageKey = 'theme-preference'; 3 | private currentTheme: string; 4 | 5 | constructor() { 6 | this.currentTheme = localStorage.getItem(this.storageKey); 7 | const colorPreference = this.getColorPreference(this.currentTheme); 8 | this.reflectPreference(colorPreference); 9 | } 10 | 11 | public getLocalStorageResult() { 12 | return this.currentTheme; 13 | } 14 | 15 | public updateTheme(theme: string) { 16 | if (theme === null) { 17 | localStorage.removeItem(this.storageKey); 18 | this.currentTheme = theme; 19 | } else { 20 | localStorage.setItem(this.storageKey, theme); 21 | this.currentTheme = theme; 22 | } 23 | 24 | const colorPreference = this.getColorPreference(this.currentTheme); 25 | this.reflectPreference(colorPreference); 26 | } 27 | 28 | private getColorPreference(value: string) { 29 | if (value !== null) { 30 | return value; 31 | } 32 | 33 | return 'myTheme'; 34 | } 35 | 36 | private reflectPreference(theme: string) { 37 | document.firstElementChild.setAttribute('data-theme', theme); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/data/cocktail-data.test.ts: -------------------------------------------------------------------------------- 1 | import { getStaticCocktails } from 'data/cocktail-data'; 2 | import { Tag } from 'data/tags-data'; 3 | import { expect } from '@jest/globals'; 4 | describe('getStaticCocktails', () => { 5 | test('Ids should not include duplicates', () => { 6 | const cocktails = getStaticCocktails(); 7 | 8 | const ids = cocktails.map(x => x.id); 9 | 10 | expect(ids.length).toBe([...new Set(ids)].length); 11 | }); 12 | 13 | test('translation keys should not include duplicates', () => { 14 | const ingredients = getStaticCocktails(); 15 | 16 | const names = ingredients.map(x => x.translation); 17 | 18 | expect(names.length).toBe([...new Set(names)].length); 19 | }); 20 | 21 | test('IBA Cocktails should include a secondary IBA tag', () => { 22 | const cocktails = getStaticCocktails(); 23 | 24 | cocktails 25 | .filter(x => x.tags.includes(Tag.IBA)) 26 | .forEach(x => { 27 | const tags: string[] = [Tag.ContemporaryClassics, Tag.NewEraDrinks, Tag.TheUnforgettables]; 28 | 29 | const foundTags = x.tags.filter(y => tags.includes(y)); 30 | 31 | expect(foundTags.length).toBe(1); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /src/modules/cocktails/dialogs/manage-cocktail-row-dialog.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /src/components/icons/icon-filter.html: -------------------------------------------------------------------------------- 1 | 40 | -------------------------------------------------------------------------------- /src/modules/cocktails/cocktail-filter-component.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /src/modules/user/ingredients/user-ingredients.html: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /src/modules/user/tags/user-tags.ts: -------------------------------------------------------------------------------- 1 | import { DialogService } from 'aurelia-dialog'; 2 | import { autoinject } from 'aurelia-framework'; 3 | import { CocktailService } from 'services/cocktail-service'; 4 | import { TagModel } from 'domain/entities/cocktail-tag'; 5 | import { UserTagDrawer } from './user-tag-drawer'; 6 | 7 | @autoinject 8 | export class UserTags { 9 | public tags: CreatedTagModel[] = []; 10 | 11 | constructor( 12 | private _dialogService: DialogService, 13 | private _cocktailService: CocktailService 14 | ) {} 15 | 16 | bind() { 17 | const createdTags = this._cocktailService.getCreatedTags(); 18 | const cocktails = this._cocktailService.getCocktails(); 19 | 20 | this.tags = createdTags.map(tag => ({ 21 | ...tag, 22 | usedInCocktailNames: cocktails 23 | .filter(cocktail => cocktail.tags.includes(tag.id)) 24 | .map(cocktail => cocktail.name) 25 | })); 26 | } 27 | 28 | openDialog(tag: CreatedTagModel) { 29 | this._dialogService.open({ viewModel: UserTagDrawer, model: tag, lock: true }).whenClosed(() => { 30 | this.bind(); 31 | }); 32 | } 33 | } 34 | 35 | export type CreatedTagModel = { 36 | usedInCocktailNames: string[]; 37 | } & TagModel; 38 | -------------------------------------------------------------------------------- /src/components/dialogs/edit-tags-drawer.html: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /src/modules/user/ingredients/user-ingredients.ts: -------------------------------------------------------------------------------- 1 | import { DialogService } from 'aurelia-dialog'; 2 | import { autoinject } from 'aurelia-framework'; 3 | import { CreatedIngredientModel } from 'domain/entities/ingredient'; 4 | import { IngredientService } from 'services/ingredient-service'; 5 | import { CocktailService } from 'services/cocktail-service'; 6 | import { Cocktail } from 'domain/entities/cocktail'; 7 | import { UserIngredientDrawer } from './user-ingredient-drawer'; 8 | 9 | @autoinject 10 | export class UserIngredients { 11 | public ingredients: CreatedIngredientModel[] = []; 12 | private _cocktails: Cocktail[] = []; 13 | 14 | constructor( 15 | private _dialogService: DialogService, 16 | private _ingredientService: IngredientService, 17 | private _cocktailService: CocktailService 18 | ) {} 19 | 20 | bind() { 21 | this._cocktails = this._cocktailService.getCocktails(); 22 | 23 | this.ingredients = this._ingredientService.getCreatedIngredientModels(this._cocktails); 24 | } 25 | 26 | openDialog(ingredient: CreatedIngredientModel) { 27 | this._dialogService.open({ viewModel: UserIngredientDrawer, model: ingredient, lock: true }).whenClosed(() => { 28 | this.ingredients = this._ingredientService.getCreatedIngredientModels(this._cocktails); 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/components/navbar/navbar.ts: -------------------------------------------------------------------------------- 1 | import { bindable, inject, observable } from 'aurelia-framework'; 2 | import { Router } from 'aurelia-router'; 3 | import { EventAggregator, Subscription } from 'aurelia-event-aggregator'; 4 | import { LocalStorageService } from 'services/local-storage-service'; 5 | import { DrinkTypeFilter } from 'domain/enums/drink-type-filter'; 6 | 7 | @inject(EventAggregator, LocalStorageService) 8 | export class Navbar { 9 | @bindable public router: Router; 10 | @bindable public hidden: boolean; 11 | @observable public currentDrinkTypeFilter: DrinkTypeFilter; 12 | private _subscription: Subscription; 13 | 14 | constructor( 15 | private _ea: EventAggregator, 16 | private _localStorageService: LocalStorageService 17 | ) { 18 | this.currentDrinkTypeFilter = this._localStorageService.getSettings().drinkTypeFilter; 19 | } 20 | 21 | public navigate(route: string) { 22 | this.router.navigateToRoute(route); 23 | } 24 | 25 | 26 | attached() { 27 | this._subscription = this._ea.subscribe('cocktails-updated', () => { 28 | this.currentDrinkTypeFilter = this._localStorageService.getSettings().drinkTypeFilter; 29 | }); 30 | } 31 | 32 | detached() { 33 | if (this._subscription) { 34 | this._subscription.dispose(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/widgets/add-ingredients/add-ingredients.ts: -------------------------------------------------------------------------------- 1 | import { ManageIngredientModel } from 'domain/entities/ingredient'; 2 | import { bindable, autoinject } from 'aurelia-framework'; 3 | import { LocalStorageService } from 'services/local-storage-service'; 4 | import { IngredientService } from 'services/ingredient-service'; 5 | 6 | @autoinject 7 | export class AddIngredients { 8 | @bindable ingredientIds: string[]; 9 | public ingredients: ManageIngredientModel[] = []; 10 | 11 | constructor( 12 | private _localStorageService: LocalStorageService, 13 | private _ingredientService: IngredientService 14 | ) {} 15 | bind() { 16 | this.ingredients = this._ingredientService.getRandomIngredients(3, this.ingredientIds); 17 | } 18 | 19 | async toggleIngredient(ingredient: ManageIngredientModel) { 20 | ingredient.isActive = !ingredient.isActive; 21 | if (ingredient.isActive) { 22 | // for aurelia Changed method to trigger on array push. 23 | const temp = [...this.ingredientIds]; 24 | temp.push(ingredient.id); 25 | this.ingredientIds = temp; 26 | } else { 27 | this.ingredientIds = this.ingredientIds.filter(id => id !== ingredient.id); 28 | } 29 | await this._localStorageService.updateSavedIngredients(this.ingredientIds); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cypress/e2e/validation-helpers/validate-cocktail.ts: -------------------------------------------------------------------------------- 1 | export type ValidateCocktailRequest = { 2 | name: string; 3 | category: string; 4 | tags: string[]; 5 | abv: string; 6 | ingredients: { name: string; amount: string }[]; 7 | isEditedText: boolean; 8 | }; 9 | 10 | export function validateCocktail(cocktail: ValidateCocktailRequest) { 11 | const { name, category, isEditedText, tags, ingredients, abv } = cocktail; 12 | 13 | cy.dataCy('cocktail-name').should('have.text', name); 14 | cy.dataCy('cocktail-category').should('have.text', category); 15 | 16 | if (isEditedText) { 17 | cy.dataCy('cocktail-edited-text').should('exist'); 18 | } else { 19 | cy.dataCy('cocktail-edited-text').should('not.exist'); 20 | } 21 | 22 | cy.get('[data-cy=cocktail-tags] > p').should('have.length', tags.length); 23 | tags.forEach(tag => { 24 | cy.get('[data-cy=cocktail-tags] > p').should('include.text', tag); 25 | }); 26 | 27 | for (let i = 0; i < ingredients.length; i++) { 28 | const element = ingredients[i]; 29 | cy.get(`[data-cy=ingredient-group-${i}] [data-cy=ingredient-name]`).should('include.text', element.name); 30 | cy.get(`[data-cy=ingredient-group-${i}] [data-cy=ingredient-amount]`).should('include.text', element.amount); 31 | } 32 | 33 | cy.dataCy('cocktail-abv').should('include.text', abv); 34 | } 35 | -------------------------------------------------------------------------------- /src/modules/cocktails/cocktails.html: -------------------------------------------------------------------------------- 1 | 31 | -------------------------------------------------------------------------------- /src/components/icons/icon-settings.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /src/components/dialogs/edit-tags-drawer.ts: -------------------------------------------------------------------------------- 1 | import { autoinject } from 'aurelia-framework'; 2 | import { DialogController } from 'aurelia-dialog'; 3 | import { CocktailService } from 'services/cocktail-service'; 4 | import { TagModel } from 'domain/entities/cocktail-tag'; 5 | 6 | @autoinject 7 | export class EditTagsDrawer { 8 | public tags: ActiveTagModel[] = []; 9 | 10 | constructor( 11 | private _dialogController: DialogController, 12 | private cocktailService: CocktailService 13 | ) {} 14 | 15 | activate(activeTags: string[]) { 16 | const tags = this.cocktailService.getTags(); 17 | 18 | tags.forEach(element => { 19 | const model: ActiveTagModel = { 20 | id: element.id, 21 | isActive: activeTags.includes(element.id), 22 | translation: element.translation, 23 | name: element.name 24 | }; 25 | 26 | this.tags.push(model); 27 | }); 28 | } 29 | 30 | cancel() { 31 | this._dialogController.cancel(); 32 | } 33 | 34 | ok() { 35 | this._dialogController.ok(this.tags.filter(x => x.isActive).map(x => x.id)); 36 | } 37 | 38 | toggleTag(tag: ActiveTagModel) { 39 | tag.isActive = !tag.isActive; 40 | } 41 | } 42 | 43 | export type ActiveTagModel = { 44 | id: string; 45 | isActive: boolean; 46 | translation: string; 47 | name: string; 48 | } & TagModel; 49 | -------------------------------------------------------------------------------- /src/domain/entities/cocktail.ts: -------------------------------------------------------------------------------- 1 | import { DrinkCategory } from 'domain/enums/drink-category'; 2 | import { Unit } from 'domain/enums/unit'; 3 | import { Ingredient } from './ingredient'; 4 | import { CocktailAlcoholInformation } from 'domain/cocktail-alcohol-information'; 5 | export class StaticCocktail { 6 | id: string; 7 | translation: string; 8 | imageSrc: string; 9 | isImagePortrait: boolean; 10 | isImageAiGenerated?: boolean; 11 | category: DrinkCategory; 12 | ingredientGroups: IngredientGroup[]; 13 | tags: string[]; 14 | } 15 | 16 | export class Cocktail extends StaticCocktail { 17 | constructor() { 18 | super(); 19 | this.ingredientGroups = []; 20 | this.tags = []; 21 | this.notes = ''; 22 | this.isEdited = false; 23 | } 24 | name: string; 25 | notes: string; 26 | isEdited: boolean; 27 | instructions?: string; 28 | rating?: number; 29 | isFavorite?: boolean; 30 | alcoholInformation?: CocktailAlcoholInformation; 31 | } 32 | 33 | export class IngredientGroup { 34 | ingredientId: string; 35 | amount: string; 36 | unit: Unit | string; 37 | } 38 | 39 | export class ExtendedIngredientGroup extends IngredientGroup { 40 | ingredient: Ingredient; 41 | isInStorage: boolean; 42 | substituteNames: string; 43 | isChecked: boolean; 44 | } 45 | 46 | export class CocktailWithMissingIngredient extends Cocktail { 47 | missingIngredient: Ingredient; 48 | } 49 | -------------------------------------------------------------------------------- /src/modules/user/ingredient-lists/ingredient-lists.ts: -------------------------------------------------------------------------------- 1 | import { DialogService } from 'aurelia-dialog'; 2 | import { autoinject } from 'aurelia-framework'; 3 | import { IngredientListDrawer } from './ingredient-list-drawer'; 4 | import { LocalStorageService } from 'services/local-storage-service'; 5 | import { IngredientList } from 'domain/entities/ingredient-list'; 6 | 7 | @autoinject 8 | export class IngredientLists { 9 | public ingredientLists: IngredientList[] = []; 10 | public activeIngredientListId: number; 11 | 12 | constructor( 13 | private _dialogService: DialogService, 14 | private localStorageService: LocalStorageService 15 | ) {} 16 | 17 | bind() { 18 | this.ingredientLists = this.localStorageService.getIngredientLists(); 19 | this.activeIngredientListId = this.localStorageService.getActiveIngredientListId(); 20 | } 21 | 22 | openDialog(ingredientList: IngredientList) { 23 | this._dialogService 24 | .open({ viewModel: IngredientListDrawer, model: ingredientList, lock: true }) 25 | .whenClosed(async () => { 26 | this.activeIngredientListId = 27 | this.localStorageService.getIngredientLists().find(x => x.id === this.activeIngredientListId)?.id ?? 28 | 0; 29 | await this.localStorageService.setActiveIngredientListId(this.activeIngredientListId); 30 | this.bind(); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ios/App/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Capacitor (5.7.4): 3 | - CapacitorCordova 4 | - CapacitorApp (5.0.7): 5 | - Capacitor 6 | - CapacitorClipboard (5.0.7): 7 | - Capacitor 8 | - CapacitorCordova (5.7.4) 9 | - CapacitorPreferences (5.0.7): 10 | - Capacitor 11 | 12 | DEPENDENCIES: 13 | - "Capacitor (from `../../node_modules/@capacitor/ios`)" 14 | - "CapacitorApp (from `../../node_modules/@capacitor/app`)" 15 | - "CapacitorClipboard (from `../../node_modules/@capacitor/clipboard`)" 16 | - "CapacitorCordova (from `../../node_modules/@capacitor/ios`)" 17 | - "CapacitorPreferences (from `../../node_modules/@capacitor/preferences`)" 18 | 19 | EXTERNAL SOURCES: 20 | Capacitor: 21 | :path: "../../node_modules/@capacitor/ios" 22 | CapacitorApp: 23 | :path: "../../node_modules/@capacitor/app" 24 | CapacitorClipboard: 25 | :path: "../../node_modules/@capacitor/clipboard" 26 | CapacitorCordova: 27 | :path: "../../node_modules/@capacitor/ios" 28 | CapacitorPreferences: 29 | :path: "../../node_modules/@capacitor/preferences" 30 | 31 | SPEC CHECKSUMS: 32 | Capacitor: 4fe9adf012caceb4c71ffea2f1f4d005cdcbeea7 33 | CapacitorApp: 17fecd0e6cb23feafac7eb0939417389038b0979 34 | CapacitorClipboard: 45e5e25f2271f98712985d422776cdc5a779cca1 35 | CapacitorCordova: a6e87fccc0307dee7aec1560ec9398485f2b0ce7 36 | CapacitorPreferences: 77ac427e98db83bace772455f8ba447430382c4c 37 | 38 | PODFILE CHECKSUM: 557ec4419097d817d26d926546df7c47839665d0 39 | 40 | COCOAPODS: 1.14.3 41 | -------------------------------------------------------------------------------- /tests/services/local-storage-service.test.ts: -------------------------------------------------------------------------------- 1 | import { LocalStorageService, StorageKey } from 'services/local-storage-service'; 2 | import { expect } from '@jest/globals'; 3 | import { IngredientList } from 'domain/entities/ingredient-list'; 4 | 5 | describe('LocalStorageService', () => { 6 | let sut: LocalStorageService; 7 | 8 | beforeEach(async () => { 9 | sut = new LocalStorageService(); 10 | await sut.initialize(); 11 | }); 12 | 13 | afterEach(() => { 14 | window.localStorage.clear(); 15 | }); 16 | 17 | test('No state. Get should not return undefined', () => { 18 | expect(sut.getCocktailInformation()).toBeTruthy(); 19 | expect(sut.getCocktails()).toBeTruthy(); 20 | expect(sut.getIngredientIds()).toBeTruthy(); 21 | expect(sut.getIngredients()).toBeTruthy(); 22 | expect(sut.getMessuarementSystem()).toBeTruthy(); 23 | expect(sut.getSettings()).toBeTruthy(); 24 | expect(sut.getWidgetOrder()).toBeTruthy(); 25 | }); 26 | 27 | test('KeyExists - Not found, should return false', async () => { 28 | const result = await sut.keyExists('test'); 29 | expect(result).toBe(false); 30 | }); 31 | 32 | test('KeyExists - Found, should return true', async () => { 33 | window.localStorage.setItem('CapacitorStorage.messuarement-system', 'Metric'); 34 | 35 | const result = await sut.keyExists(StorageKey.MessuarementSystem); 36 | expect(result).toBe(true); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /tests/functions/utils.test.ts: -------------------------------------------------------------------------------- 1 | import { convertToFraction } from 'functions/utils'; 2 | import { expect } from '@jest/globals'; 3 | 4 | describe('convertToFraction', () => { 5 | it('should return a whole number as is', () => { 6 | expect(convertToFraction(0)).toEqual('0'); 7 | expect(convertToFraction(1)).toEqual('1'); 8 | expect(convertToFraction(5)).toEqual('5'); 9 | }); 10 | 11 | it('should convert a decimal value to a fraction', () => { 12 | expect(convertToFraction(0.25)).toEqual('1/4'); 13 | expect(convertToFraction(0.33)).toEqual('1/3'); 14 | expect(convertToFraction(0.5)).toEqual('1/2'); 15 | expect(convertToFraction(0.67)).toEqual('2/3'); 16 | expect(convertToFraction(0.75)).toEqual('3/4'); 17 | 18 | expect(convertToFraction(1.25)).toEqual('1 1/4'); 19 | expect(convertToFraction(2.33)).toEqual('2 1/3'); 20 | expect(convertToFraction(3.5)).toEqual('3 1/2'); 21 | expect(convertToFraction(4.67)).toEqual('4 2/3'); 22 | expect(convertToFraction(5.75)).toEqual('5 3/4'); 23 | }); 24 | 25 | it('should round up to the nearest whole number when appropriate', () => { 26 | expect(convertToFraction(0.99)).toEqual('1'); 27 | expect(convertToFraction(1.99)).toEqual('2'); 28 | }); 29 | 30 | it('should round down to zero when appropriate', () => { 31 | expect(convertToFraction(0.05)).toEqual('0'); 32 | expect(convertToFraction(1.05)).toEqual('1'); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "editor.rulers": [120], 4 | "editor.tabSize": 4, 5 | "editor.insertSpaces": true, 6 | "editor.detectIndentation": false, 7 | "editor.defaultFormatter": "esbenp.prettier-vscode", 8 | "editor.formatOnSave": true, 9 | "tailwindCSS.experimental.classRegex": ["/\\*\\s*tw\\s*\\*/\\s*'([^']*)'", "/\\*\\s*tw\\s*\\*/\\s*\"([^\"]*)\""], 10 | "folderTemplates.structures": [ 11 | { 12 | "name": "Aurelia Component ( HTML + TS )", 13 | "customVariables": ["fileName"], 14 | "omitParentDirectory": true, 15 | "omitFTName": true, 16 | "openFilesWhenDone": ["*.html", "*.ts"], 17 | "structure": [ 18 | { 19 | "fileName": "/.ts", 20 | "template": "ts-class-with-autoinject" 21 | }, 22 | { 23 | "fileName": "/.html", 24 | "template": "empty-html-file" 25 | } 26 | ] 27 | } 28 | ], 29 | "folderTemplates.fileTemplates": { 30 | "empty-html-file": [""], 31 | "ts-class-with-autoinject": [ 32 | "import { autoinject } from 'aurelia-framework' \n\n @autoinject \n\n export class { \n\n constructor() {} \n\n } \n\n" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["@typescript-eslint"], 5 | "extends": [ 6 | "eslint:recommended", 7 | "plugin:@typescript-eslint/recommended", 8 | "plugin:@typescript-eslint/stylistic", 9 | "prettier" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/consistent-type-definitions": ["warn", "type"], 13 | "@typescript-eslint/no-unused-vars": "warn", 14 | "@typescript-eslint/no-empty-function": "warn", 15 | "@typescript-eslint/no-inferrable-types": "warn", 16 | "@typescript-eslint/no-extraneous-class": "warn", 17 | "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error", 18 | "eqeqeq": ["error", "always", { "null": "ignore" }] 19 | }, 20 | 21 | "overrides": [ 22 | { 23 | "files": ["cypress/**/*.ts"], 24 | "parserOptions": { 25 | "project": ["cypress/tsconfig.json"] 26 | }, 27 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:cypress/recommended"] 28 | } 29 | ], 30 | "parserOptions": { 31 | "ecmaVersion": 2023, 32 | "sourceType": "module", 33 | "project": "./tsconfig.json", 34 | "tsconfigRootDir": "." 35 | }, 36 | "env": { 37 | "es6": true, 38 | "browser": true, 39 | "node": true 40 | }, 41 | "ignorePatterns": ["webpack.config.js", "postcss.config.js", "tailwind.config.js"] 42 | } 43 | -------------------------------------------------------------------------------- /src/modules/user/ingredient-substitutions/ingredient-substitutions.html: -------------------------------------------------------------------------------- 1 | 35 | -------------------------------------------------------------------------------- /.github/workflows/fastlane-internal.yml: -------------------------------------------------------------------------------- 1 | name: Fastlane 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: Validate Fastlane 15 | uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2 16 | with: 17 | usePlayStoreLocales: true 18 | 19 | - name: Setup Java 20 | uses: actions/setup-java@v4 21 | with: 22 | distribution: 'zulu' 23 | java-version: '21' 24 | 25 | - name: Setup Node.js 26 | uses: actions/setup-node@v4 27 | with: 28 | node-version: 22.x 29 | 30 | - name: Install app dependencies 31 | run: npm ci 32 | 33 | - name: Create .env file 34 | uses: SpicyPizza/create-envfile@v2.0.3 35 | with: 36 | envkey_SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }} 37 | envkey_RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }} 38 | envkey_RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} 39 | envkey_SERVICE_ACCOUNT_KEY: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_KEY }} 40 | 41 | - name: Build Web 42 | run: npm run build:play-store 43 | 44 | - name: Capacitor update 45 | run: npx cap update 46 | 47 | - name: Runs on Release 48 | run: fastlane production 49 | -------------------------------------------------------------------------------- /src/modules/ingredients/all-ingredients/all-ingredients.ts: -------------------------------------------------------------------------------- 1 | import { ManageIngredientModel } from 'domain/entities/ingredient'; 2 | import { LocalStorageService } from 'services/local-storage-service'; 3 | import { inject } from 'aurelia-framework'; 4 | import { AlphabeticalGroup, ToAlphabeticalGroup } from 'domain/models/alphabetical-group'; 5 | import { IngredientService } from 'services/ingredient-service'; 6 | 7 | @inject(LocalStorageService, IngredientService) 8 | export class AllIngredients { 9 | public ingredients: AlphabeticalGroup[] = []; 10 | public activeIngredientIds: string[] = []; 11 | 12 | constructor( 13 | private _localStorageService: LocalStorageService, 14 | private _ingredientService: IngredientService 15 | ) {} 16 | 17 | bind() { 18 | this.activeIngredientIds = this._localStorageService.getIngredientIds(); 19 | 20 | const ingredientModels = this._ingredientService.getManageIngredientModels(this.activeIngredientIds); 21 | 22 | this.ingredients = ToAlphabeticalGroup(ingredientModels); 23 | } 24 | 25 | public async toggleIngredient(ingredientModel: ManageIngredientModel) { 26 | ingredientModel.isActive = !ingredientModel.isActive; 27 | 28 | if (ingredientModel.isActive) { 29 | this.activeIngredientIds.push(ingredientModel.id); 30 | } else { 31 | this.activeIngredientIds = this.activeIngredientIds.filter(x => x !== ingredientModel.id); 32 | } 33 | await this._localStorageService.updateSavedIngredients(this.activeIngredientIds); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/modules/ingredients/search-ingredients/search-ingredients.html: -------------------------------------------------------------------------------- 1 | 35 | -------------------------------------------------------------------------------- /src/modules/home/home.ts: -------------------------------------------------------------------------------- 1 | import { inject } from 'aurelia-framework'; 2 | import { LocalStorageService } from 'services/local-storage-service'; 3 | import { WidgetOrder } from 'domain/entities/widget-order'; 4 | import { Widget } from 'domain/enums/widget'; 5 | import Snowflakes from 'magic-snowflakes'; 6 | 7 | @inject(LocalStorageService) 8 | export class Home { 9 | public containerElement: HTMLElement; 10 | public snowflakes: Snowflakes; 11 | public ingredientIds: string[] = []; 12 | public widgetOrder: WidgetOrder[] = []; 13 | 14 | constructor(private _localStorageService: LocalStorageService) {} 15 | 16 | activate() { 17 | this.ingredientIds = this._localStorageService.getIngredientIds(); 18 | this.widgetOrder = this._localStorageService.getWidgetOrder(); 19 | } 20 | 21 | attached() { 22 | this.setupSnowflakes(); 23 | } 24 | 25 | detached() { 26 | this.snowflakes?.destroy(); 27 | } 28 | 29 | getOrderById(id: Widget) { 30 | const widget = this.widgetOrder.find(x => x.widgetId === id); 31 | if (widget !== undefined) { 32 | return 'order: ' + widget.order; 33 | } 34 | return 'order: ' + 0; 35 | } 36 | 37 | private setupSnowflakes() { 38 | if (new Date().getMonth() === 11) { 39 | this.snowflakes = new Snowflakes({ 40 | count: 10, 41 | speed: 0.3, 42 | minOpacity: 0.4, 43 | maxOpacity: 0.7, 44 | minSize: 10, 45 | maxSize: 18, 46 | container: this.containerElement 47 | }); 48 | } 49 | } 50 | } 51 | --------------------------------------------------------------------------------