Compare commits

...

51 commits

Author SHA1 Message Date
49406f610c
Add more quotes, see if it works
Some checks failed
ci/woodpecker/push/android-build Pipeline failed
ci/woodpecker/push/web-build Pipeline failed
ci/woodpecker/push/deb-build unknown status
ci/woodpecker/tag/android-build Pipeline was successful
ci/woodpecker/tag/deb-build Pipeline was successful
ci/woodpecker/tag/web-build Pipeline was successful
ci/woodpecker/tag/release-packaging Pipeline failed
2025-03-06 14:55:19 -05:00
e0f6406fab
different commit for new tag
Some checks failed
ci/woodpecker/push/android-build Pipeline was successful
ci/woodpecker/push/deb-build Pipeline was successful
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/tag/android-build Pipeline was successful
ci/woodpecker/tag/deb-build Pipeline was successful
ci/woodpecker/tag/web-build Pipeline was successful
ci/woodpecker/tag/release-packaging Pipeline failed
2025-03-06 14:25:20 -05:00
e2a1b8fb50
Ensure dependencies build on tag gen
All checks were successful
ci/woodpecker/push/android-build Pipeline was successful
ci/woodpecker/push/deb-build Pipeline was successful
ci/woodpecker/push/web-build Pipeline was successful
2025-03-06 14:18:25 -05:00
4ce2b6ea76
new valid CI tag
Some checks failed
ci/woodpecker/push/android-build Pipeline failed
ci/woodpecker/push/deb-build unknown status
ci/woodpecker/push/web-build Pipeline failed
2025-03-06 14:14:30 -05:00
88199d3fcc
Merge remote-tracking branch 'origin/dockerBuild'
Some checks failed
ci/woodpecker/push/android-build Pipeline failed
ci/woodpecker/push/deb-build unknown status
ci/woodpecker/push/web-build Pipeline failed
2025-03-06 14:12:23 -05:00
f22cf73708
Tweak CI to only use Tags for release 2025-03-06 14:02:51 -05:00
69320517b6
Package gradle fails in docker container? 2025-03-06 13:33:55 -05:00
81306b4140
Clean before build for consistency 2025-03-06 13:13:16 -05:00
38afc6f5c9
Add quotes
Tinkering with CI behaviour
2025-03-06 12:56:15 -05:00
7eaa2de71e
Experiment with secret values 2025-03-06 12:34:38 -05:00
261509417d Menu Dividers 2025-03-05 23:41:41 -05:00
866111e4ba Ascending and Descending Sort Order 2025-03-05 23:40:04 -05:00
4471a95ab1 Clarifying language about what the Filter Style and Sort By options do 2025-03-05 23:32:40 -05:00
19c2cc56ed Added Sort By Types 2025-03-05 23:29:19 -05:00
3ae7688aeb Added France 2025-03-05 23:16:28 -05:00
fbc690cb56 Chicken Cordon Bleu 2025-03-05 23:15:22 -05:00
2e1c8b2b93 moved to bigger .dp size due to longer tags 2025-03-05 23:00:03 -05:00
17d9f6d0f7 Added more steps for the Recipe Slider 2025-03-05 22:52:15 -05:00
8e5911fe43 Opor Ayam
Fix for Counting issue
2025-03-05 22:34:43 -05:00
1c950ef339 fix for spacing on large screens 2025-03-05 21:57:10 -05:00
27611b180a
Move depends block to end 2025-03-05 21:06:53 -05:00
f6834e5e4f
Test release build compatibility 2025-03-05 21:04:50 -05:00
652fcfe9a8
Merge remote-tracking branch 'origin/master' into dockerBuild 2025-03-05 18:30:00 -05:00
b29bb87190
Tweak release build
`./gradlew packageReleaseDeb` currently fails on Debian 12, due to
"proguard" issues... It's not totally clear what the failure is...
Possible place to start: https://www.guardsquare.com/manual/setup/gradleplugin
2025-03-04 21:07:11 -05:00
6a9329cdcf
Condense release packaging 2025-03-04 20:12:30 -05:00
04c02e3dae
Fix syntax 2025-03-04 17:10:07 -05:00
334d4e15e8
Add master to build files 2025-03-04 17:08:08 -05:00
2f2ba59ca3
add accept licenses again
why was this not working before?
2025-03-04 15:33:29 -05:00
49628a73f4
minimal re-add 2025-03-04 15:22:12 -05:00
9d10a82966
fix dependency issue
also framework for android deploy/build for release
2025-03-04 15:09:31 -05:00
0207185ce3
Add comment for further research later 2025-03-04 12:32:36 -05:00
7ddb939c2f
Add Android build to CI 2025-03-04 12:27:15 -05:00
60deff6c2a
Add jdk11 and jdk17 to deb build container 2025-03-04 12:13:25 -05:00
5758466477
Build deb with correct jdk 2025-03-04 12:08:06 -05:00
74fbe13c8e
Fix invalid env setup 2025-03-04 12:05:04 -05:00
0fac8f4611
Add androidhome environment variable 2025-03-04 12:03:16 -05:00
9d6ba8ed10
Actually install sdkmanager 2025-03-04 11:56:16 -05:00
080d85c266
Include Android SDK 2025-03-04 11:54:39 -05:00
418968c428
Fix spelling error 2025-03-04 11:50:03 -05:00
2a9f385a82
Remove excess workflow 2025-03-04 11:48:54 -05:00
5bb06e8d49
Test deb build 2025-03-04 11:41:13 -05:00
0d8b2518f1
Merge remote-tracking branch 'origin/master' into dockerBuild 2025-03-04 11:37:33 -05:00
a3a01b5581
Test web build 2025-03-02 20:11:39 -05:00
fb2756b668
Start building CI workflow 2025-03-02 19:41:39 -05:00
817472400b
Merge remote-tracking branch 'origin/master' into dockerBuild 2025-03-02 19:03:06 -05:00
cf73f9a833
Simplify build, resolve file access issue 2025-02-28 11:38:38 -05:00
1d674be4f4
Merge remote-tracking branch 'origin/master' into dockerBuild 2025-02-28 10:18:05 -05:00
ba6d0d956b
Remove Windows dockerfile
No windows docker container on linux
2025-02-23 20:46:41 -05:00
f2d72d9aa9
Continue building dockerfiles 2025-02-23 20:41:45 -05:00
0a72b9fc82
Create dedicated web build Dockerfile
Deb container is next, followed by Windows container and Android
2025-02-23 20:23:59 -05:00
5874e90288
Initial dockerfile build
Very inefficient; cache container to be built soon
2025-02-23 18:55:41 -05:00
22 changed files with 464 additions and 111 deletions

View file

@ -0,0 +1,16 @@
when:
- event: push
branch: [ dockerBuild, master ]
- event: tag
steps:
- name: build
image: gradle:8.10.2-jdk17
environment:
ANDROID_HOME: /sdk
commands:
- apt update && apt install -y sdkmanager openjdk-11-jdk
- sdkmanager "tools" && yes | sdkmanager --licenses
#More info
# https://developer.android.com/build/building-cmdline
- gradle assembleDebug

17
.woodpecker/deb-build.yml Normal file
View file

@ -0,0 +1,17 @@
when:
- event: push
branch: [ dockerBuild, master ]
- event: tag
steps:
- name: build
image: gradle:8.10.2-jdk17
environment:
ANDROID_HOME: /sdk
commands:
- apt update && apt install -y sdkmanager openjdk-11-jdk
- sdkmanager "tools" && yes | sdkmanager --licenses
- gradle buildDeb
depends_on:
- android-build

View file

@ -0,0 +1,59 @@
when:
- event: tag
steps:
- name: build-releases
image: gradle:8.10.2-jdk17
environment:
ANDROID_HOME: /sdk
KEYSTORE_FILE:
from_secret: keystore_file
TEST_ENV:
from_secret: test_secret
KEYSTORE_PASSWORD:
from_secret: keystore_password
KEY_ALIAS:
from_secret: key_alias
KEY_PASSWORD:
from_secret: key_password
commands:
- apt update && apt install -y sdkmanager openjdk-11-jdk
- sdkmanager "tools" && yes | sdkmanager --licenses
- gradle clean
- echo "$TEST_ENV"
- echo "$KEYSTORE_FILE" | base64 -d > keystore.jks
# Package Release Deb currently fails on local
- gradle buildDeb
- gradle assembleRelease -Pandroid.injected.signing.store.file=$(pwd)/keystore.jks -Pandroid.injected.signing.store.password=$KEYSTORE_PASSWORD -Pandroid.injected.signing.key.alias="$KEY_ALIAS" -Pandroid.injected.signing.key.password=$KEY_PASSWORD
- name: publish-packages
image: woodpeckerci/plugin-release
settings:
files:
- androidApp/build/outputs/apk/release/androidApp-release.apk
- desktopApp/build/compose/binaries/main/deb/bakers-menagerie_*.deb
checksum:
- androidApp/build/outputs/apk/release/androidApp-release.apk
- desktopApp/build/compose/binaries/main/deb/bakers-menagerie_*.deb
target: master
draft: true
overwrite: true
generate-release-notes: true
api_key:
from_secret: ci_access_token
- name: publish-container
image: woodpeckerci/plugin-kaniko
repo: git.blizzard.systems/Menagerie/Menagerie_Cookbook
username:
from_secret: ci_username
password:
from_secret: ci_access_token
registry: git.blizzard.systems
dockerfile: Dockerfile.web-serve
auto-tag: true
cache: true
depends_on:
- android-build
- deb-build
- web-build

10
.woodpecker/web-build.yml Normal file
View file

@ -0,0 +1,10 @@
when:
- event: push
branch: [ dockerBuild, master ]
- event: tag
steps:
- name: build
image: gradle:8.10.2-jdk21
commands:
- gradle wasmJsBrowserDistribution

29
Dockerfile.dpkg-build Normal file
View file

@ -0,0 +1,29 @@
# Original build used JVM 21.0.3
# Gradle version 8.10.2
### For RPM Builds, need to implement Nebula RPM plugin; see https://plugins.gradle.org/plugin/com.netflix.nebula.rpm
FROM gradle:8.10.2-jdk21 AS cache
RUN apt update && apt install -y sdkmanager openjdk-11-jdk
RUN sdkmanager "tools"
RUN yes | sdkmanager --licenses
RUN mkdir -p /src
ENV GRADLE_USER_HOME=/home/gradle/cache_home
COPY gradle /src/gradle
COPY build.gradle.kts gradle.properties settings.gradle.kts /src/.
COPY androidApp/build.gradle.kts /src/androidApp/.
COPY automotiveApp/build.gradle.kts /src/automotiveApp/.
COPY desktopApp/build.gradle.kts /src/desktopApp/.
COPY shared/build.gradle.kts /src/shared/.
COPY tvApp/build.gradle.kts /src/tvApp/.
COPY webApp/build.gradle.kts /src/webApp/.
WORKDIR /src
RUN ls -lahR
RUN gradle -q javaToolchains
RUN gradle buildEnvironment --refresh-dependencies
FROM gradle:8.10.2-jdk21 AS build
WORKDIR /src
COPY --from=cache /home/gradle/cache_home /home/gradle/.
COPY --chown=gradle:gradle . /src/.
RUN gradle clean
RUN gradle packageReleaseDeb

27
Dockerfile.web-serve Normal file
View file

@ -0,0 +1,27 @@
# Original build used JVM 21.0.3
# Gradle version 8.10.2
FROM gradle:8.10.2-jdk21 AS cache
RUN apt update && apt install -y sdkmanager openjdk-11-jdk
RUN sdkmanager "tools"
RUN yes | sdkmanager --licenses
RUN mkdir -p /src
ENV GRADLE_USER_HOME=/home/gradle/cache_home
COPY gradle /src/gradle
COPY build.gradle.kts gradle.properties settings.gradle.kts /src/.
COPY androidApp/build.gradle.kts /src/androidApp/.
COPY automotiveApp/build.gradle.kts /src/automotiveApp/.
COPY desktopApp/build.gradle.kts /src/desktopApp/.
COPY shared/build.gradle.kts /src/shared/.
COPY tvApp/build.gradle.kts /src/tvApp/.
COPY webApp/build.gradle.kts /src/webApp/.
WORKDIR /src
RUN gradle buildEnvironment --refresh-dependencies
FROM gradle:8.10.2-jdk21 AS build
WORKDIR /src
COPY --from=cache /home/gradle/cache_home /home/gradle/.
COPY --chown=gradle:gradle . /src/.
RUN gradle clean && gradle wasmJsBrowserDistribution
FROM nginx:latest
COPY --from=build /src/webApp/build/dist/wasmJs/productionExecutable /usr/share/nginx/html

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 KiB

View file

@ -40,6 +40,7 @@ import view.BookShelf
import view.FilterCard
import view.HomeScreen
import view.InputFieldState
import view.MainDropDown
import view.getFilteredRecipeList
import view.getRecipeList
@ -50,6 +51,12 @@ enum class Theme {
Dark
}
enum class SortBy {
Name,
Time,
Ingredients,
}
enum class RecipeAppScreen {
List, Details,
}
@ -64,6 +71,7 @@ fun App(
val navController = rememberNavController()
var theme by remember { mutableStateOf(Theme.Auto) }
var sortBy by remember { mutableStateOf(SortBy.Name) }
val onThemeToggle = {
theme = when (theme) {
@ -72,6 +80,15 @@ fun App(
Theme.Dark -> Theme.Auto
}
}
val onSortToggle = {
sortBy = when (sortBy) {
SortBy.Name -> SortBy.Time
SortBy.Time -> SortBy.Ingredients
SortBy.Ingredients -> SortBy.Name
}
}
val isDarkTheme: Boolean? = when (theme) {
Theme.Dark -> true
Theme.Light -> false
@ -87,6 +104,7 @@ fun App(
val recipeTags by remember { mutableStateOf(mutableMapOf<String, TagType>()) }
var book by remember { mutableStateOf("") }
var returnAnyMatch by remember { mutableStateOf(false) }
var descending by remember { mutableStateOf(false) }
for (recipe in getRecipeList()) {
for (tag in recipe.tags) {
@ -108,7 +126,14 @@ fun App(
}
}
val filteredItems = getFilteredRecipeList(tags, search, book, returnAnyMatch)
val filteredItems = getFilteredRecipeList(
tags = tags,
search = search,
lockTag = book,
sortBy = sortBy,
returnAny = returnAnyMatch,
reverse = descending,
)
val recipeCount = getRecipeList().size
var currentRecipe = getRecipeList().first()
@ -138,12 +163,16 @@ fun App(
Spacer(modifier = Modifier.weight(1f))
MainDropDown(
isLarge,
returnAnyMatch,
theme,
isLarge = isLarge,
andOr = returnAnyMatch,
theme = theme,
sortBy = sortBy,
descending = descending,
onClose = onClose,
onBack = {navController.navigateUp()},
onTag = {returnAnyMatch = !returnAnyMatch},
onSortBy = { onSortToggle.invoke() },
onDesc = {descending = !descending},
onTheme = { onThemeToggle.invoke() },
onRandom = {
currentRecipe = filteredItems.random()
@ -237,56 +266,4 @@ fun App(
}
}
}
}
@Composable
fun MainDropDown(
isLarge: Boolean,
andOr: Boolean,
theme: Theme,
onTag: () -> Unit,
onTheme: () -> Unit,
onRandom: () -> Unit,
onBack: () -> Unit,
onClose: () -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
Box(
modifier = Modifier
.padding(16.dp)
) {
IconButton(onClick = { expanded = !expanded }) {
Icon(imageVector = Icons.Default.MoreVert, contentDescription = "More Options")
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
DropdownMenuItem(
text = { Text(theme.name) },
onClick = onTheme
)
DropdownMenuItem(
text = {Text(if(andOr) "OR" else "AND")},
onClick = onTag
)
DropdownMenuItem(
text = { Text("Random Filtered Recipe") },
onClick = onRandom
)
if (isLarge) {
DropdownMenuItem(
text = {Text("Go Back")},
onClick = onBack
)
DropdownMenuItem(
text = { Text("Close app") },
onClick = onClose
)
}
}
}
}
}

View file

@ -31,7 +31,11 @@ import androidx.compose.ui.unit.sp
import model.Recipe
@Composable
fun InstructionItem(recipe: Recipe, index: Int, slider: Float) {
fun InstructionItem(
recipe: Recipe,
index: Int,
count: Int,
slider: Float) {
Box(modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp)) {
Box(
modifier = Modifier
@ -70,7 +74,7 @@ fun InstructionItem(recipe: Recipe, index: Int, slider: Float) {
contentAlignment = Alignment.Center
) {
Text(
text = "${index + 1}",
text = "$count",
style = MaterialTheme.typography.displayMedium.copy(
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,

View file

@ -49,6 +49,7 @@ import org.jetbrains.compose.resources.painterResource
import sensor.Listener
import sensor.SensorData
import sensor.SensorManager
import view.RecipeScaleSlider
@OptIn(ExperimentalSharedTransitionApi::class)
@ -110,9 +111,9 @@ fun RecipeDetailsLarge(
modifier = Modifier.padding(top = 64.dp)
) {
recipeHeader(recipe, true, slider)
SliderMinimalExample(
RecipeScaleSlider(
sliderPosition = slider,
steps = 2,
steps = if(reduce) 2 else 5,
rangeEnd = if(reduce) 1f else 4f,
rangeStart = if(reduce) .25f else 1f,
reduce = reduce,
@ -199,30 +200,3 @@ fun BackButton(goBack: () -> Unit) {
}
@Composable
fun SliderMinimalExample(
sliderPosition: Float,
steps: Int,
rangeStart: Float,
rangeEnd: Float,
reduce: Boolean,
onClick: () -> Unit,
onChange: (Float) -> Unit) {
Column {
Slider(
value = sliderPosition,
steps = steps,
valueRange = rangeStart..rangeEnd,
onValueChange = { onChange(it) },
modifier = Modifier.padding(start = 16.dp, end = 16.dp)
)
Row {
Text(text = sliderPosition.toString().plus("x Servings"))
Spacer(modifier = Modifier.weight(1f))
Button(onClick = onClick) {
Text(text = if (reduce) "Reducing" else "Increasing")
}
}
}
}

View file

@ -1,42 +1,33 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
@ -45,17 +36,16 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import details.StepsAndDetails
import details.ingredients
import details.ingredientsHeader
import details.recipeHeader
import details.steps
import details.stepsHeader
import model.Recipe
import org.jetbrains.compose.resources.painterResource
import sensor.Listener
import sensor.SensorData
import sensor.SensorManager
import view.RecipeScaleSlider
import kotlin.math.PI
@ -93,7 +83,6 @@ fun RecipeDetailsSmall(
consumed: Offset, available: Offset, source: NestedScrollSource
): Offset {
val delta = available.y
imageRotation.value += ((delta * PI / 180) * 10).toInt()
return super.onPostScroll(consumed, available, source)
}
@ -145,9 +134,9 @@ fun RecipeDetailsSmall(
}
item {
SliderMinimalExample(
RecipeScaleSlider(
sliderPosition = slider,
steps = 2,
steps = if(reduce) 2 else 5,
reduce = reduce,
onClick = {
reduce = !reduce

View file

@ -161,6 +161,7 @@ internal fun LazyListScope.steps(
slider: Float
)
{
var count = 1
itemsIndexed(recipe.instructions) { index, value ->
AnimateInEffect(
recipe = recipe,
@ -179,7 +180,9 @@ internal fun LazyListScope.steps(
)
}
}else {
InstructionItem(recipe, index, slider)}
InstructionItem(recipe, index, count, slider)
count++
}
})
}
}

View file

@ -117,7 +117,7 @@ val koreanList = listOf(
"HEADER-Fire Sauce",
"3 Tbsp Gochugaru",
"2 Alapenos",
"2 Jalapenos",
".5 Cup Korean Pear",
".25 White Onion",
"3 Tbsp Garlic, minced",

View file

@ -4,6 +4,7 @@ import model.Recipe
import model.TagType
import recipeappkmp.shared.generated.resources.Res
import recipeappkmp.shared.generated.resources._10_strawberries
import recipeappkmp.shared.generated.resources.opor_ayam
import kotlin.time.Duration
val seaList = listOf(
@ -34,5 +35,66 @@ val seaList = listOf(
),
servings = "About 1 Cup",
image = Res.drawable._10_strawberries
),
Recipe(
title = "Opor Ayam",
description = "Chicken with carmelised Onion in a rich coconut gravy.",
prepTime = Duration.parse("8h"),
cookTime = Duration.parse("40m"),
servings = "Serves 4",
ingredients = listOf(
"HEADER-Marinade",
"1.5kg Protein of Choice",
"2 Cloves Garlic",
"8 Shallots",
"1 cm piece Turmeric Root",
".5 Tsp Black Pepper",
"2 Tsp Coriander",
"4 Candlenuts",
".5 Tsp Fennel",
".5 Tsp Cumin",
"1.5 cm piece Ginger Root",
"3 cm piece Galangal",
"HEADER-Gravy",
"1 Stalk Lemon Grass",
"1 Cinnamon Stick",
"1 Star Anise",
"2 Daun Salam [Bay Leaves]",
"100 ml Thick Coconut Milk",
"300 ml Thin Coconut Milk",
"1 Tbsp Tamarind Juice",
"3 Lime Leaves",
"HEADER-Finishing",
"3 Shallots",
"Salt",
"1 Tsp Brown Sugar",
),
instructions = listOf(
"HEADER-Marinade",
"Grind all of the Marinade ingredients with [1 Tbsp] of oil into a paste.",
"Marinate Protein for several hours, up to overnight.",
"HEADER-Curry",
"Fry Shallots [3] in a wok until brown and crispy. Drain from Oil.",
"Add Protein to Wok and Fry until Firm.",
"Add the Lemon Grass [1 Stalk], Cinnamon Stick [1 Stick], Star Anise [1], Daun Salam [2], and Thin Coconut Milk [100 ml] and Simmer for 15-20 Minutes",
"Add Tamarind Juice [1 Tbsp] and Thick Coconut Milk [300 ml]. Cook another 10-15 minutes. Halfway through, add Salt, Brown Sugar [1 Tsp], and Lime Leaves [3]",
"Serve Garnished with Crispy Shallots",
),
tags = mapOf(
"Indonesian" to TagType.CUISINE,
"SEA" to TagType.CUISINE,
"Savory" to TagType.FLAVOUR,
"Creamy" to TagType.FLAVOUR,
"Curry" to TagType.TECHNIQUE,
"Vegan" to TagType.CUISINE,
"Entree" to TagType.COURSE,
),
image = Res.drawable.opor_ayam,
)
)

View file

@ -0,0 +1,42 @@
package model.Europe
import model.Recipe
import model.TagType
import recipeappkmp.shared.generated.resources.Res
import recipeappkmp.shared.generated.resources.cordon_bleu
import kotlin.time.Duration
val frenchList = listOf(
Recipe(
title = "Chicken Cordon Bleu",
description = "Chicken Wrapped with Ham and Cheese, Breaded, and Baked",
prepTime = Duration.parse("20m"),
cookTime = Duration.parse("40m"),
servings = "4 Large Servings",
ingredients = listOf(
"4 Chicken Breasts",
".25 Tsp Salt",
".125 Tsp Pepper",
"6 Slices Swiss Cheese",
"4 Slices Cooked Ham",
".5 Cup Bread Crumbs",
),
instructions = listOf(
"Preheat oven to 350F.",
"Pound Chicken to 1/4 inch. Season with Salt and Pepper.",
"Place 1 Piece of Swiss and 1 Slice of Ham on each Breast.",
"Wrap, securing with Toothpicks.",
"Coat with Breadcrumbs, then place each Wrap onto a baking dish.",
"Bake for 30-35 minutes, then top each Wrap with 1/2 a slice of Swiss Cheese, then return to the oven for another 5 minutes.",
"Remove Toothpicks and Serve.",
),
tags = mapOf(
"French" to TagType.CUISINE,
"Carnivorous" to TagType.CUISINE,
"Entree" to TagType.COURSE,
"Baked" to TagType.TECHNIQUE,
),
image = Res.drawable.cordon_bleu,
)
)

View file

@ -8,6 +8,7 @@ import model.Asia.indianList
import model.Asia.japaneseList
import model.Asia.koreanList
import model.Asia.seaList
import model.Europe.frenchList
import model.Europe.greekList
import model.Europe.irishList
import model.Europe.italianList
@ -27,6 +28,7 @@ object Globe {
private object EuropeRecipes {
private val frenchRecipes = frenchList
private val irishRecipes = irishList
private val italianRecipes = italianList
private val greekRecipes = greekList
@ -34,7 +36,8 @@ private object EuropeRecipes {
fun getAllRecipes() : List<Recipe> {
return italianRecipes +
greekRecipes +
irishRecipes
irishRecipes +
frenchRecipes
}
}

View file

@ -88,7 +88,7 @@ fun BookShelf(
LazyVerticalGrid(
columns = GridCells.Fixed(if (isLarge) 6 else 2),
state = listState,
modifier = Modifier.width(if (isLarge) 600.dp else 350.dp)
modifier = Modifier.width(if (isLarge) 800.dp else 350.dp)
) {
items(list.size) { item ->
val tag = list[item]

View file

@ -37,9 +37,7 @@ fun FilterCard(
Dialog(
onDismissRequest = {
onDismissRequest(activeTags)
},
) {
Card {
@ -55,7 +53,7 @@ fun FilterCard(
}
}
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 106.dp)
columns = GridCells.Adaptive(minSize = 110.dp)
) {
items(tags) { tag ->
val active = activeTags.contains(tag)

View file

@ -1,5 +1,6 @@
package view
import SortBy
import androidx.compose.runtime.Composable
import model.Globe
import model.Recipe
@ -13,7 +14,9 @@ fun getFilteredRecipeList(
tags : List<String>,
search : String,
lockTag : String,
sortBy: SortBy,
returnAny: Boolean,
reverse: Boolean,
) : List<Recipe> {
val items = getRecipeList()
@ -35,7 +38,14 @@ fun getFilteredRecipeList(
recipes = recipes.filter { it.tags.contains(lockTag)}
}
recipes = recipes.sortedBy { it.title }
recipes = when (sortBy){
SortBy.Name -> recipes.sortedBy { recipe -> recipe.title }
SortBy.Time -> recipes.sortedBy { recipe -> (recipe.prepTime + recipe.cookTime)}
SortBy.Ingredients -> recipes.sortedBy { recipe -> recipe.ingredients.count()}
}
if(reverse)
recipes = recipes.reversed()
return recipes
}

View file

@ -0,0 +1,93 @@
package view
import SortBy
import Theme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun MainDropDown(
isLarge: Boolean,
andOr: Boolean,
descending: Boolean,
theme: Theme,
sortBy: SortBy,
onTag: () -> Unit,
onSortBy: () -> Unit,
onDesc: () -> Unit,
onTheme: () -> Unit,
onRandom: () -> Unit,
onBack: () -> Unit,
onClose: () -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
Box(
modifier = Modifier
.padding(16.dp)
) {
IconButton(onClick = { expanded = !expanded }) {
Icon(imageVector = Icons.Default.MoreVert, contentDescription = "More Options")
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
DropdownMenuItem(
text = { Text(theme.name) },
onClick = onTheme
)
HorizontalDivider()
DropdownMenuItem(
text = { Text("Filter Style: ".plus(if(andOr) "OR" else "AND")) },
onClick = onTag
)
DropdownMenuItem(
text = { Text(text = "Sort By: ".plus(sortBy.name)) },
onClick = onSortBy
)
DropdownMenuItem(
text = { Text(text = "Sort Order: ".plus(if(descending)"DESC" else "ASC")) },
onClick = onDesc
)
HorizontalDivider()
DropdownMenuItem(
text = { Text("Random Filtered Recipe") },
onClick = onRandom
)
if (isLarge) {
HorizontalDivider()
DropdownMenuItem(
text = { Text("Go Back") },
onClick = onBack
)
DropdownMenuItem(
text = { Text("Close app") },
onClick = onClose
)
}
}
}
}

View file

@ -0,0 +1,40 @@
package view
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun RecipeScaleSlider(
sliderPosition: Float,
steps: Int,
rangeStart: Float,
rangeEnd: Float,
reduce: Boolean,
onClick: () -> Unit,
onChange: (Float) -> Unit) {
Column {
Slider(
value = sliderPosition,
steps = steps,
valueRange = rangeStart..rangeEnd,
onValueChange = { onChange(it) },
modifier = Modifier.padding(start = 16.dp, end = 16.dp)
)
Row {
Text(text = sliderPosition.toString().plus("x Servings"))
Spacer(modifier = Modifier.weight(1f))
Button(onClick = onClick) {
Text(text = if (reduce) "Reducing" else "Increasing")
}
}
}
}