diff --git a/.github/workflows/android_build.yml b/.github/workflows/android_build.yml index 20d9710..e18ec98 100644 --- a/.github/workflows/android_build.yml +++ b/.github/workflows/android_build.yml @@ -2,9 +2,9 @@ name: Android Build on: push: - branches: [ develop ] + branches: [ main ] pull_request: - branches: [ develop ] + branches: [ main ] jobs: build: diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..9924b65 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,62 @@ +name: Deploy App CI + +on: + pull_request: + branches: [ main ] + types: [ closed ] + +jobs: + build: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@v2.3.4 + with: + ref: ${{ github.event.inputs.branch }} + + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Setup Android SDK + uses: android-actions/setup-android@v2 + + - name: Grant rights + run: chmod +x build.gradle + + - name: Build with Gradle + id: build + run: ./gradlew build --stacktrace + + - name: Build Release AAB + id: buildRelease + run: ./gradlew bundleRelease --stacktrace + + - name: Sign AAB + id: sign + uses: r0adkll/sign-android-release@v1 + with: + releaseDirectory: app/build/outputs/bundle/release + signingKeyBase64: ${{ secrets.SIGNING_KEY }} + alias: ${{ secrets.ALIAS }} + keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }} + keyPassword: ${{ secrets.KEY_PASSWORD }} + + - name: Create service_account.json + id: createServiceAccount + run: echo '${{ secrets.SERVICE_ACCOUNT_JSON }}' > service_account.json + + - name: Deploy to Play Store + id: deploy + uses: r0adkll/upload-google-play@v1.0.15 + with: + serviceAccountJson: service_account.json + packageName: com.brandyodhiambo.quench + releaseFile: app/build/outputs/bundle/release/app-release.aab + track: internal + + + diff --git a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt index e17f875..b13fd98 100644 --- a/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt +++ b/app/src/main/java/com/brandyodhiambo/quench/ui/MainActivity.kt @@ -62,7 +62,7 @@ class MainActivity : ComponentActivity() { QuenchTheme { Surface( modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colors.background, + color = MaterialTheme.colors.background ) { startAchievementOnetimeWorkRequest(applicationContext) startDailyOnetimeWorkRequest(applicationContext) @@ -75,7 +75,7 @@ class MainActivity : ComponentActivity() { val scheduler = AlarmSchedularImpl(this) val alarmItem = AlarmData( time = LocalDateTime.now().withHour(hours).withMinute(minutes), - message = getString(R.string.it_s_time_to_drink_water), + message = getString(R.string.it_s_time_to_drink_water) ) alarmItem.let(scheduler::schedule) val navController = rememberAnimatedNavController() @@ -87,9 +87,9 @@ class MainActivity : ComponentActivity() { engine = navHostEngine, dependenciesContainerBuilder = { dependency( - currentNavigator(), + currentNavigator() ) - }, + } ) } } @@ -100,7 +100,7 @@ class MainActivity : ComponentActivity() { fun DestinationScope<*>.currentNavigator(): FeatureNavigator { return FeatureNavigator( navController = navController, - navGraph = navBackStackEntry.destination.navGraph(), + navGraph = navBackStackEntry.destination.navGraph() ) } diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt index aadfd3f..649f79b 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/achievement/AchievementViewModel.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.home.presentation.achievement import androidx.lifecycle.ViewModel diff --git a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt index b8e2f29..4d1810e 100644 --- a/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt +++ b/feature/home/src/main/java/com/brandyodhiambo/home/presentation/homeScreen/HomeScreen.kt @@ -81,7 +81,7 @@ import com.ramcosta.composedestinations.annotation.Destination @Destination @Composable fun HomeScreen( - viewModel: HomeViewModel = hiltViewModel(), + viewModel: HomeViewModel = hiltViewModel() ) { val openTimeDialog = remember { mutableStateOf(false) } val openDeleteDialog = remember { mutableStateOf(false) } @@ -109,12 +109,12 @@ fun HomeScreen( val minute = reminderTimeFromDb.value?.minute Scaffold( - backgroundColor = primaryColor, + backgroundColor = primaryColor ) { paddingValues -> Box( modifier = Modifier .fillMaxSize() - .padding(paddingValues), + .padding(paddingValues) ) { LazyColumn { item { @@ -124,7 +124,7 @@ fun HomeScreen( waterIntake = waterIntake, form = waterIntakeForm, goalForm = goalForm, - goalWaterIntake = goalWaterIntake, + goalWaterIntake = goalWaterIntake ) } item { @@ -143,16 +143,16 @@ fun HomeScreen( val (amount, taken) = incrementProgressCircle( selectedDrinksFromDB = selectedDrinksFromDB, goalWaterIntake = goalWaterIntake, - viewModel = viewModel, + viewModel = viewModel ) viewModel.deleteAllLevels() viewModel.insertLevel( Level( amountTaken = amount, - waterTaken = taken, - ), + waterTaken = taken + ) ) - }, + } ) } item { @@ -176,7 +176,7 @@ fun HomeScreen( openEmptyStateDialog.value = false selectedDrinkDialog.value = true }, - onDismiss = { openEmptyStateDialog.value = false }, + onDismiss = { openEmptyStateDialog.value = false } ) } } @@ -189,7 +189,7 @@ fun HomeScreen( onConfirmClick = { id -> viewModel.deleteOneSelectedDrink(id) openDeleteDialog.value = false - }, + } ) } } @@ -205,7 +205,7 @@ fun HomeScreen( }, onOkayClicked = { openCongratulationsDialog.value = false - }, + } ) } } @@ -221,7 +221,7 @@ fun HomeScreen( }, onAllDayClicked = { viewModel.onAllDaySelected( - isAllDay = true, + isAllDay = true ) viewModel.reminderDays.value = listOf( Days("M", viewModel.isAllDaySelected.value), @@ -230,7 +230,7 @@ fun HomeScreen( Days("T", viewModel.isAllDaySelected.value), Days("F", viewModel.isAllDaySelected.value), Days("S", viewModel.isAllDaySelected.value), - Days("S", viewModel.isAllDaySelected.value), + Days("S", viewModel.isAllDaySelected.value) ) }, onConfirmClick = { @@ -247,7 +247,7 @@ fun HomeScreen( amPm = ampm, isReapeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value, + days = viewModel.reminderDays.value ) if (viewModel.reminderTime.value != null) { viewModel.deleteAllRemindTime() @@ -259,10 +259,10 @@ fun HomeScreen( ampm = viewModel.reminderSelectedTime.value.ampm, isRepeated = false, isAllDay = viewModel.isAllDaySelected.value, - days = viewModel.reminderDays.value, - ), + days = viewModel.reminderDays.value + ) ) - }, + } ) } } @@ -282,10 +282,10 @@ fun HomeScreen( onOkayClick = { val goalWaterIntakeToInsert = GoalWaterIntake( waterIntake = viewModel.goalWaterIntakeValue.value.toInt(), - form = viewModel.goalWaterForm.value, + form = viewModel.goalWaterForm.value ) viewModel.insertGoalWaterIntake(goalWaterIntakeToInsert) - }, + } ) } } @@ -305,10 +305,10 @@ fun HomeScreen( onOkayClick = { val idealWaterIntakeToInsert = IdealWaterIntake( waterIntake = viewModel.idealWaterIntakeValue.value.toInt(), - form = viewModel.idealWaterForm.value, + form = viewModel.idealWaterForm.value ) viewModel.insertIdealWaterIntake(idealWaterIntakeToInsert) - }, + } ) } } @@ -331,10 +331,10 @@ fun HomeScreen( SelectedDrink( drinkValue = viewModel.size.value, icon = viewModel.selectedIcon.value, - time = viewModel.selectedTime.value, - ), + time = viewModel.selectedTime.value + ) ) - }, + } ) } } @@ -345,7 +345,7 @@ fun HomeScreen( private fun incrementProgressCircle( selectedDrinksFromDB: State>, goalWaterIntake: Int, - viewModel: HomeViewModel, + viewModel: HomeViewModel ): Pair { // getting the last selected drink var amountTaken = viewModel.levelFromDB.value?.amountTaken ?: 0f @@ -393,49 +393,49 @@ fun WaterIntake( waterIntake: Int, form: String, goalForm: String, - goalWaterIntake: Int, + goalWaterIntake: Int ) { Card( modifier = Modifier .height(100.dp) .padding(16.dp) .fillMaxWidth(), - elevation = 4.dp, + elevation = 4.dp ) { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalArrangement = Arrangement.SpaceEvenly, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Image( painter = painterResource(id = R.drawable.ic_glass), - contentDescription = null, + contentDescription = null ) Spacer(modifier = Modifier.width(8.dp)) Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { idealWaterIntakeDialog.value = true - }, + } ) { Text( text = "Ideal water intake", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto, + fontFamily = roboto ) Text( text = "$waterIntake $form", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto, + fontFamily = roboto ) } } @@ -444,11 +444,11 @@ fun WaterIntake( .fillMaxHeight() .width(2.dp), thickness = 2.dp, - color = primaryColor, + color = primaryColor ) Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Image(painter = painterResource(id = R.drawable.ic_cup), contentDescription = null) Spacer(modifier = Modifier.width(8.dp)) @@ -456,20 +456,20 @@ fun WaterIntake( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.clickable { openGoalDialog.value = true - }, + } ) { Text( text = "Water intake goal", fontSize = 14.sp, color = Color.Gray, - fontFamily = roboto, + fontFamily = roboto ) Text( text = "$goalWaterIntake $goalForm", fontSize = 16.sp, color = Color.Gray, fontWeight = FontWeight.Bold, - fontFamily = roboto, + fontFamily = roboto ) } } @@ -485,32 +485,32 @@ fun WaterRecord( time: String, goalWaterIntake: Int, selectedDrinkDialog: MutableState, - onAddLevelClick: () -> Unit, + onAddLevelClick: () -> Unit ) { Card( modifier = Modifier .fillMaxWidth() .height(350.dp) .padding(start = 16.dp, end = 16.dp), - elevation = 4.dp, + elevation = 4.dp ) { Column( modifier = Modifier .fillMaxSize() .padding(8.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { Spacer(modifier = Modifier.height(8.dp)) CircularRating( percentage = amountTaken, drunk = waterTaken, - goal = goalWaterIntake, + goal = goalWaterIntake ) Spacer(modifier = Modifier.height(8.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceEvenly, + horizontalArrangement = Arrangement.SpaceEvenly ) { CircularButton( backgroundColor = lightBlue, @@ -518,7 +518,7 @@ fun WaterRecord( title = time, onClick = { openDialog.value = true - }, + } ) CircularButton( backgroundColor = lightBlue, @@ -526,7 +526,7 @@ fun WaterRecord( title = "Add Level", onClick = { onAddLevelClick() - }, + } ) CircularButton( backgroundColor = lightBlue, @@ -534,7 +534,7 @@ fun WaterRecord( title = "Add Drink", onClick = { selectedDrinkDialog.value = true - }, + } ) } } @@ -544,13 +544,13 @@ fun WaterRecord( @Composable fun WaterIntakeTimeAndLevel( intake: SelectedDrink, - onDeleteIconClick: (SelectedDrink) -> Unit, + onDeleteIconClick: (SelectedDrink) -> Unit ) { Column( modifier = Modifier .fillMaxSize() .padding(start = 16.dp, end = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.CenterHorizontally ) { Row( modifier = Modifier @@ -558,48 +558,48 @@ fun WaterIntakeTimeAndLevel( .background(Color.White) .padding(4.dp), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Row( horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Icon( modifier = Modifier.size(20.dp), painter = painterResource(id = intake.icon), tint = primaryColor, - contentDescription = null, + contentDescription = null ) Text( text = intake.drinkValue, fontFamily = roboto, fontSize = 16.sp, - fontWeight = FontWeight.W400, + fontWeight = FontWeight.W400 ) } Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + verticalAlignment = Alignment.CenterVertically ) { Text( text = intake.time, fontSize = 14.sp, color = Color.Gray, fontFamily = roboto, - fontWeight = FontWeight.W300, + fontWeight = FontWeight.W300 ) IconButton(onClick = { onDeleteIconClick(intake) }) { Icon( imageVector = Icons.Default.Delete, tint = Color.Gray, - contentDescription = null, + contentDescription = null ) } } } Divider( thickness = 1.dp, - color = Color.Gray, + color = Color.Gray ) } } diff --git a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt index 3e69e91..3a68c58 100644 --- a/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt +++ b/feature/statistics/src/main/java/com/brandyodhiambo/statistics/worker/achievement/AchievementWorker.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C)2023 Brandy Odhiambo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.brandyodhiambo.statistics.worker.achievement import android.content.Context @@ -19,7 +34,7 @@ class AchievementWorker @AssistedInject constructor( @Assisted params: WorkerParameters, private val achievementRepository: AchievementRepository, private val levelRepository: LevelRepository, - private val goalWaterIntakeRepository: GoalWaterIntakeRepository, + private val goalWaterIntakeRepository: GoalWaterIntakeRepository ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { return try { @@ -29,8 +44,8 @@ class AchievementWorker @AssistedInject constructor( achievementRepository.insertAchievement( Achievement( isAchieved = amountTaken.toInt() >= goalWaterIntake.toInt(), - day = getCurrentDay(), - ), + day = getCurrentDay() + ) ) Result.success() } catch (e: Exception) { diff --git a/spotless.gradle b/spotless.gradle index 1f99636..feff2aa 100644 --- a/spotless.gradle +++ b/spotless.gradle @@ -12,7 +12,7 @@ spotless { kotlin { target "**/*.kt" trimTrailingWhitespace() - ktlint() + //ktlint() indentWithSpaces() licenseHeaderFile(rootProject.file("spotless/copyright.kt")) endWithNewline()