sync with origin

This commit is contained in:
Franek 2024-05-11 08:43:29 +02:00
commit f9fcfe6d1a
No known key found for this signature in database
GPG Key ID: 0329F871B2079351
57 changed files with 746 additions and 174 deletions

View File

@ -27,8 +27,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
targetSdkVersion 34
versionCode 157
versionName "2.5.8"
versionCode 164
versionName "2.6.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy"
@ -191,23 +191,23 @@ ext {
}
dependencies {
implementation 'io.github.wulkanowy:sdk:2.5.8'
implementation 'io.github.wulkanowy:sdk:2.6.3'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
implementation 'androidx.core:core-ktx:1.13.0'
implementation 'androidx.core:core-ktx:1.13.1'
implementation 'androidx.core:core-splashscreen:1.0.1'
implementation "androidx.activity:activity-ktx:1.9.0"
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "androidx.fragment:fragment-ktx:1.6.2"
implementation "androidx.fragment:fragment-ktx:1.7.0"
implementation "androidx.annotation:annotation:1.7.1"
implementation "androidx.preference:preference-ktx:1.2.1"
implementation "androidx.recyclerview:recyclerview:1.3.2"
implementation "androidx.viewpager2:viewpager2:1.1.0-beta02"
implementation "androidx.viewpager2:viewpager2:1.1.0-rc01"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
@ -248,13 +248,13 @@ dependencies {
implementation 'com.fredporciuncula:flow-preferences:1.9.1'
implementation 'org.apache.commons:commons-text:1.12.0'
playImplementation platform('com.google.firebase:firebase-bom:32.8.1')
playImplementation platform('com.google.firebase:firebase-bom:33.0.0')
playImplementation 'com.google.firebase:firebase-analytics'
playImplementation 'com.google.firebase:firebase-messaging'
playImplementation 'com.google.firebase:firebase-crashlytics:'
playImplementation 'com.google.firebase:firebase-config'
playImplementation 'com.google.android.gms:play-services-ads:23.0.0'
playImplementation 'com.google.android.gms:play-services-ads:22.6.0'
playImplementation "com.google.android.play:integrity:1.3.0"
playImplementation 'com.google.android.play:app-update-ktx:2.1.0'
playImplementation 'com.google.android.play:review-ktx:2.0.1'

View File

@ -36,6 +36,37 @@
"status": 2
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:1091101852179:android:b558a25f65d088b1",
"android_client_info": {
"package_name": "io.github.wulkanowy"
}
},
"oauth_client": [
{
"client_id": "",
"client_type": 3
}
],
"api_key": [
{
"current_key": ""
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"

View File

@ -4,6 +4,8 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import io.github.wulkanowy.data.enums.MessageType
import io.github.wulkanowy.data.serializers.SafeMessageTypeEnumListSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
@ -34,6 +36,8 @@ data class AdminMessage(
val priority: String,
@SerialName("messageTypes")
@Serializable(with = SafeMessageTypeEnumListSerializer::class)
@ColumnInfo(name = "types", defaultValue = "[]")
val types: List<MessageType> = emptyList(),

View File

@ -4,6 +4,8 @@ enum class MessageType {
GENERAL_MESSAGE,
DASHBOARD_MESSAGE,
LOGIN_MESSAGE,
LOGIN_STUDENT_SELECT_MESSAGE,
LOGIN_SYMBOL_MESSAGE,
PASS_RESET_MESSAGE,
ERROR_OVERRIDE,
}

View File

@ -0,0 +1,11 @@
package io.github.wulkanowy.data.enums
enum class ShowAdditionalLessonsMode(val value: String) {
NONE("none"),
INLINE("inline"),
BELOW("below");
companion object {
fun getByValue(value: String) = entries.find { it.value == value } ?: INLINE
}
}

View File

@ -15,6 +15,7 @@ import io.github.wulkanowy.data.enums.AttendanceCalculatorSortingMode
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.ShowAdditionalLessonsMode
import io.github.wulkanowy.data.enums.TimetableGapsMode
import io.github.wulkanowy.data.enums.TimetableMode
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
@ -216,6 +217,12 @@ class PreferencesRepository @Inject constructor(
)
)
val showAdditionalLessonsInPlan: ShowAdditionalLessonsMode
get() = getString(
R.string.pref_key_timetable_show_additional_lessons,
R.string.pref_default_timetable_show_additional_lessons
).let { ShowAdditionalLessonsMode.getByValue(it) }
val gradeSortingMode: GradeSortingMode
get() = GradeSortingMode.getByValue(
getString(

View File

@ -0,0 +1,27 @@
package io.github.wulkanowy.data.serializers
import io.github.wulkanowy.data.enums.MessageType
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@OptIn(ExperimentalSerializationApi::class)
object SafeMessageTypeEnumListSerializer : KSerializer<List<MessageType>> {
private val serializer = ListSerializer(String.serializer())
override val descriptor = serializer.descriptor
override fun serialize(encoder: Encoder, value: List<MessageType>) {
encoder.encodeNotNullMark()
serializer.serialize(encoder, value.map { it.name })
}
override fun deserialize(decoder: Decoder): List<MessageType> =
serializer.deserialize(decoder).mapNotNull { enumName ->
MessageType.entries.find { it.name == enumName }
}
}

View File

@ -59,7 +59,7 @@ class GetMailboxByStudentUseCase @Inject constructor(
private fun String.getUnauthorizedVersion(): String {
return normalizeStudentName().split(" ")
.joinToString(" ") {
it.first() + "*".repeat(it.length - 1)
it.firstOrNull()?.toString().orEmpty() + "*".repeat((it.length - 1).coerceAtLeast(0))
}
}
}

View File

@ -6,10 +6,12 @@ import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.databinding.FragmentLoginStudentSelectBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.support.LoginSupportDialog
@ -111,6 +113,19 @@ class LoginStudentSelectFragment :
LoginSupportDialog.newInstance(supportInfo).show(childFragmentManager, "support_dialog")
}
override fun showAdminMessage(adminMessage: AdminMessage?) {
AdminMessageViewHolder(
binding = binding.loginStudentSelectAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
).bind(adminMessage)
binding.loginStudentSelectAdminMessage.root.isVisible = adminMessage != null
}
override fun openInternetBrowser(url: String) {
requireContext().openInternetBrowser(url)
}
override fun onDestroyView() {
presenter.onDetachView()
super.onDestroyView()

View File

@ -2,16 +2,23 @@ package io.github.wulkanowy.ui.modules.login.studentselect
import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.enums.MessageType
import io.github.wulkanowy.data.flatResourceFlow
import io.github.wulkanowy.data.logResourceStatus
import io.github.wulkanowy.data.mappers.mapToStudentWithSemesters
import io.github.wulkanowy.data.onResourceData
import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.pojos.RegisterStudent
import io.github.wulkanowy.data.pojos.RegisterSymbol
import io.github.wulkanowy.data.pojos.RegisterUnit
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SchoolsRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase
import io.github.wulkanowy.sdk.scrapper.exception.StudentGraduateException
import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException
import io.github.wulkanowy.services.sync.SyncManager
@ -33,6 +40,8 @@ class LoginStudentSelectPresenter @Inject constructor(
private val syncManager: SyncManager,
private val analytics: AnalyticsHelper,
private val appInfo: AppInfo,
private val preferencesRepository: PreferencesRepository,
private val getAppropriateAdminMessageUseCase: GetAppropriateAdminMessageUseCase
) : BasePresenter<LoginStudentSelectView>(loginErrorHandler, studentRepository) {
private var lastError: Throwable? = null
@ -65,6 +74,7 @@ class LoginStudentSelectPresenter @Inject constructor(
this.loginData = loginData
this.registerUser = registerUser
loadData()
loadAdminMessage()
}
private fun loadData() {
@ -88,7 +98,20 @@ class LoginStudentSelectPresenter @Inject constructor(
refreshItems()
}
}
}.launch()
}.launch("load_data")
}
private fun loadAdminMessage() {
flatResourceFlow {
getAppropriateAdminMessageUseCase(
scrapperBaseUrl = registerUser.scrapperBaseUrl.orEmpty(),
type = MessageType.LOGIN_STUDENT_SELECT_MESSAGE,
)
}
.logResourceStatus("load login admin message")
.onResourceData { view?.showAdminMessage(it) }
.onResourceError { view?.showAdminMessage(null) }
.launch("load_admin_message")
}
private fun getStudentsWithCurrentlyActiveSemesters(): List<LoginStudentSelectItem.Student> {
@ -341,4 +364,14 @@ class LoginStudentSelectPresenter @Inject constructor(
)
}
}
fun onAdminMessageSelected(url: String?) {
url?.let { view?.openInternetBrowser(it) }
}
fun onAdminMessageDismissed(adminMessage: AdminMessage) {
preferencesRepository.dismissedAdminMessageIds += adminMessage.id
view?.showAdminMessage(null)
}
}

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.login.studentselect
import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo
@ -25,4 +26,8 @@ interface LoginStudentSelectView : BaseView {
fun openDiscordInvite()
fun openEmail(supportInfo: LoginSupportInfo)
fun showAdminMessage(adminMessage: AdminMessage?)
fun openInternetBrowser(url: String)
}

View File

@ -9,13 +9,16 @@ import android.view.inputmethod.EditorInfo.IME_NULL
import android.widget.ArrayAdapter
import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.databinding.FragmentLoginSymbolBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.support.LoginSupportDialog
@ -179,4 +182,17 @@ class LoginSymbolFragment :
override fun openSupportDialog(supportInfo: LoginSupportInfo) {
LoginSupportDialog.newInstance(supportInfo).show(childFragmentManager, "support_dialog")
}
override fun showAdminMessage(adminMessage: AdminMessage?) {
AdminMessageViewHolder(
binding = binding.loginSymbolAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
).bind(adminMessage)
binding.loginSymbolAdminMessage.root.isVisible = adminMessage != null
}
override fun openInternetBrowser(url: String) {
requireContext().openInternetBrowser(url)
}
}

View File

@ -2,10 +2,18 @@ package io.github.wulkanowy.ui.modules.login.symbol
import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.enums.MessageType
import io.github.wulkanowy.data.flatResourceFlow
import io.github.wulkanowy.data.logResourceStatus
import io.github.wulkanowy.data.onResourceData
import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.onResourceNotLoading
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase
import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol
import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException
import io.github.wulkanowy.ui.base.BasePresenter
@ -21,7 +29,9 @@ import javax.inject.Inject
class LoginSymbolPresenter @Inject constructor(
studentRepository: StudentRepository,
private val loginErrorHandler: LoginErrorHandler,
private val analytics: AnalyticsHelper
private val analytics: AnalyticsHelper,
private val preferencesRepository: PreferencesRepository,
private val getAppropriateAdminMessageUseCase: GetAppropriateAdminMessageUseCase,
) : BasePresenter<LoginSymbolView>(loginErrorHandler, studentRepository) {
private var lastError: Throwable? = null
@ -43,6 +53,21 @@ class LoginSymbolPresenter @Inject constructor(
clearAndFocusSymbol()
showSoftKeyboard()
}
loadAdminMessage()
}
private fun loadAdminMessage() {
flatResourceFlow {
getAppropriateAdminMessageUseCase(
scrapperBaseUrl = loginData.baseUrl,
type = MessageType.LOGIN_SYMBOL_MESSAGE,
)
}
.logResourceStatus("load login admin message")
.onResourceData { view?.showAdminMessage(it) }
.onResourceError { view?.showAdminMessage(null) }
.launch("load_admin_message")
}
fun onSymbolTextChanged() {
@ -166,4 +191,14 @@ class LoginSymbolPresenter @Inject constructor(
)
)
}
fun onAdminMessageSelected(url: String?) {
url?.let { view?.openInternetBrowser(it) }
}
fun onAdminMessageDismissed(adminMessage: AdminMessage) {
preferencesRepository.dismissedAdminMessageIds += adminMessage.id
view?.showAdminMessage(null)
}
}

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.login.symbol
import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.login.LoginData
@ -44,4 +45,8 @@ interface LoginSymbolView : BaseView {
fun openFaqPage()
fun openSupportDialog(supportInfo: LoginSupportInfo)
fun showAdminMessage(adminMessage: AdminMessage?)
fun openInternetBrowser(url: String)
}

View File

@ -12,6 +12,7 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.databinding.ItemTimetableBinding
import io.github.wulkanowy.databinding.ItemTimetableEmptyBinding
import io.github.wulkanowy.databinding.ItemTimetableMainAdditionalBinding
import io.github.wulkanowy.databinding.ItemTimetableSmallBinding
import io.github.wulkanowy.utils.SyncListAdapter
import io.github.wulkanowy.utils.getPlural
@ -39,6 +40,10 @@ class TimetableAdapter @Inject constructor() :
TimetableItemType.EMPTY -> EmptyViewHolder(
ItemTimetableEmptyBinding.inflate(inflater, parent, false)
)
TimetableItemType.ADDITIONAL -> AdditionalViewHolder(
ItemTimetableMainAdditionalBinding.inflate(inflater, parent, false)
)
}
}
@ -69,6 +74,22 @@ class TimetableAdapter @Inject constructor() :
binding = holder.binding,
item = getItem(position) as TimetableItem.Empty,
)
is AdditionalViewHolder -> bindAdditionalView(
binding = holder.binding,
item = getItem(position) as TimetableItem.Additional,
)
}
}
private fun bindAdditionalView(
binding: ItemTimetableMainAdditionalBinding,
item: TimetableItem.Additional
) {
with(binding) {
timetableItemSubject.text = item.additional.subject
timetableItemTimeStart.text = item.additional.start.toFormattedString("HH:mm")
timetableItemTimeFinish.text = item.additional.end.toFormattedString("HH:mm")
}
}
@ -305,6 +326,9 @@ class TimetableAdapter @Inject constructor() :
private class EmptyViewHolder(val binding: ItemTimetableEmptyBinding) :
RecyclerView.ViewHolder(binding.root)
private class AdditionalViewHolder(val binding: ItemTimetableMainAdditionalBinding) :
RecyclerView.ViewHolder(binding.root)
private object Differ : DiffUtil.ItemCallback<TimetableItem>() {
override fun areItemsTheSame(oldItem: TimetableItem, newItem: TimetableItem): Boolean =
when {

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.db.entities.TimetableAdditional
import java.time.Duration
sealed class TimetableItem(val type: TimetableItemType) {
@ -23,6 +24,10 @@ sealed class TimetableItem(val type: TimetableItemType) {
val numFrom: Int,
val numTo: Int
) : TimetableItem(TimetableItemType.EMPTY)
data class Additional(
val additional: TimetableAdditional,
) : TimetableItem(TimetableItemType.ADDITIONAL)
}
data class TimeLeft(
@ -34,5 +39,6 @@ data class TimeLeft(
enum class TimetableItemType {
SMALL,
NORMAL,
EMPTY
EMPTY,
ADDITIONAL,
}

View File

@ -4,6 +4,9 @@ import android.os.Handler
import android.os.Looper
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.db.entities.TimetableAdditional
import io.github.wulkanowy.data.enums.ShowAdditionalLessonsMode.BELOW
import io.github.wulkanowy.data.enums.ShowAdditionalLessonsMode.NONE
import io.github.wulkanowy.data.enums.TimetableGapsMode.BETWEEN_AND_BEFORE_LESSONS
import io.github.wulkanowy.data.enums.TimetableGapsMode.NO_GAPS
import io.github.wulkanowy.data.enums.TimetableMode
@ -14,6 +17,7 @@ import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.onResourceIntermediate
import io.github.wulkanowy.data.onResourceNotLoading
import io.github.wulkanowy.data.onResourceSuccess
import io.github.wulkanowy.data.pojos.TimetableFull
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
@ -169,9 +173,9 @@ class TimetablePresenter @Inject constructor(
enableSwipe(true)
showProgress(false)
showErrorView(false)
updateData(it.lessons, isDayChanged)
showContent(it.lessons.isNotEmpty())
showEmpty(it.lessons.isEmpty())
updateData(it, isDayChanged)
showContent(it.lessons.isNotEmpty() || it.additional.isNotEmpty())
showEmpty(it.lessons.isEmpty() && it.additional.isEmpty())
setDayHeaderMessage(it.headers.find { header -> header.date == currentDate }?.content)
reloadNavigation()
}
@ -216,7 +220,7 @@ class TimetablePresenter @Inject constructor(
}
}
private fun updateData(lessons: List<Timetable>, isDayChanged: Boolean) {
private fun updateData(lessons: TimetableFull, isDayChanged: Boolean) {
tickTimer?.cancel()
view?.updateData(createItems(lessons), isDayChanged)
@ -229,53 +233,84 @@ class TimetablePresenter @Inject constructor(
}
}
private fun createItems(items: List<Timetable>): List<TimetableItem> {
val filteredItems = items
.filter {
if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) {
it.isStudentPlan
} else true
}
.sortedWith(compareBy({ item -> item.start }, { item -> !item.isStudentPlan }))
private sealed class Item(
val isStudentPlan: Boolean,
val start: Instant,
val number: Int?,
) {
class Lesson(val lesson: Timetable) :
Item(lesson.isStudentPlan, lesson.start, lesson.number)
class Additional(val additional: TimetableAdditional) : Item(true, additional.start, null)
}
private fun createItems(fullTimetable: TimetableFull): List<TimetableItem> {
val showAdditionalLessonsInPlan = prefRepository.showAdditionalLessonsInPlan
val allItems =
fullTimetable.lessons.map(Item::Lesson) + fullTimetable.additional.map(Item::Additional)
.takeIf { showAdditionalLessonsInPlan != NONE }.orEmpty()
val filteredItems = allItems.filter {
if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) {
it.isStudentPlan
} else true
}.sortedWith(
(compareBy<Item> { it is Item.Additional }
.takeIf { showAdditionalLessonsInPlan == BELOW } ?: EmptyComparator())
.thenBy { it.start }
.thenBy { !it.isStudentPlan }
)
var prevNum = when (prefRepository.showTimetableGaps) {
BETWEEN_AND_BEFORE_LESSONS -> 0
else -> null
}
var prevIsAdditional = false
return buildList {
filteredItems.forEachIndexed { i, it ->
if (prefRepository.showTimetableGaps != NO_GAPS && prevNum != null && it.number > prevNum!! + 1) {
val emptyLesson = TimetableItem.Empty(
numFrom = prevNum!! + 1,
numTo = it.number - 1
)
add(emptyLesson)
if (prefRepository.showTimetableGaps != NO_GAPS) {
if (prevNum != null && it.number != null && it.number > prevNum!! + 1) {
if (!prevIsAdditional) {
// Additional lessons do count as a lesson so don't add empty lessons
// when there is an additional lesson present
val emptyLesson = TimetableItem.Empty(
numFrom = prevNum!! + 1, numTo = it.number - 1
)
add(emptyLesson)
}
}
prevNum = it.number
prevIsAdditional = it is Item.Additional
}
if (it.isStudentPlan) {
val normalLesson = TimetableItem.Normal(
lesson = it,
showGroupsInPlan = prefRepository.showGroupsInPlan,
timeLeft = filteredItems.getTimeLeftForLesson(it, i),
onClick = ::onTimetableItemSelected,
isLessonNumberVisible = !isEduOne
)
add(normalLesson)
} else {
val smallLesson = TimetableItem.Small(
lesson = it,
onClick = ::onTimetableItemSelected,
isLessonNumberVisible = !isEduOne
)
add(smallLesson)
if (it is Item.Lesson) {
if (it.isStudentPlan) {
val normalLesson = TimetableItem.Normal(
lesson = it.lesson,
showGroupsInPlan = prefRepository.showGroupsInPlan,
timeLeft = filteredItems.getTimeLeftForLesson(it.lesson, i),
onClick = ::onTimetableItemSelected,
isLessonNumberVisible = !isEduOne
)
add(normalLesson)
} else {
val smallLesson = TimetableItem.Small(
lesson = it.lesson,
onClick = ::onTimetableItemSelected,
isLessonNumberVisible = !isEduOne
)
add(smallLesson)
}
} else if (it is Item.Additional) {
// If the user disabled showing additional lessons, they would've been filtered
// out already, so there's no need to check it again.
add(TimetableItem.Additional(it.additional))
}
prevNum = it.number
}
}
}
private fun List<Timetable>.getTimeLeftForLesson(lesson: Timetable, index: Int): TimeLeft {
private fun List<Item>.getTimeLeftForLesson(lesson: Timetable, index: Int): TimeLeft {
val isShowTimeUntil = lesson.isShowTimeUntil(getPreviousLesson(index))
return TimeLeft(
until = lesson.until.plusMinutes(1).takeIf { isShowTimeUntil },
@ -284,11 +319,20 @@ class TimetablePresenter @Inject constructor(
)
}
private fun List<Timetable>.getPreviousLesson(position: Int): Instant? {
return filter { it.isStudentPlan }
.getOrNull(position - 1 - filterIndexed { i, item -> i < position && !item.isStudentPlan }.size)
private fun List<Item>.getPreviousLesson(position: Int): Instant? {
val lessonAdditionalOffset = filterIndexed { i, item ->
i < position && item is Item.Additional
}.size
val lessonStudentPlanOffset = filterIndexed { i, item ->
i < position && !item.isStudentPlan
}.size
val lessonIndex = position - 1 - lessonAdditionalOffset - lessonStudentPlanOffset
return filterIsInstance<Item.Lesson>()
.filter { it.isStudentPlan }
.getOrNull(lessonIndex)
?.let {
if (!it.canceled && it.isStudentPlan) it.end
if (!it.lesson.canceled && it.isStudentPlan) it.lesson.end
else null
}
}
@ -341,3 +385,7 @@ class TimetablePresenter @Inject constructor(
super.onDetachView()
}
}
private class EmptyComparator<T> : Comparator<T> {
override fun compare(o1: T, o2: T) = 0
}

View File

@ -13,7 +13,11 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.timetable.additional.add.AdditionalLessonAddDialog
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.*
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.openMaterialDatePicker
import java.time.LocalDate
import javax.inject.Inject
@ -132,8 +136,12 @@ class AdditionalLessonsFragment :
binding.additionalLessonsNextButton.visibility = if (show) View.VISIBLE else View.INVISIBLE
}
override fun showAddAdditionalLessonDialog() {
(activity as? MainActivity)?.showDialogFragment(AdditionalLessonAddDialog.newInstance())
override fun showAddAdditionalLessonDialog(currentDate: LocalDate) {
(activity as? MainActivity)?.showDialogFragment(
AdditionalLessonAddDialog.newInstance(
currentDate
)
)
}
override fun showDatePickerDialog(selectedDate: LocalDate) {

View File

@ -1,14 +1,27 @@
package io.github.wulkanowy.ui.modules.timetable.additional
import android.annotation.SuppressLint
import io.github.wulkanowy.data.*
import io.github.wulkanowy.data.db.entities.TimetableAdditional
import io.github.wulkanowy.data.flatResourceFlow
import io.github.wulkanowy.data.logResourceStatus
import io.github.wulkanowy.data.onResourceData
import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.onResourceNotLoading
import io.github.wulkanowy.data.onResourceSuccess
import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.repositories.TimetableRepository
import io.github.wulkanowy.domain.timetable.IsStudentHasLessonsOnWeekendUseCase
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.*
import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.capitalise
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.nextOrSameSchoolDay
import io.github.wulkanowy.utils.nextSchoolDay
import io.github.wulkanowy.utils.previousSchoolDay
import io.github.wulkanowy.utils.toFormattedString
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach
@ -22,11 +35,14 @@ class AdditionalLessonsPresenter @Inject constructor(
errorHandler: ErrorHandler,
private val semesterRepository: SemesterRepository,
private val timetableRepository: TimetableRepository,
private val isStudentHasLessonsOnWeekendUseCase: IsStudentHasLessonsOnWeekendUseCase,
private val analytics: AnalyticsHelper
) : BasePresenter<AdditionalLessonsView>(errorHandler, studentRepository) {
private var baseDate: LocalDate = LocalDate.now().nextOrSameSchoolDay
private var isWeekendHasLessons: Boolean = false
lateinit var currentDate: LocalDate
private set
@ -43,12 +59,18 @@ class AdditionalLessonsPresenter @Inject constructor(
}
fun onPreviousDay() {
loadData(currentDate.previousSchoolDay)
val date = if (isWeekendHasLessons) {
currentDate.minusDays(1)
} else currentDate.previousSchoolDay
loadData(date)
reloadView()
}
fun onNextDay() {
loadData(currentDate.nextSchoolDay)
val date = if (isWeekendHasLessons) {
currentDate.plusDays(1)
} else currentDate.nextSchoolDay
loadData(date)
reloadView()
}
@ -57,7 +79,7 @@ class AdditionalLessonsPresenter @Inject constructor(
}
fun onAdditionalLessonAddButtonClicked() {
view?.showAddAdditionalLessonDialog()
view?.showAddAdditionalLessonDialog(currentDate)
}
fun onDateSet(year: Int, month: Int, day: Int) {
@ -131,6 +153,8 @@ class AdditionalLessonsPresenter @Inject constructor(
flatResourceFlow {
val student = studentRepository.getCurrentStudent()
val semester = semesterRepository.getCurrentSemester(student)
isWeekendHasLessons = isStudentHasLessonsOnWeekendUseCase(semester, currentDate)
timetableRepository.getTimetable(
student = student,
semester = semester,

View File

@ -36,7 +36,7 @@ interface AdditionalLessonsView : BaseView {
fun showDatePickerDialog(selectedDate: LocalDate)
fun showAddAdditionalLessonDialog()
fun showAddAdditionalLessonDialog(currentDate: LocalDate)
fun showSuccessMessage()

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.timetable.additional.add
import android.app.Dialog
import android.os.Bundle
import android.view.View
import androidx.core.os.bundleOf
import androidx.core.widget.doOnTextChanged
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.timepicker.MaterialTimePicker
@ -26,10 +27,12 @@ class AdditionalLessonAddDialog : BaseDialogFragment<DialogAdditionalAddBinding>
lateinit var presenter: AdditionalLessonAddPresenter
companion object {
fun newInstance() = AdditionalLessonAddDialog()
const val ARGUMENT_KEY = "additional_lesson_default_date"
fun newInstance(defaultDate: LocalDate) = AdditionalLessonAddDialog().apply {
arguments = bundleOf(ARGUMENT_KEY to defaultDate.toEpochDay())
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireContext(), theme)
.setView(
@ -40,10 +43,13 @@ class AdditionalLessonAddDialog : BaseDialogFragment<DialogAdditionalAddBinding>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments?.getLong(ARGUMENT_KEY)?.let(LocalDate::ofEpochDay)?.let {
presenter.onDateSelected(it)
}
presenter.onAttachView(this)
}
override fun initView() {
override fun initView(selectedDate: LocalDate) {
with(binding) {
additionalLessonDialogStartEdit.doOnTextChanged { _, _, _, _ ->
additionalLessonDialogStart.isErrorEnabled = false
@ -53,6 +59,7 @@ class AdditionalLessonAddDialog : BaseDialogFragment<DialogAdditionalAddBinding>
additionalLessonDialogEnd.isErrorEnabled = false
additionalLessonDialogEnd.error = null
}
additionalLessonDialogDateEdit.setText(selectedDate.toFormattedString())
additionalLessonDialogDateEdit.doOnTextChanged { _, _, _, _ ->
additionalLessonDialogDate.isErrorEnabled = false
additionalLessonDialogDate.error = null
@ -61,7 +68,6 @@ class AdditionalLessonAddDialog : BaseDialogFragment<DialogAdditionalAddBinding>
additionalLessonDialogContent.isErrorEnabled = false
additionalLessonDialogContent.error = null
}
additionalLessonDialogAdd.setOnClickListener {
presenter.onAddAdditionalClicked(
start = additionalLessonDialogStartEdit.text?.toString(),

View File

@ -10,9 +10,12 @@ import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear
import io.github.wulkanowy.utils.toLocalDate
import kotlinx.coroutines.launch
import timber.log.Timber
import java.time.*
import java.time.LocalDate
import java.time.LocalTime
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit
import java.util.*
import java.util.UUID
import javax.inject.Inject
class AdditionalLessonAddPresenter @Inject constructor(
@ -30,7 +33,7 @@ class AdditionalLessonAddPresenter @Inject constructor(
override fun onAttachView(view: AdditionalLessonAddView) {
super.onAttachView(view)
view.initView()
view.initView(selectedDate)
Timber.i("AdditionalLesson details view was initialized")
}

View File

@ -6,7 +6,7 @@ import java.time.LocalTime
interface AdditionalLessonAddView : BaseView {
fun initView()
fun initView(selectedDate: LocalDate)
fun closeDialog()

View File

@ -6,7 +6,7 @@ Zvýrazněné vlastnosti a funkce:
- šťastné číslo,
- náhled na další a dokončené lekce,
- tmavý motiv,
- žádné reklamy,
- volitelné reklamy,
- offline režim,
- upozornění.

View File

@ -6,7 +6,7 @@ Wyróżnione cechy i funkcje:
- szczęśliwy numerek,
- podgląd lekcji dodatkowych i zrealizowanych,
- ciemny motyw.
- brak reklam,
- opcjonalne reklam,
- tryb offline,
- powiadomienia.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 KiB

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 KiB

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 469 KiB

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

After

Width:  |  Height:  |  Size: 251 KiB

View File

@ -6,7 +6,7 @@ Zvýraznené vlastnosti a funkcie:
- šťastné číslo,
- náhľad na ďalšie a dokončené lekcie,
- tmavý motív,
- žiadne reklamy,
- voliteľné reklamy,
- offline režim,
- upozornenia.

View File

@ -1,5 +1,5 @@
Wersja 2.5.8
Wersja 2.6.4
obeszliśmy próby blokowania Wulkanowego przez firmę VULCAN, o czymś pewnie zapomnieliśmy, ale nie miejcie nam tego za złe
naprawiliśmy dostęp do modułu ucznia i modułu wiadomości po kolejnej próbie blokady nas (niestety jeszcze bez nowego modułu ucznia)
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases

View File

@ -11,6 +11,18 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/login_student_select_admin_message"
layout="@layout/item_dashboard_admin_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:visibility="visible" />
<TextView
android:id="@+id/loginStudentSelectHeader"
android:layout_width="match_parent"
@ -28,7 +40,7 @@
app:layout_constraintBottom_toTopOf="@id/loginStudentSelectRecycler"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_student_select_admin_message"
app:layout_constraintVertical_chainStyle="packed" />
<androidx.recyclerview.widget.RecyclerView

View File

@ -95,6 +95,18 @@
android:background="?android:attr/listDivider" />
</LinearLayout>
<include
android:id="@+id/login_symbol_admin_message"
layout="@layout/item_dashboard_admin_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/loginSymbolContact"
app:layout_constraintVertical_chainStyle="packed"
tools:visibility="visible" />
<TextView
android:id="@+id/loginSymbolHeader"
android:layout_width="match_parent"
@ -111,7 +123,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginSymbolContact"
app:layout_constraintTop_toBottomOf="@+id/login_symbol_admin_message"
app:layout_constraintVertical_chainStyle="packed" />
<TextView

View File

@ -0,0 +1,153 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:paddingStart="8dp"
android:paddingTop="6dp"
android:paddingEnd="12dp"
android:paddingBottom="6dp"
tools:context=".ui.modules.timetable.TimetableAdapter">
<TextView
android:id="@+id/timetableItemNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:includeFontPadding="false"
android:maxLength="2"
android:minWidth="40dp"
android:minHeight="40dp"
android:textColor="?android:textColorPrimary"
android:textSize="32sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
<TextView
android:id="@+id/timetableItemSubject"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorPrimary"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@id/timetableItemTimeBarrier"
app:layout_constraintStart_toEndOf="@+id/timetableItemTimeStart"
app:layout_constraintTop_toTopOf="@id/timetableItemTimeStart"
tools:text="@tools:sample/lorem" />
<TextView
android:id="@+id/timetableItemTimeStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="13sp"
app:layout_constraintBottom_toTopOf="@id/timetableItemTimeFinish"
app:layout_constraintStart_toEndOf="@id/timetableItemNumber"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="packed"
tools:text="11:11" />
<TextView
android:id="@+id/timetableItemTimeFinish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/timetableItemNumber"
app:layout_constraintTop_toBottomOf="@id/timetableItemTimeStart"
tools:text="12:00" />
<TextView
android:id="@+id/timetableItemTeacher"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="13sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/timetableItemTimeStart"
app:layout_constraintTop_toTopOf="@id/timetableItemTimeFinish"
android:text="@string/timetable_additional_lesson"
tools:visibility="visible" />
<TextView
android:id="@+id/timetableItemDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="16dp"
android:textColor="?colorTimetableChange"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/timetableItemTimeFinish"
app:layout_constraintTop_toTopOf="@id/timetableItemTimeFinish"
tools:text="Lekcja odwołana: uczniowie zwolnieni do domu"
tools:visibility="gone" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/timetableItemTimeBarrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="timetableItemTimeUntil,timetableItemTimeLeft" />
<TextView
android:id="@+id/timetableItemTimeUntil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textColor="?colorPrimary"
android:textSize="13sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="za 15 min"
tools:visibility="gone" />
<TextView
android:id="@+id/timetableItemTimeLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginStart="4dp"
android:background="@drawable/background_timetable_time_left"
android:ellipsize="end"
android:gravity="center"
android:includeFontPadding="false"
android:maxLines="1"
android:paddingLeft="7dp"
android:paddingTop="2dp"
android:paddingRight="7dp"
android:paddingBottom="2dp"
android:textColor="?colorOnPrimary"
android:textSize="13sp"
android:visibility="gone"
app:backgroundTint="?colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/timetableItemTimeStart"
tools:text="jeszcze 15 min"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -56,6 +56,11 @@
<item>Pouze mezi lekcemi</item>
<item>Před a mezi lekcemi</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Nezobrazovat</item>
<item>Zobrazit v řadě</item>
<item>Zobrazit pod pravidelnými hodinami</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Šťastné číslo</item>
<item>Nepřečtené zprávy</item>

View File

@ -113,17 +113,17 @@
<string name="grade_comment">Komentář</string>
<string name="grade_number_new_items">Počet nových známek: %1$d</string>
<string name="grade_average">Průměr: %1$.2f</string>
<string name="grade_average_year">Annual: %1$.2f</string>
<string name="grade_average_year">Roční: %1$.2f</string>
<string name="grade_points_sum">Body: %s</string>
<string name="grade_no_average">Bez průměru</string>
<string name="grade_summary_average_semester">Semester average</string>
<string name="grade_summary_average_year">Annual average</string>
<string name="grade_summary_average_semester">Pololetní průměr</string>
<string name="grade_summary_average_year">Roční průměr</string>
<string name="grade_summary_points">Součet bodů</string>
<string name="grade_summary_final_grade">Konečná známka</string>
<string name="grade_summary_predicted_grade">Předpokládaná známka</string>
<string name="grade_summary_descriptive">Popisná známka</string>
<string name="grade_summary_calculated_average">Calculated semester average</string>
<string name="grade_summary_calculated_average_annual">Calculated annual average</string>
<string name="grade_summary_calculated_average">Vypočítaný pololetní průměr</string>
<string name="grade_summary_calculated_average_annual">Vypočítaný roční průměr</string>
<string name="grade_summary_calculated_average_help_dialog_title">Jak funguje vypočítaný průměr?</string>
<string name="grade_summary_calculated_average_help_dialog_message">Vypočítaný průměr je aritmetický průměr vypočítaný z průměrů předmětů. Umožňuje vám to znát přibližný konečný průměr. Vypočítává se způsobem zvoleným uživatelem v nastavení aplikaci. Doporučuje se vybrat příslušnou možnost. Důvodem je rozdílný výpočet školních průměrů. Pokud vaše škola navíc uvádí průměr předmětů na stránce deníku Vulcan, aplikace si je stáhne a tyto průměry nepočítá. To lze změnit vynucením výpočtu průměru v nastavení aplikaci.\n\n<b>Průměr známek pouze z vybraného semestru</b>:\n1. Výpočet váženého průměru pro každý předmět v daném semestru\n2. Sčítání vypočítaných průměrů\n3. Výpočet aritmetického průměru součtených průměrů\n\n<b>Průměr průměrů z obou semestrů</b>:\n1. Výpočet váženého průměru pro každý předmět v semestru 1 a 2\n2. Výpočet aritmetického průměru vypočítaných průměrů za semestry 1 a 2 pro každý předmět.\n3. Sčítání vypočítaných průměrů\n4. Výpočet aritmetického průměru sečtených průměrů\n\n<b>Průměr známek z celého roku:</b>\n1. Výpočet váženého průměru za rok pro každý předmět. Konečný průměr v 1. semestru je nepodstatný.\n2. Sčítání vypočítaných průměrů\n3. Výpočet aritmetického průměru součtených průměrů</string>
<string name="grade_summary_final_average_help_dialog_title">Jak funguje konečný průměr?</string>
@ -198,6 +198,7 @@
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Lekce</string>
<string name="timetable_additional_lesson">Další lekce</string>
<string name="timetable_room">Učebna</string>
<string name="timetable_group">Skupina</string>
<string name="timetable_time">Hodiny</string>
@ -747,6 +748,7 @@
<string name="pref_view_app_theme">Motiv</string>
<string name="pref_view_expand_grade">Rozvíjení známek</string>
<string name="pref_view_timetable_show_groups">Zobrazit skupiny vedle předmětů</string>
<string name="pref_view_timetable_show_additional_lessons">Zobrazit další lekce</string>
<string name="pref_view_timetable_show_gaps">Zobrazit prázdné dlaždice, kde není žádná lekce</string>
<string name="pref_view_grade_statistics_list">Zobrazit seznam grafů v známkách třídy</string>
<string name="pref_view_subjects_without_grades">Zobrazit předměty bez známek</string>
@ -811,6 +813,8 @@
<string name="pref_dashboard_appearance_header">Domů</string>
<string name="pref_dashboard_appearance_tiles_title">Viditelnost dlaždic</string>
<string name="pref_attendance_appearance_view">Docházka</string>
<string name="pref_attendance_calculator_appearance_view">Kalkulačka docházky</string>
<string name="pref_attendance_calculator_appearance_settings_title">Nastavení</string>
<string name="pref_timetable_appearance_view">Plán lekce</string>
<string name="pref_grades_advanced_header">Známky</string>
<string name="pref_counted_average_advanced_header">Vypočítaný průměr</string>
@ -862,7 +866,7 @@
<string name="auth_button">Autorizovat</string>
<string name="auth_success">Autorizace byla úspěšně dokončena</string>
<string name="auth_title">Autorizace</string>
<string name="auth_description">Dear Parent,<br/><br/>To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student <b>%1$s</b>. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.<br/><br/>After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.<br/><br/>We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.<br/><br/>We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_description">Vážený rodiči,&lt;br/&gt;&lt;br/&gt;Chcete-li autorizovat a zajistit bezpečnost dat, prosíme Vás, abyste níže zadali PESEL číslo žáka &lt;b&gt;%1$s&lt;/b&gt;. Tyto detaily jsou nutné pro správné přidělování přístupu k osobním údajům a jejich ochranu v souladu s platnými předpisy.&lt;br/&gt;&lt;br/&gt;Po zadání údajů budou data ověřena, čímž se zajistí, že přístup do systému VULCAN získají pouze autorizované osoby. Pokud máte jakékoliv pochybnosti nebo problémy, kontaktujte prosím školního správce deníku pro objasnění situace.&lt;br/&gt;&lt;br/&gt;Udržujeme nejvyšší standardy ochrany osobních údajů a zajišťujeme, aby byly všechny poskytnuté informace chráněné. Wulkanowy neukládá ani nezpracovává číslo PESEL.&lt;br/&gt;&lt;br/&gt;Připomínáme, že poskytování úplných a přesných údajů je nutné a nezbytné k používání systému VULCAN.</string>
<string name="auth_button_skip">Zatím přeskočit</string>
<!--Captcha-->
<string name="captcha_dialog_title">Webová stránka deníku VULCAN vyžaduje ověření</string>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="sort_alphabetically">Alphabetically</string>
<string name="sort_by_date">By date</string>
<string name="sort_by_average">By average</string>
<string name="sort_by_attendance_percentage">By attendance percentage</string>
<string name="sort_by_subject_attendance_balance">By subject attendance balance</string>
<string name="sort_alphabetically">Alphabetisch</string>
<string name="sort_by_date">Nach Datum</string>
<string name="sort_by_average">Nach Durchschnitt</string>
<string name="sort_by_attendance_percentage">Nach Anwesenheitsprozent</string>
<string name="sort_by_subject_attendance_balance">Nach Subjekt Anwesenheitssaldo</string>
<string-array name="app_theme_entries" tools:ignore="InconsistentArrays">
<item>Licht</item>
<item>Dunkel</item>
@ -56,6 +56,11 @@
<item>Only between lessons</item>
<item>Before and between lessons</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Nicht zeigen</item>
<item>Inline anzeigen</item>
<item>Unterhalb der regulären Lektionen anzeigen</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Glückszahl</item>
<item>Ungelesene Nachrichten</item>

View File

@ -10,10 +10,10 @@
<string name="settings_title">Einstellungen</string>
<string name="more_title">Mehr</string>
<string name="about_title">Über die Applikation</string>
<string name="logviewer_title">Log viewer</string>
<string name="logviewer_title">Log Viewer</string>
<string name="debug_title">Debuggen</string>
<string name="notification_debug_title">Benachrichtigungen debuggen</string>
<string name="debug_cookies_clear">Clear webview cookies</string>
<string name="debug_cookies_clear">Webview-Cookies löschen</string>
<string name="contributors_title">Mitarbeiter</string>
<string name="license_title">Lizenzen</string>
<string name="message_title">Nachrichten</string>
@ -38,14 +38,14 @@
<string name="login_login_pesel_email_hint">Anmeldung, PESEL oder e-mail</string>
<string name="login_password_hint">Passwort</string>
<string name="login_host_hint">UONET+ Registervariante</string>
<string name="login_domain_suffix_hint">Custom domain suffix</string>
<string name="login_domain_suffix_hint">Benutzerdefinierte Domeisensuffixe</string>
<string name="login_type_api">Mobile API</string>
<string name="login_type_scrapper">Scraper</string>
<string name="login_type_hybrid">Hybride</string>
<string name="login_token_hint">Token</string>
<string name="login_pin_hint">PIN</string>
<string name="login_symbol_hint">Symbol</string>
<string name="login_symbol_placeholder">E.g. \"lodz\" or \"powiatjaroslawski\"</string>
<string name="login_symbol_placeholder">Zum Beispiel \"lodz\" oder \"powiatjaroslawski\"</string>
<string name="login_sign_in">Anmelden</string>
<string name="login_invalid_password">Passwort ist zu kurz</string>
<string name="login_incorrect_password_default">Anmeldedaten sind falsch</string>
@ -56,9 +56,9 @@
<string name="login_invalid_email">Ungültige email</string>
<string name="login_invalid_login">Den zugewiesenen Login anstelle von email verwenden</string>
<string name="login_invalid_custom_email">Benutze den zugewiesenen Login oder E-Mail in @%1$s</string>
<string name="login_invalid_domain_suffix">Invalid domain suffix</string>
<string name="login_invalid_symbol">Invalid symbol. If you cannot find it, please contact the school</string>
<string name="login_invalid_symbol_definitely">Don\'t make this up! If you cannot find it, please contact the school</string>
<string name="login_invalid_domain_suffix">Ungültiges Domain-Suffix</string>
<string name="login_invalid_symbol">Ungültiges Symbol. Wenn Sie es nicht finden können, wenden Sie sich bitte an die Schule</string>
<string name="login_invalid_symbol_definitely">Denken Sie sich das nicht aus! Wenn Sie es nicht finden können, wenden Sie sich bitte an die Schule</string>
<string name="login_incorrect_symbol">Schüler nicht gefunden. Überprüfen Sie das Symbol und die gewählte Variation des UONET+ Registers</string>
<string name="login_duplicate_student">Ausgewählter Student ist bereits angemeldet.</string>
<string name="login_symbol_helper">Das Symbol kann auf der Registerseite in&#160;<b>Student </b>&#160;<b>Tost Möbeln</b>&#160;<b>Registrieren Sie Ihr Mobilgerät</b>gefunden werden.\n\nStellen Sie sicher, dass Sie die entsprechende Registervariante im Feld <b>UONET+ Registervariante</b> auf dem vorherigen Bildschirm festgelegt haben</string>
@ -73,7 +73,7 @@
<string name="login_contact_discord">Discord</string>
<string name="login_email_intent_title">email senden</string>
<string name="login_recover_warning">Stellen Sie sicher, dass Sie die richtige UONET+ Registervariation wählen!</string>
<string name="login_recover_button">Reset password</string>
<string name="login_recover_button">Passwort zurücksetzen</string>
<string name="login_recover_title">Ihr Konto wiederherstellen</string>
<string name="login_recover">Wiederherstellen</string>
<string name="login_signed_in">Student ist bereits angemeldet</string>
@ -81,13 +81,13 @@
<string name="login_other_search_locations">Andere Suchorte</string>
<string name="login_no_active_student">Keine aktiven Schüler gefunden</string>
<string name="login_symbol_enter">Geben Sie ein anderes Symbol ein</string>
<string name="login_support_title">Get help</string>
<string name="login_support_school_hint">Full school name with the town (required)</string>
<string name="login_support_school_placeholder">Np. ZSTiO Jarosław lub SP nr 99 w Łodzi</string>
<string name="login_support_school_invalid">Enter correct name of the school</string>
<string name="login_support_additional_hint">Additional information in Polish (optional)</string>
<string name="login_support_additional_placeholder">Np. \"Ostatnio zmieniłem szkołę i…\" albo \"Jestem rodzicem i nie widzę drugiego dziecka…\"</string>
<string name="login_support_submit">Submit</string>
<string name="login_support_title">Hilfe anfragen</string>
<string name="login_support_school_hint">Vollschulname mit der Stadt (erforderlich)</string>
<string name="login_support_school_placeholder">Z. B. ZSTiO Jarosław oder SP nr 99 w Łodzi</string>
<string name="login_support_school_invalid">Geben Sie den richtigen Namen der Schule ein</string>
<string name="login_support_additional_hint">Zusätzliche Informationen auf Polnisch (fakultativ)</string>
<string name="login_support_additional_placeholder">Z. B. „Ich habe kürzlich die Schule gewechselt und...“ oder „Ich bin ein Elternteil und kann das Konto des anderen Kindes nicht sehen...“</string>
<string name="login_support_submit">Einreichen</string>
<!--Notifications-->
<string name="notifications_header_title">Benachrichtigungen aktivieren</string>
<string name="notifications_header_description">Aktivieren Sie Benachrichtigungen, damit Sie keine Nachricht vom Lehrer oder eine neue Klasse verpassen</string>
@ -98,8 +98,8 @@
<string name="main_log_in">Anmelden</string>
<string name="main_session_expired">Die Sitzung ist abgelaufen</string>
<string name="main_session_relogin">Die Sitzung ist abgelaufen, bitte loggen Sie sich erneut ein</string>
<string name="main_expired_credentials_title">Password has expired or been changed</string>
<string name="main_expired_credentials_description">Your account password has expired or been changed. You will need to log in to Wulkanowy again</string>
<string name="main_expired_credentials_title">Das Passwort ist abgelaufen oder wurde geändert</string>
<string name="main_expired_credentials_description">Ihr Passwort ist abgelaufen oder wurde geändert. Sie müssen sich erneut bei Wulkanowy anmelden</string>
<string name="main_support_title">Anwendungsunterstützung</string>
<string name="main_support_description">Gefällt Ihnen diese App? Unterstützen Sie ihre Entwicklung, indem Sie nicht-invasive Werbung aktivieren, die Sie jederzeit deaktivieren können</string>
<string name="main_support_positive">Werbung aktivieren</string>
@ -113,17 +113,17 @@
<string name="grade_comment">Kommentar</string>
<string name="grade_number_new_items">Anzahl der neuen Bewertungen: %1$d</string>
<string name="grade_average">Durchschnitt: %1$.2f</string>
<string name="grade_average_year">Annual: %1$.2f</string>
<string name="grade_average_year">Jährlich: %1$.2f</string>
<string name="grade_points_sum">Punkte: %s</string>
<string name="grade_no_average">Kein Durchschnitt</string>
<string name="grade_summary_average_semester">Semester average</string>
<string name="grade_summary_average_year">Annual average</string>
<string name="grade_summary_average_semester">Semesterdurchschnitt</string>
<string name="grade_summary_average_year">Jahresdurchschnitt</string>
<string name="grade_summary_points">Gesamtpunkte</string>
<string name="grade_summary_final_grade">Finaler Note</string>
<string name="grade_summary_predicted_grade">Vorhergesagte Note</string>
<string name="grade_summary_descriptive">Descriptive grade</string>
<string name="grade_summary_calculated_average">Calculated semester average</string>
<string name="grade_summary_calculated_average_annual">Calculated annual average</string>
<string name="grade_summary_descriptive">Deskriptive Note</string>
<string name="grade_summary_calculated_average">Berechneter Semesterdurchschnitt</string>
<string name="grade_summary_calculated_average_annual">Berechneter Jahresdurchschnitt</string>
<string name="grade_summary_calculated_average_help_dialog_title">Wie funktioniert der berechnete Durchschnitt?</string>
<string name="grade_summary_calculated_average_help_dialog_message">Der berechnete Mittelwert ist das arithmetische Mittel, das aus den Durchschnittswerten der Probanden errechnet wird. Es erlaubt Ihnen, den ungefähre endgültigen Durchschnitt zu kennen. Sie wird auf eine vom Anwender in den Anwendungseinstellungen gewählte Weise berechnet. Es wird empfohlen, die entsprechende Option zu wählen. Das liegt daran, dass die Berechnung der Schuldurchschnitte unterschiedlich ist. Wenn Ihre Schule den Durchschnitt der Fächer auf der Vulcan-Seite angibt, lädt die Anwendung diese Fächer herunter und berechnet nicht den Durchschnitt. Dies kann geändert werden, indem die Berechnung des Durchschnitts in den Anwendungseinstellungen erzwungen wird. \n\n<b>Durchschnitt der Noten nur aus dem ausgewählten Semester </b>:\n1. Berechnung des gewichteten Durchschnitts für jedes Fach in einem bestimmten Semester\n2. Addition der berechneten Durchschnittswerte\n3. Berechnung des arithmetischen Mittels der summierten Durchschnitte\n<b>Durchschnitt der Durchschnitte aus beiden Semestern</b>:\n1. Berechnung des gewichteten Durchschnitts für jedes Fach in Semester 1 und 2\n2. Berechnung des arithmetischen Mittels der berechneten Durchschnitte für Semester 1 und 2 für jedes Fach. \n3. Hinzufügen von berechneten Durchschnittswerten\n4. Berechnung des arithmetischen Mittels der summierten Durchschnitte\n<b>Durchschnitt der Noten aus dem ganzen Jahr:</b>\n1. Berechnung des gewichteten Jahresdurchschnitts für jedes Fach. Der Abschlussdurchschnitt im 1. Semester ist irrelevant. \n2. Addition der berechneten Durchschnittswerte\n3. Berechnung des arithmetischen Mittels der summierten Mittelwerte</string>
<string name="grade_summary_final_average_help_dialog_title">Wie funktioniert der endgültige Durchschnitt?</string>
@ -159,8 +159,8 @@
<item quantity="other">Neue Abschlussnoten</item>
</plurals>
<plurals name="grade_new_items_descriptive">
<item quantity="one">New descriptive grade</item>
<item quantity="other">New descriptive grades</item>
<item quantity="one">Neuer Deskriptive Grade</item>
<item quantity="other">Neuer Deskriptive Grades</item>
</plurals>
<plurals name="grade_notify_new_items">
<item quantity="one">Du hast %1$d Note bekommen</item>
@ -175,11 +175,12 @@
<item quantity="other">Sie haben %1$d Abschlussnoten bekommen</item>
</plurals>
<plurals name="grade_notify_new_items_descriptive">
<item quantity="one">You received %1$d descriptive grade</item>
<item quantity="other">You received %1$d descriptive grades</item>
<item quantity="one">Sie haben %1$d deskriptive Grade erhalten</item>
<item quantity="other">Sie haben %1$d deskriptive Grades erhalten</item>
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Lektion</string>
<string name="timetable_additional_lesson">Zusätzliche Lektion</string>
<string name="timetable_room">Klassenzimmer</string>
<string name="timetable_group">Gruppe</string>
<string name="timetable_time">Stunden</string>
@ -198,8 +199,8 @@
<string name="timetable_notify_change_teacher">Wechsel des Lehrers von %1$s zu %2$s</string>
<string name="timetable_notify_change_subject">Thema von %1$s zu %2$s wechseln</string>
<plurals name="timetable_no_lesson">
<item quantity="one">No lesson</item>
<item quantity="other">No lessons</item>
<item quantity="one">Keine Lektion</item>
<item quantity="other">Keine Lektionen</item>
</plurals>
<plurals name="timetable_notify_new_items_title">
<item quantity="one">Änderung des Zeitplans</item>
@ -241,12 +242,12 @@
<string name="additional_lessons_end_time_error">Endzeit muss grösser sein als Startzeit</string>
<!--Attendance-->
<string name="attendance_summary_button">Übersicht über die Schulbesuch</string>
<string name="attendance_calculator_button">Attendance calculator</string>
<string name="attendance_calculator_summary_balance_positive"><b>%1$d</b> over target</string>
<string name="attendance_calculator_summary_balance_neutral">right on target</string>
<string name="attendance_calculator_summary_balance_negative"><b>%1$d</b> under target</string>
<string name="attendance_calculator_summary_values">%1$d/%2$d presences</string>
<string name="attendance_calculator_summary_values_empty">No attendances recorded</string>
<string name="attendance_calculator_button">Anwesenheitsrechner</string>
<string name="attendance_calculator_summary_balance_positive"><b>%1$d</b> Über Ziel</string>
<string name="attendance_calculator_summary_balance_neutral">direkt am ziel</string>
<string name="attendance_calculator_summary_balance_negative"><b>%1$d</b> Unter Ziel</string>
<string name="attendance_calculator_summary_values">%1$d/%2$d Präsenzen</string>
<string name="attendance_calculator_summary_values_empty">Keine Anwesenheit verzeichnet</string>
<string name="attendance_absence_school">Aus schulischen Gründen abwesend</string>
<string name="attendance_absence_excused">Entschuldigte Abwesenheit</string>
<string name="attendance_absence_unexcused">Unentschuldigtes Abwesenheit</string>
@ -306,10 +307,10 @@
<string name="message_forward">Weiterleiten</string>
<string name="message_select_all">Alle auswählen</string>
<string name="message_unselect_all">Alle abwählen</string>
<string name="message_restore_from_trash">Restore from trash</string>
<string name="message_restore_from_trash">Wiederherstellen aus dem Papierkorb</string>
<string name="message_move_to_trash">In Papierkorb verschieben</string>
<string name="message_delete_forever">Dauerhaft löschen</string>
<string name="message_restore_success">Message restored successfully</string>
<string name="message_restore_success">Nachricht erfolgreich wiederhergestellt</string>
<string name="message_delete_success">Nachricht erfolgreich gelöscht</string>
<string name="message_mailbox_type_student">schüler</string>
<string name="message_mailbox_type_parent">Eltern</string>
@ -347,10 +348,10 @@
<item quantity="other">%1$d ausgewählt</item>
</plurals>
<string name="message_messages_deleted">Nachrichten gelöscht</string>
<string name="message_messages_restored">Messages restored</string>
<string name="message_messages_restored">Wiederhergestellte Nachrichten</string>
<string name="message_mailbox_chooser_title">Postfach auswählen</string>
<string name="message_incognito_mode_on">Incognito mode is on</string>
<string name="message_incognito_description">Thanks to incognito mode sender is not notified when you read the message</string>
<string name="message_incognito_mode_on">Inkognito-Modus ist aktiviert</string>
<string name="message_incognito_description">Dank des Inkognito-Modus wird der Absender nicht benachrichtigt, wenn Sie die Nachricht lesen</string>
<!--Note-->
<string name="note_no_items">Keine Informationen über Eintragen</string>
<string name="note_points">Punkte</string>
@ -647,13 +648,14 @@
<string name="pref_view_grade_average_mode">Berechnete Durchschnittsoptionen</string>
<string name="pref_view_grade_average_force_calc">Mittelwertberechnung durch App erzwingen</string>
<string name="pref_view_present">Anwesendheit zeigen</string>
<string name="pref_attendance_target">Attendance target</string>
<string name="pref_attendance_calculator_show_empty_subjects">Show subjects without any attendances</string>
<string name="pref_view_attendance_calculator_sorting_mode">Attendance calculator sorting</string>
<string name="pref_attendance_target">Anwesenheitsziel</string>
<string name="pref_attendance_calculator_show_empty_subjects">Lektion ohne Anwesenheit anzeigen</string>
<string name="pref_view_attendance_calculator_sorting_mode">Anwesenheitsrechner Sortierung</string>
<string name="pref_view_app_theme">Thema</string>
<string name="pref_view_expand_grade">Steigende Sorten</string>
<string name="pref_view_timetable_show_groups">Gruppen neben Schulfächen anzeigen</string>
<string name="pref_view_timetable_show_gaps">Show empty tiles where there\'s no lesson</string>
<string name="pref_view_timetable_show_additional_lessons">Zusätzliche Lektionen anzeigen</string>
<string name="pref_view_timetable_show_gaps">Leere Kacheln anzeigen, wenn es keinen Lektionen gibt</string>
<string name="pref_view_grade_statistics_list">Liste der Diagramme in Klassenbewertungen anzeigen</string>
<string name="pref_view_subjects_without_grades">Schulfächer ohne Noten anzeigen</string>
<string name="pref_view_grade_color_scheme">Farbschema der Noten</string>
@ -694,12 +696,12 @@
<string name="pref_other_grade_modifier_minus">Wert des Minus</string>
<string name="pref_other_fill_message_content">Antwort mit Nachrichtenhistorie</string>
<string name="pref_other_optional_arithmetic_average">Arithmetisches Mittel anzeigen, wenn keine Gewichte angegeben sind</string>
<string name="pref_other_incognito_mode">Incognito mode</string>
<string name="pref_other_incognito_mode_summary">Do not inform about reading the message</string>
<string name="pref_other_incognito_mode">Inkognito-Modus</string>
<string name="pref_other_incognito_mode_summary">Nicht über das Lesen der Nachricht informieren</string>
<string name="pref_ads_support_category_name">Unterstützung</string>
<string name="pref_ads_privacy_policy">Datenschutz-Bestimmungen</string>
<string name="pref_ads_agreements">Vereinbarungen</string>
<string name="pref_ads_consent">Show consent to data processing</string>
<string name="pref_ads_consent">Einwilligung zur Datenverarbeitung zeigen</string>
<string name="pref_ads_show_in_app">Anzeigen in der App anzeigen</string>
<string name="pref_ads_support">Einzelanzeige ansehen, um Projekt zu unterstützen</string>
<string name="pref_ads_privacy_title">Einwilligung in die Datenverarbeitung</string>
@ -717,6 +719,8 @@
<string name="pref_dashboard_appearance_header">Dashboard</string>
<string name="pref_dashboard_appearance_tiles_title">Sichtbarkeit der Kacheln</string>
<string name="pref_attendance_appearance_view">Schulbesuch</string>
<string name="pref_attendance_calculator_appearance_view">Anwesenheits-Rechner</string>
<string name="pref_attendance_calculator_appearance_settings_title">Einstellungen</string>
<string name="pref_timetable_appearance_view">Stundenplan</string>
<string name="pref_grades_advanced_header">Noten</string>
<string name="pref_counted_average_advanced_header">Berechneter Durchschnitt</string>
@ -762,38 +766,37 @@
<string name="menu_order_confirm_content">Die Anwendung muss neu gestartet werden, damit die Änderungen gespeichert werden</string>
<string name="menu_order_confirm_restart">Restart</string>
<!--Auth-->
<string name="auth_api_error">Authorization has been rejected. The data provided does not match the records in the secretary\'s office.</string>
<string name="auth_invalid_error">Invalid PESEL</string>
<string name="auth_api_error">Die Autorisierung wurde abgelehnt. Die vorgelegten Daten stimmen nicht mit denen des Sekretariats überein.</string>
<string name="auth_invalid_error">Ungültig PESEL</string>
<string name="auth_pesel">PESEL</string>
<string name="auth_button">Authorize</string>
<string name="auth_success">Authorization completed successfully</string>
<string name="auth_title">Authorization</string>
<string name="auth_description">Dear Parent,<br/><br/>To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student <b>%1$s</b>. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.<br/><br/>After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.<br/><br/>We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.<br/><br/>We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_button_skip">Skip for now</string>
<string name="auth_button">Autorisieren Sie</string>
<string name="auth_success">Autorisierung erfolgreich abgeschlossen</string>
<string name="auth_title">Autorisierung</string>
<string name="auth_description">Liebes Elternteil,&lt;br/&gt;&lt;br/&gt;Um die Sicherheit der Daten zu gewährleisten, bitten wir Sie, die PESEL-Nummer des Schülers/der Schülerin anzugeben&lt;b&gt;%1$s&lt;/b&gt;Diese Angaben sind für die ordnungsgemäße Zuweisung des Zugriffs und den Schutz der personenbezogenen Daten gemäß den geltenden Vorschriften unerlässlich.&lt;br/&gt;&lt;br/&gt;Nach der Eingabe der Daten werden diese überprüft, um sicherzustellen, dass nur berechtigte Personen Zugang zum VULCAN-System erhalten. Wenn Sie Zweifel oder Probleme haben, wenden Sie sich bitte an den Administrator des Schülerkalenders, um die Situation zu klären.&lt;br/&gt;&lt;br/&gt;Wir halten die höchsten Standards für den Schutz personenbezogener Daten ein und gewährleisten, dass alle bereitgestellten Informationen sicher sind. Die Wulkanowy-App speichert und verarbeitet die PESEL-Nummer nicht.&lt;br/&gt;&lt;br/&gt;Wir erinnern Sie daran, dass die Angabe vollständiger und korrekter Daten obligatorisch und notwendig für die Nutzung des VULCAN-Systems ist.</string>
<string name="auth_button_skip">Vorerst überspringen</string>
<!--Captcha-->
<string name="captcha_dialog_title">VULCAN\'s website requires verification</string>
<string name="captcha_dialog_description"><b>Why am I seeing this?</b>\nThe register website from which Wulkanowy downloads data displays the same screen as above, so Wulkanowy must also show it to be able to download data from this website. There\'s no way around it</string>
<string name="captcha_verified_message">Verified successfully</string>
<string name="captcha_dialog_title">VULCAN\'s Website erfordert Überprüfung</string>
<string name="captcha_dialog_description"><b>Warum sehe ich das?</b>\nDie Website des Registers, von der Wulkanowy Daten herunterlädt, zeigt denselben Bildschirm wie oben an, so dass Wulkanowy ihn ebenfalls anzeigen muss, um Daten von dieser Website herunterladen zu können. Es gibt keinen Ausweg</string>
<string name="captcha_verified_message">Erfolgreich verifiziert</string>
<!--Errors-->
<string name="error_no_internet">Keine Internetverbindung</string>
<string name="error_invalid_device_datetime">Es ist ein Fehler aufgetreten. Überprüfen Sie Ihre Geräteuhr</string>
<string name="error_account_inactive">This account is inactive. Try logging in again</string>
<string name="error_account_inactive">Dieses Konto ist inaktiv. Versuchen Sie, sich erneut anzumelden</string>
<string name="error_timeout">Registrierungsverbindung fehlgeschlagen. Server können überlastet sein. Bitte versuchen Sie es später noch einmal</string>
<string name="error_login_failed">Das Laden der Daten ist fehlgeschlagen. Bitte versuchen Sie es später noch einmal</string>
<string name="error_password_invalid">Your password has expired or been changed. Please log in again</string>
<string name="error_password_invalid">Ihr Passwort ist abgelaufen oder wurde geändert. Bitte melden Sie sich erneut an</string>
<string name="error_password_change_required">Passwortänderung für Registrierung erforderlich</string>
<string name="error_service_unavailable">Wartung im Gange UONET + Klassenbuch. Versuchen Sie es später noch einmal</string>
<string name="error_unknown_uonet">Unbekannter UONET + Registerfehler. Versuchen Sie es später erneut</string>
<string name="error_unknown_app">Unbekannter Anwendungsfehler. Bitte versuchen Sie es später noch einmal</string>
<string name="error_cloudflare_captcha">Captcha verification required</string>
<string name="error_cloudflare_captcha">Captcha-Verifizierung erforderlich</string>
<string name="error_unknown">Ein unerwarteter Fehler ist aufgetreten</string>
<string name="error_feature_disabled">Funktion, die von Ihrer Schule deaktiviert wurde</string>
<string name="error_feature_not_available">Feature in diesem Modus nicht verfügbar</string>
<string name="error_field_required">Dieses Feld ist erforderlich</string>
<!-- Mute system -->
<string name="message_mute">Mute</string>
<string name="message_unmute">Unmute</string>
<string name="message_mute_success">You have muted this user</string>
<string name="message_unmute_success">You have unmuted this user</string>
<string name="pref_mod_settings_other_title">Sonstiges</string>
<string name="message_mute">Stumm</string>
<string name="message_unmute">Stummschaltung aufheben</string>
<string name="message_mute_success">Sie haben diesen Benutzer stummgeschaltet</string>
<string name="message_unmute_success">Sie haben die Stummschaltung dieses Benutzers aufgehoben</string>
</resources>

View File

@ -56,6 +56,11 @@
<item>Tylko między lekcjami</item>
<item>Przed i między lekcjami</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Nie pokazuj</item>
<item>Pokaż razem</item>
<item>Pokaż poniżej zwykłych lekcji</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Szczęśliwy numerek</item>
<item>Nieprzeczytane wiadomości</item>

View File

@ -198,6 +198,7 @@
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Lekcja</string>
<string name="timetable_additional_lesson">Dodatkowa lekcja</string>
<string name="timetable_room">Sala</string>
<string name="timetable_group">Grupa</string>
<string name="timetable_time">Godziny</string>
@ -747,6 +748,7 @@
<string name="pref_view_app_theme">Motyw</string>
<string name="pref_view_expand_grade">Rozwijanie ocen</string>
<string name="pref_view_timetable_show_groups">Pokazuj grupę obok przedmiotu</string>
<string name="pref_view_timetable_show_additional_lessons">Pokaż dodatkowe lekcje</string>
<string name="pref_view_timetable_show_gaps">Pokazuj puste kafelki gdzie nie ma lekcji</string>
<string name="pref_view_grade_statistics_list">Pokazuj listę wykresów w ocenach klasy</string>
<string name="pref_view_subjects_without_grades">Pokazuj przedmioty bez ocen</string>
@ -811,6 +813,8 @@
<string name="pref_dashboard_appearance_header">Start</string>
<string name="pref_dashboard_appearance_tiles_title">Widoczność kafelków</string>
<string name="pref_attendance_appearance_view">Frekwencja</string>
<string name="pref_attendance_calculator_appearance_view">Kalkulator frekwencji</string>
<string name="pref_attendance_calculator_appearance_settings_title">Ustawienia</string>
<string name="pref_timetable_appearance_view">Plan lekcji</string>
<string name="pref_grades_advanced_header">Oceny</string>
<string name="pref_counted_average_advanced_header">Obliczona średnia</string>
@ -862,7 +866,7 @@
<string name="auth_button">Potwierdź</string>
<string name="auth_success">Autoryzacja zakończona pomyślnie</string>
<string name="auth_title">Autoryzacja</string>
<string name="auth_description">Szanowny Rodzicu,<br/><br/>W celu autoryzacji i zapewnienia bezpieczeństwa danych, uprzejmie prosimy o wprowadzenie poniżej numeru PESEL ucznia <b>%1$s</b>. Te informacje są niezbędne do prawidłowego przypisania dostępu i ochrony danych osobowych zgodnie z obowiązującymi przepisami.<br/><br/>Po wprowadzeniu danych, będą one weryfikowane w celu zapewnienia, że dostęp do systemu VULCAN jest przyznawany wyłącznie upoważnionym osobom. W przypadku jakichkolwiek wątpliwości lub problemów, prosimy o kontakt z administratorem dziennika szkolnego w celu wyjaśnienia sytuacji.<br/><br/>Zachowujemy najwyższe standardy ochrony danych osobowych i zapewniamy, że wszelkie przekazane informacje są chronione. Wulkanowy nie przechowuje ani nie przetwarza numeru PESEL.<br/><br/>Przypominamy, że podanie pełnych i prawdziwych danych jest obowiązkowe i konieczne do korzystania z systemu VULCAN.</string>
<string name="auth_description">Szanowny Rodzicu,&lt;br/&gt;&lt;br/&gt;W celu autoryzacji i zapewnienia bezpieczeństwa danych, uprzejmie prosimy o wprowadzenie poniżej numeru PESEL ucznia &lt;b&gt;%1$s&lt;/b&gt;. Te informacje są niezbędne do prawidłowego przypisania dostępu i ochrony danych osobowych zgodnie z obowiązującymi przepisami.&lt;br/&gt;&lt;br/&gt;Po wprowadzeniu danych, będą one weryfikowane w celu zapewnienia, że dostęp do systemu VULCAN jest przyznawany wyłącznie upoważnionym osobom. W przypadku jakichkolwiek wątpliwości lub problemów, prosimy o kontakt z administratorem dziennika szkolnego w celu wyjaśnienia sytuacji.&lt;br/&gt;&lt;br/&gt;Zachowujemy najwyższe standardy ochrony danych osobowych i zapewniamy, że wszelkie przekazane informacje są chronione. Wulkanowy nie przechowuje ani nie przetwarza numeru PESEL.&lt;br/&gt;&lt;br/&gt;Przypominamy, że podanie pełnych i prawdziwych danych jest obowiązkowe i konieczne do korzystania z systemu VULCAN.</string>
<string name="auth_button_skip">Na razie pomiń</string>
<!--Captcha-->
<string name="captcha_dialog_title">Strona dziennika VULCAN wymaga weryfikacji</string>

View File

@ -56,6 +56,11 @@
<item>Only between lessons</item>
<item>Before and between lessons</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Don\'t show</item>
<item>Show inline</item>
<item>Show below regular lessons</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Счастливый номер</item>
<item>Непрочитанные письма</item>

View File

@ -198,6 +198,7 @@
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Урок</string>
<string name="timetable_additional_lesson">Additional lesson</string>
<string name="timetable_room">Аудитория</string>
<string name="timetable_group">Группа</string>
<string name="timetable_time">Часы</string>
@ -747,6 +748,7 @@
<string name="pref_view_app_theme">Тема</string>
<string name="pref_view_expand_grade">Разворачивание оценок</string>
<string name="pref_view_timetable_show_groups">Показать группы рядом с темами</string>
<string name="pref_view_timetable_show_additional_lessons">Show additional lessons</string>
<string name="pref_view_timetable_show_gaps">Show empty tiles where there\'s no lesson</string>
<string name="pref_view_grade_statistics_list">Показывать диаграммы в оценках класса</string>
<string name="pref_view_subjects_without_grades">Показать предметы без оценок</string>
@ -811,6 +813,8 @@
<string name="pref_dashboard_appearance_header">Главная</string>
<string name="pref_dashboard_appearance_tiles_title">Видимость плиток</string>
<string name="pref_attendance_appearance_view">Посещаемость</string>
<string name="pref_attendance_calculator_appearance_view">Attendance calculator</string>
<string name="pref_attendance_calculator_appearance_settings_title">Settings</string>
<string name="pref_timetable_appearance_view">Расписание</string>
<string name="pref_grades_advanced_header">Оценки</string>
<string name="pref_counted_average_advanced_header">Рассчитанная средняя оценка</string>
@ -862,7 +866,7 @@
<string name="auth_button">Авторизовать</string>
<string name="auth_success">Авторизация прошла успешно</string>
<string name="auth_title">Авторизация</string>
<string name="auth_description">Dear Parent,<br/><br/>To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student <b>%1$s</b>. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.<br/><br/>After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.<br/><br/>We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.<br/><br/>We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_description">Dear Parent,&lt;br /&gt;&lt;br /&gt;To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student &lt;b&gt;%1$s&lt;/b&gt;. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.&lt;br /&gt;&lt;br /&gt;After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.&lt;br /&gt;&lt;br /&gt;We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.&lt;br /&gt;&lt;br /&gt;We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_button_skip">Пропустить сейчас</string>
<!--Captcha-->
<string name="captcha_dialog_title">VULCAN\'s website requires verification</string>

View File

@ -56,6 +56,11 @@
<item>Iba medzi lekciami</item>
<item>Pred a medzi lekciami</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Nezobrazovať</item>
<item>Zobraziť v rade</item>
<item>Zobraziť pod pravidelnými hodinami</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Šťastné číslo</item>
<item>Neprečítané správy</item>

View File

@ -113,17 +113,17 @@
<string name="grade_comment">Komentár</string>
<string name="grade_number_new_items">Počet nových známok %1$d</string>
<string name="grade_average">Priemer: %1$.2f</string>
<string name="grade_average_year">Annual: %1$.2f</string>
<string name="grade_average_year">Ročný: %1$.2f</string>
<string name="grade_points_sum">Body: %s</string>
<string name="grade_no_average">Bez priemeru</string>
<string name="grade_summary_average_semester">Semester average</string>
<string name="grade_summary_average_year">Annual average</string>
<string name="grade_summary_average_semester">Polročný priemer</string>
<string name="grade_summary_average_year">Ročný priemer</string>
<string name="grade_summary_points">Súčet bodov</string>
<string name="grade_summary_final_grade">Konečná známka</string>
<string name="grade_summary_predicted_grade">Predpokladaná známka</string>
<string name="grade_summary_descriptive">Popisná známka</string>
<string name="grade_summary_calculated_average">Calculated semester average</string>
<string name="grade_summary_calculated_average_annual">Calculated annual average</string>
<string name="grade_summary_calculated_average">Vypočítaný polročný priemer</string>
<string name="grade_summary_calculated_average_annual">Vypočítaný ročný priemer</string>
<string name="grade_summary_calculated_average_help_dialog_title">Ako funguje vypočítaný priemer?</string>
<string name="grade_summary_calculated_average_help_dialog_message">Vypočítaný priemer je aritmetický priemer vypočítaný z priemerov predmetov. Umožňuje vám to poznať približný konečný priemer. Vypočítava sa spôsobom zvoleným užívateľom v nastaveniach aplikácii. Odporúča sa vybrať príslušnú možnosť. Dôvodom je rozdielny výpočet školských priemerov. Ak vaša škola navyše uvádza priemer predmetov na stránke denníka Vulcan, aplikácia si ich stiahne a tieto priemery nepočíta. To možno zmeniť vynútením výpočtu priemeru v nastavení aplikácii.\n\n<b>Priemer známok iba z vybraného semestra</b>:\n1. Výpočet váženého priemeru pre každý predmet v danom semestri\n2. Sčítanie vypočítaných priemerov\n3. Výpočet aritmetického priemeru součtených priemerov\n\n<b>Priemer priemerov z oboch semestrov</b>:\n1. Výpočet váženého priemeru pre každý predmet v semestri 1 a 2\n2. Výpočet aritmetického priemeru vypočítaných priemerov za semestre 1 a 2 pre každý predmet.\n3. Sčítanie vypočítaných priemerov\n4. Výpočet aritmetického priemeru součtených priemerov\n\n<b>Priemer známok z celého roka:</b>\n1. Výpočet váženého priemeru za rok pre každý predmet. Konečný priemer v 1. semestri je nepodstatný.\n2. Sčítanie vypočítaných priemerov\n3. Výpočet aritmetického priemeru součtených priemerov</string>
<string name="grade_summary_final_average_help_dialog_title">Ako funguje konečný priemer?</string>
@ -198,6 +198,7 @@
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Lekcia</string>
<string name="timetable_additional_lesson">Ďalšia lekcia</string>
<string name="timetable_room">Učebňa</string>
<string name="timetable_group">Skupina</string>
<string name="timetable_time">Hodiny</string>
@ -747,6 +748,7 @@
<string name="pref_view_app_theme">Motív</string>
<string name="pref_view_expand_grade">Rozvijanie známok</string>
<string name="pref_view_timetable_show_groups">Zobraziť skupiny vedľa predmetov</string>
<string name="pref_view_timetable_show_additional_lessons">Zobraziť ďalšie lekcie</string>
<string name="pref_view_timetable_show_gaps">Zobraziť prázdne dlaždice, kde nie je žiadne lekcie</string>
<string name="pref_view_grade_statistics_list">Zobraziť zoznam grafov v známkach triedy</string>
<string name="pref_view_subjects_without_grades">Zobraziť predmety bez známok</string>
@ -811,6 +813,8 @@
<string name="pref_dashboard_appearance_header">Domov</string>
<string name="pref_dashboard_appearance_tiles_title">Viditeľnosť dlaždíc</string>
<string name="pref_attendance_appearance_view">Dochádzka</string>
<string name="pref_attendance_calculator_appearance_view">Kalkulačka dochádzky</string>
<string name="pref_attendance_calculator_appearance_settings_title">Nastavenia</string>
<string name="pref_timetable_appearance_view">Plán lekcie</string>
<string name="pref_grades_advanced_header">Známky</string>
<string name="pref_counted_average_advanced_header">Vypočítaný priemer</string>
@ -862,7 +866,7 @@
<string name="auth_button">Autorizovať</string>
<string name="auth_success">Autorizácia bola úspešne dokončená</string>
<string name="auth_title">Autorizácia</string>
<string name="auth_description">Dear Parent,<br/><br/>To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student <b>%1$s</b>. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.<br/><br/>After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.<br/><br/>We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.<br/><br/>We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_description">Vážený rodiči,&lt;br/&gt;&lt;br/&gt;Ak chcete autorizovať a zaistiť bezpečnosť dát, prosíme Vás, aby ste nižšie zadali PESEL číslo žiaka &lt;b&gt;%1$s&lt;/b&gt;. Tieto detaily sú nutné pre správne prideľovanie prístupu k osobným údajom a ich ochranu v súlade s platnými predpismi.&lt;br/&gt;&lt;br/&gt;Po zadaní údajov budú dáta overené, čím sa zaistí, že prístup do systému VULCAN získajú iba autorizované osoby. Pokiaľ máte akékoľvek pochybnosti alebo problémy, kontaktujte prosím školského správcu denníka pre objasnenie situácie.&lt;br/&gt;&lt;br/&gt;Udržujeme najvyššie štandardy ochrany osobných údajov a zaisťujeme, aby boli všetky poskytnuté informácie chránené. Wulkanowy neukladá ani nespracováva číslo PESEL.&lt;br/&gt;&lt;br/&gt;Pripomíname, že poskytovanie úplných a presných údajov je nutné a nevyhnutné na používanie systému VULCAN.</string>
<string name="auth_button_skip">Zatiaľ preskočiť</string>
<!--Captcha-->
<string name="captcha_dialog_title">Webová stránka denníka VULCAN vyžaduje overenie</string>

View File

@ -56,6 +56,11 @@
<item>Тільки між уроками</item>
<item>Перед і між уроками</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Не показувати</item>
<item>Показати у рядку</item>
<item>Показати нижче стандартних уроків</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Щасливий номер</item>
<item>Непрочитані листи</item>

View File

@ -198,6 +198,7 @@
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Урок</string>
<string name="timetable_additional_lesson">Додатковий урок</string>
<string name="timetable_room">Аудиторія</string>
<string name="timetable_group">Група</string>
<string name="timetable_time">Години</string>
@ -747,6 +748,7 @@
<string name="pref_view_app_theme">Тема</string>
<string name="pref_view_expand_grade">Розгортання оцінок</string>
<string name="pref_view_timetable_show_groups">Показувати групи поруч з темами</string>
<string name="pref_view_timetable_show_additional_lessons">Показати додаткові уроки</string>
<string name="pref_view_timetable_show_gaps">Показувати порожні плитки там, де немає уроків</string>
<string name="pref_view_grade_statistics_list">Показувати діаграми в оцінках класу</string>
<string name="pref_view_subjects_without_grades">Показати предмети без оцінок</string>
@ -811,6 +813,8 @@
<string name="pref_dashboard_appearance_header">Головна</string>
<string name="pref_dashboard_appearance_tiles_title">Видимість плиток</string>
<string name="pref_attendance_appearance_view">Відвідуваність</string>
<string name="pref_attendance_calculator_appearance_view">Калькулятор відвідуваності</string>
<string name="pref_attendance_calculator_appearance_settings_title">Налаштування</string>
<string name="pref_timetable_appearance_view">Розклад</string>
<string name="pref_grades_advanced_header">Оцінки</string>
<string name="pref_counted_average_advanced_header">Розрахована середня оцінка</string>
@ -862,7 +866,7 @@
<string name="auth_button">Авторизовать</string>
<string name="auth_success">Авторизація пройшла успішно</string>
<string name="auth_title">Авторизувати</string>
<string name="auth_description">Шановні батьки,<br/><br/>Для авторизації та забезпечення безпеки даних просимо Вас ввести нижче PESEL номер учня <b>%1$s</b>. Ці дані необхідні для правильного призначення доступу та захисту персональних даних відповідно до чинного законодавства.<br/><br/>Після введення даних буде проведена перевірка, щоб переконатися, що доступ до системи VULCAN надається виключно уповноваженим особам. У разі виникнення будь-яких сумнівів або проблем, будь ласка, зв\'яжіться з адміністратором шкільного щоденника для з\'ясування ситуації.<br/><br/>Ми підтримуємо найвищі стандарти захисту персональних даних і гарантуємо, що вся надана інформація є безпечною. Додаток Wulkanowy не зберігає і не обробляє номер PESEL.<br/><br/>Нагадуємо, що надання повних і точних даних є обов\'язковим і необхідним для використання системи VULCAN.</string>
<string name="auth_description">Шановні батьки,&lt;br/&gt;&lt;br/&gt;Для авторизації та забезпечення безпеки даних просимо Вас ввести нижче PESEL номер учня &lt;b&gt;%1$s&lt;/b&gt;. Ці дані необхідні для правильного призначення доступу та захисту персональних даних відповідно до чинного законодавства.&lt;br/&gt;&lt;br/&gt;Після введення даних буде проведена перевірка, щоб переконатися, що доступ до системи VULCAN надається виключно уповноваженим особам. У разі виникнення будь-яких сумнівів або проблем, будь ласка, зв\'яжіться з адміністратором шкільного щоденника для з\'ясування ситуації.&lt;br/&gt;&lt;br/&gt;Ми підтримуємо найвищі стандарти захисту персональних даних і гарантуємо, що вся надана інформація є безпечною. Додаток Wulkanowy не зберігає і не обробляє номер PESEL.&lt;br/&gt;&lt;br/&gt;Нагадуємо, що надання повних і точних даних є обов\'язковим і необхідним для використання системи VULCAN.</string>
<string name="auth_button_skip">Поки що пропустити</string>
<!--Captcha-->
<string name="captcha_dialog_title">Веб-сайт VULCAN потребує підтвердження</string>

View File

@ -22,7 +22,8 @@
<string name="pref_default_grade_modifier_plus">0.33</string>
<string name="pref_default_grade_modifier_minus">0.33</string>
<bool name="pref_default_fill_message_content">true</bool>
<bool name="pref_default_timetable_show_groups">false</bool>
<bool name="pref_default_timetable_show_groups">true</bool>
<string name="pref_default_timetable_show_additional_lessons">below</string>
<string name="pref_default_timetable_show_whole_class">no</string>
<string name="pref_default_grade_sorting_mode">alphabetic</string>
<string name="pref_default_timetable_show_gaps">between</string>

View File

@ -31,6 +31,7 @@
<string name="pref_key_grade_sorting_mode">grade_sorting_mode</string>
<string name="pref_key_timetable_show_whole_class">show_whole_class_plan</string>
<string name="pref_key_timetable_show_groups">show_groups_in_plan</string>
<string name="pref_key_timetable_show_additional_lessons">show_additional_lessons</string>
<string name="pref_key_timetable_show_gaps">timetable_show_gaps</string>
<string name="pref_key_subjects_without_grades">subjects_without_grades</string>
<string name="pref_key_optional_arithmetic_average">optional_arithmetic_average</string>

View File

@ -152,6 +152,17 @@
<item>before_and_between</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Don\'t show</item>
<item>Show inline</item>
<item>Show below regular lessons</item>
</string-array>
<string-array name="timetable_show_additional_lessons_values" translatable="false">
<item>none</item>
<item>inline</item>
<item>below</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Lucky number</item>
<item>Unread messages</item>

View File

@ -28,7 +28,7 @@
<string name="student_info_title">Student info</string>
<string name="dashboard_title">Dashboard</string>
<string name="notifications_center_title">Notifications center</string>
<string name="menu_order_title">Menu configuartion</string>
<string name="menu_order_title">Menu configuration</string>
<!--Subtitles-->
@ -195,6 +195,7 @@
<!--Timetable-->
<string name="timetable_lesson">Lesson</string>
<string name="timetable_additional_lesson">Additional lesson</string>
<string name="timetable_room">Room</string>
<string name="timetable_group">Group</string>
<string name="timetable_time">Hours</string>
@ -731,6 +732,7 @@
<string name="pref_view_app_theme">Theme</string>
<string name="pref_view_expand_grade">Grades expanding</string>
<string name="pref_view_timetable_show_groups">Show groups next to subjects</string>
<string name="pref_view_timetable_show_additional_lessons">Show additional lessons</string>
<string name="pref_view_timetable_show_gaps">Show empty tiles where there\'s no lesson</string>
<string name="pref_view_grade_statistics_list">Show chart list in class grades</string>
<string name="pref_view_subjects_without_grades">Show subjects without grades</string>
@ -858,7 +860,7 @@
<string name="auth_button">Authorize</string>
<string name="auth_success">Authorization completed successfully</string>
<string name="auth_title">Authorization</string>
<string name="auth_description">Dear Parent,<br /><br />To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student <b>%1$s</b>. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.<br /><br />After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.<br /><br />We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.<br /><br />We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_description">Dear Parent,&lt;br />&lt;br />To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student &lt;b>%1$s&lt;/b>. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.&lt;br />&lt;br />After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.&lt;br />&lt;br />We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.&lt;br />&lt;br />We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_button_skip">Skip for now</string>

View File

@ -88,19 +88,18 @@
</PreferenceCategory>
<PreferenceCategory
app:iconSpaceReserved="false"
app:title="@string/pref_attendance_calculator_appearance_view"
app:key="@string/pref_key_attendance_calculator">
app:key="@string/pref_key_attendance_calculator"
app:title="@string/pref_attendance_calculator_appearance_view">
<SeekBarPreference
android:layout="@layout/pref_target_attendance"
android:max="99"
app:defaultValue="@integer/pref_default_attendance_target"
app:iconSpaceReserved="false"
android:layout="@layout/pref_target_attendance"
app:key="@string/pref_key_attendance_target"
app:title="@string/pref_attendance_target"
app:min="1"
app:updatesContinuously="true"
android:max="99"
app:showSeekBarValue="true"
/>
app:title="@string/pref_attendance_target"
app:updatesContinuously="true" />
<ListPreference
app:defaultValue="@string/pref_default_attendance_calculator_sorting_mode"
app:entries="@array/attendance_calculator_sorting_mode_entries"
@ -143,5 +142,13 @@
app:key="@string/pref_key_timetable_show_gaps"
app:title="@string/pref_view_timetable_show_gaps"
app:useSimpleSummaryProvider="true" />
<ListPreference
app:defaultValue="@string/pref_default_timetable_show_additional_lessons"
app:entries="@array/timetable_show_additional_lessons_entries"
app:entryValues="@array/timetable_show_additional_lessons_values"
app:iconSpaceReserved="false"
app:key="@string/pref_key_timetable_show_additional_lessons"
app:title="@string/pref_view_timetable_show_additional_lessons"
app:useSimpleSummaryProvider="true" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -5,8 +5,10 @@ import io.github.wulkanowy.data.pojos.RegisterStudent
import io.github.wulkanowy.data.pojos.RegisterSymbol
import io.github.wulkanowy.data.pojos.RegisterUnit
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SchoolsRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.services.sync.SyncManager
@ -44,6 +46,12 @@ class LoginStudentSelectPresenterTest {
@MockK
lateinit var schoolsRepository: SchoolsRepository
@MockK
lateinit var preferencesRepository: PreferencesRepository
@MockK
lateinit var getAppropriateAdminMessageUseCase: GetAppropriateAdminMessageUseCase
@MockK(relaxed = true)
lateinit var analytics: AnalyticsHelper
@ -132,6 +140,8 @@ class LoginStudentSelectPresenterTest {
syncManager = syncManager,
analytics = analytics,
appInfo = appInfo,
preferencesRepository = preferencesRepository,
getAppropriateAdminMessageUseCase = getAppropriateAdminMessageUseCase
)
}

View File

@ -1,7 +1,7 @@
buildscript {
ext {
kotlin_version = '1.9.23'
about_libraries = '11.1.3'
about_libraries = '11.1.4'
hilt_version = '2.51.1'
}
repositories {
@ -14,7 +14,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:$kotlin_version-1.0.19"
classpath 'com.android.tools.build:gradle:8.3.2'
classpath 'com.android.tools.build:gradle:8.4.0'
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath 'com.google.gms:google-services:4.4.1'
classpath 'com.huawei.agconnect:agcp:1.9.1.303'