Merge branch 'release/1.4.4'

This commit is contained in:
Mikołaj Pich 2021-12-19 22:25:52 +01:00
commit 4e12eb1552
45 changed files with 283 additions and 246 deletions

View File

@ -22,8 +22,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
targetSdkVersion 31
versionCode 101
versionName "1.4.3"
versionCode 102
versionName "1.4.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy"
@ -150,7 +150,7 @@ kapt {
play {
defaultToAppBundles = false
track = 'beta'
updatePriority = 1
updatePriority = 4
enabled.set(false)
}
@ -174,7 +174,7 @@ ext {
}
dependencies {
implementation "io.github.wulkanowy:sdk:1.4.3"
implementation "io.github.wulkanowy:sdk:1.4.4"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
@ -229,7 +229,7 @@ dependencies {
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
implementation 'com.fredporciuncula:flow-preferences:1.6.0'
playImplementation platform('com.google.firebase:firebase-bom:29.0.0')
playImplementation platform('com.google.firebase:firebase-bom:29.0.2')
playImplementation 'com.google.firebase:firebase-analytics-ktx'
playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:'
@ -238,7 +238,7 @@ dependencies {
playImplementation 'com.google.android.gms:play-services-ads:20.5.0'
hmsImplementation 'com.huawei.hms:hianalytics:6.3.2.300'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.6.2.200'
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.6.2.300'
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
@ -250,7 +250,7 @@ dependencies {
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation 'org.robolectric:robolectric:4.7.2'
testImplementation 'org.robolectric:robolectric:4.7.3'
testImplementation "androidx.test:runner:1.4.0"
testImplementation "androidx.test.ext:junit:1.1.3"
testImplementation "androidx.test:core:1.4.0"

View File

@ -6,6 +6,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import javax.inject.Singleton
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER", "unused")
@Singleton
class InAppReviewHelper @Inject constructor(
@ApplicationContext private val context: Context

View File

@ -10,6 +10,6 @@ import javax.inject.Singleton
@Singleton
interface SchoolAnnouncementDao : BaseDao<SchoolAnnouncement> {
@Query("SELECT * FROM SchoolAnnouncements WHERE student_id = :studentId")
@Query("SELECT * FROM SchoolAnnouncements WHERE student_id = :studentId ORDER BY date DESC")
fun loadAll(studentId: Int): Flow<List<SchoolAnnouncement>>
}

View File

@ -3,7 +3,7 @@ package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
import io.github.wulkanowy.data.enums.GradeExpandMode
class Migration41(private val sharedPrefProvider: SharedPrefProvider) : Migration(40, 41) {

View File

@ -0,0 +1,12 @@
package io.github.wulkanowy.data.enums
enum class AppTheme(val value: String) {
SYSTEM("system"),
LIGHT("light"),
DARK("dark"),
BLACK("black");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: LIGHT
}
}

View File

@ -0,0 +1,13 @@
package io.github.wulkanowy.data.enums
import java.io.Serializable
enum class GradeColorTheme(val value: String) : Serializable {
VULCAN("vulcan"),
MATERIAL("material"),
GRADE_COLOR("grade_color");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: VULCAN
}
}

View File

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.enums
enum class GradeExpandMode(val value: String) {
ONE("one"),
UNLIMITED("any"),
ALWAYS_EXPANDED("always");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: ONE
}
}

View File

@ -0,0 +1,10 @@
package io.github.wulkanowy.data.enums
enum class GradeSortingMode(val value: String) {
ALPHABETIC("alphabetic"),
DATE("date");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: ALPHABETIC
}
}

View File

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.enums
enum class TimetableMode(val value: String) {
WHOLE_PLAN("yes"),
ONLY_CURRENT_GROUP("no"),
SMALL_OTHER_GROUP("small");
companion object {
fun getByValue(value: String) = values().find { it.value == value } ?: ONLY_CURRENT_GROUP
}
}

View File

@ -7,11 +7,14 @@ import com.fredporciuncula.flow.preferences.FlowSharedPreferences
import com.fredporciuncula.flow.preferences.Preference
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
import io.github.wulkanowy.data.enums.AppTheme
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.enums.GradeExpandMode
import io.github.wulkanowy.data.enums.GradeSortingMode
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.sdk.toLocalDate
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -72,13 +75,15 @@ class PreferencesRepository @Inject constructor(
)
val appThemeKey = context.getString(R.string.pref_key_app_theme)
val appTheme: String
get() = getString(appThemeKey, R.string.pref_default_app_theme)
val appTheme: AppTheme
get() = AppTheme.getByValue(getString(appThemeKey, R.string.pref_default_app_theme))
val gradeColorTheme: String
get() = getString(
R.string.pref_key_grade_color_scheme,
R.string.pref_default_grade_color_scheme
val gradeColorTheme: GradeColorTheme
get() = GradeColorTheme.getByValue(
getString(
R.string.pref_key_grade_color_scheme,
R.string.pref_default_grade_color_scheme
)
)
val appLanguageKey = context.getString(R.string.pref_key_app_language)
@ -156,10 +161,12 @@ class PreferencesRepository @Inject constructor(
R.bool.pref_default_timetable_show_groups
)
val showWholeClassPlan: String
get() = getString(
R.string.pref_key_timetable_show_whole_class,
R.string.pref_default_timetable_show_whole_class
val showWholeClassPlan: TimetableMode
get() = TimetableMode.getByValue(
getString(
R.string.pref_key_timetable_show_whole_class,
R.string.pref_default_timetable_show_whole_class
)
)
val gradeSortingMode: GradeSortingMode

View File

@ -74,7 +74,7 @@ class AppNotificationManager @Inject constructor(
student: Student
) {
val notificationType = groupNotificationData.type
val groupType = notificationType.group ?: return
val groupType = notificationType.channel
val group = "${groupType}_${student.id}"
sendSummaryNotification(groupNotificationData, group, student)

View File

@ -14,72 +14,58 @@ import io.github.wulkanowy.services.sync.channels.PushChannel
import io.github.wulkanowy.services.sync.channels.TimetableChangeChannel
enum class NotificationType(
val group: String?,
val channel: String,
val icon: Int
) {
NEW_CONFERENCE(
group = "new_conferences_group",
channel = NewConferencesChannel.CHANNEL_ID,
icon = R.drawable.ic_more_conferences,
),
NEW_EXAM(
group = "new_exam_group",
channel = NewExamChannel.CHANNEL_ID,
icon = R.drawable.ic_main_exam
),
NEW_GRADE_DETAILS(
group = "new_grade_details_group",
channel = NewGradesChannel.CHANNEL_ID,
icon = R.drawable.ic_stat_grade,
),
NEW_GRADE_PREDICTED(
group = "new_grade_predicted_group",
channel = NewGradesChannel.CHANNEL_ID,
icon = R.drawable.ic_stat_grade,
),
NEW_GRADE_FINAL(
group = "new_grade_final_group",
channel = NewGradesChannel.CHANNEL_ID,
icon = R.drawable.ic_stat_grade,
),
NEW_HOMEWORK(
group = "new_homework_group",
channel = NewHomeworkChannel.CHANNEL_ID,
icon = R.drawable.ic_more_homework,
),
NEW_LUCKY_NUMBER(
group = null,
channel = LuckyNumberChannel.CHANNEL_ID,
icon = R.drawable.ic_stat_luckynumber,
),
NEW_MESSAGE(
group = "new_message_group",
channel = NewMessagesChannel.CHANNEL_ID,
icon = R.drawable.ic_stat_message,
),
NEW_NOTE(
group = "new_notes_group",
channel = NewNotesChannel.CHANNEL_ID,
icon = R.drawable.ic_stat_note
),
NEW_ANNOUNCEMENT(
group = "new_school_announcements_group",
channel = NewSchoolAnnouncementsChannel.CHANNEL_ID,
icon = R.drawable.ic_all_about
),
CHANGE_TIMETABLE(
group = "change_timetable_group",
channel = TimetableChangeChannel.CHANNEL_ID,
icon = R.drawable.ic_main_timetable
),
NEW_ATTENDANCE(
group = "new_attendance_group",
channel = NewAttendanceChannel.CHANNEL_ID,
icon = R.drawable.ic_main_attendance
),
PUSH(
group = null,
channel = PushChannel.CHANNEL_ID,
icon = R.drawable.ic_stat_all
)

View File

@ -7,6 +7,7 @@ import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
import io.github.wulkanowy.R
import io.github.wulkanowy.data.enums.AppTheme
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.main.MainActivity
@ -20,7 +21,7 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
fun applyActivityTheme(activity: AppCompatActivity) {
if (isThemeApplicable(activity)) {
applyDefaultTheme()
if (preferencesRepository.appTheme == "black") {
if (preferencesRepository.appTheme == AppTheme.BLACK) {
when (activity) {
is MainActivity -> activity.setTheme(R.style.WulkanowyTheme_Black)
is LoginActivity -> activity.setTheme(R.style.WulkanowyTheme_Login_Black)
@ -32,11 +33,10 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
fun applyDefaultTheme() {
AppCompatDelegate.setDefaultNightMode(
when (val theme = preferencesRepository.appTheme) {
"light" -> MODE_NIGHT_NO
"dark", "black" -> MODE_NIGHT_YES
"system" -> MODE_NIGHT_FOLLOW_SYSTEM
else -> throw IllegalArgumentException("Wrong theme: $theme")
when (preferencesRepository.appTheme) {
AppTheme.LIGHT -> MODE_NIGHT_NO
AppTheme.DARK, AppTheme.BLACK -> MODE_NIGHT_YES
AppTheme.SYSTEM -> MODE_NIGHT_FOLLOW_SYSTEM
}
)
}

View File

@ -20,6 +20,7 @@ import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.db.entities.TimetableHeader
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.databinding.ItemDashboardAccountBinding
import io.github.wulkanowy.databinding.ItemDashboardAdminMessageBinding
import io.github.wulkanowy.databinding.ItemDashboardAnnouncementsBinding
@ -262,7 +263,7 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
val isLoading = item.isLoading
val dashboardGradesAdapter = gradesViewHolder.adapter.apply {
this.items = subjectWithGrades.toList()
this.gradeTheme = gradeTheme.orEmpty()
this.gradeColorTheme = gradeTheme ?: GradeColorTheme.VULCAN
}
with(gradesViewHolder.binding) {
@ -421,10 +422,12 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
isFirstTimeRangeVisible = true
isFirstTimeVisible = false
} else {
firstTimeText = context.resources.getQuantityString(
R.plurals.dashboard_timetable_first_lesson_time_in_minutes,
minutesToStartLesson.toInt(),
minutesToStartLesson
firstTimeText = context.getString(
R.string.timetable_time_until,
context.getString(
R.string.timetable_minutes,
minutesToStartLesson.toString()
)
)
firstTimeRangeText = ""
@ -460,10 +463,12 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
0
}
firstTimeText = context.resources.getQuantityString(
R.plurals.dashboard_timetable_first_lesson_time_more_minutes,
minutesToEndLesson.toInt(),
minutesToEndLesson
firstTimeText = context.getString(
R.string.timetable_time_left,
context.getString(
R.string.timetable_minutes,
minutesToEndLesson.toString()
)
)
firstTimeRangeText = ""

View File

@ -4,6 +4,7 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.databinding.SubitemDashboardGradesBinding
import io.github.wulkanowy.databinding.SubitemDashboardSmallGradeBinding
import io.github.wulkanowy.utils.getBackgroundColor
@ -12,7 +13,7 @@ class DashboardGradesAdapter : RecyclerView.Adapter<DashboardGradesAdapter.ViewH
var items = listOf<Pair<String, List<Grade>>>()
var gradeTheme = ""
lateinit var gradeColorTheme: GradeColorTheme
override fun getItemCount() = items.size
@ -36,7 +37,7 @@ class DashboardGradesAdapter : RecyclerView.Adapter<DashboardGradesAdapter.ViewH
with(subitemBinding.dashboardSmallGradeSubitemValue) {
text = it.entry
setBackgroundResource(it.getBackgroundColor(gradeTheme))
setBackgroundResource(it.getBackgroundColor(gradeColorTheme))
}
dashboardGradesSubitemGradeContainer.addView(subitemBinding.root)

View File

@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.pojos.TimetableFull
import io.github.wulkanowy.data.db.entities.Homework as EntitiesHomework
@ -52,7 +53,7 @@ sealed class DashboardItem(val type: Type) {
data class Grades(
val subjectWithGrades: Map<String, List<Grade>>? = null,
val gradeTheme: String? = null,
val gradeTheme: GradeColorTheme? = null,
override val error: Throwable? = null,
override val isLoading: Boolean = false
) : DashboardItem(Type.GRADES) {

View File

@ -1,9 +0,0 @@
package io.github.wulkanowy.ui.modules.grade
enum class GradeExpandMode(val value: String) {
ONE("one"), UNLIMITED("any"), ALWAYS_EXPANDED("always");
companion object {
fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ONE
}
}

View File

@ -1,10 +0,0 @@
package io.github.wulkanowy.ui.modules.grade
enum class GradeSortingMode(val value: String) {
ALPHABETIC("alphabetic"),
DATE("date");
companion object {
fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ALPHABETIC
}
}

View File

@ -11,10 +11,11 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.enums.GradeExpandMode
import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding
import io.github.wulkanowy.databinding.ItemGradeDetailsBinding
import io.github.wulkanowy.ui.base.BaseExpandableAdapter
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
import io.github.wulkanowy.utils.getBackgroundColor
import io.github.wulkanowy.utils.toFormattedString
import timber.log.Timber
@ -33,7 +34,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
var onClickListener: (Grade, position: Int) -> Unit = { _, _ -> }
var colorTheme = ""
lateinit var gradeColorTheme: GradeColorTheme
fun setDataItems(data: List<GradeDetailsItem>, expandMode: GradeExpandMode = this.expandMode) {
headers = data.filter { it.viewType == ViewType.HEADER }.toMutableList()
@ -202,7 +203,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
with(holder.binding) {
gradeItemValue.run {
text = grade.entry
setBackgroundResource(grade.getBackgroundColor(colorTheme))
setBackgroundResource(grade.getBackgroundColor(gradeColorTheme))
}
gradeItemDescription.text = when {
grade.description.isNotBlank() -> grade.description

View File

@ -8,6 +8,7 @@ import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.databinding.DialogGradeBinding
import io.github.wulkanowy.utils.colorStringId
import io.github.wulkanowy.utils.getBackgroundColor
@ -21,19 +22,19 @@ class GradeDetailsDialog : DialogFragment() {
private lateinit var grade: Grade
private lateinit var colorScheme: String
private lateinit var gradeColorTheme: GradeColorTheme
companion object {
private const val ARGUMENT_KEY = "Item"
private const val COLOR_SCHEME_KEY = "Scheme"
private const val COLOR_THEME_KEY = "Theme"
fun newInstance(grade: Grade, colorScheme: String) =
fun newInstance(grade: Grade, colorTheme: GradeColorTheme) =
GradeDetailsDialog().apply {
arguments = Bundle().apply {
putSerializable(ARGUMENT_KEY, grade)
putString(COLOR_SCHEME_KEY, colorScheme)
putSerializable(COLOR_THEME_KEY, colorTheme)
}
}
}
@ -43,7 +44,7 @@ class GradeDetailsDialog : DialogFragment() {
setStyle(STYLE_NO_TITLE, 0)
arguments?.run {
grade = getSerializable(ARGUMENT_KEY) as Grade
colorScheme = getString(COLOR_SCHEME_KEY) ?: "default"
gradeColorTheme = getSerializable(COLOR_THEME_KEY) as GradeColorTheme
}
}
@ -76,7 +77,7 @@ class GradeDetailsDialog : DialogFragment() {
gradeDialogValue.run {
text = grade.entry
setBackgroundResource(grade.getBackgroundColor(colorScheme))
setBackgroundResource(grade.getBackgroundColor(gradeColorTheme))
}
gradeDialogTeacherValue.text = if (grade.teacher.isBlank()) {

View File

@ -12,7 +12,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.enums.GradeExpandMode
import io.github.wulkanowy.databinding.FragmentGradeDetailsBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.grade.GradeFragment
@ -80,9 +81,9 @@ class GradeDetailsFragment :
else false
}
override fun updateData(data: List<GradeDetailsItem>, expandMode: GradeExpandMode, gradeColorTheme: String) {
override fun updateData(data: List<GradeDetailsItem>, expandMode: GradeExpandMode, gradeColorTheme: GradeColorTheme) {
with(gradeDetailsAdapter) {
colorTheme = gradeColorTheme
this.gradeColorTheme = gradeColorTheme
setDataItems(data, expandMode)
notifyDataSetChanged()
}
@ -143,8 +144,8 @@ class GradeDetailsFragment :
binding.gradeDetailsSwipe.isRefreshing = show
}
override fun showGradeDialog(grade: Grade, colorScheme: String) {
(activity as? MainActivity)?.showDialogFragment(GradeDetailsDialog.newInstance(grade, colorScheme))
override fun showGradeDialog(grade: Grade, colorTheme: GradeColorTheme) {
(activity as? MainActivity)?.showDialogFragment(GradeDetailsDialog.newInstance(grade, colorTheme))
}
override fun onParentLoadData(semesterId: Int, forceRefresh: Boolean) {

View File

@ -2,6 +2,9 @@ package io.github.wulkanowy.ui.modules.grade.details
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.enums.GradeExpandMode
import io.github.wulkanowy.data.enums.GradeSortingMode.ALPHABETIC
import io.github.wulkanowy.data.enums.GradeSortingMode.DATE
import io.github.wulkanowy.data.repositories.GradeRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository
@ -9,9 +12,6 @@ import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.ALPHABETIC
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.DATE
import io.github.wulkanowy.ui.modules.grade.GradeSubject
import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.afterLoading
@ -230,10 +230,14 @@ class GradeDetailsPresenter @Inject constructor(
gradesWithAverages.filter { it.grades.isNotEmpty() }
} else gradesWithAverages
}
.let {
.let { gradeSubjects ->
when (preferencesRepository.gradeSortingMode) {
DATE -> it.sortedByDescending { gradeDetailsWithAverage -> gradeDetailsWithAverage.grades.firstOrNull()?.date }
ALPHABETIC -> it.sortedBy { gradeDetailsWithAverage -> gradeDetailsWithAverage.subject.lowercase() }
DATE -> gradeSubjects.sortedByDescending { gradeDetailsWithAverage ->
gradeDetailsWithAverage.grades.maxByOrNull { it.date }?.date
}
ALPHABETIC -> gradeSubjects.sortedBy { gradeDetailsWithAverage ->
gradeDetailsWithAverage.subject.lowercase()
}
}
}
.map { (subject, average, points, _, grades) ->

View File

@ -1,7 +1,8 @@
package io.github.wulkanowy.ui.modules.grade.details
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.enums.GradeExpandMode
import io.github.wulkanowy.ui.base.BaseView
interface GradeDetailsView : BaseView {
@ -10,7 +11,7 @@ interface GradeDetailsView : BaseView {
fun initView()
fun updateData(data: List<GradeDetailsItem>, expandMode: GradeExpandMode, gradeColorTheme: String)
fun updateData(data: List<GradeDetailsItem>, expandMode: GradeExpandMode, gradeColorTheme: GradeColorTheme)
fun updateItem(item: Grade, position: Int)
@ -22,7 +23,7 @@ interface GradeDetailsView : BaseView {
fun collapseAllItems()
fun showGradeDialog(grade: Grade, colorScheme: String)
fun showGradeDialog(grade: Grade, colorTheme: GradeColorTheme)
fun showContent(show: Boolean)

View File

@ -20,6 +20,7 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.databinding.ItemGradeStatisticsBarBinding
import io.github.wulkanowy.databinding.ItemGradeStatisticsHeaderBinding
@ -34,7 +35,7 @@ class GradeStatisticsAdapter @Inject constructor() :
var items = emptyList<GradeStatisticsItem>()
var theme: String = "vulcan"
lateinit var gradeColorTheme: GradeColorTheme
var showAllSubjectsOnList: Boolean = false
@ -156,8 +157,8 @@ class GradeStatisticsAdapter @Inject constructor() :
visibility = if (items.size == 1 || !showAllSubjectsOnList) GONE else VISIBLE
}
val gradeColors = when (theme) {
"vulcan" -> vulcanGradeColors
val gradeColors = when (gradeColorTheme) {
GradeColorTheme.VULCAN -> vulcanGradeColors
else -> materialGradeColors
}

View File

@ -7,6 +7,7 @@ import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.databinding.FragmentGradeStatisticsBinding
import io.github.wulkanowy.ui.base.BaseFragment
@ -90,12 +91,12 @@ class GradeStatisticsFragment :
override fun updateData(
newItems: List<GradeStatisticsItem>,
newTheme: String,
newTheme: GradeColorTheme,
showAllSubjectsOnStatisticsList: Boolean
) {
with(statisticsAdapter) {
showAllSubjectsOnList = showAllSubjectsOnStatisticsList
theme = newTheme
gradeColorTheme = newTheme
items = newItems
notifyDataSetChanged()
}

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.grade.statistics
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.ui.base.BaseView
@ -15,7 +16,7 @@ interface GradeStatisticsView : BaseView {
fun updateData(
newItems: List<GradeStatisticsItem>,
newTheme: String,
newTheme: GradeColorTheme,
showAllSubjectsOnStatisticsList: Boolean
)

View File

@ -52,6 +52,8 @@ class LoginFormPresenter @Inject constructor(
clearHostError()
if (formHostValue.contains("fakelog")) {
setCredentials("jan@fakelog.cf", "jan123")
} else if (formUsernameValue == "jan@fakelog.cf" && formPassValue == "jan123") {
setCredentials("", "")
}
updateUsernameLabel()
}

View File

@ -56,7 +56,7 @@ class SendMessagePresenter @Inject constructor(
}
message?.let {
setSubject(when (reply) {
true -> "RE: "
true -> "Re: "
else -> "FW: "
} + message.subject)
if (preferencesRepository.fillMessageContent || reply != true) {

View File

@ -74,7 +74,7 @@ class SchoolAnnouncementPresenter @Inject constructor(
Status.SUCCESS -> {
Timber.i("Loading School announcement result: Success")
view?.apply {
updateData(it.data!!.sortedByDescending { item -> item.date })
updateData(it.data!!)
showEmpty(it.data.isEmpty())
showErrorView(false)
showContent(it.data.isNotEmpty())

View File

@ -12,6 +12,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.databinding.ItemTimetableBinding
import io.github.wulkanowy.databinding.ItemTimetableSmallBinding
import io.github.wulkanowy.utils.getThemeAttrColor
@ -35,7 +36,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
var onClickListener: (Timetable) -> Unit = {}
private var showWholeClassPlan: String = "no"
private var showWholeClassPlan = TimetableMode.ONLY_CURRENT_GROUP
private var showGroupsInPlan: Boolean = false
@ -47,7 +48,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
fun submitList(
newTimetable: List<Timetable>,
showWholeClassPlan: String = this.showWholeClassPlan,
showWholeClassPlan: TimetableMode = this.showWholeClassPlan,
showGroupsInPlan: Boolean = this.showGroupsInPlan,
showTimers: Boolean = this.showTimers
) {
@ -87,7 +88,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
override fun getItemCount() = items.size
override fun getItemViewType(position: Int) = when {
!items[position].isStudentPlan && showWholeClassPlan == "small" -> ViewType.ITEM_SMALL.ordinal
!items[position].isStudentPlan && showWholeClassPlan == TimetableMode.SMALL_OTHER_GROUP -> ViewType.ITEM_SMALL.ordinal
else -> ViewType.ITEM_NORMAL.ordinal
}

View File

@ -14,6 +14,7 @@ import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.databinding.FragmentTimetableBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
@ -115,7 +116,7 @@ class TimetableFragment : BaseFragment<FragmentTimetableBinding>(R.layout.fragme
override fun updateData(
data: List<Timetable>,
showWholeClassPlanType: String,
showWholeClassPlanType: TimetableMode,
showGroupsInPlanType: Boolean,
showTimetableTimers: Boolean
) {

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.timetable
import android.annotation.SuppressLint
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
@ -197,7 +198,7 @@ class TimetablePresenter @Inject constructor(
}
private fun createItems(items: List<Timetable>) = items.filter { item ->
if (prefRepository.showWholeClassPlan == "no") item.isStudentPlan else true
if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) item.isStudentPlan else true
}.sortedWith(compareBy({ item -> item.number }, { item -> !item.isStudentPlan }))
private fun showErrorViewOnError(message: String, error: Throwable) {

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.ui.modules.timetable
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.ui.base.BaseView
import java.time.LocalDate
@ -12,7 +13,12 @@ interface TimetableView : BaseView {
fun initView()
fun updateData(data: List<Timetable>, showWholeClassPlanType: String, showGroupsInPlanType: Boolean, showTimetableTimers: Boolean)
fun updateData(
data: List<Timetable>,
showWholeClassPlanType: TimetableMode,
showGroupsInPlanType: Boolean,
showTimetableTimers: Boolean
)
fun updateNavigationDay(date: String)

View File

@ -14,6 +14,7 @@ import android.widget.RemoteViewsService
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
@ -88,7 +89,7 @@ class TimetableWidgetFactory(
private fun getItemLayout(lesson: Timetable): Int {
return when {
prefRepository.showWholeClassPlan == "small" && !lesson.isStudentPlan -> {
prefRepository.showWholeClassPlan == TimetableMode.SMALL_OTHER_GROUP && !lesson.isStudentPlan -> {
if (savedCurrentTheme == 0L) R.layout.item_widget_timetable_small
else R.layout.item_widget_timetable_small_dark
}
@ -109,7 +110,11 @@ class TimetableWidgetFactory(
timetableRepository.getTimetable(student, semester, date, date, false)
.toFirstResult().data?.lessons.orEmpty()
.sortedWith(compareBy({ it.number }, { !it.isStudentPlan }))
.filter { if (prefRepository.showWholeClassPlan == "no") it.isStudentPlan else true }
.filter {
if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) {
it.isStudentPlan
} else true
}
}
} catch (e: Exception) {
Timber.e(e, "An error has occurred in timetable widget factory")
@ -124,8 +129,14 @@ class TimetableWidgetFactory(
return RemoteViews(context.packageName, getItemLayout(lesson)).apply {
setTextViewText(R.id.timetableWidgetItemSubject, lesson.subject)
setTextViewText(R.id.timetableWidgetItemNumber, lesson.number.toString())
setTextViewText(R.id.timetableWidgetItemTimeStart, lesson.start.toFormattedString("HH:mm"))
setTextViewText(R.id.timetableWidgetItemTimeFinish, lesson.end.toFormattedString("HH:mm"))
setTextViewText(
R.id.timetableWidgetItemTimeStart,
lesson.start.toFormattedString("HH:mm")
)
setTextViewText(
R.id.timetableWidgetItemTimeFinish,
lesson.end.toFormattedString("HH:mm")
)
updateDescription(this, lesson)
@ -156,11 +167,16 @@ class TimetableWidgetFactory(
private fun updateStylesCanceled(remoteViews: RemoteViews) {
with(remoteViews) {
setInt(R.id.timetableWidgetItemSubject, "setPaintFlags",
STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG)
setInt(
R.id.timetableWidgetItemSubject, "setPaintFlags",
STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG
)
setTextColor(R.id.timetableWidgetItemNumber, context.getCompatColor(primaryColor!!))
setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(primaryColor!!))
setTextColor(R.id.timetableWidgetItemDescription, context.getCompatColor(primaryColor!!))
setTextColor(
R.id.timetableWidgetItemDescription,
context.getCompatColor(primaryColor!!)
)
}
}
@ -168,7 +184,10 @@ class TimetableWidgetFactory(
with(remoteViews) {
setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", ANTI_ALIAS_FLAG)
setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(textColor!!))
setTextColor(R.id.timetableWidgetItemDescription, context.getCompatColor(timetableChangeColor!!))
setTextColor(
R.id.timetableWidgetItemDescription,
context.getCompatColor(timetableChangeColor!!)
)
updateNotCanceledLessonNumberColor(this, lesson)
updateNotCanceledSubjectColor(this, lesson)
@ -180,37 +199,53 @@ class TimetableWidgetFactory(
}
private fun updateNotCanceledLessonNumberColor(remoteViews: RemoteViews, lesson: Timetable) {
remoteViews.setTextColor(R.id.timetableWidgetItemNumber, context.getCompatColor(
if (lesson.changes || (lesson.info.isNotBlank() && !lesson.canceled)) timetableChangeColor!!
else textColor!!
))
remoteViews.setTextColor(
R.id.timetableWidgetItemNumber, context.getCompatColor(
if (lesson.changes || (lesson.info.isNotBlank() && !lesson.canceled)) timetableChangeColor!!
else textColor!!
)
)
}
private fun updateNotCanceledSubjectColor(remoteViews: RemoteViews, lesson: Timetable) {
remoteViews.setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(
if (lesson.subjectOld.isNotBlank() && lesson.subject != lesson.subjectOld) timetableChangeColor!!
else textColor!!
))
remoteViews.setTextColor(
R.id.timetableWidgetItemSubject, context.getCompatColor(
if (lesson.subjectOld.isNotBlank() && lesson.subject != lesson.subjectOld) timetableChangeColor!!
else textColor!!
)
)
}
private fun updateNotCanceledRoom(remoteViews: RemoteViews, lesson: Timetable, teacherChange: Boolean) {
private fun updateNotCanceledRoom(
remoteViews: RemoteViews,
lesson: Timetable,
teacherChange: Boolean
) {
with(remoteViews) {
if (lesson.room.isNotBlank()) {
setTextViewText(R.id.timetableWidgetItemRoom,
setTextViewText(
R.id.timetableWidgetItemRoom,
if (teacherChange) lesson.room
else "${context.getString(R.string.timetable_room)} ${lesson.room}"
)
setTextColor(R.id.timetableWidgetItemRoom, context.getCompatColor(
if (lesson.roomOld.isNotBlank() && lesson.room != lesson.roomOld) timetableChangeColor!!
else textColor!!
))
setTextColor(
R.id.timetableWidgetItemRoom, context.getCompatColor(
if (lesson.roomOld.isNotBlank() && lesson.room != lesson.roomOld) timetableChangeColor!!
else textColor!!
)
)
} else setTextViewText(R.id.timetableWidgetItemRoom, "")
}
}
private fun updateNotCanceledTeacher(remoteViews: RemoteViews, lesson: Timetable, teacherChange: Boolean) {
remoteViews.setTextViewText(R.id.timetableWidgetItemTeacher,
private fun updateNotCanceledTeacher(
remoteViews: RemoteViews,
lesson: Timetable,
teacherChange: Boolean
) {
remoteViews.setTextViewText(
R.id.timetableWidgetItemTeacher,
if (teacherChange) lesson.teacher
else ""
)

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.utils
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.github.wulkanowy.sdk.scrapper.grades.isGradeValid
fun List<Grade>.calcAverage(isOptionalArithmeticAverage: Boolean): Double {
@ -37,28 +38,6 @@ fun List<GradeSummary>.calcFinalAverage(plusModifier: Double, minusModifier: Dou
.average()
.let { if (it.isNaN()) 0.0 else it }
fun Grade.getBackgroundColor(theme: String) = when (theme) {
"grade_color" -> getGradeColor()
"material" -> when (value.toInt()) {
6 -> R.color.grade_material_six
5 -> R.color.grade_material_five
4 -> R.color.grade_material_four
3 -> R.color.grade_material_three
2 -> R.color.grade_material_two
1 -> R.color.grade_material_one
else -> R.color.grade_material_default
}
else -> when (value.toInt()) {
6 -> R.color.grade_vulcan_six
5 -> R.color.grade_vulcan_five
4 -> R.color.grade_vulcan_four
3 -> R.color.grade_vulcan_three
2 -> R.color.grade_vulcan_two
1 -> R.color.grade_vulcan_one
else -> R.color.grade_vulcan_default
}
}
fun Grade.getGradeColor() = when (color) {
"000000" -> R.color.grade_black
"F04C4C" -> R.color.grade_red
@ -83,3 +62,25 @@ fun Grade.changeModifier(plusModifier: Double, minusModifier: Double) = when {
modifier < 0 -> copy(modifier = -minusModifier)
else -> this
}
fun Grade.getBackgroundColor(theme: GradeColorTheme) = when (theme) {
GradeColorTheme.GRADE_COLOR -> getGradeColor()
GradeColorTheme.MATERIAL -> when (value.toInt()) {
6 -> R.color.grade_material_six
5 -> R.color.grade_material_five
4 -> R.color.grade_material_four
3 -> R.color.grade_material_three
2 -> R.color.grade_material_two
1 -> R.color.grade_material_one
else -> R.color.grade_material_default
}
GradeColorTheme.VULCAN -> when (value.toInt()) {
6 -> R.color.grade_vulcan_six
5 -> R.color.grade_vulcan_five
4 -> R.color.grade_vulcan_four
3 -> R.color.grade_vulcan_three
2 -> R.color.grade_vulcan_two
1 -> R.color.grade_vulcan_one
else -> R.color.grade_vulcan_default
}
}

View File

@ -1,6 +1,6 @@
Wersja 1.4.3
Wersja 1.4.4
Naprawiliśmy drobne problemy ze stabilnością oraz małą usterkę w wyszukiwarce wiadomości.
Wszystko po to, aby jeszcze bardziej podnieść komfort z używania aplikacji!
- naprawiliśmy logowanie do Gdańskiej Platformy Edukacyjnej
- naprawiliśmy sortowanie ocen oraz ogłoszeń
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases

View File

@ -553,18 +553,6 @@
<string name="dashboard_timetable_first_lesson_title_soon">Brzy:</string>
<string name="dashboard_timetable_first_lesson_title_first">První:</string>
<string name="dashboard_timetable_first_lesson_title_now">Teď:</string>
<plurals name="dashboard_timetable_first_lesson_time_in_minutes">
<item quantity="one">za %1$d minutu</item>
<item quantity="few">za %1$d minuty</item>
<item quantity="many">za %1$d minut</item>
<item quantity="other">za %1$d minut</item>
</plurals>
<plurals name="dashboard_timetable_first_lesson_time_more_minutes">
<item quantity="one">ještě %1$d minutu</item>
<item quantity="few">ještě %1$d minuty</item>
<item quantity="many">ještě %1$d minut</item>
<item quantity="other">ještě %1$d minut</item>
</plurals>
<string name="dashboard_timetable_second_lesson_value_end">Konec lekcí</string>
<string name="dashboard_timetable_second_lessons_title">Další:</string>
<string name="dashboard_timetable_third_title">Později:</string>

View File

@ -477,14 +477,6 @@
<string name="dashboard_timetable_first_lesson_title_soon">Bald:</string>
<string name="dashboard_timetable_first_lesson_title_first">Erstens:</string>
<string name="dashboard_timetable_first_lesson_title_now">Jetzt:</string>
<plurals name="dashboard_timetable_first_lesson_time_in_minutes">
<item quantity="one">in %1$d Minute</item>
<item quantity="other">in %1$d Minuten</item>
</plurals>
<plurals name="dashboard_timetable_first_lesson_time_more_minutes">
<item quantity="one">Noch %1$d Minute</item>
<item quantity="other">Noch %1$d Minuten</item>
</plurals>
<string name="dashboard_timetable_second_lesson_value_end">Ende der Lektion</string>
<string name="dashboard_timetable_second_lessons_title">Nächste:</string>
<string name="dashboard_timetable_third_title">Später:</string>

View File

@ -553,18 +553,6 @@
<string name="dashboard_timetable_first_lesson_title_soon">Wkrótce:</string>
<string name="dashboard_timetable_first_lesson_title_first">Pierwsza:</string>
<string name="dashboard_timetable_first_lesson_title_now">Teraz:</string>
<plurals name="dashboard_timetable_first_lesson_time_in_minutes">
<item quantity="one">za %1$d minutę</item>
<item quantity="few">za %1$d minuty</item>
<item quantity="many">za %1$d minut</item>
<item quantity="other">za %1$d minut</item>
</plurals>
<plurals name="dashboard_timetable_first_lesson_time_more_minutes">
<item quantity="one">jeszcze %1$d minuta</item>
<item quantity="few">jeszcze %1$d minuty</item>
<item quantity="many">jeszcze %1$d minut</item>
<item quantity="other">jeszcze %1$d minut</item>
</plurals>
<string name="dashboard_timetable_second_lesson_value_end">Koniec lekcji</string>
<string name="dashboard_timetable_second_lessons_title">Następnie:</string>
<string name="dashboard_timetable_third_title">Później:</string>

View File

@ -553,18 +553,6 @@
<string name="dashboard_timetable_first_lesson_title_soon">Скоро:</string>
<string name="dashboard_timetable_first_lesson_title_first">Первый:</string>
<string name="dashboard_timetable_first_lesson_title_now">Сейчас:</string>
<plurals name="dashboard_timetable_first_lesson_time_in_minutes">
<item quantity="one">через %1$d минуту</item>
<item quantity="few">через %1$d минуту</item>
<item quantity="many">через %1$d минуту</item>
<item quantity="other">через %1$d минут</item>
</plurals>
<plurals name="dashboard_timetable_first_lesson_time_more_minutes">
<item quantity="one">Еще %1$d минута</item>
<item quantity="few">Еще %1$d минута</item>
<item quantity="many">Еще %1$d минута</item>
<item quantity="other">Ещё %1$d минут</item>
</plurals>
<string name="dashboard_timetable_second_lesson_value_end">Окончание уроков</string>
<string name="dashboard_timetable_second_lessons_title">Далее:</string>
<string name="dashboard_timetable_third_title">Позднее:</string>

View File

@ -553,18 +553,6 @@
<string name="dashboard_timetable_first_lesson_title_soon">Čoskoro:</string>
<string name="dashboard_timetable_first_lesson_title_first">Prvá:</string>
<string name="dashboard_timetable_first_lesson_title_now">Teraz:</string>
<plurals name="dashboard_timetable_first_lesson_time_in_minutes">
<item quantity="one">za %1$d minútu</item>
<item quantity="few">za %1$d minúty</item>
<item quantity="many">za %1$d minút</item>
<item quantity="other">za %1$d minút</item>
</plurals>
<plurals name="dashboard_timetable_first_lesson_time_more_minutes">
<item quantity="one">ešte %1$d minútu</item>
<item quantity="few">ešte %1$d minúty</item>
<item quantity="many">ešte %1$d minút</item>
<item quantity="other">ešte %1$d minút</item>
</plurals>
<string name="dashboard_timetable_second_lesson_value_end">Koniec lekcií</string>
<string name="dashboard_timetable_second_lessons_title">Ďalej:</string>
<string name="dashboard_timetable_third_title">Neskôr:</string>

View File

@ -553,18 +553,6 @@
<string name="dashboard_timetable_first_lesson_title_soon">Незабаром:</string>
<string name="dashboard_timetable_first_lesson_title_first">Перше:</string>
<string name="dashboard_timetable_first_lesson_title_now">Зараз:</string>
<plurals name="dashboard_timetable_first_lesson_time_in_minutes">
<item quantity="one">через %1$d хвилину</item>
<item quantity="few">через %1$d хвилину</item>
<item quantity="many">через %1$d хвилину</item>
<item quantity="other">через %1$d хвилин</item>
</plurals>
<plurals name="dashboard_timetable_first_lesson_time_more_minutes">
<item quantity="one">%1$d більше хвилини</item>
<item quantity="few">%1$d більше хвилини</item>
<item quantity="many">%1$d більше хвилини</item>
<item quantity="other">%1$d ще хвилин</item>
</plurals>
<string name="dashboard_timetable_second_lesson_value_end">Кінець уроків</string>
<string name="dashboard_timetable_second_lessons_title">Далі:</string>
<string name="dashboard_timetable_third_title">Пізніше :</string>

View File

@ -71,7 +71,7 @@
<string name="login_contact_discord">Discord</string>
<string name="login_email_intent_title">Send email</string>
<string name="login_email_subject" translatable="false">Zgłoszenie: Problemy z logowaniem</string>
<string name="login_email_text" translatable="false">Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\nDodatkowe informacje: %4$s\nOstatni błąd: %5$s\n\nPełna nazwa szkoły i klasa ucznia: </string>
<string name="login_email_text" translatable="false">Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\nDodatkowe informacje: %4$s\nOstatni błąd: %5$s\n\nNazwa szkoły wraz z miejscowością i numer klasy: </string>
<string name="login_recover_warning">Make sure you select the correct UONET+ register variation!</string>
<string name="login_recover_button">I forgot my password</string>
<string name="login_recover_title">Recover your account</string>
@ -247,8 +247,8 @@
<item quantity="other">New exams</item>
</plurals>
<plurals name="exam_notify_new_item_content">
<item quantity="one">You received %d new exam</item>
<item quantity="other">You received %d new exams</item>
<item quantity="one">%d new exam</item>
<item quantity="other">%d new exams</item>
</plurals>
<plurals name="exam_number_item">
<item quantity="one">%d exam</item>
@ -541,14 +541,6 @@
<string name="dashboard_timetable_first_lesson_title_soon">Soon:</string>
<string name="dashboard_timetable_first_lesson_title_first">First:</string>
<string name="dashboard_timetable_first_lesson_title_now">Now:</string>
<plurals name="dashboard_timetable_first_lesson_time_in_minutes">
<item quantity="one">in %1$d minute</item>
<item quantity="other">in %1$d minutes</item>
</plurals>
<plurals name="dashboard_timetable_first_lesson_time_more_minutes">
<item quantity="one">%1$d more minute</item>
<item quantity="other">%1$d more minutes</item>
</plurals>
<string name="dashboard_timetable_second_lesson_value_end">End of lessons</string>
<string name="dashboard_timetable_second_lessons_title">Next:</string>
<string name="dashboard_timetable_third_title">Later:</string>

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.utils
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.enums.GradeColorTheme
import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.MockK
import org.junit.Assert.assertEquals
@ -46,10 +47,25 @@ class GradeExtensionTest {
@Test
fun getBackgroundColor() {
assertEquals(R.color.grade_material_five, createGrade(5.0).getBackgroundColor("material"))
assertEquals(R.color.grade_material_five, createGrade(5.5).getBackgroundColor("material"))
assertEquals(R.color.grade_material_five, createGrade(5.9).getBackgroundColor("material"))
assertEquals(R.color.grade_vulcan_five, createGrade(5.9).getBackgroundColor("whatever"))
assertEquals(
R.color.grade_material_five, createGrade(5.0).getBackgroundColor(
GradeColorTheme.MATERIAL
)
)
assertEquals(
R.color.grade_material_five, createGrade(5.5).getBackgroundColor(
GradeColorTheme.MATERIAL
)
)
assertEquals(
R.color.grade_material_five, createGrade(5.9).getBackgroundColor(
GradeColorTheme.MATERIAL
)
)
assertEquals(
R.color.grade_vulcan_five,
createGrade(5.9).getBackgroundColor(GradeColorTheme.VULCAN)
)
}
@Test

View File

@ -2,7 +2,7 @@ buildscript {
ext {
kotlin_version = '1.6.0'
about_libraries = '8.9.4'
hilt_version = "2.40.2"
hilt_version = "2.40.5"
}
repositories {
mavenCentral()
@ -13,11 +13,11 @@ buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath 'com.android.tools.build:gradle:7.0.3'
classpath 'com.android.tools.build:gradle:7.0.4'
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.huawei.agconnect:agcp:1.6.2.200'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.0'
classpath 'com.huawei.agconnect:agcp:1.6.2.300'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
classpath "com.github.triplet.gradle:play-publisher:3.6.0"
classpath "ru.cian:huawei-publish-gradle-plugin:1.3.0"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3"