Unified repository layer into a single class; added splash screen (WIP); using delegate classes by Zhuinden for view binding; changed UI to more so resemble "Material Design 2"
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class CourseAdapter(private var courses: List<CourseExam>,
|
||||
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)
|
||||
|
||||
|
||||
@@ -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<HistoricalAvg>?) : RecyclerView.Adapter<HistoricalAverageAdapter.AverageViewHolder>() {
|
||||
class HistoricalAverageAdapter(private val averages: List<HistoricalAvg>, private val gradeType: Int) : RecyclerView.Adapter<HistoricalAverageAdapter.AverageViewHolder>() {
|
||||
|
||||
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<HistoricalAvg>) {
|
||||
this.averages = averages
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
// fun setAverages(averages: List<HistoricalAvg>) {
|
||||
// this.averages = averages
|
||||
// notifyDataSetChanged()
|
||||
// }
|
||||
}
|
||||
@@ -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<List<Course>> = dao.allCourses
|
||||
// val allHistoricalAverages: LiveData<List<HistoricalAvg>> = 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<List<CourseExam>> = dao.getCoursesByYearId(yearId)
|
||||
fun getAveragesForCourses(courseId: Int): List<HistoricalAvg> = dao.getAveragesForCourses(courseId)
|
||||
|
||||
fun getCourse(courseId: Int): CourseExam = dao.getCourse(courseId)[0]
|
||||
}
|
||||
@@ -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<List<FinalGrade>> = 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) }
|
||||
}
|
||||
@@ -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<List<Grade>> = dao.getGradesByForeignKey(courseId)
|
||||
fun getGrade(gradeId: Int) = dao.getGrade(gradeId)[0]
|
||||
}
|
||||
@@ -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<List<Note>> = dao.allNotes
|
||||
|
||||
fun getNotesForCategory(category: String): LiveData<List<Note>> = dao.notesForCategory(category)
|
||||
fun getAllCategories(): List<String> = 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]
|
||||
}
|
||||
@@ -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<String> = 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<List<Course>> = dao.getCoursesByDayType(getDayType(), prefs.getSchoolYear())
|
||||
|
||||
fun initParticipationTables() {
|
||||
for (day in days) {
|
||||
dao.insert(SchoolDay(day, 0, prefs.getSchoolYear()))
|
||||
}
|
||||
}
|
||||
|
||||
fun getParticipationCount(participations: List<Participation>) = 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<SchoolDay> = dao.getDays(prefs.getSchoolYear())
|
||||
fun getCourses(): List<CourseExam> = 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<List<Participation>> =
|
||||
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()
|
||||
}
|
||||
@@ -30,7 +30,7 @@ interface QwarkDao {
|
||||
fun getCoursesByYearIdAsList(yearId: Int): List<CourseExam>
|
||||
|
||||
@Query("SELECT *, -1 AS exam_time FROM course WHERE course_id = :courseId")
|
||||
fun getCourse(courseId: Int): List<CourseExam>
|
||||
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<Grade>
|
||||
fun getGrade(gradeId: Int): Grade
|
||||
|
||||
|
||||
// notes
|
||||
@@ -97,7 +97,7 @@ interface QwarkDao {
|
||||
fun getAllCategories(): List<String>
|
||||
|
||||
@Query("SELECT * FROM note WHERE note_id = :noteId")
|
||||
fun getNote(noteId: Int): List<Note>
|
||||
fun getNote(noteId: Int): Note
|
||||
|
||||
|
||||
// historical averages
|
||||
@@ -165,7 +165,7 @@ interface QwarkDao {
|
||||
fun insertAll(finalGrades: Array<FinalGrade>)
|
||||
|
||||
@Query("SELECT * FROM final_grade WHERE final_grade_id = :finalGradeId")
|
||||
fun getFinalGrade(finalGradeId: Int): List<FinalGrade>
|
||||
fun getFinalGrade(finalGradeId: Int): FinalGrade
|
||||
|
||||
|
||||
// school days
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<String> = 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<FinalGrade>()
|
||||
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<FinalGrade>) { 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<List<Note>> = dao.allNotes
|
||||
val allCoursesForToday: LiveData<List<Course>> = dao.getCoursesByDayType(getDayType(), prefs.getSchoolYear())
|
||||
val allYears: LiveData<List<SchoolYear>> = dao.allYears
|
||||
val allScoreProfiles: LiveData<List<ScoreProfile>> = 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<Participation>) = 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<List<CourseExam>> = dao.getCoursesByYearId(yearId)
|
||||
fun getAllCourses() = dao.getAllCourseExams()
|
||||
fun getAveragesForCourses(courseId: Int): List<HistoricalAvg> = dao.getAveragesForCourses(courseId)
|
||||
fun getFinalGrades(finalScoreId: Int): LiveData<List<FinalGrade>> = dao.getFinalGrades(finalScoreId)
|
||||
fun getAllYears(): List<SchoolYear> = dao.getAllYears()
|
||||
fun getGradesByForeignKey(courseId: Int): LiveData<List<Grade>> = dao.getGradesByForeignKey(courseId)
|
||||
fun getNotesForCategory(category: String): LiveData<List<Note>> = dao.notesForCategory(category)
|
||||
fun getAllCategories(): List<String> = dao.getAllCategories()
|
||||
fun getDays(): List<SchoolDay> = dao.getDays(prefs.getSchoolYear())
|
||||
fun getCourses(): List<CourseExam> =
|
||||
dao.getCoursesByYearIdAsList(prefs.getSchoolYear()).getSorted(prefs.getCourseSortType())
|
||||
fun getAllParticipationsForCourse(courseId: Int): LiveData<List<Participation>> =
|
||||
dao.getAllParticipationsForCourse(courseId)
|
||||
fun insert(timesHandRaised: Int, timesSpoken: Int, time: Long, courseId: Int) {
|
||||
dao.insert(
|
||||
Participation(
|
||||
timesHandRaised,
|
||||
timesSpoken,
|
||||
time,
|
||||
0,
|
||||
courseId,
|
||||
dayId
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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<List<SchoolYear>> = dao.allYears
|
||||
val allScoreProfiles: LiveData<List<ScoreProfile>> = 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<FinalGrade>()
|
||||
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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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("")
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 : View> 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 : View> T.resetBottomPadding() {
|
||||
setPadding(paddingLeft, paddingTop, paddingRight, 0)
|
||||
}
|
||||
|
||||
private fun <T : View> T.applyBottomPadding() {
|
||||
setPadding(paddingLeft, paddingTop, paddingRight, 56.dpToPx())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 <T : ViewBinding> FragmentActivity.viewBinding(crossinline bindingInflater: (LayoutInflater) -> T) =
|
||||
lazy(LazyThreadSafetyMode.NONE) {
|
||||
bindingInflater.invoke(layoutInflater)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.denizd.qwark.util
|
||||
|
||||
import com.denizd.qwark.database.QwarkRepository
|
||||
|
||||
object Dependencies {
|
||||
lateinit var repo: QwarkRepository
|
||||
}
|
||||
@@ -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<T : ViewBinding>(
|
||||
val fragment: Fragment,
|
||||
val viewBindingFactory: (View) -> T
|
||||
) : ReadOnlyProperty<Fragment, T> {
|
||||
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 <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) =
|
||||
FragmentViewBindingDelegate(this, viewBindingFactory)
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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) }
|
||||
}
|
||||
@@ -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<List<CourseExam>> = repo.getCoursesByYearId(getSchoolYear())
|
||||
val allCourses: LiveData<List<CourseExam>> = 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<HistoricalAvg> = 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) }
|
||||
}
|
||||
@@ -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<List<FinalGrade>> = repo.getFinalGrades(repo.getFinalScoreId())
|
||||
val allFinalGrades: LiveData<List<FinalGrade>> = 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<FinalGrade>, advancedGrades: List<FinalGrade>, examGrades: List<FinalGrade>): 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()
|
||||
}
|
||||
@@ -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) }
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String>()
|
||||
val allNotes: LiveData<List<Note>>? = Transformations.switchMap(reloadTrigger) { category ->
|
||||
val allNotes: LiveData<List<Note>> = 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<List<Note>>? {
|
||||
// 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<String> = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
repo.getAllCategories()
|
||||
}
|
||||
}
|
||||
fun getAllCategories(): List<String> = returnBlocking { repo.getAllCategories() }
|
||||
|
||||
fun getNote(noteId: Int) = returnBlocking { repo.getNote(noteId) }
|
||||
}
|
||||
@@ -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<List<Participation>> = 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) }
|
||||
}
|
||||
@@ -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<List<Course>> = 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()
|
||||
}
|
||||
@@ -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 <T> returnBlocking(function: () -> T): T = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
fun doAsync(function: () -> Unit) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
function()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> returnBlocking(function: () -> T): T = runBlocking(Dispatchers.IO) {
|
||||
function()
|
||||
}
|
||||
}
|
||||
@@ -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<List<SchoolYear>> = repo.allYears
|
||||
val allScoreProfiles: LiveData<List<ScoreProfile>> = 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) }
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/scroll_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
android:id="@+id/average"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:textColor="@color/colorAccentedControl"
|
||||
@@ -27,7 +27,7 @@
|
||||
android:id="@+id/weighting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:textColor="@color/colorText"
|
||||
@@ -59,6 +59,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
app:cornerRadius="12dp"
|
||||
|
||||
@@ -7,102 +7,81 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true"
|
||||
android:fitsSystemWindows="false"
|
||||
android:background="@color/colorBackground"
|
||||
tools:context=".activity.MainActivity">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/root_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="56dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
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">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/status_bar_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="@color/colorAppBarBackground"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/app_bar_layout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar_layout"
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="84dp"
|
||||
app:elevation="0dp"
|
||||
android:background="@color/colorAppBarBackground"
|
||||
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">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:contentInsetStart="0dp"
|
||||
android:elevation="0dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:id="@+id/super_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:textColor="@color/colorTextHighlight"
|
||||
android:textSize="20sp"
|
||||
android:fontFamily="@font/manrope_semibold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/super_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:textColor="@color/colorTextHighlight"
|
||||
android:textSize="20sp"
|
||||
android:fontFamily="@font/manrope_semibold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
<TextView
|
||||
android:id="@+id/app_bar_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:fontFamily="@font/manrope_extrabold"
|
||||
android:textColor="@color/colorTextHighlight"
|
||||
android:textSize="28sp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
app:layout_constraintTop_toBottomOf="@+id/super_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_bar_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:fontFamily="@font/manrope_extrabold"
|
||||
android:textColor="@color/colorTextHighlight"
|
||||
android:textSize="28sp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee"
|
||||
app:layout_constraintTop_toBottomOf="@+id/super_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
@@ -139,11 +118,48 @@
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@color/colorHintLight"
|
||||
android:background="@color/strokeColor"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
app:layout_anchor="@+id/bottom_nav"
|
||||
android:layout_gravity="top"
|
||||
android:fitsSystemWindows="false"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="false">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/splash_screen"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/colorBackground">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_view"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="184dp"
|
||||
android:scaleType="centerInside"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:src="@drawable/bolt"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/greeting_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="20sp"
|
||||
android:fontFamily="@font/manrope_semibold"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/image_view"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/QwarkCard"
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:layout_marginVertical="3dp"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:backgroundTint="@color/colorCardBackground">
|
||||
android:clickable="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -55,14 +55,14 @@
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:id="@+id/finish_button"
|
||||
android:id="@+id/save_button"
|
||||
app:strokeWidth="2dp"
|
||||
app:strokeColor="@color/colorAccent"
|
||||
android:textColor="@color/colorAccent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:text="@string/finish"
|
||||
android:text="@string/save"
|
||||
app:rippleColor="@color/colorAccent"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/QwarkCard"
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/QwarkCard"
|
||||
android:id="@+id/card"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
android:clipToPadding="false">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/QwarkCard"
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -65,9 +67,9 @@
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_height="3dp"
|
||||
android:progressTint="@color/colorAccent"
|
||||
android:progressBackgroundTint="@color/colorCardBackground"/>
|
||||
android:progressBackgroundTint="@color/colorBackground"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/QwarkCard"
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/QwarkCard"
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@color/colorBackground">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
@@ -9,6 +10,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layoutAnimation="@anim/layout_animation_fall_down"
|
||||
android:scrollbars="vertical"/>
|
||||
android:scrollbars="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -20,15 +20,13 @@
|
||||
android:layoutAnimation="@anim/layout_animation_fall_down">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/QwarkCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="@dimen/cardCornerRadius"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
app:cardElevation="2dp"
|
||||
app:cardBackgroundColor="@color/colorCardBackground">
|
||||
android:layout_marginBottom="3dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -79,15 +77,13 @@
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/QwarkCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="@dimen/cardCornerRadius"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
app:cardElevation="2dp"
|
||||
app:cardBackgroundColor="@color/colorCardBackground">
|
||||
android:layout_marginBottom="3dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -290,15 +286,13 @@
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/QwarkCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="@dimen/cardCornerRadius"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
app:cardElevation="2dp"
|
||||
app:cardBackgroundColor="@color/colorCardBackground">
|
||||
android:layout_marginBottom="3dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -376,15 +370,13 @@
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/QwarkCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="@dimen/cardCornerRadius"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
app:cardElevation="2dp"
|
||||
app:cardBackgroundColor="@color/colorCardBackground">
|
||||
android:layout_marginBottom="3dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -29,11 +29,7 @@
|
||||
android:layout_marginEnd="24dp"
|
||||
android:hint="@string/school_year_cap"
|
||||
android:textColorHint="@color/colorHint"
|
||||
android:importantForAutofill="no"
|
||||
app:boxCornerRadiusTopEnd="12dp"
|
||||
app:boxCornerRadiusBottomEnd="12dp"
|
||||
app:boxCornerRadiusTopStart="12dp"
|
||||
app:boxCornerRadiusBottomStart="12dp">
|
||||
android:importantForAutofill="no">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/edit_text"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="@color/colorBackground">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorText"
|
||||
android:textSize="22sp"
|
||||
android:fontFamily="@font/manrope_semibold"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"/>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorText"
|
||||
android:fontFeatureSettings="tnum"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"/>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/QwarkCard"
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:layout_marginVertical="3dp"
|
||||
android:backgroundTint="@color/colorCardBackground">
|
||||
android:layout_marginVertical="3dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/backgroundLayout"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<string name="edit">Bearbeiten</string>
|
||||
<string name="finish">Beenden</string>
|
||||
<string name="create">Erstellen</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="general">Allgemein</string>
|
||||
<string name="alert_create_school_year_title">Erstelle ein Schuljahr</string>
|
||||
<string name="alert_create_school_year_desc">Bevor du Kurse und Abschlussnoten hinzufügst, gehe in die Einstellungen und erstelle ein Schuljahr und ein Abschlussprofil!</string>
|
||||
@@ -138,6 +139,8 @@
|
||||
<string name="clear_final_grade_error">Note kann nicht gelöscht werden; ist bereits leer</string>
|
||||
<string name="pick_a_year">Wähle ein Schuljahr</string>
|
||||
<string name="pick_a_course">Wähle einen Kurs</string>
|
||||
<string name="conversion_table">Umrechnungstabelle</string>
|
||||
<string name="points_to_grade_conversion_title">Punkte zu Note-Umrechnungstabelle</string>
|
||||
|
||||
<!-- SettingsFragment.kt -->
|
||||
<string name="settings">Einstellungen</string>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<resources>
|
||||
<color name="colorAccent">#6abf69</color>
|
||||
<color name="colorBackground">#121212</color>
|
||||
<color name="colorAppBarBackground">#E6121212</color>
|
||||
<color name="colorCardBackground">#222222</color>
|
||||
<color name="colorTextHighlight">@color/colorAccent</color>
|
||||
<color name="colorText">#e0e0e0</color>
|
||||
@@ -14,4 +13,5 @@
|
||||
<color name="colorTextWhite">#e0e0e0</color>
|
||||
<color name="colorAccentedControl">@color/colorText</color>
|
||||
<color name="colorSplashLogo">@color/colorText</color>
|
||||
<color name="strokeColor">#424242</color>
|
||||
</resources>
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<color name="colorAccent">#388e3c</color>
|
||||
<color name="colorBackground">#e0e0e0</color>
|
||||
<color name="colorAppBarBackground">#E6e0e0e0</color>
|
||||
<color name="colorCardBackground">#f5f5f5</color>
|
||||
<color name="colorBackground">#ffffff</color>
|
||||
<color name="colorCardBackground">#e0e0e0</color>
|
||||
<color name="colorTextHighlight">@color/colorAccent</color>
|
||||
<color name="colorText">#212121</color>
|
||||
<color name="colorHint">#757575</color>
|
||||
@@ -14,6 +13,7 @@
|
||||
<color name="colorTextWhite">#e0e0e0</color>
|
||||
<color name="colorAccentedControl">@color/colorAccent</color>
|
||||
<color name="colorSplashLogo">@color/colorAccent</color>
|
||||
<color name="strokeColor">#bdbdbd</color>
|
||||
|
||||
<color name="mtrl_textinput_default_box_stroke_color" tools:override="true">#757575</color>
|
||||
</resources>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<string name="edit">Edit</string>
|
||||
<string name="finish">Finish</string>
|
||||
<string name="create">Create</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="general">General</string>
|
||||
<string name="alert_create_school_year_title">Create a school year</string>
|
||||
<string name="alert_create_school_year_desc">Before adding courses and final grades, please do make sure to go into the settings and create a school year and a score profile!</string>
|
||||
@@ -18,6 +19,12 @@
|
||||
<string name="powered_by_qwark" translatable="false">Powered by Qwark</string>
|
||||
<string name="made_by_deniz" translatable="false">Made by Deniz</string>
|
||||
|
||||
<string-array name="greetings">
|
||||
<item>Hello %s!</item>
|
||||
<item>Hi %s!</item>
|
||||
<item>Hope you\'re doing well, %s.</item>
|
||||
</string-array>
|
||||
|
||||
<!-- CourseFragment.kt -->
|
||||
<string name="course">Course</string>
|
||||
<string name="courses">Courses</string>
|
||||
@@ -196,7 +203,9 @@
|
||||
<string name="clear_final_grade_error">Grade cannot be cleared; is already empty</string>
|
||||
<string name="pick_a_year">Pick a school year</string>
|
||||
<string name="pick_a_course">Pick a course</string>
|
||||
<string name="points_to_grade_conversion" translatable="false">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</string>
|
||||
<string name="conversion_table">Conversion table</string>
|
||||
<string name="points_to_grade_conversion_title">Points to grade conversion table</string>
|
||||
<string name="points_to_grade_conversion" translatable="false">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</string>
|
||||
<string name="approximate_placeholder" translatable="false">≈ %s</string>
|
||||
|
||||
<!-- SettingsFragment.kt -->
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="colorPrimary">@color/colorAccent</item>
|
||||
<item name="colorPrimaryDark">@android:color/transparent</item>
|
||||
<item name="colorPrimaryDark">@color/colorBackground</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:fontFamily">@font/manrope_medium</item>
|
||||
<item name="android:colorEdgeEffect">@color/colorAccent</item>
|
||||
@@ -13,7 +13,6 @@
|
||||
<item name="shapeAppearanceSmallComponent">@style/ShapeSmallComponent</item>
|
||||
<item name="shapeAppearanceMediumComponent">@style/ShapeMediumComponent</item>
|
||||
<item name="shapeAppearanceLargeComponent">@style/ShapeLargeComponent</item>
|
||||
<item name="cardBackgroundColor">@color/colorCardBackground</item>
|
||||
<item name="cornerRadius">@dimen/cardCornerRadius</item>
|
||||
<item name="cardElevation">3dp</item>
|
||||
<item name="android:textColor">@color/colorText</item>
|
||||
@@ -23,11 +22,19 @@
|
||||
<item name="boxCornerRadiusBottomEnd">@dimen/cardCornerRadius</item>
|
||||
<item name="boxStrokeColor">@color/colorAccent</item>
|
||||
<item name="boxStrokeWidth">1dp</item>
|
||||
<!-- <item name="android:statusBarColor">@color/colorAppBarBackground</item>-->
|
||||
<!-- <item name="android:statusBarColor">@color/colorBackground</item>-->
|
||||
<!-- <item name="android:windowTranslucentStatus">true</item>-->
|
||||
<!-- <item name="android:windowDrawsSystemBarBackgrounds">true</item>-->
|
||||
</style>
|
||||
|
||||
<style name="QwarkCard" parent="Widget.MaterialComponents.CardView">
|
||||
<item name="cardBackgroundColor">@color/colorBackground</item>
|
||||
<item name="strokeColor">@color/strokeColor</item>
|
||||
<item name="strokeWidth">1dp</item>
|
||||
<item name="cardCornerRadius">12dp</item>
|
||||
<item name="cardElevation">0dp</item>
|
||||
</style>
|
||||
|
||||
<!-- Launch / splash screen -->
|
||||
<style name="AppTheme.Launcher">
|
||||
<item name="android:windowBackground">@drawable/launch_screen</item>
|
||||
|
||||
Reference in New Issue
Block a user