diff --git a/.gradle/6.1-rc-1/executionHistory/executionHistory.bin b/.gradle/6.1-rc-1/executionHistory/executionHistory.bin
index 735bd36..07c389d 100644
Binary files a/.gradle/6.1-rc-1/executionHistory/executionHistory.bin and b/.gradle/6.1-rc-1/executionHistory/executionHistory.bin differ
diff --git a/.gradle/6.1-rc-1/executionHistory/executionHistory.lock b/.gradle/6.1-rc-1/executionHistory/executionHistory.lock
index 5fa889a..3f5a7c5 100644
Binary files a/.gradle/6.1-rc-1/executionHistory/executionHistory.lock and b/.gradle/6.1-rc-1/executionHistory/executionHistory.lock differ
diff --git a/.gradle/6.1-rc-1/fileHashes/fileHashes.bin b/.gradle/6.1-rc-1/fileHashes/fileHashes.bin
index 1ee6e9c..9c85811 100644
Binary files a/.gradle/6.1-rc-1/fileHashes/fileHashes.bin and b/.gradle/6.1-rc-1/fileHashes/fileHashes.bin differ
diff --git a/.gradle/6.1-rc-1/fileHashes/fileHashes.lock b/.gradle/6.1-rc-1/fileHashes/fileHashes.lock
index eae7c11..4161d41 100644
Binary files a/.gradle/6.1-rc-1/fileHashes/fileHashes.lock and b/.gradle/6.1-rc-1/fileHashes/fileHashes.lock differ
diff --git a/.gradle/6.1-rc-1/fileHashes/resourceHashesCache.bin b/.gradle/6.1-rc-1/fileHashes/resourceHashesCache.bin
index 620255f..3f9d73f 100644
Binary files a/.gradle/6.1-rc-1/fileHashes/resourceHashesCache.bin and b/.gradle/6.1-rc-1/fileHashes/resourceHashesCache.bin differ
diff --git a/.gradle/6.1-rc-1/javaCompile/classAnalysis.bin b/.gradle/6.1-rc-1/javaCompile/classAnalysis.bin
index a194bba..edb4b38 100644
Binary files a/.gradle/6.1-rc-1/javaCompile/classAnalysis.bin and b/.gradle/6.1-rc-1/javaCompile/classAnalysis.bin differ
diff --git a/.gradle/6.1-rc-1/javaCompile/jarAnalysis.bin b/.gradle/6.1-rc-1/javaCompile/jarAnalysis.bin
index 8ddf025..80f02f6 100644
Binary files a/.gradle/6.1-rc-1/javaCompile/jarAnalysis.bin and b/.gradle/6.1-rc-1/javaCompile/jarAnalysis.bin differ
diff --git a/.gradle/6.1-rc-1/javaCompile/javaCompile.lock b/.gradle/6.1-rc-1/javaCompile/javaCompile.lock
index 61d7aba..dca76e1 100644
Binary files a/.gradle/6.1-rc-1/javaCompile/javaCompile.lock and b/.gradle/6.1-rc-1/javaCompile/javaCompile.lock differ
diff --git a/.gradle/6.1-rc-1/javaCompile/taskHistory.bin b/.gradle/6.1-rc-1/javaCompile/taskHistory.bin
index a0dc29f..301c41c 100644
Binary files a/.gradle/6.1-rc-1/javaCompile/taskHistory.bin and b/.gradle/6.1-rc-1/javaCompile/taskHistory.bin differ
diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock
index 2a0f1e5..7920580 100644
Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties
index 548c62e..49f9894 100644
--- a/.gradle/buildOutputCleanup/cache.properties
+++ b/.gradle/buildOutputCleanup/cache.properties
@@ -1,2 +1,2 @@
-#Wed Feb 12 10:01:56 CET 2020
-gradle.version=6.1-rc-1
+#Mon Mar 02 18:08:17 CET 2020
+gradle.version=6.1.1
diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin
index a021720..3e6884f 100644
Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and b/.gradle/buildOutputCleanup/outputFiles.bin differ
diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock
index be40e1a..fd7b750 100644
Binary files a/.gradle/checksums/checksums.lock and b/.gradle/checksums/checksums.lock differ
diff --git a/.idea/modules/app/app.iml b/.idea/modules/app/app.iml
index 6448b36..48895a5 100644
--- a/.idea/modules/app/app.iml
+++ b/.idea/modules/app/app.iml
@@ -4,8 +4,8 @@
-
-
+
+
@@ -31,7 +31,7 @@
-
+
@@ -70,21 +70,21 @@
-
-
-
+
+
+
-
+
-
+
@@ -134,11 +134,11 @@
+
+
-
-
@@ -161,7 +161,7 @@
-
+
diff --git a/app/src/main/java/com/denizd/qwark/activity/MainActivity.kt b/app/src/main/java/com/denizd/qwark/activity/MainActivity.kt
index 8908afd..a42f245 100644
--- a/app/src/main/java/com/denizd/qwark/activity/MainActivity.kt
+++ b/app/src/main/java/com/denizd/qwark/activity/MainActivity.kt
@@ -1,58 +1,46 @@
package com.denizd.qwark.activity
-import android.graphics.Color
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
import android.os.Bundle
+import android.os.Handler
+import android.util.Log
import android.view.View
-import android.view.ViewGroup
-import android.view.WindowManager
+import android.view.ViewAnimationUtils
+import androidx.activity.viewModels
+import androidx.appcompat.app.AppCompatDelegate
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
+import com.denizd.qwark.database.QwarkRepository
import com.denizd.qwark.databinding.ActivityMainBinding
import com.denizd.qwark.fragment.*
+import com.denizd.qwark.util.Dependencies
+import com.denizd.qwark.util.QwarkPreferences
import com.denizd.qwark.viewmodel.MainViewModel
+import kotlin.math.hypot
+import kotlin.random.Random
class MainActivity : FragmentActivity() {
private lateinit var viewModel: MainViewModel
-
- private var _binding: ActivityMainBinding? = null
- private val binding: ActivityMainBinding get() = _binding!!
+ private val binding: ActivityMainBinding by viewBinding(ActivityMainBinding::inflate)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTheme(R.style.AppTheme)
- _binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 42)
+ Dependencies.repo = QwarkRepository(application)
viewModel = ViewModelProvider(this)[MainViewModel::class.java]
viewModel.applyTheme(window, this)
viewModel.checkForFirstTimeYearNotice(this)
- binding.appBarLayout.also { appBarLayout ->
- appBarLayout.setOnApplyWindowInsetsListener { _, insets ->
- (appBarLayout.layoutParams as ViewGroup.MarginLayoutParams)
- .topMargin = insets.systemWindowInsetTop
- insets
- }
- }
-
- // TODO remove this translucent app bar layout stuff, it's hard to maintain
- 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
- } else {
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- }
-
- window.attributes = window.attributes.apply {
- flags and WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS.inv()
- }
- window.statusBarColor = Color.TRANSPARENT
-
binding.bottomNav.setOnNavigationItemSelectedListener { item ->
binding.appBarLayout.setExpanded(true)
loadFragment(viewModel.getFragmentType(item.itemId))
@@ -78,6 +66,27 @@ class MainActivity : FragmentActivity() {
// }
// TODO reselected listener for scrolling up
+
+ resources.getStringArray(R.array.greetings).also { array ->
+ binding.greetingTextView.text = String.format(array[Random.nextInt(array.size)], "TODO")
+ }
+ Handler().postDelayed({
+ binding.splashScreen.apply {
+ val cx = width / 2
+ val cy = height / 2
+ val initialRadius = hypot(cx.toDouble(), cy.toDouble()).toFloat()
+
+ ViewAnimationUtils.createCircularReveal(this, cx, cy, initialRadius, 0f).also { anim ->
+ anim.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ super.onAnimationEnd(animation)
+ visibility = View.GONE
+ }
+ })
+ anim.start()
+ }
+ }
+ }, 1200)
}
override fun onResume() {
@@ -88,11 +97,6 @@ class MainActivity : FragmentActivity() {
}
}
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
private fun loadFragment(type: String): Boolean {
val fragment = supportFragmentManager.findFragmentByTag(type) ?: viewModel.getFragment(type)
diff --git a/app/src/main/java/com/denizd/qwark/adapter/CourseAdapter.kt b/app/src/main/java/com/denizd/qwark/adapter/CourseAdapter.kt
index 6f86dd0..ad00e52 100644
--- a/app/src/main/java/com/denizd/qwark/adapter/CourseAdapter.kt
+++ b/app/src/main/java/com/denizd/qwark/adapter/CourseAdapter.kt
@@ -53,7 +53,7 @@ class CourseAdapter(private var courses: List,
val context = holder.averageTextView.context
holder.backgroundView.setBackgroundColor(
- context.getColor(if (currentItem.advanced) R.color.colorAccent else R.color.colorCardBackground)
+ context.getColor(if (currentItem.advanced) R.color.colorAccent else R.color.colorBackground)
)
val textColour = context.getColor(if (currentItem.advanced) R.color.colorTextInverted else R.color.colorText)
diff --git a/app/src/main/java/com/denizd/qwark/adapter/HistoricalAverageAdapter.kt b/app/src/main/java/com/denizd/qwark/adapter/HistoricalAverageAdapter.kt
index 46f544d..c358e17 100644
--- a/app/src/main/java/com/denizd/qwark/adapter/HistoricalAverageAdapter.kt
+++ b/app/src/main/java/com/denizd/qwark/adapter/HistoricalAverageAdapter.kt
@@ -1,39 +1,39 @@
package com.denizd.qwark.adapter
import android.view.LayoutInflater
-import android.view.View
import android.view.ViewGroup
-import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
-import com.denizd.qwark.R
+import com.denizd.qwark.databinding.AverageCardBinding
import com.denizd.qwark.util.QwarkUtil
import com.denizd.qwark.model.HistoricalAvg
+import com.denizd.qwark.util.getUserDefinedAverage
import java.util.*
-internal class HistoricalAverageAdapter(private var averages: List?) : RecyclerView.Adapter() {
+class HistoricalAverageAdapter(private val averages: List, private val gradeType: Int) : RecyclerView.Adapter() {
- internal class AverageViewHolder(view: View) : RecyclerView.ViewHolder(view) {
- val grade: TextView = view.findViewById(R.id.grade)
- val time: TextView = view.findViewById(R.id.time)
- }
+ class AverageViewHolder(val binding: AverageCardBinding) : RecyclerView.ViewHolder(binding.root)
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AverageViewHolder {
- val v = LayoutInflater.from(parent.context).inflate(R.layout.average_card, parent, false)
- return AverageViewHolder(v)
- }
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AverageViewHolder = AverageViewHolder(
+ AverageCardBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ )
override fun onBindViewHolder(holder: AverageViewHolder, position: Int) {
- val currentItem = averages!![position]
+ val currentItem = averages[position]
- val leadingZero = if (currentItem.average.toDouble() < 10.0) "0%s" else "%s"
- holder.grade.text = String.format(leadingZero, currentItem.average) // TODO this conflicts with Points (Precise)
- holder.time.text = QwarkUtil.getSimpleDateTimeFormat().format(Date(currentItem.time))
+ with (holder.binding) {
+ grade.text = currentItem.average.getUserDefinedAverage(gradeType)
+ time.text = QwarkUtil.getSimpleDateTimeFormat().format(Date(currentItem.time))
+ }
}
- override fun getItemCount(): Int = averages?.size ?: 0
+ override fun getItemCount(): Int = averages.size
- fun setAverages(averages: List) {
- this.averages = averages
- notifyDataSetChanged()
- }
+// fun setAverages(averages: List) {
+// this.averages = averages
+// notifyDataSetChanged()
+// }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/database/CourseRepository.kt b/app/src/main/java/com/denizd/qwark/database/CourseRepository.kt
deleted file mode 100644
index e9ad0b0..0000000
--- a/app/src/main/java/com/denizd/qwark/database/CourseRepository.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.denizd.qwark.database
-
-import android.app.Application
-
-import androidx.lifecycle.LiveData
-import com.denizd.qwark.model.Course
-import com.denizd.qwark.model.CourseExam
-import com.denizd.qwark.model.HistoricalAvg
-
-internal class CourseRepository(app: Application) {
-
- private val dao: QwarkDao = QwarkDatabase.getInstance(app).dao()
-// val allCourses: LiveData> = dao.allCourses
-// val allHistoricalAverages: LiveData> = dao.allHistoricalAverages
-
- fun insert(course: Course) { dao.insert(course) }
- fun update(course: Course) { dao.update(course) }
- fun delete(course: Course) { dao.delete(course) }
-
- fun insert(avg: HistoricalAvg) { dao.insert(avg) }
-
- fun getCoursesByYearId(yearId: Int): LiveData> = dao.getCoursesByYearId(yearId)
- fun getAveragesForCourses(courseId: Int): List = dao.getAveragesForCourses(courseId)
-
- fun getCourse(courseId: Int): CourseExam = dao.getCourse(courseId)[0]
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/database/FinalsRepository.kt b/app/src/main/java/com/denizd/qwark/database/FinalsRepository.kt
deleted file mode 100644
index 3cff5aa..0000000
--- a/app/src/main/java/com/denizd/qwark/database/FinalsRepository.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.denizd.qwark.database
-
-import android.app.Application
-import androidx.lifecycle.LiveData
-import com.denizd.qwark.util.QwarkPreferences
-import com.denizd.qwark.model.FinalGrade
-import java.math.BigDecimal
-import java.math.RoundingMode
-
-class FinalsRepository(app: Application) {
-
- private val dao: QwarkDao = QwarkDatabase.getInstance(app).dao()
- private val prefs: QwarkPreferences = QwarkPreferences.getPrefs(app)
-
- fun getScoreProfileName(): String = prefs.getScoreProfileName()
- fun getFinalGrades(finalScoreId: Int): LiveData> = dao.getFinalGrades(finalScoreId)
- fun getFinalScoreId() = prefs.getScoreProfileId()
- fun getCourseSortType() = prefs.getCourseSortType()
- fun getGradeType() = prefs.getGradeType()
-
- fun updateFinalGradeAverage(courseId: Int, finalGradeId: Int) {
- val course = dao.getCourse(courseId)[0]
- dao.updateFinalGradeAverage(
- course.name,
- BigDecimal(course.average).setScale(0, RoundingMode.HALF_UP).toInt(),
- finalGradeId
- )
- }
-
- fun updateLinkedGrades() {
- val finalGrades = dao.getFinalGradesAsList(getFinalScoreId())
- for (finalGrade in finalGrades) {
- if (finalGrade.courseId != -1) {
- updateFinalGradeAverage(finalGrade.courseId, finalGrade.finalGradeId)
- }
- }
- }
-
- fun getSchoolYearName(courseId: Int) = dao.getSchoolYearName(courseId)
-
- fun getAllYears() = dao.getAllYears()
- fun getAllCourses() = dao.getAllCourseExams()
-
- fun getCourse(courseId: Int) = dao.getCourse(courseId)[0]
- fun getFinalGrade(finalGradeId: Int) = dao.getFinalGrade(finalGradeId)[0]
- fun update(finalGrade: FinalGrade) { dao.update(finalGrade) }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/database/GradeRepository.kt b/app/src/main/java/com/denizd/qwark/database/GradeRepository.kt
deleted file mode 100644
index 216eb32..0000000
--- a/app/src/main/java/com/denizd/qwark/database/GradeRepository.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.denizd.qwark.database
-
-import android.app.Application
-import androidx.lifecycle.LiveData
-import com.denizd.qwark.model.Grade
-import com.denizd.qwark.model.HistoricalAvg
-import com.denizd.qwark.util.*
-import com.denizd.qwark.util.QwarkPreferences
-
-class GradeRepository(app: Application) {
-
- private val dao: QwarkDao = QwarkDatabase.getInstance(app).dao()
- private val prefs: QwarkPreferences = QwarkPreferences.getPrefs(app)
-
- fun getGradeType(): Int = prefs.getInt(PreferenceKey.GRADE_TYPE)
-
- // TODO this might crash
- fun getCourse(courseId: Int) = dao.getCourse(courseId)[0]
-
- fun insert(grade: Grade) { dao.insert(grade) }
- fun update(grade: Grade) { dao.update(grade) }
- fun delete(gradeId: Int) { dao.deleteGrade(gradeId) }
-
- fun insert(avg: HistoricalAvg) { dao.insert(avg) }
- fun updateAverage(average: String, gradeCount: Int, courseId: Int) {
- dao.updateAverage(average, gradeCount, courseId)
- }
-
- fun getGradesByForeignKey(courseId: Int): LiveData> = dao.getGradesByForeignKey(courseId)
- fun getGrade(gradeId: Int) = dao.getGrade(gradeId)[0]
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/database/NoteRepository.kt b/app/src/main/java/com/denizd/qwark/database/NoteRepository.kt
deleted file mode 100644
index 084c86b..0000000
--- a/app/src/main/java/com/denizd/qwark/database/NoteRepository.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.denizd.qwark.database
-
-import android.app.Application
-
-import androidx.lifecycle.LiveData
-import com.denizd.qwark.model.Note
-
-class NoteRepository(app: Application) {
-
- private val dao: QwarkDao = QwarkDatabase.getInstance(app).dao()
- val allNotes: LiveData> = dao.allNotes
-
- fun getNotesForCategory(category: String): LiveData> = dao.notesForCategory(category)
- fun getAllCategories(): List = dao.getAllCategories()
- fun insert(note: Note) { dao.insert(note) }
- fun update(note: Note) { dao.update(note) }
- fun updateDismissed(newDismissedStatus: Boolean, noteId: Int) { dao.updateDismissed(newDismissedStatus, noteId) }
- fun delete(noteId: Int) { dao.deleteNote(noteId) }
- fun getNote(noteId: Int) = dao.getNote(noteId)[0]
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/database/ParticipationRepository.kt b/app/src/main/java/com/denizd/qwark/database/ParticipationRepository.kt
deleted file mode 100644
index 5a7cd2c..0000000
--- a/app/src/main/java/com/denizd/qwark/database/ParticipationRepository.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.denizd.qwark.database
-
-import android.app.Application
-import android.util.Log
-import androidx.lifecycle.LiveData
-import com.denizd.qwark.model.Course
-import com.denizd.qwark.model.CourseExam
-import com.denizd.qwark.model.Participation
-import com.denizd.qwark.model.SchoolDay
-import com.denizd.qwark.util.*
-import com.denizd.qwark.util.QwarkPreferences
-import java.util.*
-
-class ParticipationRepository(app: Application) {
-
- private val days: Array = arrayOf("mon", "tue", "wed", "thu", "fri")
- private val dao: QwarkDao = QwarkDatabase.getInstance(app).dao()
- private val prefs: QwarkPreferences = QwarkPreferences.getPrefs(app.applicationContext)
- // monday: 1, increment by 1 for each day
- val dayId: Int = when (prefs.getParticipationDay()) {
- 0 -> if (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1 in 1..5)
- Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1 else 1
- else -> prefs.getParticipationDay()
- }
- val allCoursesForToday: LiveData> = dao.getCoursesByDayType(getDayType(), prefs.getSchoolYear())
-
- fun initParticipationTables() {
- for (day in days) {
- dao.insert(SchoolDay(day, 0, prefs.getSchoolYear()))
- }
- }
-
- fun getParticipationCount(participations: List) = if (prefs.getParticipationDisplay() == 0) {
- arrayOf(
- (participations.map { it.timesHandRaised }.sum().toDouble() / participations.size.toDouble()).round(),
- (participations.map { it.timesSpoken }.sum().toDouble() / participations.size.toDouble()).round()
- )
- } else {
- arrayOf(
- (participations.map { it.timesHandRaised }.sum()),
- (participations.map { it.timesSpoken }.sum())
- )
- }
-
- fun getDayType(): String = if (dayId in 1..5) days[dayId - 1] else days[1]
- fun getDays(): List = dao.getDays(prefs.getSchoolYear())
- fun getCourses(): List = dao.getCoursesByYearIdAsList(prefs.getSchoolYear()).getSorted(
- prefs.getCourseSortType()
- )
- fun link(courseId: Int) { dao.link(courseId, getDayType(), prefs.getSchoolYear()) }
- fun removeLink(relationId: Int) { dao.removeLink(relationId) }
- fun getAllParticipationsForCourse(courseId: Int): LiveData> =
- dao.getAllParticipationsForCourse(courseId)
- fun insert(timesHandRaised: Int, timesSpoken: Int, time: Long, courseId: Int) {
- dao.insert(
- Participation(
- timesHandRaised,
- timesSpoken,
- time,
- 0,
- courseId,
- dayId
- )
- )
- }
- fun delete(participation: Participation) { dao.delete(participation) }
- 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()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/database/QwarkDao.kt b/app/src/main/java/com/denizd/qwark/database/QwarkDao.kt
index 27fd695..ecd77e6 100644
--- a/app/src/main/java/com/denizd/qwark/database/QwarkDao.kt
+++ b/app/src/main/java/com/denizd/qwark/database/QwarkDao.kt
@@ -30,7 +30,7 @@ interface QwarkDao {
fun getCoursesByYearIdAsList(yearId: Int): List
@Query("SELECT *, -1 AS exam_time FROM course WHERE course_id = :courseId")
- fun getCourse(courseId: Int): List
+ fun getCourse(courseId: Int): CourseExam
@Insert
fun insert(course: Course)
@@ -68,7 +68,7 @@ interface QwarkDao {
fun deleteGrade(gradeId: Int)
@Query("SELECT * FROM grade WHERE grade_id = :gradeId")
- fun getGrade(gradeId: Int): List
+ fun getGrade(gradeId: Int): Grade
// notes
@@ -97,7 +97,7 @@ interface QwarkDao {
fun getAllCategories(): List
@Query("SELECT * FROM note WHERE note_id = :noteId")
- fun getNote(noteId: Int): List
+ fun getNote(noteId: Int): Note
// historical averages
@@ -165,7 +165,7 @@ interface QwarkDao {
fun insertAll(finalGrades: Array)
@Query("SELECT * FROM final_grade WHERE final_grade_id = :finalGradeId")
- fun getFinalGrade(finalGradeId: Int): List
+ fun getFinalGrade(finalGradeId: Int): FinalGrade
// school days
diff --git a/app/src/main/java/com/denizd/qwark/database/QwarkDatabase.kt b/app/src/main/java/com/denizd/qwark/database/QwarkDatabase.kt
index f7e1bef..96b0fcc 100644
--- a/app/src/main/java/com/denizd/qwark/database/QwarkDatabase.kt
+++ b/app/src/main/java/com/denizd/qwark/database/QwarkDatabase.kt
@@ -14,7 +14,7 @@ import com.denizd.qwark.model.Note
import com.denizd.qwark.model.SchoolYear
@Database(entities = [Course::class, Grade::class, Note::class, HistoricalAvg::class, SchoolYear::class, FinalGrade::class, ScoreProfile::class, Participation::class, SchoolDay::class, CourseDayRelation::class], version = 9, exportSchema = false)
-internal abstract class QwarkDatabase : RoomDatabase() {
+abstract class QwarkDatabase : RoomDatabase() {
abstract fun dao(): QwarkDao
diff --git a/app/src/main/java/com/denizd/qwark/database/QwarkRepository.kt b/app/src/main/java/com/denizd/qwark/database/QwarkRepository.kt
new file mode 100644
index 0000000..a04abea
--- /dev/null
+++ b/app/src/main/java/com/denizd/qwark/database/QwarkRepository.kt
@@ -0,0 +1,204 @@
+package com.denizd.qwark.database
+
+import android.app.Application
+import androidx.lifecycle.LiveData
+import com.denizd.qwark.model.*
+import com.denizd.qwark.util.*
+import java.util.*
+
+class QwarkRepository(app: Application) {
+
+ private val dao: QwarkDao = QwarkDatabase.getInstance(app.applicationContext).dao()
+ val prefs: QwarkPreferences = QwarkPreferences(app.applicationContext)
+
+ // misc
+ private val days: Array = arrayOf("mon", "tue", "wed", "thu", "fri")
+ // monday: 1, increment by 1 for each day
+ val dayId: Int = when (prefs.getParticipationDay()) {
+ 0 -> with (Calendar.getInstance()) {
+ if (get(Calendar.DAY_OF_WEEK) - 1 in 1..5) get(Calendar.DAY_OF_WEEK) - 1 else 1
+ }
+ else -> prefs.getParticipationDay()
+ }
+ fun initParticipationTables() {
+ for (day in days) {
+ dao.insert(SchoolDay(day, 0, prefs.getSchoolYear()))
+ }
+ }
+ fun link(courseId: Int) { dao.link(courseId, getDayType(), prefs.getSchoolYear()) }
+ fun removeLink(relationId: Int) { dao.removeLink(relationId) }
+ fun copyCourses(yearId: Int) {
+ val currentSchoolYearId = prefs.getCurrentSchoolYearId()
+ val courses = dao.getCoursesByYearIdAsList(yearId)
+ for (course in courses) {
+ dao.insert(
+ Course(
+ name = course.name,
+ advanced = course.advanced,
+ icon = course.icon,
+ colour = course.colour,
+ average = if (prefs.getGradeType() == QwarkUtil.GRADE_PRECISE) "0.00" else "0",
+ oralWeighting = course.oralWeighting,
+ gradeCount = course.gradeCount,
+ time = System.currentTimeMillis(),
+ courseId = 0,
+ yearId = currentSchoolYearId
+ )
+ )
+ }
+ }
+ fun initNewFinalScore(name: String) {
+ val finalScoreId = getMaxFinalScoreId(true)
+ val finalGrade = FinalGrade("", "-1", "basic", "x 1", -1, 0, finalScoreId)
+ dao.insert(ScoreProfile(name, finalScoreId))
+
+ val values = ArrayList()
+ repeat(24) { values.add(finalGrade.copy(type = "basic", note = "x 1")) }
+ repeat(2) {
+ repeat(4) { values.add(finalGrade.copy(type = "adv", note = "x 2")) }
+ values.add(finalGrade.copy(note = "x 1"))
+ }
+ for (i in 1..5) {
+ values.add(finalGrade.copy(type = "exam", note = "P$i x ${if (i == 5) "2" else "5"}"))
+ }
+
+ dao.insertAll(values.toTypedArray())
+ }
+
+ // insert
+ fun insert(course: Course) { dao.insert(course) }
+ fun insert(grade: Grade) { dao.insert(grade) }
+ fun insert(note: Note) { dao.insert(note) }
+ fun insert(historicalAvg: HistoricalAvg) { dao.insert(historicalAvg) }
+ fun insert(schoolYear: SchoolYear) { dao.insert(schoolYear) }
+ fun insert(scoreProfile: ScoreProfile) { dao.insert(scoreProfile) }
+ fun insert(schoolDay: SchoolDay) { dao.insert(schoolDay) }
+ fun insert(participation: Participation) { dao.insert(participation) }
+
+ // insert multiple
+ fun insertAll(finalGrades: Array) { dao.insertAll(finalGrades) }
+
+ // set
+ fun setCurrentScoreProfile(scoreProfile: ScoreProfile) {
+ prefs.setInt(PreferenceKey.SCORE_PROFILE_ID, scoreProfile.scoreProfileId)
+ .setString(PreferenceKey.SCORE_PROFILE_NAME, scoreProfile.name)
+ }
+
+ fun setCurrentSchoolYear(schoolYear: SchoolYear) {
+ prefs.setInt(PreferenceKey.SCHOOL_YEAR_ID, schoolYear.yearId)
+ .setString(PreferenceKey.SCHOOL_YEAR_NAME, schoolYear.year)
+ }
+
+ // update
+ fun update(course: Course) { dao.update(course) }
+ fun update(finalGrade: FinalGrade) { dao.update(finalGrade) }
+ fun updateLinkedGrades() {
+ for (finalGrade in dao.getFinalGradesAsList(prefs.getFinalScoreId())) {
+ if (finalGrade.courseId != -1) {
+ updateFinalGradeAverage(finalGrade.courseId, finalGrade.finalGradeId)
+ }
+ }
+ }
+ fun updateFinalGradeAverage(courseId: Int, finalGradeId: Int) {
+ dao.getCourse(courseId).also { course ->
+ dao.updateFinalGradeAverage(
+ course.name,
+ course.average.roundToInt(),
+ finalGradeId
+ )
+ }
+ }
+ fun updateAverage(average: String, gradeCount: Int, courseId: Int) { dao.updateAverage(average, gradeCount, courseId) }
+ fun update(grade: Grade) { dao.update(grade) }
+ fun update(note: Note) { dao.update(note) }
+ fun updateDismissed(newDismissedStatus: Boolean, noteId: Int) { dao.updateDismissed(newDismissedStatus, noteId) }
+ fun updateParticipation(participation: String, courseId: Int) {
+ dao.updateParticipation(participation, courseId)
+ }
+ fun updateParticipation(timesHandRaised: Int, timesSpoken: Int, participationId: Int) {
+ dao.updateParticipation(timesHandRaised, timesSpoken, participationId)
+ }
+ fun updateSchoolYear(name: String) {
+ dao.update(SchoolYear(name, prefs.getCurrentSchoolYearId()))
+ setCurrentSchoolYear(SchoolYear(name, prefs.getCurrentSchoolYearId()))
+ }
+
+ fun updateScoreProfile(name: String) {
+ dao.update(ScoreProfile(name, prefs.getScoreProfileId()))
+ setCurrentScoreProfile(ScoreProfile(name, prefs.getScoreProfileId()))
+ }
+
+ // delete
+ fun delete(course: Course) { dao.delete(course) }
+ fun deleteGrade(gradeId: Int) { dao.deleteGrade(gradeId) }
+ fun deleteNote(noteId: Int) { dao.deleteNote(noteId) }
+ fun delete(participation: Participation) { dao.delete(participation) }
+ fun deleteSchoolYear() {
+ dao.deleteSchoolYear(prefs.getCurrentSchoolYearId())
+ setCurrentSchoolYear(SchoolYear("", 0))
+ }
+
+ fun deleteScoreProfile() {
+ dao.deleteScoreProfile(prefs.getScoreProfileId())
+ setCurrentScoreProfile(ScoreProfile("", 0))
+ }
+
+ // live data
+ val allNotes: LiveData> = dao.allNotes
+ val allCoursesForToday: LiveData> = dao.getCoursesByDayType(getDayType(), prefs.getSchoolYear())
+ val allYears: LiveData> = dao.allYears
+ val allScoreProfiles: LiveData> = dao.allScoreProfiles
+
+ // get
+ fun getCourse(courseId: Int): CourseExam = dao.getCourse(courseId)
+ fun getSchoolYearName(courseId: Int) = dao.getSchoolYearName(courseId)
+ fun getFinalGrade(finalGradeId: Int) = dao.getFinalGrade(finalGradeId)
+ fun getGrade(gradeId: Int) = dao.getGrade(gradeId)
+ fun getNote(noteId: Int) = dao.getNote(noteId)
+ fun getParticipationCount(participations: List) = if (prefs.getParticipationDisplay() == 0) {
+ arrayOf(
+ (participations.map { it.timesHandRaised }.sum().toDouble() / participations.size.toDouble()).round(),
+ (participations.map { it.timesSpoken }.sum().toDouble() / participations.size.toDouble()).round()
+ )
+ } else {
+ arrayOf(
+ (participations.map { it.timesHandRaised }.sum()),
+ (participations.map { it.timesSpoken }.sum())
+ )
+ }
+ fun getDayType(): String = if (dayId in 1..5) days[dayId - 1] else days[1]
+ private fun getMaxFinalScoreId(increment: Boolean): Int {
+ if (increment) {
+ prefs.setInt(PreferenceKey.MAX_SCORE_PROFILE_ID, getMaxFinalScoreId(false) + 1)
+ .setInt(PreferenceKey.SCORE_PROFILE_ID, getMaxFinalScoreId(false) + 1)
+ }
+ return prefs.getInt(PreferenceKey.MAX_SCORE_PROFILE_ID)
+ }
+
+ // get multiple
+ fun getCoursesByYearId(yearId: Int): LiveData> = dao.getCoursesByYearId(yearId)
+ fun getAllCourses() = dao.getAllCourseExams()
+ fun getAveragesForCourses(courseId: Int): List = dao.getAveragesForCourses(courseId)
+ fun getFinalGrades(finalScoreId: Int): LiveData> = dao.getFinalGrades(finalScoreId)
+ fun getAllYears(): List = dao.getAllYears()
+ fun getGradesByForeignKey(courseId: Int): LiveData> = dao.getGradesByForeignKey(courseId)
+ fun getNotesForCategory(category: String): LiveData> = dao.notesForCategory(category)
+ fun getAllCategories(): List = dao.getAllCategories()
+ fun getDays(): List = dao.getDays(prefs.getSchoolYear())
+ fun getCourses(): List =
+ dao.getCoursesByYearIdAsList(prefs.getSchoolYear()).getSorted(prefs.getCourseSortType())
+ fun getAllParticipationsForCourse(courseId: Int): LiveData> =
+ dao.getAllParticipationsForCourse(courseId)
+ fun insert(timesHandRaised: Int, timesSpoken: Int, time: Long, courseId: Int) {
+ dao.insert(
+ Participation(
+ timesHandRaised,
+ timesSpoken,
+ time,
+ 0,
+ courseId,
+ dayId
+ )
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/database/SettingsRepository.kt b/app/src/main/java/com/denizd/qwark/database/SettingsRepository.kt
deleted file mode 100644
index 1958961..0000000
--- a/app/src/main/java/com/denizd/qwark/database/SettingsRepository.kt
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.denizd.qwark.database
-
-import android.app.Application
-import androidx.lifecycle.LiveData
-import com.denizd.qwark.util.PreferenceKey
-import com.denizd.qwark.util.QwarkPreferences
-import com.denizd.qwark.util.QwarkUtil
-import com.denizd.qwark.model.Course
-import com.denizd.qwark.model.FinalGrade
-import com.denizd.qwark.model.ScoreProfile
-import com.denizd.qwark.model.SchoolYear
-
-class SettingsRepository(app: Application) {
-
- private val dao: QwarkDao = QwarkDatabase.getInstance(app).dao()
- private val prefs: QwarkPreferences = QwarkPreferences.getPrefs(app.applicationContext)
- val allYears: LiveData> = dao.allYears
- val allScoreProfiles: LiveData> = dao.allScoreProfiles
-
- // Preference getters
- fun getAppTheme(): Int = prefs.getInt(PreferenceKey.APP_THEME, 2)
- fun getShowGradeAverage(): Boolean = prefs.getBool(PreferenceKey.SHOW_GRADE_AVERAGE)
- fun getGradeType(): Int = prefs.getInt(PreferenceKey.GRADE_TYPE)
- fun getCurrentSchoolYear(): String = prefs.getString(PreferenceKey.SCHOOL_YEAR_NAME)
- fun getCurrentSchoolYearId(): Int = prefs.getInt(PreferenceKey.SCHOOL_YEAR_ID)
- private fun getScoreProfileId(): Int = prefs.getInt(PreferenceKey.SCORE_PROFILE_ID, 0)
- fun getScoreProfileName(): String = prefs.getString(PreferenceKey.SCORE_PROFILE_NAME)
- fun getParticipationDisplay(): Int = prefs.getParticipationDisplay()
- fun getParticipationDay(): Int = prefs.getParticipationDay()
-
- private fun getMaxFinalScoreId(increment: Boolean): Int {
- if (increment) {
- prefs.putInt(PreferenceKey.MAX_SCORE_PROFILE_ID, getMaxFinalScoreId(false) + 1)
- .putInt(PreferenceKey.SCORE_PROFILE_ID, getMaxFinalScoreId(false) + 1)
- }
- return prefs.getInt(PreferenceKey.MAX_SCORE_PROFILE_ID)
- }
-
- // Preference setters
- fun setAppTheme(value: Int) { prefs.putInt(PreferenceKey.APP_THEME, value) }
- fun setShowGradeAverage(value: Boolean) { prefs.putBool(PreferenceKey.SHOW_GRADE_AVERAGE, value) }
- fun setGradeType(value: Int) { prefs.putInt(PreferenceKey.GRADE_TYPE, value) }
- fun setParticipationDisplay(value: Int) { prefs.setParticipationDisplay(value) }
- fun setParticipationDay(value: Int) { prefs.setParticipationDay(value) }
-
- fun setCurrentScoreProfile(scoreProfile: ScoreProfile) {
- prefs.putInt(PreferenceKey.SCORE_PROFILE_ID, scoreProfile.scoreProfileId)
- .putString(PreferenceKey.SCORE_PROFILE_NAME, scoreProfile.name)
- }
-
- fun setCurrentSchoolYear(schoolYear: SchoolYear) {
- prefs.putInt(PreferenceKey.SCHOOL_YEAR_ID, schoolYear.yearId)
- .putString(PreferenceKey.SCHOOL_YEAR_NAME, schoolYear.year)
- }
-
- // Database functions
- fun insert(schoolYear: SchoolYear) { dao.insert(schoolYear) }
- fun insert(scoreProfile: ScoreProfile) { dao.insert(scoreProfile) }
-
- fun initNewFinalScore(name: String) {
- val finalScoreId = getMaxFinalScoreId(true)
- dao.insert(ScoreProfile(name, finalScoreId))
-
- val values = ArrayList()
- for (i in 0 until 24) {
- values.add(FinalGrade("", "-1", "basic", "x 1", -1, 0, finalScoreId))
- }
-
- for (i in 0 until 3) {
- values.add(FinalGrade("", "-1", "adv", "x 2", -1, 0, finalScoreId))
- }
- values.add(FinalGrade("", "-1", "adv", "x 1", -1, 0, finalScoreId))
- for (i in 0 until 3) {
- values.add(FinalGrade("", "-1", "adv", "x 2", -1, 0, finalScoreId))
- }
- values.add(FinalGrade("", "-1", "adv", "x 1", -1, 0, finalScoreId))
-
- for (i in 1..5) {
- values.add(FinalGrade("", "-1", "exam", "P$i x ${if (i == 5) "2" else "5"}", -1, 0, finalScoreId))
- }
-
- dao.insertAll(values.toTypedArray())
- }
-
- fun updateSchoolYear(name: String) {
- dao.update(SchoolYear(name, getCurrentSchoolYearId()))
- setCurrentSchoolYear(SchoolYear(name, getCurrentSchoolYearId()))
- }
-
- fun updateScoreProfile(name: String) {
- dao.update(ScoreProfile(name, getScoreProfileId()))
- setCurrentScoreProfile(ScoreProfile(name, getScoreProfileId()))
- }
-
- fun deleteSchoolYear() {
- dao.deleteSchoolYear(getCurrentSchoolYearId())
- setCurrentSchoolYear(SchoolYear("", 0))
- }
-
- fun deleteScoreProfile() {
- dao.deleteScoreProfile(getScoreProfileId())
- setCurrentScoreProfile(ScoreProfile("", 0))
- }
-
- fun copyCourses(yearId: Int) {
- val currentSchoolYearId = getCurrentSchoolYearId()
- val courses = dao.getCoursesByYearIdAsList(yearId)
- for (course in courses) {
- dao.insert(
- Course(
- name = course.name,
- advanced = course.advanced,
- icon = course.icon,
- colour = course.colour,
- average = if (getGradeType() == QwarkUtil.GRADE_PRECISE) "0.00" else "0",
- oralWeighting = course.oralWeighting,
- gradeCount = course.gradeCount,
- time = System.currentTimeMillis(),
- courseId = 0,
- yearId = currentSchoolYearId
- )
- )
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/fragment/CourseFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/CourseFragment.kt
index ae3eea2..7bd08b8 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/CourseFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/CourseFragment.kt
@@ -11,6 +11,7 @@ import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.StaggeredGridLayoutManager
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.adapter.CourseAdapter
import com.denizd.qwark.sheet.ConfirmDeletionSheet
@@ -26,11 +27,9 @@ import com.denizd.qwark.viewmodel.CourseViewModel
import com.google.android.material.snackbar.Snackbar
import java.lang.NumberFormatException
-class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListener {
-
- private var _binding: PaddedRecyclerViewBinding? = null
- private val binding: PaddedRecyclerViewBinding get() = _binding!!
+class CourseFragment : QwarkFragment(R.layout.padded_recycler_view), CourseAdapter.CourseClickListener {
+ private val binding: PaddedRecyclerViewBinding by viewBinding(PaddedRecyclerViewBinding::bind)
private val viewModel: CourseViewModel by viewModels()
private lateinit var recyclerViewAdapter: CourseAdapter
@@ -42,10 +41,7 @@ class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListener {
viewModel.allCourses.observe(this, Observer { courses ->
recyclerViewAdapter.setCourses(courses.getSorted(viewModel.getCourseSortType()))
if (scrollPosition == null) {
- binding.recyclerView.apply {
- scrollToPosition(0)
- scheduleLayoutAnimation()
- }
+ binding.recyclerView.scheduleLayoutAnimation()
} else {
binding.recyclerView.layoutManager?.onRestoreInstanceState(scrollPosition)
}
@@ -70,11 +66,6 @@ class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListener {
)
}
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = PaddedRecyclerViewBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -102,18 +93,6 @@ class CourseFragment : QwarkFragment(), CourseAdapter.CourseClickListener {
}
}
- override fun onResume() {
- super.onResume()
- binding.recyclerView.apply {
- applyPadding(horizontalPadding = 4)
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
override fun onCourseClick(course: CourseExam) {
appBar.setExpanded(true)
val f = GradeFragment()
diff --git a/app/src/main/java/com/denizd/qwark/fragment/FinalsFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/FinalsFragment.kt
index df54c61..2dfef7e 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/FinalsFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/FinalsFragment.kt
@@ -1,6 +1,5 @@
package com.denizd.qwark.fragment
-import android.content.res.Configuration
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
@@ -11,22 +10,19 @@ import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.adapter.FinalGradeAdapter
-import com.denizd.qwark.sheet.ConfirmDeletionSheet
-import com.denizd.qwark.sheet.FinalsCreateSheet
-import com.denizd.qwark.sheet.FinalsOptionsSheet
import com.denizd.qwark.databinding.FinalsFragmentBinding
-import com.denizd.qwark.sheet.FinalsLinkSheet
import com.denizd.qwark.model.FinalGrade
+import com.denizd.qwark.sheet.*
import com.denizd.qwark.viewmodel.FinalsViewModel
import com.google.android.material.snackbar.Snackbar
-class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeClickListener {
+class FinalsFragment : QwarkFragment(R.layout.finals_fragment), FinalGradeAdapter.FinalGradeClickListener {
private lateinit var viewModel: FinalsViewModel
- private var _binding: FinalsFragmentBinding? = null
- private val binding: FinalsFragmentBinding get() = _binding!!
+ private val binding: FinalsFragmentBinding by viewBinding(FinalsFragmentBinding::bind)
private var pointsText = ""
private var gradeText = ""
@@ -80,11 +76,6 @@ class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeClickListene
binding.gradeTextview.text = gradeText
}
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = FinalsFragmentBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -94,7 +85,16 @@ class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeClickListene
} else {
getString(R.string.score_profile_template, viewModel.getScoreProfileName())
}
- fab.hide()
+ fab.apply {
+ // temporary until the scroll situation can be figured out
+// show()
+ hide()
+// text = getString(R.string.conversion_table)
+// setOnClickListener {
+// openBottomSheet(FinalGradeTableSheet())
+// }
+ }
+// binding.scrollView.addFabScrollListener()
val layoutManagerBasic = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
val layoutManagerAdvanced = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
@@ -110,20 +110,9 @@ class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeClickListene
override fun onResume() {
super.onResume()
- binding.paddingView.apply {
- applyPadding()
- }
- if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- binding.textLayout?.applyPadding()
- }
setTextForGradeTextViews()
}
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
override fun onFinalGradeClick(finalGrade: FinalGrade) {
openBottomSheet(FinalsOptionsSheet().also { sheet ->
sheet.arguments = Bundle().apply { putInt("finalGradeId", finalGrade.finalGradeId) }
@@ -146,6 +135,7 @@ class FinalsFragment : QwarkFragment(), FinalGradeAdapter.FinalGradeClickListene
fun getAllCourses() = viewModel.getAllCourses()
fun viewLinkedCourse(courseId: Int) {
+ appBar.setExpanded(true)
val f = GradeFragment().also { fragment ->
fragment.arguments = Bundle().apply {
putInt("courseId", courseId)
diff --git a/app/src/main/java/com/denizd/qwark/fragment/GradeFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/GradeFragment.kt
index 41ba11c..f06bcba 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/GradeFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/GradeFragment.kt
@@ -4,12 +4,12 @@ import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.View
-import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.adapter.GradeAdapter
import com.denizd.qwark.sheet.ConfirmDeletionSheet
@@ -23,7 +23,7 @@ import com.denizd.qwark.util.getUserDefinedAverage
import com.denizd.qwark.viewmodel.GradeViewModel
import com.google.android.material.bottomnavigation.BottomNavigationView
-class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
+class GradeFragment : QwarkFragment(R.layout.grade_fragment), GradeAdapter.GradeClickListener {
private lateinit var currentCourse: CourseExam
private var average = ""
@@ -35,8 +35,7 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
private val viewModel: GradeViewModel by viewModels()
private lateinit var inflater: LayoutInflater
- private var _binding: GradeFragmentBinding? = null
- private val binding: GradeFragmentBinding get() = _binding!!
+ private val binding: GradeFragmentBinding by viewBinding(GradeFragmentBinding::bind)
private var scrollPosition: Parcelable? = null
@@ -75,11 +74,6 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
adapter = GradeAdapter(ArrayList(), this, getGradeType())
}
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = GradeFragmentBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -109,16 +103,6 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
}
}
- override fun onResume() {
- super.onResume()
- binding.paddingView.applyPadding()
- }
-
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
private fun insertNewHistoricalAverage() {
viewModel.insert(
HistoricalAvg(
@@ -145,7 +129,7 @@ class GradeFragment : QwarkFragment(), GradeAdapter.GradeClickListener {
override fun onGradeLongClick(gradeId: Int) {
val deletionSheet = ConfirmDeletionSheet(getString(R.string.confirm_grade_deletion)) {
- viewModel.delete(gradeId)
+ viewModel.deleteGrade(gradeId)
}
openBottomSheet(deletionSheet)
}
diff --git a/app/src/main/java/com/denizd/qwark/fragment/NoteFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/NoteFragment.kt
index d27714e..38dedda 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/NoteFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/NoteFragment.kt
@@ -9,6 +9,7 @@ import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.StaggeredGridLayoutManager
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.adapter.NoteAdapter
import com.denizd.qwark.sheet.ConfirmDeletionSheet
@@ -21,7 +22,7 @@ import com.denizd.qwark.model.Note
import com.denizd.qwark.viewmodel.NoteViewModel
import com.google.android.material.appbar.AppBarLayout
-class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPressed {
+class NoteFragment : QwarkFragment(R.layout.padded_recycler_view), NoteAdapter.OnNoteClickListener, OnBackPressed {
private lateinit var viewModel: NoteViewModel
private val adapter = NoteAdapter(ArrayList(), this)
@@ -30,8 +31,7 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
private lateinit var appBarLayout: AppBarLayout
- private var _binding: PaddedRecyclerViewBinding? = null
- private val binding: PaddedRecyclerViewBinding get() = _binding!!
+ private val binding: PaddedRecyclerViewBinding by viewBinding(PaddedRecyclerViewBinding::bind)
private var isInCategoryView = false
override fun onCreate(savedInstanceState: Bundle?) {
@@ -53,11 +53,6 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
StaggeredGridLayoutManager(getGridColumnCount(newConfig), StaggeredGridLayoutManager.VERTICAL)
}
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = PaddedRecyclerViewBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -79,16 +74,6 @@ class NoteFragment : QwarkFragment(), NoteAdapter.OnNoteClickListener, OnBackPre
binding.recyclerView.addFabScrollListener()
}
- override fun onResume() {
- super.onResume()
- binding.recyclerView.applyPadding(horizontalPadding = 4)
- }
-
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
override fun onBackPressed(): Boolean {
return if (isInCategoryView) {
sortByCategory("")
diff --git a/app/src/main/java/com/denizd/qwark/fragment/ParticipationCourseFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/ParticipationCourseFragment.kt
index d725921..27013de 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/ParticipationCourseFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/ParticipationCourseFragment.kt
@@ -9,6 +9,7 @@ import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.adapter.ParticipationAdapter
import com.denizd.qwark.databinding.GradeFragmentBinding
@@ -19,10 +20,9 @@ import com.denizd.qwark.viewmodel.ParticipationCourseViewModel
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.snackbar.Snackbar
-class ParticipationCourseFragment : QwarkFragment(), ParticipationAdapter.ParticipationClickListener {
+class ParticipationCourseFragment : QwarkFragment(R.layout.grade_fragment), ParticipationAdapter.ParticipationClickListener {
- private var _binding: GradeFragmentBinding? = null
- private val binding: GradeFragmentBinding get() = _binding!!
+ private val binding: GradeFragmentBinding by viewBinding(GradeFragmentBinding::bind)
private var course: String = ""
private var courseId: Int = 0
private var advanced: Boolean = false
@@ -55,11 +55,6 @@ class ParticipationCourseFragment : QwarkFragment(), ParticipationAdapter.Partic
})
}
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = GradeFragmentBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -99,16 +94,6 @@ class ParticipationCourseFragment : QwarkFragment(), ParticipationAdapter.Partic
binding.average.text = averageText
}
- override fun onResume() {
- super.onResume()
- binding.paddingView.applyPadding()
- }
-
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
override fun onParticipationClick(participation: Participation) {
if (participation.time > System.currentTimeMillis() - 1000 * 60 * 90) {
openBottomSheet(ClassSessionSheet().also { sheet ->
diff --git a/app/src/main/java/com/denizd/qwark/fragment/ParticipationFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/ParticipationFragment.kt
index de714e1..2973a65 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/ParticipationFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/ParticipationFragment.kt
@@ -10,6 +10,7 @@ import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.StaggeredGridLayoutManager
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.adapter.CourseAdapter
import com.denizd.qwark.databinding.PaddedRecyclerViewBinding
@@ -19,10 +20,9 @@ import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.ParticipationLinkSheet
import com.denizd.qwark.viewmodel.ParticipationViewModel
-internal class ParticipationFragment : QwarkFragment(), CourseAdapter.CourseClickListener {
+internal class ParticipationFragment : QwarkFragment(R.layout.padded_recycler_view), CourseAdapter.CourseClickListener {
- private var _binding: PaddedRecyclerViewBinding? = null
- private val binding: PaddedRecyclerViewBinding get() = _binding!!
+ private val binding: PaddedRecyclerViewBinding by viewBinding(PaddedRecyclerViewBinding::bind)
private lateinit var viewModel: ParticipationViewModel
private val recyclerViewAdapter = CourseAdapter(ArrayList(), this, null, true)
@@ -59,11 +59,6 @@ internal class ParticipationFragment : QwarkFragment(), CourseAdapter.CourseClic
})
}
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = PaddedRecyclerViewBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -85,16 +80,6 @@ internal class ParticipationFragment : QwarkFragment(), CourseAdapter.CourseClic
}
}
- override fun onResume() {
- super.onResume()
- binding.recyclerView.applyPadding(horizontalPadding = 4)
- }
-
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
override fun onCourseClick(course: CourseExam) {
appBar.setExpanded(true)
(context as FragmentActivity).supportFragmentManager.beginTransaction()
diff --git a/app/src/main/java/com/denizd/qwark/fragment/QwarkFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/QwarkFragment.kt
index ab5de22..a64825d 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/QwarkFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/QwarkFragment.kt
@@ -6,7 +6,9 @@ import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.widget.TextView
+import androidx.annotation.LayoutRes
import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
@@ -15,7 +17,7 @@ import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
-open class QwarkFragment : Fragment() {
+open class QwarkFragment(@LayoutRes layoutId: Int) : Fragment(layoutId) {
private lateinit var _context: Context
@@ -32,7 +34,6 @@ open class QwarkFragment : Fragment() {
appBarTitleView.text = value
field = value
}
- private lateinit var statusBarView: View
lateinit var appBar: AppBarLayout
lateinit var snackBarContainer: CoordinatorLayout
lateinit var fab: ExtendedFloatingActionButton
@@ -49,12 +50,17 @@ open class QwarkFragment : Fragment() {
/**
* Initialise view resources
*/
- statusBarView = view.rootView.findViewById(R.id.status_bar_view)
appBarTitleView = view.rootView.findViewById(R.id.app_bar_title)
superTitleView = view.rootView.findViewById(R.id.super_title)
appBar = view.rootView.findViewById(R.id.app_bar_layout)
snackBarContainer = view.rootView.findViewById(R.id.root_view)
fab = view.rootView.findViewById(R.id.fab)
+
+ if (this is GradeFragment || this is ParticipationCourseFragment) {
+ snackBarContainer.resetBottomPadding()
+ } else {
+ snackBarContainer.applyBottomPadding()
+ }
}
/**
@@ -88,19 +94,21 @@ open class QwarkFragment : Fragment() {
})
}
- /**
- * This function must not be invoked in onViewCreated, as the view will not have been attached
- * to its lifecycle owner and therefore cannot calculate the top padding properly. Invoke in
- * onResume instead.
- */
- protected fun T.applyPadding(horizontalPadding: Int = 0) {
- val horizontal = horizontalPadding.dpToPx()
- setPadding(
- horizontal,
- (statusBarView.height / 1) + appBar.height,
- horizontal,
- 0
- )
+ protected fun NestedScrollView.addFabScrollListener() {
+ setOnScrollChangeListener { _, _, dy, _, doy ->
+ when {
+ dy > doy -> fab.hide()
+ dy < doy -> fab.show()
+ }
+ }
+ }
+
+ private fun T.resetBottomPadding() {
+ setPadding(paddingLeft, paddingTop, paddingRight, 0)
+ }
+
+ private fun T.applyBottomPadding() {
+ setPadding(paddingLeft, paddingTop, paddingRight, 56.dpToPx())
}
/**
diff --git a/app/src/main/java/com/denizd/qwark/fragment/SettingsFragment.kt b/app/src/main/java/com/denizd/qwark/fragment/SettingsFragment.kt
index 8a61540..82a092f 100644
--- a/app/src/main/java/com/denizd/qwark/fragment/SettingsFragment.kt
+++ b/app/src/main/java/com/denizd/qwark/fragment/SettingsFragment.kt
@@ -1,12 +1,11 @@
package com.denizd.qwark.fragment
import android.os.Bundle
-import android.view.LayoutInflater
import android.view.View
-import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.sheet.ConfirmDeletionSheet
import com.denizd.qwark.sheet.CopyCoursesSheet
@@ -17,17 +16,11 @@ import com.denizd.qwark.model.SchoolYear
import com.denizd.qwark.viewmodel.SettingsViewModel
import com.google.android.material.snackbar.Snackbar
-class SettingsFragment : QwarkFragment() {
+class SettingsFragment : QwarkFragment(R.layout.settings_fragment) {
- private var _binding: SettingsFragmentBinding? = null
- private val binding: SettingsFragmentBinding get() = _binding!!
+ private val binding: SettingsFragmentBinding by viewBinding(SettingsFragmentBinding::bind)
private val viewModel: SettingsViewModel by viewModels()
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = SettingsFragmentBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -94,7 +87,7 @@ class SettingsFragment : QwarkFragment() {
)
)
try {
- setText(viewModel.getCurrentSchoolYear(), false)
+ setText(viewModel.getSchoolYearName(), false)
} catch (e: IndexOutOfBoundsException) {
// do nothing if no school years exist or none has been selected
}
@@ -212,16 +205,6 @@ class SettingsFragment : QwarkFragment() {
}
}
- override fun onResume() {
- super.onResume()
- binding.settingsScrollView.applyPadding()
- }
-
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
-
fun copyCourses(yearId: Int) {
viewModel.copyCourses(yearId)
Snackbar
diff --git a/app/src/main/java/com/denizd/qwark/sheet/ClassSessionSheet.kt b/app/src/main/java/com/denizd/qwark/sheet/ClassSessionSheet.kt
index b5f9fdf..9238c84 100644
--- a/app/src/main/java/com/denizd/qwark/sheet/ClassSessionSheet.kt
+++ b/app/src/main/java/com/denizd/qwark/sheet/ClassSessionSheet.kt
@@ -9,18 +9,16 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
+import com.denizd.lawrence.util.viewBinding
import com.denizd.qwark.R
import com.denizd.qwark.databinding.ClassSessionSheetBinding
import com.denizd.qwark.fragment.ParticipationCourseFragment
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlin.random.Random
-class ClassSessionSheet : BottomSheetDialogFragment() {
+class ClassSessionSheet : QwarkSheet(R.layout.class_session_sheet) {
- private var _binding: ClassSessionSheetBinding? = null
- private val binding: ClassSessionSheetBinding get() = _binding!!
-
- private lateinit var mContext: Context
+ private val binding: ClassSessionSheetBinding by viewBinding(ClassSessionSheetBinding::bind)
private lateinit var participationFragment: ParticipationCourseFragment
private var timesHandRaised: Int = 0
@@ -36,16 +34,6 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
private var participationId = -1
private val time: Long = System.currentTimeMillis()
- override fun onAttach(context: Context) {
- super.onAttach(context)
- mContext = context
- }
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- _binding = ClassSessionSheetBinding.inflate(inflater, container, false)
- return binding.root
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -61,7 +49,7 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
binding.handRaisedButton.apply {
setCompoundDrawables(context.getDrawable(R.drawable.hand)?.also { drawable ->
drawable.bounds = Rect(0, 0, 256, 256)
- drawable.setTint(mContext.getColor(R.color.colorAccent))
+ drawable.setTint(context.getColor(R.color.colorAccent))
}, null, null, null)
text = "$timesHandRaised"
setOnClickListener {
@@ -78,7 +66,7 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
binding.spokenButton.apply {
setCompoundDrawables(context.getDrawable(R.drawable.speech)?.also { drawable ->
drawable.bounds = Rect(0, 0, 256, 256)
- drawable.setTint(mContext.getColor(R.color.colorAccent))
+ drawable.setTint(context.getColor(R.color.colorAccent))
}, null, null, null)
text = "$timesSpoken"
setOnClickListener {
@@ -102,7 +90,7 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
}
}
- binding.finishButton.apply {
+ binding.saveButton.apply {
setOnClickListener {
makeToast(R.string.long_press_to_finish)
}
@@ -124,14 +112,10 @@ class ClassSessionSheet : BottomSheetDialogFragment() {
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
- override fun onDestroy() {
- super.onDestroy()
- _binding = null
- }
private fun makeToast(stringResource: Int) {
Toast
- .makeText(mContext, getString(stringResource), Toast.LENGTH_LONG)
+ .makeText(context, getString(stringResource), Toast.LENGTH_LONG)
.show()
}
diff --git a/app/src/main/java/com/denizd/qwark/sheet/FinalGradeTableSheet.kt b/app/src/main/java/com/denizd/qwark/sheet/FinalGradeTableSheet.kt
new file mode 100644
index 0000000..9ed6645
--- /dev/null
+++ b/app/src/main/java/com/denizd/qwark/sheet/FinalGradeTableSheet.kt
@@ -0,0 +1,38 @@
+package com.denizd.qwark.sheet
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.denizd.qwark.R
+import com.denizd.qwark.databinding.TextSheetBinding
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+
+class FinalGradeTableSheet : BottomSheetDialogFragment() {
+
+ private var _binding: TextSheetBinding? = null
+ private val binding: TextSheetBinding get() = _binding!!
+ private lateinit var mContext: Context
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ mContext = context
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ _binding = TextSheetBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ binding.title.text = mContext.getString(R.string.points_to_grade_conversion_title)
+ binding.content.text = mContext.getString(R.string.points_to_grade_conversion)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/sheet/GradeCreateSheet.kt b/app/src/main/java/com/denizd/qwark/sheet/GradeCreateSheet.kt
index ba4a19b..dd7af43 100644
--- a/app/src/main/java/com/denizd/qwark/sheet/GradeCreateSheet.kt
+++ b/app/src/main/java/com/denizd/qwark/sheet/GradeCreateSheet.kt
@@ -119,7 +119,7 @@ class GradeCreateSheet : BottomSheetDialogFragment() {
note = binding.noteEditText.text.toString(),
time = if (::grade.isInitialized) grade.time else System.currentTimeMillis(),
gradeId = if (::grade.isInitialized) grade.gradeId else 0,
- courseId = courseId,
+ courseId = if (::grade.isInitialized) grade.courseId else courseId,
examTime = if (binding.examSwitch.isChecked) examDate else -1L
)
if (::grade.isInitialized) {
diff --git a/app/src/main/java/com/denizd/qwark/sheet/HistoricalAverageSheet.kt b/app/src/main/java/com/denizd/qwark/sheet/HistoricalAverageSheet.kt
index 3682e7e..7b00af6 100644
--- a/app/src/main/java/com/denizd/qwark/sheet/HistoricalAverageSheet.kt
+++ b/app/src/main/java/com/denizd/qwark/sheet/HistoricalAverageSheet.kt
@@ -37,7 +37,7 @@ class HistoricalAverageSheet : BottomSheetDialogFragment() {
binding.title.text = getString(R.string.averages_for_course, arguments?.getString("courseName"))
binding.recyclerView.apply {
layoutManager = GridLayoutManager(context, 1)
- adapter = HistoricalAverageAdapter(data)
+ adapter = HistoricalAverageAdapter(data, targetFragment.getGradeType())
}
}
diff --git a/app/src/main/java/com/denizd/qwark/sheet/QwarkSheet.kt b/app/src/main/java/com/denizd/qwark/sheet/QwarkSheet.kt
new file mode 100644
index 0000000..b5e6b8d
--- /dev/null
+++ b/app/src/main/java/com/denizd/qwark/sheet/QwarkSheet.kt
@@ -0,0 +1,24 @@
+package com.denizd.qwark.sheet
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.annotation.LayoutRes
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+
+open class QwarkSheet(@LayoutRes private val layoutId: Int) : BottomSheetDialogFragment() {
+
+ private lateinit var _context: Context
+
+ override fun getContext(): Context = _context
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ _context = context
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
+ LayoutInflater.from(context).inflate(layoutId, container, false)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/sheet/TextInputSheet.kt b/app/src/main/java/com/denizd/qwark/sheet/TextInputSheet.kt
index 47e1203..c3249fe 100644
--- a/app/src/main/java/com/denizd/qwark/sheet/TextInputSheet.kt
+++ b/app/src/main/java/com/denizd/qwark/sheet/TextInputSheet.kt
@@ -10,7 +10,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
open class TextInputSheet : BottomSheetDialogFragment() {
- protected var _binding: TextInputSheetBinding? = null
+ private var _binding: TextInputSheetBinding? = null
protected val binding: TextInputSheetBinding get() = _binding!!
private lateinit var mContext: Context
diff --git a/app/src/main/java/com/denizd/qwark/util/ActivityViewBindingDelegate.kt b/app/src/main/java/com/denizd/qwark/util/ActivityViewBindingDelegate.kt
new file mode 100644
index 0000000..c09df70
--- /dev/null
+++ b/app/src/main/java/com/denizd/qwark/util/ActivityViewBindingDelegate.kt
@@ -0,0 +1,12 @@
+package com.denizd.lawrence.util
+
+import android.view.LayoutInflater
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.FragmentActivity
+import androidx.viewbinding.ViewBinding
+
+// written by Zhuinden (props to them!)
+inline fun FragmentActivity.viewBinding(crossinline bindingInflater: (LayoutInflater) -> T) =
+ lazy(LazyThreadSafetyMode.NONE) {
+ bindingInflater.invoke(layoutInflater)
+ }
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/util/Dependencies.kt b/app/src/main/java/com/denizd/qwark/util/Dependencies.kt
new file mode 100644
index 0000000..8d5ab67
--- /dev/null
+++ b/app/src/main/java/com/denizd/qwark/util/Dependencies.kt
@@ -0,0 +1,7 @@
+package com.denizd.qwark.util
+
+import com.denizd.qwark.database.QwarkRepository
+
+object Dependencies {
+ lateinit var repo: QwarkRepository
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/util/FragmentViewBindingDelegate.kt b/app/src/main/java/com/denizd/qwark/util/FragmentViewBindingDelegate.kt
new file mode 100644
index 0000000..2b2668b
--- /dev/null
+++ b/app/src/main/java/com/denizd/qwark/util/FragmentViewBindingDelegate.kt
@@ -0,0 +1,50 @@
+package com.denizd.lawrence.util
+
+import android.view.View
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.observe
+import androidx.viewbinding.ViewBinding
+import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.KProperty
+
+// written by Zhuinden (props to them!)
+class FragmentViewBindingDelegate(
+ val fragment: Fragment,
+ val viewBindingFactory: (View) -> T
+) : ReadOnlyProperty {
+ private var _binding: T? = null
+
+ init {
+ fragment.lifecycle.addObserver(object : DefaultLifecycleObserver {
+ override fun onCreate(owner: LifecycleOwner) {
+ fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewLifecycleOwner ->
+ viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
+ override fun onDestroy(owner: LifecycleOwner) {
+ _binding = null
+ }
+ })
+ }
+ }
+ })
+ }
+
+ override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
+ val binding = _binding
+ if (binding != null) {
+ return binding
+ }
+
+ val lifecycle = fragment.viewLifecycleOwner.lifecycle
+ if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
+ throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.")
+ }
+
+ return viewBindingFactory(thisRef.requireView()).also { _binding = it }
+ }
+}
+
+fun Fragment.viewBinding(viewBindingFactory: (View) -> T) =
+ FragmentViewBindingDelegate(this, viewBindingFactory)
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/util/PreferenceKey.kt b/app/src/main/java/com/denizd/qwark/util/PreferenceKey.kt
index bf84ac0..c763ae4 100644
--- a/app/src/main/java/com/denizd/qwark/util/PreferenceKey.kt
+++ b/app/src/main/java/com/denizd/qwark/util/PreferenceKey.kt
@@ -17,5 +17,6 @@ enum class PreferenceKey(val value: String) {
PARTICIPATION_DAY("participation_day"),
// Bools
- SHOW_GRADE_AVERAGE("show_grade_average")
+ SHOW_GRADE_AVERAGE("show_grade_average"),
+ FIRST_LAUNCH("first_launch")
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/util/QwarkPreferences.kt b/app/src/main/java/com/denizd/qwark/util/QwarkPreferences.kt
index 773f8d7..8a6f506 100644
--- a/app/src/main/java/com/denizd/qwark/util/QwarkPreferences.kt
+++ b/app/src/main/java/com/denizd/qwark/util/QwarkPreferences.kt
@@ -4,51 +4,48 @@ import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager
-class QwarkPreferences private constructor(context: Context) {
+class QwarkPreferences(context: Context) {
private val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
private val edit: SharedPreferences.Editor = prefs.edit()
- companion object {
- private var qwarkPrefs: QwarkPreferences? = null
- fun getPrefs(context: Context): QwarkPreferences {
- if (qwarkPrefs == null) {
- synchronized (QwarkPreferences::class) {
- qwarkPrefs = QwarkPreferences(context)
- }
- }
- return qwarkPrefs!!
- }
- }
-
fun getString(key: PreferenceKey, default: String = ""): String = prefs.getString(key.value, default) ?: default
fun getInt(key: PreferenceKey, default: Int = 0): Int = prefs.getInt(key.value, default)
fun getBool(key: PreferenceKey, default: Boolean = false): Boolean = prefs.getBoolean(key.value, default)
- fun putString(key: PreferenceKey, value: String): QwarkPreferences {
+ fun setString(key: PreferenceKey, value: String): QwarkPreferences {
edit.putString(key.value, value).apply()
return this
}
- fun putInt(key: PreferenceKey, value: Int): QwarkPreferences {
+ fun setInt(key: PreferenceKey, value: Int): QwarkPreferences {
edit.putInt(key.value, value).apply()
return this
}
- fun putBool(key: PreferenceKey, value: Boolean): QwarkPreferences {
+ fun setBool(key: PreferenceKey, value: Boolean): QwarkPreferences {
edit.putBoolean(key.value, value).apply()
return this
}
+ // TODO remove all of these
fun getShowGradeAverage(): Boolean = getBool(PreferenceKey.SHOW_GRADE_AVERAGE)
fun getGradeType(): Int = getInt(PreferenceKey.GRADE_TYPE)
fun getCourseSortType(): Int = getInt(PreferenceKey.COURSE_SORT_TYPE, 1)
- fun setCourseSortType(value: Int) { putInt(PreferenceKey.COURSE_SORT_TYPE, value) }
fun getSchoolYear(): Int = getInt(PreferenceKey.SCHOOL_YEAR_ID)
fun getSchoolYearName(): String = getString(PreferenceKey.SCHOOL_YEAR_NAME)
fun getScoreProfileName(): String = getString(PreferenceKey.SCORE_PROFILE_NAME)
fun getScoreProfileId(): Int = getInt(PreferenceKey.SCORE_PROFILE_ID)
fun getParticipationDisplay(): Int = getInt(PreferenceKey.PARTICIPATION_DISPLAY)
fun getParticipationDay(): Int = getInt(PreferenceKey.PARTICIPATION_DAY)
+ fun getAppTheme(): Int = getInt(PreferenceKey.APP_THEME, 2)
+ fun getFinalScoreId(): Int = getInt(PreferenceKey.SCORE_PROFILE_ID)
+ fun getFirstLaunch(): Boolean = getBool(PreferenceKey.FIRST_LAUNCH)
+ fun getCurrentSchoolYearId(): Int = getInt(PreferenceKey.SCHOOL_YEAR_ID)
- fun setParticipationDisplay(value: Int) { putInt(PreferenceKey.PARTICIPATION_DISPLAY, value) }
- fun setParticipationDay(value: Int) { putInt(PreferenceKey.PARTICIPATION_DAY, value) }
+ fun setCourseSortType(value: Int) { setInt(PreferenceKey.COURSE_SORT_TYPE, value) }
+ fun setParticipationDisplay(value: Int) { setInt(PreferenceKey.PARTICIPATION_DISPLAY, value) }
+ fun setParticipationDay(value: Int) { setInt(PreferenceKey.PARTICIPATION_DAY, value) }
+ fun setAppTheme(value: Int) { setInt(PreferenceKey.APP_THEME, value) }
+ fun setFirstLaunch(value: Boolean) { setBool(PreferenceKey.FIRST_LAUNCH, value) }
+ fun setShowGradeAverage(value: Boolean) { setBool(PreferenceKey.SHOW_GRADE_AVERAGE, value) }
+ fun setGradeType(value: Int) { setInt(PreferenceKey.GRADE_TYPE, value) }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/CourseViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/CourseViewModel.kt
index 3fac0fc..ed6af2b 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/CourseViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/CourseViewModel.kt
@@ -2,32 +2,29 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.LiveData
-import com.denizd.qwark.database.CourseRepository
import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.model.HistoricalAvg
-import com.denizd.qwark.util.QwarkPreferences
class CourseViewModel(application: Application) : QwarkViewModel(application) {
- private val repo = CourseRepository(application)
- private val prefs: QwarkPreferences = QwarkPreferences.getPrefs(application)
- val allCourses: LiveData> = repo.getCoursesByYearId(getSchoolYear())
+ val allCourses: LiveData> = repo.getCoursesByYearId(repo.prefs.getSchoolYear())
- fun getShowGradeAverage(): Boolean = prefs.getShowGradeAverage()
- fun getGradeType(): Int = prefs.getGradeType()
- fun getCourseSortType(): Int = prefs.getCourseSortType()
- fun getSchoolYear(): Int = prefs.getSchoolYear()
- fun getSchoolYearName(): String = prefs.getSchoolYearName()
+ fun getShowGradeAverage(): Boolean = repo.prefs.getShowGradeAverage()
+ fun getGradeType(): Int = repo.prefs.getGradeType()
+ fun getCourseSortType(): Int = repo.prefs.getCourseSortType()
+ fun getSchoolYear(): Int = repo.prefs.getSchoolYear()
+ fun getSchoolYearName(): String = repo.prefs.getSchoolYearName()
- fun insert(avg: HistoricalAvg) = doAsync { repo.insert(avg) }
fun getAveragesForCourses(courseId: Int): List = returnBlocking {
repo.getAveragesForCourses(courseId)
}
fun insert(course: Course) = doAsync { repo.insert(course) }
+ fun insert(historicalAvg: HistoricalAvg) = doAsync { repo.insert(historicalAvg) }
fun update(course: Course) = doAsync { repo.update(course) }
fun delete(course: Course) = doAsync { repo.delete(course) }
+
fun getCourse(courseId: Int): CourseExam = returnBlocking { repo.getCourse(courseId) }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/FinalsViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/FinalsViewModel.kt
index 7eeaecc..0038379 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/FinalsViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/FinalsViewModel.kt
@@ -3,7 +3,6 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
-import com.denizd.qwark.database.FinalsRepository
import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.model.FinalGrade
import com.denizd.qwark.model.SchoolYear
@@ -13,8 +12,7 @@ import java.lang.NumberFormatException
class FinalsViewModel(app: Application) : QwarkViewModel(app) {
- private val repo = FinalsRepository(app)
- val allFinalGrades: LiveData> = repo.getFinalGrades(repo.getFinalScoreId())
+ val allFinalGrades: LiveData> = repo.getFinalGrades(repo.prefs.getFinalScoreId())
fun update(finalGrade: FinalGrade) = viewModelScope.launch {
withContext(Dispatchers.IO) {
@@ -24,8 +22,8 @@ class FinalsViewModel(app: Application) : QwarkViewModel(app) {
fun getSchoolYearName(courseId: Int) = returnBlocking { repo.getSchoolYearName(courseId) }
- fun getScoreProfileName(): String = repo.getScoreProfileName()
- fun getGradeType(): Int = repo.getGradeType()
+ fun getScoreProfileName(): String = repo.prefs.getScoreProfileName()
+ fun getGradeType(): Int = repo.prefs.getGradeType()
fun getFinalScore(basicGrades: List, advancedGrades: List, examGrades: List): Int = try {
var finalScore = 0
@@ -109,5 +107,5 @@ class FinalsViewModel(app: Application) : QwarkViewModel(app) {
fun getCourse(courseId: Int) = returnBlocking { repo.getCourse(courseId) }
fun getFinalGrade(finalGradeId: Int) = returnBlocking { repo.getFinalGrade(finalGradeId) }
- fun getCourseSortType() = repo.getCourseSortType()
+ fun getCourseSortType() = repo.prefs.getCourseSortType()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/GradeViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/GradeViewModel.kt
index 9e4292e..342d47a 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/GradeViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/GradeViewModel.kt
@@ -2,14 +2,12 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.LiveData
-import com.denizd.qwark.database.GradeRepository
import com.denizd.qwark.model.Grade
import com.denizd.qwark.model.HistoricalAvg
class GradeViewModel(application: Application) : QwarkViewModel(application) {
- private val repo = GradeRepository(application)
- fun getGradeType(): Int = repo.getGradeType()
+ fun getGradeType(): Int = repo.prefs.getGradeType()
fun getCourse(courseId: Int) = returnBlocking { repo.getCourse(courseId) }
@@ -22,7 +20,7 @@ class GradeViewModel(application: Application) : QwarkViewModel(application) {
fun updateAverage(average: String, gradeCount: Int, courseId: Int) = doAsync {
repo.updateAverage(average, gradeCount, courseId)
}
- fun delete(gradeId: Int) = doAsync { repo.delete(gradeId) }
+ fun deleteGrade(gradeId: Int) = doAsync { repo.deleteGrade(gradeId) }
fun insert(avg: HistoricalAvg) = doAsync { repo.insert(avg) }
fun getGrade(gradeId: Int) = returnBlocking { repo.getGrade(gradeId) }
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/MainViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/MainViewModel.kt
index c3a237d..1ed02f3 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/MainViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/MainViewModel.kt
@@ -2,23 +2,24 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import android.content.Context
+import android.util.Log
import android.view.Window
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.ContextCompat
import androidx.lifecycle.AndroidViewModel
import androidx.preference.PreferenceManager
import com.denizd.qwark.R
+import com.denizd.qwark.database.QwarkRepository
import com.denizd.qwark.fragment.*
import com.denizd.qwark.fragment.CourseFragment
import com.denizd.qwark.fragment.FinalsFragment
import com.denizd.qwark.fragment.NoteFragment
import com.denizd.qwark.fragment.ParticipationFragment
import com.denizd.qwark.fragment.SettingsFragment
+import com.denizd.qwark.util.Dependencies
import com.denizd.qwark.util.QwarkUtil
-class MainViewModel(val app: Application) : AndroidViewModel(app) {
-
- private val prefs = PreferenceManager.getDefaultSharedPreferences(app.applicationContext)
+class MainViewModel(val app: Application) : QwarkViewModel(app) {
fun getFragmentType(type: Int): String = when (type) { // TODO replace with Fragment#tag
R.id.courses -> "CourseFragment"
@@ -37,24 +38,25 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) {
}
fun applyTheme(window: Window, context: Context) {
- when (prefs.getInt("dark_mode", 2)) {
- 0 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
- 1 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
- else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
+ AppCompatDelegate.setDefaultNightMode(when (repo.prefs.getAppTheme()) {
+ 0 -> AppCompatDelegate.MODE_NIGHT_NO
+ 1 -> AppCompatDelegate.MODE_NIGHT_YES
+ else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
+ })
+ ContextCompat.getColor(context, R.color.colorBackground).also { barColour ->
+ window.navigationBarColor = barColour
+ window.statusBarColor = barColour
}
- val barColour = ContextCompat.getColor(context, R.color.colorBackground)
- window.navigationBarColor = barColour
- window.statusBarColor = barColour
}
fun checkForFirstTimeYearNotice(context: Context) {
- if (prefs.getBoolean("first_launch", true)) {
+ if (repo.prefs.getFirstLaunch()) {
QwarkUtil.createInfoDialog(
context,
app.getString(R.string.alert_create_school_year_title),
app.getString(R.string.alert_create_school_year_desc)
)
- prefs.edit().putBoolean("first_launch", false).apply()
+ repo.prefs.setFirstLaunch(false)
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/NoteViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/NoteViewModel.kt
index 87a23c5..b791f70 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/NoteViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/NoteViewModel.kt
@@ -2,18 +2,12 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.*
-import com.denizd.qwark.database.NoteRepository
import com.denizd.qwark.model.Note
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withContext
class NoteViewModel(application: Application) : QwarkViewModel(application) {
- private val repo = NoteRepository(application)
private val reloadTrigger = MutableLiveData()
- val allNotes: LiveData>? = Transformations.switchMap(reloadTrigger) { category ->
+ val allNotes: LiveData> = Transformations.switchMap(reloadTrigger) { category ->
if (category == "") {
repo.allNotes
} else {
@@ -21,60 +15,19 @@ class NoteViewModel(application: Application) : QwarkViewModel(application) {
}
}
- init {
- refresh("")
- }
+ init { refresh("") }
- fun refresh(category: String) {
- reloadTrigger.value = category
- }
+ fun refresh(category: String) { reloadTrigger.value = category }
- fun insert(note: Note) {
- viewModelScope.launch {
- withContext(Dispatchers.IO) {
- repo.insert(note)
- }
- }
- }
+ fun insert(note: Note) = doAsync { repo.insert(note) }
- fun updateDismissedStatus(newDismissedStatus: Boolean, noteId: Int) {
- viewModelScope.launch {
- withContext(Dispatchers.IO) {
- repo.updateDismissed(newDismissedStatus, noteId)
- }
- }
- }
+ fun updateDismissedStatus(newDismissedStatus: Boolean, noteId: Int) = doAsync { repo.updateDismissed(newDismissedStatus, noteId) }
- fun delete(noteId: Int) {
- viewModelScope.launch {
- withContext(Dispatchers.IO) {
- repo.delete(noteId)
- }
- }
- }
+ fun delete(noteId: Int) = doAsync { repo.deleteNote(noteId) }
-// // TODO get this as LiveData variable to get changes
-// fun getNotesForCategory(category: String): LiveData>? {
-// return runBlocking {
-// withContext(Dispatchers.IO) {
-// repo.notesForCategory(category)
-// }
-// }
-// }
+ fun update(note: Note) = doAsync { repo.update(note) }
- fun update(note: Note) {
- viewModelScope.launch {
- withContext(Dispatchers.IO) {
- repo.update(note)
- }
- }
- }
-
- fun getAllCategories(): List = runBlocking {
- withContext(Dispatchers.IO) {
- repo.getAllCategories()
- }
- }
+ fun getAllCategories(): List = returnBlocking { repo.getAllCategories() }
fun getNote(noteId: Int) = returnBlocking { repo.getNote(noteId) }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationCourseViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationCourseViewModel.kt
index e0179ff..ad1b6cf 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationCourseViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationCourseViewModel.kt
@@ -2,13 +2,10 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.LiveData
-import com.denizd.qwark.database.ParticipationRepository
import com.denizd.qwark.model.Participation
class ParticipationCourseViewModel(app: Application) : QwarkViewModel(app) {
- private val repo = ParticipationRepository(app)
-
fun getAllParticipationsForCourse(courseId: Int): LiveData> = returnBlocking {
repo.getAllParticipationsForCourse(courseId)
}
@@ -22,6 +19,6 @@ class ParticipationCourseViewModel(app: Application) : QwarkViewModel(app) {
fun createParticipation(timesHandRaised: Int, timesSpoken: Int, time: Long, courseId: Int) = doAsync {
repo.insert(timesHandRaised, timesSpoken, time, courseId)
}
- fun getSchoolYearName() = repo.getSchoolYearName()
+ fun getSchoolYearName() = repo.prefs.getSchoolYearName()
fun delete(participation: Participation) = doAsync { repo.delete(participation) }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationViewModel.kt
index 4f238fb..8a8d80c 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/ParticipationViewModel.kt
@@ -2,15 +2,12 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.LiveData
-import com.denizd.qwark.database.ParticipationRepository
import com.denizd.qwark.model.Course
import com.denizd.qwark.model.CourseExam
import com.denizd.qwark.model.Participation
-import com.denizd.qwark.model.SchoolDay
class ParticipationViewModel(app: Application) : QwarkViewModel(app) {
- private val repo = ParticipationRepository(app)
val allCoursesForToday: LiveData> = repo.allCoursesForToday
val dayId: Int = repo.dayId
@@ -18,5 +15,5 @@ class ParticipationViewModel(app: Application) : QwarkViewModel(app) {
fun link(courseId: Int) = doAsync { repo.link(courseId) }
fun removeLink(relationId: Int) = doAsync { repo.removeLink(relationId) }
fun delete(participation: Participation) = doAsync { repo.delete(participation) }
- fun getSchoolYearName() = repo.getSchoolYearName()
+ fun getSchoolYearName() = repo.prefs.getSchoolYearName()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/QwarkViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/QwarkViewModel.kt
index a27222a..3d943b2 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/QwarkViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/QwarkViewModel.kt
@@ -3,24 +3,23 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
+import com.denizd.qwark.database.QwarkRepository
+import com.denizd.qwark.util.Dependencies
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withContext
open class QwarkViewModel(app: Application) : AndroidViewModel(app) {
- fun doAsync(function: () -> Unit) {
- viewModelScope.launch {
- withContext(Dispatchers.IO) {
- function()
- }
- }
- }
+ protected val repo: QwarkRepository = Dependencies.repo
- fun returnBlocking(function: () -> T): T = runBlocking {
- withContext(Dispatchers.IO) {
+ fun doAsync(function: () -> Unit) {
+ viewModelScope.launch(Dispatchers.IO) {
function()
}
}
+
+ fun returnBlocking(function: () -> T): T = runBlocking(Dispatchers.IO) {
+ function()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/denizd/qwark/viewmodel/SettingsViewModel.kt b/app/src/main/java/com/denizd/qwark/viewmodel/SettingsViewModel.kt
index bdcab67..7bb8812 100644
--- a/app/src/main/java/com/denizd/qwark/viewmodel/SettingsViewModel.kt
+++ b/app/src/main/java/com/denizd/qwark/viewmodel/SettingsViewModel.kt
@@ -3,38 +3,34 @@ package com.denizd.qwark.viewmodel
import android.app.Application
import androidx.lifecycle.LiveData
import com.denizd.qwark.database.QwarkClient
-import com.denizd.qwark.util.QwarkPreferences
-import com.denizd.qwark.database.SettingsRepository
import com.denizd.qwark.model.ScoreProfile
import com.denizd.qwark.model.SchoolYear
class SettingsViewModel(private val app: Application) : QwarkViewModel(app) {
- private val repo = SettingsRepository(app)
val allYears: LiveData> = repo.allYears
val allScoreProfiles: LiveData> = repo.allScoreProfiles
- private val prefs: QwarkPreferences = QwarkPreferences.getPrefs(app.applicationContext)
// Preference getters
- fun getAppTheme() = repo.getAppTheme()
- fun getShowGradeAverage() = repo.getShowGradeAverage()
- fun getCourseSortType(): Int = prefs.getCourseSortType()
- fun getGradeType() = repo.getGradeType()
- fun getScoreProfileName() = repo.getScoreProfileName()
- fun getCurrentSchoolYear(): String = repo.getCurrentSchoolYear()
- fun getCurrentSchoolYearId(): Int = repo.getCurrentSchoolYearId()
- fun getParticipationDisplay(): Int = repo.getParticipationDisplay()
- fun getParticipationDay(): Int = repo.getParticipationDay()
+ fun getAppTheme() = repo.prefs.getAppTheme()
+ fun getShowGradeAverage() = repo.prefs.getShowGradeAverage()
+ fun getCourseSortType(): Int = repo.prefs.getCourseSortType()
+ fun getGradeType() = repo.prefs.getGradeType()
+ fun getScoreProfileName() = repo.prefs.getScoreProfileName()
+ fun getSchoolYearName(): String = repo.prefs.getSchoolYearName()
+ fun getCurrentSchoolYearId(): Int = repo.prefs.getCurrentSchoolYearId()
+ fun getParticipationDisplay(): Int = repo.prefs.getParticipationDisplay()
+ fun getParticipationDay(): Int = repo.prefs.getParticipationDay()
// Preference setters
- fun setAppTheme(value: Int) { repo.setAppTheme(value) }
- fun setShowGradeAverage(value: Boolean) { repo.setShowGradeAverage(value) }
- fun setCourseSortType(value: Int) { prefs.setCourseSortType(value) }
- fun setGradeType(value: Int) { repo.setGradeType(value) }
+ fun setAppTheme(value: Int) { repo.prefs.setAppTheme(value) }
+ fun setShowGradeAverage(value: Boolean) { repo.prefs.setShowGradeAverage(value) }
+ fun setCourseSortType(value: Int) { repo.prefs.setCourseSortType(value) }
+ fun setGradeType(value: Int) { repo.prefs.setGradeType(value) }
fun setCurrentScoreProfile(scoreProfile: ScoreProfile) { repo.setCurrentScoreProfile(scoreProfile) }
fun updateSchoolYear(schoolYear: SchoolYear) { repo.setCurrentSchoolYear(schoolYear) }
- fun setParticipationDisplay(value: Int) { repo.setParticipationDisplay(value) }
- fun setParticipationDay(value: Int) { repo.setParticipationDay(value) }
+ fun setParticipationDisplay(value: Int) { repo.prefs.setParticipationDisplay(value) }
+ fun setParticipationDay(value: Int) { repo.prefs.setParticipationDay(value) }
// Database functions
fun insert(schoolYear: SchoolYear) = doAsync { repo.insert(schoolYear) }
diff --git a/app/src/main/res/layout-land/finals_fragment.xml b/app/src/main/res/layout-land/finals_fragment.xml
index 60280c6..05e76d1 100644
--- a/app/src/main/res/layout-land/finals_fragment.xml
+++ b/app/src/main/res/layout-land/finals_fragment.xml
@@ -32,6 +32,7 @@
+ android:layout_height="match_parent">
-
+ android:layout_height="84dp"
+ app:elevation="0dp"
+ android:background="@color/colorBackground"
+ android:layout_gravity="top"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
-
-
-
-
-
+ android:layout_height="match_parent"
+ app:contentInsetStart="0dp"
+ android:elevation="0dp"
+ app:layout_scrollFlags="scroll|enterAlwaysCollapsed">
-
+ android:layout_height="match_parent">
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/average_card.xml b/app/src/main/res/layout/average_card.xml
index deda6d1..cc4fdad 100644
--- a/app/src/main/res/layout/average_card.xml
+++ b/app/src/main/res/layout/average_card.xml
@@ -1,13 +1,13 @@
+ android:clickable="true">
diff --git a/app/src/main/res/layout/course_card.xml b/app/src/main/res/layout/course_card.xml
index f0a0e1a..f80e0f7 100644
--- a/app/src/main/res/layout/course_card.xml
+++ b/app/src/main/res/layout/course_card.xml
@@ -1,6 +1,8 @@
-
diff --git a/app/src/main/res/layout/finals_overview_item.xml b/app/src/main/res/layout/finals_overview_item.xml
index 801527a..15b9bde 100644
--- a/app/src/main/res/layout/finals_overview_item.xml
+++ b/app/src/main/res/layout/finals_overview_item.xml
@@ -1,5 +1,6 @@
-
-
+ android:progressBackgroundTint="@color/colorBackground"/>
diff --git a/app/src/main/res/layout/note_card.xml b/app/src/main/res/layout/note_card.xml
index c921b5c..b2f984b 100644
--- a/app/src/main/res/layout/note_card.xml
+++ b/app/src/main/res/layout/note_card.xml
@@ -1,6 +1,8 @@
-
-
+ android:scrollbars="vertical"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/settings_fragment.xml b/app/src/main/res/layout/settings_fragment.xml
index 0701b2b..5af0db2 100644
--- a/app/src/main/res/layout/settings_fragment.xml
+++ b/app/src/main/res/layout/settings_fragment.xml
@@ -20,15 +20,13 @@
android:layoutAnimation="@anim/layout_animation_fall_down">
+ android:layout_marginBottom="3dp">
+ android:layout_marginBottom="3dp">
+ android:layout_marginBottom="3dp">
+ android:layout_marginBottom="3dp">
+ android:importantForAutofill="no">
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/year_card.xml b/app/src/main/res/layout/year_card.xml
index 47bb7f6..47aee42 100644
--- a/app/src/main/res/layout/year_card.xml
+++ b/app/src/main/res/layout/year_card.xml
@@ -1,11 +1,12 @@
-
+ android:layout_marginVertical="3dp">
Bearbeiten
Beenden
Erstellen
+ Speichern
Allgemein
Erstelle ein Schuljahr
Bevor du Kurse und Abschlussnoten hinzufügst, gehe in die Einstellungen und erstelle ein Schuljahr und ein Abschlussprofil!
@@ -138,6 +139,8 @@
Note kann nicht gelöscht werden; ist bereits leer
Wähle ein Schuljahr
Wähle einen Kurs
+ Umrechnungstabelle
+ Punkte zu Note-Umrechnungstabelle
Einstellungen
diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml
index 359058a..53592f2 100644
--- a/app/src/main/res/values-night/colors.xml
+++ b/app/src/main/res/values-night/colors.xml
@@ -2,7 +2,6 @@
#6abf69
#121212
- #E6121212
#222222
@color/colorAccent
#e0e0e0
@@ -14,4 +13,5 @@
#e0e0e0
@color/colorText
@color/colorText
+ #424242
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index fcdf05c..d4426ca 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,9 +1,8 @@
#388e3c
- #e0e0e0
- #E6e0e0e0
- #f5f5f5
+ #ffffff
+ #e0e0e0
@color/colorAccent
#212121
#757575
@@ -14,6 +13,7 @@
#e0e0e0
@color/colorAccent
@color/colorAccent
+ #bdbdbd
#757575
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1fa9041..434a08c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -11,6 +11,7 @@
Edit
Finish
Create
+ Save
General
Create a school year
Before adding courses and final grades, please do make sure to go into the settings and create a school year and a score profile!
@@ -18,6 +19,12 @@
Powered by Qwark
Made by Deniz
+
+ - Hello %s!
+ - Hi %s!
+ - Hope you\'re doing well, %s.
+
+
Course
Courses
@@ -196,7 +203,9 @@
Grade cannot be cleared; is already empty
Pick a school year
Pick a course
- 900 – 823 –> 1.0\n822 – 805 –> 1.1\n804 – 787 –> 1.2\n786 – 769 –> 1.3\n768 – 751 –> 1.4\n750 – 733 –> 1.5\n732 – 715 –> 1.6\n714 – 697 –> 1.7\n696 – 679 –> 1.8\n678 – 661 –> 1.9\n660 – 643 –> 2.0\n\n642 – 625 –> 2.1\n624 – 607 –> 2.2\n606 – 589 –> 2.3\n588 – 571 –> 2.4\n570 – 553 –> 2.5\n552 – 535 –> 2.6\n534 – 517 –> 2.7\n516 – 499 –> 2.8\n498 – 481 –> 2.9\n480 – 463 –> 3.0\n\n462 – 445 –> 3.1\n444 – 427 –> 3.2\n426 – 409 –> 3.3\n408 – 391 –> 3.4\n390 – 373 –> 3.5\n372 – 355 –> 3.6\n354 – 337 –> 3.7\n336 – 319 –> 3.8\n318 – 301 –> 3.9\n300 –> 4.0
+ Conversion table
+ Points to grade conversion table
+ 900 – 823 → 1.0\n822 – 805 → 1.1\n804 – 787 → 1.2\n786 – 769 → 1.3\n768 – 751 → 1.4\n750 – 733 → 1.5\n732 – 715 → 1.6\n714 – 697 → 1.7\n696 – 679 → 1.8\n678 – 661 → 1.9\n660 – 643 → 2.0\n\n642 – 625 → 2.1\n624 – 607 → 2.2\n606 – 589 → 2.3\n588 – 571 → 2.4\n570 – 553 → 2.5\n552 – 535 → 2.6\n534 – 517 → 2.7\n516 – 499 → 2.8\n498 – 481 → 2.9\n480 – 463 → 3.0\n\n462 – 445 → 3.1\n444 – 427 → 3.2\n426 – 409 → 3.3\n408 – 391 → 3.4\n390 – 373 → 3.5\n372 – 355 → 3.6\n354 – 337 → 3.7\n336 – 319 → 3.8\n318 – 301 → 3.9\n300 → 4.0
≈ %s
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index b16d4d3..8b75583 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -3,7 +3,7 @@
+
+