diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..a3696b9f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,44 @@ +# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs +# editorconfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 + +# We recommend you to keep these unchanged + +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + + +# Use 2 spaces for indentation in HTML, JavaScript, Ruby, SCSS, and XML +[*.{html,js,ts,rb,scss,xml, kt, jv, java}] +indent_size = 2 + +[Gemfile*] +indent_size = 2 + +[Rakefile] +indent_size = 2 + +[Makefile] +indent_style = tab +indent_size = 2 + +# Use 4 spaces for indentation in c source files +[*.c] +indent_size = 4 + +# Use 4 spaces for indentation in Markdown files +[*.md] +indent_size = 4 +trim_trailing_whitespace = false + +[gnome-terminal/**.xml] +indent_style = tab +indent_size = 4 diff --git a/app/build.gradle b/app/build.gradle index 73259156..f789a8b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,118 +5,111 @@ apply plugin: 'realm-android' apply plugin: 'io.fabric' android { - defaultConfig { - vectorDrawables.useSupportLibrary = true + defaultConfig { + vectorDrawables.useSupportLibrary = true + } + flavorDimensions "default" + configurations.all { + resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9' + } + dexOptions { + maxProcessCount 4 + } + compileSdkVersion 26 + defaultConfig { + applicationId 'com.bodyweight.fitness' + minSdkVersion 21 + targetSdkVersion 26 + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_6 + targetCompatibility JavaVersion.VERSION_1_6 + } + packagingOptions { + exclude 'META-INF/DEPENDENCIES.txt' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE' + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/notice.txt' + exclude 'META-INF/license.txt' + exclude 'META-INF/dependencies.txt' + exclude 'META-INF/LGPL2.1' + exclude 'META-INF/services/javax.annotation.processing.Processor' + } + productFlavors { + pro { + resValue "string", "file_provider", "com.bodyweight.fitness.pro.fileprovider" + applicationId 'com.bodyweight.fitness.pro' + versionCode 142 + versionName "1.4.2" } - flavorDimensions "default" - configurations.all { - resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9' + free { + resValue "string", "file_provider", "com.bodyweight.fitness.free.fileprovider" + applicationId 'com.bodyweight.fitness.free' + versionCode 142 + versionName "1.4.2" } - dexOptions { - maxProcessCount 4 + } + buildTypes { + release { + minifyEnabled false } - compileSdkVersion 26 - defaultConfig { - applicationId 'com.bodyweight.fitness' - minSdkVersion 21 - targetSdkVersion 26 - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + debug { + minifyEnabled false + ext.enableCrashlytics = false } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_6 - targetCompatibility JavaVersion.VERSION_1_6 - } - packagingOptions { - exclude 'META-INF/DEPENDENCIES.txt' - exclude 'META-INF/LICENSE.txt' - exclude 'META-INF/NOTICE.txt' - exclude 'META-INF/NOTICE' - exclude 'META-INF/LICENSE' - exclude 'META-INF/DEPENDENCIES' - exclude 'META-INF/notice.txt' - exclude 'META-INF/license.txt' - exclude 'META-INF/dependencies.txt' - exclude 'META-INF/LGPL2.1' - exclude 'META-INF/services/javax.annotation.processing.Processor' - } - productFlavors { - pro { - resValue "string", "file_provider", "com.bodyweight.fitness.pro.fileprovider" - applicationId 'com.bodyweight.fitness.pro' - versionCode 142 - versionName "1.4.2" - } - free { - resValue "string", "file_provider", "com.bodyweight.fitness.free.fileprovider" - applicationId 'com.bodyweight.fitness.free' - versionCode 142 - versionName "1.4.2" - } - } - buildTypes { - release { - minifyEnabled false - } - debug { - minifyEnabled false - ext.enableCrashlytics = false - } - } - sourceSets { - main.java.srcDirs += 'src/main/java' - main.java.srcDirs += 'src/main/kotlin' - test.java.srcDirs += 'src/test/kotlin' + + customDebugType { + debuggable true } + } + sourceSets { + main.java.srcDirs += 'src/main/java' + main.java.srcDirs += 'src/main/kotlin' + test.java.srcDirs += 'src/test/kotlin' + } } kapt { - generateStubs = true + generateStubs = true } configurations { - all*.exclude group: 'io.reactivex', module: 'rxjava' + all*.exclude group: 'io.reactivex', module: 'rxjava' } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - - implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" - - testImplementation 'org.jetbrains.spek:spek:1.0.9' - testImplementation 'org.mockito:mockito-all:2.0.2-beta' - - androidTestImplementation "com.android.support:support-annotations:$support_version" - androidTestImplementation 'com.android.support.test:runner:0.5' - androidTestImplementation 'com.android.support.test:rules:0.5' - androidTestImplementation "com.android.support.test.espresso:espresso-core:2.2.2" - - implementation "com.android.support:support-v4:$support_version" - implementation "com.android.support:recyclerview-v7:$support_version" - implementation "com.android.support:cardview-v7:$support_version" - implementation "com.android.support:design:$support_version" - - implementation 'com.google.code.gson:gson:2.4' - - implementation 'commons-io:commons-io:2.4' - implementation 'net.danlew:android.joda:2.9.3' - - implementation 'com.netflix.rxjava:rxjava-core:0.20.7' - implementation 'io.reactivex:rxandroid:1.2.1' - implementation 'io.reactivex:rxjava:1.2.1' - - implementation 'com.trello:rxlifecycle:0.8.0' - implementation 'com.trello:rxlifecycle-components:0.8.0' - implementation 'com.trello:rxlifecycle-kotlin:0.8.0' - - implementation 'com.robinhood.spark:spark:1.2.0' - - implementation 'com.roughike:bottom-bar:2.0.2' - implementation 'com.github.johnkil.android-robototextview:robototextview:4.0.0' - implementation 'com.gordonwong:material-sheet-fab:1.2.1' - implementation 'io.github.kobakei:ratethisapp:1.0.3' - implementation 'com.github.paolorotolo:appintro:4.1.0' - - implementation('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') { - transitive = true - } + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" + testImplementation 'org.jetbrains.spek:spek:1.0.9' + testImplementation 'org.mockito:mockito-all:2.0.2-beta' + androidTestImplementation "com.android.support:support-annotations:$support_version" + androidTestImplementation 'com.android.support.test:runner:0.5' + androidTestImplementation 'com.android.support.test:rules:0.5' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2' + implementation "com.android.support:support-v4:$support_version" + implementation "com.android.support:recyclerview-v7:$support_version" + implementation "com.android.support:cardview-v7:$support_version" + implementation "com.android.support:design:$support_version" + implementation 'com.google.code.gson:gson:2.4' + implementation 'commons-io:commons-io:2.4' + implementation 'net.danlew:android.joda:2.9.3' + implementation 'com.netflix.rxjava:rxjava-core:0.20.7' + implementation 'io.reactivex:rxandroid:1.2.1' + implementation 'io.reactivex:rxjava:1.2.1' + implementation 'com.trello:rxlifecycle:0.8.0' + implementation 'com.trello:rxlifecycle-components:0.8.0' + implementation 'com.trello:rxlifecycle-kotlin:0.8.0' + implementation 'com.robinhood.spark:spark:1.2.0' + implementation 'com.roughike:bottom-bar:2.0.2' + implementation 'com.github.johnkil.android-robototextview:robototextview:4.0.0' + implementation 'com.gordonwong:material-sheet-fab:1.2.1' + implementation 'io.github.kobakei:ratethisapp:1.0.3' + implementation 'com.github.paolorotolo:appintro:4.1.0' + implementation('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') { + transitive = true + } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 47010cc4..6574f147 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,89 +1,90 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/kotlin/com/bodyweight/fitness/App.kt b/app/src/main/kotlin/com/bodyweight/fitness/App.kt index 758ef280..86173164 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/App.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/App.kt @@ -1,8 +1,8 @@ package com.bodyweight.fitness +import android.annotation.SuppressLint import android.app.Application import android.content.Context - import com.bodyweight.fitness.repository.SchemaMigration import com.crashlytics.android.Crashlytics @@ -12,29 +12,36 @@ import com.kobakei.ratethisapp.RateThisApp import net.danlew.android.joda.JodaTimeAndroid import io.fabric.sdk.android.Fabric +import io.realm.Realm + class App : Application() { - companion object { - @JvmStatic - var context: Context? = null - } + companion object { + @JvmStatic + var context: Context? = null + } - override fun onCreate() { - super.onCreate() + override fun onCreate() { + super.onCreate() - JodaTimeAndroid.init(applicationContext) + JodaTimeAndroid.init(applicationContext) - val config = RateThisApp.Config(2, 7) - RateThisApp.init(config) + val config = RateThisApp.Config(2, 7) + RateThisApp.init(config) - if (!BuildConfig.DEBUG) { - Fabric.with(applicationContext, Crashlytics(), Answers()) - } + if (!BuildConfig.DEBUG) { + Fabric.with(applicationContext, Crashlytics(), Answers()) + } - context = applicationContext + context = applicationContext - SchemaMigration().apply { - migrateSchemaIfNeeded() - } + SchemaMigration().apply { + migrateSchemaIfNeeded() } + } + + override fun onTerminate() { + Realm.getDefaultInstance().close() + super.onTerminate() + } } diff --git a/app/src/main/kotlin/com/bodyweight/fitness/Constants.kt b/app/src/main/kotlin/com/bodyweight/fitness/Constants.kt index 73c5df77..11c6e145 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/Constants.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/Constants.kt @@ -1,28 +1,30 @@ package com.bodyweight.fitness object Constants { - val primaryKeyRoutineId = "primaryKeyRoutineId" - val exerciseId = "exerciseId" + val primaryKeyRoutineId = "primaryKeyRoutineId" + val exerciseId = "exerciseId" - val googlePlayUrl = "https://play.google.com/store/apps/details?id=com.bodyweight.fitness.pro" - val fileProvider: String by lazy { - App.context!!.getString(R.string.file_provider) - } + val googlePlayUrl = "https://play.google.com/store/apps/details?id=com.bodyweight.fitness.pro" + val fileProvider: String by lazy { + App.context!!.getString(R.string.file_provider) + } - val maximumNumberOfSets = 12 + val maximumNumberOfSets = 12 - val preferencesDefaultRoutineKey = "PREFERENCE_DEFAULT_ROUTINE" - val preferencesWeightMeasurementUnitsKey = "PREFERENCE_WEIGHT_MEASUREMENT_UNITS" - val preferencesPlaySoundWhenTimerStopsKey = "PREFERENCE_PLAY_SOUND_WHEN_TIMER_STOPS" - val preferencesAutomaticallyLogWorkoutTimeKey = "PREFERENCE_AUTOMATICALLY_LOG_WORKOUT_TIME" - val preferencesKeepScreenOnKey = "PREFERENCE_KEEP_SCREEN_ON" - val preferencesTimerKey = "PREFERENCE_TIMER_KEY_" - val preferencesNumberOfRepsKey = "PREFERENCE_NUMBER_OF_REPS_KEY_" - val preferencesExerciseIdForSection = "PREFERENCE_EXERCISE_ID_FOR_SECTION_" - val preferencesIntroductionShown = "PREFERENCE_INTRODUCTION_SHOWN" - val preferencesShowRestTimer = "PREFERENCE_SHOW_REST_TIMER" - val preferencesRestTimerDefaultSeconds = "PREFERENCE_REST_TIMER_DEFAULT_SECONDS" - val preferencesShowRestTimerAfterWarmup = "PREFERENCE_SHOW_REST_TIMER_WARMUP_EXERCISES" - val preferencesShowRestTimerAfterBodylineDrills = "PREFERENCE_SHOW_REST_TIMER_BODYLINE_DRILLS" - val preferencesShowRestTimerAfterFlexibilityExercises = "PREFERENCE_SHOW_REST_TIMER_FLEXIBILITY_ROUTINES" -} \ No newline at end of file + val preferencesDefaultRoutineKey = "PREFERENCE_DEFAULT_ROUTINE" + val preferencesWeightMeasurementUnitsKey = "PREFERENCE_WEIGHT_MEASUREMENT_UNITS" + val preferencesPlaySoundWhenTimerStopsKey = "PREFERENCE_PLAY_SOUND_WHEN_TIMER_STOPS" + val preferencesAutomaticallyLogWorkoutTimeKey = "PREFERENCE_AUTOMATICALLY_LOG_WORKOUT_TIME" + val preferencesKeepScreenOnKey = "PREFERENCE_KEEP_SCREEN_ON" + val preferencesTimerKey = "PREFERENCE_TIMER_KEY_" + val preferencesNumberOfRepsKey = "PREFERENCE_NUMBER_OF_REPS_KEY_" + val preferencesExerciseIdForSection = "PREFERENCE_EXERCISE_ID_FOR_SECTION_" + val preferencesIntroductionShown = "PREFERENCE_INTRODUCTION_SHOWN" + val preferencesShowRestTimer = "PREFERENCE_SHOW_REST_TIMER" + val preferencesRestTimerDefaultSeconds = "PREFERENCE_REST_TIMER_DEFAULT_SECONDS" + val preferencesShowRestTimerAfterWarmup = "PREFERENCE_SHOW_REST_TIMER_WARMUP_EXERCISES" + val preferencesShowRestTimerAfterBodylineDrills = "PREFERENCE_SHOW_REST_TIMER_BODYLINE_DRILLS" + val preferencesShowRestTimerAfterFlexibilityExercises = "PREFERENCE_SHOW_REST_TIMER_FLEXIBILITY_ROUTINES" + + val SchemaVersion: Long = 4 +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/adapter/ProgressListAdapter.kt b/app/src/main/kotlin/com/bodyweight/fitness/adapter/ProgressListAdapter.kt index 333148cb..d0a1063e 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/adapter/ProgressListAdapter.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/adapter/ProgressListAdapter.kt @@ -169,7 +169,7 @@ class ProgressHeaderPresenter(itemView: View) : ProgressPresenter(itemView) { } } - completionRateTabLayout.setOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { + completionRateTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab) { updateCompletionRateTitle() diff --git a/app/src/main/kotlin/com/bodyweight/fitness/model/Routine.kt b/app/src/main/kotlin/com/bodyweight/fitness/model/Routine.kt index dfe8e5a7..70b925ff 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/model/Routine.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/model/Routine.kt @@ -5,249 +5,271 @@ import java.io.Serializable import java.util.* abstract class LinkedRoutine : Serializable { - abstract val title: String - abstract val type: RoutineType + abstract val title: String + abstract val type: RoutineType } class Routine(JSONRoutine: JSONRoutine) : Serializable { - var routineId: String = "routine0" - var title: String = "" - var subtitle: String = "" - var shortDescription: String = "" - var url: String = "" - - val categories = ArrayList() - val sections = ArrayList
() - val exercises = ArrayList() - val linkedExercises = ArrayList() - val linkedRoutine = ArrayList() - - init { - routineId = JSONRoutine.routineId - title = JSONRoutine.title - subtitle = JSONRoutine.subtitle - shortDescription = JSONRoutine.shortDescription - url = JSONRoutine.url - - var currentCategory: Category? = null - var currentSection: Section? = null - var currentExercise: Exercise? = null - - for (JSONLinkedRoutine in JSONRoutine.routine) { - if (JSONLinkedRoutine.routineType === RoutineType.Category) { - currentCategory = Category(JSONLinkedRoutine.categoryId, JSONLinkedRoutine.title) - - categories.add(currentCategory) - linkedRoutine.add(currentCategory) - } else if (JSONLinkedRoutine.routineType === RoutineType.Section) { - currentSection = Section( - JSONLinkedRoutine.sectionId, - JSONLinkedRoutine.title, - JSONLinkedRoutine.description, - JSONLinkedRoutine.sectionMode) - - currentCategory!!.insertSection(currentSection) - - sections.add(currentSection) - linkedRoutine.add(currentSection) - } else if (JSONLinkedRoutine.routineType === RoutineType.Exercise) { - val exercise = Exercise( - JSONLinkedRoutine.exerciseId, - JSONLinkedRoutine.level, - JSONLinkedRoutine.title, - JSONLinkedRoutine.description, - JSONLinkedRoutine.youTubeId, - JSONLinkedRoutine.videoId, - JSONLinkedRoutine.defaultSet) - - currentSection!!.insertExercise(exercise) - - exercises.add(exercise) - - if (currentSection.sectionMode === SectionMode.Levels || currentSection.sectionMode === SectionMode.Pick) { - val currentExerciseId: String? = Preferences.getExerciseIdForSection(currentSection.sectionId) - - if (currentExerciseId != null) { - if (exercise.exerciseId.matches(currentExerciseId.toRegex())) { - linkedExercises.add(exercise) - linkedRoutine.add(exercise) - - exercise.previous = currentExercise - - if (currentExercise != null) { - currentExercise.next = exercise - } - - currentExercise = exercise - currentSection.setCurrentLevel(exercise) - } - } else { - if (currentSection.exercises.size == 1) { - linkedExercises.add(exercise) - linkedRoutine.add(exercise) - - exercise.previous = currentExercise - - if (currentExercise != null) { - currentExercise.next = exercise - } - - currentExercise = exercise - } - } - } else { - exercise.previous = currentExercise - - if (currentExercise != null) { - currentExercise.next = exercise - } - - currentExercise = exercise - - linkedExercises.add(exercise) - linkedRoutine.add(exercise) - } + var routineId: String = "routine0" + var title: String = "" + var subtitle: String = "" + var shortDescription: String = "" + var url: String = "" + + val categories = ArrayList() + val sections = ArrayList
() + val exercises = ArrayList() + val linkedExercises = ArrayList() + val linkedRoutine = ArrayList() + + init { + routineId = JSONRoutine.routineId + title = JSONRoutine.title + subtitle = JSONRoutine.subtitle + shortDescription = JSONRoutine.shortDescription + url = JSONRoutine.url + + var currentCategory: Category? = null + var currentSection: Section? = null + var currentExercise: Exercise? = null + + for (JSONLinkedRoutine in JSONRoutine.routine) { + if (JSONLinkedRoutine.routineType === RoutineType.Category) { + currentCategory = Category(JSONLinkedRoutine.categoryId, JSONLinkedRoutine.title) + + categories.add(currentCategory) + linkedRoutine.add(currentCategory) + } else if (JSONLinkedRoutine.routineType === RoutineType.Section) { + currentSection = Section( + JSONLinkedRoutine.sectionId, + JSONLinkedRoutine.title, + JSONLinkedRoutine.description, + JSONLinkedRoutine.sets, + JSONLinkedRoutine.sectionMode, + JSONLinkedRoutine.bundle) + + currentCategory!!.insertSection(currentSection) + + sections.add(currentSection) + linkedRoutine.add(currentSection) + } else if (JSONLinkedRoutine.routineType === RoutineType.Exercise) { + val exercise = Exercise( + JSONLinkedRoutine.exerciseId, + JSONLinkedRoutine.level, + JSONLinkedRoutine.title, + JSONLinkedRoutine.description, + JSONLinkedRoutine.youTubeId, + JSONLinkedRoutine.videoId, + JSONLinkedRoutine.defaultSet) + + currentSection!!.insertExercise(exercise) + + exercises.add(exercise) + + if (currentSection.sectionMode === SectionMode.Levels || currentSection.sectionMode === SectionMode.Pick) { + val currentExerciseId: String? = Preferences.getExerciseIdForSection(currentSection.sectionId) + + if (currentExerciseId != null) { + if (exercise.exerciseId.matches(currentExerciseId.toRegex())) { + linkedExercises.add(exercise) + linkedRoutine.add(exercise) + + exercise.previous = currentExercise + + if (currentExercise != null) { + currentExercise.next = exercise + } + + currentExercise = exercise + currentSection.setCurrentLevel(exercise) + } + } else { + if (currentSection.exercises.size == 1) { + linkedExercises.add(exercise) + linkedRoutine.add(exercise) + + exercise.previous = currentExercise + + if (currentExercise != null) { + currentExercise.next = exercise + } + + currentExercise = exercise } + } + } else { + exercise.previous = currentExercise + + if (currentExercise != null) { + currentExercise.next = exercise + } + + currentExercise = exercise + + linkedExercises.add(exercise) + linkedRoutine.add(exercise) } + } } + } - fun setLevel(exercise: Exercise, level: Int) { - val currentSectionExercise = exercise.section!!.currentExercise + fun setLevel(exercise: Exercise, level: Int) { + val currentSectionExercise = exercise.section!!.currentExercise - if (currentSectionExercise != exercise) { - if (currentSectionExercise.previous != null) { - currentSectionExercise.previous!!.next = exercise - } + if (currentSectionExercise != exercise) { + if (currentSectionExercise.previous != null) { + currentSectionExercise.previous!!.next = exercise + } - if (currentSectionExercise.next != null) { - currentSectionExercise.next!!.previous = exercise - } + if (currentSectionExercise.next != null) { + currentSectionExercise.next!!.previous = exercise + } - exercise.previous = currentSectionExercise.previous - exercise.next = currentSectionExercise.next + exercise.previous = currentSectionExercise.previous + exercise.next = currentSectionExercise.next - exercise.section!!.currentLevel = level + exercise.section!!.currentLevel = level - currentSectionExercise.previous = null - currentSectionExercise.next = null + currentSectionExercise.previous = null + currentSectionExercise.next = null - val indexOfCurrentExercise = linkedRoutine.indexOf(currentSectionExercise) - if (indexOfCurrentExercise > -1) { - linkedRoutine[indexOfCurrentExercise] = exercise - } + val indexOfCurrentExercise = linkedRoutine.indexOf(currentSectionExercise) + if (indexOfCurrentExercise > -1) { + linkedRoutine[indexOfCurrentExercise] = exercise + } - val indexOfLinkedExercise = linkedExercises.indexOf(currentSectionExercise) - if (indexOfLinkedExercise > -1) { - linkedExercises[indexOfLinkedExercise] = exercise - } - } + val indexOfLinkedExercise = linkedExercises.indexOf(currentSectionExercise) + if (indexOfLinkedExercise > -1) { + linkedExercises[indexOfLinkedExercise] = exercise + } } + } } class Category( - val categoryId: String, - val categoryTitle: String + val categoryId: String, + val categoryTitle: String ) : LinkedRoutine(), Serializable { - val sections = ArrayList
() + val sections = ArrayList
() - override val title: String = categoryTitle - override val type: RoutineType = RoutineType.Category + override val title: String = categoryTitle + override val type: RoutineType = RoutineType.Category - fun insertSection(section: Section) { - section.category = this + fun insertSection(section: Section) { + section.category = this - sections.add(section) - } + sections.add(section) + } } class Section( - val sectionId: String, - val sectionTitle: String, - val description: String, - val sectionMode: SectionMode) : LinkedRoutine(), Serializable { - - var category: Category? = null - var currentLevel = 0 - set(level) { - if (sectionMode == SectionMode.Levels || sectionMode == SectionMode.Pick) { - if (level < 0 || level >= exercises.size) { - return - } - - field = level - } + val sectionId: String, + val sectionTitle: String, + val description: String, + val sets: Number, + val sectionMode: SectionMode, + val bundle: Number) : LinkedRoutine(), Serializable { + + var category: Category? = null + var currentLevel = 0 + set(level) { + if (sectionMode == SectionMode.Levels || sectionMode == SectionMode.Pick) { + if (level < 0 || level >= exercises.size) { + return } - val exercises = ArrayList() + field = level + } + } - override val title: String - get() = sectionTitle + val exercises = ArrayList() - override val type: RoutineType - get() = RoutineType.Section + override val title: String + get() = sectionTitle - fun setCurrentLevel(exercise: Exercise) { - var current = 0 - for (ex in exercises) { - if (ex == exercise) { - currentLevel = current - return - } + override val type: RoutineType + get() = RoutineType.Section - current++ - } + fun setCurrentLevel(exercise: Exercise) { + var current = 0 + for (ex in exercises) { + if (ex == exercise) { + currentLevel = current + return + } + + current++ + } + } + + val availableLevels: Int + get() { + if (sectionMode == SectionMode.Levels || sectionMode == SectionMode.Pick) { + return exercises.size + } else { + return 0 + } } - val availableLevels: Int - get() { - if (sectionMode == SectionMode.Levels || sectionMode == SectionMode.Pick) { - return exercises.size - } else { - return 0 - } - } + fun insertExercise(exercise: Exercise) { + exercise.category = category + exercise.section = this - fun insertExercise(exercise: Exercise) { - exercise.category = category - exercise.section = this + exercises.add(exercise) + } - exercises.add(exercise) + val currentExercise: Exercise + get() = exercises[currentLevel] + + val bundledExercise: Exercise? + get() { + val section = bundledSection + + return section?.currentExercise } - val currentExercise: Exercise - get() = exercises[currentLevel] + val bundledSection: Section? + get() { + var bundledSection: Section? = null + + if (bundle.toInt() > 0) { + bundledSection = category!!.sections.find { it.bundle == bundle && it.sectionId !== sectionId } + } + + return bundledSection + } } class Exercise( - val exerciseId: String, - val level: String, - val exerciseTitle: String, - val description: String, - val youTubeId: String, - val videoId: String, - val defaultSet: String) : LinkedRoutine(), Serializable { + val exerciseId: String, + val level: String, + val exerciseTitle: String, + val description: String, + val youTubeId: String, + val videoId: String, + val defaultSet: String) : LinkedRoutine(), Serializable { - var category: Category? = null - var section: Section? = null + var category: Category? = null + var section: Section? = null - var previous: Exercise? = null - var next: Exercise? = null + var previous: Exercise? = null + var next: Exercise? = null - override val title: String - get() = exerciseTitle + override val title: String + get() = exerciseTitle - override val type: RoutineType - get() = RoutineType.Exercise + override val type: RoutineType + get() = RoutineType.Exercise - val isTimedSet: Boolean - get() = defaultSet.equals("timed", ignoreCase = true) + val isTimedSet: Boolean + get() = defaultSet.equals("timed", ignoreCase = true) - val hasProgressions: Boolean - get() = section?.sectionMode != SectionMode.All + val hasProgressions: Boolean + get() = section?.sectionMode != SectionMode.All - val isPrevious: Boolean - get() = previous != null + val isPrevious: Boolean + get() = previous != null - val isNext: Boolean - get() = next != null -} \ No newline at end of file + val isNext: Boolean + get() = next != null +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineJson.kt b/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineJson.kt index f5b4b784..a232c7fd 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineJson.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineJson.kt @@ -3,50 +3,52 @@ package com.bodyweight.fitness.model import java.util.ArrayList class JSONRoutine { - var routineId: String = "" - var title: String = "" - var subtitle: String = "" - var shortDescription: String = "" - var url: String = "" - var routine = ArrayList() - - val size: Int by lazy { - routine.size - } + var routineId: String = "" + var title: String = "" + var subtitle: String = "" + var shortDescription: String = "" + var url: String = "" + var routine = ArrayList() + + val size: Int by lazy { + routine.size + } } class JSONLinkedRoutine { - var categoryId: String = "" - var sectionId: String = "" - var exerciseId: String = "" - var level: String = "" - var title: String = "" - var description: String = "" - var youTubeId: String = "" - var videoId: String = "" - - private var type: String = "" - private var mode: String = "" - - var defaultSet: String = "" - - val routineType: RoutineType by lazy { - if (type.equals("category")) { - RoutineType.Category - } else if (type.equals("section")) { - RoutineType.Section - } else { - RoutineType.Exercise - } + var categoryId: String = "" + var sectionId: String = "" + var exerciseId: String = "" + var bundle: Number = 0 + var sets: Number = 1 + var level: String = "" + var title: String = "" + var description: String = "" + var youTubeId: String = "" + var videoId: String = "" + + private var type: String = "" + private var mode: String = "" + + var defaultSet: String = "" + + val routineType: RoutineType by lazy { + if (type.equals("category")) { + RoutineType.Category + } else if (type.equals("section")) { + RoutineType.Section + } else { + RoutineType.Exercise } - - val sectionMode: SectionMode by lazy { - if (mode.equals("all")) { - SectionMode.All - } else if (mode.equals("pick")) { - SectionMode.Pick - } else { - SectionMode.Levels - } + } + + val sectionMode: SectionMode by lazy { + if (mode.equals("all")) { + SectionMode.All + } else if (mode.equals("pick")) { + SectionMode.Pick + } else { + SectionMode.Levels } + } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineRepository.kt b/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineRepository.kt index e170cf44..b95dde12 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineRepository.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/model/RoutineRepository.kt @@ -20,276 +20,279 @@ import org.joda.time.format.PeriodFormatterBuilder import java.util.* open class RepositoryRoutine( - @PrimaryKey @Required - open var id: String = "", + @PrimaryKey @Required + open var id: String = "", - @Index - open var routineId: String = "routine0", + @Index + open var routineId: String = "routine0", - open var title: String = "", - open var subtitle: String = "", + open var title: String = "", + open var subtitle: String = "", - @Index - open var startTime: Date = Date(), + @Index + open var startTime: Date = Date(), - @Index - open var lastUpdatedTime: Date = Date(), + @Index + open var lastUpdatedTime: Date = Date(), - open var categories: RealmList = RealmList(), - open var sections: RealmList = RealmList(), - open var exercises: RealmList = RealmList() + open var categories: RealmList = RealmList(), + open var sections: RealmList = RealmList(), + open var exercises: RealmList = RealmList() ) : RealmObject() { - companion object { - fun setLastUpdatedTime(repositoryRoutine: RepositoryRoutine, isNestedTransaction: Boolean) { - val now = DateTime.now() - - val startTime = DateTime(repositoryRoutine.startTime) - val lastUpdatedTime = DateTime(repositoryRoutine.lastUpdatedTime) - - /** - * Set last updated time only if it's the same day. - * Set last updated time only if the difference in minutes is less than 180. - */ - if (Days.daysBetween(startTime.toLocalDate(), now.toLocalDate()).days == 0) { - if (Minutes.minutesBetween(startTime.toLocalDate(), lastUpdatedTime.toLocalDate()).minutes < 180) { - if (isNestedTransaction) { - repositoryRoutine.lastUpdatedTime = DateTime().toDate() - } else { - Repository.realm.executeTransaction { - repositoryRoutine.lastUpdatedTime = DateTime().toDate() - } - } - } + companion object { + fun setLastUpdatedTime(repositoryRoutine: RepositoryRoutine, isNestedTransaction: Boolean) { + val now = DateTime.now() + + val startTime = DateTime(repositoryRoutine.startTime) + val lastUpdatedTime = DateTime(repositoryRoutine.lastUpdatedTime) + + /** + * Set last updated time only if it's the same day. + * Set last updated time only if the difference in minutes is less than 180. + */ + if (Days.daysBetween(startTime.toLocalDate(), now.toLocalDate()).days == 0) { + if (Minutes.minutesBetween(startTime.toLocalDate(), lastUpdatedTime.toLocalDate()).minutes < 180) { + if (isNestedTransaction) { + repositoryRoutine.lastUpdatedTime = DateTime().toDate() + } else { + Repository.realm.executeTransaction { + repositoryRoutine.lastUpdatedTime = DateTime().toDate() } + } } + } + } - fun getStartTime(repositoryRoutine: RepositoryRoutine): String { - return DateTime(repositoryRoutine.startTime) - .toString("HH:mm", Locale.ENGLISH) - } + fun getStartTime(repositoryRoutine: RepositoryRoutine): String { + return DateTime(repositoryRoutine.startTime) + .toString("HH:mm", Locale.ENGLISH) + } - fun getLastUpdatedTime(repositoryRoutine: RepositoryRoutine): String { - return DateTime(repositoryRoutine.lastUpdatedTime) - .toString("HH:mm", Locale.ENGLISH) - } + fun getLastUpdatedTime(repositoryRoutine: RepositoryRoutine): String { + return DateTime(repositoryRoutine.lastUpdatedTime) + .toString("HH:mm", Locale.ENGLISH) + } - fun getWorkoutLength(repositoryRoutine: RepositoryRoutine): String { - val duration = Duration( - DateTime(repositoryRoutine.startTime), - DateTime(repositoryRoutine.lastUpdatedTime)) - - val formatter = PeriodFormatterBuilder() - .appendHours() - .appendSuffix("h ") - .appendMinutes() - .appendSuffix("m") - .toFormatter() - .print(duration.toPeriod()) - - if (formatter.replace(" ", "").equals("")) { - return "--" - } else { - return formatter - } - } + fun getWorkoutLength(repositoryRoutine: RepositoryRoutine): String { + val duration = Duration( + DateTime(repositoryRoutine.startTime), + DateTime(repositoryRoutine.lastUpdatedTime)) + + val formatter = PeriodFormatterBuilder() + .appendHours() + .appendSuffix("h ") + .appendMinutes() + .appendSuffix("m") + .toFormatter() + .print(duration.toPeriod()) + + if (formatter.replace(" ", "").equals("")) { + return "--" + } else { + return formatter + } + } - fun getWorkoutLengthInMinutes(repositoryRoutine: RepositoryRoutine): Int { - return Duration( - DateTime(repositoryRoutine.startTime), - DateTime(repositoryRoutine.lastUpdatedTime) - ).toStandardMinutes().minutes - } + fun getWorkoutLengthInMinutes(repositoryRoutine: RepositoryRoutine): Int { + return Duration( + DateTime(repositoryRoutine.startTime), + DateTime(repositoryRoutine.lastUpdatedTime) + ).toStandardMinutes().minutes + } - fun getVisibleAndCompletedExercises(exercises: List): List { - return exercises.filter { - it.visible || RepositoryExercise.isCompleted(it) - } - } + fun getVisibleAndCompletedExercises(exercises: List): List { + return exercises.filter { + it.visible || RepositoryExercise.isCompleted(it) + } + } - fun getNumberOfExercises(exercises: List): Int { - return getVisibleAndCompletedExercises(exercises).count() - } + fun getNumberOfExercises(exercises: List): Int { + return getVisibleAndCompletedExercises(exercises).count() + } - fun getNumberOfCompletedExercises(exercises: List): Int { - return exercises.filter { - RepositoryExercise.isCompleted(it) - }.count() - } + fun getNumberOfCompletedExercises(exercises: List): Int { + return exercises.filter { + RepositoryExercise.isCompleted(it) + }.count() + } - fun getMissedExercises(exercises: List): List { - return exercises.filter { - it.visible && !RepositoryExercise.isCompleted(it) - } - } + fun getMissedExercises(exercises: List): List { + return exercises.filter { + it.visible && !RepositoryExercise.isCompleted(it) + } + } - fun getCompletionRate(repositoryRoutine: RepositoryRoutine): CompletionRate { - val exercises = getVisibleAndCompletedExercises(repositoryRoutine.exercises) + fun getCompletionRate(repositoryRoutine: RepositoryRoutine): CompletionRate { + val exercises = getVisibleAndCompletedExercises(repositoryRoutine.exercises) - val numberOfExercises: Int = getNumberOfExercises(exercises) - val numberOfCompletedExercises: Int = getNumberOfCompletedExercises(exercises) + val numberOfExercises: Int = getNumberOfExercises(exercises) + val numberOfCompletedExercises: Int = getNumberOfCompletedExercises(exercises) - if (numberOfExercises == 0) { - return CompletionRate(0, "0%") - } + if (numberOfExercises == 0) { + return CompletionRate(0, "0%") + } - val completionRate = numberOfCompletedExercises * 100 / numberOfExercises + val completionRate = numberOfCompletedExercises * 100 / numberOfExercises - return CompletionRate(completionRate, "$completionRate%") - } + return CompletionRate(completionRate, "$completionRate%") + } - fun getTitleWithDate(repositoryRoutine: RepositoryRoutine): String { - val date = DateTime(repositoryRoutine.startTime).toString("EEEE, d MMMM YYYY - HH:mm") + fun getTitleWithDate(repositoryRoutine: RepositoryRoutine): String { + val date = DateTime(repositoryRoutine.startTime).toString("EEEE, d MMMM YYYY - HH:mm") - return "${repositoryRoutine.title} - ${repositoryRoutine.subtitle} - $date." - } + return "${repositoryRoutine.title} - ${repositoryRoutine.subtitle} - $date." + } - fun toText(repositoryRoutine: RepositoryRoutine): String { - val startTime = DateTime(repositoryRoutine.startTime).toString("EEEE, d MMMM YYYY - HH:mm") - val lastUpdatedTime = RepositoryRoutine.getLastUpdatedTime(repositoryRoutine) - val workoutLength = RepositoryRoutine.getWorkoutLength(repositoryRoutine) - val weightUnit = Preferences.weightMeasurementUnit.toString() - - var content = "Hello, The following is your workout in Text/HTML format (CSV attached)." - - content += "\n\nWorkout on $startTime." - content += "\nLast Updated at $lastUpdatedTime." - content += "\nWorkout length: $workoutLength" - content += "\n\n${repositoryRoutine.title} - ${repositoryRoutine.subtitle}" - - for (exercise in RepositoryRoutine.getVisibleAndCompletedExercises(repositoryRoutine.exercises)) { - content += "\n\n${exercise.title}" - - for ((index, set) in exercise.sets.withIndex()) { - content += "\nSet ${index + 1}" - - if (set.isTimed) { - content += "\nMinutes: ${set.seconds.formatMinutes(false)}" - content += "\nSeconds: ${set.seconds.formatSeconds(false)}" - } else { - content += "\nReps: ${set.reps}" - content += "\nWeight: ${set.weight} $weightUnit" - } - } - } + fun toText(repositoryRoutine: RepositoryRoutine): String { + val startTime = DateTime(repositoryRoutine.startTime).toString("EEEE, d MMMM YYYY - HH:mm") + val lastUpdatedTime = RepositoryRoutine.getLastUpdatedTime(repositoryRoutine) + val workoutLength = RepositoryRoutine.getWorkoutLength(repositoryRoutine) + val weightUnit = Preferences.weightMeasurementUnit.toString() + + var content = "Hello, The following is your workout in Text/HTML format (CSV attached)." + + content += "\n\nWorkout on $startTime." + content += "\nLast Updated at $lastUpdatedTime." + content += "\nWorkout length: $workoutLength" + content += "\n\n${repositoryRoutine.title} - ${repositoryRoutine.subtitle}" + + for (exercise in RepositoryRoutine.getVisibleAndCompletedExercises(repositoryRoutine.exercises)) { + content += "\n\n${exercise.title}" - return content + for ((index, set) in exercise.sets.withIndex()) { + content += "\nSet ${index + 1}" + + if (set.isTimed) { + content += "\nMinutes: ${set.seconds.formatMinutes(false)}" + content += "\nSeconds: ${set.seconds.formatSeconds(false)}" + } else { + content += "\nReps: ${set.reps}" + content += "\nWeight: ${set.weight} $weightUnit" + } } + } - fun toCSV(repositoryRoutine: RepositoryRoutine): String { - val date = DateTime(repositoryRoutine.startTime).toString("d MMMM YYYY") - val startTime = getStartTime(repositoryRoutine) - val lastUpdatedTime = getLastUpdatedTime(repositoryRoutine) - val workoutLength = getWorkoutLength(repositoryRoutine) - val routineTitle = "${repositoryRoutine.title} - ${repositoryRoutine.subtitle}" - val weightUnit = Preferences.weightMeasurementUnit.toString() + return content + } - var content = "Date, Start Time, End Time, Workout Length, Routine, Exercise, Set Order, Reps, Weight, Minutes, Seconds\n" + fun toCSV(repositoryRoutine: RepositoryRoutine): String { + val date = DateTime(repositoryRoutine.startTime).toString("d MMMM YYYY") + val startTime = getStartTime(repositoryRoutine) + val lastUpdatedTime = getLastUpdatedTime(repositoryRoutine) + val workoutLength = getWorkoutLength(repositoryRoutine) + val routineTitle = "${repositoryRoutine.title} - ${repositoryRoutine.subtitle}" + val weightUnit = Preferences.weightMeasurementUnit.toString() - for (exercise in getVisibleAndCompletedExercises(repositoryRoutine.exercises)) { - for ((index, set) in exercise.sets.withIndex()) { - content += "$date,$startTime,$lastUpdatedTime,$workoutLength,$routineTitle,${exercise.title},${index + 1},${set.reps},${set.weight} $weightUnit,${set.seconds.formatMinutes(false)},${set.seconds.formatSeconds(false)}\n" - } - } + var content = "Date, Start Time, End Time, Workout Length, Routine, Exercise, Set Order, Reps, Weight, Minutes, Seconds\n" - return content + for (exercise in getVisibleAndCompletedExercises(repositoryRoutine.exercises)) { + for ((index, set) in exercise.sets.withIndex()) { + content += "$date,$startTime,$lastUpdatedTime,$workoutLength,$routineTitle,${exercise.title},${index + 1},${set.reps},${set.weight} $weightUnit,${set.seconds.formatMinutes(false)},${set.seconds.formatSeconds(false)}\n" } + } + + return content } + } } open class RepositoryCategory( - @PrimaryKey @Required - open var id: String = "", + @PrimaryKey @Required + open var id: String = "", - @Index - open var categoryId: String = "", + @Index + open var categoryId: String = "", - open var title: String = "", + open var title: String = "", - open var routine: RepositoryRoutine? = null, + open var routine: RepositoryRoutine? = null, - open var sections: RealmList = RealmList(), - open var exercises: RealmList = RealmList() + open var sections: RealmList = RealmList(), + open var exercises: RealmList = RealmList(), + open var bundle: Int? = null ) : RealmObject() { - companion object { - fun getCompletionRate(repositoryCategory: RepositoryCategory): CompletionRate { - val exercises = RepositoryRoutine.getVisibleAndCompletedExercises(repositoryCategory.exercises) + companion object { + fun getCompletionRate(repositoryCategory: RepositoryCategory): CompletionRate { + val exercises = RepositoryRoutine.getVisibleAndCompletedExercises(repositoryCategory.exercises) - val numberOfExercises: Int = RepositoryRoutine.getNumberOfExercises(exercises) - val numberOfCompletedExercises: Int = RepositoryRoutine.getNumberOfCompletedExercises(exercises) + val numberOfExercises: Int = RepositoryRoutine.getNumberOfExercises(exercises) + val numberOfCompletedExercises: Int = RepositoryRoutine.getNumberOfCompletedExercises(exercises) - if (numberOfExercises == 0) { - return CompletionRate(0, "0%") - } + if (numberOfExercises == 0) { + return CompletionRate(0, "0%") + } - val completionRate = numberOfCompletedExercises * 100 / numberOfExercises + val completionRate = numberOfCompletedExercises * 100 / numberOfExercises - return CompletionRate(completionRate, "$completionRate%") - } + return CompletionRate(completionRate, "$completionRate%") } + } } open class RepositorySection( - @PrimaryKey @Required - open var id: String = "", + @PrimaryKey @Required + open var id: String = "", - @Index - open var sectionId: String = "", + @Index + open var sectionId: String = "", - open var title: String = "", - open var mode: String = "", + open var title: String = "", + open var mode: String = "", - open var routine: RepositoryRoutine? = null, - open var category: RepositoryCategory? = null, + open var routine: RepositoryRoutine? = null, + open var category: RepositoryCategory? = null, - open var exercises: RealmList = RealmList() + open var exercises: RealmList = RealmList(), + open var bundle: Int = 0, + open var sets: Int = 1 ) : RealmObject() {} open class RepositoryExercise( - @PrimaryKey @Required - open var id: String = "", + @PrimaryKey @Required + open var id: String = "", - @Index open var exerciseId: String = "", + @Index open var exerciseId: String = "", - open var title: String = "", - open var description: String = "", - open var defaultSet: String = "timed", + open var title: String = "", + open var description: String = "", + open var defaultSet: String = "timed", - open var visible: Boolean = false, + open var visible: Boolean = false, - open var routine: RepositoryRoutine? = null, - open var category: RepositoryCategory? = null, - open var section: RepositorySection? = null, + open var routine: RepositoryRoutine? = null, + open var category: RepositoryCategory? = null, + open var section: RepositorySection? = null, - open var sets: RealmList = RealmList() + open var sets: RealmList = RealmList() ) : RealmObject() { - companion object { - fun isCompleted(repositoryExercise: RepositoryExercise): Boolean { - val size = repositoryExercise.sets.size + companion object { + fun isCompleted(repositoryExercise: RepositoryExercise): Boolean { + val size = repositoryExercise.sets.size - if (size == 0) { - return false - } + if (size == 0) { + return false + } - val firstSet = repositoryExercise.sets[0] + val firstSet = repositoryExercise.sets[0] - if (size == 1 && firstSet.seconds == 0 && firstSet.reps == 0) { - return false - } + if (size == 1 && firstSet.seconds == 0 && firstSet.reps == 0) { + return false + } - return true - } + return true } + } } open class RepositorySet( - @PrimaryKey @Required - open var id: String = "", + @PrimaryKey @Required + open var id: String = "", - open var isTimed: Boolean = false, + open var isTimed: Boolean = false, - open var weight: Double = 0.0, - open var reps: Int = 0, - open var seconds: Int = 0, + open var weight: Double = 0.0, + open var reps: Int = 0, + open var seconds: Int = 0, - open var exercise: RepositoryExercise? = null + open var exercise: RepositoryExercise? = null ) : RealmObject() {} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/repository/Repository.kt b/app/src/main/kotlin/com/bodyweight/fitness/repository/Repository.kt index 5c59dabe..5f49c5cb 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/repository/Repository.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/repository/Repository.kt @@ -5,6 +5,7 @@ import org.joda.time.DateTime import java.util.UUID import com.bodyweight.fitness.App +import com.bodyweight.fitness.Constants import com.bodyweight.fitness.model.* import com.bodyweight.fitness.stream.RoutineStream @@ -14,154 +15,164 @@ import io.realm.Realm import io.realm.RealmConfiguration object Repository { - private val realmName = "bodyweight.fitness.realm" - - val realm: Realm - get() { - Realm.init(App.context) - - val configuration = RealmConfiguration.Builder() - .name(realmName) - .schemaVersion(2) - .migration { realm: DynamicRealm, oldVersion: Long, newVersion: Long -> - val schema = realm.schema - val routineSchema = schema.get("RepositoryRoutine") - - if (oldVersion.toInt() == 1) { - routineSchema - .addField("title", String::class.java) - .addField("subtitle", String::class.java) - .transform { obj: DynamicRealmObject -> - obj.set("title", "Bodyweight Fitness") - obj.set("subtitle", "Recommended Routine") - } - } - } - .build() - - return Realm.getInstance(configuration) + private val realmName = "bodyweight.fitness.realm" + + val realm: Realm + get() { + Realm.init(App.context) + + val configuration = RealmConfiguration.Builder() + .name(realmName) + .schemaVersion(Constants.SchemaVersion) + .migration { realm: DynamicRealm, oldVersion: Long, newVersion: Long -> + val schema = realm.schema + val routineSchema = schema.get("RepositoryRoutine") + val sectionSchema = schema.get("Section") + val exerciseSchema = schema.get("Exercise") + + if (oldVersion.toInt() == 1) { + routineSchema + .addField("title", String::class.java) + .addField("subtitle", String::class.java) + .transform { obj: DynamicRealmObject -> + obj.set("title", "Bodyweight Fitness") + obj.set("subtitle", "Recommended Routine") + } + } + + if (oldVersion.toInt() == 3) { + sectionSchema + .addField("bundle", Int::class.java) + .addField("sets", Int::class.java) + } } + .build() - fun buildRealmRoutine(routine: Routine): RepositoryRoutine { - var repositoryRoutine: RepositoryRoutine? = null - - realm.executeTransaction { - repositoryRoutine = realm.createObject(RepositoryRoutine::class.java, "Routine-" + UUID.randomUUID().toString()) - repositoryRoutine?.let { - it.routineId = routine.routineId - it.title = routine.title - it.subtitle = routine.subtitle - it.startTime = DateTime().toDate() - it.lastUpdatedTime = DateTime().toDate() - - var repositoryCategory: RepositoryCategory? = null - var repositorySection: RepositorySection? = null - - for (exercise in routine.exercises) { - val repositoryExercise = realm.createObject(RepositoryExercise::class.java, "Exercise-" + UUID.randomUUID().toString()) - repositoryExercise.exerciseId = exercise.exerciseId - repositoryExercise.title = exercise.title - repositoryExercise.description = exercise.description - repositoryExercise.defaultSet = exercise.defaultSet - - val repositorySetId = "Set-" + UUID.randomUUID().toString() - val repositorySet = realm.createObject(RepositorySet::class.java, repositorySetId) - - if (exercise.defaultSet == "weighted") { - repositorySet.isTimed = false - } else { - repositorySet.isTimed = true - } - - repositorySet.seconds = 0 - repositorySet.weight = 0.0 - repositorySet.reps = 0 - repositorySet.exercise = repositoryExercise - - repositoryExercise.sets.add(repositorySet) - - if (repositoryCategory == null || !repositoryCategory.title.equals(exercise.category!!.title, ignoreCase = true)) { - repositoryCategory = realm.createObject(RepositoryCategory::class.java, "Category-" + UUID.randomUUID().toString()) - repositoryCategory.categoryId = exercise.category!!.categoryId - repositoryCategory.title = exercise.category!!.title - repositoryCategory.routine = repositoryRoutine - - it.categories.add(repositoryCategory) - } - - if (repositorySection == null || !repositorySection.title.equals(exercise.section!!.title, ignoreCase = true)) { - repositorySection = realm.createObject(RepositorySection::class.java, "Section-" + UUID.randomUUID().toString()) - repositorySection.sectionId = exercise.section!!.sectionId - repositorySection.title = exercise.section!!.title - repositorySection.mode = exercise.section!!.sectionMode.toString() - repositorySection.routine = repositoryRoutine - repositorySection.category = repositoryCategory - - it.sections.add(repositorySection) - repositoryCategory!!.sections.add(repositorySection) - } - - repositoryExercise.routine = repositoryRoutine - repositoryExercise.category = repositoryCategory - repositoryExercise.section = repositorySection - - /** - * Hide exercises not relevant to user level. - */ - if (exercise.section!!.sectionMode == SectionMode.Levels || exercise.section!!.sectionMode == SectionMode.Pick) { - if (exercise == exercise.section!!.currentExercise) { - repositoryExercise.visible = true - } else { - repositoryExercise.visible = false - } - } else { - repositoryExercise.visible = true - } - - it.exercises.add(repositoryExercise) - repositoryCategory!!.exercises.add(repositoryExercise) - repositorySection!!.exercises.add(repositoryExercise) - } + return Realm.getInstance(configuration) + } + + fun buildRealmRoutine(routine: Routine): RepositoryRoutine { + var repositoryRoutine: RepositoryRoutine? = null + + realm.executeTransaction { + repositoryRoutine = realm.createObject(RepositoryRoutine::class.java, "Routine-" + UUID.randomUUID().toString()) + repositoryRoutine?.let { + it.routineId = routine.routineId + it.title = routine.title + it.subtitle = routine.subtitle + it.startTime = DateTime().toDate() + it.lastUpdatedTime = DateTime().toDate() + + var repositoryCategory: RepositoryCategory? = null + var repositorySection: RepositorySection? = null + + for (exercise in routine.exercises) { + val repositoryExercise = realm.createObject(RepositoryExercise::class.java, "Exercise-" + UUID.randomUUID().toString()) + repositoryExercise.exerciseId = exercise.exerciseId + repositoryExercise.title = exercise.title + repositoryExercise.description = exercise.description + repositoryExercise.defaultSet = exercise.defaultSet + + val repositorySetId = "Set-" + UUID.randomUUID().toString() + val repositorySet = realm.createObject(RepositorySet::class.java, repositorySetId) + + if (exercise.defaultSet == "weighted") { + repositorySet.isTimed = false + } else { + repositorySet.isTimed = true + } + + repositorySet.seconds = 0 + repositorySet.weight = 0.0 + repositorySet.reps = 0 + repositorySet.exercise = repositoryExercise + + repositoryExercise.sets.add(repositorySet) + + if (repositoryCategory == null || !repositoryCategory.title.equals(exercise.category!!.title, ignoreCase = true)) { + repositoryCategory = realm.createObject(RepositoryCategory::class.java, "Category-" + UUID.randomUUID().toString()) + repositoryCategory.categoryId = exercise.category!!.categoryId + repositoryCategory.title = exercise.category!!.title + repositoryCategory.routine = repositoryRoutine + repositoryCategory.bundle = null + + it.categories.add(repositoryCategory) + } + + if (repositorySection == null || !repositorySection.title.equals(exercise.section!!.title, ignoreCase = true)) { + repositorySection = realm.createObject(RepositorySection::class.java, "Section-" + UUID.randomUUID().toString()) + repositorySection.sectionId = exercise.section!!.sectionId + repositorySection.title = exercise.section!!.title + repositorySection.mode = exercise.section!!.sectionMode.toString() + repositorySection.routine = repositoryRoutine + repositorySection.category = repositoryCategory + repositorySection.sets = Constants.maximumNumberOfSets + + it.sections.add(repositorySection) + repositoryCategory!!.sections.add(repositorySection) + } + + repositoryExercise.routine = repositoryRoutine + repositoryExercise.category = repositoryCategory + repositoryExercise.section = repositorySection + + /** + * Hide exercises not relevant to user level. + */ + if (exercise.section!!.sectionMode == SectionMode.Levels || exercise.section!!.sectionMode == SectionMode.Pick) { + if (exercise == exercise.section!!.currentExercise) { + repositoryExercise.visible = true + } else { + repositoryExercise.visible = false } - } + } else { + repositoryExercise.visible = true + } - return repositoryRoutine!! + it.exercises.add(repositoryExercise) + repositoryCategory!!.exercises.add(repositoryExercise) + repositorySection!!.exercises.add(repositoryExercise) + } + } } - fun getRepositoryRoutineForPrimaryKeyRoutineId(primaryKeyRoutineId: String): RepositoryRoutine { - return realm.where(RepositoryRoutine::class.java).equalTo("id", primaryKeyRoutineId).findFirst() - } + return repositoryRoutine!! + } - val repositoryRoutineForToday: RepositoryRoutine - get() { - val start = DateTime().withTimeAtStartOfDay().toDate() - val end = DateTime().withTimeAtStartOfDay().plusDays(1).minusSeconds(1).toDate() + fun getRepositoryRoutineForPrimaryKeyRoutineId(primaryKeyRoutineId: String): RepositoryRoutine { + return realm.where(RepositoryRoutine::class.java).equalTo("id", primaryKeyRoutineId).findFirst() + } - val routineId = RoutineStream.routine.routineId + val repositoryRoutineForToday: RepositoryRoutine + get() { + val start = DateTime().withTimeAtStartOfDay().toDate() + val end = DateTime().withTimeAtStartOfDay().plusDays(1).minusSeconds(1).toDate() - var repositoryRoutine: RepositoryRoutine? = realm.where(RepositoryRoutine::class.java) - .between("startTime", start, end) - .equalTo("routineId", routineId) - .findFirst() + val routineId = RoutineStream.routine.routineId - if (repositoryRoutine == null) { - repositoryRoutine = buildRealmRoutine(RoutineStream.routine) - } + var repositoryRoutine: RepositoryRoutine? = realm.where(RepositoryRoutine::class.java) + .between("startTime", start, end) + .equalTo("routineId", routineId) + .findFirst() - return repositoryRoutine - } + if (repositoryRoutine == null) { + repositoryRoutine = buildRealmRoutine(RoutineStream.routine) + } - fun repositoryRoutineForTodayExists(): Boolean { - val start = DateTime().withTimeAtStartOfDay().toDate() - val end = DateTime().withTimeAtStartOfDay().plusDays(1).minusSeconds(1).toDate() + return repositoryRoutine + } - val routineId = RoutineStream.routine.routineId + fun repositoryRoutineForTodayExists(): Boolean { + val start = DateTime().withTimeAtStartOfDay().toDate() + val end = DateTime().withTimeAtStartOfDay().plusDays(1).minusSeconds(1).toDate() - realm.where(RepositoryRoutine::class.java) - .between("startTime", start, end) - .equalTo("routineId", routineId) - .findFirst() ?: return false + val routineId = RoutineStream.routine.routineId - return true - } + realm.where(RepositoryRoutine::class.java) + .between("startTime", start, end) + .equalTo("routineId", routineId) + .findFirst() ?: return false + + return true + } } diff --git a/app/src/main/kotlin/com/bodyweight/fitness/repository/SchemaMigration.kt b/app/src/main/kotlin/com/bodyweight/fitness/repository/SchemaMigration.kt index ebb7acb3..a7f875d8 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/repository/SchemaMigration.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/repository/SchemaMigration.kt @@ -5,55 +5,63 @@ import com.bodyweight.fitness.model.RepositoryRoutine import com.bodyweight.fitness.stream.RoutineStream class SchemaMigration { - fun migrateSchemaIfNeeded() { - if (Repository.repositoryRoutineForTodayExists()) { - val routine = RoutineStream.routine - val currentSchema = Repository.repositoryRoutineForToday - migrateSchemaIfNeeded(routine, currentSchema) - } - } - - private fun migrateSchemaIfNeeded(routine: Routine, currentSchema: RepositoryRoutine) { - if (!(isValidSchema(routine, currentSchema))) { - val newSchema = Repository.buildRealmRoutine(routine) + fun migrateSchemaIfNeeded() { + if (Repository.repositoryRoutineForTodayExists()) { + val routine = RoutineStream.routine + val currentSchema = Repository.repositoryRoutineForToday - val realm = Repository.realm + migrateSchemaIfNeeded(routine, currentSchema) + } + } - realm.executeTransaction { - newSchema.startTime = currentSchema.startTime - newSchema.lastUpdatedTime = currentSchema.lastUpdatedTime + private fun migrateSchemaIfNeeded(routine: Routine, currentSchema: RepositoryRoutine) { + if (!(isValidSchema(routine, currentSchema))) { + val newSchema = Repository.buildRealmRoutine(routine) - for (exercise in newSchema.exercises) { - val currentExercise = currentSchema.exercises.filter { - it.exerciseId == exercise.exerciseId - }.firstOrNull() + val realm = Repository.realm - if (currentExercise != null) { - exercise.sets.removeAll { true } + realm.executeTransaction { + newSchema.startTime = currentSchema.startTime + newSchema.lastUpdatedTime = currentSchema.lastUpdatedTime - for (set in currentExercise.sets) { - exercise.sets.add(set) - } - } - } + for (exercise in newSchema.exercises) { + val currentExercise = currentSchema.exercises.filter { + it.exerciseId == exercise.exerciseId + }.firstOrNull() - currentSchema.deleteFromRealm() + if (currentExercise != null) { + exercise.sets.removeAll { true } - realm.copyToRealmOrUpdate(newSchema) + for (set in currentExercise.sets) { + exercise.sets.add(set) } + } } + + currentSchema.deleteFromRealm() + realm.copyToRealmOrUpdate(newSchema) + } } + } - private fun isValidSchema(routine: Routine, currentSchema: RepositoryRoutine): Boolean { - for (exercise in routine.exercises) { - val contains = currentSchema.exercises.filter { - it.exerciseId == exercise.exerciseId - }.firstOrNull() + private fun isValidSchema(routine: Routine, currentSchema: RepositoryRoutine): Boolean { + for (section in routine.sections) { + val contains = currentSchema.sections.filter { + it.sectionId == section.sectionId + }.firstOrNull() - contains ?: return false - } + contains ?: return false + } - return true + for (exercise in routine.exercises) { + val contains = currentSchema.exercises.filter { + it.exerciseId == exercise.exerciseId + }.firstOrNull() + + contains ?: return false } -} \ No newline at end of file + + return true + } +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/stream/RoutineStream.kt b/app/src/main/kotlin/com/bodyweight/fitness/stream/RoutineStream.kt index d8fea7ae..62a1d4a7 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/stream/RoutineStream.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/stream/RoutineStream.kt @@ -19,90 +19,89 @@ import rx.android.schedulers.AndroidSchedulers import rx.subjects.PublishSubject class JsonRoutineLoader { - fun getRoutine(resource: Int): Routine { - try { - val raw = IOUtils.toString(App.context!!.resources.openRawResource(resource)) - val jsonRoutine = Gson().fromJson(raw, JSONRoutine::class.java) - - return Routine(jsonRoutine) - } catch (e: IOException) { - error(e.message.toString()) - } + fun getRoutine(resource: Int): Routine { + try { + val raw = IOUtils.toString(App.context!!.resources.openRawResource(resource)) + val jsonRoutine = Gson().fromJson(raw, JSONRoutine::class.java) + + return Routine(jsonRoutine) + } catch (e: IOException) { + error(e.message.toString()) } + } } object RoutineStream { - private val routineSubject = PublishSubject.create() - private val exerciseSubject = PublishSubject.create() - - var routine: Routine = - if (Preferences.defaultRoutine == "routine0") { - JsonRoutineLoader().getRoutine(R.raw.bodyweight_fitness_recommended_routine) - } else if(Preferences.defaultRoutine == "d8a722a0-fae2-4e7e-a751-430348c659fe") { - JsonRoutineLoader().getRoutine(R.raw.starting_stretching_flexibility_routine) - } else { - JsonRoutineLoader().getRoutine(R.raw.molding_mobility_flexibility_routine) - } - - set(value) { - if (value.routineId.equals(routine.routineId)) { - return - } - - Preferences.defaultRoutine = value.routineId - - exercise = value.linkedExercises.first() - - routineSubject.onNext(value) - - field = value - - debug("set value of: " + routine.title) - } - - var exercise: Exercise = routine.linkedExercises.first() - set(value) { - exerciseSubject.onNext(value) - - field = value - } - - fun setRoutine(spinnerRoutine: SpinnerRoutine) { - when(spinnerRoutine.id) { - 0 -> { - routine = JsonRoutineLoader().getRoutine(R.raw.bodyweight_fitness_recommended_routine) - } - 1 -> { - routine = JsonRoutineLoader().getRoutine(R.raw.starting_stretching_flexibility_routine) - } - 2 -> { - routine = JsonRoutineLoader().getRoutine(R.raw.molding_mobility_flexibility_routine) - } - } + private val routineSubject = PublishSubject.create() + private val exerciseSubject = PublishSubject.create() + + var routine: Routine = + if (Preferences.defaultRoutine == "routine0") { + JsonRoutineLoader().getRoutine(R.raw.bodyweight_fitness_recommended_routine) + } else if (Preferences.defaultRoutine == "d8a722a0-fae2-4e7e-a751-430348c659fe") { + JsonRoutineLoader().getRoutine(R.raw.starting_stretching_flexibility_routine) + } else { + JsonRoutineLoader().getRoutine(R.raw.molding_mobility_flexibility_routine) } + set(value) { + if (value.routineId.equals(routine.routineId)) { + return + } - fun routineObservable(): Observable { - return Observable.merge(Observable.just(routine).publish().refCount(), routineSubject) - .observeOn(AndroidSchedulers.mainThread()) - .publish() - .refCount() + Preferences.defaultRoutine = value.routineId + + exercise = value.linkedExercises.first() + + routineSubject.onNext(value) + + field = value + + debug("set value of: " + routine.title) + } + + var exercise: Exercise = routine.linkedExercises.first() + set(value) { + exerciseSubject.onNext(value) + + field = value } - fun exerciseObservable(): Observable { - return Observable.merge(Observable.just(exercise).publish().refCount(), exerciseSubject) - .observeOn(AndroidSchedulers.mainThread()) - .publish() - .refCount() + fun setRoutine(spinnerRoutine: SpinnerRoutine) { + when (spinnerRoutine.id) { + 0 -> { + routine = JsonRoutineLoader().getRoutine(R.raw.bodyweight_fitness_recommended_routine) + } + 1 -> { + routine = JsonRoutineLoader().getRoutine(R.raw.starting_stretching_flexibility_routine) + } + 2 -> { + routine = JsonRoutineLoader().getRoutine(R.raw.molding_mobility_flexibility_routine) + } } + } - fun setLevel(chosenExercise: Exercise, level: Int) { - routine.setLevel(chosenExercise, level) + fun routineObservable(): Observable { + return Observable.merge(Observable.just(routine).publish().refCount(), routineSubject) + .observeOn(AndroidSchedulers.mainThread()) + .publish() + .refCount() + } - exercise = chosenExercise + fun exerciseObservable(): Observable { + return Observable.merge(Observable.just(exercise).publish().refCount(), exerciseSubject) + .observeOn(AndroidSchedulers.mainThread()) + .publish() + .refCount() + } - val sectionId = chosenExercise.section!!.sectionId - val exerciseId = chosenExercise.section!!.currentExercise.exerciseId + fun setLevel(chosenExercise: Exercise, level: Int) { + routine.setLevel(chosenExercise, level) - Preferences.setExerciseIdForSection(sectionId, exerciseId) - } + exercise = chosenExercise + + val sectionId = chosenExercise.section!!.sectionId + val exerciseId = chosenExercise.section!!.currentExercise.exerciseId + + Preferences.setExerciseIdForSection(sectionId, exerciseId) + } } diff --git a/app/src/main/kotlin/com/bodyweight/fitness/stream/Stream.kt b/app/src/main/kotlin/com/bodyweight/fitness/stream/Stream.kt index b95b433f..1e11c4bc 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/stream/Stream.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/stream/Stream.kt @@ -10,105 +10,105 @@ import rx.subjects.PublishSubject import kotlin.properties.Delegates object UiEvent { - private val dialogSubject = PublishSubject.create() + private val dialogSubject = PublishSubject.create() - val dialogObservable: Observable get() = dialogSubject + val dialogObservable: Observable get() = dialogSubject - fun showDialog(dialogType: DialogType, exerciseId: String) { - dialogSubject.onNext(Dialog(dialogType, exerciseId)) - } + fun showDialog(dialogType: DialogType, exerciseId: String) { + dialogSubject.onNext(Dialog(dialogType, exerciseId)) + } } object Stream { - var currentDrawerId: Int = R.id.action_menu_home - private set - - var currentCalendarPage: Int = 60 - private set - - var currentCalendarDay: CalendarDay = CalendarDay() - private set - - private val menuSubject = PublishSubject.create() - private val drawerSubject = PublishSubject.create() - private val restTimerSubject = PublishSubject.create() - private val loggedSecondsSubject = PublishSubject.create() - private val loggedSetRepsSubject = PublishSubject.create() - - private val calendarPageSubject = PublishSubject.create() - private val calendarDaySubject = PublishSubject.create() - - /** - * Emits when changes to repository have been made. - */ - private val repositorySubject = PublishSubject.create() - - /** - * Observables that should be re-emitted should be functions rather than values. - */ - val menuObservable: Observable get() = menuSubject - val restTimerObservable: Observable get() = restTimerSubject - val loggedSecondsObservable: Observable get() = loggedSecondsSubject - val loggedSetRepsObservable: Observable get() = loggedSetRepsSubject - - fun drawerObservable(): Observable { - return Observable.merge(Observable.just(currentDrawerId).publish().refCount(), drawerSubject) - .observeOn(AndroidSchedulers.mainThread()) - .publish() - .refCount() - } - - fun calendarPageObservable(): Observable { - return Observable.merge(Observable.just(currentCalendarPage).publish().refCount(), calendarPageSubject) - .observeOn(AndroidSchedulers.mainThread()) - .publish() - .refCount() - } - - fun calendarDayObservable(): Observable { - return Observable.merge(Observable.just(currentCalendarDay).publish().refCount(), calendarDaySubject) - .observeOn(AndroidSchedulers.mainThread()) - .publish() - .refCount() - } - - fun repositoryObservable(): Observable { - return repositorySubject.observeOn(AndroidSchedulers.mainThread()).publish().refCount() - } - - fun setMenu(toolbarMenuItemId: Int) { - menuSubject.onNext(toolbarMenuItemId) - } - - fun setRestTimer() { - restTimerSubject.onNext(0) - } - - fun setDrawer(drawerMenuItemId: Int) { - currentDrawerId = drawerMenuItemId - - drawerSubject.onNext(drawerMenuItemId) - } - - fun setLoggedSeconds(loggedSeconds: Int) { - loggedSecondsSubject.onNext(loggedSeconds) - } - - fun setLoggedSetReps(setReps: SetReps) { - loggedSetRepsSubject.onNext(setReps) - } - - fun setCalendarPage(page: Int) { - currentCalendarPage = page - calendarPageSubject.onNext(page) - } - - fun setCalendarDay(day: CalendarDay) { - currentCalendarDay = day - calendarDaySubject.onNext(day) - } - - fun setRepository() { - repositorySubject.onNext(true) - } -} \ No newline at end of file + var currentDrawerId: Int = R.id.action_menu_home + private set + + var currentCalendarPage: Int = 60 + private set + + var currentCalendarDay: CalendarDay = CalendarDay() + private set + + private val menuSubject = PublishSubject.create() + private val drawerSubject = PublishSubject.create() + private val restTimerSubject = PublishSubject.create() + private val loggedSecondsSubject = PublishSubject.create() + private val loggedSetRepsSubject = PublishSubject.create() + + private val calendarPageSubject = PublishSubject.create() + private val calendarDaySubject = PublishSubject.create() + + /** + * Emits when changes to repository have been made. + */ + private val repositorySubject = PublishSubject.create() + + /** + * Observables that should be re-emitted should be functions rather than values. + */ + val menuObservable: Observable get() = menuSubject + val restTimerObservable: Observable get() = restTimerSubject + val loggedSecondsObservable: Observable get() = loggedSecondsSubject + val loggedSetRepsObservable: Observable get() = loggedSetRepsSubject + + fun drawerObservable(): Observable { + return Observable.merge(Observable.just(currentDrawerId).publish().refCount(), drawerSubject) + .observeOn(AndroidSchedulers.mainThread()) + .publish() + .refCount() + } + + fun calendarPageObservable(): Observable { + return Observable.merge(Observable.just(currentCalendarPage).publish().refCount(), calendarPageSubject) + .observeOn(AndroidSchedulers.mainThread()) + .publish() + .refCount() + } + + fun calendarDayObservable(): Observable { + return Observable.merge(Observable.just(currentCalendarDay).publish().refCount(), calendarDaySubject) + .observeOn(AndroidSchedulers.mainThread()) + .publish() + .refCount() + } + + fun repositoryObservable(): Observable { + return repositorySubject.observeOn(AndroidSchedulers.mainThread()).publish().refCount() + } + + fun setMenu(toolbarMenuItemId: Int) { + menuSubject.onNext(toolbarMenuItemId) + } + + fun setRestTimer() { + restTimerSubject.onNext(0) + } + + fun setDrawer(drawerMenuItemId: Int) { + currentDrawerId = drawerMenuItemId + + drawerSubject.onNext(drawerMenuItemId) + } + + fun setLoggedSeconds(loggedSeconds: Int) { + loggedSecondsSubject.onNext(loggedSeconds) + } + + fun setLoggedSetReps(setReps: SetReps) { + loggedSetRepsSubject.onNext(setReps) + } + + fun setCalendarPage(page: Int) { + currentCalendarPage = page + calendarPageSubject.onNext(page) + } + + fun setCalendarDay(day: CalendarDay) { + currentCalendarDay = day + calendarDaySubject.onNext(day) + } + + fun setRepository() { + repositorySubject.onNext(true) + } +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/ui/MainActivity.kt b/app/src/main/kotlin/com/bodyweight/fitness/ui/MainActivity.kt index a2cf5f31..995eb660 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/ui/MainActivity.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/ui/MainActivity.kt @@ -20,69 +20,69 @@ import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.view_toolbar.* class MainActivity : RxAppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - setToolbar() + setContentView(R.layout.activity_main) + setToolbar() - val fragmentManager = fragmentManager - val fragmentTransaction = fragmentManager.beginTransaction() + val fragmentManager = fragmentManager + val fragmentTransaction = fragmentManager.beginTransaction() - fragmentTransaction.replace(R.id.view_settings, SettingsFragment(), "SettingsFragment") - fragmentTransaction.commit() + fragmentTransaction.replace(R.id.view_settings, SettingsFragment(), "SettingsFragment") + fragmentTransaction.commit() - Stream.drawerObservable() - .bindUntilEvent(this, ActivityEvent.DESTROY) - .subscribe { - invalidateOptionsMenu() - } + Stream.drawerObservable() + .bindUntilEvent(this, ActivityEvent.DESTROY) + .subscribe { + invalidateOptionsMenu() + } - if (!Preferences.introductionShown) { - Preferences.introductionShown = true + if (!Preferences.introductionShown) { + Preferences.introductionShown = true - startActivity(Intent(this, IntroductionActivity::class.java)) - } + startActivity(Intent(this, IntroductionActivity::class.java)) } + } - override fun onStart() { - super.onStart() + override fun onStart() { + super.onStart() - RateThisApp.onStart(this) - RateThisApp.showRateDialogIfNeeded(this) - } - - override fun onStop() { - super.onStop() + RateThisApp.onStart(this) + RateThisApp.showRateDialogIfNeeded(this) + } - Repository.realm.close() - } + override fun onStop() { + super.onStop() - override fun onOptionsItemSelected(item: MenuItem): Boolean { - Stream.setMenu(item.itemId) + Repository.realm.close() + } - return super.onOptionsItemSelected(item) - } + override fun onOptionsItemSelected(item: MenuItem): Boolean { + Stream.setMenu(item.itemId) - override fun onPrepareOptionsMenu(menu: Menu?): Boolean { - menu?.clear() + return super.onOptionsItemSelected(item) + } - when (Stream.currentDrawerId) { - R.id.action_menu_workout_log -> menuInflater.inflate(R.menu.menu_log_workout, menu) - } + override fun onPrepareOptionsMenu(menu: Menu?): Boolean { + menu?.clear() - return super.onPrepareOptionsMenu(menu) + when (Stream.currentDrawerId) { + R.id.action_menu_workout_log -> menuInflater.inflate(R.menu.menu_log_workout, menu) } - private fun setToolbar() { - setSupportActionBar(toolbar) + return super.onPrepareOptionsMenu(menu) + } + + private fun setToolbar() { + setSupportActionBar(toolbar) - supportActionBar?.let { - it.elevation = 0f - } + supportActionBar?.let { + it.elevation = 0f + } - bottomBar.setOnTabSelectListener { - Stream.setDrawer(it) - } + bottomBar.setOnTabSelectListener { + Stream.setDrawer(it) } + } } diff --git a/app/src/main/kotlin/com/bodyweight/fitness/ui/ProgressActivity.kt b/app/src/main/kotlin/com/bodyweight/fitness/ui/ProgressActivity.kt index cb08a79a..44f3c7d9 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/ui/ProgressActivity.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/ui/ProgressActivity.kt @@ -26,89 +26,89 @@ import com.trello.rxlifecycle.kotlin.bindToLifecycle import kotlinx.android.synthetic.main.activity_progress.* class ProgressActivity : RxAppCompatActivity() { - val primaryKeyRoutineId: String by lazy { - intent.getStringExtra(Constants.primaryKeyRoutineId) - } - - val repositoryRoutine: RepositoryRoutine by lazy { - Repository.realm.where(RepositoryRoutine::class.java) - .equalTo("id", primaryKeyRoutineId) - .findFirst() - } - - val progressPagerAdapter: ProgressPagerAdapter by lazy { - ProgressPagerAdapter(repositoryRoutine) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContentView(R.layout.activity_progress) + val primaryKeyRoutineId: String by lazy { + intent.getStringExtra(Constants.primaryKeyRoutineId) + } - view_progress_pager.offscreenPageLimit = 4 - view_progress_pager.adapter = progressPagerAdapter + val repositoryRoutine: RepositoryRoutine by lazy { + Repository.realm.where(RepositoryRoutine::class.java) + .equalTo("id", primaryKeyRoutineId) + .findFirst() + } - setSupportActionBar(toolbar) + val progressPagerAdapter: ProgressPagerAdapter by lazy { + ProgressPagerAdapter(repositoryRoutine) + } - supportActionBar?.let { - it.title = DateTime(repositoryRoutine.startTime).toString("dd MMMM, YYYY", Locale.ENGLISH) - it.elevation = 0f - it.displayOptions = ActionBar.DISPLAY_SHOW_HOME or ActionBar.DISPLAY_HOME_AS_UP or ActionBar.DISPLAY_SHOW_TITLE - it.setHomeButtonEnabled(true) - it.setDisplayHomeAsUpEnabled(true) - } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) - tablayout.setupWithViewPager(view_progress_pager) - tablayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { - override fun onTabSelected(tab: TabLayout.Tab) { - view_progress_pager.setCurrentItem(tab.position, true) - } + setContentView(R.layout.activity_progress) - override fun onTabUnselected(tab: TabLayout.Tab) { + view_progress_pager.offscreenPageLimit = 4 + view_progress_pager.adapter = progressPagerAdapter - } + setSupportActionBar(toolbar) - override fun onTabReselected(tab: TabLayout.Tab) { - if (tab.position != 0) { - progressPagerAdapter.onTabReselected(tab.position) - } - } - }) + supportActionBar?.let { + it.title = DateTime(repositoryRoutine.startTime).toString("dd MMMM, YYYY", Locale.ENGLISH) + it.elevation = 0f + it.displayOptions = ActionBar.DISPLAY_SHOW_HOME or ActionBar.DISPLAY_HOME_AS_UP or ActionBar.DISPLAY_SHOW_TITLE + it.setHomeButtonEnabled(true) + it.setDisplayHomeAsUpEnabled(true) } - override fun onResume() { - super.onResume() - - UiEvent.dialogObservable - .bindToLifecycle(this) - .filter { it.dialogType == DialogType.ProgressActivityLogWorkout } - .subscribe { dialog -> - val bundle = Bundle() - bundle.putString(Constants.primaryKeyRoutineId, primaryKeyRoutineId) - bundle.putString(Constants.exerciseId, dialog.exerciseId) + tablayout.setupWithViewPager(view_progress_pager) + tablayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab) { + view_progress_pager.setCurrentItem(tab.position, true) + } - val logWorkoutDialog = LogWorkoutDialog() - logWorkoutDialog.arguments = bundle + override fun onTabUnselected(tab: TabLayout.Tab) { - logWorkoutDialog.show(supportFragmentManager, "dialog") - } - - Stream.repositoryObservable() - .bindToLifecycle(this) - .subscribe { - progressPagerAdapter.onRepositoryUpdated() - } - } + } - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - android.R.id.home -> { - this.onBackPressed() - - return true - } + override fun onTabReselected(tab: TabLayout.Tab) { + if (tab.position != 0) { + progressPagerAdapter.onTabReselected(tab.position) } - - return super.onOptionsItemSelected(item) + } + }) + } + + override fun onResume() { + super.onResume() + + UiEvent.dialogObservable + .bindToLifecycle(this) + .filter { it.dialogType == DialogType.ProgressActivityLogWorkout } + .subscribe { dialog -> + val bundle = Bundle() + bundle.putString(Constants.primaryKeyRoutineId, primaryKeyRoutineId) + bundle.putString(Constants.exerciseId, dialog.exerciseId) + + val logWorkoutDialog = LogWorkoutDialog() + logWorkoutDialog.arguments = bundle + + logWorkoutDialog.show(supportFragmentManager, "dialog") + } + + Stream.repositoryObservable() + .bindToLifecycle(this) + .subscribe { + progressPagerAdapter.onRepositoryUpdated() + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + android.R.id.home -> { + this.onBackPressed() + + return true + } } + + return super.onOptionsItemSelected(item) + } } diff --git a/app/src/main/kotlin/com/bodyweight/fitness/ui/WorkoutActivity.kt b/app/src/main/kotlin/com/bodyweight/fitness/ui/WorkoutActivity.kt index 6ac15b95..0968823c 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/ui/WorkoutActivity.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/ui/WorkoutActivity.kt @@ -26,114 +26,114 @@ import com.trello.rxlifecycle.kotlin.bindUntilEvent import kotlinx.android.synthetic.main.activity_dashboard.* class WorkoutActivity : RxAppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener { - companion object { - fun start(context: Context) { - context.startActivity(Intent(context, WorkoutActivity::class.java)) - } + companion object { + fun start(context: Context) { + context.startActivity(Intent(context, WorkoutActivity::class.java)) } + } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) - setContentView(R.layout.activity_workout) - setToolbar() + setContentView(R.layout.activity_workout) + setToolbar() - keepScreenOnWhenAppIsRunning() + keepScreenOnWhenAppIsRunning() - Stream.menuObservable - .bindUntilEvent(this, ActivityEvent.DESTROY) - .filter { it == R.id.action_dashboard } - .subscribe { - startActivity(Intent(this, DashboardActivity::class.java)) - } + Stream.menuObservable + .bindUntilEvent(this, ActivityEvent.DESTROY) + .filter { it == R.id.action_dashboard } + .subscribe { + startActivity(Intent(this, DashboardActivity::class.java)) + } - RoutineStream.exerciseObservable().bindUntilEvent(this, ActivityEvent.DESTROY).subscribe { exercise -> - supportActionBar?.let { toolbar -> - toolbar.title = exercise.title + RoutineStream.exerciseObservable().bindUntilEvent(this, ActivityEvent.DESTROY).subscribe { exercise -> + supportActionBar?.let { toolbar -> + toolbar.title = exercise.title - exercise.section?.let { - toolbar.subtitle = it.title + " " + exercise.description - } - } + exercise.section?.let { + toolbar.subtitle = it.title + " " + exercise.description } + } } + } + + override fun onResume() { + super.onResume() + + keepScreenOnWhenAppIsRunning() + + UiEvent.dialogObservable + .bindUntilEvent(this, ActivityEvent.PAUSE) + .subscribe { + if (it.dialogType === DialogType.MainActivityLogWorkout) { + val bundle = Bundle() + bundle.putString(Constants.exerciseId, it.exerciseId) + + val logWorkoutDialog = LogWorkoutDialog() + logWorkoutDialog.arguments = bundle + logWorkoutDialog.show(supportFragmentManager, "logWorkoutDialog") + } else if (it.dialogType === DialogType.Progress) { + val bundle = Bundle() + bundle.putString(Constants.exerciseId, it.exerciseId) + + val progressDialog = ProgressDialog() + progressDialog.arguments = bundle + progressDialog.show(supportFragmentManager, "progressDialog") + } + } + } - override fun onResume() { - super.onResume() - - keepScreenOnWhenAppIsRunning() - - UiEvent.dialogObservable - .bindUntilEvent(this, ActivityEvent.PAUSE) - .subscribe { - if (it.dialogType === DialogType.MainActivityLogWorkout) { - val bundle = Bundle() - bundle.putString(Constants.exerciseId, it.exerciseId) - - val logWorkoutDialog = LogWorkoutDialog() - logWorkoutDialog.arguments = bundle - logWorkoutDialog.show(supportFragmentManager, "logWorkoutDialog") - } else if (it.dialogType === DialogType.Progress) { - val bundle = Bundle() - bundle.putString(Constants.exerciseId, it.exerciseId) - - val progressDialog = ProgressDialog() - progressDialog.arguments = bundle - progressDialog.show(supportFragmentManager, "progressDialog") - } - } - } - - override fun onStop() { - super.onStop() - - clearFlagKeepScreenOn() - } + override fun onStop() { + super.onStop() - override fun onOptionsItemSelected(item: MenuItem): Boolean { - Stream.setMenu(item.itemId) + clearFlagKeepScreenOn() + } - when (item.itemId) { - android.R.id.home -> { - supportFinishAfterTransition() + override fun onOptionsItemSelected(item: MenuItem): Boolean { + Stream.setMenu(item.itemId) - return true - } - } + when (item.itemId) { + android.R.id.home -> { + supportFinishAfterTransition() - return super.onOptionsItemSelected(item) + return true + } } - override fun onPrepareOptionsMenu(menu: Menu?): Boolean { - menuInflater.inflate(R.menu.menu_workout, menu) + return super.onOptionsItemSelected(item) + } - return super.onPrepareOptionsMenu(menu) - } + override fun onPrepareOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_workout, menu) - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { - keepScreenOnWhenAppIsRunning() - } + return super.onPrepareOptionsMenu(menu) + } - private fun setToolbar() { - setSupportActionBar(toolbar) + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + keepScreenOnWhenAppIsRunning() + } - supportActionBar?.let { - it.elevation = 0f - it.displayOptions = ActionBar.DISPLAY_SHOW_HOME or ActionBar.DISPLAY_HOME_AS_UP or ActionBar.DISPLAY_SHOW_TITLE - it.setHomeButtonEnabled(true) - it.setDisplayHomeAsUpEnabled(true) - } - } + private fun setToolbar() { + setSupportActionBar(toolbar) - private fun keepScreenOnWhenAppIsRunning() { - if (Preferences.keepScreenOnWhenAppIsRunning()) { - window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - } else { - clearFlagKeepScreenOn() - } + supportActionBar?.let { + it.elevation = 0f + it.displayOptions = ActionBar.DISPLAY_SHOW_HOME or ActionBar.DISPLAY_HOME_AS_UP or ActionBar.DISPLAY_SHOW_TITLE + it.setHomeButtonEnabled(true) + it.setDisplayHomeAsUpEnabled(true) } + } - private fun clearFlagKeepScreenOn() { - window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + private fun keepScreenOnWhenAppIsRunning() { + if (Preferences.keepScreenOnWhenAppIsRunning()) { + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + } else { + clearFlagKeepScreenOn() } + } + + private fun clearFlagKeepScreenOn() { + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + } } diff --git a/app/src/main/kotlin/com/bodyweight/fitness/view/progress/ProgressGeneralViewPresenter.kt b/app/src/main/kotlin/com/bodyweight/fitness/view/progress/ProgressGeneralViewPresenter.kt index 711561cc..d2bdf2c0 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/view/progress/ProgressGeneralViewPresenter.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/view/progress/ProgressGeneralViewPresenter.kt @@ -29,329 +29,329 @@ import java.util.* import kotlin.properties.Delegates class ProgressGeneralViewPresenter : AbstractPresenter() { - var repositoryRoutine: RepositoryRoutine by Delegates.notNull() + var repositoryRoutine: RepositoryRoutine by Delegates.notNull() - val exercises by lazy { - RepositoryRoutine.getVisibleAndCompletedExercises(repositoryRoutine.exercises) - } + val exercises by lazy { + RepositoryRoutine.getVisibleAndCompletedExercises(repositoryRoutine.exercises) + } - val missedExercises by lazy { - RepositoryRoutine.getMissedExercises(repositoryRoutine.exercises) - } + val missedExercises by lazy { + RepositoryRoutine.getMissedExercises(repositoryRoutine.exercises) + } - val numberOfExercises by lazy { - RepositoryRoutine.getNumberOfExercises(exercises) - } + val numberOfExercises by lazy { + RepositoryRoutine.getNumberOfExercises(exercises) + } - val numberOfCompletedExercises by lazy { - RepositoryRoutine.getNumberOfCompletedExercises(exercises) - } + val numberOfCompletedExercises by lazy { + RepositoryRoutine.getNumberOfCompletedExercises(exercises) + } - val routineCompletionRate by lazy { - RepositoryRoutine.getCompletionRate(repositoryRoutine) - } + val routineCompletionRate by lazy { + RepositoryRoutine.getCompletionRate(repositoryRoutine) + } + + override fun updateView() { + super.updateView() - override fun updateView() { - super.updateView() + renderTime() + renderTodaysProgress() + renderMissedExercises() + renderWorkoutLengthHistoryGraph() + renderCompletionRateHistoryGraph() + } - renderTime() - renderTodaysProgress() - renderMissedExercises() - renderWorkoutLengthHistoryGraph() - renderCompletionRateHistoryGraph() + fun renderTime() { + val view = getView() as ProgressGeneralView + + view.start_time_value.text = RepositoryRoutine.getStartTime(repositoryRoutine) + view.end_time_value.text = RepositoryRoutine.getLastUpdatedTime(repositoryRoutine) + view.workout_length_value.text = RepositoryRoutine.getWorkoutLength(repositoryRoutine) + + if (routineCompletionRate.percentage == 100) { + view.end_time_label.text = "End Time" + } else { + view.end_time_label.text = "Last Updated" } + } - fun renderTime() { - val view = getView() as ProgressGeneralView + fun renderTodaysProgress() { + val view = getView() as ProgressGeneralView - view.start_time_value.text = RepositoryRoutine.getStartTime(repositoryRoutine) - view.end_time_value.text = RepositoryRoutine.getLastUpdatedTime(repositoryRoutine) - view.workout_length_value.text = RepositoryRoutine.getWorkoutLength(repositoryRoutine) + view.general_completed_exercises_value.text = "$numberOfCompletedExercises out of $numberOfExercises" + view.general_completion_rate_value.text = "${routineCompletionRate.percentage}%" - if (routineCompletionRate.percentage == 100) { - view.end_time_label.text = "End Time" - } else { - view.end_time_label.text = "Last Updated" - } + view.clearCategories() + + for (category in repositoryRoutine.categories) { + val completionRate = RepositoryCategory.getCompletionRate(category) + + view.createCategory(category.title, completionRate.label, calculateLayoutWeight(completionRate.percentage)) } + } - fun renderTodaysProgress() { - val view = getView() as ProgressGeneralView + fun renderMissedExercises() { + val view = getView() as ProgressGeneralView + val parent = view.missed_exercises_layout - view.general_completed_exercises_value.text = "$numberOfCompletedExercises out of $numberOfExercises" - view.general_completion_rate_value.text = "${routineCompletionRate.percentage}%" + if (missedExercises.isNotEmpty()) { + view.missed_exercises_title.setVisible() + view.missed_exercises_card.setVisible() - view.clearCategories() + for (exercise in missedExercises) { + val layout = parent.inflate(R.layout.activity_progress_general_exercise) - for (category in repositoryRoutine.categories) { - val completionRate = RepositoryCategory.getCompletionRate(category) + layout.exercise_title.text = exercise.title + layout.category_title.text = exercise.category?.title + " - " + exercise.section?.title - view.createCategory(category.title, completionRate.label, calculateLayoutWeight(completionRate.percentage)) - } + parent.addView(layout) + } + } else { + view.missed_exercises_title.setGone() + view.missed_exercises_card.setGone() } + } + + fun renderWorkoutLengthHistoryGraph() { + val view = getView() as ProgressGeneralView - fun renderMissedExercises() { - val view = getView() as ProgressGeneralView - val parent = view.missed_exercises_layout + val workoutLengthGraphView = view.graph_workout_length_view + val workoutLengthTabLayout = view.graph_workout_length_tablayout - if (missedExercises.isNotEmpty()) { - view.missed_exercises_title.setVisible() - view.missed_exercises_card.setVisible() + val workoutLengthAdapter = WorkoutLengthAdapter() - for (exercise in missedExercises) { - val layout = parent.inflate(R.layout.activity_progress_general_exercise) + workoutLengthGraphView.adapter = workoutLengthAdapter + workoutLengthGraphView.baseLineColor = Color.WHITE + workoutLengthGraphView.scrubLineColor = Color.parseColor("#111111") + workoutLengthGraphView.isScrubEnabled = true +// workoutLengthGraphView.animateChanges = true + + workoutLengthGraphView.setScrubListener { + val dateTimeWorkoutLength = it as? DateTimeWorkoutLength - layout.exercise_title.text = exercise.title - layout.category_title.text = exercise.category?.title + " - " + exercise.section?.title + dateTimeWorkoutLength?.let { + view.graph_workout_length_title.text = it.dateTime.toString("dd MMMM, YYYY", Locale.ENGLISH) - parent.addView(layout) - } + if (it.repositoryRoutine != null) { + view.graph_workout_length_value.text = RepositoryRoutine.getWorkoutLength(it.repositoryRoutine) } else { - view.missed_exercises_title.setGone() - view.missed_exercises_card.setGone() + view.graph_workout_length_value.text = "Not Completed" } + } } - fun renderWorkoutLengthHistoryGraph() { - val view = getView() as ProgressGeneralView + workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("1W")) + workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("1M")) + workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("3M")) + workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("6M")) + workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("1Y")) - val workoutLengthGraphView = view.graph_workout_length_view - val workoutLengthTabLayout = view.graph_workout_length_tablayout + workoutLengthTabLayout.setOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab) { + updateWorkoutLengthTitle() - val workoutLengthAdapter = WorkoutLengthAdapter() + when (tab.position) { + 0 -> updateWorkoutLengthGraph(workoutLengthAdapter, 7) + 1 -> updateWorkoutLengthGraph(workoutLengthAdapter, 30) + 2 -> updateWorkoutLengthGraph(workoutLengthAdapter, 90) + 3 -> updateWorkoutLengthGraph(workoutLengthAdapter, 180) + else -> updateWorkoutLengthGraph(workoutLengthAdapter, 360) + } + } - workoutLengthGraphView.adapter = workoutLengthAdapter - workoutLengthGraphView.baseLineColor = Color.WHITE - workoutLengthGraphView.scrubLineColor = Color.parseColor("#111111") - workoutLengthGraphView.isScrubEnabled = true -// workoutLengthGraphView.animateChanges = true + override fun onTabUnselected(tab: TabLayout.Tab) { - workoutLengthGraphView.setScrubListener { - val dateTimeWorkoutLength = it as? DateTimeWorkoutLength + } - dateTimeWorkoutLength?.let { - view.graph_workout_length_title.text = it.dateTime.toString("dd MMMM, YYYY", Locale.ENGLISH) + override fun onTabReselected(tab: TabLayout.Tab) { - if (it.repositoryRoutine != null) { - view.graph_workout_length_value.text = RepositoryRoutine.getWorkoutLength(it.repositoryRoutine) - } else { - view.graph_workout_length_value.text = "Not Completed" - } - } - } + } + }) - workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("1W")) - workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("1M")) - workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("3M")) - workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("6M")) - workoutLengthTabLayout.addTab(workoutLengthTabLayout.newTab().setText("1Y")) + updateWorkoutLengthGraph(workoutLengthAdapter, 7) + updateWorkoutLengthTitle() + } - workoutLengthTabLayout.setOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { - override fun onTabSelected(tab: TabLayout.Tab) { - updateWorkoutLengthTitle() + fun updateWorkoutLengthTitle() { + val view = getView() as ProgressGeneralView - when (tab.position) { - 0 -> updateWorkoutLengthGraph(workoutLengthAdapter, 7) - 1 -> updateWorkoutLengthGraph(workoutLengthAdapter, 30) - 2 -> updateWorkoutLengthGraph(workoutLengthAdapter, 90) - 3 -> updateWorkoutLengthGraph(workoutLengthAdapter, 180) - else -> updateWorkoutLengthGraph(workoutLengthAdapter, 360) - } - } + view.graph_workout_length_title.text = DateTime(repositoryRoutine.startTime).toString("dd MMMM, YYYY", Locale.ENGLISH) + view.graph_workout_length_value.text = "${RepositoryRoutine.getWorkoutLength(repositoryRoutine)}" + } - override fun onTabUnselected(tab: TabLayout.Tab) { + fun updateWorkoutLengthGraph(adapter: WorkoutLengthAdapter, minusDays: Int = 7) { + val start = DateTime.now().withTimeAtStartOfDay().minusDays(minusDays) + val end = DateTime.now() - } + Repository.realm.where(RepositoryRoutine::class.java) + .between("startTime", start.toDate(), end.toDate()) + .findAllAsync() + .sort("startTime", Sort.DESCENDING) + .asObservable() + .filter { it.isLoaded } + .map { + val dates = ArrayList() - override fun onTabReselected(tab: TabLayout.Tab) { + for (index in 1..minusDays) { + val date = start.plusDays(index) - } - }) + val repositoryRoutine = it.filter { + val startTime = DateTime(it.startTime) - updateWorkoutLengthGraph(workoutLengthAdapter, 7) - updateWorkoutLengthTitle() - } + date.dayOfMonth == startTime.dayOfMonth + && date.monthOfYear == startTime.monthOfYear + && date.year == startTime.year + }.firstOrNull() - fun updateWorkoutLengthTitle() { - val view = getView() as ProgressGeneralView + if (repositoryRoutine != null) { + dates.add(DateTimeWorkoutLength(date, repositoryRoutine)) + } else { + dates.add(DateTimeWorkoutLength(date, null)) + } + } - view.graph_workout_length_title.text = DateTime(repositoryRoutine.startTime).toString("dd MMMM, YYYY", Locale.ENGLISH) - view.graph_workout_length_value.text = "${RepositoryRoutine.getWorkoutLength(repositoryRoutine)}" - } + dates + } + .observeOn(AndroidSchedulers.mainThread()) + .bindToLifecycle(getView()) + .subscribe { + adapter.changeData(it) + } + } - fun updateWorkoutLengthGraph(adapter: WorkoutLengthAdapter, minusDays: Int = 7) { - val start = DateTime.now().withTimeAtStartOfDay().minusDays(minusDays) - val end = DateTime.now() - - Repository.realm.where(RepositoryRoutine::class.java) - .between("startTime", start.toDate(), end.toDate()) - .findAllAsync() - .sort("startTime", Sort.DESCENDING) - .asObservable() - .filter { it.isLoaded } - .map { - val dates = ArrayList() - - for (index in 1..minusDays) { - val date = start.plusDays(index) - - val repositoryRoutine = it.filter { - val startTime = DateTime(it.startTime) - - date.dayOfMonth == startTime.dayOfMonth - && date.monthOfYear == startTime.monthOfYear - && date.year == startTime.year - }.firstOrNull() - - if (repositoryRoutine != null) { - dates.add(DateTimeWorkoutLength(date, repositoryRoutine)) - } else { - dates.add(DateTimeWorkoutLength(date, null)) - } - } - - dates - } - .observeOn(AndroidSchedulers.mainThread()) - .bindToLifecycle(getView()) - .subscribe { - adapter.changeData(it) - } - } + fun renderCompletionRateHistoryGraph() { + val view = getView() as ProgressGeneralView - fun renderCompletionRateHistoryGraph() { - val view = getView() as ProgressGeneralView + val completionRateGraphView = view.graph_completion_rate_view + val completionRateTabLayout = view.graph_completion_rate_tablayout - val completionRateGraphView = view.graph_completion_rate_view - val completionRateTabLayout = view.graph_completion_rate_tablayout + val completionRateAdapter = CompletionRateAdapter() - val completionRateAdapter = CompletionRateAdapter() + completionRateGraphView.adapter = completionRateAdapter + completionRateGraphView.baseLineColor = Color.WHITE + completionRateGraphView.scrubLineColor = Color.parseColor("#111111") + completionRateGraphView.isScrubEnabled = true - completionRateGraphView.adapter = completionRateAdapter - completionRateGraphView.baseLineColor = Color.WHITE - completionRateGraphView.scrubLineColor = Color.parseColor("#111111") - completionRateGraphView.isScrubEnabled = true + completionRateGraphView.setScrubListener { + val dateTimeCompletionRate = it as? DateTimeCompletionRate - completionRateGraphView.setScrubListener { - val dateTimeCompletionRate = it as? DateTimeCompletionRate + dateTimeCompletionRate?.let { + view.graph_completion_rate_title.text = it.dateTime.toString("dd MMMM, YYYY", Locale.ENGLISH) - dateTimeCompletionRate?.let { - view.graph_completion_rate_title.text = it.dateTime.toString("dd MMMM, YYYY", Locale.ENGLISH) + if (it.repositoryRoutine != null) { + val completionRate = RepositoryRoutine.getCompletionRate(it.repositoryRoutine) - if (it.repositoryRoutine != null) { - val completionRate = RepositoryRoutine.getCompletionRate(it.repositoryRoutine) + view.graph_completion_rate_value.text = "${completionRate.label}" + } else { + view.graph_completion_rate_value.text = "Not Completed" + } + } + } - view.graph_completion_rate_value.text = "${completionRate.label}" - } else { - view.graph_completion_rate_value.text = "Not Completed" - } - } + completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("1W")) + completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("1M")) + completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("3M")) + completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("6M")) + completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("1Y")) + + completionRateTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab) { + updateCompletionRateTitle() + + when (tab.position) { + 0 -> updateCompletionRateGraph(completionRateAdapter, 7) + 1 -> updateCompletionRateGraph(completionRateAdapter, 30) + 2 -> updateCompletionRateGraph(completionRateAdapter, 90) + 3 -> updateCompletionRateGraph(completionRateAdapter, 180) + else -> updateCompletionRateGraph(completionRateAdapter, 360) } + } - completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("1W")) - completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("1M")) - completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("3M")) - completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("6M")) - completionRateTabLayout.addTab(completionRateTabLayout.newTab().setText("1Y")) + override fun onTabUnselected(tab: TabLayout.Tab) { - completionRateTabLayout.setOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { - override fun onTabSelected(tab: TabLayout.Tab) { - updateCompletionRateTitle() + } - when (tab.position) { - 0 -> updateCompletionRateGraph(completionRateAdapter, 7) - 1 -> updateCompletionRateGraph(completionRateAdapter, 30) - 2 -> updateCompletionRateGraph(completionRateAdapter, 90) - 3 -> updateCompletionRateGraph(completionRateAdapter, 180) - else -> updateCompletionRateGraph(completionRateAdapter, 360) - } - } + override fun onTabReselected(tab: TabLayout.Tab) { - override fun onTabUnselected(tab: TabLayout.Tab) { + } + }) - } + updateCompletionRateGraph(completionRateAdapter, 7) + updateCompletionRateTitle() + } - override fun onTabReselected(tab: TabLayout.Tab) { + fun updateCompletionRateTitle() { + val view = getView() as ProgressGeneralView - } - }) + val completionRate = RepositoryRoutine.getCompletionRate(repositoryRoutine) - updateCompletionRateGraph(completionRateAdapter, 7) - updateCompletionRateTitle() - } + view.graph_completion_rate_title.text = DateTime(repositoryRoutine.startTime).toString("dd MMMM, YYYY", Locale.ENGLISH) + view.graph_completion_rate_value.text = "${completionRate.label}" + } - fun updateCompletionRateTitle() { - val view = getView() as ProgressGeneralView + fun updateCompletionRateGraph(adapter: CompletionRateAdapter, minusDays: Int = 7) { + val start = DateTime.now().withTimeAtStartOfDay().minusDays(minusDays) + val end = DateTime.now() - val completionRate = RepositoryRoutine.getCompletionRate(repositoryRoutine) + Repository.realm.where(RepositoryRoutine::class.java) + .between("startTime", start.toDate(), end.toDate()) + .findAllAsync() + .sort("startTime", Sort.DESCENDING) + .asObservable() + .filter { it.isLoaded } + .map { + val dates = ArrayList() - view.graph_completion_rate_title.text = DateTime(repositoryRoutine.startTime).toString("dd MMMM, YYYY", Locale.ENGLISH) - view.graph_completion_rate_value.text = "${completionRate.label}" - } + for (index in 1..minusDays) { + val date = start.plusDays(index) - fun updateCompletionRateGraph(adapter: CompletionRateAdapter, minusDays: Int = 7) { - val start = DateTime.now().withTimeAtStartOfDay().minusDays(minusDays) - val end = DateTime.now() - - Repository.realm.where(RepositoryRoutine::class.java) - .between("startTime", start.toDate(), end.toDate()) - .findAllAsync() - .sort("startTime", Sort.DESCENDING) - .asObservable() - .filter { it.isLoaded } - .map { - val dates = ArrayList() - - for (index in 1..minusDays) { - val date = start.plusDays(index) - - val repositoryRoutine = it.filter { - val startTime = DateTime(it.startTime) - - date.dayOfMonth == startTime.dayOfMonth - && date.monthOfYear == startTime.monthOfYear - && date.year == startTime.year - }.firstOrNull() - - if (repositoryRoutine != null) { - dates.add(DateTimeCompletionRate(date, repositoryRoutine)) - } else { - dates.add(DateTimeCompletionRate(date, null)) - } - } - - dates - } - .observeOn(AndroidSchedulers.mainThread()) - .bindToLifecycle(getView()) - .subscribe { - adapter.changeData(it) - } - } + val repositoryRoutine = it.filter { + val startTime = DateTime(it.startTime) + + date.dayOfMonth == startTime.dayOfMonth + && date.monthOfYear == startTime.monthOfYear + && date.year == startTime.year + }.firstOrNull() + + if (repositoryRoutine != null) { + dates.add(DateTimeCompletionRate(date, repositoryRoutine)) + } else { + dates.add(DateTimeCompletionRate(date, null)) + } + } + + dates + } + .observeOn(AndroidSchedulers.mainThread()) + .bindToLifecycle(getView()) + .subscribe { + adapter.changeData(it) + } + } } open class ProgressGeneralView : AbstractView { - override var presenter: AbstractPresenter = ProgressGeneralViewPresenter() + override var presenter: AbstractPresenter = ProgressGeneralViewPresenter() - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - override fun onCreateView() { - super.onCreateView() - } + override fun onCreateView() { + super.onCreateView() + } - fun clearCategories() { - category.removeAllViews() - } + fun clearCategories() { + category.removeAllViews() + } - fun createCategory(title: String, completionRateLabel: String, completionRateValue: Float) { - val new_category = category.inflate(R.layout.view_home_category) + fun createCategory(title: String, completionRateLabel: String, completionRateValue: Float) { + val new_category = category.inflate(R.layout.view_home_category) - new_category.title.text = title - new_category.completion_rate_label.text = completionRateLabel - new_category.completion_rate_value.setLayoutWeight(completionRateValue) + new_category.title.text = title + new_category.completion_rate_label.text = completionRateLabel + new_category.completion_rate_value.setLayoutWeight(completionRateValue) - category.addView(new_category) - } -} \ No newline at end of file + category.addView(new_category) + } +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/ActionViewPresenter.kt b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/ActionViewPresenter.kt index a38207ee..c1e34273 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/ActionViewPresenter.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/ActionViewPresenter.kt @@ -28,138 +28,138 @@ import com.trello.rxlifecycle.kotlin.bindToLifecycle import kotlinx.android.synthetic.main.view_action.view.* class ActionPresenter : AbstractPresenter() { - override fun bindView(view: AbstractView) { - super.bindView(view) - - val view = (mView as ActionView) - - RoutineStream.exerciseObservable() - .bindToLifecycle(view) - .subscribe { - if (it.hasProgressions) { - view.setActionButtonImageDrawable(R.drawable.action_progression_white) - view.showActionSheetChooseProgression() - } else { - view.setActionButtonImageDrawable(R.drawable.action_add) - view.hideActionSheetChooseProgression() - } - } - - Stream.loggedSecondsObservable - .bindToLifecycle(view) - .subscribe { - val format = String.format("Logged time %s:%s", it.formatMinutes(), it.formatSeconds()) - - Snackbar.make(view.action_view_coordinator_layout, format, Snackbar.LENGTH_LONG).show() - } - - Stream.loggedSetRepsObservable - .bindToLifecycle(view) - .subscribe { - val format = String.format("Logged Set %d with %d Reps", it.set, it.reps) - - Snackbar.make(view.action_view_coordinator_layout, format, Snackbar.LENGTH_LONG).show() - } - } + override fun bindView(view: AbstractView) { + super.bindView(view) + + val view = (mView as ActionView) + + RoutineStream.exerciseObservable() + .bindToLifecycle(view) + .subscribe { + if (it.hasProgressions) { + view.setActionButtonImageDrawable(R.drawable.action_progression_white) + view.showActionSheetChooseProgression() + } else { + view.setActionButtonImageDrawable(R.drawable.action_add) + view.hideActionSheetChooseProgression() + } + } - fun logWorkout() { - UiEvent.showDialog(DialogType.MainActivityLogWorkout, RoutineStream.exercise.exerciseId) - } + Stream.loggedSecondsObservable + .bindToLifecycle(view) + .subscribe { + val format = String.format("Logged time %s:%s", it.formatMinutes(), it.formatSeconds()) - fun watchFullVideo() { - val view = (mView as ActionView) - val id = RoutineStream.exercise.youTubeId + Snackbar.make(view.action_view_coordinator_layout, format, Snackbar.LENGTH_LONG).show() + } - try { - view.context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:" + id))) - } catch (e: ActivityNotFoundException) { - view.context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com/watch?v=" + id))) - } - } + Stream.loggedSetRepsObservable + .bindToLifecycle(view) + .subscribe { + val format = String.format("Logged Set %d with %d Reps", it.set, it.reps) - fun chooseProgression() { - UiEvent.showDialog(DialogType.Progress, RoutineStream.exercise.exerciseId) - } + Snackbar.make(view.action_view_coordinator_layout, format, Snackbar.LENGTH_LONG).show() + } + } + + fun logWorkout() { + UiEvent.showDialog(DialogType.MainActivityLogWorkout, RoutineStream.exercise.exerciseId) + } - fun todaysWorkout() { - val view = (mView as ActionView) - val routineId = Repository.repositoryRoutineForToday.id + fun watchFullVideo() { + val view = (mView as ActionView) + val id = RoutineStream.exercise.youTubeId - view.context.startActivity(Intent(view.context, ProgressActivity::class.java) - .putExtra(Constants.primaryKeyRoutineId, routineId)) + try { + view.context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:" + id))) + } catch (e: ActivityNotFoundException) { + view.context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com/watch?v=" + id))) } -} + } -open class ActionView : AbstractView { - override var presenter: AbstractPresenter = ActionPresenter() + fun chooseProgression() { + UiEvent.showDialog(DialogType.Progress, RoutineStream.exercise.exerciseId) + } - var mMaterialSheet: MaterialSheetFab? = null + fun todaysWorkout() { + val view = (mView as ActionView) + val routineId = Repository.repositoryRoutineForToday.id - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + view.context.startActivity(Intent(view.context, ProgressActivity::class.java) + .putExtra(Constants.primaryKeyRoutineId, routineId)) + } +} - override fun onCreateView() { - val presenter = (presenter as ActionPresenter) +open class ActionView : AbstractView { + override var presenter: AbstractPresenter = ActionPresenter() - mMaterialSheet = MaterialSheetFab( - action_view_action_button, - action_view_action_sheet, - action_view_overlay, - Color.parseColor("#FFFFFF"), - Color.parseColor("#FFFDDD")) + var mMaterialSheet: MaterialSheetFab? = null - mMaterialSheet?.setEventListener(object : MaterialSheetFabEventListener() { - override fun onShowSheet() { - super.onShowSheet() + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - action_view_log_workout_button.hide() - } + override fun onCreateView() { + val presenter = (presenter as ActionPresenter) - override fun onSheetShown() { - super.onSheetShown() - } + mMaterialSheet = MaterialSheetFab( + action_view_action_button, + action_view_action_sheet, + action_view_overlay, + Color.parseColor("#FFFFFF"), + Color.parseColor("#FFFDDD")) - override fun onHideSheet() { - super.onHideSheet() - } + mMaterialSheet?.setEventListener(object : MaterialSheetFabEventListener() { + override fun onShowSheet() { + super.onShowSheet() - override fun onSheetHidden() { - super.onSheetHidden() + action_view_log_workout_button.hide() + } - action_view_log_workout_button.show() - } - }) + override fun onSheetShown() { + super.onSheetShown() + } - action_view_log_workout_button.setOnClickListener { - presenter.logWorkout() - } + override fun onHideSheet() { + super.onHideSheet() + } - action_view_action_sheet_watch_on_youtube.setOnClickListener { - mMaterialSheet?.hideSheet() - presenter.watchFullVideo() - } + override fun onSheetHidden() { + super.onSheetHidden() - action_view_action_sheet_choose_progression.setOnClickListener { - mMaterialSheet?.hideSheet() - presenter.chooseProgression() - } + action_view_log_workout_button.show() + } + }) - action_view_action_sheet_todays_workout.setOnClickListener { - mMaterialSheet?.hideSheet() - presenter.todaysWorkout() - } + action_view_log_workout_button.setOnClickListener { + presenter.logWorkout() } - fun showActionSheetChooseProgression() { - action_view_action_sheet_choose_progression.visibility = View.VISIBLE + action_view_action_sheet_watch_on_youtube.setOnClickListener { + mMaterialSheet?.hideSheet() + presenter.watchFullVideo() } - fun hideActionSheetChooseProgression() { - action_view_action_sheet_choose_progression.visibility = View.GONE + action_view_action_sheet_choose_progression.setOnClickListener { + mMaterialSheet?.hideSheet() + presenter.chooseProgression() } - fun setActionButtonImageDrawable(drawable: Int) { - action_view_action_button.setImageResource(drawable) + action_view_action_sheet_todays_workout.setOnClickListener { + mMaterialSheet?.hideSheet() + presenter.todaysWorkout() } -} \ No newline at end of file + } + + fun showActionSheetChooseProgression() { + action_view_action_sheet_choose_progression.visibility = View.VISIBLE + } + + fun hideActionSheetChooseProgression() { + action_view_action_sheet_choose_progression.visibility = View.GONE + } + + fun setActionButtonImageDrawable(drawable: Int) { + action_view_action_button.setImageResource(drawable) + } +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/NavigationViewPresenter.kt b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/NavigationViewPresenter.kt index 12dd5d91..3042b9ea 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/NavigationViewPresenter.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/NavigationViewPresenter.kt @@ -3,6 +3,8 @@ package com.bodyweight.fitness.view.workout import android.content.Context import android.util.AttributeSet import android.view.View +import com.bodyweight.fitness.model.Exercise +import com.bodyweight.fitness.repository.Repository import com.bodyweight.fitness.setGone import com.bodyweight.fitness.setInvisible @@ -17,140 +19,168 @@ import com.trello.rxlifecycle.kotlin.bindToLifecycle import kotlinx.android.synthetic.main.view_timer.view.* class NavigationPresenter : AbstractPresenter() { - override fun bindView(view: AbstractView) { - super.bindView(view) + override fun bindView(view: AbstractView) { + super.bindView(view) - RoutineStream.exerciseObservable() - .bindToLifecycle(view) - .subscribe { - val view = (view as NavigationView) + RoutineStream.exerciseObservable() + .bindToLifecycle(view) + .subscribe { + val view = (view as NavigationView) - view.showTimerOrRepsLogger(it.isTimedSet) - view.showPreviousNextButtons(it.isPrevious, it.isNext) - } + view.showTimerOrRepsLogger(it.isTimedSet) + view.showPreviousNextButtons(it.isPrevious, it.isNext) + } - Stream.restTimerObservable - .bindToLifecycle(view) - .subscribe { - restoreView(view) - } + Stream.restTimerObservable + .bindToLifecycle(view) + .subscribe { + restoreView(view) + } - Stream.loggedSetRepsObservable - .bindToLifecycle(view) - .subscribe { - val view = (view as NavigationView) + Stream.loggedSetRepsObservable + .bindToLifecycle(view) + .subscribe { + val view = (view as NavigationView) - showRestTimer(view) - } + showRestTimer(view) + } - Stream.loggedSecondsObservable - .bindToLifecycle(view) - .subscribe { - val view = (view as NavigationView) + Stream.loggedSecondsObservable + .bindToLifecycle(view) + .subscribe { + val view = (view as NavigationView) - showRestTimer(view) - } - } + showRestTimer(view) + } + } - override fun restoreView(view: AbstractView) { - super.restoreView(view) + override fun restoreView(view: AbstractView) { + super.restoreView(view) - val view = (view as NavigationView) + val view = (view as NavigationView) - val exercise = RoutineStream.exercise + val exercise = RoutineStream.exercise - view.showTimerOrRepsLogger(exercise.isTimedSet) - view.showPreviousNextButtons(exercise.isPrevious, exercise.isNext) - } + view.showTimerOrRepsLogger(exercise.isTimedSet) + view.showPreviousNextButtons(exercise.isPrevious, exercise.isNext) + } + + fun showRestTimer(view: NavigationView) { + if (Preferences.showRestTimer) { + val section = RoutineStream.exercise.section!! - fun showRestTimer(view: NavigationView) { - if (Preferences.showRestTimer) { - val section = RoutineStream.exercise.section!! - - if (section.sectionId == "section0") { - if (Preferences.showRestTimerAfterWarmup) { - view.showRestTimer() - } - } else if (section.sectionId == "section1") { - if (Preferences.showRestTimerAfterBodylineDrills) { - view.showRestTimer() - } - } else { - if (RoutineStream.routine.routineId != "routine0") { - if (Preferences.showRestTimerAfterFlexibilityExercises) { - view.showRestTimer() - } - } else { - view.showRestTimer() - } - } + if (section.sectionId == "section0") { + if (Preferences.showRestTimerAfterWarmup) { + view.showRestTimer() + } + } else if (section.sectionId == "section1") { + if (Preferences.showRestTimerAfterBodylineDrills) { + view.showRestTimer() + } + } else { + if (RoutineStream.routine.routineId != "routine0") { + if (Preferences.showRestTimerAfterFlexibilityExercises) { + view.showRestTimer() + } + } else { + view.showRestTimer() } + } } + } - fun previousExercise() { - if (RoutineStream.exercise.isPrevious) { - RoutineStream.exercise = RoutineStream.exercise.previous!! - } + fun previousExercise() { + if (RoutineStream.exercise.isPrevious) { + RoutineStream.exercise = RoutineStream.exercise.previous!! } + } - fun nextExercise() { - if (RoutineStream.exercise.isNext) { - RoutineStream.exercise = RoutineStream.exercise.next!! - } + fun nextExercise() { + RoutineStream.exercise = getNextExercise() + } + + fun getNextExercise(): Exercise { + val bundledSection = RoutineStream.exercise.section?.bundledSection + val bundledSectionExercise = bundledSection?.currentExercise + + val repositoryRoutine = Repository.repositoryRoutineForToday + + // no bundled Exercise for this Section + if (bundledSectionExercise == null && RoutineStream.exercise.isNext) { + return RoutineStream.exercise.next!! + } + + val bundledExercise = repositoryRoutine.exercises.filter { + it.exerciseId == bundledSectionExercise?.exerciseId + }.firstOrNull() + + val currentExercise = repositoryRoutine.exercises.filter { + it.exerciseId == RoutineStream.exercise.exerciseId + }.firstOrNull() + + if (bundledExercise != null && bundledExercise.sets.size < bundledSection!!.sets.toInt()) { + return bundledSectionExercise!! + } + + if (currentExercise!!.sets.size < RoutineStream.exercise.section!!.sets.toInt()) { + return RoutineStream.exercise } + + return RoutineStream.exercise.next!! + } } open class NavigationView : AbstractView { - override var presenter: AbstractPresenter = NavigationPresenter() + override var presenter: AbstractPresenter = NavigationPresenter() - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - override fun onCreateView() { - prev_exercise_button.setOnClickListener { - (presenter as NavigationPresenter).previousExercise() - } - - next_exercise_button.setOnClickListener { - (presenter as NavigationPresenter).nextExercise() - } + override fun onCreateView() { + prev_exercise_button.setOnClickListener { + (presenter as NavigationPresenter).previousExercise() } - fun showRestTimer() { - rest_timer_view.setVisible() - timer_view.setGone() + next_exercise_button.setOnClickListener { + (presenter as NavigationPresenter).nextExercise() + } + } + + fun showRestTimer() { + rest_timer_view.setVisible() + timer_view.setGone() + reps_logger_view.setGone() + } + + fun showTimerOrRepsLogger(isTimed: Boolean) { + if (!RestTimerShared.isPlaying) { + if (isTimed) { + rest_timer_view.setGone() + timer_view.setVisible() reps_logger_view.setGone() + } else { + rest_timer_view.setGone() + timer_view.setGone() + reps_logger_view.setVisible() + } + } else { + showRestTimer() } + } - fun showTimerOrRepsLogger(isTimed: Boolean) { - if (!RestTimerShared.isPlaying) { - if (isTimed) { - rest_timer_view.setGone() - timer_view.setVisible() - reps_logger_view.setGone() - } else { - rest_timer_view.setGone() - timer_view.setGone() - reps_logger_view.setVisible() - } - } else { - showRestTimer() - } + fun showPreviousNextButtons(hasPrevious: Boolean, hasNext: Boolean) { + if (hasPrevious) { + prev_exercise_button.setVisible() + } else { + prev_exercise_button.setInvisible() } - fun showPreviousNextButtons(hasPrevious: Boolean, hasNext: Boolean) { - if (hasPrevious) { - prev_exercise_button.setVisible() - } else { - prev_exercise_button.setInvisible() - } - - if (hasNext) { - next_exercise_button.setVisible() - } else { - next_exercise_button.setInvisible() - } + if (hasNext) { + next_exercise_button.setVisible() + } else { + next_exercise_button.setInvisible() } -} \ No newline at end of file + } +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/RepsLoggerViewPresenter.kt b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/RepsLoggerViewPresenter.kt index 6d770518..b75e572b 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/RepsLoggerViewPresenter.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/RepsLoggerViewPresenter.kt @@ -17,175 +17,179 @@ import kotlinx.android.synthetic.main.view_timer.view.* import java.util.* class RepsLoggerPresenter : AbstractPresenter() { - var numberOfReps: Int = 5 + var numberOfReps: Int = 5 + var presenter: AbstractPresenter = NavigationPresenter() - override fun bindView(view: AbstractView) { - super.bindView(view) + override fun bindView(view: AbstractView) { + super.bindView(view) - RoutineStream.exerciseObservable() - .bindToLifecycle(view) - .subscribe { - numberOfReps = Preferences.getNumberOfRepsForExercise(it.exerciseId, 5) + RoutineStream.exerciseObservable() + .bindToLifecycle(view) + .subscribe { + numberOfReps = Preferences.getNumberOfRepsForExercise(it.exerciseId, 5) - updateLabels() - } + updateLabels() + } - Stream.repositoryObservable() - .bindToLifecycle(view) - .subscribe { - updateLabels() - } - } + Stream.repositoryObservable() + .bindToLifecycle(view) + .subscribe { + updateLabels() + } + } - override fun restoreView(view: AbstractView) { - super.restoreView(view) + override fun restoreView(view: AbstractView) { + super.restoreView(view) - numberOfReps = Preferences.getNumberOfRepsForExercise(RoutineStream.exercise.exerciseId, 5) + numberOfReps = Preferences.getNumberOfRepsForExercise(RoutineStream.exercise.exerciseId, 5) - updateLabels() - } + updateLabels() + } - fun updateLabels() { - val repsLoggerView: RepsLoggerView = (mView as RepsLoggerView) + fun updateLabels() { + val repsLoggerView: RepsLoggerView = (mView as RepsLoggerView) - repsLoggerView.setSets(formatSets()) - repsLoggerView.setNumberOfReps(formatNumberOfReps(numberOfReps)) + repsLoggerView.setSets(formatSets()) + repsLoggerView.setNumberOfReps(formatNumberOfReps(numberOfReps)) - Preferences.setNumberOfReps(RoutineStream.exercise.exerciseId, numberOfReps) - } + Preferences.setNumberOfReps(RoutineStream.exercise.exerciseId, numberOfReps) + } - fun logReps() { - val realm = Repository.realm - val repositoryRoutine = Repository.repositoryRoutineForToday + fun logReps() { + val realm = Repository.realm + val repositoryRoutine = Repository.repositoryRoutineForToday - realm.executeTransaction { - repositoryRoutine.exercises.filter { - it.exerciseId == RoutineStream.exercise.exerciseId - }.firstOrNull()?.let { - val numberOfSets = it.sets.size + realm.executeTransaction { + repositoryRoutine.exercises.filter { + it.exerciseId == RoutineStream.exercise.exerciseId + }.firstOrNull()?.let { + val numberOfSets = it.sets.size + val maximumNumberOfSets: Int = if (it.section !== null) it.section?.sets!! else 1 - if (numberOfSets < Constants.maximumNumberOfSets) { - val firstSet = it.sets.first() + if (numberOfSets < maximumNumberOfSets) { + val firstSet = it.sets.first() - if (numberOfSets == 1 && firstSet.reps == 0) { - firstSet.reps = numberOfReps + if (numberOfSets == 1 && firstSet.reps == 0) { + firstSet.reps = numberOfReps - Stream.setLoggedSetReps(SetReps(numberOfSets, numberOfReps)) - } else { - val repositorySet = realm.createObject(RepositorySet::class.java, "Set-" + UUID.randomUUID().toString()) + Stream.setLoggedSetReps(SetReps(numberOfSets, numberOfReps)) + } else { + val repositorySet = realm.createObject(RepositorySet::class.java, "Set-" + UUID.randomUUID().toString()) - repositorySet.isTimed = false - repositorySet.seconds = 0 - repositorySet.weight = 0.0 - repositorySet.reps = numberOfReps + repositorySet.isTimed = false + repositorySet.seconds = 0 + repositorySet.weight = 0.0 + repositorySet.reps = numberOfReps - repositorySet.exercise = it + repositorySet.exercise = it - it.sets.add(repositorySet) + it.sets.add(repositorySet) - Stream.setRepository() - Stream.setLoggedSetReps(SetReps(numberOfSets + 1, numberOfReps)) - } + Stream.setRepository() + Stream.setLoggedSetReps(SetReps(numberOfSets + 1, numberOfReps)) + } - RepositoryRoutine.setLastUpdatedTime(repositoryRoutine, isNestedTransaction = true) - } - } + RepositoryRoutine.setLastUpdatedTime(repositoryRoutine, isNestedTransaction = true) } - - updateLabels() + } } - fun increaseReps() { - if (numberOfReps < 25) { - numberOfReps += 1 + updateLabels() - updateLabels() - } - } + (presenter as NavigationPresenter).nextExercise() + } - fun decreaseReps() { - if (numberOfReps > 1) { - numberOfReps -= 1 + fun increaseReps() { + if (numberOfReps < 25) { + numberOfReps += 1 - updateLabels() - } + updateLabels() } + } - fun formatSets(): String { - val exists = Repository.repositoryRoutineForTodayExists() + fun decreaseReps() { + if (numberOfReps > 1) { + numberOfReps -= 1 - if (exists) { - val routine = Repository.repositoryRoutineForToday + updateLabels() + } + } - routine.exercises.filter { - it.exerciseId == RoutineStream.exercise.exerciseId - }.firstOrNull()?.let { - val sets = it.sets + fun formatSets(): String { + val exists = Repository.repositoryRoutineForTodayExists() - if (sets.size == 1 && sets.first().reps == 0) { - return "First Set" - } else if (sets.size >= Constants.maximumNumberOfSets) { - return "12 Sets" - } else if (sets.size >= 5) { - return "Set ${sets.count() + 1}" - } + if (exists) { + val routine = Repository.repositoryRoutineForToday - var str = "" + routine.exercises.filter { + it.exerciseId == RoutineStream.exercise.exerciseId + }.firstOrNull()?.let { + val sets = it.sets - for (set in sets) { - str += set.reps.toString() + "-" - } + if (sets.size == 1 && sets.first().reps == 0) { + return "First Set" + } else if (sets.size >= Constants.maximumNumberOfSets) { + return "12 Sets" + } else if (sets.size >= 5) { + return "Set ${sets.count() + 1}" + } - str += "X" + var str = "" - return str - } + for (set in sets) { + str += set.reps.toString() + "-" } - return "First Set" + str += "X" + + return str + } } - fun formatNumberOfReps(numberOfReps: Int): String { - if (numberOfReps == 0) { - return "00" - } else if (numberOfReps < 10) { - return "0" + numberOfReps - } + return "First Set" + } - return numberOfReps.toString() + fun formatNumberOfReps(numberOfReps: Int): String { + if (numberOfReps == 0) { + return "00" + } else if (numberOfReps < 10) { + return "0" + numberOfReps } + + return numberOfReps.toString() + } } open class RepsLoggerView : AbstractView { - override var presenter: AbstractPresenter = RepsLoggerPresenter() - - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - - override fun onFinishInflate() { - super.onFinishInflate() + override var presenter: AbstractPresenter = RepsLoggerPresenter() - val repsLoggerPresenter: RepsLoggerPresenter = (presenter as RepsLoggerPresenter) + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - log_reps_button.setOnClickListener { - repsLoggerPresenter.logReps() - } + override fun onFinishInflate() { + super.onFinishInflate() - increase_reps_button.setOnClickListener { - repsLoggerPresenter.increaseReps() - } + val repsLoggerPresenter: RepsLoggerPresenter = (presenter as RepsLoggerPresenter) - decrease_reps_button.setOnClickListener { - repsLoggerPresenter.decreaseReps() - } + log_reps_button.setOnClickListener { + repsLoggerPresenter.logReps() } - fun setSets(sets: String) { - reps_logger_sets.text = sets + increase_reps_button.setOnClickListener { + repsLoggerPresenter.increaseReps() } - fun setNumberOfReps(numberOfReps: String) { - reps_logger_reps.text = numberOfReps + decrease_reps_button.setOnClickListener { + repsLoggerPresenter.decreaseReps() } -} \ No newline at end of file + } + + fun setSets(sets: String) { + reps_logger_sets.text = sets + } + + fun setNumberOfReps(numberOfReps: String) { + reps_logger_reps.text = numberOfReps + } +} diff --git a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/TimerViewPresenter.kt b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/TimerViewPresenter.kt index aaec9f1e..c075a0b1 100644 --- a/app/src/main/kotlin/com/bodyweight/fitness/view/workout/TimerViewPresenter.kt +++ b/app/src/main/kotlin/com/bodyweight/fitness/view/workout/TimerViewPresenter.kt @@ -21,284 +21,284 @@ import kotlinx.android.synthetic.main.view_timer.view.* import java.util.* object TimerShared { - var seconds = 60 - var currentSeconds = seconds - var startedLoggingSeconds = seconds - var loggedSeconds = 0 + var seconds = 60 + var currentSeconds = seconds + var startedLoggingSeconds = seconds + var loggedSeconds = 0 - var isPlaying = false - var restored = false + var isPlaying = false + var restored = false - var countDownTimer: CountDownTimer? = null + var countDownTimer: CountDownTimer? = null } class TimerPresenter : AbstractPresenter() { - override fun bindView(view: AbstractView) { - super.bindView(view) - - RoutineStream.exerciseObservable() - .bindToLifecycle(view) - .subscribe { - TimerShared.countDownTimer?.cancel() - - if (TimerShared.restored) { - TimerShared.restored = false - - restartTimer(TimerShared.currentSeconds, true, TimerShared.isPlaying) - - if (TimerShared.isPlaying) { - startTimer() - } - } else { - restartTimer(getSeconds(), false, false) - } - } - } + override fun bindView(view: AbstractView) { + super.bindView(view) - override fun saveView() { - TimerShared.restored = true + RoutineStream.exerciseObservable() + .bindToLifecycle(view) + .subscribe { + TimerShared.countDownTimer?.cancel() - super.saveView() - } + if (TimerShared.restored) { + TimerShared.restored = false - fun increaseTimer(extraSeconds: Int) { - val view = (mView as TimerView) + restartTimer(TimerShared.currentSeconds, true, TimerShared.isPlaying) - if (TimerShared.isPlaying) { - TimerShared.countDownTimer?.cancel() + if (TimerShared.isPlaying) { + startTimer() + } + } else { + restartTimer(getSeconds(), false, false) + } + } + } - TimerShared.currentSeconds += extraSeconds - TimerShared.countDownTimer = buildCountDownTimer(TimerShared.currentSeconds, false, true) + override fun saveView() { + TimerShared.restored = true - view.setMinutes(TimerShared.currentSeconds.formatMinutes()) - view.setSeconds(TimerShared.currentSeconds.formatSeconds()) + super.saveView() + } - TimerShared.countDownTimer?.start() - } else { - TimerShared.currentSeconds += extraSeconds - TimerShared.countDownTimer = buildCountDownTimer(TimerShared.currentSeconds, false, true) + fun increaseTimer(extraSeconds: Int) { + val view = (mView as TimerView) - view.setMinutes(TimerShared.currentSeconds.formatMinutes()) - view.setSeconds(TimerShared.currentSeconds.formatSeconds()) - } - } - - fun pauseTimer() { - val view = (mView as TimerView) + if (TimerShared.isPlaying) { + TimerShared.countDownTimer?.cancel() - TimerShared.countDownTimer?.cancel() + TimerShared.currentSeconds += extraSeconds + TimerShared.countDownTimer = buildCountDownTimer(TimerShared.currentSeconds, false, true) - TimerShared.isPlaying = false - TimerShared.countDownTimer = buildCountDownTimer(TimerShared.currentSeconds, false, false) + view.setMinutes(TimerShared.currentSeconds.formatMinutes()) + view.setSeconds(TimerShared.currentSeconds.formatSeconds()) - view.setMinutes(TimerShared.currentSeconds.formatMinutes()) - view.setSeconds(TimerShared.currentSeconds.formatSeconds()) + TimerShared.countDownTimer?.start() + } else { + TimerShared.currentSeconds += extraSeconds + TimerShared.countDownTimer = buildCountDownTimer(TimerShared.currentSeconds, false, true) - view.showPaused() + view.setMinutes(TimerShared.currentSeconds.formatMinutes()) + view.setSeconds(TimerShared.currentSeconds.formatSeconds()) } + } - fun startTimer() { - TimerShared.countDownTimer?.start() - } + fun pauseTimer() { + val view = (mView as TimerView) - fun restartTimer(seconds: Int, restored: Boolean, isPlaying: Boolean) { - val view = (mView as TimerView) + TimerShared.countDownTimer?.cancel() - TimerShared.countDownTimer?.cancel() + TimerShared.isPlaying = false + TimerShared.countDownTimer = buildCountDownTimer(TimerShared.currentSeconds, false, false) - TimerShared.isPlaying = isPlaying - TimerShared.currentSeconds = seconds + view.setMinutes(TimerShared.currentSeconds.formatMinutes()) + view.setSeconds(TimerShared.currentSeconds.formatSeconds()) - TimerShared.countDownTimer = buildCountDownTimer(seconds, restored, false) + view.showPaused() + } - view.setMinutes(seconds.formatMinutes()) - view.setSeconds(seconds.formatSeconds()) + fun startTimer() { + TimerShared.countDownTimer?.start() + } - view.showPaused() - } + fun restartTimer(seconds: Int, restored: Boolean, isPlaying: Boolean) { + val view = (mView as TimerView) - fun playSound() { - val view = (mView as TimerView) + TimerShared.countDownTimer?.cancel() - if (Preferences.playSoundWhenTimerStops()) { - val mediaPlayer = MediaPlayer.create(view.context, R.raw.finished) + TimerShared.isPlaying = isPlaying + TimerShared.currentSeconds = seconds - mediaPlayer.isLooping = false - mediaPlayer.start() - } - } + TimerShared.countDownTimer = buildCountDownTimer(seconds, restored, false) - fun onClickTimeLayout() { - val view = (mView as TimerView) + view.setMinutes(seconds.formatMinutes()) + view.setSeconds(seconds.formatSeconds()) - pauseTimer() + view.showPaused() + } - val timePickerDialog = TimePickerDialog(view.context, { view, minutes, seconds -> - TimerShared.currentSeconds = seconds + minutes * 60 + fun playSound() { + val view = (mView as TimerView) - if (TimerShared.currentSeconds < 10) { - TimerShared.currentSeconds = 10 - } + if (Preferences.playSoundWhenTimerStops()) { + val mediaPlayer = MediaPlayer.create(view.context, R.raw.finished) - restartTimer(TimerShared.currentSeconds, false, false) + mediaPlayer.isLooping = false + mediaPlayer.start() + } + } - TimerShared.seconds = TimerShared.currentSeconds + fun onClickTimeLayout() { + val view = (mView as TimerView) - val save = (TimerShared.seconds * 1000).toLong() + pauseTimer() - Preferences.setTimerValue(RoutineStream.exercise.exerciseId, save) - }, TimerShared.currentSeconds.formatMinutesAsNumber(), TimerShared.currentSeconds.formatSecondsAsNumber(), true) + val timePickerDialog = TimePickerDialog(view.context, { view, minutes, seconds -> + TimerShared.currentSeconds = seconds + minutes * 60 - timePickerDialog.show() - } + if (TimerShared.currentSeconds < 10) { + TimerShared.currentSeconds = 10 + } - fun onClickIncreaseTimeButton() { - increaseTimer(5) - } + restartTimer(TimerShared.currentSeconds, false, false) - fun onClickStartStopTimeButton() { - if (TimerShared.isPlaying) { - logTime() + TimerShared.seconds = TimerShared.currentSeconds - pauseTimer() - } else { - startTimer() - } - } + val save = (TimerShared.seconds * 1000).toLong() - fun onClickRestartTimeButton() { - logTime() + Preferences.setTimerValue(RoutineStream.exercise.exerciseId, save) + }, TimerShared.currentSeconds.formatMinutesAsNumber(), TimerShared.currentSeconds.formatSecondsAsNumber(), true) - restartTimer(getSeconds(), false, false) - } + timePickerDialog.show() + } - fun buildCountDownTimer(seconds: Int, restored: Boolean, increaseTimer: Boolean): CountDownTimer? { - val view = (mView as TimerView) + fun onClickIncreaseTimeButton() { + increaseTimer(5) + } - if (increaseTimer) { - TimerShared.loggedSeconds += 5 - } else { - if (restored) { - TimerShared.loggedSeconds = TimerShared.startedLoggingSeconds - } else { - TimerShared.startedLoggingSeconds = seconds - TimerShared.loggedSeconds = seconds - } - } + fun onClickStartStopTimeButton() { + if (TimerShared.isPlaying) { + logTime() - return object : CountDownTimer((seconds * 1000).toLong(), 100) { - override fun onTick(millisUntilFinished: Long) { - val timerSeconds = millisUntilFinished.toInt() / 1000 + pauseTimer() + } else { + startTimer() + } + } + + fun onClickRestartTimeButton() { + logTime() + + restartTimer(getSeconds(), false, false) + } + + fun buildCountDownTimer(seconds: Int, restored: Boolean, increaseTimer: Boolean): CountDownTimer? { + val view = (mView as TimerView) + + if (increaseTimer) { + TimerShared.loggedSeconds += 5 + } else { + if (restored) { + TimerShared.loggedSeconds = TimerShared.startedLoggingSeconds + } else { + TimerShared.startedLoggingSeconds = seconds + TimerShared.loggedSeconds = seconds + } + } - TimerShared.isPlaying = true - TimerShared.currentSeconds = timerSeconds + return object : CountDownTimer((seconds * 1000).toLong(), 100) { + override fun onTick(millisUntilFinished: Long) { + val timerSeconds = millisUntilFinished.toInt() / 1000 - view.setMinutes(timerSeconds.formatMinutes()) - view.setSeconds(timerSeconds.formatSeconds()) + TimerShared.isPlaying = true + TimerShared.currentSeconds = timerSeconds - view.showPlaying() - } + view.setMinutes(timerSeconds.formatMinutes()) + view.setSeconds(timerSeconds.formatSeconds()) - override fun onFinish() { - logTime() + view.showPlaying() + } - restartTimer(getSeconds(), false, false) + override fun onFinish() { + logTime() - playSound() - } - } - } + restartTimer(getSeconds(), false, false) - fun getSeconds(): Int { - return (Preferences.getTimerValueForExercise(RoutineStream.exercise.exerciseId, 60 * 1000) / 1000).toInt() + playSound() + } } + } - fun logTime() { - if (Preferences.automaticallyLogWorkoutTime() && RoutineStream.exercise.isTimedSet) { - val loggedSeconds = TimerShared.loggedSeconds - TimerShared.currentSeconds + fun getSeconds(): Int { + return (Preferences.getTimerValueForExercise(RoutineStream.exercise.exerciseId, 60 * 1000) / 1000).toInt() + } - if (loggedSeconds > 0) { - if (logIntoRealm(loggedSeconds)) { - Stream.setLoggedSeconds(loggedSeconds) - } - } + fun logTime() { + if (Preferences.automaticallyLogWorkoutTime() && RoutineStream.exercise.isTimedSet) { + val loggedSeconds = TimerShared.loggedSeconds - TimerShared.currentSeconds + + if (loggedSeconds > 0) { + if (logIntoRealm(loggedSeconds)) { + Stream.setLoggedSeconds(loggedSeconds) } + } } + } - private fun logIntoRealm(logSeconds: Int): Boolean { - val realm = Repository.realm - val repositoryRoutine = Repository.repositoryRoutineForToday + private fun logIntoRealm(logSeconds: Int): Boolean { + val realm = Repository.realm + val repositoryRoutine = Repository.repositoryRoutineForToday - var isLogged: Boolean = false + var isLogged: Boolean = false - realm.executeTransaction { - repositoryRoutine.exercises - .filter { it.exerciseId == RoutineStream.exercise.exerciseId } - .firstOrNull()?.let { + realm.executeTransaction { + repositoryRoutine.exercises + .filter { it.exerciseId == RoutineStream.exercise.exerciseId } + .firstOrNull()?.let { - val numberOfSets = it.sets.size - if (numberOfSets < Constants.maximumNumberOfSets) { - val firstSet = it.sets.first() + val numberOfSets = it.sets.size + if (numberOfSets < Constants.maximumNumberOfSets) { + val firstSet = it.sets.first() - if (numberOfSets == 1 && firstSet.isTimed && firstSet.seconds == 0) { - if (firstSet.isTimed && firstSet.seconds == 0) { - firstSet.seconds = logSeconds - } - } else { - val repositorySet = realm.createObject(RepositorySet::class.java, "Set-" + UUID.randomUUID().toString()) + if (numberOfSets == 1 && firstSet.isTimed && firstSet.seconds == 0) { + if (firstSet.isTimed && firstSet.seconds == 0) { + firstSet.seconds = logSeconds + } + } else { + val repositorySet = realm.createObject(RepositorySet::class.java, "Set-" + UUID.randomUUID().toString()) - repositorySet.isTimed = true - repositorySet.seconds = logSeconds - repositorySet.weight = 0.0 - repositorySet.reps = 0 + repositorySet.isTimed = true + repositorySet.seconds = logSeconds + repositorySet.weight = 0.0 + repositorySet.reps = 0 - repositorySet.exercise = it + repositorySet.exercise = it - it.sets.add(repositorySet) - } + it.sets.add(repositorySet) + } - RepositoryRoutine.setLastUpdatedTime(repositoryRoutine, isNestedTransaction = true) + RepositoryRoutine.setLastUpdatedTime(repositoryRoutine, isNestedTransaction = true) - isLogged = true - } - } + isLogged = true + } } - - return isLogged } + + return isLogged + } } open class TimerView : AbstractView { - override var presenter: AbstractPresenter = TimerPresenter() + override var presenter: AbstractPresenter = TimerPresenter() - constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - override fun onFinishInflate() { - super.onFinishInflate() + override fun onFinishInflate() { + super.onFinishInflate() - val presenter = (presenter as TimerPresenter) + val presenter = (presenter as TimerPresenter) - timer_layout.setOnClickListener { presenter.onClickTimeLayout() } - increase_timer_button.setOnClickListener { presenter.onClickIncreaseTimeButton() } - start_stop_timer_button.setOnClickListener { presenter.onClickStartStopTimeButton() } - restart_timer_button.setOnClickListener { presenter.onClickRestartTimeButton() } - } + timer_layout.setOnClickListener { presenter.onClickTimeLayout() } + increase_timer_button.setOnClickListener { presenter.onClickIncreaseTimeButton() } + start_stop_timer_button.setOnClickListener { presenter.onClickStartStopTimeButton() } + restart_timer_button.setOnClickListener { presenter.onClickRestartTimeButton() } + } - fun setMinutes(text: String) { - timer_minutes.text = text - } + fun setMinutes(text: String) { + timer_minutes.text = text + } - fun setSeconds(text: String) { - timer_seconds.text = text - } + fun setSeconds(text: String) { + timer_seconds.text = text + } - fun showPlaying() { - start_stop_timer_button.setImageResource(R.drawable.action_pause) - } + fun showPlaying() { + start_stop_timer_button.setImageResource(R.drawable.action_pause) + } - fun showPaused() { - start_stop_timer_button.setImageResource(R.drawable.action_play) - } -} \ No newline at end of file + fun showPaused() { + start_stop_timer_button.setImageResource(R.drawable.action_play) + } +} diff --git a/app/src/main/res/layout/view_dashboard_section.xml b/app/src/main/res/layout/view_dashboard_section.xml index e8d87209..935ab0aa 100644 --- a/app/src/main/res/layout/view_dashboard_section.xml +++ b/app/src/main/res/layout/view_dashboard_section.xml @@ -1,7 +1,6 @@ @@ -9,40 +8,40 @@ + android:gravity="center" + android:orientation="horizontal"> + android:paddingRight="20dp"> + android:textSize="18dp" + app:robotoTypeface="roboto_regular" /> + android:textSize="14dp" + app:robotoTypeface="roboto_light" /> \ No newline at end of file diff --git a/app/src/main/res/layout/view_home.xml b/app/src/main/res/layout/view_home.xml index 21b58cf8..ce795d83 100644 --- a/app/src/main/res/layout/view_home.xml +++ b/app/src/main/res/layout/view_home.xml @@ -66,29 +66,29 @@ + android:paddingBottom="8dp" + android:paddingTop="8dp">