Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .idea/dictionaries/vm.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 20 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,70 @@
## FeelFine - activity tracker app

Application to track your activities with [Google Fit API](https://developers.google.com/fit "Google Fit API").
Smart watch synchronization with the app through Google Fit API.
Kotlin first, Koin for DI, [MPAndroidChart](https://github.com/PhilJay/MPAndroidChart "MPAndroidChart") for activity charts.
Application to track your fitness activities with [Google Fit API](https://developers.google.com/fit "Google Fit API").
- Kotlin
- Jetpack Compose
- [Koin](https://github.com/InsertKoinIO/koin "Koin") for DI
- [MPAndroidChart](https://github.com/PhilJay/MPAndroidChart "MPAndroidChart") for activity charts

------------



### [Welcome screen](https://github.com/feelsoftware/FeelFine/blob/main/app/src/main/java/com/feelsoftware/feelfine/ui/onboarding/OnboardingFragment.kt "Welcome screen")
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/welcome.png" width="180" height="390" />
### [Welcome screen](https://github.com/feelsoftware/FeelFine/blob/main/app/src/main/java/com/feelsoftware/feelfine/ui/welcome/WelcomeContent.kt "Welcome screen")
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/welcome.png" width="180" height="360" />

Welcome screen if user is not signed it yet.

Welcome screen with custom logo and a possibility to sign in or sign up. Authorize with your Google Account.


------------



### [Registration flow](https://github.com/feelsoftware/FeelFine/tree/main/app/src/main/java/com/feelsoftware/feelfine/ui/onboarding "Registration flow")
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/registration_1.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/registration_2.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/registration_3.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/registration_4.png" width="180" height="390" />
### [Onboarding flow](https://github.com/feelsoftware/FeelFine/tree/main/app/src/main/java/com/feelsoftware/feelfine/ui/onboarding "Onboarding flow")
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/onboarding_name.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/onboarding_gender.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/onboarding_weight.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/onboarding_birthday.png" width="180" height="360" />

Four simple registration steps with progress indicator.
Four simple onboarding steps to pick your name, gender, weight and birthday.



------------



### [Today's score with details](https://github.com/feelsoftware/FeelFine/tree/main/app/src/main/java/com/feelsoftware/feelfine/ui/score "Today's score with details")
### [Today's score with details](https://github.com/feelsoftware/FeelFine/tree/main/app/src/main/java/com/feelsoftware/feelfine/ui/score "Today's score with details") (Not Compose yet)

<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_1.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_2.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_3.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_4.png" width="180" height="390" />
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_1.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_2.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_3.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/score_4.png" width="180" height="360" />

A user’s data as steps, sleep, biking, running and other activities synced via [Google Fit API](https://developers.google.com/fit "Google Fit API"). User has an every day score, based on his own metrics.


------------


### [Activities statistic](https://github.com/feelsoftware/FeelFine/tree/main/app/src/main/java/com/feelsoftware/feelfine/ui/statistic "Activities statistic")
### [Activities statistic](https://github.com/feelsoftware/FeelFine/tree/main/app/src/main/java/com/feelsoftware/feelfine/ui/statistic "Activities statistic") (Not Compose yet)

<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/statistic_1.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/statistic_2.png" width="180" height="390" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/statistic_3.png" width="180" height="390" />
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/statistic_1.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/statistic_2.png" width="180" height="360" /> <img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/statistic_3.png" width="180" height="360" />

Users could observe week/month/custom range activities statistics.


------------


### [Mood score](https://github.com/feelsoftware/FeelFine/blob/main/app/src/main/java/com/feelsoftware/feelfine/ui/score/MoodFragment.kt "Mood score")
### [Mood score](https://github.com/feelsoftware/FeelFine/blob/main/app/src/main/java/com/feelsoftware/feelfine/ui/score/MoodFragment.kt "Mood score") (Not Compose yet)

<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/mood.png" width="180" height="390" />
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/mood.png" width="180" height="360" />

We are asking each day 'How are you?' for the mood score with 9 options for users.


------------


### [User profile](https://github.com/feelsoftware/FeelFine/blob/main/app/src/main/java/com/feelsoftware/feelfine/ui/profile/ProfileFragment.kt "User profile")
### [User profile](https://github.com/feelsoftware/FeelFine/blob/main/app/src/main/java/com/feelsoftware/feelfine/ui/profile/ProfileFragment.kt "User profile") (Not Compose yet)

<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/profile.png" width="180" height="390" />
<img src="https://github.com/feelsoftware/FeelFine/raw/main/readme/profile.png" width="180" height="360" />

User profile with wage, age and goals (steps, sleep, activity) customizations.

45 changes: 31 additions & 14 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'kotlin-android-extensions'
id "androidx.navigation.safeargs"
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
}

android {
namespace 'com.feelsoftware.feelfine'
compileSdk 33
buildToolsVersion '33.0.0'

Expand Down Expand Up @@ -47,29 +47,35 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "11"
jvmTarget = "17"
}

packagingOptions {
resources {
excludes += ['META-INF/DEPENDENCIES', 'META-INF/LICENSE', 'META-INF/LICENSE.txt', 'META-INF/license.txt', 'META-INF/NOTICE', 'META-INF/NOTICE.txt', 'META-INF/notice.txt', 'META-INF/ASL2.0', 'META-INF/*.kotlin_module']
}
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.0"
}
}

dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'

implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation "androidx.activity:activity-ktx:1.6.1"
implementation "androidx.fragment:fragment-ktx:1.5.4"
implementation 'com.google.android.material:material:1.7.0'
implementation "androidx.fragment:fragment-ktx:1.5.5"
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

// ArchComponents
Expand All @@ -81,11 +87,21 @@ dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:2.5.3"
implementation "androidx.navigation:navigation-ui-ktx:2.5.3"

// Compose
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.activity:activity-compose:1.6.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.compose.material3:material3:1.1.0-alpha05'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"

// Google Fit
implementation "com.google.android.gms:play-services-fitness:21.1.0"
implementation "com.google.android.gms:play-services-auth:20.3.0"
implementation "com.google.android.gms:play-services-auth:20.4.1"
implementation 'com.google.firebase:firebase-analytics-ktx:21.2.0'
implementation 'com.google.firebase:firebase-crashlytics-ktx:18.3.1'
implementation 'com.google.firebase:firebase-crashlytics-ktx:18.3.3'
//noinspection GradleDependency
implementation('com.google.api-client:google-api-client:1.30.11') {
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
Expand All @@ -97,9 +113,10 @@ dependencies {
implementation 'com.google.apis:google-api-services-fitness:v1-rev127-1.25.0'

// DataBase
implementation "androidx.room:room-runtime:2.4.3"
kapt "androidx.room:room-compiler:2.4.3"
implementation "androidx.room:room-rxjava3:2.4.3"
implementation "androidx.room:room-runtime:2.5.0"
kapt "androidx.room:room-compiler:2.5.0"
implementation "androidx.room:room-ktx:2.5.0"
implementation "androidx.room:room-rxjava3:2.5.0"

// RxJava
implementation 'io.reactivex.rxjava3:rxjava:3.0.12'
Expand All @@ -125,6 +142,6 @@ dependencies {
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.schedulers.Schedulers

@Database(
version = 2,
version = 3,
entities = [
ActivityEntity::class,
MoodEntity::class,
SleepEntity::class,
StepsEntity::class,
UserProfileEntity::class,
],
exportSchema = false
exportSchema = false,
)
@TypeConverters(
DateConverter::class,
Expand All @@ -41,6 +41,6 @@ abstract class AppDatabase : RoomDatabase() {
.andThen(moodDao().delete())
.andThen(sleepDao().delete())
.andThen(stepsDao().delete())
.andThen(userProfileDao().delete())
.andThen(userProfileDao().deleteLegacy())
.subscribeOn(Schedulers.io())
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
package com.feelsoftware.feelfine.data.db.dao

import androidx.room.*
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.feelsoftware.feelfine.data.db.entity.UserProfileEntity
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Observable
import kotlinx.coroutines.flow.Flow

@Dao
interface UserProfileDao {

@Query("SELECT * FROM user_profile")
fun get(): Observable<List<UserProfileEntity>>
fun get(): Flow<List<UserProfileEntity>>

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(profile: UserProfileEntity): Completable
suspend fun insert(profile: UserProfileEntity)

@Query("DELETE FROM user_profile")
fun delete(): Completable
suspend fun delete()

@Deprecated("Use Coroutines instead")
@Query("SELECT * FROM user_profile")
fun getLegacy(): Observable<List<UserProfileEntity>>

@Deprecated("Use Coroutines instead")
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertLegacy(profile: UserProfileEntity): Completable

@Deprecated("Use Coroutines instead")
@Query("DELETE FROM user_profile")
fun deleteLegacy(): Completable
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import java.util.Date

@Entity(
tableName = "user_profile"
Expand All @@ -16,8 +17,8 @@ data class UserProfileEntity(
val id: Int,
val name: String,
val gender: Gender,
val weight: Int,
val age: Int,
val weight: Float,
val birthday: Date,
val isDemo: Boolean,
) {

Expand Down
Loading