From 0316099a0fef0d8dca1691a145360c3c1254f871 Mon Sep 17 00:00:00 2001 From: tsb1995 <47466105+tsb1995@users.noreply.github.com> Date: Fri, 17 Apr 2020 12:10:02 -0700 Subject: [PATCH] add base app --- .gitignore | 14 ++ .idea/codeStyles/Project.xml | 122 +++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/gradle.xml | 20 ++ .idea/misc.xml | 9 + .idea/runConfigurations.xml | 12 ++ app/.gitignore | 1 + app/build.gradle | 67 +++++++ app/proguard-rules.pro | 21 +++ .../tutortoolkit/ExampleInstrumentedTest.kt | 24 +++ app/src/main/AndroidManifest.xml | 21 +++ app/src/main/ic_launcher-playstore.png | Bin 0 -> 28980 bytes .../com/taymath/tutortoolkit/MainActivity.kt | 17 ++ .../tutortoolkit/addgrade/AddGradeFragment.kt | 68 +++++++ .../addgrade/AddGradeViewModel.kt | 79 ++++++++ .../addgrade/AddGradeViewModelFactory.kt | 20 ++ .../addstudent/AddStudentFragment.kt | 59 ++++++ .../addstudent/AddStudentViewModel.kt | 67 +++++++ .../addstudent/AddStudentViewModelFactory.kt | 18 ++ .../chooseicon/ChooseIconFragment.kt | 59 ++++++ .../chooseicon/ChooseIconViewModel.kt | 81 +++++++++ .../chooseicon/ChooseIconViewModelFactory.kt | 16 ++ .../tutortoolkit/studentdatabase/Grade.kt | 30 +++ .../tutortoolkit/studentdatabase/Student.kt | 47 +++++ .../studentdatabase/StudentDatabase.kt | 49 +++++ .../studentdatabase/StudentDatabaseDao.kt | 87 +++++++++ .../studentdetail/GradeAdapter.kt | 66 +++++++ .../studentdetail/GradeBindingUtils.kt | 26 +++ .../studentdetail/StudentDetailFragment.kt | 79 ++++++++ .../studentdetail/StudentDetailViewModel.kt | 97 ++++++++++ .../StudentDetailViewModelFactory.kt | 19 ++ .../studentlist/StudentAdapter.kt | 55 ++++++ .../studentlist/StudentBindingUtils.kt | 35 ++++ .../studentlist/StudentListFragment.kt | 88 +++++++++ .../studentlist/StudentListViewModel.kt | 57 ++++++ .../StudentListViewModelFactory.kt | 18 ++ .../main/res/drawable-v24/ic_item_test.xml | 31 ++++ .../drawable-v24/ic_launcher_foreground.xml | 30 +++ .../res/drawable/ic_launcher_background.xml | 74 ++++++++ app/src/main/res/drawable/icon_1.png | Bin 0 -> 5925 bytes app/src/main/res/drawable/icon_2.png | Bin 0 -> 5887 bytes app/src/main/res/drawable/icon_3.png | Bin 0 -> 5932 bytes app/src/main/res/drawable/icon_4.png | Bin 0 -> 5788 bytes app/src/main/res/drawable/icon_5.png | Bin 0 -> 5607 bytes app/src/main/res/drawable/icon_6.png | Bin 0 -> 5828 bytes app/src/main/res/drawable/icon_7.png | Bin 0 -> 5587 bytes app/src/main/res/drawable/icon_8.png | Bin 0 -> 5915 bytes app/src/main/res/layout/activity_main.xml | 16 ++ .../main/res/layout/fragment_add_grade.xml | 84 +++++++++ .../main/res/layout/fragment_add_student.xml | 120 ++++++++++++ .../main/res/layout/fragment_choose_icon.xml | 58 ++++++ .../res/layout/fragment_student_detail.xml | 85 +++++++++ .../main/res/layout/fragment_student_list.xml | 40 ++++ app/src/main/res/layout/list_item_grade.xml | 53 ++++++ app/src/main/res/layout/list_item_student.xml | 72 ++++++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2131 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 2976 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 3730 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1494 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 1700 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2262 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 3132 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 4478 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 5436 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 4894 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 8383 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 8791 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 7144 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 13367 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 12976 bytes app/src/main/res/navigation/navigation.xml | 59 ++++++ app/src/main/res/values/colors.xml | 13 ++ app/src/main/res/values/dimens.xml | 7 + app/src/main/res/values/strings.xml | 26 +++ app/src/main/res/values/styles.xml | 21 +++ .../taymath/tutortoolkit/ExampleUnitTest.kt | 59 ++++++ build.gradle | 41 +++++ gradle.properties | 21 +++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 ++++++++++++++++++ gradlew.bat | 84 +++++++++ settings.gradle | 2 + 85 files changed, 2737 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/taymath/tutortoolkit/ExampleInstrumentedTest.kt create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/com/taymath/tutortoolkit/MainActivity.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/addgrade/AddGradeFragment.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/addgrade/AddGradeViewModel.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/addgrade/AddGradeViewModelFactory.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentFragment.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModel.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModelFactory.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconFragment.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModel.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModelFactory.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Grade.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Student.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabase.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabaseDao.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeAdapter.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeBindingUtils.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailFragment.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModel.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModelFactory.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentAdapter.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentBindingUtils.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListFragment.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModel.kt create mode 100644 app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModelFactory.kt create mode 100644 app/src/main/res/drawable-v24/ic_item_test.xml create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/icon_1.png create mode 100644 app/src/main/res/drawable/icon_2.png create mode 100644 app/src/main/res/drawable/icon_3.png create mode 100644 app/src/main/res/drawable/icon_4.png create mode 100644 app/src/main/res/drawable/icon_5.png create mode 100644 app/src/main/res/drawable/icon_6.png create mode 100644 app/src/main/res/drawable/icon_7.png create mode 100644 app/src/main/res/drawable/icon_8.png create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/fragment_add_grade.xml create mode 100644 app/src/main/res/layout/fragment_add_student.xml create mode 100644 app/src/main/res/layout/fragment_choose_icon.xml create mode 100644 app/src/main/res/layout/fragment_student_detail.xml create mode 100644 app/src/main/res/layout/fragment_student_list.xml create mode 100644 app/src/main/res/layout/list_item_grade.xml create mode 100644 app/src/main/res/layout/list_item_student.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/navigation/navigation.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/test/java/com/taymath/tutortoolkit/ExampleUnitTest.kt create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..88ea3aa --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,122 @@ + + + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+ + +
+
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..37a7509 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..2874e5c --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' +apply plugin: 'androidx.navigation.safeargs' + +android { + compileSdkVersion 29 + buildToolsVersion "29.0.3" + + defaultConfig { + applicationId "com.taymath.tutortoolkit" + minSdkVersion 19 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + vectorDrawables.useSupportLibrary = true + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + // Enables data binding. + dataBinding { + enabled = true + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$version_kotlin" + + + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.core:core-ktx:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + + // Support libraries + implementation "androidx.appcompat:appcompat:$version_appcompat" + implementation "androidx.fragment:fragment:$version_fragment" + implementation "androidx.constraintlayout:constraintlayout:$version_constraint_layout" + + // Room and Lifecycle dependencies + implementation "androidx.room:room-runtime:$version_room" + kapt "androidx.room:room-compiler:$version_room" + implementation "androidx.lifecycle:lifecycle-extensions:$version_lifecycle_extensions" + + // Navigation + implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1' + implementation 'androidx.navigation:navigation-ui-ktx:2.2.1' + + // Coroutines + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version_coroutine" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version_coroutine" + + // Testing + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/com/taymath/tutortoolkit/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/taymath/tutortoolkit/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..4542276 --- /dev/null +++ b/app/src/androidTest/java/com/taymath/tutortoolkit/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.taymath.tutortoolkit + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.taymath.tutortoolkit", appContext.packageName) + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..e000ff3 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..78177541aeab15fd260948bc6a74c8eb5c251142 GIT binary patch literal 28980 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 + val navigateToStudentList: LiveData + get() = _navigateToStudentList + + val gradeFloatText = MutableLiveData() + + // Initialize mediatorLiveData containing Student Class + private val student = MediatorLiveData() + + fun getStudent() = student + + // Add Student from database to our mediatorLiveData + init { + student.addSource(database.getStudentWithId(student_id), student::setValue) + } + +// fun validateForm(): Boolean { +// return gradeFloatText.value!!.isNotEmpty() +// } + + + // Initialize Grade and add to grade_table + fun onAddGrade( + gradeString: String, + gradeFloat: Float, + noteString: String, + studentNameString: String + ) { + uiScope.launch { + withContext(Dispatchers.IO) { + val newGrade = Grade() + newGrade.studentNameString = studentNameString + newGrade.gradeString = gradeString + newGrade.gradeFloat = gradeFloat + newGrade.noteString = noteString + newGrade.studentIdLong = student_id + insert(newGrade) + } + } + _navigateToStudentList.value = true + } + + override fun onCleared() { + super.onCleared() + viewModelJob.cancel() + } + + fun doneNavigating() { + _navigateToStudentList.value = false + } + + private fun insert(grade: Grade) { + database.insertGrade(grade) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/addgrade/AddGradeViewModelFactory.kt b/app/src/main/java/com/taymath/tutortoolkit/addgrade/AddGradeViewModelFactory.kt new file mode 100644 index 0000000..8f786dd --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/addgrade/AddGradeViewModelFactory.kt @@ -0,0 +1,20 @@ +package com.taymath.tutortoolkit.addgrade + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.taymath.tutortoolkit.studentdatabase.Student +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao + +class AddGradeViewModelFactory( + private val student_id: Long, + private val dataSource: StudentDatabaseDao +) : ViewModelProvider.Factory { + + @Suppress("unchecked_cast") + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(AddGradeViewModel::class.java)) { + return AddGradeViewModel(student_id, dataSource) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} diff --git a/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentFragment.kt b/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentFragment.kt new file mode 100644 index 0000000..3532589 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentFragment.kt @@ -0,0 +1,59 @@ +package com.taymath.tutortoolkit.addstudent + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProviders +import androidx.navigation.fragment.findNavController +import com.taymath.tutortoolkit.R +import com.taymath.tutortoolkit.databinding.FragmentAddStudentBindingImpl +import com.taymath.tutortoolkit.studentdatabase.StudentDatabase + +class AddStudentFragment : Fragment() { + + /** + * Called when the Fragment is ready to display content to the screen. + * + * This function uses DataBindingUtil to inflate R.layout.fragment_add_student. + */ + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + + // Get a reference to the binding object and inflate the fragment views. + val binding: FragmentAddStudentBindingImpl = DataBindingUtil.inflate( + inflater, R.layout.fragment_add_student, container, false) + + // Get reference to application + val application = requireNotNull(this.activity).application + + // Get a reference to the DAO + val dataSource = StudentDatabase.getInstance(application).studentDatabaseDao + + // Create instance of viewModelFactory using DAO and application + val viewModelFactory = AddStudentViewModelFactory(dataSource) + + // Get reference to viewModel + val addStudentViewModel = + ViewModelProviders.of( + this, viewModelFactory).get(AddStudentViewModel::class.java) + + // Add our viewModel to binding + binding.addStudentViewModel = addStudentViewModel + + binding.setLifecycleOwner(this) + + // Listen for when we navigate to student list + addStudentViewModel.navigateToStudentList.observe(viewLifecycleOwner, Observer { + if (it == true) { // Observed state is true. + this.findNavController().navigate( + AddStudentFragmentDirections.actionAddStudentFragmentToStudentListFragment()) + addStudentViewModel.doneNavigating() + } + }) + return binding.root + } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModel.kt b/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModel.kt new file mode 100644 index 0000000..bc40714 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModel.kt @@ -0,0 +1,67 @@ +package com.taymath.tutortoolkit.addstudent + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.taymath.tutortoolkit.studentdatabase.Student +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao +import kotlinx.coroutines.* + +class AddStudentViewModel( + val database: StudentDatabaseDao +) : ViewModel() { + + // Initialize viewModelJob + private val viewModelJob = Job() + + // Initialize uiScope + private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob) + + // Setup Livdata to signal when to navigate to studentList + private val _navigateToStudentList = MutableLiveData() + val navigateToStudentList: LiveData + get() = _navigateToStudentList + + // Initialize Student and add to student_table + fun onAddStudent(studentNameString : String, subjectString: String, + gradeLevelString: String, addressString: String, emailString: String) { + uiScope.launch { + withContext(Dispatchers.IO) { + val newStudent = Student() + newStudent.studentNameString = studentNameString + newStudent.subjectString = subjectString + newStudent.emailString = emailString + newStudent.gradeLevelString = gradeLevelString + newStudent.addressString = addressString + insert(newStudent) + } + } + _navigateToStudentList.value = true + } + + override fun onCleared() { + super.onCleared() + viewModelJob.cancel() + } + + fun doneNavigating() { + _navigateToStudentList.value = null + } + + private suspend fun insert(student: Student) { + withContext(Dispatchers.IO) { + database.insertStudent(student) + } + } + +// fun onSetSleepQuality(quality: Int) { +// uiScope.launch { +// withContext(Dispatchers.IO) { +// val tonight = database.get(sleepNightKey) ?: return@withContext +// tonight.sleepQuality = quality +// database.update(tonight) +// } +// _navigateToSleepTracker.value = true +// } +// } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModelFactory.kt b/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModelFactory.kt new file mode 100644 index 0000000..58c5206 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/addstudent/AddStudentViewModelFactory.kt @@ -0,0 +1,18 @@ +package com.taymath.tutortoolkit.addstudent + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao + +class AddStudentViewModelFactory( + private val dataSource: StudentDatabaseDao +) : ViewModelProvider.Factory { + + @Suppress("unchecked_cast") + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(AddStudentViewModel::class.java)) { + return AddStudentViewModel(dataSource) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} diff --git a/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconFragment.kt b/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconFragment.kt new file mode 100644 index 0000000..f192317 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconFragment.kt @@ -0,0 +1,59 @@ +package com.taymath.tutortoolkit.chooseicon + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProviders +import androidx.navigation.fragment.findNavController +import com.taymath.tutortoolkit.R +import com.taymath.tutortoolkit.databinding.FragmentChooseIconBinding +import com.taymath.tutortoolkit.studentdatabase.StudentDatabase + +class ChooseIconFragment : Fragment() { + + /** + * Called when the Fragment is ready to display content to the screen. + * + * This function uses DataBindingUtil to inflate R.layout.fragment_sleep_quality. + */ + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + + // Get a reference to the binding object and inflate the fragment views. + val binding: FragmentChooseIconBinding = DataBindingUtil.inflate( + inflater, R.layout.fragment_choose_icon, container, false) + + val application = requireNotNull(this.activity).application + +// val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!) + + // Create an instance of the ViewModel Factory. + val dataSource = StudentDatabase.getInstance(application).studentDatabaseDao + val viewModelFactory = ChooseIconViewModelFactory(dataSource) + + // Get a reference to the ViewModel associated with this fragment. + val chooseIconViewModel = + ViewModelProviders.of( + this, viewModelFactory).get(ChooseIconViewModel::class.java) + + // To use the View Model with data binding, you have to explicitly + // give the binding object a reference to it. + binding.chooseIconViewModel = chooseIconViewModel + + // Add an Observer to the state variable for Navigating when a Quality icon is tapped. +// chooseIconViewModel.navigateToSleepTracker.observe(this, Observer { +// if (it == true) { // Observed state is true. +// this.findNavController().navigate( +// SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment()) +// // Reset state to make sure we only navigate once, even if the device +// // has a configuration change. +// sleepQualityViewModel.doneNavigating() +// } +// }) + + return binding.root + } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModel.kt b/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModel.kt new file mode 100644 index 0000000..83404eb --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModel.kt @@ -0,0 +1,81 @@ +package com.taymath.tutortoolkit.chooseicon + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao +import kotlinx.coroutines.* + +class ChooseIconViewModel( + val database: StudentDatabaseDao) : ViewModel() { + + /** Coroutine setup variables */ + + /** + * viewModelJob allows us to cancel all coroutines started by this ViewModel. + */ + private val viewModelJob = Job() + + /** + * A [CoroutineScope] keeps track of all coroutines started by this ViewModel. + * + * Because we pass it [viewModelJob], any coroutine started in this scope can be cancelled + * by calling `viewModelJob.cancel()` + * + * By default, all coroutines started in uiScope will launch in [Dispatchers.Main] which is + * the main thread on Android. This is a sensible default because most coroutines started by + * a [ViewModel] update the UI after performing some processing. + */ + private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob) + + /** + * Variable that tells the fragment whether it should navigate to [SleepTrackerFragment]. + * + * This is `private` because we don't want to expose the ability to set [MutableLiveData] to + * the [Fragment] + */ + private val _navigateToSleepTracker = MutableLiveData() + + /** + * When true immediately navigate back to the [SleepTrackerFragment] + */ + val navigateToSleepTracker: LiveData + get() = _navigateToSleepTracker + + /** + * Cancels all coroutines when the ViewModel is cleared, to cleanup any pending work. + * + * onCleared() gets called when the ViewModel is destroyed. + */ + override fun onCleared() { + super.onCleared() + viewModelJob.cancel() + } + + /** + * Call this immediately after navigating to [SleepTrackerFragment] + */ + fun doneNavigating() { + _navigateToSleepTracker.value = null + } + + /** + * Sets the sleep quality and updates the database. + * + * Then navigates back to the SleepTrackerFragment. + */ +// fun onSetSleepQuality(quality: Int) { +// uiScope.launch { +// // IO is a thread pool for running operations that access the disk, such as +// // our Room database. +// withContext(Dispatchers.IO) { +// val tonight = database.get(sleepNightKey) ?: return@withContext +// tonight.sleepQuality = quality +// database.update(tonight) +// } +// +// // Setting this state variable to true will alert the observer and trigger navigation. +// _navigateToSleepTracker.value = true +// } +// } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModelFactory.kt b/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModelFactory.kt new file mode 100644 index 0000000..cffed31 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/chooseicon/ChooseIconViewModelFactory.kt @@ -0,0 +1,16 @@ +package com.taymath.tutortoolkit.chooseicon + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao + +class ChooseIconViewModelFactory( + private val dataSource: StudentDatabaseDao) : ViewModelProvider.Factory { + @Suppress("unchecked_cast") + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(ChooseIconViewModel::class.java)) { + return ChooseIconViewModel(dataSource) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Grade.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Grade.kt new file mode 100644 index 0000000..4f81180 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Grade.kt @@ -0,0 +1,30 @@ +package com.taymath.tutortoolkit.studentdatabase + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "grade_table") +data class Grade ( + + @PrimaryKey(autoGenerate = true) + var gradeId: Long = 0L, + + @ColumnInfo(name="grade_string") + var gradeString: String = "BLANK Grade", + + @ColumnInfo(name = "student_name_string") + var studentNameString: String = "CHECK_GRADE.KT", + + @ColumnInfo(name = "grade_float") + var gradeFloat: Float = 0F, + + @ColumnInfo(name = "time_milli") + val startTimeMilli: Long = System.currentTimeMillis(), + + @ColumnInfo(name = "note_string") + var noteString: String = "CHECK_GRADE.KT", + + @ColumnInfo(name= "student_id_long") + var studentIdLong: Long = 0L +) \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Student.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Student.kt new file mode 100644 index 0000000..ff390c5 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/Student.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.taymath.tutortoolkit.studentdatabase + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "student_table") +data class Student ( + + @PrimaryKey(autoGenerate = true) + var studentId: Long = 0L, + + @ColumnInfo(name="student_name") + var studentNameString: String = "BLANK STUDENT", + + @ColumnInfo(name = "todo_string") + var todoString: String = "CHECK_Student.KT", + + @ColumnInfo(name = "subject") + var subjectString: String = "CHECK_Student.KT", + + @ColumnInfo(name = "grade_level") + var gradeLevelString: String = "CHECK_Student.KT", + + @ColumnInfo(name = "address") + var addressString: String = "CHECK_Student.KT", + + @ColumnInfo(name = "email") + var emailString: String = "CHECK_Student.KT" + +) diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabase.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabase.kt new file mode 100644 index 0000000..a97f608 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabase.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.taymath.tutortoolkit.studentdatabase + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase + +@Database(entities = [Student::class, Grade::class], version = 1, exportSchema = false) +abstract class StudentDatabase : RoomDatabase() { + + abstract val studentDatabaseDao: StudentDatabaseDao + + companion object { + @Volatile + private var INSTANCE: StudentDatabase? = null + + fun getInstance(context: Context): StudentDatabase { + synchronized(this) { + var instance = INSTANCE + + if (instance == null) { + instance = Room.databaseBuilder( + context.applicationContext, + StudentDatabase::class.java, + "student_database" + ).fallbackToDestructiveMigration().build() + } + + return instance + } + } + } +} diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabaseDao.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabaseDao.kt new file mode 100644 index 0000000..e191532 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdatabase/StudentDatabaseDao.kt @@ -0,0 +1,87 @@ +/* + * Copyright 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.taymath.tutortoolkit.studentdatabase + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import androidx.room.Update + +@Dao +interface StudentDatabaseDao { + + // Student Table Dao + @Insert + fun insertStudent(student: Student) + + @Update + fun updateStudent(student: Student) + + @Query("DELETE FROM student_table WHERE studentId = :studentId") + fun deleteStudent(studentId: Long) + + @Query("DELETE FROM student_table") + fun clearStudentTable() + + @Query("SELECT * FROM student_table ORDER BY studentId DESC LIMIT 1") + fun getStudent(): Student? + + @Query("SELECT * FROM student_table ORDER BY studentId DESC") + fun getAllStudents(): LiveData> + + @Query("SELECT * from student_table WHERE studentId = :key") + fun getStudentWithId(key: Long): LiveData + + @Query("SELECT * FROM student_table WHERE studentId = :studentId") + fun getStudentClassWithId(studentId: Long): Student + + @Query("SELECT * from student_table WHERE student_name = :studentName") + fun getStudentWithName(studentName: String): LiveData + + + + // Grade Table Dao + @Insert + fun insertGrade(grade: Grade) + + @Update + fun updateGrade(grade: Grade) + + @Query("DELETE FROM grade_table WHERE student_id_long = :studentId") + fun deleteGradeTable(studentId: Long) + + @Query("DELETE FROM grade_table") + fun clearGradeTable() + + @Query("SELECT * FROM grade_table ORDER BY gradeId DESC LIMIT 1") + fun getGrade(): Grade? + + @Query("SELECT * FROM grade_table ORDER BY student_name_string DESC") + fun getAllGrades(): LiveData> + + @Query("SELECT * FROM grade_table WHERE student_name_string = :studentName") + fun getGradesForStudent(studentName: String): LiveData> + + @Query("SELECT * from grade_table WHERE gradeId = :key") + fun getGradeWithId(key: Long): LiveData + + @Query("SELECT * from grade_table WHERE student_id_long = :studentId") + fun getGradesWithStudentId(studentId: Long): LiveData> + +} + diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeAdapter.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeAdapter.kt new file mode 100644 index 0000000..ba0f8cb --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeAdapter.kt @@ -0,0 +1,66 @@ +package com.taymath.tutortoolkit.studentdetail + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.taymath.tutortoolkit.databinding.ListItemGradeBinding +import com.taymath.tutortoolkit.studentdatabase.Grade + +class GradeAdapter : ListAdapter(GradeDiffCallback()) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder.from(parent) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + class ViewHolder private constructor(val binding: ListItemGradeBinding) + : RecyclerView.ViewHolder(binding.root) { + + fun bind(item: Grade) { + binding.grade = item + binding.executePendingBindings() + } + + companion object { + fun from(parent: ViewGroup): ViewHolder { + val layoutInflater = LayoutInflater.from(parent.context) + val binding = ListItemGradeBinding.inflate(layoutInflater, parent, false) + return ViewHolder(binding) + } + } + } + + class GradeDiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Grade, newItem: Grade): Boolean { + return oldItem.gradeId == newItem.gradeId + } + + override fun areContentsTheSame(oldItem: Grade, newItem: Grade): Boolean { + return oldItem == newItem + } + } +} + +/** + * Callback for calculating the diff between two non-null items in a list. + * + * Used by ListAdapter to calculate the minumum number of changes between and old list and a new + * list that's been passed to `submitList`. + */ + + +class GradeDiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Grade, newItem: Grade): Boolean { + return oldItem.gradeId == newItem.gradeId + } + + override fun areContentsTheSame(oldItem: Grade, newItem: Grade): Boolean { + return oldItem == newItem + } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeBindingUtils.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeBindingUtils.kt new file mode 100644 index 0000000..4b4a9f4 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/GradeBindingUtils.kt @@ -0,0 +1,26 @@ +package com.taymath.tutortoolkit.studentdetail + +import android.widget.TextView +import androidx.databinding.BindingAdapter +import com.taymath.tutortoolkit.studentdatabase.Grade + +@BindingAdapter("gradeFloat") +fun TextView.setGradeFloat(item: Grade?){ + item?.let { + text = item.gradeFloat.toString() + } +} + +@BindingAdapter("gradeString") +fun TextView.setSubjectText(item: Grade?){ + item?.let { + text =item.gradeString + } +} + +@BindingAdapter("noteString") +fun TextView.setStudentNameText(item: Grade?){ + item?.let { + text =item.noteString + } +} diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailFragment.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailFragment.kt new file mode 100644 index 0000000..9de61f2 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailFragment.kt @@ -0,0 +1,79 @@ +package com.taymath.tutortoolkit.studentdetail + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProviders +import androidx.navigation.fragment.findNavController +import com.taymath.tutortoolkit.R +import com.taymath.tutortoolkit.databinding.FragmentStudentDetailBinding +import com.taymath.tutortoolkit.studentdatabase.StudentDatabase +import com.taymath.tutortoolkit.studentlist.StudentListFragmentDirections +import com.taymath.tutortoolkit.studentlist.StudentListener + +class StudentDetailFragment: Fragment() { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + + val binding:FragmentStudentDetailBinding = DataBindingUtil.inflate( + inflater, R.layout.fragment_student_detail, container,false + ) + + val application = requireNotNull(this.activity).application + val arguments = StudentDetailFragmentArgs.fromBundle(arguments!!) + + // Create an instance of the ViewModel Factory. + val dataSource = StudentDatabase.getInstance(application).studentDatabaseDao + val viewModelFactory = StudentDetailViewModelFactory(dataSource, arguments.studentId) + + // Get a reference to the ViewModel associated with this fragment. + val studentDetailViewModel = + ViewModelProviders.of( + this, viewModelFactory).get(StudentDetailViewModel::class.java) + + // To use the View Model with data binding, you have to explicitly + // give the binding object a reference to it. + binding.studentDetailViewModel = studentDetailViewModel + + binding.setLifecycleOwner(this) + + // Add an Observer to the state variable for Navigating when Add Grade button is clicked. + studentDetailViewModel.navigateToAddGrade.observe(viewLifecycleOwner, Observer { + if (it == true) { // Observed state is true. + this.findNavController().navigate( + StudentDetailFragmentDirections.actionStudentDetailFragmentToAddGradeFragment(arguments.studentId)) + // Reset state to make sure we only navigate once, even if the device + // has a configuration change. + studentDetailViewModel.doneNavigating() + } + }) + + // Add an Observer to the state variable for Navigating when Add Grade button is clicked. + studentDetailViewModel.navigateToStudentList.observe(viewLifecycleOwner, Observer { + if (it == true) { // Observed state is true. + this.findNavController().navigate( + StudentDetailFragmentDirections.actionStudentDetailFragmentToStudentListFragment()) + // Reset state to make sure we only navigate once, even if the device + // has a configuration change. + studentDetailViewModel.doneNavigating() + } + }) + + // Initialize adapter and add to gradeList + val adapter = GradeAdapter() + binding.gradeList.adapter = adapter + + // If we have a list of grades, send it to the adapter + studentDetailViewModel.grades.observe(viewLifecycleOwner, Observer { + it?.let { + adapter.submitList(it) + } + }) + + return binding.root + } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModel.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModel.kt new file mode 100644 index 0000000..93d27c1 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModel.kt @@ -0,0 +1,97 @@ +package com.taymath.tutortoolkit.studentdetail + +import androidx.lifecycle.* +import com.taymath.tutortoolkit.studentdatabase.Student +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao +import kotlinx.coroutines.* + +class StudentDetailViewModel( + val studentId: Long, + dataSource: StudentDatabaseDao +): ViewModel() { + + /** + * Hold a reference to StudentDatabase via its StudentDatabaseDao. + */ + val database = dataSource + + // Initialize mediatorLiveData with student datatype + private val student = MediatorLiveData() + fun getStudent() = student + + // Grab grades from grades_table with StudentId + val grades = database.getGradesWithStudentId(studentId) + + // add student from database as source for student + init { + student.addSource(database.getStudentWithId(studentId), student::setValue) + } + + // Initialize viewModelJob + private val viewModelJob = Job() + + // Initialize uiScope + private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob) + + // Setup Livedata to signal when to navigate to AddGrade + private val _navigateToAddGrade = MutableLiveData() + val navigateToAddGrade: LiveData + get() = _navigateToAddGrade + + // Setup Livedata to signal when to navigate to studentList + private val _navigateToStudentList = MutableLiveData() + val navigateToStudentList: LiveData + get() = _navigateToStudentList + + // Setup Livedata to tell whethere the clear button should be visible + // Based on the contents of our grades list + val clearButtonVisible = Transformations.map(grades) { + it?.isNotEmpty() + } + + fun onNavigateToStudentList() { + _navigateToStudentList.value = true + } + + fun onNavigateToAddGrade() { + _navigateToAddGrade.value = true + } + + override fun onCleared() { + super.onCleared() + viewModelJob.cancel() + } + + fun doneNavigating() { + _navigateToAddGrade.value = null + _navigateToStudentList.value = null + } + + fun onClear() { + uiScope.launch { + // Clear the database table. + clearGrades(studentId) + } + } + + private suspend fun clearGrades(studentId: Long) { + withContext(Dispatchers.IO) { + database.deleteGradeTable(studentId) + } + } + + private suspend fun deleteStudent(studentId: Long) { + withContext(Dispatchers.IO) { + database.deleteGradeTable(studentId) + database.deleteStudent(studentId) + } + } + + fun onDeleteStudent() { + uiScope.launch { + deleteStudent(studentId) + } + _navigateToStudentList.value = true + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModelFactory.kt b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModelFactory.kt new file mode 100644 index 0000000..2ac0467 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentdetail/StudentDetailViewModelFactory.kt @@ -0,0 +1,19 @@ +package com.taymath.tutortoolkit.studentdetail + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.taymath.tutortoolkit.studentdatabase.Student +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao + +class StudentDetailViewModelFactory( + private val dataSource: StudentDatabaseDao, + private val studentId: Long +) : ViewModelProvider.Factory { + @Suppress("unchecked_cast") + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(StudentDetailViewModel::class.java)) { + return StudentDetailViewModel(studentId, dataSource) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentAdapter.kt b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentAdapter.kt new file mode 100644 index 0000000..40eafef --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentAdapter.kt @@ -0,0 +1,55 @@ +package com.taymath.tutortoolkit.studentlist + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.taymath.tutortoolkit.databinding.ListItemStudentBinding +import com.taymath.tutortoolkit.studentdatabase.Student + +class StudentAdapter(val clickListener: StudentListener) : ListAdapter(StudentDiffCallback()) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder.from(parent) + } + + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(clickListener, getItem(position)!!) + } + + + class ViewHolder private constructor(val binding: ListItemStudentBinding): RecyclerView.ViewHolder(binding.root) { + + fun bind(clickListener: StudentListener, item: Student) { + binding.student = item + binding.clickListener = clickListener + binding.executePendingBindings() + } + + companion object { + fun from(parent: ViewGroup): ViewHolder { + val layoutInflater = LayoutInflater.from(parent.context) + val binding = ListItemStudentBinding.inflate(layoutInflater, parent, false) + return ViewHolder(binding) + } + } + + } + + class StudentDiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Student, newItem: Student): Boolean { + return oldItem.studentId == newItem.studentId + } + + override fun areContentsTheSame(oldItem: Student, newItem: Student): Boolean { + return oldItem == newItem + } + + } +} + +class StudentListener(val clickListener: (studentId: Long) -> Unit) { + fun onClick(student: Student) = clickListener(student.studentId) +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentBindingUtils.kt b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentBindingUtils.kt new file mode 100644 index 0000000..d05eb10 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentBindingUtils.kt @@ -0,0 +1,35 @@ +package com.taymath.tutortoolkit.studentlist + +import android.widget.ImageView +import android.widget.TextView +import androidx.databinding.BindingAdapter +import com.taymath.tutortoolkit.R +import com.taymath.tutortoolkit.studentdatabase.Student + +@BindingAdapter("studentImage") +fun ImageView.setStudentImage(item: Student?){ + item?.let { + setImageResource(R.drawable.ic_item_test) + } +} + +@BindingAdapter("subjectText") +fun TextView.setSubjectText(item: Student?){ + item?.let { + text =item.subjectString + } +} + +@BindingAdapter("studentNameText") +fun TextView.setStudentNameText(item: Student?){ + item?.let { + text =item.studentNameString + } +} + +@BindingAdapter("gradeLevelText") +fun TextView.setGradeLevelText(item: Student?){ + item?.let { + text =item.gradeLevelString + } +} diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListFragment.kt b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListFragment.kt new file mode 100644 index 0000000..c0efa9f --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListFragment.kt @@ -0,0 +1,88 @@ +package com.taymath.tutortoolkit.studentlist + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProviders +import androidx.navigation.fragment.findNavController +import com.taymath.tutortoolkit.R +import com.taymath.tutortoolkit.databinding.FragmentStudentListBinding +import com.taymath.tutortoolkit.studentdatabase.StudentDatabase +import kotlinx.android.synthetic.main.fragment_add_student.* + +/** + * A fragment with buttons to record start and end times for sleep, which are saved in + * a database. Cumulative data is displayed in a simple scrollable TextView. + * (Because we have not learned about RecyclerView yet.) + */ +class StudentListFragment : Fragment() { + + /** + * Called when the Fragment is ready to display content to the screen. + * + * This function uses DataBindingUtil to inflate R.layout.fragment_get_todo. + */ + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + + // Get a reference to the binding object and inflate the fragment views. + val binding: FragmentStudentListBinding = DataBindingUtil.inflate( + inflater, R.layout.fragment_student_list, container, false) + + // Get reference to application + val application = requireNotNull(this.activity).application + + // Get a reference to the DAO + val dataSource = StudentDatabase.getInstance(application).studentDatabaseDao + + // Create instance of viewModelFactory using DAO and application + val viewModelFactory = StudentListViewModelFactory(dataSource, application) + + // Get reference to viewModel + val studentListViewModel = + ViewModelProviders.of( + this, viewModelFactory).get(StudentListViewModel::class.java) + + // Add ViewModel to our binding + binding.studentListViewModel = studentListViewModel + + binding.setLifecycleOwner(this) + + // Add an Observer to the state variable for Navigating when Add Student button is clicked. + studentListViewModel.navigateToAddStudent.observe(viewLifecycleOwner, Observer { + if (it == true) { // Observed state is true. + this.findNavController().navigate( + StudentListFragmentDirections.actionStudentListFragmentToAddStudentFragment()) + studentListViewModel.onAddStudentNavigated() + } + }) + + // Add an Observer to the state variable for Navigating when student icon is clicked. + studentListViewModel.navigateToStudentDetail.observe(viewLifecycleOwner, Observer {student -> + student?.let { + this.findNavController().navigate(StudentListFragmentDirections + .actionStudentListFragmentToStudentDetailFragment(student)) + studentListViewModel.onStudentDetailNavigated() + } + }) + + // Initialize adapter and add to studentList + val adapter = StudentAdapter(StudentListener { + studentId -> studentListViewModel.onNavToStudentDetail(studentId) + }) + binding.studentList.adapter = adapter + + // If we have a list of students, send it to the adapter + studentListViewModel.students.observe(viewLifecycleOwner, Observer { + it?.let { + adapter.submitList(it) + } + }) + + return binding.root + } +} diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModel.kt b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModel.kt new file mode 100644 index 0000000..5259802 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModel.kt @@ -0,0 +1,57 @@ +package com.taymath.tutortoolkit.studentlist + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.taymath.tutortoolkit.studentdatabase.Student +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao +import kotlinx.coroutines.* + +class StudentListViewModel( + val database: StudentDatabaseDao, + application: Application +) : AndroidViewModel(application) { + + /** Coroutine setup variables */ + + /** + * viewModelJob allows us to cancel all coroutines started by this ViewModel. + */ + private val viewModelJob = Job() + + // Add variable to navigation signaller + private val _navigateToAddStudent = MutableLiveData() + val navigateToAddStudent: LiveData + get() = _navigateToAddStudent + + private val _navigateToStudentDetail = MutableLiveData() + val navigateToStudentDetail: LiveData + get() = _navigateToStudentDetail + + val students = database.getAllStudents() + + override fun onCleared() { + super.onCleared() + viewModelJob.cancel() + } + + // set navigate to student to be true when clicked + fun onNavToAddStudent() { + _navigateToAddStudent.value = true + } + + // Reset nav value after navigation + fun onAddStudentNavigated() { + _navigateToAddStudent.value = null + } + + fun onNavToStudentDetail(studentId: Long) { + _navigateToStudentDetail.value = studentId + } + + fun onStudentDetailNavigated() { + _navigateToStudentDetail.value = null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModelFactory.kt b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModelFactory.kt new file mode 100644 index 0000000..50b84e8 --- /dev/null +++ b/app/src/main/java/com/taymath/tutortoolkit/studentlist/StudentListViewModelFactory.kt @@ -0,0 +1,18 @@ +package com.taymath.tutortoolkit.studentlist + +import android.app.Application +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.taymath.tutortoolkit.studentdatabase.StudentDatabaseDao + +class StudentListViewModelFactory( + private val dataSource: StudentDatabaseDao, + private val application: Application) : ViewModelProvider.Factory { + @Suppress("unchecked_cast") + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(StudentListViewModel::class.java)) { + return StudentListViewModel(dataSource, application) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_item_test.xml b/app/src/main/res/drawable-v24/ic_item_test.xml new file mode 100644 index 0000000..da1dcd9 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_item_test.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..ca3826a --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/icon_1.png b/app/src/main/res/drawable/icon_1.png new file mode 100644 index 0000000000000000000000000000000000000000..39ca33abc09de1076f1a619ca436bcc4bbf00427 GIT binary patch literal 5925 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 Hu0mjfCOw0q literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/icon_2.png b/app/src/main/res/drawable/icon_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ec9bddbd59a2d5d17cc2ef4e43a43354c3773b87 GIT binary patch literal 5887 zcmVoJ7ED%HTu*tJZc9SK<9PtsZ0EQ%lz_STCHY9nn3n75P2L|7VY#o+tNtSIL zbN6)Dei+TE8C$Y7Ga~W-Q+HK$)!X&&y54&0Z8(KfIE7OXLEfhVPMj($$I0Woh1lur_5AJ*N=Jq^_J!E_=2w8R43*|w@ zycUb=5#mBX9c~^1_DCsTx8SAwS1*1)3u2B4Ml~Ui-1*#isfY&!ECy^Nm$TR^rF_^^ z+475qhKBIS<$LlNRfPQ4*M44VQ-hZZsZ5hXP6NIO6r`rpR6&tTQ0NfYG=ZkYU&FE_ z;V^_v@CPjVeHI}jW0Bh}2ouM6yF0r3+U<6*lmK!GL@=w z6<6W##0~@{NBb-ecANBhticI{c%r{w-q)~ZQQ!o`A5r9;kmXCCe^5yA9gteOc)Lwd zH&&y%LP3a=7uO%KXgO%oao7Zz6tz*&w9nuB_*V{|bRj2!yb|)rUC%#>;Eu#FT^E$O z6>K&^p||=)I#r zP(NN{Oo^H^sicHGEd~b;nF*ny(X`|R5BzvhM{cA@MqUV6e%DXxgiv=eFklxs73NH} zp{4D#vX8dTFpc}e@h(h=w_U;DC3if1N9O53mXL+cUc=GrAm#ZUoBp5qkR|6WWW~~-6&cd#1ndCQ>ouw?^2kO4b~G7ucE`FeQwZg}`&Qn( zE|)UoyoH1af1Uv{bS*Myj}}a;({b2iRia91{YWBn`qAc`5CIFL*A=Bho61`9xJgC? ziULz6B(>Ia9=q$st8-I&1i9}kq&z)(=`PItJxHLbElhi-i6x=LEvT*5C@;?LH&kA% zP*I}L-4j_rTEe^^_;pqbO+Y>d^@-67hdp!aXl@JBdN7P>Nu-Rdw72XIv2lBduESIp`5>e)dZ8+VTZknkJDWnWH9<**gKHMgrG9Ez(ws14NLmhtS+^y~ z`&&XZwuU*}V-X0+RF%lEU`gopSQI(qRU_fLTn+9yok27-G$`)wx^T4IbLSRNU`rOE zsVz*)!AR>6LhyxK=Q6gg7=Z4B9zJ@no!y(e2#3=s2?wAm0%xH>(?C}Qs!EbZ7$Q2d zv6abMfj*C9Yhy62cGxnNx%WSD^X3zI@8KY~gL-qF4OhGhQX7b2NLmxRsyUw+8zTdt zqQ=Fiu9?Qd%O|trgAR6m)XAX^&!84zT9Q7`@tcVdP*WN2H+MA~8CCU)A};{`z6fbp zvncS$lIQ(^10ZZlbUn_BL?DRNZ*iHOb1$t=n~&Y0F>hfl^A^_P?GMtt>jfI0vpJirW~ zs4BHntGV(FC+$tWoW7t2T|fS!(djN=*8Cb~&94E#2$>w|^3ij|Pbd&37&Hk522T)* zN(z{DRt;jHnd+9r;neYaBTYm~>wYV&{aL8yWkQJF`&KXd?FhX4aglpM1YO7oAz@SC zEHA=cT|(*j3N%|}Z)*JH(i6^Jx2aUsx~Zyl4^J#bFnMMLTh|Y4hX`@){ZHQXGvKEu zEX)ZY_bYWtSM<7KMjewD&Y*H~O^l3uqJBn2{6=!w50|~@%$zzq$T=YvB1VX(FPQ7% zkBRa1CD?4SZqhFN)>*lhA?JiB$iC>cb&RQNKA>t!(yUHVSdeQOayEwiaM_Da5itKn z!snu4x+DMHR4R(f9Ij$=MCr88G z#e*z-@{Xc1d+b^WrU_Uf4e#5l?s}m-7v<-K5NVhzK+H%DFHU&*(Sp*-!gRrB1{L{G zF3Qh3AwPKFS+^9#_7uj}75QC71)Mf}3{_)?H#N-#YA2RZKcfP7iJb{k5~kmh8=kuT zsjT<0Ssz0bub7F5*j#Cv!d17-b!b|Cw(^GpO;`BbjkAErBJ-K=zk_K?K)QT|wsAmn zHp|a?%_u^tieB5DI-{A4ROmJpd&0!SGOglcBp(rEy>^6ue|*S@LN7>E-zbiZ z2}cN7uOSP$H+tRQ6U55Z2Kfj;N{Od8zIZjw>~>d>147(EV-FAlFvAu{I=$I0a>UTn z?N8iyIg$%&#;g-EVEwl~dcS+?p==j9V%WW|}1&10n= z6)+5w?Hl6_LJI4pT$Gy=LWIrwCD04t^@MomPy2FF>`7tmpPLeupPlZY@ta(fn-jCa zKfU)`|78oV4k5S>9;oS)aHJ3$2YuS^s7$TQ|gyiAX8$z5B`Aa&j&) zXY){(5n3rAc64ml<}O}avzeAXM{*^?anZc{2)}t@GdniLyD9|+-jF3B? zzQfRjevN=P6T`P{$m@ZnB&5nBkgq#Kq3aqN8gjNzkaO#Ii4>16S@SL6yAaufxb++7 zQee-o1$@A7@Z1m94yZ{0DVBVF^)0J&Ek_=Vt%cM@|HDL#9WcWdjiX>H+_?2noDA4M zzN_%be8`a(UB=xj?+!}I3(@<{?;kiRYr~U_-kwIT1Z~| z#;RKn93y#FkyrJr6zab*&`J*O@1tqg;hf9Rw4QGD0eL0l>nm^G zgk(+h{>|U*!3gE9>kbx(}Ae4vt%bQ=ym7}w)6VlM|ip_o4cY~1fTM|x7jV~Qn z&ZM)aF=kTae8=v0wz2oUow4|;S~pkTG&{-q<3tb)g!$c1w{WmEW?IbTbEY$OVZ`L; zXnQyN*6pTiUs`2ni-gA%-T8F3O-i#yNW_*me7is_1I8xDO2*mtF!`JrI2T-<8pYPX zY-0cB_$F3)m6OlhFq6`Xv{r@3#gRi^{`m3^4tK@(^T*Gf#Oa@!H>d_Y@BfN@@9(DF zm_nNBIUteCrCoda{^d7i#W-NZ33=%Dr;2r3!4d@bAZ0~joIuJ6wrygj<84aRLj)Gw zOW^dI2WKK-`x_t9vMIhs&~=ps7uRvdd9|qO(8M-P$)T;Sxaylv-!Y<7!Vx26#nR_0!f*z-ZAoT4LMY6*cn)>*CZ~N4!2O3?P&+@2-S=DNZ1XRqB{)Y~4DtigDP+O zN87vE{KpOWdXjqxp$ICfoRn9)aJnMni`Qe&-QnSIhZiZ6XRU=LPUc)bpVDzjjW!9k zy}zgMt#74`^IFC1@Sn@R;5=!frPiAl!85{8mY=MD;1ed~v9CQh$x_4v2yP+8bEqyt z)>QlZ$~5~r3WV?287Vscv+gD|^G2kSel}$qCVSWIqT0qJC?{~Y!N7g%9AXigqPvPQAw!}mV1_=GGuhE2%BcRzoc zCi%9M;-6C;SK5T%n(lZ{IjvwlHZi>8YL;s(fjPHgoOX3aVnV(k`!_eyzO4mskLQ^A zIZIrOn^nj7IrZ2IGb}Krg{|c;*f*|5=^LKPCL|r~4lH12;B3o~juc`<+L-ANM?C&U33O1pNlk{UUjkCKQjH$1tqQ07nx-qDFvT=lIm>h2Dq^qfu?&c2sed))r3tg`;&bBLU+{wT~ z&=Q)>7T?9vYZWEduMa7&|N831zdzRV$0TI=k{3QBuzt1v`Fp+eb@pIcgFg}ls8S^d&B!ayDSU%j_P4Y3 z3Yb!3dtf13{pXXQR1XRvuDoyMEq~7RTt-3$+<&iUz@3s!__@ISDr2IvF{^hqnHArnR zsD&6(+zAu`*oBwV9dBh%%3(qRU8bNttgzoyIBE^gGpW#@Gc9ILdlSL3{4lAq;s=VUWdEKwG*-+Dx z0TG*`LzZAuNac4votM2f-VA8$4XcFm%#ALBOt-I%2S{;KsxQZ+7V^lQYvv1>1fU?9 zXv?}syR=B`cwY9{(k|Z=Bo%rqmFj+6T112FF-zz&>Np%8k2NsV2V{iM<}fG;$6>NL zZ9f+33pTUacM%c=38y`N*YopO%?Hu=Gfp}Fr=M>#v~3HQ|Jgy!Y?BpBciJlfy~>C(INV&(Aqc@o&bQ1)OmVB z1e_hcE?0BnVlXW#w06#Q{hHl@1!%&gO54X+eJ>?iCqq$p=pw)b+jb_{wu4h})U4uw zF@;WJ5~kFcYF|gWmN#orDzx?(At269j7uHVYoixMT6ebPIwtCD+o-c`J8n9k<>q~F zWE=P#=W93y?Yl@y)ecJ4j+`t6hk_z4VJ}NEJ~1wJ+8c90l(3K))o2XNr^A>?hcS`H zV9p)Doe&C$>(^vLokJ=iGQkZvDMn``SBF`ICKBpalH?L8@1~@ukc?A= zj53@eWRzh@gc#V^?7Ns9f%9Suu0;5(B0lh4N>gY~+UJjiYuM+l1{R5to9 zr`N1Z8^0%T79aXPO~4wy8{L3(@}ck383+6xvyzRz%V`e{GO7fi!n1&WVJwhxoyH~6lIy--O} z7o}RVRsY{S*WBJnE#ic9TXU6kR|K3Gu z(;f@QZ6T&=CsUoRMa ze%Kq?&9sD#mb$MbJ?c@9KwCub6tGv(Qg?n*e80C1x+5#!e)n`*>OP$mA2_%NypdY# zEJuq&=DNR`dk*$b@^d$^EZIw-z3*a2OUjlJID z*=#ud8OHB_1$F-xG9e=&2WqawUw07zsv~Yvq@_6)pxJGaiUl-#ns|qeus?)Q6;xY_ zKC?iJ{Mp5lXoZ6pc8U3^_QCOqVX7m|^9f;Ent0V=!|L~gA|kRR#_1|T5lBm-rhV^t zn4UK81lb)nOw~#A#6>v5Z^n9sL3ySRhNGqPiMly1o-_skMN=tE`N9CoX4lfcuK-)I z16%RnBLkIZ)#GV9LSa=gLQNjF)B>F`XV&BI?#Ep>*zVR|;ii1{cnoilqDfVQ;@x!> zNXr65+UHBAk3+F(Xihu!^1;S)mGdUj-`b76vIw;xxzdHEGG@VKe4V|x(!95=xR8o7 z>In7uan}!?A-cwuVTMekX~yahB6SPt4H}0u%MzMO$<*}IK8UoC(wXBj#@mVuDN93C z6ppH59I4%00$dX^8%PUPp?FGl#(1?rqjW}Q*>ty^vRSnm=l_EK0C*i;mnl1 zA}F3bCPQR~N0ROYu@T1#jn>`ik3UQ!VHZ}&BrR@g3)uop2k6;#04XGDK7ZrWc z>DiTN!6TBkWs_=KO0h}^c`YCeZ;Ra9tf^U#tXG#Ak zkRTse_TyWVcFoe7Zalj5`3o%M5+RulV)Xsw<6{jOl!7goa%CzRr*I0Va0(wY{6D8) VLA#iG{Nw-t002ovPDHLkV1iv$Qz!rc literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/icon_3.png b/app/src/main/res/drawable/icon_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f1d8ed1a1b33387bb91b60738163e67a5180a10c GIT binary patch literal 5932 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 O0000HLo?aUSP!9_Mi$=W!kr50P&H#*6Q4 zc+w*V^kqUQD-dEP$YOykvQTWXGy>Tzp&dA(2;N3l-dz94jVJRc_L%XmAY|*BCrZMK zc`X*#BgA_Fb-eEo@Q#%784I4;xNY^TSrBtVFsTW-|MugtS%d+)hpQW5g+U-)s6T@8OoNM)`RaxU->fFm`XrV0wY0=G+G*94jt{|w8L z7zP+73=UcJ4_HL>j9Kotkn1*XUHzwQe9zfnQV_Cf-S!1Sif;lR1#IckIPHScVwJKI z6|Z}IVh@ES-F+6#9VUH2Yjgr39`5g#>+5!|8afN{Clq-nWYfAG_XsJz22x8G@3aeQ zrfQT26ofc;aR-Mi8k$X7I!%yCQEw=k_VK$O`p4#T&g2}BS3>Szv*Qs2wL)(Ou_14SY+AeHp9MS=yLUMR zwbdF^3e}uRB_+JmpmVC-Ob8W6OiNyI_xDz{@@S=HWn=kOgHh1_(49fR(Z9K+)KSvX(q!k_myL zz^rLWt@Y9e*F5=&+~gib?sbKfi(;2Pcjo#af#XdECtFP{357mERk=oqKf86P#IF!2 zROsl5P9QB|ZUlar)l3tRk4}Ah?84>D+&b!;3>upaOiLnVbf&%caD+GZM`-Ibv)XE= zRmAJ5KwS2~+Q(O9FSlgmgAh;bLd(#7^oJx3E$MB3{UM9}$8=tKE6njGgMp!mXQsfb zq?l)v&rNtH8ITV`+_4K)8QnrGDLHsNGBPJ947j*v^-^l*6eo=dBf6xa+2FOkVP4%E z;Yg!FXOG2DM5dZV#sy14Z_uK^6E7MG*X62n&*=!FuC7k;b<`NKd@oz-z+q1o;dqll zLvyrs2qF07%}beD;|HLlImlbDoaFGHHVh+;k#HEQBJj8cng%vSpsFNUgdu7pn_8M| z73d2}_8keQwGLaRvUKCaH|{x`?;a0w+o{*r*zv}TAhm($x}-5dRV}$>>IfMCfeJ4l zyk;&dKRlBIZ?i5X-WEmXKp4!Kt*X>Zyu`GGn(oZMP32?brDjxbJfuO zYj+F+E&#)n*lclDBmzOSeEr2vF8fez+V?nJ8p~Ezv20}(q5d%Shq`Dy(oI`)kiPE0 zF{`X8bEYzTNhyk^VwmvUuJ}Tt5TZp&S;lZ15?D=V_0i)*KBmZRKn;Ly3^M~Ls!G+I za<0C>!^z{lEV`%yo9)b#Mvu?I!W9)PTu}jl9x>@^8=$9akjRihIBXIb8a+TLD0HxJ zc?Dv)nc6Ig%VT3O6m23>S{p4x`=e0JtAr4}>$k1?%>;b=8IgNJ1Z~JDA%-dNloa4A zFQlkCfM$=bO;yh?&ndKFX?m;}c5}%v=y)->%{15FxJJ_{a@E0)BYb!kh(i zKU0^q#jXSMYnZWeKBY4&M##t~YUc;yH$w^3O>NdGO93RwzTpuHhxynXz!6f0Tz$ z-ceBO9Jv;PxdJvzJ@mrXHBXe}BLAEaB6V{!i214E{)CU8EGQ~_Q+q$^8DeUc@vdAiV=_dnHhx&HS@o zGKx^jV%JWOjmb<#Dr|NYXTre4GA;jUl1~V-UOGa^5zCThd-sqLgUyj>zENBm6HXAa zUP2b~XzaSbCybS=1@Z}il#*a?eDZ3V*;QAN144XZ{T(0zU>X)(t)XmZIbrDO7))Gu z>B@ySW7Y{7_Ws)yyFa|IJ=l$ zJ+ei>$kwq#d)oNb&OJ1|)0Ha`&WQTMUHtlqJsj8_S5*T3D_GjNJy$a1jF8(NyG_@G z?HU2kC5FHKdR{jyB_UN7fqcdjiCkA#SC_MOf}DH5OQd*U?ar?PUx(-##LZv242Ltn z9`HkhI@`bf^01i%kYeo@x81ZY*K*{+*;+`O=)aGsvje7Kabyws@vR; zfBZd)qI^xlm5JeQubu0^a3S7;?6?Vqf)ReY?F~Y~NOFYaC82QdU0ZJYoj~Me zAf9tV>gwtgZ|Ag63dubnmSsv;UR}U7tCmjqvag|A{9^lGXl?30O)9xt3ceLAY5YYl z%_fjTLh9=3G+*cR&myfar}NP&oLWptRVhbbJ2VnDZB`L~_t}MG+LkaD=(@@8pL(0d zBi$omwJYY()znUJOLv+lm2yBkn*b%W~as%RhBU0 z;<-$j5#8T$_{Fz5`pUtP__8V=SKqKW$@}AM5FRr4?GN|T+&JP|%*;#YF=u7e<)`~( z2ghDJOxv-v#?A%_4=Og#W7&2o%^D$5UtZ%@f!F{{O^lPk$$}E*Tr!XMEh$faP{O|d z-pz?U@kOkXG7lg5^a6?kX}t>1h_3b!e|Y);oo(^;{OYAMSoFbVqe|euDl@a z*Z;mg#M6g@6b*)0&~bw5-j319gy=x>kRAzd{qkeCP3Vwt!U);CZhNU=i94lW4Upte zCK2*jahcd3s3K^O`}58%vh$UTGw+tFf8z)TpWlN_a2@jc9b9l(6?2wO!Q)MTE@mhg z;qY5+{N?4QBsU%*6y|?m2{p@RrhN|J8?SY7xI4b{vmi3a{PrelyW6A~y*0X5NVaK; zeCUoXt0%-{ea?hD@cAbyrOn!a-oTEO~`{^*gnHj#N7yPBIV>zLshLq z#Z#5TB~uyFPTv`8Lhz|MUap$vLP>Lw0D!5R9DVH|^=}-()WImS)MeRu4b ztx5hxO7WT0gDbIu?ws*8c{Ad#WyjN9(C<1X@2IJFp0p?B0XreT7V2u(X{B2rH0WeKG-$_dn#;VT)R1A4HdkM{Z&+K;!=-PD04C8q)vJU?Z|gq~iaNJ&j^ zI}6(zEnj#jwJ;h4*0t-m-u(KR-g8Eg?q9p}YLHJ8-{Vin?v#6`)QARu0676?>87H( zuaoyQ9!MMK^tqT)TTY<1oIuSKR9muYGDGr53ugc+um9q<)xSIa^QXb4wNHFRVEvNePFo__TQ-e@fl5q~Jwx%L zwi7IFi<;ppG>bMvA)R7T6orDaLR|jn;BK%tL|^v!>@Tg( z)+eA?77II0u(16^qM0%*gt&VBmYe>V>A8%A3?Ki!i{ayx!m7p#)8^CW$@-oZ7PmFB zs4cpzdXqPTDWT00G#UzxhC*nJy2dG>T(zjyB-N^kUBJ#@wENpzR>Qt55)wmsu!of= z4q!J&s#HkAiVa&=9ZZ)#Z8hJ#ZnHy3@f5>k=&HtZ(--E1jC4>1RH%|m944Rg=v?jA zxzJ%!rCGRy9H~_?0+!lMKI+oB-V@>dPJ@|Rl#G0!#aqaqYL^g+k2*a9@$(1n`dL~Z z+O%U+UHa|@mO@lb{a^Jwx?GcIgJ!WJDOSu3$M#P?bUQt~R5h3PHNHKpzT_gQ53C2i znVNP~3)#GGdnvFXc7HH1l~!+IHsw8Qgr%Ux6f_L0vNls;QvD1h0nNT54i{G@gvgDX zZhdr=*KO{ zo-K5H%ce2Cw+)A(1Naq(?ejp=3ED}7NThgxoj1hp4+bjH&vBx6t_TCohC;I$?bHX) z(4kvEyCrCksO*lYqdN9{LRVA{mQ=E|wLTgk#SIeq&BW#6Btq`Ledh`RGa%Y`950-b zLviCU6XrHg2kmLSOeKO2kB?TjpO7PJob-l=C=K;eI?#_8eriZUy`fNVfReBsCY!_d z)8Tkg8B5w45K{WN=v>2Z3-WbTNl8jbz{js5^aLSZ;WMSm9+ z!5&m;akzLYU3vb#7$G1oPK-;fVpXw=KF8TDmrfKK{G~MbOV60jrH8q!DQZxCxoQrB zw&X=CDWb#9Zl@=!GxPDF*O{#Pa52Ozls{b-3wrC9h|{ zxA7n@JBAMJ&*7xilWZtm*?1U#IK-^3W_~^QB8Ig1u-RsrytiRLs*P0clTVE;9tv{F z$>@;V8yV#JngvPmwLNWdGYPPFO3fMN9a9VOB(U#^jIIf8BOc~XQ&VEKN0k;1Q%{N0 zM_OIFXWd48%RsvLGa>OAw;mZ4?;4g}krJ1lESudlP-S#}?@1?HLRlo1LAt!tm0LQT zv4z+K6lifZRpqeo6eJ7oPOzxXahp^XWL7Q9ygG&>UJo2<++eODxisZjZ#W)bppA|% z?uswhmfNjS@rkm}bQzST#A^vEc!}2_?1{%~;pDWb?{*t;HRM)C%U0AIm#sjP*aYZj zFg|A_L;x2T=v-c?6Y4gJY0&9Tlchz;HSLrtiHWkvYv4|aPu!$-sb5EP#qA%usuSDt zstI_1%Co_cNo*@ z-Wb$LbVE#)Z6IP0^B?u9a#Vb8yGg9qtZ|yGsUG0P9vh9PansJIvMw&rxw0sNQ%F=- zT(4?rwgqU;gm`C~_~GY;s-W6a?3oU2zR==j92L^)IQPQ4!Wj3T14 zB*xj)k>6RUX}>!jW=s3-1le77oI>)!q6iliWL`$g*g|Hy;?2=NBWi|MG!=K%XxEwI z#Z~klb71$ou=_{bz)F|b5^Us^;s|g@23lM3aFPvA2V%N|-PMjs9o##rIO{c%H17~Rgsw273g{Cs)qL~b|_To+R z-FCm5zy&o#`UdgUj<&mbD~mBBCek!V$`D|d%b;~s>L|uE$`YDN;hc($@tV_4(Spj1 z@piwP;xt6X;41UuD$DFZ;hmP*L0YH^{#oT2<5h=7(frJ^*?dll7glAAcLsbo1DP$u zp2}i8nO?65{4>Y5rj%S=#fZAaicHqk>32WO#L=9PNjtJqTgYBu9zf5bQ%E6E^Z6U+ zzd~5LNzb7~tF%b^(OB}Dx)fW5kkkK#cpZj#b;H9q9Iv3*6UIA&kZrd;UY`)w zwXpGV5dAd(X|ib$aG05&vVkWzZD0Fh8N{3x%xFUHyLCqk3%Z+twE)!VOPTgF^S$B5 z?(cVWbePkZ?wMmo5%M3O`ChFmB|bnb&Sm0r0sK7xPkuaEB2)zkJ}*I)39_6mhHW!U z6EH0x7Pk?K+R%-XSst*#>o;v%`RLTR6=8&gr<54 z0pH}rjwcwyV>V6>SQrc2g%OAz3Waz>$F4Q;DTqIR$>Vg8Q zO7Llfrg{lNOn=^?2;)$2*hnTvUXR&9{BKl}I{>)PP;(7g(`ag7uT#^iMGXcIXa@m@O zGTAza2p_v~CFZwQ0{{k2hVj}9$8l(HKTNZTkuU{G5d1!ZECY%lND^`^!a&kSHoq~~ zDlisi>_3tyY8|#Mv2xQxH|(8CxhDg62lcL26@hFOtLFRV)5#eufMHXqXqk z`>#0{mw&JwZ@k)zgRk}BRByPTMOZdtEPVQALIlif%=ViHyNr^idLj4<0DoSDbnIFa zzi-{n7yvH-m=;4(vaB!&gk=3z*J-%y18qgq(Y!J)yu29~UfzsID1oknLpXM182u;1 z7#ogFxXYTecs|Zq(Fh?+FfHKO-PwgiBI;%4CZyUB!S0z-p(lw-Op*Hmv;u%(rkDXB zBni!n=i=%M{5ak@it{g-2Sqvkq|qPrVA-m9Shi{&0Km{K4E0AbG8BUzH<3tK(Bp*) zLRF0i%PyV=N;Ol(W_bMyVv%GMVYWBfru+;^)>T9_x?%g8pHD;CPYd@6A@qZjgqRk= zUtfjb+#1xjG(c99Yf~-lwNp-BQ6)4r2hr3VoSayK(7v<*`*)|7Lx`^3^zilH1@N6I z3o`|{KT~J)r>`59v|`caOVHRpFGEHp(YB-^d&9Wu>l>f&myTT?xK4--$`BGBOSql= zxM*psfvRS@NsVIm#cs>sIw1l)mcF*fQC%wmNftR;oe;RhZ5dn}L%zQ82|vZHe`4Un z>1T?!^4(NEs_ML%Yuo0VHm}>M3&sEK4G&xwb0dFOTF3);d}p4Bo4Zp>w(aTX!Ri7J zpNgZZPRm>q;amc?uo3ygw%Z=BcO!pS2w}t80??BD=hcqF&lJ=)`ieciC?WVBH}Wq# zAz!=eu^nSn$p*rU%^Z!BOi(?L31b`wq;k36Mb4x_SzxhjAcny-Z^BXp?I9;8{sV(ahg!} z8nVG}rLRLH3D|BekWT}c8R60F$48y{K zSF#O)$$rv}d|e@gRQrbjMgbra*73)ukGhfV8R7Y7I-SPPzF@-mnH%}K;x_p73qOxt zb;(C{5Uv7%{u3dL4#uErGOFv!uDDDJ$BqnR_p`^a|K;p95oW&g_J?nBWnZFedT7AV zw-S)qI(BexKYqGvFS-v8xh2AB(RFADKYM&H-q@4vstEX1xbfHyw`6dQkXs(T#gIw4 zhJa_C&tHGJq8pZSkS_~?pYrSabsZfYuB{We?)}bSx_{lSF97&5kX(bf@pG5KqgB=e zJ{~i$<7>~S%p?Gq)_r#S>g{gJQ2}RbVueEYBI)b^%d~N12B^YE_Mgg<0leMP?|Zls za#X~Yar@TW6U=x#eZTj`6KCXYc*bC0-%BSlw?zEtbw9eUBD#6Sj7yTu4+F3PV4ydQ zt_lwBod*Xo(3`d(kZCZxHi+k=VualJ(AuK}emZ^s^0VEQ5(O{+-?7X!F@E~FZ8x46 zCwf^?QS&R4^e;%Yl9O+bq4VIN>oRn{F@WBlwBH4pwy^)zbs-$6C?TKSdcz(tcBSv1 z{l#Gzx_e!>X;}E(Q*UJ-5Wcl>>)HdZ2~Y$TU!ag=^KJlR01zHcV7H51*9-sKg|Xq( zX&Q`>W$~9?%e(|CPRJeKxTz1okJ9&hp6kJh?$NU6d%SBDuRZTLLQBvOD|J|a6BRvL zWAm+#y+;V~B?jK-eC`XV`1ofoLZGTVZbFf;jvsD+1(C3x8^Cyu1n#+W>*`+;s3MBE z>x6W4bcn#<+LyRnud)Z@Awn?dP3vG;yq0GYPkN`kKHtz z04@^J(a|9X2N!-4Y=6F(k5>#AV7@bq!B7khXTNI++TPoq`yvDT z|7Q>0-kV*-s&De+L!VfR+J>TDg{Q^PsR(}kgEuhPpIy&yS-A-3zyHF58aVo!!#Mil zLFj6tSmm5x@MhNJM>lQ0zAVlG(@w}eH$PIXsGfBo+yUl>+)!dA;UP8dhh)lV`%oL^ zU$LMt5e5$Y_D|^Elbs_diiAt9Y{dodZiXaHOl-?y?0K#SyMNma)5y+mS}$nF()V3Z zwDiY+e;i#;b;6cR#C>6yYLP7yL<3+vXy}P;pMUh0X;lfQjgT$tcQl$d-NA(00OUB7 z5rY-oOKQvyVP(gIs)bcpe)EcwX?DGG1aJOsFWBKa6sY##g3Fq*c;y`U1I5q9jD&R@ zdaWOSdcG&ejfY5J$(1Y6dSQFf_W)quBYQE{o$c0a$wa~%g`vh7RIoLAlo;D(!4KZP zb?vm6tk0N``#=5o0#@veVB7@9p#Z7mZ8h!{YRm^=7ay1xUw1AVFK8^8{_ybu?EUr2 zh>qm;5F`i&HlnHs@GdmX9g6;xgHS$glC6KMgd_s-;K=$}* zD@g*aSG8jPW%EHLx+2T4@YYLjqU)6-u#CwmJCY(};l*d8{nGOwmC)AMVw`yX1iF9S zmD3uF#uYYnEdpJO*-V^YxC9uxgw6Nf`Ow-ad2&pekb7_6d5+BZA~XF%{=t>RB1ME3 zg|dzht=5AD?`=WTMNK7%(W42xy|)v`U++d_Bs^|<{+a+5ENex}iZ-ae;uB0}#?b47 z=zgXfv4P1cPfQG5iz4BT*oB29lZd}>68`P3Eo%->Cfx}Wa?j0=RLhF;MIu^{yhDwJ zEhULacyXpDP&kRPZ3`fRROC>U$VeC?Cx#Fm4nvP8XWXi$!dDwW&HOs}YXSxDSf&Lq zL&(yUi6{Ws(6u;pEn?fEpgYi+d8;baFWM~a4NK`-XC%|%1oTr{-Kfu!U*M_7i1!R|ivclKeRs~54cXwh_hp&H0~ z8Ej?5Fw_JR-Z0ye<*eT*m_Pp6?Q4HI?(5?PZeI8JhY0phkRG&|;EDO+iTlpDYZ?y; zZv+Wna*UWK+vqn1imj3eAyCy+18;Rwxr>cPFxEE$+b%Re2>?wJ<7BFiJkbC=vGQ$0 zXE1bM1PO1Bc9eji&P+EfC4p#g6r434M;KVOaod_V zi^VTmvMuYkcnl7{2w)`u5DWOmY9N{JY-7$RBp*XIp~n*Fw+Mq4AD$DR*7T# zXC5R|hBsV;XfSP2=JVNzZUFF={I~^^g)QrMGy>R|zW2m@kX`7erh)_$dM!eCsw?Za z1ZLFFKpc>DHE+z~O`C6iq`+)Y&_WERTLDx70NJ9f1K(u90QxP$aZ})JOJLY8>~RHv zdckOxZ8Xa^>c!02LZ`<3(6tztYyhYh9_7;ja!%0BA%wwnKXzT8zW2oaz$9nf(~Sgx zlcvB)D>PW*R}#boHRj8Vk6^luTLxrrXMdkA#X=gH( z1WZ+jsU*N6bttkUo}^c1TqIjSGE`VfQhVfNofjvBfJ@WYmDH*vQ-L>J1zn4Qm>?M{ z6x{=1O>D~oF+tHaD0_v(!NgGGK1fz&%a&}nSH`z(3UJgdBj-q@io24|A{VoS%rMLn zGQ%(-LYNqFZx{)0wCIG(78c_E5DZW8A7xsyfw(^eODTRVtf?jt_lICh#Vt{~CyInG zoHjX33M_0Sd|?<`@ugZzHWBxSV3v|i(UY>v#bq-*F(iCp*rJ#ffT3%tN$vz?pO9{w z&?3-%$%PhTf*Q|NN8^EPfh0?U$eY8&f}=?{8c!6#;W;@9gDq@C1ET;jEJcTZB=@XI zQ_&F*Bpst!SkS_gTf&X|!Z18ZGRTq&45e}ZC@k58uEmm;38&gjcG5yifT6?@9LaT8 zvSbsnl*(;MCVZiqoN&VvN8F!v#_&wQ+&{4vB4ybv_LVxn4oi#^P5|=5$%Ep2-3X!u8vhp}&D`F>e$~#fnPv1ghg78U5uc69wRA_-* zrlW%+uv7k0>RB2*p4L2Jnk zH$!pgsZ~Ba!-9gEG$p@8YUl!G14* z)PFbBb|1V=x#9R#_R_OF0NI=EHjJ?t@cUFc62W_M?z>ix3A~mnR8T4ij~^HVI#Y$2 zqr$s1H+<}cz6{~YLNC0{d9puEU^81@r7GJUn=##SItvQ&<~{~eek9}-1>yRkD3J2X zQs$|sd4CgPuZ3V9E?fmoqhyz*Ee*iCstTkCNRA4Wi);&!HAlEsBs}##Ndl6ZXV3J= znLoS8zCweaGd)Qw40k?r%9)>c{&m4Sf|9a0!xSm=I}533xwFrdqG>y1_o^U8z_+Rz z+S1ZvNy!$XG-q9Wsu#^k$}CIpHP;oyty|uV&`}T6YA@94LVu^mi`x+H8G^5=8YJa@ z1CmFwQg2C!`dprY^BoVNf%l_C2zX!V5^ z(RkrPgpLhBYpjCg$*pvfCCs^`9nro~1d5bft@feef>!8bF$CKR{gVR=>R{;>*s?Np z2&C$^#P4Ayq-BvTp=R;ClHszZqIPMKZ3Pa&>xvMShPSC2-lo#pQ{b%94$>qERG&S! zWVqy!QM;tHY)Vi=-LmGA;aWowT0`jrpZyE!;4hWDAXK-{DG^xWm7F_5W+GwhGj(

)S0#s@wEWR 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 O0000L(kfbgO2Jkj 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/icon_8.png b/app/src/main/res/drawable/icon_8.png new file mode 100644 index 0000000000000000000000000000000000000000..76fea584b1037ee518c43f3efff6fb9044ad1945 GIT binary patch literal 5915 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 + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_add_grade.xml b/app/src/main/res/layout/fragment_add_grade.xml new file mode 100644 index 0000000..0bd2f28 --- /dev/null +++ b/app/src/main/res/layout/fragment_add_grade.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + +