add: new settings view

merge #9
This commit is contained in:
Franek 2024-03-21 23:41:09 +01:00 committed by GitHub
commit e5412086d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 590 additions and 334 deletions

View File

@ -1,7 +1,7 @@
[*] [*]
charset=utf-8 charset=utf-8
end_of_line=lf end_of_line=lf
insert_final_newline=true insert_final_newline=Advanced
indent_style=space indent_style=space
indent_size=4 indent_size=4

View File

@ -3,12 +3,12 @@
# Wulkanowy MOD # Wulkanowy MOD
## Funkce: ## Funkce:
* skrýt špatná hodnocení * skrýt známky
* skrýt špatnou docházku (vše kromě oprávněné docházky/docházky) * Skrýt jednotlivé záznamy o docházce.
* skrýt komentáře * Skrýt komentáře.
* falešná účast * falešná docházka %
Chcete-li se dostat do skrytého panelu, přejděte na kartu „Další“ a poté dlouze stiskněte dlaždici „Nastavení“. Pro přístup ke skrytému panelu přejděte na kartu "Více", poté na "Nastavení" a nakonec klikněte na poslední dlaždici.
# Wulkanowy # Wulkanowy

View File

@ -3,12 +3,12 @@
# Wulkanowy MOD # Wulkanowy MOD
## Funktionen: ## Funktionen:
* schlechte Bewertungen ausblenden * Noten ausblenden
* schlechte Anwesenheit ausblenden (alles außer berechtigter Anwesenheit/Anwesenheit) * Individuelle Anwesenheitslisten ausblenden.
* Kommentare ausblenden * Kommentare ausblenden.
* gefälschte Anwesenheit * Anwesenheit fälschen %
Um zum ausgeblendeten Bereich zu gelangen, gehen Sie zur Registerkarte „Mehr“ und drücken Sie dann lange auf die Kachel „Einstellungen“. Um auf das verborgene Panel zuzugreifen, gehen Sie auf die Registerkarte "Mehr", dann auf "Einstellungen" und schließlich auf die letzte Kachel.
# Wulkanowy # Wulkanowy

View File

@ -3,12 +3,12 @@
# Wulkanowy MOD # Wulkanowy MOD
## Functions: ## Functions:
* hide bad grades * hide grades
* hide bad attendance (everything except present/excused attendance) * hide individual attendance entries
* hide comments * hide comments
* fake attendance * fake attendance %.
To get to the hidden panel, go to the "More" tab and then long-press the "Settings" tile. To get to the hidden panel, go to the "More" tab, then "Settings", and finally click the last tile.
# Wulkanowy # Wulkanowy

View File

@ -3,12 +3,12 @@
# Wulkanowy MOD # Wulkanowy MOD
## Funkcje: ## Funkcje:
* ukryj złe oceny * ukryj oceny
* ukryj złą frekwencję (wszystko prócz obecności/frekwencji usprawiedliwionej) * ukryj poszczególne wpisy frekwencji
* ukryj uwagi * ukryj uwagi
* sfałszuj frekwencję * sfałszuj % frekwencji
Aby dostać się do ukrytego panelu, przejdź do karty "Więcej", a następnie przytrzymaj kafelek "Ustawienia". Aby dostać się do ukrytego panelu, przejdź do karty "Więcej", następnie "Ustawienia", a na końcu kliknij ostatni kafelek.
# Wulkanowy # Wulkanowy

View File

@ -3,12 +3,12 @@
# Wulkanowy MOD # Wulkanowy MOD
## Funkcie: ## Funkcie:
* skryť zlé hodnotenia * skryť známky
* skryť zlú dochádzku (všetko okrem odôvodnenej dochádzky/dochádzky) * Skryť individuálne záznamy o dochádzke.
* skryť komentáre * Skryť komentáre.
* falošná účasť * falošná dochádzka %
Ak chcete prejsť na skrytý panel, prejdite na kartu „Viac“ a potom dlho stlačte dlaždicu „Nastavenia“. Ak chcete získať prístup k skrytému panelu, prejdite na kartu "Viac", potom na "Nastavenia" a nakoniec kliknite na poslednú dlaždicu.
# Wulkanowy # Wulkanowy

View File

@ -28,7 +28,7 @@ android {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 34 targetSdkVersion 34
versionCode 151 versionCode 151
versionName "2.5.2" versionName "2.6.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy" resValue "string", "app_name", "Wulkanowy"

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import java.time.LocalDate import java.time.LocalDate
import javax.inject.Singleton import javax.inject.Singleton
@ -18,12 +19,4 @@ interface AttendanceDao : BaseDao<Attendance> {
start: LocalDate, start: LocalDate,
end: LocalDate end: LocalDate
): Flow<List<Attendance>> ): Flow<List<Attendance>>
@Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :start AND date <= :end AND (presence OR excused)")
fun loadAllCensored(
diaryId: Int,
studentId: Int,
start: LocalDate,
end: LocalDate
): Flow<List<Attendance>>
} }

View File

@ -11,7 +11,4 @@ import javax.inject.Singleton
interface NoteDao : BaseDao<Note> { interface NoteDao : BaseDao<Note> {
@Query("SELECT * FROM Notes WHERE student_id = :studentId") @Query("SELECT * FROM Notes WHERE student_id = :studentId")
fun loadAll(studentId: Int): Flow<List<Note>> fun loadAll(studentId: Int): Flow<List<Note>>
@Query("SELECT * FROM Notes WHERE student_id = :studentId AND 1 != 1")
fun pretendLoadingAll(studentId: Int): Flow<List<Note>>
} }

View File

@ -9,6 +9,7 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.mappers.mapToEntities import io.github.wulkanowy.data.mappers.mapToEntities
import io.github.wulkanowy.data.networkBoundResource import io.github.wulkanowy.data.networkBoundResource
import io.github.wulkanowy.sdk.pojo.Absent import io.github.wulkanowy.sdk.pojo.Absent
import io.github.wulkanowy.sdk.pojo.Attendance as SdkAttendance
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.utils.AutoRefreshHelper import io.github.wulkanowy.utils.AutoRefreshHelper
import io.github.wulkanowy.utils.getRefreshKey import io.github.wulkanowy.utils.getRefreshKey
@ -16,6 +17,7 @@ import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.sunday import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract import io.github.wulkanowy.utils.uniqueSubtract
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
@ -36,6 +38,64 @@ class AttendanceRepository @Inject constructor(
private val cacheKey = "attendance" private val cacheKey = "attendance"
private fun filterAttendance(
hiddenAttendanceTiles: List<DashboardItem.HiddenAttendanceTile>,
attendanceItem: Attendance
): Boolean {
return when {
attendanceItem.absence && attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.EXCUSED_ABSENCE
) -> false
attendanceItem.absence && !attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.UNEXCUSED_ABSENCE
) -> false
attendanceItem.lateness && attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.EXCUSED_LATENESS
) -> false
attendanceItem.lateness && !attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.UNEXCUSED_LATENESS
) -> false
attendanceItem.exemption && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.EXEMPTION) -> false
attendanceItem.deleted && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.DELETED) -> false
attendanceItem.presence && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.PRESENT) -> false
else -> !hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.UNKNOWN)
}
}
private fun filterAttendance(
hiddenAttendanceTiles: List<DashboardItem.HiddenAttendanceTile>,
attendanceItem: SdkAttendance
): Boolean {
return when {
attendanceItem.absence && attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.EXCUSED_ABSENCE
) -> false
attendanceItem.absence && !attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.UNEXCUSED_ABSENCE
) -> false
attendanceItem.lateness && attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.EXCUSED_LATENESS
) -> false
attendanceItem.lateness && !attendanceItem.excused && hiddenAttendanceTiles.contains(
DashboardItem.HiddenAttendanceTile.UNEXCUSED_LATENESS
) -> false
attendanceItem.exemption && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.EXEMPTION) -> false
attendanceItem.deleted && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.DELETED) -> false
attendanceItem.presence && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.PRESENT) -> false
else -> !hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.UNKNOWN)
}
}
fun getAttendance( fun getAttendance(
student: Student, student: Student,
semester: Semester, semester: Semester,
@ -53,30 +113,16 @@ class AttendanceRepository @Inject constructor(
it.isEmpty() || forceRefresh || isExpired it.isEmpty() || forceRefresh || isExpired
}, },
query = { query = {
val badAttendanceHidden = preferencesRepository val hiddenAttendanceItems = preferencesRepository.hiddenAttendanceItems
.selectedHiddenSettingTiles
.contains(DashboardItem.HiddenSettingTile.NOTES)
if (badAttendanceHidden) { attendanceDb
attendanceDb.loadAllCensored( .loadAll(semester.diaryId, semester.studentId, start.monday, end.sunday)
semester.diaryId, .map {
semester.studentId, it.filter { item -> filterAttendance(hiddenAttendanceItems, item) }
start.monday, }
end.sunday
)
} else {
attendanceDb.loadAll(
semester.diaryId,
semester.studentId,
start.monday,
end.sunday
)
}
}, },
fetch = { fetch = {
val badAttendanceHidden = preferencesRepository val hiddenAttendanceItems = preferencesRepository.hiddenAttendanceItems
.selectedHiddenSettingTiles
.contains(DashboardItem.HiddenSettingTile.NOTES)
val lessons = timetableDb.load( val lessons = timetableDb.load(
semester.diaryId, semester.studentId, start.monday, end.sunday semester.diaryId, semester.studentId, start.monday, end.sunday
@ -84,7 +130,7 @@ class AttendanceRepository @Inject constructor(
wulkanowySdkFactory.create(student, semester) wulkanowySdkFactory.create(student, semester)
.getAttendance(start.monday, end.sunday) .getAttendance(start.monday, end.sunday)
.filter { !badAttendanceHidden || (it.presence || it.excused) } .filter { item -> filterAttendance(hiddenAttendanceItems, item) }
.mapToEntities(semester, lessons) .mapToEntities(semester, lessons)
}, },
saveFetchResult = { old, new -> saveFetchResult = { old, new ->
@ -105,15 +151,13 @@ class AttendanceRepository @Inject constructor(
start: LocalDate, start: LocalDate,
end: LocalDate end: LocalDate
): Flow<List<Attendance>> { ): Flow<List<Attendance>> {
val badAttendanceHidden = preferencesRepository val hiddenAttendanceItems = preferencesRepository.hiddenAttendanceItems
.selectedHiddenSettingTiles
.contains(DashboardItem.HiddenSettingTile.BAD_ATTENDANCE)
return if (badAttendanceHidden) { return attendanceDb
attendanceDb.loadAllCensored(semester.diaryId, semester.studentId, start, end) .loadAll(semester.diaryId, semester.studentId, start.monday, end.sunday)
} else { .map {
attendanceDb.loadAll(semester.diaryId, semester.studentId, start, end) it.filter { item -> filterAttendance(hiddenAttendanceItems, item) }
} }
} }
suspend fun updateTimetable(timetable: List<Attendance>) { suspend fun updateTimetable(timetable: List<Attendance>) {

View File

@ -7,7 +7,6 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.mappers.mapToEntities import io.github.wulkanowy.data.mappers.mapToEntities
import io.github.wulkanowy.data.networkBoundResource import io.github.wulkanowy.data.networkBoundResource
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.utils.AutoRefreshHelper import io.github.wulkanowy.utils.AutoRefreshHelper
import io.github.wulkanowy.utils.getRefreshKey import io.github.wulkanowy.utils.getRefreshKey
import io.github.wulkanowy.utils.toLocalDate import io.github.wulkanowy.utils.toLocalDate
@ -41,27 +40,16 @@ class NoteRepository @Inject constructor(
val isExpired = refreshHelper.shouldBeRefreshed( val isExpired = refreshHelper.shouldBeRefreshed(
getRefreshKey(cacheKey, semester) getRefreshKey(cacheKey, semester)
) )
it.isEmpty() || forceRefresh || isExpired it.isEmpty() || forceRefresh || isExpired
}, },
query = { query = { noteDb.loadAll(student.studentId) },
val notesHidden = preferencesRepository
.selectedHiddenSettingTiles
.contains(DashboardItem.HiddenSettingTile.NOTES)
if (notesHidden) {
noteDb.pretendLoadingAll(student.studentId)
} else {
noteDb.loadAll(student.studentId)
}
},
fetch = { fetch = {
val notesHidden = preferencesRepository val showNotes = preferencesRepository.showNotes
.selectedHiddenSettingTiles
.contains(DashboardItem.HiddenSettingTile.NOTES)
wulkanowySdkFactory.create(student, semester) wulkanowySdkFactory.create(student, semester)
.getNotes() .getNotes()
.filter { !notesHidden } .filter { showNotes }
.mapToEntities(semester) .mapToEntities(semester)
}, },
saveFetchResult = { old, new -> saveFetchResult = { old, new ->
@ -80,15 +68,7 @@ class NoteRepository @Inject constructor(
) )
fun getNotesFromDatabase(student: Student): Flow<List<Note>> { fun getNotesFromDatabase(student: Student): Flow<List<Note>> {
val notesHidden = preferencesRepository return noteDb.loadAll(student.studentId)
.selectedHiddenSettingTiles
.contains(DashboardItem.HiddenSettingTile.NOTES)
return if (notesHidden) {
noteDb.pretendLoadingAll(student.studentId)
} else {
noteDb.loadAll(student.studentId)
}
} }
suspend fun updateNote(note: Note) { suspend fun updateNote(note: Note) {

View File

@ -2,13 +2,12 @@ package io.github.wulkanowy.data.repositories
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.content.edit import androidx.core.content.edit
import com.fredporciuncula.flow.preferences.FlowSharedPreferences import com.fredporciuncula.flow.preferences.FlowSharedPreferences
import com.fredporciuncula.flow.preferences.Preference import com.fredporciuncula.flow.preferences.Preference
import com.fredporciuncula.flow.preferences.Serializer import com.fredporciuncula.flow.preferences.Serializer
import com.fredporciuncula.flow.preferences.map
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.enums.AppTheme import io.github.wulkanowy.data.enums.AppTheme
@ -25,7 +24,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.internal.notifyAll import timber.log.Timber
import java.time.Instant import java.time.Instant
import java.util.UUID import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
@ -38,6 +37,8 @@ class PreferencesRepository @Inject constructor(
private val flowSharedPref: FlowSharedPreferences, private val flowSharedPref: FlowSharedPreferences,
private val json: Json, private val json: Json,
) { ) {
private val NO_ATTENDANCE_VALUE = -1.0
val isShowPresent: Boolean val isShowPresent: Boolean
get() = getBoolean( get() = getBoolean(
R.string.pref_key_attendance_present, R.string.pref_key_attendance_present,
@ -296,33 +297,22 @@ class PreferencesRepository @Inject constructor(
selectedDashboardTilesPreference.set(filteredValue) selectedDashboardTilesPreference.set(filteredValue)
} }
var selectedHiddenSettingTiles: List<DashboardItem.HiddenSettingTile> var attendancePercentage: Double?
get() = selectedHiddenSettingTilesPreference.get() get() = attendancePercentagePreference.get().takeIf { it != NO_ATTENDANCE_VALUE }
.map { DashboardItem.HiddenSettingTile.valueOf(it) } set(value) = attendancePercentagePreference.set(value ?: NO_ATTENDANCE_VALUE)
set(value) {
val filteredValue = value
.map { it.name }
.toSet()
selectedHiddenSettingTilesPreference.set(filteredValue) var hiddenAttendanceItems: List<DashboardItem.HiddenAttendanceTile>
} get() = hiddenAttendanceItemsPreference.get().toList()
set(value) = hiddenAttendanceItemsPreference.set(value.toSet())
var attendancePercentage: Float?
get() {
val value = attendancePercentagePreference.get()
return if (value == context.resources.getInteger(R.integer.pref_default_attendance_percentage).toFloat()) {
null
} else {
value
}
}
set(value) = value?.let { attendancePercentagePreference.set(it) }
?: attendancePercentagePreference.delete()
var hiddenGrades: List<String> var hiddenGrades: List<String>
get() = hiddenGradesPreference.get().toList() get() = hiddenGradesPreference.get().toList()
set(value) = hiddenGradesPreference.set(value.toSet()) set(value) = hiddenGradesPreference.set(value.toSet())
var showNotes: Boolean
get() = showNotesPreference.get()
set(value) = showNotesPreference.set(value)
private val hiddenGradesPreference: Preference<Set<String>> private val hiddenGradesPreference: Preference<Set<String>>
get() { get() {
val defaultSet = context.resources.getStringArray(R.array.pref_default_hidden_grades).toSet() val defaultSet = context.resources.getStringArray(R.array.pref_default_hidden_grades).toSet()
@ -331,6 +321,26 @@ class PreferencesRepository @Inject constructor(
return flowSharedPref.getStringSet(prefKey, defaultSet) return flowSharedPref.getStringSet(prefKey, defaultSet)
} }
private val showNotesPreference: Preference<Boolean>
get() = flowSharedPref.getBoolean(
context.getString(R.string.pref_key_show_notes),
context.resources.getBoolean(R.bool.pref_default_show_notes)
)
private val hiddenAttendanceItemsPreference: Preference<Set<DashboardItem.HiddenAttendanceTile>>
get() {
val defaultSet =
context.resources.getStringArray(R.array.pref_default_hidden_attendance_items).toSet()
val prefKey = "attendance_items"
return flowSharedPref
.getStringSet(prefKey, defaultSet)
.map(
mapper = { it -> it.map { DashboardItem.HiddenAttendanceTile.valueOf(it) }.toSet() },
reverse = { it -> it.map { it.name }.toSet() }
)
}
private val selectedDashboardTilesPreference: Preference<Set<String>> private val selectedDashboardTilesPreference: Preference<Set<String>>
get() { get() {
val defaultSet = val defaultSet =
@ -340,21 +350,19 @@ class PreferencesRepository @Inject constructor(
return flowSharedPref.getStringSet(prefKey, defaultSet) return flowSharedPref.getStringSet(prefKey, defaultSet)
} }
private val selectedHiddenSettingTilesPreference: Preference<Set<String>> private val attendancePercentagePreference: Preference<Double>
get() { get() {
val defaultSet = val prefKey = context.getString(R.string.pref_key_attendance_percentage)
context.resources.getStringArray(R.array.pref_default_hidden_settings_tiles).toSet() val defaultValue = context.resources.getString(R.string.pref_default_attendance_percentage)
val prefKey = "hidden_settings_tiles"
return flowSharedPref.getStringSet(prefKey, defaultSet) return flowSharedPref
.getString(prefKey, defaultValue)
.map(
mapper = { it.toDoubleOrNull() ?: NO_ATTENDANCE_VALUE },
reverse = { it.toString() }
)
} }
private val attendancePercentagePreference: Preference<Float>
get() = flowSharedPref.getFloat(
context.getString(R.string.pref_key_attendance_percentage),
context.resources.getInteger(R.integer.pref_default_attendance_percentage).toFloat()
)
var dismissedAdminMessageIds: List<Int> var dismissedAdminMessageIds: List<Int>
get() = sharedPref.getStringSet(PREF_KEY_ADMIN_DISMISSED_MESSAGE_IDS, emptySet()) get() = sharedPref.getStringSet(PREF_KEY_ADMIN_DISMISSED_MESSAGE_IDS, emptySet())
.orEmpty() .orEmpty()

View File

@ -54,7 +54,7 @@ class AttendanceSummaryAdapter @Inject constructor(
private fun bindHeaderViewHolder(binding: ScrollableHeaderAttendanceSummaryBinding) { private fun bindHeaderViewHolder(binding: ScrollableHeaderAttendanceSummaryBinding) {
binding.attendanceSummaryScrollableHeaderPercentage.text = formatPercentage( binding.attendanceSummaryScrollableHeaderPercentage.text = formatPercentage(
attendancePercentage?.toDouble() ?: attendancePercentage ?:
items.calculatePercentage() items.calculatePercentage()
) )
} }
@ -68,8 +68,8 @@ class AttendanceSummaryAdapter @Inject constructor(
else -> item.month.getFormattedName() else -> item.month.getFormattedName()
} }
attendanceSummaryPercentage.text = when (position) { attendanceSummaryPercentage.text = when (position) {
-1 -> formatPercentage(attendancePercentage?.toDouble() ?: item.calculatePercentage()) -1 -> formatPercentage(attendancePercentage ?: item.calculatePercentage())
else -> formatPercentage(attendancePercentage?.toDouble() ?: item.calculatePercentage()) else -> formatPercentage(attendancePercentage ?: item.calculatePercentage())
} }
attendanceSummaryPresent.text = item.presence.toString() attendanceSummaryPresent.text = item.presence.toString()

View File

@ -148,10 +148,15 @@ sealed class DashboardItem(val type: Type) {
CONFERENCES, CONFERENCES,
} }
enum class HiddenSettingTile { enum class HiddenAttendanceTile {
BAD_ATTENDANCE, UNEXCUSED_ABSENCE,
NOTES, EXEMPTION,
ATTENDANCE, EXCUSED_LATENESS,
UNEXCUSED_LATENESS,
PRESENT,
DELETED,
EXCUSED_ABSENCE,
UNKNOWN,
} }
} }

View File

@ -338,7 +338,7 @@ class DashboardPresenter @Inject constructor(
} else null } else null
}, },
attendancePercentage = DashboardItem.HorizontalGroup.Cell( attendancePercentage = DashboardItem.HorizontalGroup.Cell(
data = attendancePercentage?.toDouble() ?: attendanceResource.dataOrNull?.calculatePercentage(), data = attendancePercentage ?: attendanceResource.dataOrNull?.calculatePercentage(),
error = attendanceResource.errorOrNull != null, error = attendanceResource.errorOrNull != null,
isLoading = attendanceResource is Resource.Loading, isLoading = attendanceResource is Resource.Loading,
), ),

View File

@ -1,45 +1,19 @@
package io.github.wulkanowy.ui.modules.more package io.github.wulkanowy.ui.modules.more
import android.os.Bundle import android.os.Bundle
import android.text.InputFilter
import android.text.InputType
import android.text.Spanned
import android.view.View import android.view.View
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.databinding.FragmentMoreBinding import io.github.wulkanowy.databinding.FragmentMoreBinding
import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.Destination import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.MessageFragment import io.github.wulkanowy.ui.modules.message.MessageFragment
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
private class AttendancePercentageFilter : InputFilter {
override fun filter(
source: CharSequence?,
start: Int,
end: Int,
dest: Spanned?,
dstart: Int,
dend: Int
): CharSequence? {
val input = dest.toString() + source.toString()
val floatRepresentation = input.toFloatOrNull()
if (floatRepresentation != null && floatRepresentation in 0.0..100.0) return null
return ""
}
}
@AndroidEntryPoint @AndroidEntryPoint
class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more), MoreView, class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more), MoreView,
MainView.TitledView, MainView.MainChildView { MainView.TitledView, MainView.MainChildView {
@ -68,7 +42,6 @@ class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more),
override fun initView() { override fun initView() {
moreAdapter.onClickListener = presenter::onItemSelected moreAdapter.onClickListener = presenter::onItemSelected
moreAdapter.onLongClickListener = presenter::onItemHold
with(binding.moreRecycler) { with(binding.moreRecycler) {
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
@ -105,68 +78,6 @@ class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more),
super.onDestroyView() super.onDestroyView()
} }
private fun showGradeDialog() {
val hiddenGrades = preferencesRepository.hiddenGrades
val grades = requireContext().resources.getStringArray(R.array.hidden_settings_bad_grades)
val selectedItemsState = grades.map { grade -> hiddenGrades.any { it == grade } }
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.pref_hidden_settings_hide_grades_title)
.setMultiChoiceItems(grades, selectedItemsState.toBooleanArray()) { _, _, _ -> }
.setPositiveButton(android.R.string.ok) { dialog, _ ->
val selectedState = (dialog as AlertDialog).listView.checkedItemPositions
val selectedValues = grades.filterIndexed { index, _ -> selectedState[index] }
Timber.i("Selected hidden grades: $selectedValues")
presenter.onHiddenGradesSelected(selectedValues)
}
.show()
}
override fun showHiddenSettings(data: List<DashboardItem.HiddenSettingTile>) {
val entries = requireContext().resources.getStringArray(R.array.hidden_settings_entries)
val values = requireContext().resources.getStringArray(R.array.hidden_settings_values)
val selectedItemsState = values.map { value -> data.any { it.name == value } }
val attendancePercentage = preferencesRepository.attendancePercentage
val input = EditText(requireContext()).apply {
setPadding(40, 20, 40, 20)
hint = requireContext().getString(R.string.pref_hidden_settings_hint)
filters = arrayOf(AttendancePercentageFilter())
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
}
// enable only if attendance modifier is enabled
val attendanceModifierEnabled = data.any { it == DashboardItem.HiddenSettingTile.ATTENDANCE }
input.isEnabled = attendanceModifierEnabled
if (attendancePercentage != null) input.setText(attendancePercentage.toString())
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.pref_hidden_settings_title)
.setMultiChoiceItems(entries, selectedItemsState.toBooleanArray()) { dialog, index, _ ->
// if attendance modifier is enabled, enable text input
if (index == values.indexOf(DashboardItem.HiddenSettingTile.ATTENDANCE.name))
input.isEnabled = (dialog as AlertDialog).listView.checkedItemPositions[index]
}
.setView(input)
.setPositiveButton(android.R.string.ok) { dialog, _ ->
val selectedState = (dialog as AlertDialog).listView.checkedItemPositions
val selectedValues = values.filterIndexed { index, _ -> selectedState[index] }
val inputAttendancePercentage = selectedValues
.find { it == DashboardItem.HiddenSettingTile.ATTENDANCE.name }
?.let { input.text.toString().toFloatOrNull() }
Timber.i("Selected hidden settings: $selectedValues")
presenter.onHiddenSettingsSelected(selectedValues, inputAttendancePercentage)
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.setNeutralButton(R.string.pref_hidden_settings_hide_grades_title) { _, _ -> showGradeDialog() }
.show()
}
override fun restartApp() { override fun restartApp() {
startActivity(MainActivity.getStartIntent(requireContext())) startActivity(MainActivity.getStartIntent(requireContext()))
requireActivity().finishAffinity() requireActivity().finishAffinity()

View File

@ -6,23 +6,19 @@ import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.Destination import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import okhttp3.internal.notify
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
class MorePresenter @Inject constructor( class MorePresenter @Inject constructor(
errorHandler: ErrorHandler, errorHandler: ErrorHandler,
studentRepository: StudentRepository, studentRepository: StudentRepository,
private val preferencesRepository: PreferencesRepository preferencesRepository: PreferencesRepository
) : BasePresenter<MoreView>(errorHandler, studentRepository) { ) : BasePresenter<MoreView>(errorHandler, studentRepository) {
private val moreAppMenuItem = preferencesRepository.appMenuItemOrder private val moreAppMenuItem = preferencesRepository.appMenuItemOrder
.sortedBy { it.order } .sortedBy { it.order }
.drop(4) .drop(4)
private val selectedHiddenSettingsTiles = preferencesRepository.selectedHiddenSettingTiles
override fun onAttachView(view: MoreView) { override fun onAttachView(view: MoreView) {
super.onAttachView(view) super.onAttachView(view)
view.initView() view.initView()
@ -36,30 +32,6 @@ class MorePresenter @Inject constructor(
view?.openView(moreItem.destination) view?.openView(moreItem.destination)
} }
fun onItemHold(moreItem: MoreItem) {
Timber.i("More item hold")
when (moreItem.destination) {
Destination.Settings -> view?.showHiddenSettings(selectedHiddenSettingsTiles)
else -> return
}
}
fun onHiddenSettingsSelected(selectedItems: List<String>, attendance: Float?) {
preferencesRepository.selectedHiddenSettingTiles = selectedItems.map {
DashboardItem.HiddenSettingTile.valueOf(it)
}
preferencesRepository.attendancePercentage = attendance
view?.restartApp()
}
fun onHiddenGradesSelected(selectedItems: List<String>) {
preferencesRepository.hiddenGrades = selectedItems
view?.restartApp()
}
fun onViewReselected() { fun onViewReselected() {
Timber.i("More view is reselected") Timber.i("More view is reselected")
view?.popView(2) view?.popView(2)

View File

@ -2,7 +2,6 @@ package io.github.wulkanowy.ui.modules.more
import io.github.wulkanowy.ui.base.BaseView import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.Destination import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
interface MoreView : BaseView { interface MoreView : BaseView {
@ -14,7 +13,5 @@ interface MoreView : BaseView {
fun openView(destination: Destination) fun openView(destination: Destination)
fun showHiddenSettings(data: List<DashboardItem.HiddenSettingTile>)
fun restartApp() fun restartApp()
} }

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.note
import io.github.wulkanowy.data.* import io.github.wulkanowy.data.*
import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.repositories.NoteRepository import io.github.wulkanowy.data.repositories.NoteRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.BasePresenter
@ -17,6 +18,7 @@ class NotePresenter @Inject constructor(
studentRepository: StudentRepository, studentRepository: StudentRepository,
private val noteRepository: NoteRepository, private val noteRepository: NoteRepository,
private val semesterRepository: SemesterRepository, private val semesterRepository: SemesterRepository,
private val preferencesRepository: PreferencesRepository,
private val analytics: AnalyticsHelper private val analytics: AnalyticsHelper
) : BasePresenter<NoteView>(errorHandler, studentRepository) { ) : BasePresenter<NoteView>(errorHandler, studentRepository) {
@ -48,6 +50,19 @@ class NotePresenter @Inject constructor(
} }
private fun loadData(forceRefresh: Boolean = false) { private fun loadData(forceRefresh: Boolean = false) {
if (!preferencesRepository.showNotes) {
view?.run {
enableSwipe(false)
showEmpty(false)
showContent(false)
showErrorView(false)
showProgress(false)
showEmpty(true)
}
return
}
flatResourceFlow { flatResourceFlow {
val student = studentRepository.getCurrentStudent() val student = studentRepository.getCurrentStudent()
val semester = semesterRepository.getCurrentSemester(student) val semester = semesterRepository.getCurrentSemester(student)

View File

@ -0,0 +1,147 @@
package io.github.wulkanowy.ui.modules.settings.mod_settings
import android.content.SharedPreferences
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.preference.EditTextPreference
import androidx.preference.MultiSelectListPreference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.base.ErrorDialog
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.AppInfo
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
class ModSettingsFragment : PreferenceFragmentCompat(),
SharedPreferences.OnSharedPreferenceChangeListener,
MainView.TitledView, ModSettingsView {
@Inject
lateinit var presenter: ModSettingsPresenter
@Inject
lateinit var appInfo: AppInfo
@Inject
lateinit var preferencesRepository: PreferencesRepository
override val titleStringId get() = R.string.pref_mod_settings_title
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter.onAttachView(this)
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.scheme_preferences_mod_settings, rootKey)
val attendancePercentagePreference: EditTextPreference? = findPreference("attendance_percentage")
attendancePercentagePreference?.setOnBindEditTextListener { editText ->
editText.inputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL
editText.filters = arrayOf(
android.text.InputFilter { source, _, _, dest, _, _ ->
if (source == "." && dest.isEmpty()) {
return@InputFilter "0."
}
val input = dest.toString() + source.toString()
if (input == "100.00") {
return@InputFilter null
}
val inputVal = input.toFloatOrNull()
if (inputVal != null && inputVal >= 0 && inputVal <= 100) {
null
} else {
""
}
}
)
}
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
presenter.onSharedPreferenceChanged(key)
}
override fun showError(text: String, error: Throwable) {
(activity as? BaseActivity<*, *>)?.showError(text, error)
}
override fun showMessage(text: String) {
(activity as? BaseActivity<*, *>)?.showMessage(text)
}
override fun showExpiredCredentialsDialog() {
(activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog()
}
override fun onCaptchaVerificationRequired(url: String?) {
(activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url)
}
override fun showDecryptionFailedDialog() {
(activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog()
}
override fun showChangePasswordSnackbar(redirectUrl: String) {
(activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl)
}
override fun openClearLoginView() {
(activity as? BaseActivity<*, *>)?.openClearLoginView()
}
override fun showErrorDetailsDialog(error: Throwable) {
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
}
override fun showAuthDialog() {
(activity as? BaseActivity<*, *>)?.showAuthDialog()
}
override fun onResume() {
super.onResume()
preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
}
override fun onPause() {
super.onPause()
preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this)
}
override fun showAttendanceSettings(items: List<DashboardItem.HiddenAttendanceTile>) {
val entries = requireContext().resources.getStringArray(R.array.mod_settings_attendance_entries)
val values = requireContext().resources.getStringArray(R.array.mod_settings_attendance_values)
val selectedItemsState = values.map { value -> items.any { it.name == value } }
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.attendance_title)
.setMultiChoiceItems(entries, selectedItemsState.toBooleanArray()) { _, _, _ -> }
.setPositiveButton(android.R.string.ok) { dialog, _ ->
val selectedState = (dialog as AlertDialog).listView.checkedItemPositions
val selectedValues = values
.filterIndexed { index, _ -> selectedState[index] }
.map { DashboardItem.HiddenAttendanceTile.valueOf(it) }
Timber.i("Selected attendance to hide: $selectedValues")
presenter.onAttendanceSettingsSelected(selectedValues)
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
}
override fun restartApp() {
startActivity(MainActivity.getStartIntent(requireContext()))
requireActivity().finishAffinity()
}
}

View File

@ -0,0 +1,40 @@
package io.github.wulkanowy.ui.modules.settings.mod_settings
import io.github.wulkanowy.data.repositories.PreferencesRepository
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.dashboard.DashboardItem
import io.github.wulkanowy.utils.AnalyticsHelper
import timber.log.Timber
import javax.inject.Inject
class ModSettingsPresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val analytics: AnalyticsHelper,
private val preferencesRepository: PreferencesRepository
) : BasePresenter<ModSettingsView>(errorHandler, studentRepository) {
override fun onAttachView(view: ModSettingsView) {
super.onAttachView(view)
Timber.i("Mod settings view was initialized")
}
fun onSharedPreferenceChanged(key: String?) {
key ?: return
Timber.i("Change mod settings $key")
analytics.logEvent("setting_changed", "name" to key)
}
fun onHiddenGradesSelected(selectedItems: List<String>) {
preferencesRepository.hiddenGrades = selectedItems
view?.restartApp()
}
fun onAttendanceSettingsSelected(selectedValues: List<DashboardItem.HiddenAttendanceTile>) {
preferencesRepository.hiddenAttendanceItems = selectedValues
view?.restartApp()
}
}

View File

@ -0,0 +1,9 @@
package io.github.wulkanowy.ui.modules.settings.mod_settings
import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
interface ModSettingsView : BaseView {
fun restartApp()
fun showAttendanceSettings(items: List<DashboardItem.HiddenAttendanceTile>)
}

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Skrytá nastavení</string> <string name="pref_mod_settings_title">Skrytá nastavení</string>
<string name="pref_hidden_settings_hint">Procento docházky</string> <string name="pref_hidden_settings_attendance_percentage">Procento docházky</string>
<string name="pref_hidden_settings_hide_grades_title">Skrýt známky</string> <string name="pref_hidden_settings_hidden_grades">Skrýt známky</string>
<string name="pref_mod_settings_hidden_attendance_items">Skryté položky docházky</string>
<string name="pref_mod_settings_show_notes">Poznámky k pořadu</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Špatná účast</item> <item>Neomluvená absence</item>
<item>Poznámky</item> <item>Výjimka</item>
<item>Falešná účast</item> <item>Ospravedlněné zpoždění</item>
<item>Neomluvené zpoždění</item>
<item>Přítomnost</item>
<item>Smazáno</item>
<item>Ospravedlněná absence</item>
<item>Neznámá</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Hidden settings</string> <string name="pref_mod_settings_title">Hidden settings</string>
<string name="pref_hidden_settings_hint">Attendance percentage</string> <string name="pref_hidden_settings_attendance_percentage">Attendance percentage</string>
<string name="pref_hidden_settings_hide_grades_title">Hide grades</string> <string name="pref_hidden_settings_hidden_grades">Hide grades</string>
<string name="pref_mod_settings_hidden_attendance_items">Hidden attendance items</string>
<string name="pref_mod_settings_show_notes">Show notes</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Bad attendance</item> <item>Unexcused absence</item>
<item>Notes</item> <item>Exemption</item>
<item>Fake attendance</item> <item>Excused lateness</item>
<item>Unexcused lateness</item>
<item>Present</item>
<item>Deleted</item>
<item>Excused absence</item>
<item>Unknown</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Geheime Einstellungen</string> <string name="pref_mod_settings_title">Geheime Einstellungen</string>
<string name="pref_hidden_settings_hint">Prozentuale Erwartung</string> <string name="pref_hidden_settings_attendance_percentage">Prozentuale Erwartung</string>
<string name="pref_hidden_settings_hide_grades_title">Hide Grades</string> <string name="pref_hidden_settings_hidden_grades">Hide Grades</string>
<string name="pref_mod_settings_hidden_attendance_items">Versteckte Anwesenheitsposten</string>
<string name="pref_mod_settings_show_notes">Notizen anzeigen</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Schlechte Anwesenheit</item> <item>Unentschuldigtes Fehlen</item>
<item>Notizen</item> <item>Befreiung</item>
<item>Vorgetäuschte 100-prozentige Anwesenheit</item> <item>Entschuldigtes Zuspätkommen</item>
<item>Unentschuldigtes Zuspätkommen</item>
<item>Anwesend</item>
<item>Löschen</item>
<item>Unentschuldigtes Fehlen</item>
<item>Unbekannt</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Hidden settings</string> <string name="pref_mod_settings_title">Hidden settings</string>
<string name="pref_hidden_settings_hint">Attendance percentage</string> <string name="pref_hidden_settings_attendance_percentage">Attendance percentage</string>
<string name="pref_hidden_settings_hide_grades_title">Hide grades</string> <string name="pref_hidden_settings_hidden_grades">Hide grades</string>
<string name="pref_mod_settings_hidden_attendance_items">Hidden attendance items</string>
<string name="pref_mod_settings_show_notes">Show notes</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Bad attendance</item> <item>Unexcused absence</item>
<item>Notes</item> <item>Exemption</item>
<item>Fake attendance</item> <item>Excused lateness</item>
<item>Unexcused lateness</item>
<item>Present</item>
<item>Deleted</item>
<item>Excused absence</item>
<item>Unknown</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Hidden settings</string> <string name="pref_mod_settings_title">Hidden settings</string>
<string name="pref_hidden_settings_hint">Attendance percentage</string> <string name="pref_hidden_settings_attendance_percentage">Attendance percentage</string>
<string name="pref_hidden_settings_hide_grades_title">Hide grades</string> <string name="pref_hidden_settings_hidden_grades">Hide grades</string>
<string name="pref_mod_settings_hidden_attendance_items">Hidden attendance items</string>
<string name="pref_mod_settings_show_notes">Note sullo spettacolo</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Bad attendance</item> <item>Unexcused absence</item>
<item>Notes</item> <item>Exemption</item>
<item>Fake attendance</item> <item>Excused lateness</item>
<item>Unexcused lateness</item>
<item>Present</item>
<item>Deleted</item>
<item>Excused absence</item>
<item>Unknown</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Sekretne ustawienia</string> <string name="pref_mod_settings_title">Sekretne ustawienia</string>
<string name="pref_hidden_settings_hint">Procent frekwencji</string> <string name="pref_hidden_settings_attendance_percentage">Procent frekwencji</string>
<string name="pref_hidden_settings_hide_grades_title">Ukryj oceny</string> <string name="pref_hidden_settings_hidden_grades">Ukryj oceny</string>
<string name="pref_mod_settings_hidden_attendance_items">Ukryte wpisy frekwencji</string>
<string name="pref_mod_settings_show_notes">Pokazuj uwagi</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Słaba frekwencja</item> <item>Nieusprawiedliwiona nieobecność</item>
<item>Uwagi</item> <item>Zwolnienie</item>
<item>Fałszywa frekwencja</item> <item>Usprawiedliwione spóźnienie</item>
<item>Nieusprawiedliwione spóźnienie</item>
<item>Obecność</item>
<item>Usunięte</item>
<item>Nieobecność usprawiedliwiona</item>
<item>Nieznane</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Секретные настройки</string> <string name="pref_mod_settings_title">Секретные настройки</string>
<string name="pref_hidden_settings_hint">Процент посещаемости</string> <string name="pref_hidden_settings_attendance_percentage">Процент посещаемости</string>
<string name="pref_hidden_settings_hide_grades_title">Скрыть оценки</string> <string name="pref_hidden_settings_hidden_grades">Скрыть оценки</string>
<string name="pref_mod_settings_hidden_attendance_items">Скрытые элементы посещаемости</string>
<string name="pref_mod_settings_show_notes">Показать заметки</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Плохая посещаемость</item> <item>Отсутствие без уважительной причины</item>
<item>Примечания</item> <item>Исключение</item>
<item>Фейковая посещаемость</item> <item>Опоздание без уважительной причины</item>
<item>Не оправданное опоздание</item>
<item>Присутствует</item>
<item>Удалено</item>
<item>Отсутствие без уважительной причины</item>
<item>Неизвестный</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Skryté nastavenia</string> <string name="pref_mod_settings_title">Skryté nastavenia</string>
<string name="pref_hidden_settings_hint">Percento dochádzky</string> <string name="pref_hidden_settings_attendance_percentage">Percento dochádzky</string>
<string name="pref_hidden_settings_hide_grades_title">Skryť známky</string> <string name="pref_hidden_settings_hidden_grades">Skryť známky</string>
<string name="pref_mod_settings_hidden_attendance_items">Skryté položky dochádzky</string>
<string name="pref_mod_settings_show_notes">Zobraziť poznámky</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Zlá účasť</item> <item>Neospravedlnená neprítomnosť</item>
<item>Poznámky</item> <item>Vynechanie</item>
<item>Falošná účasť</item> <item>Ospravedlnené meškanie</item>
<item>Neospravedlnené meškanie</item>
<item>Prítomnosť</item>
<item>Zrušené</item>
<item>Ospravedlnená absencia</item>
<item>Neznámy</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Секретні налаштування</string> <string name="pref_mod_settings_title">Секретні налаштування</string>
<string name="pref_hidden_settings_hint">Відсоток відвідуваності</string> <string name="pref_hidden_settings_attendance_percentage">Відсоток відвідуваності</string>
<string name="pref_hidden_settings_hide_grades_title">Приховати оцінки</string> <string name="pref_hidden_settings_hidden_grades">Приховати оцінки</string>
<string name="pref_mod_settings_hidden_attendance_items">Приховані елементи відвідування</string>
<string name="pref_mod_settings_show_notes">Показати нотатки</string>
<string-array name="hidden_settings_entries"> <string-array name="mod_settings_attendance_entries">
<item>Погана відвідуваність</item> <item>Прогул без поважних причин</item>
<item>Примітки</item> <item>Звільнення</item>
<item>Фальшива явка</item> <item>Поважне запізнення</item>
<item>Запізнення без поважних причин</item>
<item>Присутній</item>
<item>Видалено</item>
<item>Поважна відсутність</item>
<item>Невідомо</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="pref_default_attendance_percentage">-1</integer>
</resources>

View File

@ -1,19 +1,43 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_hidden_settings_title">Hidden settings</string> <string name="pref_mod_settings_title">Wulkanowy MOD settings</string>
<string name="pref_hidden_settings_hint">Attendance percentage</string> <string name="pref_mod_settings_hidden_attendance_items">Hidden attendance items</string>
<string name="pref_key_attendance_percentage" translatable="false">attendance_percentage</string> <string name="pref_hidden_settings_attendance_percentage">Attendance percentage</string>
<string name="pref_hidden_settings_hide_grades_title">Hide grades</string> <string name="pref_hidden_settings_hidden_grades">Hidden grades</string>
<string-array name="hidden_settings_entries"> <string name="pref_key_hidden_grades" translatable="false">hidden_grades</string>
<item>Bad attendance</item> <string name="pref_key_attendance_items" translatable="false">attendance_items</string>
<item>Notes</item> <string name="pref_key_attendance_percentage" translatable="false">attendance_percentage</string>
<item>Fake attendance</item> <string name="pref_default_attendance_percentage" translatable="false">-1</string>
<string name="pref_mod_settings_show_notes">Show notes</string>
<string name="pref_key_show_notes" translatable="false">show_notes</string>
<bool name="pref_default_show_notes">true</bool>
<string-array name="mod_settings_attendance_entries">
<item>Unexcused absence</item>
<item>Exemption</item>
<item>Excused lateness</item>
<item>Unexcused lateness</item>
<item>Present</item>
<item>Deleted</item>
<item>Excused absence</item>
<item>Unknown</item>
</string-array> </string-array>
<string-array name="hidden_settings_values" translatable="false">
<item>BAD_ATTENDANCE</item> <string-array name="mod_settings_attendance_values" translatable="false">
<item>NOTES</item> <item>UNEXCUSED_ABSENCE</item>
<item>ATTENDANCE</item> <item>EXEMPTION</item>
<item>EXCUSED_LATENESS</item>
<item>UNEXCUSED_LATENESS</item>
<item>PRESENT</item>
<item>DELETED</item>
<item>EXCUSED_ABSENCE</item>
<item>UNKNOWN</item>
</string-array>
<string-array name="pref_default_hidden_attendance_items">
</string-array> </string-array>
<string-array name="hidden_settings_bad_grades" translatable="false"> <string-array name="hidden_settings_bad_grades" translatable="false">

View File

@ -30,4 +30,9 @@
app:key="about" app:key="about"
app:summary="@string/pref_about_category_summary" app:summary="@string/pref_about_category_summary"
app:title="@string/about_title" /> app:title="@string/about_title" />
<Preference
app:fragment="io.github.wulkanowy.ui.modules.settings.mod_settings.ModSettingsFragment"
app:icon="@drawable/ic_dashboard_warning"
app:key="mod_settings"
app:title="@string/pref_mod_settings_title" />
</PreferenceScreen> </PreferenceScreen>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
app:iconSpaceReserved="false"
app:title="@string/attendance_title">
<EditTextPreference
android:inputType="numberDecimal"
android:digits="0123456789"
app:iconSpaceReserved="false"
app:key="@string/pref_key_attendance_percentage"
app:title="@string/pref_hidden_settings_attendance_percentage"
app:useSimpleSummaryProvider="true" />
<MultiSelectListPreference
app:defaultValue="@array/pref_default_hidden_attendance_items"
app:entries="@array/mod_settings_attendance_entries"
app:entryValues="@array/mod_settings_attendance_values"
app:iconSpaceReserved="false"
app:key="@string/pref_key_attendance_items"
app:title="@string/pref_mod_settings_hidden_attendance_items"
app:useSimpleSummaryProvider="true" />
</PreferenceCategory>
<PreferenceCategory
app:iconSpaceReserved="false"
app:title="@string/grade_title">
<MultiSelectListPreference
app:entries="@array/hidden_settings_bad_grades"
app:entryValues="@array/hidden_settings_bad_grades"
app:iconSpaceReserved="false"
app:key="@string/pref_key_hidden_grades"
app:title="@string/pref_hidden_settings_hidden_grades"
app:useSimpleSummaryProvider="true" />
</PreferenceCategory>
<PreferenceCategory
app:iconSpaceReserved="false"
app:title="@string/note_title">
<SwitchPreferenceCompat
app:defaultValue="@bool/pref_default_show_notes"
app:iconSpaceReserved="false"
app:key="@string/pref_key_show_notes"
app:singleLineTitle="false"
app:title="@string/pref_mod_settings_show_notes" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -36,4 +36,9 @@
app:key="about" app:key="about"
app:summary="@string/pref_about_category_summary" app:summary="@string/pref_about_category_summary"
app:title="@string/about_title" /> app:title="@string/about_title" />
<Preference
app:fragment="io.github.wulkanowy.ui.modules.settings.mod_settings.ModSettingsFragment"
app:icon="@drawable/ic_dashboard_warning"
app:key="mod_settings"
app:title="@string/pref_hidden_settings_title" />
</PreferenceScreen> </PreferenceScreen>