Skip to content

Commit

Permalink
Publish project on GitHub
Browse files Browse the repository at this point in the history
  • Loading branch information
Subfly committed May 27, 2023
0 parents commit d7cb2cd
Show file tree
Hide file tree
Showing 213 changed files with 7,521 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.iml
.gradle
.idea
.DS_Store
build
captures
.externalNativeBuild
.cxx
local.properties
xcuserdata
52 changes: 52 additions & 0 deletions appAndroid/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@Suppress("DSL_SCOPE_VIOLATION")

plugins {
alias(libs.plugins.android.application)
kotlin("android")
}

android {
namespace = "dev.subfly.kmmeal.android"
compileSdk = 33
defaultConfig {
applicationId = "dev.subfly.kmmeal.android"
minSdk = 24
targetSdk = 33
versionCode = 1
versionName = "1.0"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.7"
}
packagingOptions {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
signingConfig = signingConfigs.getByName("debug")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}

dependencies {
implementation(project(":shared"))
implementation(libs.bundles.compose)
implementation(libs.bundles.accompanist)
implementation(libs.bundles.koin.android)
implementation(libs.kmm.viewmodel)
implementation(libs.coil)
implementation(libs.splash)
}
26 changes: 26 additions & 0 deletions appAndroid/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application
android:label="KMMeal"
android:name=".app.KMMealApplication"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:supportsRtl="true"
android:theme="@style/Theme.KmmApp.Splash"
android:usesCleartextTraffic="true">
<activity
android:name=".app.MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.subfly.kmmeal.android.app

import android.app.Application
import dev.subfly.kmmeal.android.di.appModule
import dev.subfly.kmmeal.di.DIHelper
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger

class KMMealApplication: Application() {
private val koin = DIHelper()

override fun onCreate() {
super.onCreate()
koin.initKoin {
androidLogger()
androidContext(this@KMMealApplication)
modules(appModule)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package dev.subfly.kmmeal.android.app

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import dev.subfly.kmmeal.android.navigation.KMMNavHost
import dev.subfly.kmmeal.android.common.theme.AppTheme
import dev.subfly.kmmeal.state.liked.LikedMealsStateMachine
import org.koin.androidx.compose.koinViewModel
import org.koin.core.component.KoinComponent

val LocalGlobalNavigator = compositionLocalOf<NavHostController> {
error("No nav host found!")
}
val LocalLikedMealsProvider = compositionLocalOf<LikedMealsStateMachine> {
error("No liked meals state machine found!")
}

class MainActivity : ComponentActivity(), KoinComponent {
private lateinit var globalNavController: NavHostController
private lateinit var likedMealsStateMachine: LikedMealsStateMachine

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

installSplashScreen()

WindowCompat.setDecorFitsSystemWindows(window, false)

setContent {
globalNavController = rememberNavController()
likedMealsStateMachine = koinViewModel()

AppTheme {
CompositionLocalProvider(
LocalGlobalNavigator provides globalNavController,
LocalLikedMealsProvider provides likedMealsStateMachine
) {
KMMNavHost()
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package dev.subfly.kmmeal.android.common.components

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.Icon
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun DummySearchBar(
onSearchPressed: () -> Unit = {}
) {
Surface(
modifier = Modifier.fillMaxWidth()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(48.dp)
.padding(
horizontal = 12.dp
)
.padding(
bottom = 4.dp
)
.clip(
RoundedCornerShape(32.dp)
)
.background(
Color.Gray.copy(alpha = 0.2F)
)
.clickable(
onClick = onSearchPressed
),
contentAlignment = Alignment.CenterStart
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "Tap to Search Meals...",
style = TextStyle(
fontStyle = FontStyle.Italic,
fontSize = 14.sp,
fontWeight = FontWeight.Light
)
)
Icon(
imageVector = Icons.Default.Search,
contentDescription = "Search Icon",
tint = Color.Gray.copy(alpha = 0.5F)
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package dev.subfly.kmmeal.android.common.components.layout

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp

@Composable
fun BaseScreenLayout(
screenModifier: Modifier = Modifier,
topAppBar: @Composable () -> Unit,
onSuccessLayout: @Composable () -> Unit,
fab: (@Composable () -> Unit)? = null,
isLoading: Boolean,
errorMessage: String,
onErrorRetry: () -> Unit = {}
) {
Scaffold(
modifier = screenModifier,
topBar = topAppBar,
floatingActionButton = {
fab?.invoke()
}
) { paddings ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(paddings),
contentAlignment = Alignment.Center
) {
when {
// Lazy column in order to make refresh work :(
errorMessage.isNotEmpty() -> Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier.padding(horizontal = 64.dp),
text = errorMessage,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.padding(top = 16.dp))
Button(
onClick = onErrorRetry
) {
Text(text = "Retry")
}
}
isLoading -> CircularProgressIndicator()
else -> onSuccessLayout()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package dev.subfly.kmmeal.android.common.components.layout

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import dev.subfly.kmmeal.android.common.components.tiles.MealTile
import dev.subfly.kmmeal.domain.model.MealModel

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MealGridLayout(
meals: List<MealModel>,
onMealPressed: (String) -> Unit
) {
LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Fixed(2),
contentPadding = PaddingValues(
horizontal = 16.dp,
vertical = 8.dp
),
verticalItemSpacing = 16.dp,
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxSize()
) {
items(meals) { model ->
MealTile(
model = model,
onCardPressed = {
if(model.id.isNotEmpty()) {
onMealPressed(model.id)
}
}
)
}
}
}
Loading

0 comments on commit d7cb2cd

Please sign in to comment.