diff --git a/.gitignore b/.gitignore
index ad83ced8d..810f5e7aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,6 +71,7 @@ captures/
.idea/deploymentTargetDropDown.xml
.idea/deploymentTargetSelector.xml
.idea/kotlinc.xml
+.idea/studiobot.xml
# Keystore files
*.jks
@@ -127,3 +128,4 @@ google-services.json
!app/google-services.json
+.idea/appInsightsSettings.xml
diff --git a/app/build.gradle b/app/build.gradle
index 245daab05..f56d86955 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -27,8 +27,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
targetSdkVersion 34
- versionCode 160
- versionName "2.6.0"
+ versionCode 175
+ versionName "2.6.15"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy"
@@ -160,8 +160,8 @@ play {
defaultToAppBundles = false
track = 'production'
releaseStatus = ReleaseStatus.IN_PROGRESS
- userFraction = 0.25d
- updatePriority = 1
+ userFraction = 0.99d
+ updatePriority = 3
enabled.set(false)
}
@@ -186,28 +186,30 @@ ext {
android_hilt = "1.2.0"
room = "2.6.1"
chucker = "4.0.0"
- mockk = "1.13.10"
- coroutines = "1.8.0"
+ mockk = "1.13.11"
+ coroutines = "1.8.1"
}
dependencies {
- implementation 'io.github.wulkanowy:sdk:2.6.0'
+ implementation 'io.github.wulkanowy:sdk:2.6.13'
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 "org.jetbrains.kotlinx:kotlinx-coroutines-guava:$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.annotation:annotation:1.7.1"
+ implementation "androidx.fragment:fragment-ktx:1.7.1"
+ implementation "androidx.annotation:annotation:1.8.0"
+ implementation "androidx.javascriptengine:javascriptengine:1.0.0-beta01"
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"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
@@ -219,7 +221,7 @@ dependencies {
implementation "androidx.work:work-runtime:$work_manager"
playImplementation "androidx.work:work-gcm:$work_manager"
- implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0"
+ implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.0"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
@@ -248,13 +250,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'
@@ -274,7 +276,7 @@ dependencies {
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
- testImplementation 'org.robolectric:robolectric:4.12.1'
+ testImplementation 'org.robolectric:robolectric:4.12.2'
testImplementation "androidx.test:runner:1.5.2"
testImplementation "androidx.test.ext:junit:1.1.5"
testImplementation "androidx.test:core:1.5.0"
diff --git a/app/google-services.json b/app/google-services.json
index e9303986b..2f71b8549 100644
--- a/app/google-services.json
+++ b/app/google-services.json
@@ -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"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 79d75bc01..a4257893f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="internalOnly">
+
+
@@ -42,9 +44,9 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
+ android:resizeableActivity="true"
android:supportsRtl="false"
android:theme="@style/WulkanowyTheme"
- android:resizeableActivity="true"
tools:ignore="DataExtractionRules,UnusedAttribute">
()
+ private val sandbox: ListenableFuture? =
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && JavaScriptSandbox.isSupported())
+ JavaScriptSandbox.createConnectedInstanceAsync(context)
+ else null
private val sdk = Sdk().apply {
- androidVersion = android.os.Build.VERSION.RELEASE
- buildTag = android.os.Build.MODEL
+ androidVersion = Build.VERSION.RELEASE
+ buildTag = Build.MODEL
userAgentTemplate = remoteConfig.userAgentTemplate
setSimpleHttpLogger { Timber.d(it) }
setAdditionalCookieManager(webkitCookieManagerProxy)
@@ -36,14 +50,47 @@ class WulkanowySdkFactory @Inject constructor(
addInterceptor(chuckerInterceptor, network = true)
}
- fun create() = sdk
+ fun createBase() = sdk
+
+ suspend fun create(): Sdk {
+ val mapping = wulkanowyRepository.getMapping()
+
+ return createBase().apply {
+ if (mapping != null) {
+ endpointsMapping = mapping.endpoints
+ vTokenMapping = mapping.vTokens
+ vHeaders = mapping.vHeaders
+ responseMapping = mapping.responseMap
+ vParamsEvaluation = createIsolate()
+ }
+ }
+ }
+
+ private suspend fun createIsolate(): suspend () -> EvaluateHandler {
+ return {
+ val isolate = sandbox?.await()?.createIsolate()
+ object : EvaluateHandler {
+ override suspend fun evaluate(code: String): String? {
+ return isolate?.evaluateJavaScriptAsync(code)?.await()
+ }
+
+ override fun close() {
+ isolate?.close()
+ }
+ }
+ }
+ }
suspend fun create(student: Student, semester: Semester? = null): Sdk {
val overrideIsEduOne = checkEduOneAndMigrateIfNecessary(student)
return buildSdk(student, semester, overrideIsEduOne)
}
- private fun buildSdk(student: Student, semester: Semester?, isStudentEduOne: Boolean): Sdk {
+ private suspend fun buildSdk(
+ student: Student,
+ semester: Semester?,
+ isStudentEduOne: Boolean
+ ): Sdk {
return create().apply {
email = student.email
password = student.password
diff --git a/app/src/main/java/io/github/wulkanowy/data/api/models/Mapping.kt b/app/src/main/java/io/github/wulkanowy/data/api/models/Mapping.kt
new file mode 100644
index 000000000..e80f7cda4
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/data/api/models/Mapping.kt
@@ -0,0 +1,23 @@
+package io.github.wulkanowy.data.api.models
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class Mapping(
+
+ @SerialName("endpoints")
+ val endpoints: Map>>,
+
+ @SerialName("vTokens")
+ val vTokens: Map>>,
+
+ @SerialName("vTokenScheme")
+ val vTokenScheme: Map> = emptyMap(),
+
+ @SerialName("vHeaders")
+ val vHeaders: Map>> = emptyMap(),
+
+ @SerialName("responseMap")
+ val responseMap: Map>>> = emptyMap(),
+)
diff --git a/app/src/main/java/io/github/wulkanowy/data/api/SchoolsService.kt b/app/src/main/java/io/github/wulkanowy/data/api/services/SchoolsService.kt
similarity index 87%
rename from app/src/main/java/io/github/wulkanowy/data/api/SchoolsService.kt
rename to app/src/main/java/io/github/wulkanowy/data/api/services/SchoolsService.kt
index a7da9b63c..07fbeb896 100644
--- a/app/src/main/java/io/github/wulkanowy/data/api/SchoolsService.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/api/services/SchoolsService.kt
@@ -1,4 +1,4 @@
-package io.github.wulkanowy.data.api
+package io.github.wulkanowy.data.api.services
import io.github.wulkanowy.data.pojos.IntegrityRequest
import io.github.wulkanowy.data.pojos.LoginEvent
diff --git a/app/src/main/java/io/github/wulkanowy/data/api/AdminMessageService.kt b/app/src/main/java/io/github/wulkanowy/data/api/services/WulkanowyService.kt
similarity index 51%
rename from app/src/main/java/io/github/wulkanowy/data/api/AdminMessageService.kt
rename to app/src/main/java/io/github/wulkanowy/data/api/services/WulkanowyService.kt
index 23f5af24a..e780bdd22 100644
--- a/app/src/main/java/io/github/wulkanowy/data/api/AdminMessageService.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/api/services/WulkanowyService.kt
@@ -1,12 +1,16 @@
-package io.github.wulkanowy.data.api
+package io.github.wulkanowy.data.api.services
+import io.github.wulkanowy.data.api.models.Mapping
import io.github.wulkanowy.data.db.entities.AdminMessage
import retrofit2.http.GET
import javax.inject.Singleton
@Singleton
-interface AdminMessageService {
+interface WulkanowyService {
@GET("/v1.json")
suspend fun getAdminMessages(): List
-}
\ No newline at end of file
+
+ @GET("/mapping4.json")
+ suspend fun getMapping(): Mapping
+}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/AdminMessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/AdminMessageRepository.kt
deleted file mode 100644
index aa0022b08..000000000
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/AdminMessageRepository.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package io.github.wulkanowy.data.repositories
-
-import io.github.wulkanowy.data.Resource
-import io.github.wulkanowy.data.api.AdminMessageService
-import io.github.wulkanowy.data.db.dao.AdminMessageDao
-import io.github.wulkanowy.data.db.entities.AdminMessage
-import io.github.wulkanowy.data.networkBoundResource
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.filterNot
-import kotlinx.coroutines.sync.Mutex
-import javax.inject.Inject
-import javax.inject.Singleton
-
-@Singleton
-class AdminMessageRepository @Inject constructor(
- private val adminMessageService: AdminMessageService,
- private val adminMessageDao: AdminMessageDao,
-) {
-
- private val saveFetchResultMutex = Mutex()
-
- fun getAdminMessages(): Flow>> =
- networkBoundResource(
- mutex = saveFetchResultMutex,
- isResultEmpty = { false },
- query = { adminMessageDao.loadAll() },
- fetch = { adminMessageService.getAdminMessages() },
- shouldFetch = { true },
- saveFetchResult = { oldItems, newItems ->
- adminMessageDao.removeOldAndSaveNew(oldItems, newItems)
- },
- )
- .filterNot { it is Resource.Intermediate }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
index 8082068c5..29e8bccd0 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
@@ -9,6 +9,7 @@ import com.fredporciuncula.flow.preferences.Preference
import com.fredporciuncula.flow.preferences.Serializer
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
+import io.github.wulkanowy.data.api.models.Mapping
import io.github.wulkanowy.data.enums.AppTheme
import io.github.wulkanowy.data.enums.AttendanceCalculatorSortingMode
import io.github.wulkanowy.data.enums.GradeColorTheme
@@ -375,6 +376,15 @@ class PreferencesRepository @Inject constructor(
get() = sharedPref.getString(PREF_KEY_INSTALLATION_ID, null).orEmpty()
private set(value) = sharedPref.edit { putString(PREF_KEY_INSTALLATION_ID, value) }
+ var mapping: Mapping?
+ get() {
+ val value = sharedPref.getString("mapping", null)
+ return value?.let { json.decodeFromString(it) }
+ }
+ set(value) = sharedPref.edit(commit = true) {
+ putString("mapping", value?.let { json.encodeToString(it) })
+ }
+
init {
if (installationId.isEmpty()) {
installationId = UUID.randomUUID().toString()
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolsRepository.kt
index 4a16d6f13..25da241a0 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolsRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolsRepository.kt
@@ -1,7 +1,7 @@
package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.WulkanowySdkFactory
-import io.github.wulkanowy.data.api.SchoolsService
+import io.github.wulkanowy.data.api.services.SchoolsService
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/WulkanowyRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/WulkanowyRepository.kt
new file mode 100644
index 000000000..815f8b758
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/WulkanowyRepository.kt
@@ -0,0 +1,66 @@
+package io.github.wulkanowy.data.repositories
+
+import io.github.wulkanowy.data.Resource
+import io.github.wulkanowy.data.api.models.Mapping
+import io.github.wulkanowy.data.api.services.WulkanowyService
+import io.github.wulkanowy.data.db.dao.AdminMessageDao
+import io.github.wulkanowy.data.db.entities.AdminMessage
+import io.github.wulkanowy.data.networkBoundResource
+import io.github.wulkanowy.utils.AutoRefreshHelper
+import io.github.wulkanowy.utils.getRefreshKey
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filterNot
+import kotlinx.coroutines.sync.Mutex
+import timber.log.Timber
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class WulkanowyRepository @Inject constructor(
+ private val wulkanowyService: WulkanowyService,
+ private val adminMessageDao: AdminMessageDao,
+ private val preferencesRepository: PreferencesRepository,
+ private val refreshHelper: AutoRefreshHelper,
+) {
+
+ private val saveFetchResultMutex = Mutex()
+
+ private val cacheKey = "mapping_refresh_key"
+
+ fun getAdminMessages(): Flow>> =
+ networkBoundResource(
+ mutex = saveFetchResultMutex,
+ isResultEmpty = { false },
+ query = { adminMessageDao.loadAll() },
+ fetch = { wulkanowyService.getAdminMessages() },
+ shouldFetch = { true },
+ saveFetchResult = { oldItems, newItems ->
+ adminMessageDao.removeOldAndSaveNew(oldItems, newItems)
+ },
+ )
+ .filterNot { it is Resource.Intermediate }
+
+ suspend fun getMapping(): Mapping? {
+ var savedMapping = preferencesRepository.mapping
+
+ val isExpired = refreshHelper.shouldBeRefreshed(
+ key = getRefreshKey(cacheKey)
+ )
+
+ if (savedMapping == null || isExpired) {
+ fetchMapping()
+ savedMapping = preferencesRepository.mapping
+ }
+
+ return savedMapping
+ }
+
+ suspend fun fetchMapping() {
+ runCatching { wulkanowyService.getMapping() }
+ .onFailure { Timber.e(it) }
+ .onSuccess {
+ preferencesRepository.mapping = it
+ refreshHelper.updateLastRefreshTimestamp(cacheKey)
+ }
+ }
+}
diff --git a/app/src/main/java/io/github/wulkanowy/domain/adminmessage/GetAppropriateAdminMessageUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/adminmessage/GetAppropriateAdminMessageUseCase.kt
index b55bf899d..8b0d67b57 100644
--- a/app/src/main/java/io/github/wulkanowy/domain/adminmessage/GetAppropriateAdminMessageUseCase.kt
+++ b/app/src/main/java/io/github/wulkanowy/domain/adminmessage/GetAppropriateAdminMessageUseCase.kt
@@ -5,14 +5,14 @@ import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.enums.MessageType
import io.github.wulkanowy.data.mapResourceData
-import io.github.wulkanowy.data.repositories.AdminMessageRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
+import io.github.wulkanowy.data.repositories.WulkanowyRepository
import io.github.wulkanowy.utils.AppInfo
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class GetAppropriateAdminMessageUseCase @Inject constructor(
- private val adminMessageRepository: AdminMessageRepository,
+ private val wulkanowyRepository: WulkanowyRepository,
private val preferencesRepository: PreferencesRepository,
private val appInfo: AppInfo
) {
@@ -22,7 +22,7 @@ class GetAppropriateAdminMessageUseCase @Inject constructor(
}
operator fun invoke(scrapperBaseUrl: String, type: MessageType): Flow> {
- return adminMessageRepository.getAdminMessages().mapResourceData { adminMessages ->
+ return wulkanowyRepository.getAdminMessages().mapResourceData { adminMessages ->
adminMessages
.asSequence()
.filter { it.isNotDismissed() }
diff --git a/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt
index 669514aae..8f25eba14 100644
--- a/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt
+++ b/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt
@@ -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))
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/captcha/CaptchaDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/captcha/CaptchaDialog.kt
index ce2173d28..922b652be 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/captcha/CaptchaDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/captcha/CaptchaDialog.kt
@@ -59,7 +59,7 @@ class CaptchaDialog : BaseDialogFragment() {
webView = this
with(settings) {
javaScriptEnabled = true
- userAgentString = wulkanowySdkFactory.create().userAgent
+ userAgentString = wulkanowySdkFactory.createBase().userAgent
}
webViewClient = object : WebViewClient() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt
index b7a0796c5..25774d044 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt
@@ -30,6 +30,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.notificationscenter.NotificationsCenterFragment
+import io.github.wulkanowy.ui.modules.panicmode.PanicModeFragment
import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
import io.github.wulkanowy.utils.capitalise
@@ -125,6 +126,7 @@ class DashboardFragment : BaseFragment(R.layout.fragme
mainActivity.pushView(ConferenceFragment.newInstance())
}
onAdminMessageClickListener = presenter::onAdminMessageSelected
+ onPanicButtonClickListener = presenter::onPanicButtonClicked
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed
registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
@@ -208,7 +210,11 @@ class DashboardFragment : BaseFragment(R.layout.fragme
binding = binding.dashboardErrorAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
- ).bind(adminMessageItem.adminMessage)
+ onPanicButtonClickListener = presenter::onPanicButtonClicked,
+ ).bind(
+ item = adminMessageItem.adminMessage,
+ showPanicButton = true,
+ )
}
}
@@ -236,6 +242,10 @@ class DashboardFragment : BaseFragment(R.layout.fragme
requireContext().openInternetBrowser(url)
}
+ override fun openPanicWebView(url: String) {
+ (requireActivity() as MainActivity).pushView(PanicModeFragment.newInstance(url))
+ }
+
override fun onDestroyView() {
dashboardAdapter.clearTimers()
presenter.onDetachView()
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt
index 3fec62562..a70f82e20 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt
@@ -11,6 +11,7 @@ import io.github.wulkanowy.data.errorOrNull
import io.github.wulkanowy.data.flatResourceFlow
import io.github.wulkanowy.data.mapResourceData
import io.github.wulkanowy.data.onResourceError
+import io.github.wulkanowy.data.onResourceSuccess
import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository
import io.github.wulkanowy.data.repositories.ConferenceRepository
import io.github.wulkanowy.data.repositories.ExamRepository
@@ -23,6 +24,7 @@ import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository
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.data.resourceFlow
import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase
import io.github.wulkanowy.domain.timetable.IsStudentHasLessonsOnWeekendUseCase
import io.github.wulkanowy.ui.base.BasePresenter
@@ -44,6 +46,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
+import okhttp3.HttpUrl.Companion.toHttpUrl
import timber.log.Timber
import java.time.Instant
import java.time.LocalDate
@@ -282,6 +285,22 @@ class DashboardPresenter @Inject constructor(
url?.let { view?.openInternetBrowser(it) }
}
+ fun onPanicButtonClicked() {
+ resourceFlow { studentRepository.getCurrentStudent() }
+ .onResourceError { errorHandler.dispatch(it) }
+ .onResourceSuccess {
+ val baseUrl = it.scrapperBaseUrl.toHttpUrl()
+ val urlToOpen = baseUrl.newBuilder()
+ .host("uonetplus${it.scrapperDomainSuffix}.${baseUrl.host}")
+ .addPathSegment(it.symbol)
+ .build()
+ .toString()
+
+ view?.openPanicWebView(urlToOpen)
+ }
+ .launch("panic_button")
+ }
+
private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) {
flow {
val selectedTiles = selectedDashboardTiles
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardView.kt
index 56a0a773a..dd7fb962f 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardView.kt
@@ -31,4 +31,6 @@ interface DashboardView : BaseView {
fun openNotificationsCenterView()
fun openInternetBrowser(url: String)
+
+ fun openPanicWebView(url: String)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt
index 7c74cae80..e51975701 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt
@@ -59,6 +59,8 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter Unit = {}
+ var onPanicButtonClickListener: () -> Unit = {}
+
var onAdminMessageDismissClickListener: (AdminMessage) -> Unit = {}
val items = mutableListOf()
@@ -86,35 +88,46 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter AccountViewHolder(
ItemDashboardAccountBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.HORIZONTAL_GROUP.ordinal -> HorizontalGroupViewHolder(
ItemDashboardHorizontalGroupBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.GRADES.ordinal -> GradesViewHolder(
ItemDashboardGradesBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.LESSONS.ordinal -> LessonsViewHolder(
ItemDashboardLessonsBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.HOMEWORK.ordinal -> HomeworkViewHolder(
ItemDashboardHomeworkBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.ANNOUNCEMENTS.ordinal -> AnnouncementsViewHolder(
ItemDashboardAnnouncementsBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.EXAMS.ordinal -> ExamsViewHolder(
ItemDashboardExamsBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.CONFERENCES.ordinal -> ConferencesViewHolder(
ItemDashboardConferencesBinding.inflate(inflater, parent, false)
)
+
DashboardItem.Type.ADMIN_MESSAGE.ordinal -> AdminMessageViewHolder(
ItemDashboardAdminMessageBinding.inflate(inflater, parent, false),
onAdminMessageDismissClickListener = onAdminMessageDismissClickListener,
onAdminMessageClickListener = onAdminMessageClickListener,
+ onPanicButtonClickListener = onPanicButtonClickListener,
)
+
DashboardItem.Type.ADS.ordinal -> AdsViewHolder(
ItemDashboardAdsBinding.inflate(inflater, parent, false)
)
+
else -> throw IllegalArgumentException()
}
}
@@ -129,7 +142,11 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter bindAnnouncementsViewHolder(holder, position)
is ExamsViewHolder -> bindExamsViewHolder(holder, position)
is ConferencesViewHolder -> bindConferencesViewHolder(holder, position)
- is AdminMessageViewHolder -> holder.bind((items[position] as DashboardItem.AdminMessages).adminMessage)
+ is AdminMessageViewHolder -> holder.bind(
+ (items[position] as DashboardItem.AdminMessages).adminMessage,
+ showPanicButton = true
+ )
+
is AdsViewHolder -> bindAdsViewHolder(holder, position)
}
}
@@ -240,12 +257,15 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter {
root.context.getThemeAttrColor(R.attr.colorOnSurface)
}
+
attendancePercentage <= ATTENDANCE_SECOND_WARNING_THRESHOLD -> {
root.context.getThemeAttrColor(R.attr.colorPrimary)
}
+
attendancePercentage <= ATTENDANCE_FIRST_WARNING_THRESHOLD -> {
root.context.getThemeAttrColor(R.attr.colorTimetableChange)
}
+
else -> root.context.getThemeAttrColor(R.attr.colorOnSurface)
}
val attendanceString = if (attendancePercentage == null || attendancePercentage == .0) {
@@ -336,24 +356,28 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter {
dateToNavigate = tomorrowDate
updateLessonView(item, tomorrowTimetable, binding)
binding.dashboardLessonsItemTitleTomorrow.isVisible = true
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
}
+
currentDayHeader != null && currentDayHeader.content.isNotBlank() -> {
dateToNavigate = currentDate
updateLessonView(item, emptyList(), binding, currentDayHeader)
binding.dashboardLessonsItemTitleTomorrow.isVisible = false
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
}
+
tomorrowDayHeader != null && tomorrowDayHeader.content.isNotBlank() -> {
dateToNavigate = tomorrowDate
updateLessonView(item, emptyList(), binding, tomorrowDayHeader)
binding.dashboardLessonsItemTitleTomorrow.isVisible = true
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
}
+
else -> {
dateToNavigate = currentDate
updateLessonView(item, emptyList(), binding)
@@ -461,6 +485,7 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter {
firstTitleAndValueTextColor =
context.getThemeAttrColor(R.attr.colorOnSurface)
@@ -468,6 +493,7 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter {
firstTitleAndValueTextColor =
context.getThemeAttrColor(R.attr.colorOnSurface)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/viewholders/AdminMessageViewHolder.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/viewholders/AdminMessageViewHolder.kt
index 1e0f0bdbf..94a7686db 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/viewholders/AdminMessageViewHolder.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/viewholders/AdminMessageViewHolder.kt
@@ -13,9 +13,10 @@ class AdminMessageViewHolder(
private val binding: ItemDashboardAdminMessageBinding,
private val onAdminMessageDismissClickListener: (AdminMessage) -> Unit,
private val onAdminMessageClickListener: (String?) -> Unit,
+ private val onPanicButtonClickListener: () -> Unit,
) : RecyclerView.ViewHolder(binding.root) {
- fun bind(item: AdminMessage?) {
+ fun bind(item: AdminMessage?, showPanicButton: Boolean = false) {
item ?: return
val context = binding.root.context
@@ -48,10 +49,14 @@ class AdminMessageViewHolder(
dashboardAdminMessageItemClose.setOnClickListener {
onAdminMessageDismissClickListener(item)
}
+ dashboardPanicSection.root.isVisible = showPanicButton
+ dashboardPanicSection.dashboardPanicButton.setOnClickListener {
+ onPanicButtonClickListener()
+ }
- root.setCardBackgroundColor(backgroundColor?.let { ColorStateList.valueOf(it) })
+ dashboardAdminMessage.setCardBackgroundColor(backgroundColor?.let { ColorStateList.valueOf(it) })
item.destinationUrl?.let { url ->
- root.setOnClickListener { onAdminMessageClickListener(url) }
+ dashboardAdminMessage.setOnClickListener { onAdminMessageClickListener(url) }
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
index 88f295788..e528c5147 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
@@ -118,5 +118,6 @@ class LoginActivity : BaseActivity(), Logi
override fun onResume() {
super.onResume()
inAppUpdateHelper.onResume()
+ presenter.updateSdkMappings()
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt
index 9031cb8ab..aff0515f0 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt
@@ -1,12 +1,15 @@
package io.github.wulkanowy.ui.modules.login
import io.github.wulkanowy.data.repositories.StudentRepository
+import io.github.wulkanowy.data.repositories.WulkanowyRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
+import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class LoginPresenter @Inject constructor(
+ private val wulkanowyRepository: WulkanowyRepository,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter(errorHandler, studentRepository) {
@@ -16,4 +19,11 @@ class LoginPresenter @Inject constructor(
view.initView()
Timber.i("Login view was initialized")
}
+
+ fun updateSdkMappings() {
+ presenterScope.launch {
+ runCatching { wulkanowyRepository.fetchMapping() }
+ .onFailure { Timber.e(it) }
+ }
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt
index 1c4920696..2d1a48243 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt
@@ -238,6 +238,7 @@ class LoginFormFragment : BaseFragment(R.layout.fragme
binding = binding.loginFormMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
+ onPanicButtonClickListener = {},
).bind(message)
binding.loginFormMessage.root.isVisible = message != null
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
index 4eb602658..586c395c3 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
@@ -118,6 +118,7 @@ class LoginStudentSelectFragment :
binding = binding.loginStudentSelectAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
+ onPanicButtonClickListener = {},
).bind(adminMessage)
binding.loginStudentSelectAdminMessage.root.isVisible = adminMessage != null
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
index a813e7c00..824d8d22c 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
@@ -188,6 +188,7 @@ class LoginSymbolFragment :
binding = binding.loginSymbolAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
+ onPanicButtonClickListener = {},
).bind(adminMessage)
binding.loginSymbolAdminMessage.root.isVisible = adminMessage != null
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
index 62c16257e..e64aa9b07 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
@@ -138,6 +138,7 @@ class MainActivity : BaseActivity(), MainVie
override fun onResume() {
super.onResume()
inAppUpdateHelper.onResume()
+ presenter.updateSdkMappings()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
index a544381ce..6a072718d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
@@ -6,6 +6,7 @@ import io.github.wulkanowy.data.onResourceError
import io.github.wulkanowy.data.onResourceSuccess
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.StudentRepository
+import io.github.wulkanowy.data.repositories.WulkanowyRepository
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.services.sync.SyncManager
import io.github.wulkanowy.ui.base.BasePresenter
@@ -29,6 +30,7 @@ class MainPresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val preferencesRepository: PreferencesRepository,
+ private val wulkanowyRepository: WulkanowyRepository,
private val syncManager: SyncManager,
private val analytics: AnalyticsHelper,
private val json: Json,
@@ -199,4 +201,11 @@ class MainPresenter @Inject constructor(
.onFailure { errorHandler.dispatch(it) }
}
}
+
+ fun updateSdkMappings() {
+ presenterScope.launch {
+ runCatching { wulkanowyRepository.fetchMapping() }
+ .onFailure { Timber.e(it) }
+ }
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
index 12f9d3234..b29c2cd85 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
@@ -27,6 +27,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog
import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment
+import io.github.wulkanowy.ui.modules.panicmode.PanicModeFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor
@@ -132,6 +133,7 @@ class MessageTabFragment : BaseFragment(R.layout.frag
)
messageTabErrorRetry.setOnClickListener { presenter.onRetry() }
messageTabErrorDetails.setOnClickListener { presenter.onDetailsClick() }
+ messageTabPanicSection.dashboardPanicButton.setOnClickListener { presenter.onPanicButtonClicked() }
}
setFragmentResultListener(requireArguments().getString(MESSAGE_TAB_FOLDER_ID)!!) { _, bundle ->
@@ -283,6 +285,10 @@ class MessageTabFragment : BaseFragment(R.layout.frag
)
}
+ override fun openPanicWebView(url: String) {
+ (requireActivity() as MainActivity).pushView(PanicModeFragment.newInstance(url))
+ }
+
override fun hideKeyboard() {
activity?.hideSoftInput()
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt
index cda0b32bd..ad3e7c9cd 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt
@@ -20,6 +20,7 @@ import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import me.xdrop.fuzzywuzzy.FuzzySearch
+import okhttp3.HttpUrl.Companion.toHttpUrl
import timber.log.Timber
import javax.inject.Inject
import kotlin.math.pow
@@ -429,4 +430,20 @@ class MessageTabPresenter @Inject constructor(
+ dateRatio.toDouble().pow(2) * 2
).toInt()
}
+
+ fun onPanicButtonClicked() {
+ resourceFlow { studentRepository.getCurrentStudent() }
+ .onResourceError { errorHandler.dispatch(it) }
+ .onResourceSuccess {
+ val baseUrl = it.scrapperBaseUrl.toHttpUrl()
+ val urlToOpen = baseUrl.newBuilder()
+ .host("uonetplus${it.scrapperDomainSuffix}-wiadomosciplus.${baseUrl.host}")
+ .addPathSegment(it.symbol)
+ .build()
+ .toString()
+
+ view?.openPanicWebView(urlToOpen)
+ }
+ .launch("panic_button")
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt
index 247af4342..e544a3d68 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt
@@ -50,4 +50,6 @@ interface MessageTabView : BaseView {
fun showRecyclerBottomPadding(show: Boolean)
fun showMailboxChooser(mailboxes: List)
+
+ fun openPanicWebView(url: String)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/panicmode/PanicModeFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/panicmode/PanicModeFragment.kt
new file mode 100644
index 000000000..df51c5f94
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/panicmode/PanicModeFragment.kt
@@ -0,0 +1,99 @@
+package io.github.wulkanowy.ui.modules.panicmode
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import android.view.View
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.activity.addCallback
+import androidx.core.os.bundleOf
+import dagger.hilt.android.AndroidEntryPoint
+import io.github.wulkanowy.R
+import io.github.wulkanowy.data.WulkanowySdkFactory
+import io.github.wulkanowy.databinding.FragmentPanicModeBinding
+import io.github.wulkanowy.ui.base.BaseFragment
+import io.github.wulkanowy.ui.modules.main.MainView
+import io.github.wulkanowy.utils.WebkitCookieManagerProxy
+import io.github.wulkanowy.utils.openInternetBrowser
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class PanicModeFragment : BaseFragment(R.layout.fragment_panic_mode),
+ MainView.TitledView {
+
+ @Inject
+ lateinit var wulkanowySdkFactory: WulkanowySdkFactory
+
+ @Inject
+ lateinit var webkitCookieManagerProxy: WebkitCookieManagerProxy
+
+ private var webView: WebView? = null
+
+ override val titleStringId: Int get() = R.string.panic_mode_title
+
+ companion object {
+
+ private const val PANIC_URL = "panic_mode_url"
+ fun newInstance(url: String?): PanicModeFragment {
+ return PanicModeFragment().apply {
+ arguments = bundleOf(PANIC_URL to url)
+ }
+ }
+ }
+
+ @SuppressLint("SetJavaScriptEnabled")
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ binding = FragmentPanicModeBinding.bind(view)
+
+ binding.panicModeRefresh.setOnClickListener {
+ binding.panicModeWebview.loadUrl(
+ binding.panicModeWebview.url ?: arguments?.getString(PANIC_URL).orEmpty()
+ )
+ }
+ binding.panicModeBack.setOnClickListener { binding.panicModeWebview.goBack() }
+ binding.panicModeHome.setOnClickListener {
+ binding.panicModeWebview.loadUrl(
+ arguments?.getString(PANIC_URL).orEmpty()
+ )
+ }
+ binding.panicModeForward.setOnClickListener { binding.panicModeWebview.goForward() }
+ binding.panicModeShare.setOnClickListener {
+ requireContext().openInternetBrowser(
+ binding.panicModeWebview.url.toString(),
+ )
+ }
+
+ val onBackPressedCallback = requireActivity().onBackPressedDispatcher
+ .addCallback(viewLifecycleOwner) {
+ binding.panicModeWebview.goBack()
+ }
+
+ with(binding.panicModeWebview) {
+ webView = this
+ with(settings) {
+ javaScriptEnabled = true
+ userAgentString = wulkanowySdkFactory.createBase().userAgent
+ }
+
+ webViewClient = object : WebViewClient() {
+ override fun doUpdateVisitedHistory(
+ view: WebView?,
+ url: String?,
+ isReload: Boolean
+ ) {
+ binding.panicModeBack.isEnabled = binding.panicModeWebview.canGoBack()
+ binding.panicModeForward.isEnabled = binding.panicModeWebview.canGoForward()
+ onBackPressedCallback.isEnabled = binding.panicModeWebview.canGoBack()
+ }
+ }
+ loadUrl(arguments?.getString(PANIC_URL).orEmpty())
+ }
+ }
+
+ override fun onDestroy() {
+ webkitCookieManagerProxy.webkitCookieManager?.flush()
+ webView?.destroy()
+ super.onDestroy()
+ }
+}
diff --git a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt
index e43654b8b..4cce4be43 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt
@@ -30,6 +30,10 @@ fun getRefreshKey(name: String, mailbox: Mailbox?, folder: MessageFolder): Strin
return "${name}_${mailbox?.globalKey ?: "all"}_${folder.id}"
}
+fun getRefreshKey(name: String): String {
+ return name
+}
+
class AutoRefreshHelper @Inject constructor(
@ApplicationContext private val context: Context,
private val sharedPref: SharedPrefProvider
diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt
index e7a50d0c3..77689fcb7 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt
@@ -1,14 +1,32 @@
package io.github.wulkanowy.utils
import java.text.SimpleDateFormat
-import java.time.*
-import java.time.DayOfWeek.*
+import java.time.DayOfWeek.FRIDAY
+import java.time.DayOfWeek.MONDAY
+import java.time.DayOfWeek.SATURDAY
+import java.time.DayOfWeek.SUNDAY
+import java.time.Instant
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.Month
+import java.time.ZoneId
+import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
-import java.time.temporal.TemporalAdjusters.*
-import java.util.*
+import java.time.temporal.TemporalAdjusters.firstInMonth
+import java.time.temporal.TemporalAdjusters.next
+import java.time.temporal.TemporalAdjusters.previous
+import java.util.Locale
private const val DEFAULT_DATE_PATTERN = "dd.MM.yyyy"
+fun getDefaultLocaleWithFallback(): Locale {
+ val locale = Locale.getDefault()
+ if (locale.language == "csb") {
+ return Locale.forLanguageTag("pl")
+ }
+ return locale
+}
+
fun LocalDate.toTimestamp(): Long = atStartOfDay()
.toInstant(ZoneOffset.UTC)
.toEpochMilli()
@@ -23,7 +41,7 @@ fun String.toLocalDate(format: String = DEFAULT_DATE_PATTERN): LocalDate =
LocalDate.parse(this, DateTimeFormatter.ofPattern(format))
fun LocalDate.toFormattedString(pattern: String = DEFAULT_DATE_PATTERN): String =
- format(DateTimeFormatter.ofPattern(pattern))
+ format(DateTimeFormatter.ofPattern(pattern, getDefaultLocaleWithFallback()))
fun Instant.toFormattedString(
pattern: String = DEFAULT_DATE_PATTERN,
@@ -31,7 +49,7 @@ fun Instant.toFormattedString(
): String = atZone(tz).format(DateTimeFormatter.ofPattern(pattern))
fun Month.getFormattedName(): String {
- val formatter = SimpleDateFormat("LLLL", Locale.getDefault())
+ val formatter = SimpleDateFormat("LLLL", getDefaultLocaleWithFallback())
val date = LocalDateTime.now().withMonth(value)
return formatter.format(date.toInstant(ZoneOffset.UTC).toEpochMilli()).capitalise()
@@ -76,7 +94,7 @@ inline val LocalDate.previousOrSameSchoolDay: LocalDate
}
inline val LocalDate.weekDayName: String
- get() = format(DateTimeFormatter.ofPattern("EEEE", Locale.getDefault()))
+ get() = format(DateTimeFormatter.ofPattern("EEEE", getDefaultLocaleWithFallback()))
inline val LocalDate.monday: LocalDate get() = with(MONDAY)
diff --git a/app/src/main/play/release-notes/pl-PL/default.txt b/app/src/main/play/release-notes/pl-PL/default.txt
index fb07d4244..329da27f1 100644
--- a/app/src/main/play/release-notes/pl-PL/default.txt
+++ b/app/src/main/play/release-notes/pl-PL/default.txt
@@ -1,8 +1,5 @@
-Wersja 2.6.0
+Wersja 2.6.15
-— dodaliśmy kalkulator frekwencji
-— dodaliśmy wyświetlanie lekcji dodatkowych w planie lekcji
-— ulepszyliśmy wyjaśnienie na ekranie z miejscem na wpisanie numeru PESEL
-— naprawiliśmy rzadkie sytuacje, gdy plan lekcji nakładał się na informację o jego braku
+— naprawiliśmy moduł wiadomości
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
diff --git a/app/src/main/res/layout/fragment_message_tab.xml b/app/src/main/res/layout/fragment_message_tab.xml
index f17ec8df9..1bbf08817 100644
--- a/app/src/main/res/layout/fragment_message_tab.xml
+++ b/app/src/main/res/layout/fragment_message_tab.xml
@@ -60,6 +60,16 @@
tools:ignore="UseCompoundDrawables"
tools:visibility="invisible">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_dashboard_admin_message.xml b/app/src/main/res/layout/item_dashboard_admin_message.xml
index 407e12921..0d519b7ea 100644
--- a/app/src/main/res/layout/item_dashboard_admin_message.xml
+++ b/app/src/main/res/layout/item_dashboard_admin_message.xml
@@ -1,87 +1,105 @@
-
+ android:orientation="vertical">
-
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="12dp"
+ android:layout_marginVertical="6dp">
-
-
+
-
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_dashboard_panic_button.xml b/app/src/main/res/layout/item_dashboard_panic_button.xml
new file mode 100644
index 000000000..5f5936cf1
--- /dev/null
+++ b/app/src/main/res/layout/item_dashboard_panic_button.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-cs/preferences_values.xml b/app/src/main/res/values-cs/preferences_values.xml
index c9b2258fc..fa5bad545 100644
--- a/app/src/main/res/values-cs/preferences_values.xml
+++ b/app/src/main/res/values-cs/preferences_values.xml
@@ -19,6 +19,7 @@
- Deutsch
- Čeština
- Slovenčina
+ - Kaszëbsczi
- 15 minut
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index c89414a21..bfb19ee14 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -29,7 +29,7 @@
Centrum oznámení
Konfigurace menu
- Semestr %1$d, %2$d/%3$d
+ Pololetí %1$d, %2$d/%3$d
Přihlaste se pomocí žákovského nebo rodičovského účtu
Zadejte symbol ze stránky deníku: <b>%1$s</b>
@@ -105,8 +105,8 @@
Zapnout reklamy
Známka
- Semestr %d
- Změnit semestr
+ Pololetí %d
+ Změnit pololetí
Žádné známky
Váha
Váha: %s
@@ -125,16 +125,16 @@
Vypočítaný pololetní průměr
Vypočítaný roční průměr
Jak funguje vypočítaný průměr?
- 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\nPrůměr známek pouze z vybraného semestru:\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\nPrůměr průměrů z obou semestrů:\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\nPrůměr známek z celého roku:\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ů
+ 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\nPrůměr známek pouze z vybraného pololetí:\n1. Výpočet váženého průměru pro každý předmět v daném pololetí\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\nPrůměr průměrů z obou pololetí:\n1. Výpočet váženého průměru pro každý předmět v pololetí 1 a 2\n2. Výpočet aritmetického průměru vypočítaných průměrů za pololetí 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\nPrůměr známek z celého roku:\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. pololetí 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ů
Jak funguje konečný průměr?
- Konečný průměr je aritmetický průměr vypočítaný ze všech aktuálně dostupných konečných známek v daném semestru.\n\nSchéma výpočtu se skládá z následujících kroků:\n1. Sčítání konečných známek zadaných učiteli\n2. Děleno počtem předmětů, pro které už byly uděleny známky
+ Konečný průměr je aritmetický průměr vypočítaný ze všech aktuálně dostupných konečných známek v daném pololetí.\n\nSchéma výpočtu se skládá z následujících kroků:\n1. Sčítání konečných známek zadaných učiteli\n2. Děleno počtem předmětů, pro které už byly uděleny známky
Konečný průměr
z %1$d z %2$d předmětů
Shrnutí
Třída
Označit jako přečtené
Částečně
- Semestr
+ Pololetí
Body
Vysvětlivky
Průměr třídy: %1$s
@@ -499,7 +499,7 @@
Mobilní přístup
Žádná zařízení
Zrušit registraci
- Zařízení odstranění
+ Zařízení odstraněno
QR kód
Token
Symbol
@@ -872,6 +872,8 @@
Webová stránka deníku VULCAN vyžaduje ověření
Proč se mi to zobrazuje?\nWebová stránka deníku, ze které Wulkanowy stahuje data, zobrazuje stejnou obrazovku jako výše, takže Wulkanowy ji musí také zobrazit, aby bylo možné získávat data z této stránky. Nedá se to obejít
Úspěšně ověřeno
+
+ Nouzový přístup
Žádné internetové připojení
Vyskytla se chyba. Zkontrolujte hodiny svého zařízení
diff --git a/app/src/main/res/values-csb-rPL/preferences_values.xml b/app/src/main/res/values-csb-rPL/preferences_values.xml
new file mode 100644
index 000000000..902014177
--- /dev/null
+++ b/app/src/main/res/values-csb-rPL/preferences_values.xml
@@ -0,0 +1,76 @@
+
+
+ Alfabéticzno
+ Pòdług datë
+ Pòdług strzédny
+ Pòdług procentu bëtnoscë
+ Pòdług salda frekwencje na przibiorze
+
+ - Jôsny
+ - Cemny
+ - Cemny (AMOLED)
+
+
+ - Systemòwi jãzëk
+ - Polski
+ - English
+ - Pусский
+ - Українська
+ - Deutsch
+ - Čeština
+ - Slovenčina
+ - Kaszëbsczi
+
+
+ - 15 minutów
+ - 30 minutów
+ - 1 gòdzëna
+ - 2 gòdzënë
+ - 6 gòdzyn
+ - 12 gòdzyn
+ - 24 gòdzyn
+
+
+ - 0,00
+ - 0,25
+ - 0,33
+ - 0,5
+ - 0,75
+
+
+ - Dzienniczek+
+ - Wulkanowy
+ - Farwa taksów w dzénnikù
+
+
+ - Do 1 na rôz
+ - Wiedno rozwiniãti
+ - Rozwijanié bez grańców
+
+
+ - Strzédnô taksów leno z wëbrónégò semestru
+ - Strzédnô z strzédnëch z òbùch semestrów
+ - Strzédnô wszëtczich taksów z całégò rokù
+
+
+ - Nié pòkazuj
+ - Leno midzë ùczbama
+ - Przed a midzë ùczbama
+
+
+ - Nié pòkazuj
+ - Pòkażë razã
+ - Pòkôżë niżi zwëczajné ùczbë
+
+
+ - Szczestlëwi numerk
+ - Nieprzeczëtóné wiadë
+ - Frekwencjô
+ - Ùczbë
+ - Taksë
+ - Zadanié dodóm
+ - Szkòlowi ògłos
+ - Testë
+ - Zéńdzenia
+
+
diff --git a/app/src/main/res/values-csb-rPL/strings.xml b/app/src/main/res/values-csb-rPL/strings.xml
new file mode 100644
index 000000000..010a30821
--- /dev/null
+++ b/app/src/main/res/values-csb-rPL/strings.xml
@@ -0,0 +1,851 @@
+
+
+
+ Logòwanié
+ Wulkanowy
+ Taksë
+ Frekwencjô
+ Testë
+ Plan zajmów
+ Nastôwë
+ Wicy
+ Ò aplikacëje
+ Pòkazéwôcz logów
+ Debùgòwanié
+ Debùgòwanié wiadłów
+ Rëmni kùszczi webview
+ Wkłôdôrze
+ Licencëje
+ Wiadë
+ Nowô wiada
+ Nowé zadanié dodóm
+ Ùwôdżi i pòstãpë
+ Zadanié dodóm
+ Czerownik kòntów
+ Wëbierzë kònto
+ Drobnotë kònta
+ Jinfòrmacëje ò ùczniu
+ Doma
+ Centrum wiadłów
+ Kònfigùracëjô menu
+
+ Semestr %1$d, %2$d/%3$d
+
+ Zalogùj sã brëkùjącë kònta ùcznia abò rodzëca
+ Pòdôj symbòl z starnë dzénnika dlô kònta: <b>%1$s</b>
+ Pòzwa brëkòwnika
+ Adresa E-mail
+ Login, PESEL abò adresa e-mail
+ Parola
+ Wariant dzénnika UONET+
+ Niesztandardowi sufiks domenë
+ Mòbilné API
+ Scraper
+ Hibdridowé
+ Token
+ PIN
+ Symbol
+ Np. \"lodz\" czë \"powiatjaroslawski\"
+ Zalogùj
+ Parola je za krótkô
+ Dane logòwaniô są niépasowné
+ %1$s. Ùgwësni sã, że wëbrôno pòprawną òdmianã dzénnika UONET+ niżi
+ Niepasowny PIN
+ Niepasowny token
+ Token wëgôsł
+ Niepasowny adresa e-mail
+ Ùżij loginu miast adresu e-mail
+ Ùżij loginu abò adresu e-mail w @%1$s
+ Niepasowny sufiks domenë
+ Niepasowny symbòl. Żelë nié mòżesz gò nalézc, proszã skòntaktowac sã z szkòłą
+ Nie szkaluj! żelë nié mòżesz nalézc symbòlu, skòntaktuj sã z szkòłą
+ Ùczeń nie nalazłi. Sprôwdzë pòprawnosc symbòlu i wëbróny òdmianë dzénnika UONET+
+ Wëbróny ùczeń je ju zalogòwóny
+ Symbòl mòżna nalézc na starnie dzénnika w Ùczeń→ Dostãp mòbilny → Wëgeneruj kòd dostãpù .\n\nÙgwësni sã, że ùstôwił jes pasowną òdmianã dzénnika w pòlu Òdmiana dzénnika UONET+ na pierszim ekranie logòwania
+ Wëbierzë ùczniów do zalogòwaniô w aplikacëje
+ Jiné òpcëje
+ W tim tribie nie dzejô szczestlëwi numerk, ùczeń na tle klasë, pòdrëchòwanié frekwencëje, ùsprôwiedliwianié niebëtnoscë, zajmë zrealizowóné, jimfòrmacëje ò szkòle i pòzdrzatk listë zarejestrowónëch ùrządzeniów
+ Nen trib wëswietlô ne samé dane, chtërne są widoczné na jinternetowi starnie dzénnika
+ Sparłãczënié nôlepszich znanków dwùch òstatnich tribów. Dzejô chùdzy jak scraper i ùgwësniô Fùnkcëje niédostãpné w tribie Mòbilné API, Je to w eksperimentalnym stadium
+ Pòlitëka priwatnoscë
+ Tôkel z logòwanim? Napiszë do naju!
+ E-mail
+ Discord
+ Wëslë e-mail
+ Ùgwësni sã, że òsta wëbrónô òdpòwiedniô òdmiana dzénnika UONET+!
+ Resetuj parolã
+ Przëwarcë swòje kònto
+ Przëwarcë
+ Ùczeń je ju zalogòwóny
+ Sztandardowô
+ Jinô lokalizacëjô wësznëkrowaniô
+ Nie nalazło aktiwnëch ùczniów
+ Wprowadzë jiny symbòl
+ Zëskôj pòmòc
+ Fùl pòzwa szkòłë z gardã (Wëmôgô)
+ Np. ZSTiO Jarosław abò SP nr 99 w Łodzi
+ Wprowadzë pòprawną pòzwã szkòłë
+ Dodôtkòwé jinfòrmacëje pò Pòlskù (Òpcjonalno)
+ Np. \"Òstatnio zmienił jem szkòłã i…\" abò \"Jô jem rodzëcã i nié widzã drëdżégò dzecka…\"
+ Wëslë
+
+ Włączë wiadła
+ Włączë wiadła, abë nie zabôczëc wiadów òd szkólnëch abò nowi taksë
+ Pòmiń
+ Włączë
+
+ Czerownik kòntów
+ Zalogùj sã
+ Sesjô zgasłô
+ Sesja zgasłô, zalogùj sã znôwa
+ Parola zgasłô abò òsta zmieniona
+ Parola do twòjégò kònta zgasłô abò òsta zmieniona. Mùszisz zalogòwac sã znôwa do Wùlkanowégò
+ Wspiarcé aplikacëje
+ Widzy cë sã ta aplikacëjô? Wësprzë ji rozwój pòprzez włączenié nieszkòdzącëch reklamów, chtërne mòżesz wëłączëc w kôżdim mòmence
+ Włączë reklamë
+
+ Taksa
+ Semestr %d
+ Zmieni semestr
+ Felënk taksów
+ Wôga
+ Wôga: %s
+ Kòmentôrz
+ Jilosc nowich taksów: %1$d
+ Strzédnô: %1$.2f
+ Rocznô: %1$.2f
+ Pónktë: %s
+ Felënk strzédny
+ Strzédnô semestru
+ Strzédnô rocznô
+ Jilosc pónktów
+ Kùńcowô taksa
+ Spòdzónô taksa
+ Òpisowô taksa
+ Òbliczonô strzédnô semestru
+ Òbliczonô rocznô strzédna
+ Jak dzejô òbliczonô strzédnô?
+ Òbrechòwiwónô strzédnô to je aritmeticznô strzédnô jakô je òbrechòwiwónô ze strzédnëch z apartnëch przibiorów. Pòzwôlô na doznanié sã przëblëżony kùńcowi strzédny. Òna je òbrechòwiwónô na ôrt wëbróny przez brëkòwnika w nastawach aplikacje. Bédëjemë wëbrac pasowną òpcją, kò òbrechòwiwanié szkòłowëch strzédnëch mòże sã jinaczëc. Żelë wasza szkòła pòdôwô strzédné z przibiorów na starnie Vulcan, aplikacjô je scygô a sama nick nie òbrechòwiwô. To mòże to zmienic przez wëmùszenié òbrechòwiwaniégò w nastawach aplikacje.\n\nStrzédnô taksów leno z wëbrónégò semestru:\n1. Òbrechòwiwanié wôżony strzédny dlô kòżdégò przibioru w dónym semestrze\n2.Dodôwanié òbrechòwónëch strzédnëch\n3. Òbrëchòwiwanié aritmeticzny strzédny ze strzédnëch zesadzonëch razã\n\nStrzédnô ze strzédnëch z òbùch semestrów:\n1.Òbrechòwiwanié wôżony strzédny dlô kòżdégò przibioru w 1. i 2. semestrze\n2. Òbrechòwiwanié aritmeticzny strzédny ze strzédnëch òbrechòwónëch dlô kòżdégò przëbioru na semester 1. i 2.\n3. Dodôwanié òbrechòwónëch strzédnëch\n4. Òbrëchòwiwanié aritmeticzny strzédny ze strzédnëch zesadzonëch razã\n\nStrzédnô taksów z całégò rokù:\n1. Òbrechòwiwanié wôżony strzédny w rocznym pòzdrzatkù dlô kòżdégò przibioru. Kùńcowô strzédnô w 1. semestrze sã nie rechùje. \n2. Dodôwanié òbrechòwónëch strzédnëch\n3. Òbrëchòwiwanié aritmeticzny strzédny ze strzédnëch zesadzonëch razã
+ Jak fónksnéruje kùńcowô strzédna?
+ Kùńcową strzédną je strzédnô aritmetëcznô òbliczonô na spòdlim wszëtczich òbecno dostãpnëch taksów kùńcowëch w danym semestrze.\n\nSchemat òbliczeniów skłôdô sã z nôstãpùjącëch kroków:\n1. Sumòwanié kùńcowëch taksów wpisanëch przez szkólnëch\n2. Dzélenié przez lëczbã zajmów, z chtërnëch taksë òstałë ju wstôwioné
+ Kùńcowô strzédna
+ z %1$d na %2$d zajmów
+ Pòdrëchòwanié
+ Klasa
+ Zamérkô jakò przeczëtóné
+ Cawné
+ Semestr
+ Pónktë
+ Legenda
+ Strzédna klasë: %1$s
+ Twòja strzédnô: %1$s
+ Twòja taksa: %1$s
+ Klasa
+ Ùczeń
+
+ - %d taksa
+ - %d taksë
+ - %d taksów
+
+
+ - Nowô taksa
+ - Nowé taksë
+ - Nowé taksë
+
+
+ - Nowô spòdzónô taksa
+ - Nowé spòdzóné taksë
+ - Nowé spòdzóné taksë
+
+
+ - Nowô kùńcowô taksa
+ - Nowé kùńcowé taksë
+ - Nowé kùńcowé taksë
+
+
+ - Nowô òpisowô taksa
+ - Nowé òpisowé taksë
+ - Nowé òpisowé taksë
+
+
+ - Môsz %1$d nową taksã
+ - Môsz %1$d nowé taksë
+ - Môsz %1$d nowëch taksów
+
+
+ - Môsz %1$d nową spodzóną taksã
+ - Môsz %1$d nowé spodzón taksë
+ - Môsz %1$d nowëch spodzónëch taksów
+
+
+ - Môsz %1$d nową kùńcową taksã
+ - Môsz %1$d nowé kùńcowé taksë
+ - Môsz %1$d nowëch kùńcowëch taksów
+
+
+ - Môsz %1$d nową òpisową taksã
+ - Môsz %1$d nowé òpisowé taksë
+ - Môsz %1$d nowëch òpisowëch taksów
+
+
+ Ùczba
+ Dodôtkòwô ùczba
+ Zala
+ Karno
+ Gòdzënë
+ Zmianë
+ Felënk ùczbów dzysô
+ %s min
+ %s sek
+ jesz %1$s
+ za %1$s
+ Fardëch
+ Terô: %s
+ Pòstãpné: %s
+ Pózdni: %s
+ %1$s ùczba %2$d - %3$s
+ Pòzmiana zalë z %1$s na %2$s
+ Pòzmiana szkólnégò z %1$s na %2$s
+ Pòzmiana zajmë z %1$s na %2$s
+
+ - Ni ma ùczbë
+ - Ni ma ùczbów
+ - Ni ma ùczbów
+
+
+ - Pòzmiana planu zajmów
+ - Pòzmianë planu zajmów
+ - Pòzmianë planu zajmów
+
+
+ - %1$s - %2$d Pòzmiana planu zajmów
+ - %1$s - %2$d Pòzmianë planu zajmów
+ - %1$s - %2$d Pòzmianów planu ùczbów
+
+
+ - %1$d Pòzmiana planu zajmów
+ - %1$d Pòzmianë planu zajmów
+ - %1$d Pòzmianë planu zajmów
+
+
+ - %d Pòzmiana
+ - %d Pòzmianë
+ - %d Pòzmianë
+
+
+ Ùczbë są skùńczoné
+ Pòkôżë skùńczoné ùczbë
+ Felënk jinfòrmacëjów ò ùkòńczonëch ùczbach
+ Témat
+ Niebëtnosc
+ Zôsóbczi
+
+ Dodatkòwé ùczbë
+ Pòkôżë dodatkòwé ùczbë
+ Felënk jinfòrmacëjów ò dodôtkòwëch ùczbach
+ Nowô ùczba
+ Nowô dodatkòwô ùczba
+ Dodatkòwa ùczba òsta dodónô z sukcesã
+ Dodôtkòwô ùczba òsta rëmniãtô z sukcesã
+ Pòwtórzë co tidzéń
+ Rëmni dodôtkòwą ùczbã
+ Leno ta ùczba
+ Wszëtczé w serie
+ Gòdzëna zôczãcô
+ Gòdzëna skùńczeniô
+ Gòdzëna skùńczeniô mùszi bëc pózdniszô jak gòdzëzna zôczãcô
+
+ Pòdrëchòwanié bëtnoscë
+ Kalkulator bëtnoscë
+ %1$d Wëżi célu
+ dokładno kù célu
+ %1$d niżi célu
+ %1$d/%2$d bëtnoscë
+ Nié zaùwôżono niżôdny frekwencëje
+ Niebëtnosc z szkòlnëch przëczënów
+ Ùsprawiedlëwiono niéòbecnosc
+ Nieùsprawiedlëwiono niéòbecnosc
+ Zwòlnienié
+ Spózdnienié ùsprawiedlëwioné
+ Spózdnienié Nieùsprawiedlëwioné
+ Bëtnosc
+ Rëmniãto
+ Niéznóny
+ Lëczba ùczbów
+ Ni ma wpisów
+ Pòwód niebëtnoscë (òpcjonalny)
+ Wëslë
+ Proszba ò ùsprawiedlëwienié òsta wësłónô z sukcesã!
+ Mùszisz wëbrac bënômni jedną nieòbecnosc!
+ Ùsprawiedliwi
+
+ - Nowô frekwencjô
+ - Nowé frekwencëje
+ - Nowé frekwencëje
+
+
+ - %1$d nowô frekwencjô
+ - %1$d nowé frekwencëje
+ - %1$d nowëch frekwencjów
+
+
+ - %d frekwencjô
+ - %d frekwencëje
+ - %d frekwencjów
+
+
+ Razã
+
+ Ni ma testów w tim tidzéniu
+ Ôrt
+ Data wpisënkù
+
+ - Nowi test
+ - Nowé testë
+ - Nowé testë
+
+
+ - %d nowi test
+ - %d nowé testë
+ - %d nowëch testów
+
+
+ - %d test
+ - %d testë
+ - %d testów
+
+
+ Òdebróné
+ Wësłóno
+ Wãbórk
+ (Niżôdny témat)
+ Ni ma wiadów
+ Òd:
+ Do:
+ Data: %1$s
+ Òdrzekni
+ Wëslë dali
+ Zamérkô wszëtkò
+ Òdmérkô wszëtkò
+ Przëwrócë z wãbórka
+ Przeniesë do wãbórka
+ Rëmni na wiedno
+ Wiada òsta przëwróconô z sukcesã
+ Wiada òsta rëmniãtô z sukcesã
+ ùczeń
+ rodzëc
+ òpiekùn
+ robòtnik
+ Ùdostãpni
+ Drukùj
+ Témat
+ Tresc
+ Wiada òsta wësłónô z sukcesã
+ Wiada nie jistnieje
+ Mùszisz wëbrac bënômni 1 adresata
+ Tresc wiadë mùszi zawierac bënômni 3 znanczi
+ Wszëtczé skrzënie
+ Leno nieprzeczëtóné
+ Leno z lopkama
+ Przeczëtónô: %s
+ Przeczëtónô bez: %1$d z %2$d osób
+
+ - %1$d wiada
+ - %1$d wiadë
+ - %1$d wiadë
+
+
+ - Nowô wiada
+ - Nowé wiadë
+ - Nowé wiadë
+
+ Chcemë le przëwrócyc robòczą wersëją wiadów?
+ Chcemë le przëwrócyc robòczą wersëją wiadów z adresatama? %s?
+
+ - Môsz %1$d nową wiadã
+ - Môsz %1$d nowé wiadë
+ - Môsz %1$d nowëch wiadów
+
+
+ - %1$d wëbrónô
+ - %1$d wëbróné
+ - %1$d wëbrónëch
+
+ Wiadë òstałë rëmniãté
+ Przewrócono wiadë
+ Wëbierzë skrzënią
+ Trib incognito je włączony
+ Dzãka tribòwi incognito nadôwca nié òbôczi, że przeczëtôł jes ną wiadã
+
+ Ni ma jinfòrmacëjów ò ùwôgach
+ Pónktë
+
+ - %d ùwôga
+ - %d ùwôdżi
+ - %d ùwôgów
+
+
+ - Nowô ùwôga
+ - Nowé ùwôdżi
+ - Nowé ùwôdżi
+
+
+ - Môsz %1$d nową ùwôgã
+ - Môsz %1$d nowé ùwôdżi
+ - Môsz %1$d nowëch ùwôgów
+
+
+
+ - %d chwôła
+ - %d chwałë
+ - %d chwôłów
+
+
+ - Nowô chwôła
+ - Nowé chwôłë
+ - Nowé chwôłë
+
+
+ - Môsz %1$d nową chwôłã
+ - Môsz %1$d nowé chwôłë
+ - Môsz %1$d nowëch chwôłów
+
+
+
+ - %d neùtralnô ùwôga
+ - %d neùtralné ùwôdżi
+ - %d neùtralnëch ùwôgów
+
+
+ - Nowô neùtralnô ùwôga
+ - Nowé neùtralné ùwôdżi
+ - Nowé neùtralné ùwôdżi
+
+
+ - Môsz %1$d nową neùtralną ùwôgã
+ - Môsz %1$d nowé neùtralné ùwôdżi
+ - Môsz %1$d nowëch neùtralnëch ùwôgów
+
+
+ Ni ma zadaniów dodóm
+ Fardëch
+ Nié je fardëch
+ Dodôj Zadanié dodóm
+ Zadanié dodóm dodóné z sukcesã
+ Zadanié dodóm rëmniãté z sukcesã
+ Lópk
+
+ - Nowé zadanié dodóm
+ - Nowé zadania dodóm
+ - Nowé zadania dodóm
+
+
+ - Môsz %d nowé zadania dodóm
+ - Môsz %d nowé zadania dodóm
+ - Môsz %d nowëch zadaniów dodóm
+
+
+ - %d zadanié dodóm
+ - %d zadania dodóm
+ - %d zadaniów dodóm
+
+
+ Szczestlëwi numerk
+ Dzysészim szczestlëwim numerkã je
+ Ni ma jinfòrmacëjów ò szczestlëwim numerkù
+ Szczestlëwi numerk na dzysô
+ Dzysészim szczestlëwim numerkã je: %s
+ Pòkôżë historëją
+
+ Historijô numerków
+ Ni ma jinfòrmacëjów ò szczestlëwich numerkach
+
+ Przëstãp mòbilny
+ Ni ma ùrządzeniów
+ Wërejestruj
+ Ùrządzenié òstało rëmniãté
+ Kòd QR
+ Token
+ Symbol
+ PIN
+
+ Szkòła i szkólny
+
+ Szkòła
+ Ni ma jinfòrmacëjów ò szkòle
+ Pòzwa szkòłë
+ Adresa szkòłë
+ Telefòn
+ Miono i nôzwëskò direktóra
+ Miono i nôzwëskò pedagóga
+ Pòkôżë na kôrce
+ Zazwòni
+
+ Szkólny
+ Ni ma jinfòrmacëjów ò szkólnëch
+ Ni ma zajmë
+
+ Zéńdzenia
+ Ni ma jinfòrmacëjów ò zéńdzeniach
+
+ - %d zéńdzenié
+ - %d zéńdzenia
+ - %d zéńdzeniów
+
+
+ - Nowé zéńdzenie
+ - Nowé zéńdzenia
+ - Nowé zéńdzenia
+
+
+ - Môsz %1$d nowé zéńdzenié
+ - Môsz %1$d nowé zéńdzenia
+ - Môsz %1$d nowëch zéńdzeniów
+
+ Òbecnosc na zéńdzenim
+ Agenda
+ Plac
+ Témat
+
+ Szkòlowi ògłos
+ Ni ma szkòlowich ògłosów
+
+ - %d szkòlowi ògłos
+ - %d szkòlowé ògłosë
+ - %d szkòlowich ògłosów
+
+
+ - %d Nowi szkòlowi ògłos
+ - %d Nowé szkòlowé ògłosë
+ - %d Nowé szkòlowé ògłosë
+
+
+ - Môsz %1$d nowi szkòlowi ògłos
+ - Môsz %1$d nowé szkòlowé ògłosë
+ - Môsz %1$d nowëch szkòlowich ògłosów
+
+
+ Dodôj kònto
+ Wëlogùj sã
+ Chcemë le wëlogòwac tegò ùcznia?
+ Wëlogòwanié ùcznia
+ Kònto ùcznia
+ Rodzëcelsczé kònto
+ Edituj dane
+ Czerownik kòntów
+ Wëbierzë ùcznia
+ Rodzëzna
+ Kòntakt
+ Adresowé dane
+ Òsobòwé dane
+
+ Wersëjô aplikacëje
+ Wkłôdôrze
+ Lësta programistów Wùlkanowégò
+ Zgłosë błãd
+ Wëslë zgłoszenié ò błãdze bez e-mail
+ FAQ
+ Òbôczë nôczãscy zadawóné pëtania
+ Serwer Discord
+ Dołączë do spòlëznë Wùlkanowégò
+ Fanpage na Facebookù
+ Starna na Twitterze
+ Szlachùj nas na Twitterze
+ Pòlub najégò fanpage na Facebookù
+ Pòlitëka priwatnoscë
+ Regle zbieraniégò òsobòwëch danëch
+ Systemòwé nastôwë
+ Òdemkni systemòwé nastôwë
+ Domôcô starna
+ Òdwiedzë starnã i pòmòżë rozwijac aplikacëją
+ Licencëje
+ Licencëje ùżitëch biblijotéków w aplikacëje
+
+ Licencëjô
+
+ Awatar
+ Òbôczë wicy na GitHub
+
+ Ni ma jinfòrmacëjów ò ùczniu abò rodzëznie ùcznia
+ Miono
+ Drëdżé miono
+ Płoc
+ Pòlsczé òbëwatelstwò
+ Rodné nazwëskò
+ Miono òjca i mùterczi
+ Telefòn
+ Mòbilk
+ Adresa e-mail
+ Adresa zamieszkaniô
+ Adresa zameldowaniô
+ Adresa kòrespòndencëjnë
+ Nôzwëskò ë miono
+ Stopień pòkrëwieństwa
+ Adresa
+ Telefònë
+ Chłop
+ Białka
+ Nôzwëskò
+ Òpiekùn
+
+ Pòzwa
+ Dodôj Pòzwã
+ Wëbierzë farwã profilowégò
+
+ Ùdostãpni logi
+ Òdswieżë
+
+ Ùczbë
+ (Witro)
+ (Dzysô i witro)
+ Za chwilã:
+ Wnetka:
+ Pierszi:
+ Terô:
+ Kùńc ùczbë
+ Pòstãpno:
+ Pòzdze:
+
+ - Jesz %1$d ùczba
+ - Jesz %1$d ùczbë
+ - Jesz %1$d ùczbów
+
+ do %1$s
+ Felënk przińdłich ùczbów
+ Wëstąpił błãd òbczas ładowaniô ùczbë
+ Zadanié dodóm
+ Ni ma zadaniów dodóm do przërëchtowaniô
+ Wëstąpił błãd òbczas ładowaniô zadaniégò dodóm
+
+ - Jesz %1$d zadanié dodóm
+ - Jesz %1$d zadaniów dodóm
+ - Jesz %1$d zadaniów dodóm
+
+ do %1$s
+ Slédné taksë
+ Ni ma nowëch taksów
+ Wëstąpił błãd òbczas ładowaniô taksów
+ Szkòlowé ògłosë
+ Ni ma aktualnëch ògłosów
+ Wëstąpił błãd òbczas ładowaniô ògłosów
+
+ - Jesz %1$d ògłos
+ - Jesz %1$d ògłosë
+ - Jesz %1$d ògłosów
+
+ Testë
+ Felënk przińdłich testów
+ Wëstąpił błãd òbczas ładowaniô testów
+
+ - Jesz %1$d test
+ - Jesz %1$d testë
+ - Jesz %1$d testów
+
+ Zéńdzenia
+ Ni ma przińdłich zéńdzeniów
+ Wëstąpił błãd òbczas ładowaniô zéńdzeniów
+
+ - Jesz %1$d dodôtkòwé zéńdzenié
+ - Jesz %1$d dodôtkòwé zéńdzenia
+ - Jesz %1$d zéńdzeniów
+
+ Wëstąpił błãd òbczas ładowaniô danëch
+ Niżôdny
+
+ Sprôwdzë dostãpnosc aktualizacëjów
+ Przed zgłoszenim błãdu sprôwdzë wczesny czë dostãpnô je ju aktualizacëjô z pòprôwką błãdu
+
+ Tresc
+ Pònowi
+ Òpisënk
+ Felënk òpisënkù
+ Szkólny
+ Data
+ Data wpisënkù
+ Farwa
+ Detale
+ Kategòrijô
+ Zamkni
+ Ni ma danëch
+ Témat
+ Slédny
+ Pòstãpny
+ Szëkôj
+ Szëkôj…
+ Jo
+ Nié
+ Zapiszë
+ Titel
+ Dodôj
+ Òstało skòpiérowóné
+ Cofni
+ Zmieni
+ Dodôj do kaléndarzu
+ Anuluj
+
+ Ni ma ùczbów
+ Zsynchronizowóno %1$s ò %2$s
+ Wëbierzë témã
+ Jôsny
+ Cemny
+ Systemòwô téma
+
+ Aplikacëjô
+ Domëslny pòzdrzatk
+ Nastôwë òbliczony strzédny
+ Wëmùszë òbliczenié strzédny bez aplikacëją
+ Pòkôżë bëtnosc
+ Docélowô bëtnosc
+ Pòkôżë témë bez frekwencji
+ Zortowanié kalkulatora bëtnoscë
+ Téma
+ Rozwijanié taksów
+ Pòkazuj karno kòl zajmë
+ Pòkôżë dodatkòwé ùczbë
+ Pòkôzuj pùsté kachle gdze ni ma ùczbów
+ Pòkôżë lëstã nacéchùnków w klasowich taksach
+ Pòkôżë zajmë bez taksów
+ Schemat farwów taksów
+ Zortowanié zajmów
+ Jãzëk
+ Kònfigùracëjô menu
+ Ùstôw kòlejnosc fónkcëje w menu
+ Wiadła
+ Jiné
+ Pòkôżë wiadła
+ Pòkôżë wiadła ò przińdłich ùczbach
+ Ùstawi wiadło ò przińdłi ùczbie jakò trwałé
+ Wëłączë ga wiadła nie pòkazëją sã na twòjim zégarkù/òpasce
+ Òdemkô systemòwé nastôwë wiadłów
+ Naprawi tôkle z synchronizacëją i wiadłama
+ Na twòjim ùrządzeniu mògą sã pòkôzywac tôkle z synchronizacëją danëch i wiadłama.\n\nBë je naprawic, dodôj Wùlkanowégò do aùtostartu i wëłączë òptimalizacëją/òszczãdzanié baterije w nastôwach systemòwëch mòbilkù.
+ Pòkôżë debùgòwanié wiadła
+ Synchronizacja je wëłączonô
+ Wiadła òficjalny aplikacëje
+ Przechwatiwanié wiadłów òficjalny aplikacëje
+ Rëmni wiadła òficjalny aplikacëje pò przechwôceniu
+ Przechwatiwanié wiadłów
+ Dzãka ti òpcje mòżesz zwëskac erzac pòwiadomieniów push tak jak w òficjalny aplikacje. Do tegò brëkùjesz ùdzelëc pòzwòleniégò na dostôwanié wszëtczich pòwiadomieniów w systémòwëch nastawach.\n\nJak to dzejô?\nCzedë Dziennik VULCAN wësle do cebie pòwiadomienié, Wulkanowy je òdbierze (do te brëkòwné są te dodôwkòwé pòzwòlenia), a tak ùrëszni synchronizacją, dzãka chtërny bãdze mógł wësłac swòje gwôsné pòwiadomienié.\n\nLENO DLÔ ZAAWANSOWÓNËCH BRËKÒWNIKÓW
+ Wiadła ò przińdłich ùczbach
+ Mùszisz zezwòlëc Wùlkanowémù na twòrzenié alarmów i przëpòmnieniów w nastôwach Twòjégò systemù, abë ùżic ti fónkcje.
+ Jidzë do nastôwów
+ Synchronizacja
+ Automaticznô aktulizacëja
+ Wstrzëmónô òbczas wakacjów
+ Jinterwôł aktualizacëjów
+ Leno Wi-Fi
+ Synchronizuj terô
+ Zsynchronizowóno!
+ Synchronizacëjô sã nié ùda
+ Synchronizacëjô w tokù
+ Òstatniô fùl synchronizacëjô: %s
+ Wôrtnosc plusa
+ Wôrtnosc minusa
+ Òdpòwiadôj z historëją wiadów
+ Licz strzédną aritmeticzną, ga niżôdnô taksa ni ma wôdżi
+ Trib incognito
+ Nie jinfòrmùj ò przeczëtaniu wiadë
+ Wspiarcé
+ Pòlitëka priwatnoscë
+ Zgòdë
+ Pòkôżë zgòdã na òbrabianié danëch
+ Pòkôżë reklamë w aplikacëje
+ Òbezdrzë jedurną reklamã, bë wesprzec projekt
+ Zgòdã na przerôbianié danëch
+ Abë òbézdrzëc reklamã, mùszisz sã zgòdzyc na warënczi przerôbianiégò danëch zawôrtë w naszi Pòlitëce Priwatnoscë
+ Zgôdzóm sã
+ Pòlitëka priwatnoscë
+ Reklama sã ładuje
+ Dzãkùjemë za wspiarcé, wrócë pózdni pò wicy reklamów
+ Zaawansowóné
+ Wëzdrzatk i zachòwanié
+ Wiadła
+ Synchronizacëjô
+ Reklamë
+ Taksë
+ Doma
+ Widocznosc kachlów
+ Frekwencjô
+ Kalkùlator frekwencëje
+ Nastôwë
+ Plan zajmów
+ Taksë
+ Òbliczonô strzédna
+ Wiadë
+ Wëzdrzatk i zachòwanié
+ Jãzëczi, témë, zortowanié témów
+ Wiadła aplikacëje, naprawianié tôklów
+ Wiadła
+ Synchronizacëjô
+ Aùtomaticznô aktualizacëjô, jinterwôł synchronizacëje
+ Wôrtnoscë plusa i minusa, òbliczanié strzédny
+ Zaawansowóné
+ Wersëjô aplikacëje, twórcë, spòlëznowé media
+ Wëswietlanié reklamów, wspiarcé projektu
+
+ Nowé taksë
+ Nowé zadanié dodóm
+ Nowé zéńdzenia
+ Nowé testë
+ Szczestlëwi numerk
+ Nowé wiadë
+ Nowé ùwôdżi
+ Nowé szkòlowé ògłosë
+ Wiadła push
+ Przińdłé ùczbë
+ Debùgòwanié
+ Pòzmianë planu zajmów
+ Nowô frekwencjô
+
+ Czôrny
+ Czerwiony
+ Mòdri
+ Zelony
+ Lilewi
+ Felënk farwë
+
+ Ładowanié aktualizacëje òstało zôczãté…
+ Aktualizacëjô prawie òsta załadowónô.
+ Restartuj
+ Aktualizacëjô sã nié pòwiodła! Wùlkanowi mòże nie dzejac richtic. Rozważë aktualizacëjã
+
+ Restartuj aplikacëjã
+ Żebë zmianë sã zapisałë, aplikacëjô mùszi sã zrestartowac
+ Restartuj
+
+ Autorizacëjô òsta òdrzëconô. Dane chtërne bëłë dóné są niezgòdné z danyma w sekretariace.
+ Złi PESEL
+ PESEL
+ Pòcwierdzë
+ Autorizacëjô skùńczonô z sukcesã
+ Autorizacëjô
+ Drodżi Rodzëcu,<br /><br />Żebë pòcwierdzëc a zagwësnic bezpiek dónëch, prosëmë ò wpisanié niżi numru PESEL ùczni <b>%1$s</b>. Taczé detale są brëkòwné dlô pòprawnégò przedzéleniô przistãpù a téż òbarnë personowëch dónëch zgódno z òbrzesziwającyma reglama.<br /><br />Pò wprowadzenim dónëch, òstóną òne sprôwdzoné, żebë ùgwësnic sã czë przistãp do systémù VULCAN je przëznôwóny leno ùprôwnionym òsobóm. W przëtrôfkù jaczich le wątplëwòtów a tôklów, w célu wëwidnieniô stojiznë skòntaktuj sã ze administracją w szkòle.<br /><br />Ùtrzimiwómë nôwëższé sztandardë òbarnë personowëch dónëch, a garantérëjemë że wszëtczé pòdôwóné jinfòrmacje są w bezpiekù. Aplikacjô Wulkanowy nie przetrzimiwô ani nie przerôbiô numru PESEL.<br /><br />Przëbôcziwómë, że pòdanié fùlnëch a prôwdzëwëch dónëch je òbrzészkòwé a brëkòwné żebë ùżëwac systémù VULCAN.
+ Timczasã pòmiń
+
+ Starna dzénnika VULCAN wëmôga werëfikacëji
+ Dlôcze to widzã?\n Jinternetowô starna dzénnika, z chtërny Wùlkanowy ładuje dabe, wëswietlô ną samą ekranã jak wëżi, tej Wùlkanowy téż mùszi ją pòkôzac, zebë móc załadowac dane z ny starnë. Niémòżnô tegò òbéńc
+ Zwerëfikòwóno z sukcesã
+
+ Awarëjné dostãp
+
+ Felënk sparłãczëniô z jinternetã
+ Wëstąpił błãd. Sprôwdzë twòji ùrządzenia
+ Kònto je niéaktywné. Spróbùj zalogòwac sã pònowno
+ Nie ùdało sã sparłãczëc z dzénnika. Serwerë mògą bëc przecyżoné. Spróbùj pònowno pózdni
+ Ładowanié pòdôwków skùńczoné niezdarã. Proszã spróbòwac znowù pòzdze
+ Twòjô parola zgôsłô abò òsta zmienionô. Zalogùj sã pònowno
+ Wëmôgô zmienic parolã do dzénnika
+ Trwô technicznô przerwa dzénnika UONET+. Spróbùj pònowno pózdni
+ Nieznóné błãd dzénnika UONET+. Spróbùj znowù pòzdze
+ Nieznóné błãd aplikacëji. Proszã spróbòwac znowù pòzdze
+ Brekòwóna werëfikacëja captcha
+ Wëstąpił nieżdónié błãd
+ Funkcëjô je wëłączona przez twòją szkòłã
+ Funkcëjô nie je dostąpnô. Zalogùj sã w jinszim tribie nigle Móbilné API
+ To pòle je brekòwané
+
+ Wëcëszenié
+ Wëłączë wëcëszenié
+ Wëcësził jes tegò brëkòwnika
+ Wëłącził jes wëcëszenié tegò brëkòwnika
+
diff --git a/app/src/main/res/values-de/preferences_values.xml b/app/src/main/res/values-de/preferences_values.xml
index 23828b030..a6d698416 100644
--- a/app/src/main/res/values-de/preferences_values.xml
+++ b/app/src/main/res/values-de/preferences_values.xml
@@ -19,6 +19,7 @@
- Deutsch
- Čeština
- Slovenčina
+ - Kaszëbsczi
- 15 Minuten
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index cc61a83cc..cf682cf56 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -778,6 +778,8 @@
VULCAN\'s Website erfordert Überprüfung
Warum sehe ich das?\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
Erfolgreich verifiziert
+
+ Notfallzugriff
Keine Internetverbindung
Es ist ein Fehler aufgetreten. Überprüfen Sie Ihre Geräteuhr
diff --git a/app/src/main/res/values-pl/preferences_values.xml b/app/src/main/res/values-pl/preferences_values.xml
index 8eafa1cb4..ae7d0ac84 100644
--- a/app/src/main/res/values-pl/preferences_values.xml
+++ b/app/src/main/res/values-pl/preferences_values.xml
@@ -19,6 +19,7 @@
- Deutsch
- Čeština
- Slovenčina
+ - Kaszëbsczi
- 15 minut
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index a56a07791..9d291261e 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -872,6 +872,8 @@
Strona dziennika VULCAN wymaga weryfikacji
Dlaczego to widzę?\nStrona internetowa dziennika, z której Wulkanowy pobiera dane, wyświetla ten sam ekran jak powyżej, więc Wulkanowy musi również ją pokazać, aby móc pobrać dane z tej witryny. Nie da się tego obejść
Pomyślnie zweryfikowano
+
+ Dostęp awaryjny
Brak połączenia z internetem
Wystąpił błąd. Sprawdź poprawność daty w urządzeniu
diff --git a/app/src/main/res/values-ru/preferences_values.xml b/app/src/main/res/values-ru/preferences_values.xml
index 6c7a74aea..095a2a975 100644
--- a/app/src/main/res/values-ru/preferences_values.xml
+++ b/app/src/main/res/values-ru/preferences_values.xml
@@ -1,10 +1,10 @@
- Alphabetically
- By date
- By average
- By attendance percentage
- By subject attendance balance
+ По алфавиту
+ По дате
+ По средней
+ Согласно проценту посещаемости
+ Согласно балансу посещаемости уроков
- Светлая
- Тёмная
@@ -19,6 +19,7 @@
- Deutsch
- Čeština
- Slovenčina
+ - Kaszëbsczi
- 15 минут
@@ -52,14 +53,14 @@
- Средняя из оценок со всего года
- - Don\'t show
- - Only between lessons
- - Before and between lessons
+ - Не показывать
+ - Только между уроками
+ - Перед и между уроками
- - Don\'t show
- - Show inline
- - Show below regular lessons
+ - Не показывать
+ - Показать в строке
+ - Показать ниже обычных уроков
- Счастливый номер
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 95400f93d..8f6847c75 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -13,7 +13,7 @@
Просмотр журнала
Отладка
Отладка уведомлений
- Clear webview cookies
+ Очистить файлы cookie
Разработчики
Лицензии
Сообщения
@@ -38,14 +38,14 @@
Логин, PESEL или электронная почта
Пароль
Тип дневника UONET+
- Custom domain suffix
+ Пользовательский суффикс домена
Мобильный API
Scraper
Hybrid
Token
PIN
Symbol
- E.g. \"lodz\" or \"powiatjaroslawski\"
+ Например: \"lodz\" или \"powiatjaroslawski\"
Войти
Пароль слишком короткий
Данные для входа указаны неверно
@@ -56,8 +56,8 @@
Неверный e-mail
Используйте назначенный логин вместо e-mail
Используйте назначенный логин или email в @%1$s
- Invalid domain suffix
- Invalid symbol. If you cannot find it, please contact the school
+ Недопустимый суффикс домена
+ Неверный символ. Если вы не можете найти символ, пожалуйста, свяжитесь со школой
Don\'t make this up! If you cannot find it, please contact the school
Ученик не найден. Проверьте symbol и выбранный тип дненика UONET+
Данный ученик уже авторизован
@@ -73,7 +73,7 @@
Discord
Отправить письмо
Убедитесь, что вы выбрали правильный тип дневника UONET+
- Reset password
+ Сбросить пароль
Восстановите свой аккаунт
Восстановить
Ученик уже авторизован
@@ -81,13 +81,13 @@
Другие места поиска
Не найдено активных учеников
Введите другой symbol
- Get help
- Full school name with the town (required)
- Np. ZSTiO Jarosław lub SP nr 99 w Łodzi
- Enter correct name of the school
- Additional information in Polish (optional)
- Np. \"Ostatnio zmieniłem szkołę i…\" albo \"Jestem rodzicem i nie widzę drugiego dziecka…\"
- Submit
+ Помощь
+ Полное название школы с городом (обязательно)
+ Например: ZSTiO Jarosław или SP nr 99 w Łodzi
+ Введите правильное название школы
+ Дополнительная информация на польском языке (опционально)
+ Например: \"Ostatnio zmieniłem szkołę i…\" или \"Jestem rodzicem i nie widzę drugiego dziecka…\"
+ Отправить
Включить уведомления
Включить уведомления, чтобы вы не пропустили сообщение от учителя или новую оценку
@@ -98,8 +98,8 @@
Войти
Сеанс истёк
Сеанс истёк, авторизуйтесь снова
- Password has expired or been changed
- Your account password has expired or been changed. You will need to log in to Wulkanowy again
+ Срок действия пароля истек или был изменен
+ Пароль вашей учетной записи устарел или был изменен. Вам нужно будет войти в Wulkanowy снова
Поддержка приложения
Вам нравится это приложение? Поддержите его разработку, включив неинвазивную рекламу, которую можно отключить в любое время
Включить рекламу
@@ -113,16 +113,16 @@
Комментарий
Количество новых оценок: %1$d
Средняя оценка: %1$.2f
- Annual: %1$.2f
+ Годовое: %1$.2f
Баллы: %s
Нет средней оценки
- Semester average
- Annual average
+ Средняя семестра
+ Средняя годовой
Сумма баллов
Итоговая оценка
Ожидаемая оценка
- Descriptive grade
- Calculated semester average
+ Описательная оценка
+ Рассчитанная средняя семестра
Calculated annual average
Как работает \"Рассчитанная средняя оценка\"?
Рассчитанная средняя оценка - это среднее арифметическое, рассчитанное на основе средних оценок по предметам. Это позволяет узнать приблизительную итоговую среднюю оценку. Она рассчитывается способом, выбранным пользователем в настройках приложения. Рекомендуется выбрать подходящий вариант, так как каждая школа по разному считает среднюю оценку. Кроме того, если ваша школа выставляет средние оценки по предметам на странице Vulcan, приложение просто загрузит их. Это можно изменить, заставив приложение считать среднюю оценку в настройках.\n\nСредняя из оценок выбранного семестра:\n1. Вычисление средневзвешенного значения по каждому предмету за семестр\n2.Суммирование вычисленных значений\n3. Вычисление среднего арифметического суммированных значений\n\nСредняя из средних оценок семестров:\n1.Расчет средневзвешенного значения для каждого предмета в семестрах. \n2. Вычисление среднего арифметического из средневзвешенных значений для каждого предмета в семестрах.\n3. Суммирование средних арифметических\n4. Вычисление среднего арифматического из суммированных значений\n\nСредняя из оценок со всего года:\n1. Расчет средневзвешенного значения по каждому предмету за год. Итоговое среднее значение за 1 семестр не имеет значения.\n2. Суммирование вычисленных средних\n3. Расчет среднего арифметического суммированных чисел
@@ -167,10 +167,10 @@
- Новые итоговые оценки
- - New descriptive grade
- - New descriptive grades
- - New descriptive grades
- - New descriptive grades
+ - Новая описательная оценка
+ - Новые описательные оценки
+ - Новые описательные оценки
+ - Новые описательные оценки
- Вы получили %1$d новую оценку
@@ -191,14 +191,14 @@
- Вы получили %1$d новых итоговые оценки
- - You received %1$d descriptive grade
- - You received %1$d descriptive grades
- - You received %1$d descriptive grades
- - You received %1$d descriptive grades
+ - Вы получили %1$d новую описательную оценку
+ - Вы получили %1$d новых описательных оценок
+ - Вы получили %1$d новых описательных оценок
+ - Вы получили %1$d новых описательных оценок
Урок
- Additional lesson
+ Дополнительный урок
Аудитория
Группа
Часы
@@ -217,10 +217,10 @@
Учитель изменён с %1$s на %2$s
Тема изменена с %1$s на %2$s
- - No lesson
- - No lessons
- - No lessons
- - No lessons
+ - Нет урока
+ - Нет урока
+ - Нет урока
+ - Нет урока
- Изменение расписания
@@ -270,7 +270,7 @@
Время окончания должно быть больше, чем время начала
Итоговая посещаемость
- Attendance calculator
+ Калькулятор посещаемости
%1$d over target
right on target
%1$d under target
@@ -347,10 +347,10 @@
Переслать
Выбрать все
Отменить выбор
- Restore from trash
+ Восстановить из корзины
Перенести в корзину
Удалить навсегда
- Message restored successfully
+ Сообщение успешно восстановлено
Сообщение успешно удалено
ученик
родитель
@@ -396,10 +396,10 @@
- %1$d выбрано
Сообщение удалено
- Messages restored
+ Сообщения восстановлены
Выбрать почтовый ящик
- Incognito mode is on
- Thanks to incognito mode sender is not notified when you read the message
+ Режим инкогнито включен
+ Благодаря режиму инкогнито отправитель не уведомлен о прочтении сообщения
Нет записей о замечаниях и свершениях
Баллы
@@ -748,8 +748,8 @@
Тема
Разворачивание оценок
Показать группы рядом с темами
- Show additional lessons
- Show empty tiles where there\'s no lesson
+ Показать дополнительные уроки
+ Показать пустые поля, где нет уроков
Показывать диаграммы в оценках класса
Показать предметы без оценок
Цветовая схема оценок
@@ -790,12 +790,12 @@
Стоимость минуса
Отвечать с историей сообщений
Показывать среднее арифметическое при отсутствии стоимости
- Incognito mode
- Do not inform about reading the message
+ Режим инкогнито
+ Не сообщать о чтении сообщения
Поддержка
Политика приватности
Соглашения
- Show consent to data processing
+ Показать согласие на обработку данных
Показать рекламу в приложении
Посмотреть рекламу для поддержки проекта
Согласие на обработку данных
@@ -813,8 +813,8 @@
Главная
Видимость плиток
Посещаемость
- Attendance calculator
- Settings
+ Калькулятор посещаемости
+ Настройки
Расписание
Оценки
Рассчитанная средняя оценка
@@ -866,31 +866,33 @@
Авторизовать
Авторизация прошла успешно
Авторизация
- 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.
+ Уважаемый родитель,<br /><br />для авторизации и обеспечения безопасности данных, просим Вас ввести ниже номер PESEL <b>%1$s</b>. Эти данные необходимы для надлежащего доступа к и защиты личных данных в соответствии с действующими нормами.<br /><br />После ввода данных мы обеспечим проверку, чтобы доступ к системе VULCAN был предоставлен исключительно уполномоченным лицам. Если у Вас возникли какие-либо сомнения или проблемы, пожалуйста, свяжитесь с администратором школьного дневника для уточнения ситуации.<br /><br />Мы соблюдаем наивысшие стандарты защиты персональных данных и гарантируем сохранность всей информации. Приложение Wulkanowy не сохраняет и не обрабатывает номер PESEL.<br /><br />Напоминаем, что предоставление точных данных является обязательным и необходимым для использования системы VULCAN.
Пропустить сейчас
- VULCAN\'s website requires verification
+ Требуется верификация веб-сайта VULCAN
Why am I seeing this?\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
- Verified successfully
+ Верификация успешна
+
+ Emergency access
Интернет-соединение отсутствует
Произошла ошибка. Проверьте время на вашем устройстве
- This account is inactive. Try logging in again
+ Эта учетная запись неактивна. Попробуйте войти снова
Не удалось подключиться к дневнику. Возможно, сервера перегружены, повторите попытку позже
Не удалось загрузить данные, повторите попытку позже
- Your password has expired or been changed. Please log in again
+ Ваш пароль устарел или был изменен. Пожалуйста, войдите снова
Необходимо изменить пароль дневника
UONET+ проводит техническое обслуживание, повторите попытку позже
Неизвестная ошибка дневника UONET+, повторите попытку позже
Неизвестная ошибка приложения, повторите попытку позже
- Captcha verification required
+ Требуется подтверждение капчи
Произошла непредвиденная ошибка
Функция отключена вашей школой
Функция недоступна в режиме Mobile API. Воспользуйтесь другим режимом
Это поле обязательно
- Mute
- Unmute
- You have muted this user
- You have unmuted this user
+ Отключить уведомления
+ Включить уведомления
+ Вы отключили уведомления от этого пользователя
+ Вы включили уведомления от этого пользователя снова
diff --git a/app/src/main/res/values-sk/preferences_values.xml b/app/src/main/res/values-sk/preferences_values.xml
index b06f2b3fa..af34eebcc 100644
--- a/app/src/main/res/values-sk/preferences_values.xml
+++ b/app/src/main/res/values-sk/preferences_values.xml
@@ -19,6 +19,7 @@
- Deutsch
- Čeština
- Slovenčina
+ - Kaszëbsczi
- 15 minút
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 981213842..519670f6c 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -29,7 +29,7 @@
Centrum oznámení
Konfigurácia menu
- Semester %1$d, %2$d/%3$d
+ Polrok %1$d, %2$d/%3$d
Prihláste sa pomocou žiackeho alebo rodičovského účtu
Zadajte symbol zo stránky denníka: <b>%1$s</b>
@@ -105,8 +105,8 @@
Zapnúť reklamy
Známka
- Semester %d
- Zmeniť semester
+ Polrok %d
+ Zmeniť polrok
Žiadne známky
Váha
Váha: %s
@@ -125,16 +125,16 @@
Vypočítaný polročný priemer
Vypočítaný ročný priemer
Ako funguje vypočítaný priemer?
- 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\nPriemer známok iba z vybraného semestra:\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\nPriemer priemerov z oboch semestrov:\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\nPriemer známok z celého roka:\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
+ 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 nastavení aplikácii. Odporúča sa vybrať príslušnú možnosť. Dôvodom je rozdielny výpočet školských priemerov. Pokiaľ 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 je možné zmeniť vynútením výpočtu priemeru v nastavení aplikácie.\n\nPriemer známok iba z vybraného polroka:\n1. Výpočet váženého priemeru pre každý predmet v danom polroku\n2. Sčítanie vypočítaných priemerov\n3. Výpočet aritmetického priemeru sčítaných priemerov\n\nPriemer priemerov z oboch polrokov:\n1. Výpočet váženého priemeru pre každý predmet v polroku 1 a 2\n2. Výpočet aritmetického priemeru vypočítaných priemerov za polrok 1 a 2 pre každý predmet.\n3. Sčítanie vypočítaných priemerov\n4. Výpočet aritmetického priemeru sčítaných priemerov\n\nPriemer známok z celého roka:\n1. Výpočet váženého priemeru za rok pre každý predmet. Konečný priemer v 1. polroku je nepodstatný.\n2. Sčítanie vypočítaných priemerov\n3. Výpočet aritmetického priemeru sčítaných priemerov
Ako funguje konečný priemer?
- Konečný priemer je aritmetický priemer vypočítaný zo všetkých aktuálne dostupných konečných známok v danom semestri.\n\nSchéma výpočtu sa skladá z nasledujúcich krokov:\n1. Sčítanie konečných známok zadaných učiteľmi\n2. Delené počtom predmetov, pre ktoré už boli vydané známky
+ Konečný priemer je aritmetický priemer vypočítaný zo všetkých aktuálne dostupných konečných známok v danom polroku.\n\nSchéma výpočtu sa skladá z nasledujúcich krokov:\n1. Sčítanie konečných známok zadaných učiteľmi\n2. Delené počtom predmetov, pre ktoré už boli udelené známky
Konečný priemer
z %1$d z %2$d predmetov
Zhrnutie
Trieda
Označiť ako prečítané
Čiastočné
- Semester
+ Polrok
Body
Vysvetlivky
Priemer triedy: %1$s
@@ -499,7 +499,7 @@
Mobilný prístup
Žiadne zariadenia
Zrušiť registráciu
- Zariadenie odstránenie
+ Zariadenie odstránené
QR kód
Token
Symbol
@@ -872,6 +872,8 @@
Webová stránka denníka VULCAN vyžaduje overenie
Prečo sa mi to zobrazuje?\nWebová stránka denníka, z ktorej Wulkanowy sťahuje dáta, zobrazuje rovnakú obrazovku ako vyššie, takže Wulkanowy ju musí tiež zobraziť, aby bolo možné získavať dáta z tejto stránky. Nedá sa to obísť
Úspešne overené
+
+ Núdzový prístup
Žiadne internetové pripojenie
Vyskytla sa chyba. Skontrolujte hodiny svojho zariadenia
diff --git a/app/src/main/res/values-uk/preferences_values.xml b/app/src/main/res/values-uk/preferences_values.xml
index 72abe1f70..4b090f095 100644
--- a/app/src/main/res/values-uk/preferences_values.xml
+++ b/app/src/main/res/values-uk/preferences_values.xml
@@ -19,6 +19,7 @@
- Deutsch
- Čeština
- Slovenčina
+ - Kaszëbsczi
- 15 хвилин
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 2ce0a2d9f..c6f6f0462 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -872,6 +872,8 @@
Веб-сайт VULCAN потребує підтвердження
Чому я це бачу?\nСайт реєстру, з якого Wulkanowy завантажує дані, відображає той самий екран, що й вище, тому Wulkanowy також повинен показувати його, щоб мати змогу завантажувати дані з цього сайту. Це неможливо обійти
Верифікація завершена
+
+ Екстрений доступ
Немає з\'єднання з інтернетом
Сталася помилка. Перевірте годинник пристрою
diff --git a/app/src/main/res/values/preferences_values.xml b/app/src/main/res/values/preferences_values.xml
index e5020b533..fc9a4eeb4 100644
--- a/app/src/main/res/values/preferences_values.xml
+++ b/app/src/main/res/values/preferences_values.xml
@@ -40,6 +40,7 @@
- Deutsch
- Čeština
- Slovenčina
+ - Kaszëbsczi
- system
@@ -50,6 +51,7 @@
- de
- cs
- sk
+ - csb
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ed4f438c6..82ccf5a2a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -28,7 +28,7 @@
Student info
Dashboard
Notifications center
- Menu configuartion
+ Menu configuration
@@ -869,6 +869,9 @@
Why am I seeing this?\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
Verified successfully
+
+ Emergency access
+
No internet connection
diff --git a/app/src/test/java/io/github/wulkanowy/WulkanowySdkFactoryCreator.kt b/app/src/test/java/io/github/wulkanowy/WulkanowySdkFactoryCreator.kt
index 9623c9f98..4a8ff6566 100644
--- a/app/src/test/java/io/github/wulkanowy/WulkanowySdkFactoryCreator.kt
+++ b/app/src/test/java/io/github/wulkanowy/WulkanowySdkFactoryCreator.kt
@@ -8,6 +8,7 @@ import io.mockk.mockk
fun createWulkanowySdkFactoryMock(sdk: Sdk) = mockk()
.apply {
- every { create() } returns sdk
+ every { createBase() } returns sdk
+ coEvery { create() } returns sdk
coEvery { create(any(), any()) } returns sdk
}
diff --git a/app/src/test/java/io/github/wulkanowy/data/WulkanowySdkFactoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/WulkanowySdkFactoryTest.kt
index bedeffe74..939804295 100644
--- a/app/src/test/java/io/github/wulkanowy/data/WulkanowySdkFactoryTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/WulkanowySdkFactoryTest.kt
@@ -11,7 +11,6 @@ import io.github.wulkanowy.sdk.pojo.RegisterStudent
import io.mockk.Runs
import io.mockk.coEvery
import io.mockk.coVerify
-import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.spyk
@@ -40,11 +39,13 @@ class WulkanowySdkFactoryTest {
chuckerInterceptor = mockk(),
remoteConfig = mockk(relaxed = true),
webkitCookieManagerProxy = mockk(),
- studentDb = studentDao
+ studentDb = studentDao,
+ wulkanowyRepository = mockk(relaxed = true),
+ context = mockk(),
)
)
- every { wulkanowySdkFactory.create() } returns sdk
+ coEvery { wulkanowySdkFactory.create() } returns sdk
}
@Test
diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt
index 3e95774dd..afb60305e 100644
--- a/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/ui/modules/main/MainPresenterTest.kt
@@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.main
import io.github.wulkanowy.MainCoroutineRule
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.StudentRepository
+import io.github.wulkanowy.data.repositories.WulkanowyRepository
import io.github.wulkanowy.services.sync.SyncManager
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.AdsHelper
@@ -31,6 +32,9 @@ class MainPresenterTest {
@MockK
lateinit var studentRepository: StudentRepository
+ @MockK(relaxed = true)
+ lateinit var wulkanowyRepository: WulkanowyRepository
+
@MockK(relaxed = true)
lateinit var prefRepository: PreferencesRepository
@@ -65,7 +69,8 @@ class MainPresenterTest {
analytics = analytics,
json = Json,
appInfo = appInfo,
- adsHelper = adsHelper
+ adsHelper = adsHelper,
+ wulkanowyRepository = wulkanowyRepository
)
presenter.onAttachView(mainView, null)
}
diff --git a/build.gradle b/build.gradle
index 100c0eb9e..6c4bc5c08 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
buildscript {
ext {
- kotlin_version = '1.9.23'
- about_libraries = '11.1.3'
+ kotlin_version = '1.9.24'
+ about_libraries = '11.1.4'
hilt_version = '2.51.1'
}
repositories {
@@ -13,12 +13,12 @@ buildscript {
dependencies {
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.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:$kotlin_version-1.0.20"
+ classpath 'com.android.tools.build:gradle:8.4.1'
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
- classpath 'com.google.gms:google-services:4.4.1'
+ classpath 'com.google.gms:google-services:4.4.2'
classpath 'com.huawei.agconnect:agcp:1.9.1.303'
- classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.1'
classpath "com.github.triplet.gradle:play-publisher:3.8.4"
classpath "ru.cian:huawei-publish-gradle-plugin:1.4.2"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:5.0.0.4638"