Fragments now get data class instances from Room instead of having them passed through a Bundle object; ClassSessionSheet.kt now keeps screen turned on; renamed *BottomSheet.kt to *Sheet.kt

This commit is contained in:
Deniz Düzgören
2020-02-22 08:02:01 +01:00
parent bbec19e79c
commit 9ed5d7bb5f
64 changed files with 436 additions and 471 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7 -7
View File
@@ -70,21 +70,21 @@
<output-test url="file://$MODULE_DIR$/../../../app/build/intermediates/javac/debugUnitTest/classes" /> <output-test url="file://$MODULE_DIR$/../../../app/build/intermediates/javac/debugUnitTest/classes" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$/../../../app"> <content url="file://$MODULE_DIR$/../../../app">
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/aidl_source_output_dir/debug/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/aidl_source_output_dir/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kaptKotlin/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/renderscript_source_output_dir/debug/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/renderscript_source_output_dir/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kaptKotlin/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/res/rs/debug" type="java-resource" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/res/rs/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debugAndroidTest" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debugAndroidTest/out" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/aidl_source_output_dir/debugAndroidTest/out" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/aidl_source_output_dir/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debugAndroidTest" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/renderscript_source_output_dir/debugAndroidTest/out" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/renderscript_source_output_dir/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debugUnitTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debugUnitTest" isTestSource="true" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debugUnitTest" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debugUnitTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/src/debug/res" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/src/debug/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../../app/src/debug/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/../../../app/src/debug/assets" type="java-resource" />
@@ -134,11 +134,11 @@
<orderEntry type="module-library"> <orderEntry type="module-library">
<library name="Gradle: kaptGeneratedClasses"> <library name="Gradle: kaptGeneratedClasses">
<CLASSES> <CLASSES>
<root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/releaseUnitTest" />
<root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/release" />
<root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debugAndroidTest" /> <root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debugAndroidTest" />
<root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debug" /> <root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debug" />
<root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debugUnitTest" /> <root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debugUnitTest" />
<root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/release" />
<root url="file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/releaseUnitTest" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+1
View File
@@ -56,6 +56,7 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'com.shawnlin:number-picker:2.4.8' implementation 'com.shawnlin:number-picker:2.4.8'
@@ -1,46 +1,39 @@
package com.denizd.qwark.activity package com.denizd.qwark.activity
import android.Manifest
import android.graphics.Color import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import android.widget.TextView import androidx.fragment.app.FragmentActivity
import androidx.core.app.ActivityCompat
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.databinding.ActivityMainBinding
import com.denizd.qwark.fragment.* import com.denizd.qwark.fragment.*
import com.denizd.qwark.fragment.CourseFragment
import com.denizd.qwark.fragment.ParticipationFragment
import com.denizd.qwark.viewmodel.MainViewModel import com.denizd.qwark.viewmodel.MainViewModel
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
internal class MainActivity : AppCompatActivity(R.layout.activity_main) { class MainActivity : FragmentActivity() {
private lateinit var toolbarTitle: TextView
private lateinit var bottomNavigationView: BottomNavigationView
private lateinit var viewModel: MainViewModel private lateinit var viewModel: MainViewModel
private var _binding: ActivityMainBinding? = null
private val binding: ActivityMainBinding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setTheme(R.style.AppTheme) setTheme(R.style.AppTheme)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 42) // ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 42)
viewModel = ViewModelProvider(this)[MainViewModel::class.java] viewModel = ViewModelProvider(this)[MainViewModel::class.java]
viewModel.applyTheme(window, this) viewModel.applyTheme(window, this)
viewModel.checkForFirstTimeYearNotice(this) viewModel.checkForFirstTimeYearNotice(this)
val actionBar = findViewById<AppBarLayout>(R.id.app_bar_layout) binding.appBarLayout.also { appBarLayout ->
toolbarTitle = findViewById(R.id.toolbarTxt)
bottomNavigationView = findViewById(R.id.bottom_nav)
findViewById<AppBarLayout>(R.id.app_bar_layout).also { appBarLayout ->
appBarLayout.setOnApplyWindowInsetsListener { _, insets -> appBarLayout.setOnApplyWindowInsetsListener { _, insets ->
(appBarLayout.layoutParams as ViewGroup.MarginLayoutParams) (appBarLayout.layoutParams as ViewGroup.MarginLayoutParams)
.topMargin = insets.systemWindowInsetTop .topMargin = insets.systemWindowInsetTop
@@ -48,6 +41,7 @@ internal class MainActivity : AppCompatActivity(R.layout.activity_main) {
} }
} }
// TODO remove this translucent app bar layout stuff, it's hard to maintain
window.decorView.systemUiVisibility = if (resources.getBoolean(R.bool.isLight)) { window.decorView.systemUiVisibility = if (resources.getBoolean(R.bool.isLight)) {
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else { } else {
@@ -59,8 +53,8 @@ internal class MainActivity : AppCompatActivity(R.layout.activity_main) {
} }
window.statusBarColor = Color.TRANSPARENT window.statusBarColor = Color.TRANSPARENT
bottomNavigationView.setOnNavigationItemSelectedListener { item -> binding.bottomNav.setOnNavigationItemSelectedListener { item ->
actionBar.setExpanded(true) binding.appBarLayout.setExpanded(true)
loadFragment(viewModel.getFragmentType(item.itemId)) loadFragment(viewModel.getFragmentType(item.itemId))
} }
@@ -89,11 +83,16 @@ internal class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (supportFragmentManager.fragments.size == 0) { if (supportFragmentManager.fragments.size == 0) {
bottomNavigationView.selectedItemId = R.id.courses binding.bottomNav.selectedItemId = R.id.courses
loadFragment(viewModel.getFragmentType(R.id.courses)) loadFragment(viewModel.getFragmentType(R.id.courses))
} }
} }
override fun onDestroy() {
super.onDestroy()
_binding = null
}
private fun loadFragment(type: String): Boolean { private fun loadFragment(type: String): Boolean {
val fragment = supportFragmentManager.findFragmentByTag(type) ?: viewModel.getFragment(type) val fragment = supportFragmentManager.findFragmentByTag(type) ?: viewModel.getFragment(type)
@@ -101,8 +100,10 @@ internal class MainActivity : AppCompatActivity(R.layout.activity_main) {
return false return false
} }
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, type) supportFragmentManager.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).commit() .replace(R.id.fragment_container, fragment, type)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit()
// with (supportFragmentManager) { // with (supportFragmentManager) {
// beginTransaction() // beginTransaction()
@@ -118,8 +119,8 @@ internal class MainActivity : AppCompatActivity(R.layout.activity_main) {
// Log.d("TAG2", "${supportFragmentManager.}") // supportFragmentManager.fragments[0].tag} ${supportFragmentManager.fragments[0].javaClass.simpleName // Log.d("TAG2", "${supportFragmentManager.}") // supportFragmentManager.fragments[0].tag} ${supportFragmentManager.fragments[0].javaClass.simpleName
when (supportFragmentManager.fragments[0].tag) { when (supportFragmentManager.fragments[0].tag) {
"GradeFragment", "ParticipationCourseFragment" -> { "GradeFragment", "ParticipationCourseFragment" -> {
bottomNavigationView.visibility = View.INVISIBLE binding.bottomNav.visibility = View.INVISIBLE
findViewById<View>(R.id.view).visibility = View.INVISIBLE binding.view.visibility = View.INVISIBLE
super.onBackPressed() super.onBackPressed()
} }
"NoteFragment" -> { "NoteFragment" -> {
@@ -128,8 +129,8 @@ internal class MainActivity : AppCompatActivity(R.layout.activity_main) {
} }
} }
else -> { else -> {
bottomNavigationView.visibility = View.VISIBLE binding.bottomNav.visibility = View.VISIBLE
findViewById<View>(R.id.view).visibility = View.VISIBLE binding.view.visibility = View.VISIBLE
super.onBackPressed() super.onBackPressed()
} }
} }
@@ -12,6 +12,7 @@ import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.model.Course import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.util.getUserDefinedAverage import com.denizd.qwark.util.getUserDefinedAverage
import com.denizd.qwark.util.round
import com.denizd.qwark.util.roundToInt import com.denizd.qwark.util.roundToInt
class CourseAdapter(private var courses: List<CourseExam>, class CourseAdapter(private var courses: List<CourseExam>,
@@ -69,14 +70,16 @@ class CourseAdapter(private var courses: List<CourseExam>,
else -> context.getString(R.string.average_grade_placeholder, currentItem.average.getUserDefinedAverage(gradeType)) else -> context.getString(R.string.average_grade_placeholder, currentItem.average.getUserDefinedAverage(gradeType))
} }
} }
var timeLeft = ((currentItem.examTime.toDouble() - QwarkUtil.timeAtMidnight.toDouble()) / (1000.0 * 60.0 * 60.0 * 24.0)).roundToInt() val examText = when (val timeLeft = ((currentItem.examTime.toDouble() - QwarkUtil.timeAtMidnight.toDouble()) / (1000.0 * 60.0 * 60.0 * 24.0)).roundToInt()) {
val examText = when (timeLeft) {
0 -> context.getString(R.string.exam_today_placeholder) 0 -> context.getString(R.string.exam_today_placeholder)
else -> { else -> {
when { when {
timeLeft > 7 -> { timeLeft > 7 -> {
timeLeft /= 7 context.resources.getQuantityString(
context.resources.getQuantityString(R.plurals.exam_weeks_placeholder, timeLeft, timeLeft.toString()) R.plurals.exam_weeks_placeholder,
2,
(timeLeft.toDouble() / 7.0).round(1).toString()
)
} }
timeLeft in 1..7 -> context.resources.getQuantityString(R.plurals.exam_days_placeholder, timeLeft, timeLeft.toString()) timeLeft in 1..7 -> context.resources.getQuantityString(R.plurals.exam_days_placeholder, timeLeft, timeLeft.toString())
else -> "" else -> ""
@@ -53,7 +53,16 @@ class ParticipationAdapter(private var participations: List<Participation>, priv
} }
} }
)) ))
holder.time.text = QwarkUtil.getSimpleDateTimeFormat().format(Date(currentItem.time)) holder.time.text = buildString {
append(QwarkUtil.getSimpleDateTimeFormat().format(Date(currentItem.time)))
// TODO this checks the time on fragment launch, but it doesn't change, even if the time has passed
append(if (currentItem.time > System.currentTimeMillis() - 1000 * 60 * 90) {
holder.time.context.getString(R.string.participation_resumable)
} else {
""
})
}
holder.participationText.text = holder.participationText.context.getString( holder.participationText.text = holder.participationText.context.getString(
R.string.participation_placeholder, R.string.participation_placeholder,
currentItem.timesHandRaised.toString(), currentItem.timesHandRaised.toString(),
@@ -21,4 +21,6 @@ internal class CourseRepository(app: Application) {
fun getCoursesByYearId(yearId: Int): LiveData<List<CourseExam>> = dao.getCoursesByYearId(yearId) fun getCoursesByYearId(yearId: Int): LiveData<List<CourseExam>> = dao.getCoursesByYearId(yearId)
fun getAveragesForCourses(courseId: Int): List<HistoricalAvg> = dao.getAveragesForCourses(courseId) fun getAveragesForCourses(courseId: Int): List<HistoricalAvg> = dao.getAveragesForCourses(courseId)
fun getCourse(courseId: Int): CourseExam = dao.getCourse(courseId)[0]
} }
@@ -42,6 +42,6 @@ class FinalsRepository(app: Application) {
fun getAllCourses() = dao.getAllCourseExams() fun getAllCourses() = dao.getAllCourseExams()
fun getCourse(courseId: Int) = dao.getCourse(courseId)[0] fun getCourse(courseId: Int) = dao.getCourse(courseId)[0]
fun getFinalGrade(finalGradeId: Int) = dao.getFinalGrade(finalGradeId)[0]
fun update(finalGrade: FinalGrade) { dao.update(finalGrade) } fun update(finalGrade: FinalGrade) { dao.update(finalGrade) }
} }
@@ -27,4 +27,5 @@ class GradeRepository(app: Application) {
} }
fun getGradesByForeignKey(courseId: Int): LiveData<List<Grade>> = dao.getGradesByForeignKey(courseId) fun getGradesByForeignKey(courseId: Int): LiveData<List<Grade>> = dao.getGradesByForeignKey(courseId)
fun getGrade(gradeId: Int) = dao.getGrade(gradeId)[0]
} }
@@ -16,4 +16,5 @@ class NoteRepository(app: Application) {
fun update(note: Note) { dao.update(note) } fun update(note: Note) { dao.update(note) }
fun updateDismissed(newDismissedStatus: Boolean, noteId: Int) { dao.updateDismissed(newDismissedStatus, noteId) } fun updateDismissed(newDismissedStatus: Boolean, noteId: Int) { dao.updateDismissed(newDismissedStatus, noteId) }
fun delete(noteId: Int) { dao.deleteNote(noteId) } fun delete(noteId: Int) { dao.deleteNote(noteId) }
fun getNote(noteId: Int) = dao.getNote(noteId)[0]
} }
@@ -3,14 +3,12 @@ package com.denizd.qwark.database
import android.app.Application import android.app.Application
import android.util.Log import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.denizd.qwark.util.QwarkPreferences
import com.denizd.qwark.model.Course import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.model.Participation import com.denizd.qwark.model.Participation
import com.denizd.qwark.model.SchoolDay import com.denizd.qwark.model.SchoolDay
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.*
import com.denizd.qwark.util.round import com.denizd.qwark.util.QwarkPreferences
import com.denizd.qwark.util.roundToInt
import java.util.* import java.util.*
class ParticipationRepository(app: Application) { class ParticipationRepository(app: Application) {
@@ -46,8 +44,7 @@ class ParticipationRepository(app: Application) {
fun getDayType(): String = if (dayId in 1..5) days[dayId - 1] else days[1] fun getDayType(): String = if (dayId in 1..5) days[dayId - 1] else days[1]
fun getDays(): List<SchoolDay> = dao.getDays(prefs.getSchoolYear()) fun getDays(): List<SchoolDay> = dao.getDays(prefs.getSchoolYear())
fun getCourses(): List<CourseExam> = QwarkUtil.getCoursesSorted( fun getCourses(): List<CourseExam> = dao.getCoursesByYearIdAsList(prefs.getSchoolYear()).getSorted(
dao.getCoursesByYearIdAsList(prefs.getSchoolYear()),
prefs.getCourseSortType() prefs.getCourseSortType()
) )
fun link(courseId: Int) { dao.link(courseId, getDayType(), prefs.getSchoolYear()) } fun link(courseId: Int) { dao.link(courseId, getDayType(), prefs.getSchoolYear()) }
@@ -67,6 +64,11 @@ class ParticipationRepository(app: Application) {
) )
} }
fun delete(participation: Participation) { dao.delete(participation) } fun delete(participation: Participation) { dao.delete(participation) }
fun updateParticipation(participation: String, courseId: Int) { dao.updateParticipation(participation, courseId) } fun updateParticipation(participation: String, courseId: Int) {
dao.updateParticipation(participation, courseId)
}
fun updateParticipation(timesHandRaised: Int, timesSpoken: Int, participationId: Int) {
dao.updateParticipation(timesHandRaised, timesSpoken, participationId)
}
fun getSchoolYearName() = prefs.getSchoolYearName() fun getSchoolYearName() = prefs.getSchoolYearName()
} }
@@ -47,6 +47,9 @@ interface QwarkDao {
@Query("UPDATE course SET participation = :participation WHERE course_id = :courseId") @Query("UPDATE course SET participation = :participation WHERE course_id = :courseId")
fun updateParticipation(participation: String, courseId: Int) fun updateParticipation(participation: String, courseId: Int)
@Query("UPDATE participation SET times_hand_raised = :timesHandRaised, times_spoken = :timesSpoken WHERE participation_id = :participationId")
fun updateParticipation(timesHandRaised: Int, timesSpoken: Int, participationId: Int)
// grades // grades
@get:Query("SELECT * FROM grade ORDER BY time") @get:Query("SELECT * FROM grade ORDER BY time")
@@ -64,6 +67,9 @@ interface QwarkDao {
@Query("DELETE FROM grade WHERE grade_id = :gradeId") @Query("DELETE FROM grade WHERE grade_id = :gradeId")
fun deleteGrade(gradeId: Int) fun deleteGrade(gradeId: Int)
@Query("SELECT * FROM grade WHERE grade_id = :gradeId")
fun getGrade(gradeId: Int): List<Grade>
// notes // notes
@get:Query("SELECT * FROM note ORDER BY time DESC") @get:Query("SELECT * FROM note ORDER BY time DESC")
@@ -90,6 +96,9 @@ interface QwarkDao {
@Query("SELECT DISTINCT category FROM note") @Query("SELECT DISTINCT category FROM note")
fun getAllCategories(): List<String> fun getAllCategories(): List<String>
@Query("SELECT * FROM note WHERE note_id = :noteId")
fun getNote(noteId: Int): List<Note>
// historical averages // historical averages
@get:Query("SELECT * FROM historical_avg ORDER BY course_id DESC") @get:Query("SELECT * FROM historical_avg ORDER BY course_id DESC")
@@ -155,6 +164,9 @@ interface QwarkDao {
@Insert @Insert
fun insertAll(finalGrades: Array<FinalGrade>) fun insertAll(finalGrades: Array<FinalGrade>)
@Query("SELECT * FROM final_grade WHERE final_grade_id = :finalGradeId")
fun getFinalGrade(finalGradeId: Int): List<FinalGrade>
// school days // school days
@Insert @Insert
@@ -174,7 +186,7 @@ interface QwarkDao {
@Query("DELETE FROM course_schoolday_relation WHERE relation_id = :relationId") @Query("DELETE FROM course_schoolday_relation WHERE relation_id = :relationId")
fun removeLink(relationId: Int) fun removeLink(relationId: Int)
@Query("SELECT * FROM participation WHERE course_id = :courseId") @Query("SELECT * FROM participation WHERE course_id = :courseId ORDER BY time DESC")
fun getAllParticipationsForCourse(courseId: Int): LiveData<List<Participation>> fun getAllParticipationsForCourse(courseId: Int): LiveData<List<Participation>>
@Insert @Insert
@@ -8,44 +8,44 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.StaggeredGridLayoutManager import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.adapter.CourseAdapter import com.denizd.qwark.adapter.CourseAdapter
import com.denizd.qwark.sheet.ConfirmDeletionBottomSheet import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.CourseCreateBottomSheet import com.denizd.qwark.sheet.CourseCreateSheet
import com.denizd.qwark.sheet.CourseOptionsBottomSheet import com.denizd.qwark.sheet.CourseOptionsSheet
import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.databinding.* import com.denizd.qwark.databinding.*
import com.denizd.qwark.sheet.HistoricalAverageBottomSheet import com.denizd.qwark.sheet.HistoricalAverageSheet
import com.denizd.qwark.model.Course import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.util.calculateTotalAverage import com.denizd.qwark.util.calculateTotalAverage
import com.denizd.qwark.util.getSorted
import com.denizd.qwark.viewmodel.CourseViewModel import com.denizd.qwark.viewmodel.CourseViewModel
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import java.lang.NumberFormatException import java.lang.NumberFormatException
internal class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListener { class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListener {
private var _binding: PaddedRecyclerViewBinding? = null private var _binding: PaddedRecyclerViewBinding? = null
private val binding: PaddedRecyclerViewBinding get() = _binding!! private val binding: PaddedRecyclerViewBinding get() = _binding!!
private lateinit var viewModel: CourseViewModel private val viewModel: CourseViewModel by viewModels()
private lateinit var recyclerViewAdapter: CourseAdapter private lateinit var recyclerViewAdapter: CourseAdapter
private var scrollPosition: Parcelable? = null private var scrollPosition: Parcelable? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this)[CourseViewModel::class.java]
recyclerViewAdapter = CourseAdapter(ArrayList(), this, viewModel.getGradeType()) recyclerViewAdapter = CourseAdapter(ArrayList(), this, viewModel.getGradeType())
viewModel.allCourses.observe(this, Observer { courses -> viewModel.allCourses.observe(this, Observer { courses ->
val c = QwarkUtil.getCoursesSorted(courses, viewModel.getCourseSortType()) recyclerViewAdapter.setCourses(courses.getSorted(viewModel.getCourseSortType()))
recyclerViewAdapter.setCourses(c)
if (scrollPosition == null) { if (scrollPosition == null) {
binding.recyclerView.scrollToPosition(0) binding.recyclerView.apply {
binding.recyclerView.scheduleLayoutAnimation() scrollToPosition(0)
scheduleLayoutAnimation()
}
} else { } else {
binding.recyclerView.layoutManager?.onRestoreInstanceState(scrollPosition) binding.recyclerView.layoutManager?.onRestoreInstanceState(scrollPosition)
} }
@@ -105,16 +105,7 @@ internal class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListen
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.recyclerView.apply { binding.recyclerView.apply {
applyPadding(verticalPadding = 4) applyPadding(horizontalPadding = 4)
/**
* On first app launch, setting the padding will not scroll the recycler view items
* down. This is a workaround to scroll the recycler view down programmatically.
*/
// TODO this actually doesn't do anything
// if (!QwarkUtil.hasAppLaunched) {
// scrollToPosition(0)
// QwarkUtil.hasAppLaunched = true
// }
} }
} }
@@ -142,8 +133,8 @@ internal class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListen
} }
private fun createOptionsDialog(course: CourseExam) { private fun createOptionsDialog(course: CourseExam) {
openBottomSheet(CourseOptionsBottomSheet().also { sheet -> openBottomSheet(CourseOptionsSheet().also { sheet ->
QwarkUtil.putCourseInBundle(sheet, course) sheet.arguments = Bundle().apply { putInt("courseId", course.courseId) }
}) })
} }
@@ -162,7 +153,7 @@ internal class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListen
fun getAveragesForCourse(courseId: Int) = viewModel.getAveragesForCourses(courseId) fun getAveragesForCourse(courseId: Int) = viewModel.getAveragesForCourses(courseId)
fun createHistoryDialog(courseId: Int, course: String) { fun createHistoryDialog(courseId: Int, course: String) {
openBottomSheet(HistoricalAverageBottomSheet().also { sheet -> openBottomSheet(HistoricalAverageSheet().also { sheet ->
sheet.arguments = Bundle(2).apply { sheet.arguments = Bundle(2).apply {
putString("courseName", course) putString("courseName", course)
putInt("courseId", courseId) putInt("courseId", courseId)
@@ -171,18 +162,20 @@ internal class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListen
} }
fun createCourseDialog(course: CourseExam? = null) { fun createCourseDialog(course: CourseExam? = null) {
openBottomSheet(CourseCreateBottomSheet().also { sheet -> openBottomSheet(CourseCreateSheet().also { sheet ->
if (course != null) QwarkUtil.putCourseInBundle(sheet, course) if (course != null) sheet.arguments = Bundle().apply { putInt("courseId", course.courseId) }
}) })
} }
fun deleteCourse(course: Course) { fun deleteCourse(course: Course) {
openBottomSheet( openBottomSheet(
ConfirmDeletionBottomSheet( ConfirmDeletionSheet(
getString(R.string.delete_course_and_data_confirmation, course.name) getString(R.string.delete_course_and_data_confirmation, course.name)
) { ) {
viewModel.delete(course) viewModel.delete(course)
} }
) )
} }
fun getCourse(courseId: Int): CourseExam = viewModel.getCourse(courseId)
} }
@@ -3,27 +3,26 @@ package com.denizd.qwark.fragment
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.adapter.FinalGradeAdapter import com.denizd.qwark.adapter.FinalGradeAdapter
import com.denizd.qwark.sheet.ConfirmDeletionBottomSheet import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.FinalsCreateBottomSheet import com.denizd.qwark.sheet.FinalsCreateSheet
import com.denizd.qwark.sheet.FinalsOptionsBottomSheet import com.denizd.qwark.sheet.FinalsOptionsSheet
import com.denizd.qwark.databinding.FinalsFragmentBinding import com.denizd.qwark.databinding.FinalsFragmentBinding
import com.denizd.qwark.sheet.FinalsLinkBottomSheet import com.denizd.qwark.sheet.FinalsLinkSheet
import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.model.FinalGrade import com.denizd.qwark.model.FinalGrade
import com.denizd.qwark.viewmodel.FinalsViewModel import com.denizd.qwark.viewmodel.FinalsViewModel
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
internal class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeClickListener { class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeClickListener {
private lateinit var viewModel: FinalsViewModel private lateinit var viewModel: FinalsViewModel
private var _binding: FinalsFragmentBinding? = null private var _binding: FinalsFragmentBinding? = null
@@ -44,7 +43,7 @@ internal class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeCli
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this)[FinalsViewModel::class.java] viewModel = ViewModelProvider(this)[FinalsViewModel::class.java]
viewModel.updateLinkedGrades { viewModel.updateLinkedGrades {
viewModel.allFinalGrades?.observe(this, Observer { finalGrades -> viewModel.allFinalGrades.observe(this, Observer { finalGrades ->
// createOverview(finalGrades, view.rootView) // TODO export to bitmap // createOverview(finalGrades, view.rootView) // TODO export to bitmap
if (basicScrollPosition == null) { if (basicScrollPosition == null) {
binding.basicCoursesRecyclerview.scheduleLayoutAnimation() binding.basicCoursesRecyclerview.scheduleLayoutAnimation()
@@ -67,7 +66,7 @@ internal class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeCli
binding.gradeTextview.text = "---" binding.gradeTextview.text = "---"
} else { } else {
pointsText = "$finalScore" pointsText = "$finalScore"
gradeText = getString(R.string.approximate_placeholder, viewModel.getFinalGrade(finalScore).toString()) gradeText = getString(R.string.approximate_placeholder, viewModel.getFinalGradeScore(finalScore).toString())
setTextForGradeTextViews() setTextForGradeTextViews()
} }
@@ -126,41 +125,42 @@ internal class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeCli
} }
override fun onFinalGradeClick(finalGrade: FinalGrade) { override fun onFinalGradeClick(finalGrade: FinalGrade) {
openBottomSheet(FinalsOptionsBottomSheet().also { sheet -> openBottomSheet(FinalsOptionsSheet().also { sheet ->
QwarkUtil.putFinalGradeInBundle(sheet, finalGrade) sheet.arguments = Bundle().apply { putInt("finalGradeId", finalGrade.finalGradeId) }
}) })
} }
internal fun createEditGradeSheet(finalGrade: FinalGrade) { fun createEditGradeSheet(finalGrade: FinalGrade) {
openBottomSheet(FinalsCreateBottomSheet().also { sheet -> openBottomSheet(FinalsCreateSheet().also { sheet ->
QwarkUtil.putFinalGradeInBundle(sheet, finalGrade) sheet.arguments = Bundle().apply { putInt("finalGradeId", finalGrade.finalGradeId) }
}) })
} }
internal fun createLinkGradeSheet(finalGrade: FinalGrade) { fun createLinkGradeSheet(finalGrade: FinalGrade) {
openBottomSheet(FinalsLinkBottomSheet().also { sheet -> openBottomSheet(FinalsLinkSheet().also { sheet ->
QwarkUtil.putFinalGradeInBundle(sheet, finalGrade) sheet.arguments = Bundle().apply { putInt("finalGradeId", finalGrade.finalGradeId) }
}) })
} }
internal fun getAllYears() = viewModel.getAllYears() fun getAllYears() = viewModel.getAllYears()
internal fun getAllCourses() = viewModel.getAllCourses() fun getAllCourses() = viewModel.getAllCourses()
internal fun viewLinkedCourse(courseId: Int) { fun viewLinkedCourse(courseId: Int) {
val f = GradeFragment() val f = GradeFragment().also { fragment ->
QwarkUtil.putCourseInBundle(f, viewModel.getCourse(courseId)) fragment.arguments = Bundle().apply {
val d = viewModel.getSchoolYearName(courseId) putInt("courseId", courseId)
Log.d("TAG", d) putString("schoolYear", viewModel.getSchoolYearName(courseId))
f.arguments?.putString("schoolYear", d) }
activity?.supportFragmentManager?.beginTransaction() }
?.replace(R.id.fragment_container, f) (context as FragmentActivity).supportFragmentManager.beginTransaction()
?.addToBackStack("GradeFragment") .replace(R.id.fragment_container, f)
?.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) .addToBackStack(f.name)
?.commit() .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit()
} }
internal fun clearFinalGrade(finalGrade: FinalGrade) { fun clearFinalGrade(finalGrade: FinalGrade) {
val deletionSheet = ConfirmDeletionBottomSheet(getString(R.string.clear_final_grade_desc, finalGrade.name)) { val deletionSheet = ConfirmDeletionSheet(getString(R.string.clear_final_grade_desc, finalGrade.name)) {
val newFinalGrade = FinalGrade( val newFinalGrade = FinalGrade(
name = "", name = "",
grade = "-1", grade = "-1",
@@ -175,14 +175,14 @@ internal class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeCli
openBottomSheet(deletionSheet) openBottomSheet(deletionSheet)
} }
internal fun clearFinalGradeError() { fun clearFinalGradeError() {
Snackbar Snackbar
.make(snackBarContainer, getString(R.string.clear_final_grade_error), Snackbar.LENGTH_LONG) .make(snackBarContainer, getString(R.string.clear_final_grade_error), Snackbar.LENGTH_LONG)
.setBackgroundTint(context.getColor(R.color.colorWarning)) .setBackgroundTint(context.getColor(R.color.colorWarning))
.show() .show()
} }
internal fun update(finalGrade: FinalGrade) { viewModel.update(finalGrade) } fun update(finalGrade: FinalGrade) { viewModel.update(finalGrade) }
// TODO perhaps replace with a bottom sheet // TODO perhaps replace with a bottom sheet
// private fun createOverview(finalGrades: List<FinalGrade>, view: View) { // private fun createOverview(finalGrades: List<FinalGrade>, view: View) {
@@ -284,6 +284,7 @@ internal class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeCli
binding.finalExamsRecyclerview.layoutManager?.onRestoreInstanceState(examScrollPosition) binding.finalExamsRecyclerview.layoutManager?.onRestoreInstanceState(examScrollPosition)
} }
internal fun getCourseSortType() = viewModel.getCourseSortType() fun getCourseSortType() = viewModel.getCourseSortType()
fun getGradeType() = viewModel.getGradeType() fun getGradeType() = viewModel.getGradeType()
fun getFinalGrade(finalGradeId: Int) = viewModel.getFinalGrade(finalGradeId)
} }
@@ -2,24 +2,22 @@ package com.denizd.qwark.fragment
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.adapter.GradeAdapter import com.denizd.qwark.adapter.GradeAdapter
import com.denizd.qwark.sheet.ConfirmDeletionBottomSheet import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.GradeCreateBottomSheet import com.denizd.qwark.sheet.GradeCreateSheet
import com.denizd.qwark.databinding.GradeFragmentBinding import com.denizd.qwark.databinding.GradeFragmentBinding
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.model.Grade import com.denizd.qwark.model.Grade
import com.denizd.qwark.model.HistoricalAvg import com.denizd.qwark.model.HistoricalAvg
import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.util.calculateAverage import com.denizd.qwark.util.calculateAverage
import com.denizd.qwark.util.getUserDefinedAverage import com.denizd.qwark.util.getUserDefinedAverage
import com.denizd.qwark.viewmodel.GradeViewModel import com.denizd.qwark.viewmodel.GradeViewModel
@@ -34,7 +32,7 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
private lateinit var weightingString: String private lateinit var weightingString: String
private lateinit var adapter: GradeAdapter private lateinit var adapter: GradeAdapter
private lateinit var viewModel: GradeViewModel private val viewModel: GradeViewModel by viewModels()
private lateinit var inflater: LayoutInflater private lateinit var inflater: LayoutInflater
private var _binding: GradeFragmentBinding? = null private var _binding: GradeFragmentBinding? = null
@@ -45,12 +43,9 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this)[GradeViewModel::class.java]
// currentCourse = QwarkUtil.getCourseFromBundle(arguments)
schoolYear = arguments?.getString("schoolYear") ?: "" schoolYear = arguments?.getString("schoolYear") ?: ""
currentCourse = viewModel.getCourse(arguments?.getInt("courseId") ?: -1) currentCourse = viewModel.getCourse(arguments?.getInt("courseId") ?: -1)
average = currentCourse.average average = currentCourse.average.getUserDefinedAverage(getGradeType())
weightingString = "${currentCourse.oralWeighting} / ${100 - currentCourse.oralWeighting}" weightingString = "${currentCourse.oralWeighting} / ${100 - currentCourse.oralWeighting}"
viewModel.getGradesByForeignKey(currentCourse.courseId).observe(this, Observer { grades -> viewModel.getGradesByForeignKey(currentCourse.courseId).observe(this, Observer { grades ->
@@ -67,7 +62,7 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
average = filteredGrades.calculateAverage( average = filteredGrades.calculateAverage(
currentCourse.oralWeighting currentCourse.oralWeighting
) )
binding.average.text = if (filteredGrades.isEmpty()) "X" else average.getUserDefinedAverage(getGradeType()) binding.average.text = if (filteredGrades.isEmpty()) "??" else average.getUserDefinedAverage(getGradeType())
viewModel.updateAverage(average, filteredGrades.size, currentCourse.courseId) viewModel.updateAverage(average, filteredGrades.size, currentCourse.courseId)
} }
@@ -94,7 +89,7 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
currentCourse.name currentCourse.name
) )
fab.hide() fab.hide()
with(view.rootView) { with (view.rootView) {
findViewById<BottomNavigationView>(R.id.bottom_nav).visibility = View.GONE findViewById<BottomNavigationView>(R.id.bottom_nav).visibility = View.GONE
findViewById<View>(R.id.view).visibility = View.GONE findViewById<View>(R.id.view).visibility = View.GONE
} }
@@ -103,7 +98,7 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
presentGradeDialog() presentGradeDialog()
} }
binding.average.text = currentCourse.average binding.average.text = currentCourse.average.getUserDefinedAverage(getGradeType())
binding.weighting.text = weightingString binding.weighting.text = weightingString
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
@@ -135,12 +130,12 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
} }
private fun presentGradeDialog(grade: Grade? = null) { private fun presentGradeDialog(grade: Grade? = null) {
openBottomSheet(GradeCreateBottomSheet().also { sheet -> openBottomSheet(GradeCreateSheet().also { sheet ->
if (grade == null) { sheet.arguments = Bundle(1).apply { if (grade == null) {
sheet.arguments = Bundle(1).apply { putInt("courseId", currentCourse.courseId) } putInt("courseId", currentCourse.courseId)
} else { } else {
QwarkUtil.putGradeInBundle(sheet, grade) putInt("gradeId", grade.gradeId)
} }}
}) })
} }
@@ -149,7 +144,7 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
} }
override fun onGradeLongClick(gradeId: Int) { override fun onGradeLongClick(gradeId: Int) {
val deletionSheet = ConfirmDeletionBottomSheet(getString(R.string.confirm_grade_deletion)) { val deletionSheet = ConfirmDeletionSheet(getString(R.string.confirm_grade_deletion)) {
viewModel.delete(gradeId) viewModel.delete(gradeId)
} }
openBottomSheet(deletionSheet) openBottomSheet(deletionSheet)
@@ -157,23 +152,27 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
private fun openParticipationCourseFragment() { private fun openParticipationCourseFragment() {
appBar.setExpanded(true) appBar.setExpanded(true)
(context as FragmentActivity).supportFragmentManager.also { fm ->
if (fm.getBackStackEntryAt(0).name == "ParticipationCourseFragment") {
fm.popBackStack()
} else {
val f = ParticipationCourseFragment() val f = ParticipationCourseFragment()
f.arguments = Bundle().apply { f.arguments = Bundle().apply {
putString("course", currentCourse.name) putString("course", currentCourse.name)
putInt("courseId", currentCourse.courseId) putInt("courseId", currentCourse.courseId)
putBoolean("advanced", currentCourse.advanced) putBoolean("advanced", currentCourse.advanced)
} }
// for targetFragment to work, ParticipationFragment needs to be active fm.beginTransaction()
// TODO fix the dependency on targetFragment (maybe introduce a ParticipationCourseViewModel)
// f.setTargetFragment((context as FragmentActivity).supportFragmentManager.findFragmentByTag("ParticipationFragment"), 42)
(context as FragmentActivity).supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, f) .replace(R.id.fragment_container, f)
.addToBackStack(f.name) .addToBackStack(f.name)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit() .commit()
} }
}
}
fun insert(grade: Grade) { viewModel.insert(grade) } fun insert(grade: Grade) { viewModel.insert(grade) }
fun update(grade: Grade) { viewModel.update(grade) } fun update(grade: Grade) { viewModel.update(grade) }
fun getGradeType(): Int = viewModel.getGradeType() fun getGradeType(): Int = viewModel.getGradeType()
fun getGrade(gradeId: Int) = viewModel.getGrade(gradeId)
} }
@@ -11,14 +11,13 @@ import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.StaggeredGridLayoutManager import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.adapter.NoteAdapter import com.denizd.qwark.adapter.NoteAdapter
import com.denizd.qwark.sheet.ConfirmDeletionBottomSheet import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.NoteCreateBottomSheet import com.denizd.qwark.sheet.NoteCreateSheet
import com.denizd.qwark.sheet.NoteDisplayBottomSheet import com.denizd.qwark.sheet.NoteDisplaySheet
import com.denizd.qwark.sheet.NoteOptionsBottomSheet import com.denizd.qwark.sheet.NoteOptionsSheet
import com.denizd.qwark.util.OnBackPressed import com.denizd.qwark.util.OnBackPressed
import com.denizd.qwark.databinding.* import com.denizd.qwark.databinding.*
import com.denizd.qwark.model.Note import com.denizd.qwark.model.Note
import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.viewmodel.NoteViewModel import com.denizd.qwark.viewmodel.NoteViewModel
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
@@ -82,7 +81,7 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.recyclerView.applyPadding(verticalPadding = 4) binding.recyclerView.applyPadding(horizontalPadding = 4)
} }
override fun onDestroy() { override fun onDestroy() {
@@ -113,8 +112,8 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
} }
override fun onNoteClick(note: Note) { override fun onNoteClick(note: Note) {
openBottomSheet(NoteDisplayBottomSheet().also { sheet -> openBottomSheet(NoteDisplaySheet().also { sheet ->
QwarkUtil.putNoteInBundle(sheet, note) sheet.arguments = Bundle().apply { putInt("noteId", note.noteId) }
}) })
} }
@@ -124,7 +123,7 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
} }
fun deleteNote(noteId: Int) { fun deleteNote(noteId: Int) {
val deletionSheet = ConfirmDeletionBottomSheet(getString(R.string.confirm_note_deletion)) { val deletionSheet = ConfirmDeletionSheet(getString(R.string.confirm_note_deletion)) {
scrollPosition = binding.recyclerView.layoutManager?.onSaveInstanceState() scrollPosition = binding.recyclerView.layoutManager?.onSaveInstanceState()
viewModel.delete(noteId) viewModel.delete(noteId)
binding.recyclerView.scheduleLayoutAnimation() binding.recyclerView.scheduleLayoutAnimation()
@@ -141,14 +140,14 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
} }
private fun createOptionsSheet(note: Note) { private fun createOptionsSheet(note: Note) {
openBottomSheet(NoteOptionsBottomSheet().also { sheet -> openBottomSheet(NoteOptionsSheet().also { sheet ->
QwarkUtil.putNoteInBundle(sheet, note) sheet.arguments = Bundle().apply { putInt("noteId", note.noteId) }
}) })
} }
fun createNoteDialog(note: Note? = null) { fun createNoteDialog(note: Note? = null) {
val createSheet = NoteCreateBottomSheet().also { sheet -> val createSheet = NoteCreateSheet().also { sheet ->
if (note != null) QwarkUtil.putNoteInBundle(sheet, note) if (note != null) sheet.arguments = Bundle().apply { putInt("noteId", note.noteId) }
} }
openBottomSheet(createSheet) openBottomSheet(createSheet)
} }
@@ -165,4 +164,5 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
fun insert(note: Note) { viewModel.insert(note) } fun insert(note: Note) { viewModel.insert(note) }
fun update(note: Note) { viewModel.update(note) } fun update(note: Note) { viewModel.update(note) }
fun getAllCategories(): List<String> = viewModel.getAllCategories() fun getAllCategories(): List<String> = viewModel.getAllCategories()
fun getNote(noteId: Int) = viewModel.getNote(noteId)
} }
@@ -14,9 +14,10 @@ import com.denizd.qwark.adapter.ParticipationAdapter
import com.denizd.qwark.databinding.GradeFragmentBinding import com.denizd.qwark.databinding.GradeFragmentBinding
import com.denizd.qwark.model.Participation import com.denizd.qwark.model.Participation
import com.denizd.qwark.sheet.ClassSessionSheet import com.denizd.qwark.sheet.ClassSessionSheet
import com.denizd.qwark.sheet.ConfirmDeletionBottomSheet import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.viewmodel.ParticipationCourseViewModel import com.denizd.qwark.viewmodel.ParticipationCourseViewModel
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.snackbar.Snackbar
class ParticipationCourseFragment : QwarkFragment(), ParticipationAdapter.ParticipationClickListener { class ParticipationCourseFragment : QwarkFragment(), ParticipationAdapter.ParticipationClickListener {
@@ -109,11 +110,24 @@ class ParticipationCourseFragment : QwarkFragment(), ParticipationAdapter.Partic
} }
override fun onParticipationClick(participation: Participation) { override fun onParticipationClick(participation: Participation) {
// do nothing if (participation.time > System.currentTimeMillis() - 1000 * 60 * 90) {
openBottomSheet(ClassSessionSheet().also { sheet ->
sheet.arguments = Bundle(2).apply {
putInt("timesHandRaised", participation.timesHandRaised)
putInt("timesSpoken", participation.timesSpoken)
putInt("participationId", participation.participationId)
}
sheet.isCancelable = false
})
} else {
Snackbar
.make(snackBarContainer, getString(R.string.participation_too_old), Snackbar.LENGTH_LONG)
.show()
}
} }
override fun onParticipationLongClick(participation: Participation) { override fun onParticipationLongClick(participation: Participation) {
openBottomSheet(ConfirmDeletionBottomSheet( openBottomSheet(ConfirmDeletionSheet(
getString(R.string.delete_participation_confirmation) getString(R.string.delete_participation_confirmation)
) { ) {
viewModel.delete(participation) viewModel.delete(participation)
@@ -122,19 +136,30 @@ class ParticipationCourseFragment : QwarkFragment(), ParticipationAdapter.Partic
private fun openGradeFragment() { private fun openGradeFragment() {
appBar.setExpanded(true) appBar.setExpanded(true)
(context as FragmentActivity).supportFragmentManager.also { fm ->
if (fm.getBackStackEntryAt(0).name == "GradeFragment") {
fm.popBackStack()
} else {
val f = GradeFragment() val f = GradeFragment()
f.arguments = Bundle().apply { f.arguments = Bundle().apply {
putString("schoolYear", viewModel.getSchoolYearName()) putString("schoolYear", viewModel.getSchoolYearName())
putInt("courseId", courseId) putInt("courseId", courseId)
} }
(context as FragmentActivity).supportFragmentManager.beginTransaction() fm.beginTransaction()
.replace(R.id.fragment_container, f) .replace(R.id.fragment_container, f)
.addToBackStack("GradeFragment") .addToBackStack("GradeFragment")
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit() .commit()
} }
}
}
fun createParticipation(timesHandRaised: Int, timesSpoken: Int, time: Long) { fun createParticipation(timesHandRaised: Int, timesSpoken: Int, time: Long) {
viewModel.createParticipation(timesHandRaised, timesSpoken, time, courseId) viewModel.createParticipation(timesHandRaised, timesSpoken, time, courseId)
} }
// TODO this function has the same name as another one with a different function signature
fun updateParticipation(timesHandRaised: Int, timesSpoken: Int, participationId: Int) {
viewModel.updateParticipation(timesHandRaised, timesSpoken, participationId)
}
} }
@@ -7,7 +7,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.StaggeredGridLayoutManager import androidx.recyclerview.widget.StaggeredGridLayoutManager
@@ -16,8 +15,8 @@ import com.denizd.qwark.adapter.CourseAdapter
import com.denizd.qwark.databinding.PaddedRecyclerViewBinding import com.denizd.qwark.databinding.PaddedRecyclerViewBinding
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.model.Participation import com.denizd.qwark.model.Participation
import com.denizd.qwark.sheet.ConfirmDeletionBottomSheet import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.ParticipationLinkBottomSheet import com.denizd.qwark.sheet.ParticipationLinkSheet
import com.denizd.qwark.viewmodel.ParticipationViewModel import com.denizd.qwark.viewmodel.ParticipationViewModel
internal class ParticipationFragment : QwarkFragment(), CourseAdapter.CourseClickListener { internal class ParticipationFragment : QwarkFragment(), CourseAdapter.CourseClickListener {
@@ -88,7 +87,7 @@ internal class ParticipationFragment : QwarkFragment(), CourseAdapter.CourseClic
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.recyclerView.applyPadding(verticalPadding = 4) binding.recyclerView.applyPadding(horizontalPadding = 4)
} }
override fun onDestroy() { override fun onDestroy() {
@@ -118,11 +117,11 @@ internal class ParticipationFragment : QwarkFragment(), CourseAdapter.CourseClic
} }
private fun openLinkSheet() { private fun openLinkSheet() {
openBottomSheet(ParticipationLinkBottomSheet()) openBottomSheet(ParticipationLinkSheet())
} }
private fun openRemoveLinkSheet(courseName: String, relationId: Int) { private fun openRemoveLinkSheet(courseName: String, relationId: Int) {
openBottomSheet(ConfirmDeletionBottomSheet( openBottomSheet(ConfirmDeletionSheet(
getString(R.string.confirm_remove_participation_link, courseName, getDay()) getString(R.string.confirm_remove_participation_link, courseName, getDay())
) { ) {
viewModel.removeLink(relationId) viewModel.removeLink(relationId)
@@ -50,8 +50,8 @@ open class QwarkFragment : Fragment() {
* Initialise view resources * Initialise view resources
*/ */
statusBarView = view.rootView.findViewById(R.id.status_bar_view) statusBarView = view.rootView.findViewById(R.id.status_bar_view)
appBarTitleView = view.rootView.findViewById(R.id.toolbarTxt) appBarTitleView = view.rootView.findViewById(R.id.app_bar_title)
superTitleView = view.rootView.findViewById(R.id.text_above) superTitleView = view.rootView.findViewById(R.id.super_title)
appBar = view.rootView.findViewById(R.id.app_bar_layout) appBar = view.rootView.findViewById(R.id.app_bar_layout)
snackBarContainer = view.rootView.findViewById(R.id.root_view) snackBarContainer = view.rootView.findViewById(R.id.root_view)
fab = view.rootView.findViewById(R.id.fab) fab = view.rootView.findViewById(R.id.fab)
@@ -93,11 +93,12 @@ open class QwarkFragment : Fragment() {
* to its lifecycle owner and therefore cannot calculate the top padding properly. Invoke in * to its lifecycle owner and therefore cannot calculate the top padding properly. Invoke in
* onResume instead. * onResume instead.
*/ */
protected fun <T : View> T.applyPadding(verticalPadding: Int = 0) { protected fun <T : View> T.applyPadding(horizontalPadding: Int = 0) {
val horizontal = horizontalPadding.dpToPx()
setPadding( setPadding(
verticalPadding.dpToPx(), horizontal,
(statusBarView.height / 1) + appBar.height, (statusBarView.height / 1) + appBar.height,
verticalPadding.dpToPx(), horizontal,
0 0
) )
} }
@@ -5,15 +5,14 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.sheet.ConfirmDeletionBottomSheet import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.CopyCoursesBottomSheet import com.denizd.qwark.sheet.CopyCoursesSheet
import com.denizd.qwark.sheet.ScoreProfileCreateBottomSheet import com.denizd.qwark.sheet.ScoreProfileCreateSheet
import com.denizd.qwark.sheet.YearCreateBottomSheet import com.denizd.qwark.sheet.YearCreateSheet
import com.denizd.qwark.databinding.SettingsFragmentBinding import com.denizd.qwark.databinding.SettingsFragmentBinding
import com.denizd.qwark.model.ScoreProfile
import com.denizd.qwark.model.SchoolYear import com.denizd.qwark.model.SchoolYear
import com.denizd.qwark.viewmodel.SettingsViewModel import com.denizd.qwark.viewmodel.SettingsViewModel
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@@ -22,12 +21,7 @@ class SettingsFragment : QwarkFragment() {
private var _binding: SettingsFragmentBinding? = null private var _binding: SettingsFragmentBinding? = null
private val binding: SettingsFragmentBinding get() = _binding!! private val binding: SettingsFragmentBinding get() = _binding!!
private lateinit var viewModel: SettingsViewModel private val viewModel: SettingsViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this)[SettingsViewModel::class.java]
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = SettingsFragmentBinding.inflate(inflater, container, false) _binding = SettingsFragmentBinding.inflate(inflater, container, false)
@@ -120,7 +114,7 @@ class SettingsFragment : QwarkFragment() {
if (binding.schoolYearDropdown.text.isNullOrBlank()) { if (binding.schoolYearDropdown.text.isNullOrBlank()) {
presentErrorSnackBar(getString(R.string.no_school_year_selected)) presentErrorSnackBar(getString(R.string.no_school_year_selected))
} else { } else {
val deleteYearSheet = ConfirmDeletionBottomSheet(getString(R.string.delete_school_year_desc, binding.schoolYearDropdown.text.toString())) { val deleteYearSheet = ConfirmDeletionSheet(getString(R.string.delete_school_year_desc, binding.schoolYearDropdown.text.toString())) {
viewModel.deleteSchoolYear() viewModel.deleteSchoolYear()
binding.schoolYearDropdown.setText("") binding.schoolYearDropdown.setText("")
} }
@@ -128,7 +122,7 @@ class SettingsFragment : QwarkFragment() {
} }
} }
binding.copyCoursesButton.setOnClickListener { binding.copyCoursesButton.setOnClickListener {
openBottomSheet(CopyCoursesBottomSheet()) openBottomSheet(CopyCoursesSheet())
} }
// binding.copyCoursesButton.setOnLongClickListener { // binding.copyCoursesButton.setOnLongClickListener {
// // TODO this is currently an experiment // // TODO this is currently an experiment
@@ -206,7 +200,7 @@ class SettingsFragment : QwarkFragment() {
if (binding.scoreProfileDropdown.text.isNullOrBlank()) { if (binding.scoreProfileDropdown.text.isNullOrBlank()) {
presentErrorSnackBar(getString(R.string.no_score_profile_selected)) presentErrorSnackBar(getString(R.string.no_score_profile_selected))
} else { } else {
val deleteScoreProfileSheet = ConfirmDeletionBottomSheet( val deleteScoreProfileSheet = ConfirmDeletionSheet(
getString(R.string.delete_score_profile_desc, getString(R.string.delete_score_profile_desc,
binding.scoreProfileDropdown.text.toString()) binding.scoreProfileDropdown.text.toString())
) { ) {
@@ -243,7 +237,7 @@ class SettingsFragment : QwarkFragment() {
if (edit && currentYear == "") { if (edit && currentYear == "") {
presentErrorSnackBar(getString(R.string.no_school_year_selected)) presentErrorSnackBar(getString(R.string.no_school_year_selected))
} else { } else {
val yearCreateSheet = YearCreateBottomSheet().also { sheet -> val yearCreateSheet = YearCreateSheet().also { sheet ->
sheet.arguments = Bundle(1).apply { sheet.arguments = Bundle(1).apply {
putString("currentYear", if (edit) currentYear else "") putString("currentYear", if (edit) currentYear else "")
} }
@@ -264,7 +258,7 @@ class SettingsFragment : QwarkFragment() {
if (edit && currentScoreProfile == "") { if (edit && currentScoreProfile == "") {
presentErrorSnackBar(getString(R.string.no_score_profile_selected)) presentErrorSnackBar(getString(R.string.no_score_profile_selected))
} else { } else {
openBottomSheet(ScoreProfileCreateBottomSheet().also { sheet -> openBottomSheet(ScoreProfileCreateSheet().also { sheet ->
sheet.arguments = Bundle(1).apply { sheet.arguments = Bundle(1).apply {
putString("currentScoreProfile", if (edit) currentScoreProfile else "") putString("currentScoreProfile", if (edit) currentScoreProfile else "")
} }
@@ -7,6 +7,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.databinding.ClassSessionSheetBinding import com.denizd.qwark.databinding.ClassSessionSheetBinding
@@ -32,6 +33,7 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
field = value field = value
binding.spokenButton.text = "$value" binding.spokenButton.text = "$value"
} }
private var participationId = -1
private val time: Long = System.currentTimeMillis() private val time: Long = System.currentTimeMillis()
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -46,12 +48,20 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
participationFragment = targetFragment as ParticipationCourseFragment participationFragment = targetFragment as ParticipationCourseFragment
arguments?.let { args ->
timesHandRaised = args.getInt ("timesHandRaised")
timesSpoken = args.getInt("timesSpoken")
participationId = args.getInt("participationId")
binding.title.text = getString(R.string.class_session_resumed)
}
binding.handRaisedButton.apply { binding.handRaisedButton.apply {
setCompoundDrawables(context.getDrawable(R.drawable.hand).also { drawable -> setCompoundDrawables(context.getDrawable(R.drawable.hand)?.also { drawable ->
drawable?.bounds = Rect(0, 0, 256, 256) drawable.bounds = Rect(0, 0, 256, 256)
drawable?.setTint(mContext.getColor(R.color.colorAccent)) drawable.setTint(mContext.getColor(R.color.colorAccent))
}, null, null, null) }, null, null, null)
text = "$timesHandRaised" text = "$timesHandRaised"
setOnClickListener { setOnClickListener {
@@ -66,9 +76,9 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
} }
} }
binding.spokenButton.apply { binding.spokenButton.apply {
setCompoundDrawables(context.getDrawable(R.drawable.speech).also { drawable -> setCompoundDrawables(context.getDrawable(R.drawable.speech)?.also { drawable ->
drawable?.bounds = Rect(0, 0, 256, 256) drawable.bounds = Rect(0, 0, 256, 256)
drawable?.setTint(mContext.getColor(R.color.colorAccent)) drawable.setTint(mContext.getColor(R.color.colorAccent))
}, null, null, null) }, null, null, null)
text = "$timesSpoken" text = "$timesSpoken"
setOnClickListener { setOnClickListener {
@@ -104,6 +114,16 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
} }
} }
override fun onResume() {
super.onResume()
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
override fun onPause() {
super.onPause()
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
_binding = null _binding = null
@@ -116,8 +136,10 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
} }
private fun finish() { private fun finish() {
participationFragment.createParticipation( if (participationId == -1) {
timesHandRaised, timesSpoken, time participationFragment.createParticipation(timesHandRaised, timesSpoken, time)
) } else {
participationFragment.updateParticipation(timesHandRaised, timesSpoken, participationId)
}
} }
} }
@@ -10,7 +10,7 @@ import com.denizd.qwark.databinding.ConfirmationDialogBinding
import com.denizd.qwark.viewmodel.ConfirmDeletionViewModel import com.denizd.qwark.viewmodel.ConfirmDeletionViewModel
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class ConfirmDeletionBottomSheet() : BottomSheetDialogFragment() { class ConfirmDeletionSheet() : BottomSheetDialogFragment() {
constructor(text: String, confirmedAction: () -> Unit) : this() { constructor(text: String, confirmedAction: () -> Unit) : this() {
this.text = text this.text = text
@@ -12,7 +12,7 @@ import com.denizd.qwark.fragment.SettingsFragment
import com.denizd.qwark.model.SchoolYear import com.denizd.qwark.model.SchoolYear
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class CopyCoursesBottomSheet : BottomSheetDialogFragment(), YearAdapter.YearClickListener { class CopyCoursesSheet : BottomSheetDialogFragment(), YearAdapter.YearClickListener {
private var _binding: RecyclerDialogBinding? = null private var _binding: RecyclerDialogBinding? = null
private val binding: RecyclerDialogBinding get() = _binding!! private val binding: RecyclerDialogBinding get() = _binding!!
@@ -41,7 +41,7 @@ internal class CopyCoursesBottomSheet : BottomSheetDialogFragment(), YearAdapter
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
adapter = YearAdapter((settingsTargetFragment.getSchoolYears() ?: ArrayList()).filter { y -> adapter = YearAdapter((settingsTargetFragment.getSchoolYears() ?: ArrayList()).filter { y ->
y.yearId != settingsTargetFragment.getCurrentSchoolYearId() y.yearId != settingsTargetFragment.getCurrentSchoolYearId()
}, this@CopyCoursesBottomSheet) }, this@CopyCoursesSheet)
scheduleLayoutAnimation() scheduleLayoutAnimation()
} }
} }
@@ -7,6 +7,7 @@ import android.text.TextWatcher
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.databinding.CourseCreateDialogBinding import com.denizd.qwark.databinding.CourseCreateDialogBinding
@@ -15,7 +16,7 @@ import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class CourseCreateBottomSheet : BottomSheetDialogFragment() { class CourseCreateSheet : BottomSheetDialogFragment() {
private var _binding: CourseCreateDialogBinding? = null private var _binding: CourseCreateDialogBinding? = null
private val binding: CourseCreateDialogBinding get() = _binding!! private val binding: CourseCreateDialogBinding get() = _binding!!
@@ -25,7 +26,7 @@ internal class CourseCreateBottomSheet : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (arguments?.size() ?: 0 != 0) course = QwarkUtil.getCourseFromBundle(arguments) if (arguments?.size() ?: 0 != 0) course = (targetFragment as CourseFragment).getCourse(arguments?.getInt("courseId") ?: -1) // QwarkUtil.getCourseFromBundle(arguments)
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -121,17 +122,17 @@ internal class CourseCreateBottomSheet : BottomSheetDialogFragment() {
_binding = null _binding = null
} }
private fun openIconBottomSheet() = fragmentManager?.let { fm -> private fun openIconBottomSheet() {
val sheet = IconPickerBottomSheet().apply { val sheet = IconPickerSheet().apply {
arguments = Bundle(1).apply { arguments = Bundle(1).apply {
putString("currentIcon", icon) putString("currentIcon", icon)
} }
} }
sheet.setTargetFragment(this, 42) sheet.setTargetFragment(this, 42)
sheet.show(fm, sheet.tag) sheet.show((context as FragmentActivity).supportFragmentManager, sheet.tag)
} }
internal fun setIcon(icon: String) { fun setIcon(icon: String) {
binding.imageView.setImageResource(QwarkUtil.getDrawableIntForString(icon)) binding.imageView.setImageResource(QwarkUtil.getDrawableIntForString(icon))
this.icon = icon this.icon = icon
} }
@@ -8,21 +8,20 @@ import android.view.ViewGroup
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.databinding.CourseOptionsDialogBinding import com.denizd.qwark.databinding.CourseOptionsDialogBinding
import com.denizd.qwark.fragment.CourseFragment import com.denizd.qwark.fragment.CourseFragment
import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.asCourse
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class CourseOptionsBottomSheet : BottomSheetDialogFragment() { class CourseOptionsSheet : BottomSheetDialogFragment() {
private var _binding: CourseOptionsDialogBinding? = null private var _binding: CourseOptionsDialogBinding? = null
private val binding: CourseOptionsDialogBinding get() = _binding!! private val binding: CourseOptionsDialogBinding get() = _binding!!
private lateinit var mContext: Context private lateinit var mContext: Context
private lateinit var course: CourseExam private lateinit var courseExam: CourseExam
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
course = QwarkUtil.getCourseFromBundle(arguments) courseExam = (targetFragment as CourseFragment).getCourse(arguments?.getInt("courseId") ?: -1)
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -40,18 +39,18 @@ internal class CourseOptionsBottomSheet : BottomSheetDialogFragment() {
val targetFragment = targetFragment as CourseFragment val targetFragment = targetFragment as CourseFragment
binding.title.text = getString(R.string.options_for_course, course.name) binding.title.text = getString(R.string.options_for_course, courseExam.name)
binding.viewHistoryButton.setOnClickListener { binding.viewHistoryButton.setOnClickListener {
targetFragment.createHistoryDialog(course.courseId, course.name) targetFragment.createHistoryDialog(courseExam.courseId, courseExam.name)
dismiss() dismiss()
} }
binding.editCourseButton.setOnClickListener { binding.editCourseButton.setOnClickListener {
targetFragment.createCourseDialog(course) targetFragment.createCourseDialog(courseExam)
dismiss() dismiss()
} }
binding.deleteCourseButton.setOnClickListener { binding.deleteCourseButton.setOnClickListener {
targetFragment.deleteCourse(QwarkUtil.getCourseExamAsCourse(course)) targetFragment.deleteCourse(courseExam.asCourse())
dismiss() dismiss()
} }
} }
@@ -5,24 +5,24 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ArrayAdapter
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.databinding.FinalGradeEditDialogBinding import com.denizd.qwark.databinding.FinalGradeEditDialogBinding
import com.denizd.qwark.fragment.FinalsFragment import com.denizd.qwark.fragment.FinalsFragment
import com.denizd.qwark.model.FinalGrade import com.denizd.qwark.model.FinalGrade
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class FinalsCreateBottomSheet : BottomSheetDialogFragment() { class FinalsCreateSheet : BottomSheetDialogFragment() {
private var _binding: FinalGradeEditDialogBinding? = null private var _binding: FinalGradeEditDialogBinding? = null
private val binding: FinalGradeEditDialogBinding get() = _binding!! private val binding: FinalGradeEditDialogBinding get() = _binding!!
private lateinit var mContext: Context private lateinit var mContext: Context
private lateinit var finalGrade: FinalGrade private lateinit var finalGrade: FinalGrade
private lateinit var finalsFragment: FinalsFragment
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
finalGrade = QwarkUtil.getFinalGradeFromBundle(arguments) finalsFragment = targetFragment as FinalsFragment
finalGrade = finalsFragment.getFinalGrade(arguments?.getInt("finalGradeId") ?: -1)
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -38,20 +38,7 @@ internal class FinalsCreateBottomSheet : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val targetFragment = targetFragment as FinalsFragment
binding.courseEdittext.setText(finalGrade.name) binding.courseEdittext.setText(finalGrade.name)
// val gradeArray = ArrayAdapter.createFromResource(mContext, R.array.grades_points, R.layout.dropdown_item)
// binding.gradePicker.setAdapter(gradeArray)
// binding.gradePicker.setText(
// if (finalGrade.grade == "-1") {
// binding.gradePicker.adapter.getItem(0).toString()
// } else {
// QwarkUtil.getGradeWithLeadingZero(finalGrade.grade.toInt())
// },
// false
// )
binding.gradePicker.value = if (finalGrade.grade == "-1") 0 else finalGrade.grade.toInt() binding.gradePicker.value = if (finalGrade.grade == "-1") 0 else finalGrade.grade.toInt()
binding.cancelButton.setOnClickListener { binding.cancelButton.setOnClickListener {
@@ -71,7 +58,7 @@ internal class FinalsCreateBottomSheet : BottomSheetDialogFragment() {
finalGradeId = finalGrade.finalGradeId, finalGradeId = finalGrade.finalGradeId,
scoreProfileId = finalGrade.scoreProfileId scoreProfileId = finalGrade.scoreProfileId
) )
targetFragment.update(newFinalGrade) finalsFragment.update(newFinalGrade)
dismiss() dismiss()
} }
} }
@@ -8,28 +8,28 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.adapter.CourseAdapter import com.denizd.qwark.adapter.CourseAdapter
import com.denizd.qwark.adapter.YearAdapter import com.denizd.qwark.adapter.YearAdapter
import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.databinding.RecyclerDialogBinding import com.denizd.qwark.databinding.RecyclerDialogBinding
import com.denizd.qwark.fragment.FinalsFragment import com.denizd.qwark.fragment.FinalsFragment
import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.model.FinalGrade import com.denizd.qwark.model.FinalGrade
import com.denizd.qwark.model.SchoolYear import com.denizd.qwark.model.SchoolYear
import com.denizd.qwark.util.getSorted
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import java.math.BigDecimal import java.math.BigDecimal
import java.math.RoundingMode import java.math.RoundingMode
internal class FinalsLinkBottomSheet : BottomSheetDialogFragment(), YearAdapter.YearClickListener, CourseAdapter.CourseClickListener { class FinalsLinkSheet : BottomSheetDialogFragment(), YearAdapter.YearClickListener, CourseAdapter.CourseClickListener {
private lateinit var finalGrade: FinalGrade private lateinit var finalGrade: FinalGrade
private lateinit var binding: RecyclerDialogBinding private lateinit var binding: RecyclerDialogBinding
private var advanced = false private var advanced = false
private var isSelectingCourse = false private var isSelectingCourse = false
private lateinit var finalsTargetFragment: FinalsFragment private lateinit var finalsFragment: FinalsFragment
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
finalGrade = QwarkUtil.getFinalGradeFromBundle(arguments) finalsFragment = targetFragment as FinalsFragment
finalGrade = finalsFragment.getFinalGrade(arguments?.getInt("finalGradeId") ?: -1)
advanced = finalGrade.type == "adv" advanced = finalGrade.type == "adv"
} }
@@ -41,7 +41,7 @@ internal class FinalsLinkBottomSheet : BottomSheetDialogFragment(), YearAdapter.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
finalsTargetFragment = targetFragment as FinalsFragment finalsFragment = targetFragment as FinalsFragment
fillWithYears() fillWithYears()
} }
@@ -59,7 +59,7 @@ internal class FinalsLinkBottomSheet : BottomSheetDialogFragment(), YearAdapter.
finalGradeId = finalGrade.finalGradeId, finalGradeId = finalGrade.finalGradeId,
scoreProfileId = finalGrade.scoreProfileId scoreProfileId = finalGrade.scoreProfileId
) )
finalsTargetFragment.update(newFinalGrade) finalsFragment.update(newFinalGrade)
dismiss() dismiss()
} }
@@ -69,7 +69,7 @@ internal class FinalsLinkBottomSheet : BottomSheetDialogFragment(), YearAdapter.
binding.title.text = getString(R.string.pick_a_year) binding.title.text = getString(R.string.pick_a_year)
binding.recyclerView.apply { binding.recyclerView.apply {
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
adapter = YearAdapter(finalsTargetFragment.getAllYears(), this@FinalsLinkBottomSheet) adapter = YearAdapter(finalsFragment.getAllYears(), this@FinalsLinkSheet)
scheduleLayoutAnimation() scheduleLayoutAnimation()
} }
isSelectingCourse = false isSelectingCourse = false
@@ -77,14 +77,14 @@ internal class FinalsLinkBottomSheet : BottomSheetDialogFragment(), YearAdapter.
private fun fillWithCourses(schoolYear: SchoolYear) { private fun fillWithCourses(schoolYear: SchoolYear) {
binding.title.text = getString(R.string.pick_a_course) binding.title.text = getString(R.string.pick_a_course)
binding.recyclerView.adapter = binding.recyclerView.adapter = CourseAdapter(
CourseAdapter( finalsFragment.getAllCourses().filter { c ->
QwarkUtil.getCoursesSorted( c.yearId == schoolYear.yearId && c.advanced == advanced
finalsTargetFragment.getAllCourses().filter { c -> c.yearId == schoolYear.yearId && c.advanced == advanced }, }.getSorted(
finalsTargetFragment.getCourseSortType() finalsFragment.getCourseSortType()
), ),
this, this,
finalsTargetFragment.getGradeType() finalsFragment.getGradeType()
) )
binding.recyclerView.scheduleLayoutAnimation() binding.recyclerView.scheduleLayoutAnimation()
isSelectingCourse = true isSelectingCourse = true
@@ -12,16 +12,18 @@ import com.denizd.qwark.model.FinalGrade
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.QwarkUtil
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class FinalsOptionsBottomSheet : BottomSheetDialogFragment() { class FinalsOptionsSheet : BottomSheetDialogFragment() {
private var _binding: FinalGradeOptionsDialogBinding? = null private var _binding: FinalGradeOptionsDialogBinding? = null
private val binding: FinalGradeOptionsDialogBinding get() = _binding!! private val binding: FinalGradeOptionsDialogBinding get() = _binding!!
private lateinit var mContext: Context private lateinit var mContext: Context
private lateinit var finalGrade: FinalGrade private lateinit var finalGrade: FinalGrade
private lateinit var finalsFragment: FinalsFragment
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
finalGrade = QwarkUtil.getFinalGradeFromBundle(arguments) finalsFragment = targetFragment as FinalsFragment
finalGrade = finalsFragment.getFinalGrade(arguments?.getInt("finalGradeId") ?: -1)
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -37,29 +39,27 @@ internal class FinalsOptionsBottomSheet : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val targetFragment = targetFragment as FinalsFragment
binding.title.text = getString(R.string.options_for_final_grade, if (finalGrade.name.isEmpty()) getString(R.string.final_grade) else finalGrade.name) binding.title.text = getString(R.string.options_for_final_grade, if (finalGrade.name.isEmpty()) getString(R.string.final_grade) else finalGrade.name)
if (finalGrade.type == "exam") binding.linkGradeButton.visibility = View.GONE if (finalGrade.type == "exam") binding.linkGradeButton.visibility = View.GONE
if (finalGrade.courseId == -1) binding.viewLinkedCourseButton.visibility = View.GONE if (finalGrade.courseId == -1) binding.viewLinkedCourseButton.visibility = View.GONE
binding.editGradeButton.setOnClickListener { binding.editGradeButton.setOnClickListener {
targetFragment.createEditGradeSheet(finalGrade) finalsFragment.createEditGradeSheet(finalGrade)
dismiss() dismiss()
} }
binding.linkGradeButton.setOnClickListener { binding.linkGradeButton.setOnClickListener {
targetFragment.createLinkGradeSheet(finalGrade) finalsFragment.createLinkGradeSheet(finalGrade)
dismiss() dismiss()
} }
binding.viewLinkedCourseButton.setOnClickListener { binding.viewLinkedCourseButton.setOnClickListener {
targetFragment.viewLinkedCourse(finalGrade.courseId) finalsFragment.viewLinkedCourse(finalGrade.courseId)
dismiss() dismiss()
} }
binding.clearGradeButton.setOnClickListener { binding.clearGradeButton.setOnClickListener {
if (finalGrade.grade == "-1") { if (finalGrade.grade == "-1") {
targetFragment.clearFinalGradeError() finalsFragment.clearFinalGradeError()
} else { } else {
targetFragment.clearFinalGrade(finalGrade) finalsFragment.clearFinalGrade(finalGrade)
} }
dismiss() dismiss()
} }
@@ -5,10 +5,10 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.databinding.GradeCreateDialogBinding import com.denizd.qwark.databinding.GradeCreateDialogBinding
@@ -18,18 +18,24 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import java.text.ParseException import java.text.ParseException
import java.util.* import java.util.*
class GradeCreateBottomSheet : BottomSheetDialogFragment() { class GradeCreateSheet : BottomSheetDialogFragment() {
private var _binding: GradeCreateDialogBinding? = null private var _binding: GradeCreateDialogBinding? = null
private val binding: GradeCreateDialogBinding get() = _binding!! private val binding: GradeCreateDialogBinding get() = _binding!!
private lateinit var mContext: Context private lateinit var mContext: Context
private lateinit var grade: Grade private lateinit var grade: Grade
private var courseId: Int = 0 private var courseId: Int = 0
private lateinit var gradeFragment: GradeFragment
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (arguments?.size() ?: 0 > 1) grade = QwarkUtil.getGradeFromBundle(arguments) gradeFragment = targetFragment as GradeFragment
courseId = arguments?.getInt("courseId") ?: 0 val gradeId = arguments?.getInt("gradeId") ?: -1
if (gradeId == 0) { // 0 signifies no value has been set
courseId = arguments?.getInt("courseId") ?: -1
} else {
grade = gradeFragment.getGrade(gradeId)
}
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -47,11 +53,9 @@ class GradeCreateBottomSheet : BottomSheetDialogFragment() {
LayoutTransition().apply { LayoutTransition().apply {
setAnimateParentHierarchy(false) setAnimateParentHierarchy(false)
(binding.root as LinearLayout).layoutTransition = this binding.root.layoutTransition = this
} }
val targetFragment = targetFragment as GradeFragment
// initGradeDropdown() // initGradeDropdown()
binding.verbalSwitch.setOnCheckedChangeListener { switch, isChecked -> binding.verbalSwitch.setOnCheckedChangeListener { switch, isChecked ->
@@ -79,7 +83,7 @@ class GradeCreateBottomSheet : BottomSheetDialogFragment() {
} }
} }
binding.gradePicker.displayedValues = QwarkUtil.getGradeArray(targetFragment.getGradeType()) binding.gradePicker.displayedValues = QwarkUtil.getGradeArray(gradeFragment.getGradeType())
binding.examSwitch.setOnCheckedChangeListener { _, isChecked -> binding.examSwitch.setOnCheckedChangeListener { _, isChecked ->
setGradePickerVisibility(isChecked) setGradePickerVisibility(isChecked)
@@ -119,9 +123,9 @@ class GradeCreateBottomSheet : BottomSheetDialogFragment() {
examTime = if (binding.examSwitch.isChecked) examDate else -1L examTime = if (binding.examSwitch.isChecked) examDate else -1L
) )
if (::grade.isInitialized) { if (::grade.isInitialized) {
targetFragment.update(newGrade) gradeFragment.update(newGrade)
} else { } else {
targetFragment.insert(newGrade) gradeFragment.insert(newGrade)
} }
dismiss() dismiss()
} catch (e: ParseException) { } catch (e: ParseException) {
@@ -12,7 +12,7 @@ import com.denizd.qwark.databinding.RecyclerDialogBinding
import com.denizd.qwark.fragment.CourseFragment import com.denizd.qwark.fragment.CourseFragment
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class HistoricalAverageBottomSheet : BottomSheetDialogFragment() { class HistoricalAverageSheet : BottomSheetDialogFragment() {
private var _binding: RecyclerDialogBinding? = null private var _binding: RecyclerDialogBinding? = null
private val binding: RecyclerDialogBinding get() = _binding!! private val binding: RecyclerDialogBinding get() = _binding!!
@@ -12,7 +12,7 @@ import com.denizd.qwark.databinding.IconDialogBinding
import com.denizd.qwark.model.CourseIcon import com.denizd.qwark.model.CourseIcon
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class IconPickerBottomSheet : BottomSheetDialogFragment(), class IconPickerSheet : BottomSheetDialogFragment(),
IconAdapter.IconClickListener { IconAdapter.IconClickListener {
private var _binding: IconDialogBinding? = null private var _binding: IconDialogBinding? = null
@@ -39,7 +39,7 @@ class IconPickerBottomSheet : BottomSheetDialogFragment(),
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val targetFragment = targetFragment as CourseCreateBottomSheet val targetFragment = targetFragment as CourseCreateSheet
val icons = QwarkUtil.drawablesList val icons = QwarkUtil.drawablesList
iconAdapter = IconAdapter(icons, this) iconAdapter = IconAdapter(icons, this)
@@ -13,7 +13,7 @@ import com.denizd.qwark.model.Note
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.QwarkUtil
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class NoteCreateBottomSheet : BottomSheetDialogFragment() { class NoteCreateSheet : BottomSheetDialogFragment() {
private var _binding: NoteCreateDialogBinding? = null private var _binding: NoteCreateDialogBinding? = null
private val binding: NoteCreateDialogBinding get() = _binding!! private val binding: NoteCreateDialogBinding get() = _binding!!
@@ -22,7 +22,7 @@ internal class NoteCreateBottomSheet : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (arguments?.size() ?: 0 != 0) note = QwarkUtil.getNoteFromBundle(arguments) if (arguments?.size() ?: 0 != 0) note = (targetFragment as NoteFragment).getNote(arguments?.getInt("noteId") ?: -1)
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -8,10 +8,11 @@ import android.view.ViewGroup
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.databinding.NoteBottomSheetBinding import com.denizd.qwark.databinding.NoteBottomSheetBinding
import com.denizd.qwark.fragment.NoteFragment
import com.denizd.qwark.model.Note import com.denizd.qwark.model.Note
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class NoteDisplayBottomSheet : BottomSheetDialogFragment() { class NoteDisplaySheet : BottomSheetDialogFragment() {
private var _binding: NoteBottomSheetBinding? = null private var _binding: NoteBottomSheetBinding? = null
private val binding: NoteBottomSheetBinding get() = _binding!! private val binding: NoteBottomSheetBinding get() = _binding!!
@@ -20,7 +21,7 @@ internal class NoteDisplayBottomSheet : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
note = QwarkUtil.getNoteFromBundle(arguments) note = (targetFragment as NoteFragment).getNote(arguments?.getInt("noteId") ?: -1)
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -33,18 +34,6 @@ internal class NoteDisplayBottomSheet : BottomSheetDialogFragment() {
return binding.root return binding.root
} }
// override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// return super.onCreateDialog(savedInstanceState).also { dialog ->
// dialog.setOnShowListener {
// BottomSheetBehavior.from(dialog.findViewById<FrameLayout>(
// com.google.android.material.R.id.design_bottom_sheet
// )).apply {
// state = BottomSheetBehavior.STATE_EXPANDED
// }
// }
// }
// }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@@ -12,7 +12,7 @@ import com.denizd.qwark.model.Note
import com.denizd.qwark.util.QwarkUtil import com.denizd.qwark.util.QwarkUtil
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class NoteOptionsBottomSheet : BottomSheetDialogFragment() { class NoteOptionsSheet : BottomSheetDialogFragment() {
private var _binding: NoteOptionsDialogBinding? = null private var _binding: NoteOptionsDialogBinding? = null
private val binding: NoteOptionsDialogBinding get() = _binding!! private val binding: NoteOptionsDialogBinding get() = _binding!!
@@ -21,7 +21,7 @@ internal class NoteOptionsBottomSheet : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
note = QwarkUtil.getNoteFromBundle(arguments) note = (targetFragment as NoteFragment).getNote(arguments?.getInt("noteId") ?: -1)
} }
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
@@ -12,7 +12,7 @@ import com.denizd.qwark.fragment.ParticipationFragment
import com.denizd.qwark.model.* import com.denizd.qwark.model.*
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal class ParticipationLinkBottomSheet : BottomSheetDialogFragment(), CourseAdapter.CourseClickListener { class ParticipationLinkSheet : BottomSheetDialogFragment(), CourseAdapter.CourseClickListener {
private lateinit var finalGrade: FinalGrade private lateinit var finalGrade: FinalGrade
private lateinit var binding: RecyclerDialogBinding private lateinit var binding: RecyclerDialogBinding
@@ -58,7 +58,7 @@ internal class ParticipationLinkBottomSheet : BottomSheetDialogFragment(), Cours
0 0
) )
}, },
this@ParticipationLinkBottomSheet, this@ParticipationLinkSheet,
null null
) )
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
@@ -5,7 +5,7 @@ import android.view.View
import com.denizd.qwark.R import com.denizd.qwark.R
import com.denizd.qwark.fragment.SettingsFragment import com.denizd.qwark.fragment.SettingsFragment
internal class ScoreProfileCreateBottomSheet : TextInputBottomSheet() { class ScoreProfileCreateSheet : TextInputSheet() {
private lateinit var settingsFragment: SettingsFragment private lateinit var settingsFragment: SettingsFragment
private var currentScoreProfile: String = "" private var currentScoreProfile: String = ""
@@ -8,7 +8,7 @@ import android.view.ViewGroup
import com.denizd.qwark.databinding.TextInputSheetBinding import com.denizd.qwark.databinding.TextInputSheetBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
internal open class TextInputBottomSheet : BottomSheetDialogFragment() { open class TextInputSheet : BottomSheetDialogFragment() {
protected var _binding: TextInputSheetBinding? = null protected var _binding: TextInputSheetBinding? = null
protected val binding: TextInputSheetBinding get() = _binding!! protected val binding: TextInputSheetBinding get() = _binding!!
@@ -6,7 +6,7 @@ import com.denizd.qwark.R
import com.denizd.qwark.fragment.SettingsFragment import com.denizd.qwark.fragment.SettingsFragment
import com.denizd.qwark.model.SchoolYear import com.denizd.qwark.model.SchoolYear
internal class YearCreateBottomSheet : TextInputBottomSheet() { class YearCreateSheet : TextInputSheet() {
private lateinit var settingsFragment: SettingsFragment private lateinit var settingsFragment: SettingsFragment
private var currentYear: String = "" private var currentYear: String = ""
@@ -0,0 +1,28 @@
package com.denizd.qwark.util
import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam
fun List<CourseExam>.getSorted(sortType: Int): List<CourseExam> = when (sortType) { // TODO check what ascending and descending really mean lol
QwarkUtil.SORT_COURSES_TIME_ASC -> this.asReversed()
QwarkUtil.SORT_COURSES_NAME_ASC -> this.sortedBy { c -> c.name }
QwarkUtil.SORT_COURSES_NAME_DESC -> this.sortedByDescending { c -> c.name }
QwarkUtil.SORT_COURSES_ADV -> this.sortedByDescending { c -> c.advanced }
QwarkUtil.SORT_COURSES_BASIC -> this.sortedBy { c -> c.advanced }
QwarkUtil.SORT_COURSES_AVG_ASC -> this.sortedBy { c -> c.average.toDouble() }
QwarkUtil.SORT_COURSES_AVG_DESC -> this.sortedByDescending { c -> c.average.toDouble() }
QwarkUtil.SORT_COURSES_NEXT_EXAM -> this.sortedBy { c -> if (c.examTime > 1L) c.examTime else Long.MAX_VALUE }
else -> this // TIME_DESC
}
fun CourseExam.asCourse(): Course = Course(
name = name,
advanced = advanced,
icon = icon,
colour = colour,
average = average,
oralWeighting = oralWeighting,
gradeCount = gradeCount,
time = time,
courseId = courseId,
yearId = yearId
)
@@ -1,5 +1,5 @@
package com.denizd.qwark.util package com.denizd.qwark.util
internal interface OnBackPressed { interface OnBackPressed {
fun onBackPressed(): Boolean fun onBackPressed(): Boolean
} }
@@ -4,14 +4,14 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
internal class QwarkPreferences private constructor(context: Context) { class QwarkPreferences private constructor(context: Context) {
private val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) private val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private val edit: SharedPreferences.Editor = prefs.edit() private val edit: SharedPreferences.Editor = prefs.edit()
companion object { companion object {
private var qwarkPrefs: QwarkPreferences? = null private var qwarkPrefs: QwarkPreferences? = null
internal fun getPrefs(context: Context): QwarkPreferences { fun getPrefs(context: Context): QwarkPreferences {
if (qwarkPrefs == null) { if (qwarkPrefs == null) {
synchronized (QwarkPreferences::class) { synchronized (QwarkPreferences::class) {
qwarkPrefs = QwarkPreferences(context) qwarkPrefs = QwarkPreferences(context)
@@ -21,31 +21,31 @@ internal class QwarkPreferences private constructor(context: Context) {
} }
} }
internal fun getString(key: PreferenceKey, default: String = ""): String = prefs.getString(key.value, default) ?: default fun getString(key: PreferenceKey, default: String = ""): String = prefs.getString(key.value, default) ?: default
internal fun getInt(key: PreferenceKey, default: Int = 0): Int = prefs.getInt(key.value, default) fun getInt(key: PreferenceKey, default: Int = 0): Int = prefs.getInt(key.value, default)
internal fun getBool(key: PreferenceKey, default: Boolean = false): Boolean = prefs.getBoolean(key.value, default) fun getBool(key: PreferenceKey, default: Boolean = false): Boolean = prefs.getBoolean(key.value, default)
internal fun putString(key: PreferenceKey, value: String): QwarkPreferences { fun putString(key: PreferenceKey, value: String): QwarkPreferences {
edit.putString(key.value, value).apply() edit.putString(key.value, value).apply()
return this return this
} }
internal fun putInt(key: PreferenceKey, value: Int): QwarkPreferences { fun putInt(key: PreferenceKey, value: Int): QwarkPreferences {
edit.putInt(key.value, value).apply() edit.putInt(key.value, value).apply()
return this return this
} }
internal fun putBool(key: PreferenceKey, value: Boolean): QwarkPreferences { fun putBool(key: PreferenceKey, value: Boolean): QwarkPreferences {
edit.putBoolean(key.value, value).apply() edit.putBoolean(key.value, value).apply()
return this return this
} }
internal fun getShowGradeAverage(): Boolean = getBool(PreferenceKey.SHOW_GRADE_AVERAGE) fun getShowGradeAverage(): Boolean = getBool(PreferenceKey.SHOW_GRADE_AVERAGE)
internal fun getGradeType(): Int = getInt(PreferenceKey.GRADE_TYPE) fun getGradeType(): Int = getInt(PreferenceKey.GRADE_TYPE)
internal fun getCourseSortType(): Int = getInt(PreferenceKey.COURSE_SORT_TYPE, 1) fun getCourseSortType(): Int = getInt(PreferenceKey.COURSE_SORT_TYPE, 1)
internal fun setCourseSortType(value: Int) { putInt(PreferenceKey.COURSE_SORT_TYPE, value) } fun setCourseSortType(value: Int) { putInt(PreferenceKey.COURSE_SORT_TYPE, value) }
internal fun getSchoolYear(): Int = getInt(PreferenceKey.SCHOOL_YEAR_ID) fun getSchoolYear(): Int = getInt(PreferenceKey.SCHOOL_YEAR_ID)
internal fun getSchoolYearName(): String = getString(PreferenceKey.SCHOOL_YEAR_NAME) fun getSchoolYearName(): String = getString(PreferenceKey.SCHOOL_YEAR_NAME)
internal fun getScoreProfileName(): String = getString(PreferenceKey.SCORE_PROFILE_NAME) fun getScoreProfileName(): String = getString(PreferenceKey.SCORE_PROFILE_NAME)
internal fun getScoreProfileId(): Int = getInt(PreferenceKey.SCORE_PROFILE_ID) fun getScoreProfileId(): Int = getInt(PreferenceKey.SCORE_PROFILE_ID)
fun getParticipationDisplay(): Int = getInt(PreferenceKey.PARTICIPATION_DISPLAY) fun getParticipationDisplay(): Int = getInt(PreferenceKey.PARTICIPATION_DISPLAY)
fun getParticipationDay(): Int = getInt(PreferenceKey.PARTICIPATION_DAY) fun getParticipationDay(): Int = getInt(PreferenceKey.PARTICIPATION_DAY)
@@ -148,16 +148,12 @@ object QwarkUtil {
else -> pointGradeArray else -> pointGradeArray
} }
private fun Double.getGradeType(map: Map<Int, String>): String = map[this.roundToInt()] ?: ""
fun getNewGradeType(grade: Int, type: Int): String = when (type) { fun getNewGradeType(grade: Int, type: Int): String = when (type) {
GRADE_NUMBERED -> numberedGrades[grade] ?: "error" GRADE_NUMBERED -> numberedGrades[grade] ?: "error"
GRADE_LETTERED -> letteredGrades[grade] ?: "error" GRADE_LETTERED -> letteredGrades[grade] ?: "error"
else -> "error" else -> "error"
} }
fun getNumberForLetter(grade: String): Int = lettersToPoints[grade] ?: -1
val timeAtMidnight: Long = GregorianCalendar().apply { val timeAtMidnight: Long = GregorianCalendar().apply {
set(Calendar.HOUR_OF_DAY, 0) set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0) set(Calendar.MINUTE, 0)
@@ -170,27 +166,15 @@ object QwarkUtil {
const val GRADE_NUMBERED = 2 const val GRADE_NUMBERED = 2
const val GRADE_LETTERED = 3 const val GRADE_LETTERED = 3
private const val SORT_COURSES_TIME_ASC = 0 const val SORT_COURSES_TIME_ASC = 0
private const val SORT_COURSES_TIME_DESC = 1 const val SORT_COURSES_TIME_DESC = 1
private const val SORT_COURSES_NAME_ASC = 2 const val SORT_COURSES_NAME_ASC = 2
private const val SORT_COURSES_NAME_DESC = 3 const val SORT_COURSES_NAME_DESC = 3
private const val SORT_COURSES_ADV = 4 const val SORT_COURSES_ADV = 4
private const val SORT_COURSES_BASIC = 5 const val SORT_COURSES_BASIC = 5
private const val SORT_COURSES_AVG_ASC = 6 const val SORT_COURSES_AVG_ASC = 6
private const val SORT_COURSES_AVG_DESC = 7 const val SORT_COURSES_AVG_DESC = 7
private const val SORT_COURSES_NEXT_EXAM = 8 const val SORT_COURSES_NEXT_EXAM = 8
fun getCoursesSorted(courses: List<CourseExam>, sortType: Int): List<CourseExam> = when (sortType) { // TODO check what ascending and descending really mean lol
SORT_COURSES_TIME_ASC -> courses.asReversed()
SORT_COURSES_TIME_DESC -> courses
SORT_COURSES_NAME_ASC -> courses.sortedBy { c -> c.name }
SORT_COURSES_NAME_DESC -> courses.sortedByDescending { c -> c.name }
SORT_COURSES_ADV -> courses.sortedByDescending { c -> c.advanced }
SORT_COURSES_BASIC -> courses.sortedBy { c -> c.advanced }
SORT_COURSES_AVG_ASC -> courses.sortedBy { c -> c.average.toDouble() }
SORT_COURSES_AVG_DESC -> courses.sortedByDescending { c -> c.average.toDouble() }
else -> courses.sortedBy { c -> if (c.examTime > 1L) c.examTime else Long.MAX_VALUE } // NEXT_EXAM
}
fun getGradeAsString(grade: Int, leadingZero: Boolean): String = (if (leadingZero && grade < 10) "0" else "") + grade fun getGradeAsString(grade: Int, leadingZero: Boolean): String = (if (leadingZero && grade < 10) "0" else "") + grade
fun getGradeWithLeadingZero(grade: Int) = "${if (grade < 10) "0" else ""}$grade" fun getGradeWithLeadingZero(grade: Int) = "${if (grade < 10) "0" else ""}$grade"
@@ -227,115 +211,4 @@ object QwarkUtil {
} }
dialog.show() dialog.show()
} }
fun putCourseInBundle(fragment: Fragment, course: CourseExam) {
val bundle = Bundle(11).apply {
putString("name", course.name)
putBoolean("advanced", course.advanced)
putString("icon", course.icon)
putString("colour", course.colour)
putString("average", course.average)
putInt("oralWeighting", course.oralWeighting)
putInt("gradeCount", course.gradeCount)
putLong("time", course.time)
putInt("courseId", course.courseId)
putInt("yearId", course.yearId)
putLong("examTime", course.examTime)
}
fragment.arguments = bundle
}
fun getCourseFromBundle(bundle: Bundle?) = CourseExam(
name = bundle?.getString("name") ?: "",
advanced = bundle?.getBoolean("advanced") ?: false,
icon = bundle?.getString("icon") ?: "",
colour = bundle?.getString("colour") ?: "",
average = bundle?.getString("average") ?: "",
oralWeighting = bundle?.getInt("oralWeighting") ?: 0,
gradeCount = bundle?.getInt("gradeCount") ?: 0,
time = bundle?.getLong("time") ?: 0L,
courseId = bundle?.getInt("courseId") ?: 0,
yearId = bundle?.getInt("yearId") ?: 0,
examTime = bundle?.getLong("examTime") ?: 0L
)
fun putFinalGradeInBundle(fragment: Fragment, finalGrade: FinalGrade) {
val bundle = Bundle(7).apply {
putString("name", finalGrade.name)
putInt("courseId", finalGrade.courseId)
putString("grade", finalGrade.grade)
putString("type", finalGrade.type)
putString("note", finalGrade.note)
putInt("finalGradeId", finalGrade.finalGradeId)
putInt("scoreProfileId", finalGrade.scoreProfileId)
}
fragment.arguments = bundle
}
fun getFinalGradeFromBundle(bundle: Bundle?) = FinalGrade(
name = bundle?.getString("name") ?: "",
courseId = bundle?.getInt("courseId") ?: 0,
grade = bundle?.getString("grade") ?: "",
type = bundle?.getString("type") ?: "",
note = bundle?.getString("note") ?: "",
finalGradeId = bundle?.getInt("finalGradeId") ?: 0,
scoreProfileId = bundle?.getInt("scoreProfileId") ?: 0
)
fun putGradeInBundle(fragment: Fragment, grade: Grade) {
val bundle = Bundle(8).apply {
putInt("grade", grade.grade)
putString("note", grade.note)
putBoolean("verbal", grade.verbal)
putLong("time", grade.time)
putInt("weighting", grade.weighting)
putLong("examTime", grade.examTime)
putInt("gradeId", grade.gradeId)
putInt("courseId", grade.courseId)
}
fragment.arguments = bundle
}
fun getGradeFromBundle(bundle: Bundle?) = Grade(
grade = bundle?.getInt("grade") ?: 0,
note = bundle?.getString("note") ?: "",
verbal = bundle?.getBoolean("verbal") ?: false,
time = bundle?.getLong("time") ?: 0L,
weighting = bundle?.getInt("weighting") ?: 0,
examTime = bundle?.getLong("examTime") ?: 0L,
gradeId = bundle?.getInt("gradeId") ?: 0,
courseId = bundle?.getInt("courseId") ?: 0
)
fun putNoteInBundle(fragment: Fragment, note: Note) {
val bundle = Bundle(5).apply {
putString("content", note.content)
putBoolean("dismissed", note.dismissed)
putLong("time", note.time)
putString("category", note.category)
putInt("noteId", note.noteId)
}
fragment.arguments = bundle
}
fun getNoteFromBundle(bundle: Bundle?) = Note(
content = bundle?.getString("content") ?: "",
dismissed = bundle?.getBoolean("dismissed") ?: false,
time = bundle?.getLong("time") ?: 0L,
category = bundle?.getString("category") ?: "",
noteId = bundle?.getInt("noteId") ?: 0
)
fun getCourseExamAsCourse(c: CourseExam): Course = Course(
name = c.name,
advanced = c.advanced,
icon = c.icon,
colour = c.colour,
average = c.average,
oralWeighting = c.oralWeighting,
gradeCount = c.gradeCount,
time = c.time,
courseId = c.courseId,
yearId = c.yearId
)
} }
@@ -29,4 +29,5 @@ class CourseViewModel(application: Application) : QwarkViewModel(application) {
fun insert(course: Course) = doAsync { repo.insert(course) } fun insert(course: Course) = doAsync { repo.insert(course) }
fun update(course: Course) = doAsync { repo.update(course) } fun update(course: Course) = doAsync { repo.update(course) }
fun delete(course: Course) = doAsync { repo.delete(course) } fun delete(course: Course) = doAsync { repo.delete(course) }
fun getCourse(courseId: Int): CourseExam = returnBlocking { repo.getCourse(courseId) }
} }
@@ -14,7 +14,7 @@ import java.lang.NumberFormatException
class FinalsViewModel(app: Application) : QwarkViewModel(app) { class FinalsViewModel(app: Application) : QwarkViewModel(app) {
private val repo = FinalsRepository(app) private val repo = FinalsRepository(app)
val allFinalGrades: LiveData<List<FinalGrade>>? = repo.getFinalGrades(repo.getFinalScoreId()) val allFinalGrades: LiveData<List<FinalGrade>> = repo.getFinalGrades(repo.getFinalScoreId())
fun update(finalGrade: FinalGrade) = viewModelScope.launch { fun update(finalGrade: FinalGrade) = viewModelScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
@@ -53,7 +53,7 @@ class FinalsViewModel(app: Application) : QwarkViewModel(app) {
private fun checkGrade(finalGrade: FinalGrade): Int = if (finalGrade.grade.toInt() > -1) finalGrade.grade.toInt() else throw NumberFormatException() private fun checkGrade(finalGrade: FinalGrade): Int = if (finalGrade.grade.toInt() > -1) finalGrade.grade.toInt() else throw NumberFormatException()
fun getFinalGrade(points: Int): Double = when (points) { fun getFinalGradeScore(points: Int): Double = when (points) {
in 823..900 -> 1.0 in 823..900 -> 1.0
in 805..822 -> 1.1 in 805..822 -> 1.1
in 787..804 -> 1.2 in 787..804 -> 1.2
@@ -107,11 +107,7 @@ class FinalsViewModel(app: Application) : QwarkViewModel(app) {
} }
} }
fun getCourse(courseId: Int) = runBlocking { fun getCourse(courseId: Int) = returnBlocking { repo.getCourse(courseId) }
withContext(Dispatchers.IO) { fun getFinalGrade(finalGradeId: Int) = returnBlocking { repo.getFinalGrade(finalGradeId) }
repo.getCourse(courseId)
}
}
fun getCourseSortType() = repo.getCourseSortType() fun getCourseSortType() = repo.getCourseSortType()
} }
@@ -25,4 +25,5 @@ class GradeViewModel(application: Application) : QwarkViewModel(application) {
fun delete(gradeId: Int) = doAsync { repo.delete(gradeId) } fun delete(gradeId: Int) = doAsync { repo.delete(gradeId) }
fun insert(avg: HistoricalAvg) = doAsync { repo.insert(avg) } fun insert(avg: HistoricalAvg) = doAsync { repo.insert(avg) }
fun getGrade(gradeId: Int) = returnBlocking { repo.getGrade(gradeId) }
} }
@@ -9,7 +9,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class NoteViewModel(application: Application) : AndroidViewModel(application) { class NoteViewModel(application: Application) : QwarkViewModel(application) {
private val repo = NoteRepository(application) private val repo = NoteRepository(application)
private val reloadTrigger = MutableLiveData<String>() private val reloadTrigger = MutableLiveData<String>()
@@ -75,4 +75,6 @@ class NoteViewModel(application: Application) : AndroidViewModel(application) {
repo.getAllCategories() repo.getAllCategories()
} }
} }
fun getNote(noteId: Int) = returnBlocking { repo.getNote(noteId) }
} }
@@ -13,7 +13,12 @@ class ParticipationCourseViewModel(app: Application) : QwarkViewModel(app) {
repo.getAllParticipationsForCourse(courseId) repo.getAllParticipationsForCourse(courseId)
} }
fun getParticipationCount(participations: List<Participation>) = repo.getParticipationCount(participations) fun getParticipationCount(participations: List<Participation>) = repo.getParticipationCount(participations)
fun updateParticipation(participation: String, courseId: Int) = doAsync { repo.updateParticipation(participation, courseId) } fun updateParticipation(participation: String, courseId: Int) = doAsync {
repo.updateParticipation(participation, courseId)
}
fun updateParticipation(timesHandRaised: Int, timesSpoken: Int, participationId: Int) = doAsync {
repo.updateParticipation(timesHandRaised, timesSpoken, participationId)
}
fun createParticipation(timesHandRaised: Int, timesSpoken: Int, time: Long, courseId: Int) = doAsync { fun createParticipation(timesHandRaised: Int, timesSpoken: Int, time: Long, courseId: Int) = doAsync {
repo.insert(timesHandRaised, timesSpoken, time, courseId) repo.insert(timesHandRaised, timesSpoken, time, courseId)
} }
+3 -3
View File
@@ -64,7 +64,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <TextView
android:id="@+id/text_above" android:id="@+id/super_title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@@ -78,7 +78,7 @@
app:layout_constraintEnd_toEndOf="parent"/> app:layout_constraintEnd_toEndOf="parent"/>
<TextView <TextView
android:id="@+id/toolbarTxt" android:id="@+id/app_bar_title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start" android:layout_gravity="start"
@@ -91,7 +91,7 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:singleLine="true" android:singleLine="true"
android:ellipsize="marquee" android:ellipsize="marquee"
app:layout_constraintTop_toBottomOf="@+id/text_above" app:layout_constraintTop_toBottomOf="@+id/super_title"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/> app:layout_constraintEnd_toEndOf="parent"/>
@@ -4,7 +4,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:backgroundTint="@color/colorBackground" android:backgroundTint="@color/colorBackground"
android:paddingTop="8dp"
android:paddingBottom="8dp"> android:paddingBottom="8dp">
<TextView <TextView
+5
View File
@@ -76,6 +76,7 @@
<string name="exam_date">Klausurdatum (yyyy-mm-dd)</string> <string name="exam_date">Klausurdatum (yyyy-mm-dd)</string>
<string name="date_format_issue">Dieses Datum kann nicht verarbeitet werden</string> <string name="date_format_issue">Dieses Datum kann nicht verarbeitet werden</string>
<string name="exam_past_issue">Vergangene Klausuren müssen benotet werden</string> <string name="exam_past_issue">Vergangene Klausuren müssen benotet werden</string>
<string name="open_participation_fragment">Beteiligung einsehen</string>
<!-- NotesFragment.kt --> <!-- NotesFragment.kt -->
<string name="notes">Notizen</string> <string name="notes">Notizen</string>
@@ -104,8 +105,12 @@
<string name="participation_ratio_desc">Gemeldet : Gesprochen</string> <string name="participation_ratio_desc">Gemeldet : Gesprochen</string>
<string name="delete_participation_confirmation">Bist du dir sicher, dass du diese Beteiligung löschen möchtest?</string> <string name="delete_participation_confirmation">Bist du dir sicher, dass du diese Beteiligung löschen möchtest?</string>
<string name="class_session">Klassenzimmermodus</string> <string name="class_session">Klassenzimmermodus</string>
<string name="class_session_resumed">Klassenzimmermodus (fortgesetzt)</string>
<string name="long_press_to_cancel">Lange drücken um abzubrechen</string> <string name="long_press_to_cancel">Lange drücken um abzubrechen</string>
<string name="long_press_to_finish">Lange drücken um zu beenden</string> <string name="long_press_to_finish">Lange drücken um zu beenden</string>
<string name="open_grade_fragment">Kurs einsehen</string>
<string name="participation_too_old">Beteiligung zu alt, um fortgesetzt zu werden</string>
<string name="participation_resumable">" (fortsetzbar)"</string>
<string-array name="days"> <string-array name="days">
<item>Montag</item> <item>Montag</item>
+5 -2
View File
@@ -133,7 +133,7 @@
<string name="exam_date">Exam date (yyyy-mm-dd)</string> <string name="exam_date">Exam date (yyyy-mm-dd)</string>
<string name="date_format_issue">This date can\'t be parsed</string> <string name="date_format_issue">This date can\'t be parsed</string>
<string name="exam_past_issue">Passed exams must have a grade associated</string> <string name="exam_past_issue">Passed exams must have a grade associated</string>
<string name="open_participation_fragment">Open participation</string> <string name="open_participation_fragment">View participation</string>
<!-- NotesFragment.kt --> <!-- NotesFragment.kt -->
<string name="notes">Notes</string> <string name="notes">Notes</string>
@@ -163,9 +163,12 @@
<string name="participation_ratio_desc">Hand raised : Spoken</string> <string name="participation_ratio_desc">Hand raised : Spoken</string>
<string name="delete_participation_confirmation">Are you sure you want to delete this participation?</string> <string name="delete_participation_confirmation">Are you sure you want to delete this participation?</string>
<string name="class_session">Class Session</string> <string name="class_session">Class Session</string>
<string name="class_session_resumed">Class Session (resumed)</string>
<string name="long_press_to_cancel">Long-press to cancel</string> <string name="long_press_to_cancel">Long-press to cancel</string>
<string name="long_press_to_finish">Long-press to finish</string> <string name="long_press_to_finish">Long-press to finish</string>
<string name="open_grade_fragment">Open course</string> <string name="open_grade_fragment">View course</string>
<string name="participation_too_old">Participation too old to be resumed</string>
<string name="participation_resumable">" (resumable)"</string>
<string-array name="days"> <string-array name="days">
<item>Monday</item> <item>Monday</item>