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:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
||||
#Wed Feb 12 10:01:56 CET 2020
|
||||
gradle.version=6.1-rc-1
|
||||
#Mon Mar 02 18:08:17 CET 2020
|
||||
gradle.version=6.1.1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Generated
+11
-11
File diff suppressed because one or more lines are too long
@@ -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)
|
||||
}
|
||||
val barColour = ContextCompat.getColor(context, R.color.colorBackground)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
protected val repo: QwarkRepository = Dependencies.repo
|
||||
|
||||
fun doAsync(function: () -> Unit) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
function()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> returnBlocking(function: () -> T): T = runBlocking {
|
||||
withContext(Dispatchers.IO) {
|
||||
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,46 +7,20 @@
|
||||
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">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="84dp"
|
||||
app:elevation="0dp"
|
||||
android:background="@color/colorAppBarBackground"
|
||||
android:background="@color/colorBackground"
|
||||
android:layout_gravity="top"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -57,7 +31,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:contentInsetStart="0dp"
|
||||
android:elevation="0dp">
|
||||
android:elevation="0dp"
|
||||
app:layout_scrollFlags="scroll|enterAlwaysCollapsed">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -102,7 +77,11 @@
|
||||
|
||||
</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>
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ buildscript {
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.0-alpha09'
|
||||
classpath 'com.android.tools.build:gradle:4.0.0-beta01'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Mon Feb 03 16:46:00 CET 2020
|
||||
#Mon Mar 02 18:07:39 CET 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-rc-1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
|
||||
Reference in New Issue
Block a user