Compare commits

...

53 Commits

Author SHA1 Message Date
a0a589240a Bump androidx.lifecycle:lifecycle-livedata-ktx from 2.8.0 to 2.8.2
Bumps androidx.lifecycle:lifecycle-livedata-ktx from 2.8.0 to 2.8.2.

---
updated-dependencies:
- dependency-name: androidx.lifecycle:lifecycle-livedata-ktx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-17 13:43:01 +00:00
da48285764 Merge branch 'release/2.7.0' into develop 2024-06-12 22:22:32 +02:00
f5aadb9cc8 Version 2.7.0 2024-06-12 22:22:22 +02:00
6ac30c5a03 New Crowdin updates (#2593) 2024-06-12 21:36:13 +02:00
3e106d5af0 Add end (#2574) 2024-06-11 20:37:31 +02:00
fc549309d8 Merge branch 'release/2.6.16' into develop 2024-06-10 19:05:08 +02:00
77155a74d3 Version 2.6.16 2024-06-10 19:03:55 +02:00
d0ad5028d8 Add Kashubian language (#2579) 2024-05-31 10:14:48 +02:00
7f6a2435d0 New Crowdin updates (#2578)
* New translations strings.xml (Kashubian)
2024-05-31 10:02:38 +02:00
3a07ec7755 Revert "Bump com.google.android.gms:play-services-ads from 22.6.0 to 23.1.0 (…" (#2580)
This reverts commit c6eea8b84d.
2024-05-31 09:47:32 +02:00
3f9e1fd08d Merge branch 'release/2.6.15' into develop 2024-05-30 17:58:43 +02:00
246d01ca26 Version 2.6.15 2024-05-30 17:58:32 +02:00
09aea4c484 Bump sdk to 2.6.13-SNAPSHOT 2024-05-30 15:56:00 +02:00
947bd6ba85 New Crowdin updates (#2570) 2024-05-30 00:55:45 +02:00
f2232558a3 Merge branch 'release/2.6.14' into develop 2024-05-29 17:38:59 +02:00
2ae451ac4f Version 2.6.14 2024-05-29 17:38:34 +02:00
85d3a6e8a7 Bump sdk to 2.6.12-SNAPSHOT 2024-05-29 16:33:49 +02:00
47041c5fcb Bump com.android.tools.build:gradle from 8.4.0 to 8.4.1 (#2573) 2024-05-25 15:28:26 +00:00
eed0a3b6f1 Bump androidx.annotation:annotation from 1.7.1 to 1.8.0 (#2563) 2024-05-25 13:49:33 +00:00
c6eea8b84d Bump com.google.android.gms:play-services-ads from 22.6.0 to 23.1.0 (#2556) 2024-05-25 13:44:02 +00:00
b02865e963 Bump androidx.lifecycle:lifecycle-livedata-ktx from 2.7.0 to 2.8.0 (#2561) 2024-05-25 13:43:47 +00:00
20be52a60a Bump com.google.firebase:firebase-crashlytics-gradle from 2.9.9 to 3.0.1 (#2562) 2024-05-25 13:43:33 +00:00
0ffc661b4f Bump androidx.viewpager2:viewpager2 from 1.1.0-rc01 to 1.1.0 (#2564) 2024-05-25 13:43:04 +00:00
2a0e8497db Bump org.robolectric:robolectric from 4.12.1 to 4.12.2 (#2565) 2024-05-25 13:42:41 +00:00
e8643bc8ba Bump mockk from 1.13.10 to 1.13.11 (#2566) 2024-05-25 13:42:19 +00:00
b3b4603e89 Bump androidx.fragment:fragment-ktx from 1.7.0 to 1.7.1 (#2567) 2024-05-25 13:41:54 +00:00
528a947ffd Merge branch 'release/2.6.13' into develop 2024-05-23 23:26:24 +02:00
ca9caeca66 Version 2.6.13 2024-05-23 23:26:06 +02:00
e971eb7821 Add full panic mode (#2569) 2024-05-23 23:15:47 +02:00
c7afa262d9 Merge branch 'release/2.6.12' into develop 2024-05-23 07:55:17 +02:00
b622c09e56 Version 2.6.12 2024-05-23 07:55:02 +02:00
87fb1916d8 Add panic button 2024-05-23 07:37:49 +02:00
5ca9ac3978 Version 2.6.11 2024-05-22 22:05:11 +02:00
c76ace40eb Fix mapping refresh key 2024-05-22 21:05:17 +02:00
4a585fc56e Fix mapping refresh key 2024-05-22 21:00:09 +02:00
f3afe7fdb7 Bump sdk to 2.6.10-SNAPSHOT 2024-05-22 20:31:40 +02:00
859c6ef154 Add auto refresh to wulkanowy repo 2024-05-22 20:23:57 +02:00
24abe47332 Version 2.6.10 2024-05-22 19:26:01 +02:00
52c1878f6b Bump sdk to 2.6.9-SNAPSHOT 2024-05-22 19:26:01 +02:00
4060240368 New Crowdin updates (#2551) 2024-05-17 22:22:43 +02:00
f69816fbac Bump coroutines from 1.8.0 to 1.8.1 (#2560) 2024-05-17 20:21:52 +00:00
1a41e9e3ee Merge branch 'release/2.6.9' into develop 2024-05-17 21:23:40 +02:00
1c0df6c145 Version 2.6.9 2024-05-17 21:23:29 +02:00
2b61e883c5 Bump sdk to 2.6.8-SNAPSHOT 2024-05-17 19:45:53 +02:00
31a7ae6d15 Fix tests 2024-05-17 08:04:28 +02:00
4b3b4a21fa Merge branch 'release/2.6.8' into develop 2024-05-17 07:39:16 +02:00
9a6b17c9d9 Version 2.6.8 2024-05-17 07:38:13 +02:00
729e0f547b Add sandbox isolate 2024-05-16 23:23:06 +02:00
faa8d34e79 Bump sdk to 2.6.7-SNAPSHOT 2024-05-16 18:55:02 +02:00
b6f5ac91ad Merge branch 'release/2.6.7' into develop 2024-05-16 08:50:37 +02:00
d1d0caa1e3 Version 2.6.7 2024-05-16 08:50:28 +02:00
c40779f48f Merge branch 'release/2.6.6' into develop 2024-05-14 22:31:01 +02:00
594d2dbec5 Version 2.6.6 2024-05-14 22:30:51 +02:00
59 changed files with 1762 additions and 208 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -27,8 +27,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
targetSdkVersion 34
versionCode 165
versionName "2.6.5"
versionCode 177
versionName "2.7.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy"
@ -161,7 +161,7 @@ play {
track = 'production'
releaseStatus = ReleaseStatus.IN_PROGRESS
userFraction = 0.99d
updatePriority = 3
updatePriority = 2
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.4'
implementation 'io.github.wulkanowy:sdk:2.7.0'
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.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.7.0"
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-rc01"
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.2"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
@ -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"

View File

@ -3,6 +3,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="internalOnly">
<uses-sdk tools:overrideLibrary="androidx.javascriptengine" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
@ -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">
<activity
android:name=".ui.modules.splash.SplashActivity"

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.data
import io.github.wulkanowy.data.repositories.isEndDateReached
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
@ -267,7 +268,8 @@ inline fun <DatabaseType, ApiType, OutputType> networkBoundResource(
emit(Resource.Loading())
val data = query().first()
if (shouldFetch(data)) {
val updatedShouldFetch = if (isEndDateReached) false else shouldFetch(data)
if (updatedShouldFetch) {
emit(Resource.Intermediate(data))
try {

View File

@ -1,14 +1,21 @@
package io.github.wulkanowy.data
import android.content.Context
import android.os.Build
import androidx.javascriptengine.JavaScriptSandbox
import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.google.common.util.concurrent.ListenableFuture
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentIsEduOne
import io.github.wulkanowy.data.repositories.WulkanowyRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.scrapper.EvaluateHandler
import io.github.wulkanowy.utils.RemoteConfigHelper
import io.github.wulkanowy.utils.WebkitCookieManagerProxy
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import timber.log.Timber
@ -17,6 +24,7 @@ import javax.inject.Singleton
@Singleton
class WulkanowySdkFactory @Inject constructor(
@ApplicationContext private val context: Context,
private val chuckerInterceptor: ChuckerInterceptor,
private val remoteConfig: RemoteConfigHelper,
private val webkitCookieManagerProxy: WebkitCookieManagerProxy,
@ -26,10 +34,16 @@ class WulkanowySdkFactory @Inject constructor(
private val eduOneMutex = Mutex()
private val migrationFailedStudentIds = mutableSetOf<Long>()
private val sandbox: ListenableFuture<JavaScriptSandbox>? =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && JavaScriptSandbox.isSupported())
runCatching { JavaScriptSandbox.createConnectedInstanceAsync(context) }
.onFailure { Timber.e(it) }
.getOrNull()
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)
@ -47,6 +61,24 @@ class WulkanowySdkFactory @Inject constructor(
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()
}
}
}
}

View File

@ -11,4 +11,13 @@ data class Mapping(
@SerialName("vTokens")
val vTokens: Map<String, Map<String, Map<String, String>>>,
@SerialName("vTokenScheme")
val vTokenScheme: Map<String, Map<String, String>> = emptyMap(),
@SerialName("vHeaders")
val vHeaders: Map<String, Map<String, Map<String, String>>> = emptyMap(),
@SerialName("responseMap")
val responseMap: Map<String, Map<String, Map<String, Map<String, String>>>> = emptyMap(),
)

View File

@ -11,6 +11,6 @@ interface WulkanowyService {
@GET("/v1.json")
suspend fun getAdminMessages(): List<AdminMessage>
@GET("/mapping1.json")
@GET("/mapping4.json")
suspend fun getMapping(): Mapping
}

View File

@ -6,21 +6,29 @@ 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 java.time.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
private val endDate = LocalDate.of(2024, 6, 25)
val isEndDateReached = LocalDate.now() >= endDate
@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<Resource<List<AdminMessage>>> =
networkBoundResource(
@ -38,7 +46,11 @@ class WulkanowyRepository @Inject constructor(
suspend fun getMapping(): Mapping? {
var savedMapping = preferencesRepository.mapping
if (savedMapping == null) {
val isExpired = refreshHelper.shouldBeRefreshed(
key = getRefreshKey(cacheKey)
)
if (savedMapping == null || isExpired) {
fetchMapping()
savedMapping = preferencesRepository.mapping
}
@ -49,6 +61,9 @@ class WulkanowyRepository @Inject constructor(
suspend fun fetchMapping() {
runCatching { wulkanowyService.getMapping() }
.onFailure { Timber.e(it) }
.onSuccess { preferencesRepository.mapping = it }
.onSuccess {
preferencesRepository.mapping = it
refreshHelper.updateLastRefreshTimestamp(cacheKey)
}
}
}

View File

@ -4,19 +4,27 @@ import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.O
import androidx.core.app.NotificationManagerCompat
import androidx.lifecycle.asFlow
import androidx.work.*
import androidx.work.BackoffPolicy.EXPONENTIAL
import androidx.work.Constraints
import androidx.work.Data
import androidx.work.ExistingPeriodicWorkPolicy.KEEP
import androidx.work.ExistingPeriodicWorkPolicy.UPDATE
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType.CONNECTED
import androidx.work.NetworkType.UNMETERED
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkInfo
import androidx.work.WorkManager
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.isEndDateReached
import io.github.wulkanowy.services.sync.channels.Channel
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.isHolidays
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import timber.log.Timber
import java.time.LocalDate.now
import java.util.concurrent.TimeUnit.MINUTES
@ -34,7 +42,9 @@ class SyncManager @Inject constructor(
) {
init {
if (now().isHolidays) stopSyncWorker()
if (now().isHolidays || isEndDateReached) {
stopSyncWorker()
}
if (SDK_INT >= O) {
channels.forEach { it.create() }
@ -50,7 +60,7 @@ class SyncManager @Inject constructor(
}
fun startPeriodicSyncWorker(restart: Boolean = false) {
if (preferencesRepository.isServiceEnabled && !now().isHolidays) {
if (preferencesRepository.isServiceEnabled && !now().isHolidays && isEndDateReached) {
val serviceInterval = preferencesRepository.servicesInterval
workManager.enqueueUniquePeriodicWork(
@ -70,6 +80,10 @@ class SyncManager @Inject constructor(
// if quiet, no notifications will be sent
fun startOneTimeSyncWorker(quiet: Boolean = false): Flow<WorkInfo?> {
if (isEndDateReached) {
return flowOf(null)
}
val work = OneTimeWorkRequestBuilder<SyncWorker>()
.setInputData(
Data.Builder()

View File

@ -15,6 +15,7 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.SemesterRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.repositories.isEndDateReached
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.scrapper.exception.FeatureUnavailableException
@ -42,7 +43,9 @@ class SyncWorker @AssistedInject constructor(
override suspend fun doWork(): Result = withContext(dispatchersProvider.io) {
Timber.i("SyncWorker is starting")
if (!studentRepository.isCurrentStudentSet()) return@withContext Result.failure()
if (!studentRepository.isCurrentStudentSet() || isEndDateReached) {
return@withContext Result.failure()
}
val (student, semester) = try {
val student = studentRepository.getCurrentStudent()
@ -91,6 +94,7 @@ class SyncWorker @AssistedInject constructor(
.build()
)
}
errors.isNotEmpty() -> Result.retry()
else -> {
preferencesRepository.lasSyncDate = Instant.now()

View File

@ -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<FragmentDashboardBinding>(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<FragmentDashboardBinding>(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<FragmentDashboardBinding>(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()

View File

@ -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

View File

@ -31,4 +31,6 @@ interface DashboardView : BaseView {
fun openNotificationsCenterView()
fun openInternetBrowser(url: String)
fun openPanicWebView(url: String)
}

View File

@ -59,6 +59,8 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
var onAdminMessageClickListener: (String?) -> Unit = {}
var onPanicButtonClickListener: () -> Unit = {}
var onAdminMessageDismissClickListener: (AdminMessage) -> Unit = {}
val items = mutableListOf<DashboardItem>()
@ -86,35 +88,46 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
DashboardItem.Type.ACCOUNT.ordinal -> 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<RecyclerView
is AnnouncementsViewHolder -> 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<RecyclerView
attendancePercentage == null || attendancePercentage == .0 -> {
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<RecyclerView
binding.dashboardLessonsItemTitleTomorrow.isVisible = false
binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false
}
tomorrowTimetable.isNotEmpty() -> {
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<RecyclerView
firstTitleText =
context.getString(R.string.dashboard_timetable_first_lesson_title_moment)
}
minutesToStartLesson < 240 -> {
firstTitleAndValueTextColor =
context.getThemeAttrColor(R.attr.colorOnSurface)
@ -468,6 +493,7 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
firstTitleText =
context.getString(R.string.dashboard_timetable_first_lesson_title_soon)
}
else -> {
firstTitleAndValueTextColor =
context.getThemeAttrColor(R.attr.colorOnSurface)

View File

@ -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) }
}
}
}

View File

@ -0,0 +1,31 @@
package io.github.wulkanowy.ui.modules.end
import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.view.View
import androidx.activity.addCallback
import androidx.core.text.HtmlCompat
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.FragmentEndBinding
import io.github.wulkanowy.ui.base.BaseFragment
@AndroidEntryPoint
class EndFragment : BaseFragment<FragmentEndBinding>(R.layout.fragment_end), EndView {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentEndBinding.bind(view)
requireActivity().onBackPressedDispatcher.addCallback {
requireActivity().finishAffinity()
}
binding.endClose.setOnClickListener { requireActivity().finishAffinity() }
val message = getString(R.string.end_message)
binding.endDescription.movementMethod = LinkMovementMethod.getInstance()
binding.endDescription.text =
HtmlCompat.fromHtml(message, HtmlCompat.FROM_HTML_MODE_COMPACT)
}
}

View File

@ -0,0 +1,5 @@
package io.github.wulkanowy.ui.modules.end
import io.github.wulkanowy.ui.base.BaseView
interface EndView : BaseView

View File

@ -15,6 +15,7 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.databinding.ActivityLoginBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.end.EndFragment
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
@ -115,9 +116,14 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
}
}
override fun navigateToEnd() {
openFragment(EndFragment(), clearBackStack = true)
}
override fun onResume() {
super.onResume()
inAppUpdateHelper.onResume()
presenter.updateSdkMappings()
presenter.checkIfEnd()
}
}

View File

@ -2,6 +2,8 @@ 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.data.repositories.isEndDateReached
import io.github.wulkanowy.services.sync.SyncManager
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import kotlinx.coroutines.launch
@ -11,7 +13,8 @@ import javax.inject.Inject
class LoginPresenter @Inject constructor(
private val wulkanowyRepository: WulkanowyRepository,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
studentRepository: StudentRepository,
private val syncManager: SyncManager
) : BasePresenter<LoginView>(errorHandler, studentRepository) {
override fun onAttachView(view: LoginView) {
@ -26,4 +29,11 @@ class LoginPresenter @Inject constructor(
.onFailure { Timber.e(it) }
}
}
fun checkIfEnd() {
if (isEndDateReached) {
syncManager.stopSyncWorker()
view?.navigateToEnd()
}
}
}

View File

@ -5,4 +5,6 @@ import io.github.wulkanowy.ui.base.BaseView
interface LoginView : BaseView {
fun initView()
fun navigateToEnd()
}

View File

@ -238,6 +238,7 @@ class LoginFormFragment : BaseFragment<FragmentLoginFormBinding>(R.layout.fragme
binding = binding.loginFormMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
onPanicButtonClickListener = {},
).bind(message)
binding.loginFormMessage.root.isVisible = message != null
}

View File

@ -118,6 +118,7 @@ class LoginStudentSelectFragment :
binding = binding.loginStudentSelectAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
onPanicButtonClickListener = {},
).bind(adminMessage)
binding.loginStudentSelectAdminMessage.root.isVisible = adminMessage != null
}

View File

@ -188,6 +188,7 @@ class LoginSymbolFragment :
binding = binding.loginSymbolAdminMessage,
onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed,
onAdminMessageClickListener = presenter::onAdminMessageSelected,
onPanicButtonClickListener = {},
).bind(adminMessage)
binding.loginSymbolAdminMessage.root.isVisible = adminMessage != null
}

View File

@ -14,7 +14,9 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.dataOrThrow
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.repositories.isEndDateReached
import io.github.wulkanowy.data.toFirstResult
import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.ui.modules.splash.SplashActivity
@ -35,6 +37,9 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
@Inject
lateinit var sharedPref: SharedPrefProvider
@Inject
lateinit var preferencesRepository: PreferencesRepository
companion object {
private const val LUCKY_NUMBER_WIDGET_MAX_SIZE = 196
@ -130,6 +135,10 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
}
private fun getLuckyNumber(studentId: Long, appWidgetId: Int) = runBlocking {
if (isEndDateReached) {
return@runBlocking null
}
try {
val students = studentRepository.getSavedStudents()
val student = students.singleOrNull { it.student.id == studentId }?.student

View File

@ -33,6 +33,7 @@ import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog
import io.github.wulkanowy.ui.modules.auth.AuthDialog
import io.github.wulkanowy.ui.modules.captcha.CaptchaDialog
import io.github.wulkanowy.ui.modules.end.EndFragment
import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem
import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.AppInfo
@ -139,6 +140,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
super.onResume()
inAppUpdateHelper.onResume()
presenter.updateSdkMappings()
presenter.checkIfEnd()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@ -362,4 +364,10 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
super.onSaveInstanceState(outState)
navController.onSaveInstanceState(outState)
}
override fun navigateToEnd() {
binding.mainToolbar.isVisible = false
pushView(EndFragment())
onBackCallback?.isEnabled = false
}
}

View File

@ -7,6 +7,7 @@ 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.repositories.isEndDateReached
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.services.sync.SyncManager
import io.github.wulkanowy.ui.base.BasePresenter
@ -15,6 +16,7 @@ import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.ui.modules.account.AccountView
import io.github.wulkanowy.ui.modules.account.accountdetails.AccountDetailsView
import io.github.wulkanowy.ui.modules.end.EndView
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
import io.github.wulkanowy.utils.AdsHelper
import io.github.wulkanowy.utils.AnalyticsHelper
@ -110,6 +112,7 @@ class MainPresenter @Inject constructor(
}
private fun shouldShowBottomNavigation(destination: BaseView) = when (destination) {
is EndView,
is AccountView,
is StudentInfoView,
is AccountDetailsView -> false
@ -208,4 +211,11 @@ class MainPresenter @Inject constructor(
.onFailure { Timber.e(it) }
}
}
fun checkIfEnd() {
if (isEndDateReached) {
syncManager.stopSyncWorker()
view?.navigateToEnd()
}
}
}

View File

@ -48,6 +48,8 @@ interface MainView : BaseView {
fun openMoreDestination(destination: Destination)
fun navigateToEnd()
interface MainChildView {
fun onFragmentReselected()

View File

@ -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<FragmentMessageTabBinding>(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<FragmentMessageTabBinding>(R.layout.frag
)
}
override fun openPanicWebView(url: String) {
(requireActivity() as MainActivity).pushView(PanicModeFragment.newInstance(url))
}
override fun hideKeyboard() {
activity?.hideSoftInput()
}

View File

@ -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")
}
}

View File

@ -50,4 +50,6 @@ interface MessageTabView : BaseView {
fun showRecyclerBottomPadding(show: Boolean)
fun showMailboxChooser(mailboxes: List<Mailbox>)
fun openPanicWebView(url: String)
}

View File

@ -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<FragmentPanicModeBinding>(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()
}
}

View File

@ -22,6 +22,7 @@ import io.github.wulkanowy.data.repositories.PreferencesRepository
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.repositories.isEndDateReached
import io.github.wulkanowy.data.toFirstResult
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getDateWidgetKey
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey
@ -71,6 +72,8 @@ class TimetableWidgetFactory(
items = emptyList()
if (isEndDateReached) return
runBlocking {
runCatching {
val student = getStudent(studentId) ?: return@runBlocking

View File

@ -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

View File

@ -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)

View File

@ -1,5 +1,7 @@
Wersja 2.6.5
Wersja 2.7.0
— naprawiliśmy pozostałe bieżące problemy spowodowane ostatnimi blokadami Wulkanowego przez wiadomo kogo
— naprawiliśmy ustawienia wyglądu po zmianie na język kaszubski
— dodaliśmy ekran końca
- naprawiliśmy ładowanie ocen z modułu Uczeń Plus
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/endIcon"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginTop="32dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintBottom_toTopOf="@id/endText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/endText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="16dp"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:text="@string/end_title"
android:textSize="28sp"
app:layout_constraintBottom_toTopOf="@id/endDescription"
app:layout_constraintTop_toBottomOf="@id/endIcon" />
<TextView
android:id="@+id/endDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@id/endClose"
app:layout_constraintTop_toBottomOf="@id/endText"
tools:maxLines="15"
tools:text="@string/end_message" />
<com.google.android.material.button.MaterialButton
android:id="@+id/endClose"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="48dp"
android:layout_marginBottom="32dp"
android:text="ZAMKNIJ APLIKACJĘ"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/endDescription"
app:layout_constraintVertical_bias="0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@ -60,6 +60,16 @@
tools:ignore="UseCompoundDrawables"
tools:visibility="invisible">
<include
android:id="@+id/message_tab_panic_section"
layout="@layout/item_dashboard_panic_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="16dp"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="@id/dashboard_error_admin_message" />
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"

View File

@ -0,0 +1,69 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.modules.panicmode.PanicModeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorControlHighlight">
<com.google.android.material.button.MaterialButton
android:id="@+id/panic_mode_share"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
app:icon="@drawable/ic_share"
app:iconTint="?colorOnSurface" />
<com.google.android.material.button.MaterialButton
android:id="@+id/panic_mode_home"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
app:icon="@drawable/ic_all_home"
app:iconTint="?colorOnSurface" />
<com.google.android.material.button.MaterialButton
android:id="@+id/panic_mode_refresh"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:contentDescription="@string/logviewer_refresh"
app:icon="@drawable/ic_refresh"
app:iconTint="?colorOnSurface" />
<com.google.android.material.button.MaterialButton
android:id="@+id/panic_mode_back"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
app:icon="@drawable/ic_chevron_left"
app:iconTint="?colorOnSurface" />
<com.google.android.material.button.MaterialButton
android:id="@+id/panic_mode_forward"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
app:icon="@drawable/ic_chevron_right"
app:iconTint="?colorOnSurface" />
</LinearLayout>
<WebView
android:id="@+id/panic_mode_webview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>

View File

@ -1,87 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="6dp">
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/dashboard_admin_message_item_content"
<com.google.android.material.card.MaterialCardView
android:id="@+id/dashboard_admin_message"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="6dp">
<ImageView
android:id="@+id/dashboard_admin_message_item_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:src="@drawable/ic_error"
app:layout_constraintBottom_toBottomOf="@id/dashboard_admin_message_item_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/dashboard_admin_message_item_title"
tools:ignore="ContentDescription"
tools:tint="@android:color/black" />
<TextView
android:id="@+id/dashboard_admin_message_item_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/dashboard_admin_message_item_close"
app:layout_constraintStart_toEndOf="@id/dashboard_admin_message_item_icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/dashboard_admin_message_item_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/dashboard_admin_message_item_close"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:padding="12dp"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/dashboard_admin_message_item_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:src="@drawable/ic_error"
app:layout_constraintBottom_toBottomOf="@id/dashboard_admin_message_item_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/dashboard_admin_message_item_title"
tools:ignore="ContentDescription"
tools:tint="@android:color/black" />
<TextView
android:id="@+id/dashboard_admin_message_item_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_title"
app:layout_constraintVertical_bias="0"
app:lineHeight="20dp"
tools:maxLines="5"
tools:text="@tools:sample/lorem/random" />
<TextView
android:id="@+id/dashboard_admin_message_item_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/dashboard_admin_message_item_close"
app:layout_constraintStart_toEndOf="@id/dashboard_admin_message_item_icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<com.google.android.material.button.MaterialButton
android:id="@+id/dashboard_admin_message_item_dismiss"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:text="@android:string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_description"
app:layout_constraintVertical_bias="0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<ImageView
android:id="@+id/dashboard_admin_message_item_close"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:background="?selectableItemBackgroundBorderless"
android:padding="12dp"
android:src="@drawable/ic_close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/dashboard_admin_message_item_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_title"
app:layout_constraintVertical_bias="0"
app:lineHeight="20dp"
tools:maxLines="5"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.button.MaterialButton
android:id="@+id/dashboard_admin_message_item_dismiss"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:text="@android:string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/dashboard_admin_message_item_description"
app:layout_constraintVertical_bias="0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<include
android:id="@+id/dashboard_panic_section"
layout="@layout/item_dashboard_panic_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="16dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/dashboard_error_admin_message" />
</LinearLayout>

View File

@ -0,0 +1,28 @@
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="6dp">
<LinearLayout
android:layout_margin="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Aplikacja nie działa?"
android:textSize="18sp"
android:textStyle="bold" />
<com.google.android.material.button.MaterialButton
android:id="@+id/dashboard_panic_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Otwórz stronę dziennika" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -19,6 +19,7 @@
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 minut</item>

View File

@ -29,7 +29,7 @@
<string name="notifications_center_title">Centrum oznámení</string>
<string name="menu_order_title">Konfigurace menu</string>
<!--Subtitles-->
<string name="grade_subtitle">Semestr %1$d, %2$d/%3$d</string>
<string name="grade_subtitle">Pololetí %1$d, %2$d/%3$d</string>
<!--Login-->
<string name="login_header_default">Přihlaste se pomocí žákovského nebo rodičovského účtu</string>
<string name="login_header_symbol">Zadejte symbol ze stránky deníku: &lt;b&gt;%1$s&lt;/b&gt;</string>
@ -105,8 +105,8 @@
<string name="main_support_positive">Zapnout reklamy</string>
<!--Grade-->
<string name="grade_header">Známka</string>
<string name="grade_semester">Semestr %d</string>
<string name="grade_switch_semester">Změnit semestr</string>
<string name="grade_semester">Pololetí %d</string>
<string name="grade_switch_semester">Změnit pololetí</string>
<string name="grade_no_items">Žádné známky</string>
<string name="grade_weight">Váha</string>
<string name="grade_weight_value">Váha: %s</string>
@ -125,16 +125,16 @@
<string name="grade_summary_calculated_average">Vypočítaný pololetní průměr</string>
<string name="grade_summary_calculated_average_annual">Vypočítaný roční průměr</string>
<string name="grade_summary_calculated_average_help_dialog_title">Jak funguje vypočítaný průměr?</string>
<string name="grade_summary_calculated_average_help_dialog_message">Vypočítaný průměr je aritmetický průměr vypočítaný z průměrů předmětů. Umožňuje vám to znát přibližný konečný průměr. Vypočítává se způsobem zvoleným uživatelem v nastavení aplikaci. Doporučuje se vybrat příslušnou možnost. Důvodem je rozdílný výpočet školních průměrů. Pokud vaše škola navíc uvádí průměr předmětů na stránce deníku Vulcan, aplikace si je stáhne a tyto průměry nepočítá. To lze změnit vynucením výpočtu průměru v nastavení aplikaci.\n\n<b>Průměr známek pouze z vybraného semestru</b>:\n1. Výpočet váženého průměru pro každý předmět v daném semestru\n2. Sčítání vypočítaných průměrů\n3. Výpočet aritmetického průměru součtených průměrů\n\n<b>Průměr průměrů z obou semestrů</b>:\n1. Výpočet váženého průměru pro každý předmět v semestru 1 a 2\n2. Výpočet aritmetického průměru vypočítaných průměrů za semestry 1 a 2 pro každý předmět.\n3. Sčítání vypočítaných průměrů\n4. Výpočet aritmetického průměru sečtených průměrů\n\n<b>Průměr známek z celého roku:</b>\n1. Výpočet váženého průměru za rok pro každý předmět. Konečný průměr v 1. semestru je nepodstatný.\n2. Sčítání vypočítaných průměrů\n3. Výpočet aritmetického průměru součtených průměrů</string>
<string name="grade_summary_calculated_average_help_dialog_message">Vypočítaný průměr je aritmetický průměr vypočítaný z průměrů předmětů. Umožňuje vám to znát přibližný konečný průměr. Vypočítává se způsobem zvoleným uživatelem v nastavení aplikaci. Doporučuje se vybrat příslušnou možnost. Důvodem je rozdílný výpočet školních průměrů. Pokud vaše škola navíc uvádí průměr předmětů na stránce deníku Vulcan, aplikace si je stáhne a tyto průměry nepočítá. To lze změnit vynucením výpočtu průměru v nastavení aplikaci.\n\n<b>Průměr známek pouze z vybraného pololetí</b>:\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\n<b>Průměr průměrů z obou pololetí</b>:\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\n<b>Průměr známek z celého roku:</b>\n1. Výpočet váženého průměru za rok pro každý předmět. Konečný průměr v 1. 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ů</string>
<string name="grade_summary_final_average_help_dialog_title">Jak funguje konečný průměr?</string>
<string name="grade_summary_final_average_help_dialog_message">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</string>
<string name="grade_summary_final_average_help_dialog_message">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</string>
<string name="grade_summary_final_average">Konečný průměr</string>
<string name="grade_summary_from_subjects">z %1$d z %2$d předmětů</string>
<string name="grade_menu_summary">Shrnutí</string>
<string name="grade_menu_statistics">Třída</string>
<string name="grade_menu_read">Označit jako přečtené</string>
<string name="grade_statistics_partial">Částečně</string>
<string name="grade_statistics_semester">Semestr</string>
<string name="grade_statistics_semester">Pololetí</string>
<string name="grade_statistics_points">Body</string>
<string name="grade_statistics_legend">Vysvětlivky</string>
<string name="grade_statistics_class_average">Průměr třídy: %1$s</string>
@ -499,7 +499,7 @@
<string name="mobile_devices_title">Mobilní přístup</string>
<string name="mobile_devices_no_items">Žádná zařízení</string>
<string name="mobile_devices_unregister">Zrušit registraci</string>
<string name="mobile_device_removed">Zařízení odstranění</string>
<string name="mobile_device_removed">Zařízení odstraněno</string>
<string name="mobile_device_qr">QR kód</string>
<string name="mobile_device_token">Token</string>
<string name="mobile_device_symbol">Symbol</string>
@ -872,6 +872,8 @@
<string name="captcha_dialog_title">Webová stránka deníku VULCAN vyžaduje ověření</string>
<string name="captcha_dialog_description"><b>Proč se mi to zobrazuje?</b>\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</string>
<string name="captcha_verified_message">Úspěšně ověřeno</string>
<!--Panic mode-->
<string name="panic_mode_title">Nouzový přístup</string>
<!--Errors-->
<string name="error_no_internet">Žádné internetové připojení</string>
<string name="error_invalid_device_datetime">Vyskytla se chyba. Zkontrolujte hodiny svého zařízení</string>
@ -893,4 +895,7 @@
<string name="message_unmute">Zrušit ztlumení</string>
<string name="message_mute_success">Ztlumili jste tohoto uživatele</string>
<string name="message_unmute_success">Zrušili jste ztlumení tohoto uživatele</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br /&gt;&lt;br /&gt;Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href=\"https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl\"&gt;Dzienniczek VULCAN&lt;/a&gt;. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string-array name="app_theme_entries" tools:ignore="InconsistentArrays">
<item>Motiw systemu</item>
<item>Jôsny</item>
<item>Cemny</item>
<item>Cemny (AMOLED)</item>
</string-array>
</resources>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="sort_alphabetically">Alfabéticzno</string>
<string name="sort_by_date">Pòdług datë</string>
<string name="sort_by_average">Pòdług strzédny</string>
<string name="sort_by_attendance_percentage">Pòdług procentu bëtnoscë</string>
<string name="sort_by_subject_attendance_balance">Pòdług salda frekwencje na przibiorze</string>
<string-array name="app_theme_entries" tools:ignore="InconsistentArrays">
<item>Jôsny</item>
<item>Cemny</item>
<item>Cemny (AMOLED)</item>
</string-array>
<string-array name="app_language_entries">
<item>Systemòwi jãzëk</item>
<item>Polski</item>
<item>English</item>
<item>Pусский</item>
<item>Українська</item>
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 minutów</item>
<item>30 minutów</item>
<item>1 gòdzëna</item>
<item>2 gòdzënë</item>
<item>6 gòdzyn</item>
<item>12 gòdzyn</item>
<item>24 gòdzyn</item>
</string-array>
<string-array name="grade_modifier_entries">
<item>0,00</item>
<item>0,25</item>
<item>0,33</item>
<item>0,5</item>
<item>0,75</item>
</string-array>
<string-array name="grade_color_scheme_entries">
<item>Dzienniczek+</item>
<item>Wulkanowy</item>
<item>Farwa taksów w dzénnikù</item>
</string-array>
<string-array name="default_expand_grade_entries">
<item>Do 1 na rôz</item>
<item>Wiedno rozwiniãti</item>
<item>Rozwijanié bez grańców</item>
</string-array>
<string-array name="grade_average_mode_entries">
<item>Strzédnô taksów leno z wëbrónégò semestru</item>
<item>Strzédnô z strzédnëch z òbùch semestrów</item>
<item>Strzédnô wszëtczich taksów z całégò rokù</item>
</string-array>
<string-array name="timetable_show_gaps_entries">
<item>Nié pòkazuj</item>
<item>Leno midzë ùczbama</item>
<item>Przed a midzë ùczbama</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Nié pòkazuj</item>
<item>Pòkażë razã</item>
<item>Pòkôżë niżi zwëczajné ùczbë</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Szczestlëwi numerk</item>
<item>Nieprzeczëtóné wiadë</item>
<item>Frekwencjô</item>
<item>Ùczbë</item>
<item>Taksë</item>
<item>Zadanié dodóm</item>
<item>Szkòlowi ògłos</item>
<item>Testë</item>
<item>Zéńdzenia</item>
</string-array>
</resources>

View File

@ -0,0 +1,854 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Activity/Fragment title-->
<string name="login_title">Logòwanié</string>
<string name="main_title">Wulkanowy</string>
<string name="grade_title">Taksë</string>
<string name="attendance_title">Frekwencjô</string>
<string name="exam_title">Testë</string>
<string name="timetable_title">Plan zajmów</string>
<string name="settings_title">Nastôwë</string>
<string name="more_title">Wicy</string>
<string name="about_title">Ò aplikacëje</string>
<string name="logviewer_title">Pòkazéwôcz logów</string>
<string name="debug_title">Debùgòwanié</string>
<string name="notification_debug_title">Debùgòwanié wiadłów</string>
<string name="debug_cookies_clear">Rëmni kùszczi webview</string>
<string name="contributors_title">Wkłôdôrze</string>
<string name="license_title">Licencëje</string>
<string name="message_title">Wiadë</string>
<string name="send_message_title">Nowô wiada</string>
<string name="add_homework_title">Nowé zadanié dodóm</string>
<string name="note_title">Ùwôdżi i pòstãpë</string>
<string name="homework_title">Zadanié dodóm</string>
<string name="account_title">Czerownik kòntów</string>
<string name="account_quick_title">Wëbierzë kònto</string>
<string name="account_details_title">Drobnotë kònta</string>
<string name="student_info_title">Jinfòrmacëje ò ùczniu</string>
<string name="dashboard_title">Doma</string>
<string name="notifications_center_title">Centrum wiadłów</string>
<string name="menu_order_title">Kònfigùracëjô menu</string>
<!--Subtitles-->
<string name="grade_subtitle">Semestr %1$d, %2$d/%3$d</string>
<!--Login-->
<string name="login_header_default">Zalogùj sã brëkùjącë kònta ùcznia abò rodzëca</string>
<string name="login_header_symbol">Pòdôj symbòl z starnë dzénnika dlô kònta: &lt;b&gt;%1$s&lt;/b&gt;</string>
<string name="login_nickname_hint">Pòzwa brëkòwnika</string>
<string name="login_email_hint">Adresa E-mail</string>
<string name="login_login_pesel_email_hint">Login, PESEL abò adresa e-mail</string>
<string name="login_password_hint">Parola</string>
<string name="login_host_hint">Wariant dzénnika UONET+</string>
<string name="login_domain_suffix_hint">Niesztandardowi sufiks domenë</string>
<string name="login_type_api">Mòbilné API</string>
<string name="login_type_scrapper">Scraper</string>
<string name="login_type_hybrid">Hibdridowé</string>
<string name="login_token_hint">Token</string>
<string name="login_pin_hint">PIN</string>
<string name="login_symbol_hint">Symbol</string>
<string name="login_symbol_placeholder">Np. \"lodz\" czë \"powiatjaroslawski\"</string>
<string name="login_sign_in">Zalogùj</string>
<string name="login_invalid_password">Parola je za krótkô</string>
<string name="login_incorrect_password_default">Dane logòwaniô są niépasowné</string>
<string name="login_incorrect_password">%1$s. Ùgwësni sã, że wëbrôno pòprawną òdmianã dzénnika UONET+ niżi</string>
<string name="login_invalid_pin">Niepasowny PIN</string>
<string name="login_invalid_token">Niepasowny token</string>
<string name="login_expired_token">Token wëgôsł</string>
<string name="login_invalid_email">Niepasowny adresa e-mail</string>
<string name="login_invalid_login">Ùżij loginu miast adresu e-mail</string>
<string name="login_invalid_custom_email">Ùżij loginu abò adresu e-mail w @%1$s</string>
<string name="login_invalid_domain_suffix">Niepasowny sufiks domenë</string>
<string name="login_invalid_symbol">Niepasowny symbòl. Żelë nié mòżesz gò nalézc, proszã skòntaktowac sã z szkòłą</string>
<string name="login_invalid_symbol_definitely">Nie szkaluj! żelë nié mòżesz nalézc symbòlu, skòntaktuj sã z szkòłą</string>
<string name="login_incorrect_symbol">Ùczeń nie nalazłi. Sprôwdzë pòprawnosc symbòlu i wëbróny òdmianë dzénnika UONET+</string>
<string name="login_duplicate_student">Wëbróny ùczeń je ju zalogòwóny</string>
<string name="login_symbol_helper">Symbòl mòżna nalézc na starnie dzénnika w&#160;<b>Ùczeń</b>&#160;<b>Dostãp mòbilny</b>&#160;<b>Wëgeneruj kòd dostãpù </b>.\n\nÙgwësni sã, że ùstôwił jes pasowną òdmianã dzénnika w pòlu <b>Òdmiana dzénnika UONET+</b> na pierszim ekranie logòwania</string>
<string name="login_select_student">Wëbierzë ùczniów do zalogòwaniô w aplikacëje</string>
<string name="login_advanced">Jiné òpcëje</string>
<string name="login_advanced_warning_mobile_api">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</string>
<string name="login_advanced_warning_scraper">Nen trib wëswietlô ne samé dane, chtërne są widoczné na jinternetowi starnie dzénnika</string>
<string name="login_advanced_warning_hybrid">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</string>
<string name="login_privacy_policy">Pòlitëka priwatnoscë</string>
<string name="login_contact_header">Tôkel z logòwanim? Napiszë do naju!</string>
<string name="login_contact_email">E-mail</string>
<string name="login_contact_discord">Discord</string>
<string name="login_email_intent_title">Wëslë e-mail</string>
<string name="login_recover_warning">Ùgwësni sã, że òsta wëbrónô òdpòwiedniô òdmiana dzénnika UONET+!</string>
<string name="login_recover_button">Resetuj parolã</string>
<string name="login_recover_title">Przëwarcë swòje kònto</string>
<string name="login_recover">Przëwarcë</string>
<string name="login_signed_in">Ùczeń je ju zalogòwóny</string>
<string name="login_host_standard">Sztandardowô</string>
<string name="login_other_search_locations">Jinô lokalizacëjô wësznëkrowaniô</string>
<string name="login_no_active_student">Nie nalazło aktiwnëch ùczniów</string>
<string name="login_symbol_enter">Wprowadzë jiny symbòl</string>
<string name="login_support_title">Zëskôj pòmòc</string>
<string name="login_support_school_hint">Fùl pòzwa szkòłë z gardã (Wëmôgô)</string>
<string name="login_support_school_placeholder">Np. ZSTiO Jarosław abò SP nr 99 w Łodzi</string>
<string name="login_support_school_invalid">Wprowadzë pòprawną pòzwã szkòłë</string>
<string name="login_support_additional_hint">Dodôtkòwé jinfòrmacëje pò Pòlskù (Òpcjonalno)</string>
<string name="login_support_additional_placeholder">Np. \"Òstatnio zmienił jem szkòłã i…\" abò \"Jô jem rodzëcã i nié widzã drëdżégò dzecka…\"</string>
<string name="login_support_submit">Wëslë</string>
<!--Notifications-->
<string name="notifications_header_title">Włączë wiadła</string>
<string name="notifications_header_description">Włączë wiadła, abë nie zabôczëc wiadów òd szkólnëch abò nowi taksë</string>
<string name="notifications_skip">Pòmiń</string>
<string name="notifications_enable">Włączë</string>
<!--Main-->
<string name="main_account_picker">Czerownik kòntów</string>
<string name="main_log_in">Zalogùj sã</string>
<string name="main_session_expired">Sesjô zgasłô</string>
<string name="main_session_relogin">Sesja zgasłô, zalogùj sã znôwa</string>
<string name="main_expired_credentials_title">Parola zgasłô abò òsta zmieniona</string>
<string name="main_expired_credentials_description">Parola do twòjégò kònta zgasłô abò òsta zmieniona. Mùszisz zalogòwac sã znôwa do Wùlkanowégò</string>
<string name="main_support_title">Wspiarcé aplikacëje</string>
<string name="main_support_description">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</string>
<string name="main_support_positive">Włączë reklamë</string>
<!--Grade-->
<string name="grade_header">Taksa</string>
<string name="grade_semester">Semestr %d</string>
<string name="grade_switch_semester">Zmieni semestr</string>
<string name="grade_no_items">Felënk taksów</string>
<string name="grade_weight">Wôga</string>
<string name="grade_weight_value">Wôga: %s</string>
<string name="grade_comment">Kòmentôrz</string>
<string name="grade_number_new_items">Jilosc nowich taksów: %1$d</string>
<string name="grade_average">Strzédnô: %1$.2f</string>
<string name="grade_average_year">Rocznô: %1$.2f</string>
<string name="grade_points_sum">Pónktë: %s</string>
<string name="grade_no_average">Felënk strzédny</string>
<string name="grade_summary_average_semester">Strzédnô semestru</string>
<string name="grade_summary_average_year">Strzédnô rocznô</string>
<string name="grade_summary_points">Jilosc pónktów</string>
<string name="grade_summary_final_grade">Kùńcowô taksa</string>
<string name="grade_summary_predicted_grade">Spòdzónô taksa</string>
<string name="grade_summary_descriptive">Òpisowô taksa</string>
<string name="grade_summary_calculated_average">Òbliczonô strzédnô semestru</string>
<string name="grade_summary_calculated_average_annual">Òbliczonô rocznô strzédna</string>
<string name="grade_summary_calculated_average_help_dialog_title">Jak dzejô òbliczonô strzédnô?</string>
<string name="grade_summary_calculated_average_help_dialog_message">Ò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\n<b>Strzédnô taksów leno z wëbrónégò semestru</b>:\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\n<b>Strzédnô ze strzédnëch z òbùch semestrów</b>:\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\n<b>Strzédnô taksów z całégò rokù:</b>\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ã</string>
<string name="grade_summary_final_average_help_dialog_title">Jak fónksnéruje kùńcowô strzédna?</string>
<string name="grade_summary_final_average_help_dialog_message">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é</string>
<string name="grade_summary_final_average">Kùńcowô strzédna</string>
<string name="grade_summary_from_subjects">z %1$d na %2$d zajmów</string>
<string name="grade_menu_summary">Pòdrëchòwanié</string>
<string name="grade_menu_statistics">Klasa</string>
<string name="grade_menu_read">Zamérkô jakò przeczëtóné</string>
<string name="grade_statistics_partial">Cawné</string>
<string name="grade_statistics_semester">Semestr</string>
<string name="grade_statistics_points">Pónktë</string>
<string name="grade_statistics_legend">Legenda</string>
<string name="grade_statistics_class_average">Strzédna klasë: %1$s</string>
<string name="grade_statistics_student_average">Twòja strzédnô: %1$s</string>
<string name="grade_statistics_student_grade">Twòja taksa: %1$s</string>
<string name="grade_statistics_average_class">Klasa</string>
<string name="grade_statistics_average_student">Ùczeń</string>
<plurals name="grade_number_item">
<item quantity="one">%d taksa</item>
<item quantity="few">%d taksë</item>
<item quantity="other">%d taksów</item>
</plurals>
<plurals name="grade_new_items">
<item quantity="one">Nowô taksa</item>
<item quantity="few">Nowé taksë</item>
<item quantity="other">Nowé taksë</item>
</plurals>
<plurals name="grade_new_items_predicted">
<item quantity="one">Nowô spòdzónô taksa</item>
<item quantity="few">Nowé spòdzóné taksë</item>
<item quantity="other">Nowé spòdzóné taksë</item>
</plurals>
<plurals name="grade_new_items_final">
<item quantity="one">Nowô kùńcowô taksa</item>
<item quantity="few">Nowé kùńcowé taksë</item>
<item quantity="other">Nowé kùńcowé taksë</item>
</plurals>
<plurals name="grade_new_items_descriptive">
<item quantity="one">Nowô òpisowô taksa</item>
<item quantity="few">Nowé òpisowé taksë</item>
<item quantity="other">Nowé òpisowé taksë</item>
</plurals>
<plurals name="grade_notify_new_items">
<item quantity="one">Môsz %1$d nową taksã</item>
<item quantity="few">Môsz %1$d nowé taksë</item>
<item quantity="other">Môsz %1$d nowëch taksów</item>
</plurals>
<plurals name="grade_notify_new_items_predicted">
<item quantity="one">Môsz %1$d nową spodzóną taksã</item>
<item quantity="few">Môsz %1$d nowé spodzón taksë</item>
<item quantity="other">Môsz %1$d nowëch spodzónëch taksów</item>
</plurals>
<plurals name="grade_notify_new_items_final">
<item quantity="one">Môsz %1$d nową kùńcową taksã</item>
<item quantity="few">Môsz %1$d nowé kùńcowé taksë</item>
<item quantity="other">Môsz %1$d nowëch kùńcowëch taksów</item>
</plurals>
<plurals name="grade_notify_new_items_descriptive">
<item quantity="one">Môsz %1$d nową òpisową taksã</item>
<item quantity="few">Môsz %1$d nowé òpisowé taksë</item>
<item quantity="other">Môsz %1$d nowëch òpisowëch taksów</item>
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Ùczba</string>
<string name="timetable_additional_lesson">Dodôtkòwô ùczba</string>
<string name="timetable_room">Zala</string>
<string name="timetable_group">Karno</string>
<string name="timetable_time">Gòdzënë</string>
<string name="timetable_changes">Zmianë</string>
<string name="timetable_no_items">Felënk ùczbów dzysô</string>
<string name="timetable_minutes">%s min</string>
<string name="timetable_seconds">%s sek</string>
<string name="timetable_time_left">jesz %1$s</string>
<string name="timetable_time_until">za %1$s</string>
<string name="timetable_finished">Fardëch</string>
<string name="timetable_now">Terô: %s</string>
<string name="timetable_next">Pòstãpné: %s</string>
<string name="timetable_later">Pózdni: %s</string>
<string name="timetable_notify_lesson">%1$s ùczba %2$d - %3$s</string>
<string name="timetable_notify_change_room">Pòzmiana zalë z %1$s na %2$s</string>
<string name="timetable_notify_change_teacher">Pòzmiana szkólnégò z %1$s na %2$s</string>
<string name="timetable_notify_change_subject">Pòzmiana zajmë z %1$s na %2$s</string>
<plurals name="timetable_no_lesson">
<item quantity="one">Ni ma ùczbë</item>
<item quantity="few">Ni ma ùczbów</item>
<item quantity="other">Ni ma ùczbów</item>
</plurals>
<plurals name="timetable_notify_new_items_title">
<item quantity="one">Pòzmiana planu zajmów</item>
<item quantity="few">Pòzmianë planu zajmów</item>
<item quantity="other">Pòzmianë planu zajmów</item>
</plurals>
<plurals name="timetable_notify_new_items">
<item quantity="one">%1$s - %2$d Pòzmiana planu zajmów</item>
<item quantity="few">%1$s - %2$d Pòzmianë planu zajmów</item>
<item quantity="other">%1$s - %2$d Pòzmianów planu ùczbów</item>
</plurals>
<plurals name="timetable_notify_new_items_group">
<item quantity="one">%1$d Pòzmiana planu zajmów</item>
<item quantity="few">%1$d Pòzmianë planu zajmów</item>
<item quantity="other">%1$d Pòzmianë planu zajmów</item>
</plurals>
<plurals name="timetable_number_item">
<item quantity="one">%d Pòzmiana</item>
<item quantity="few">%d Pòzmianë</item>
<item quantity="other">%d Pòzmianë</item>
</plurals>
<!--Completed lessons-->
<string name="completed_lessons_title">Ùczbë są skùńczoné</string>
<string name="completed_lessons_button">Pòkôżë skùńczoné ùczbë</string>
<string name="completed_lessons_no_items">Felënk jinfòrmacëjów ò ùkòńczonëch ùczbach</string>
<string name="completed_lessons_topic">Témat</string>
<string name="completed_lessons_absence">Niebëtnosc</string>
<string name="completed_lessons_resources">Zôsóbczi</string>
<!--Additional lessons-->
<string name="additional_lessons_title">Dodatkòwé ùczbë</string>
<string name="additional_lessons_button">Pòkôżë dodatkòwé ùczbë</string>
<string name="additional_lessons_no_items">Felënk jinfòrmacëjów ò dodôtkòwëch ùczbach</string>
<string name="additional_lessons_add">Nowô ùczba</string>
<string name="additional_lessons_add_title">Nowô dodatkòwô ùczba</string>
<string name="additional_lessons_add_success">Dodatkòwa ùczba òsta dodónô z sukcesã</string>
<string name="additional_lessons_delete_success">Dodôtkòwô ùczba òsta rëmniãtô z sukcesã</string>
<string name="additional_lessons_repeat">Pòwtórzë co tidzéń</string>
<string name="additional_lessons_delete_title">Rëmni dodôtkòwą ùczbã</string>
<string name="additional_lessons_delete_one">Leno ta ùczba</string>
<string name="additional_lessons_delete_series">Wszëtczé w serie</string>
<string name="additional_lessons_start">Gòdzëna zôczãcô</string>
<string name="additional_lessons_end">Gòdzëna skùńczeniô</string>
<string name="additional_lessons_end_time_error">Gòdzëna skùńczeniô mùszi bëc pózdniszô jak gòdzëzna zôczãcô</string>
<!--Attendance-->
<string name="attendance_summary_button">Pòdrëchòwanié bëtnoscë</string>
<string name="attendance_calculator_button">Kalkulator bëtnoscë</string>
<string name="attendance_calculator_summary_balance_positive"><b>%1$d</b> Wëżi célu</string>
<string name="attendance_calculator_summary_balance_neutral">dokładno kù célu</string>
<string name="attendance_calculator_summary_balance_negative"><b>%1$d</b> niżi célu</string>
<string name="attendance_calculator_summary_values">%1$d/%2$d bëtnoscë</string>
<string name="attendance_calculator_summary_values_empty">Nié zaùwôżono niżôdny frekwencëje</string>
<string name="attendance_absence_school">Niebëtnosc z szkòlnëch przëczënów</string>
<string name="attendance_absence_excused">Ùsprawiedlëwiono niéòbecnosc</string>
<string name="attendance_absence_unexcused">Nieùsprawiedlëwiono niéòbecnosc</string>
<string name="attendance_exemption">Zwòlnienié</string>
<string name="attendance_excused_lateness">Spózdnienié ùsprawiedlëwioné</string>
<string name="attendance_unexcused_lateness">Spózdnienié Nieùsprawiedlëwioné</string>
<string name="attendance_present">Bëtnosc</string>
<string name="attendance_deleted">Rëmniãto</string>
<string name="attendance_unknown">Niéznóny</string>
<string name="attendance_number">Lëczba ùczbów</string>
<string name="attendance_no_items">Ni ma wpisów</string>
<string name="attendance_excuse_dialog_reason">Pòwód niebëtnoscë (òpcjonalny)</string>
<string name="attendance_excuse_dialog_submit">Wëslë</string>
<string name="attendance_excuse_success">Proszba ò ùsprawiedlëwienié òsta wësłónô z sukcesã!</string>
<string name="attendance_excuse_no_selection">Mùszisz wëbrac bënômni jedną nieòbecnosc!</string>
<string name="attendance_excuse_title">Ùsprawiedliwi</string>
<plurals name="attendance_notify_new_items_title">
<item quantity="one">Nowô frekwencjô</item>
<item quantity="few">Nowé frekwencëje</item>
<item quantity="other">Nowé frekwencëje</item>
</plurals>
<plurals name="attendance_notify_new_items">
<item quantity="one">%1$d nowô frekwencjô</item>
<item quantity="few">%1$d nowé frekwencëje</item>
<item quantity="other">%1$d nowëch frekwencjów</item>
</plurals>
<plurals name="attendance_number_item">
<item quantity="one">%d frekwencjô</item>
<item quantity="few">%d frekwencëje</item>
<item quantity="other">%d frekwencjów</item>
</plurals>
<!--Attendance summary-->
<string name="attendance_summary_total">Razã</string>
<!--Exam-->
<string name="exam_no_items">Ni ma testów w tim tidzéniu</string>
<string name="exam_type">Ôrt</string>
<string name="exam_entry_date">Data wpisënkù</string>
<plurals name="exam_notify_new_item_title">
<item quantity="one">Nowi test</item>
<item quantity="few">Nowé testë</item>
<item quantity="other">Nowé testë</item>
</plurals>
<plurals name="exam_notify_new_item_content">
<item quantity="one">%d nowi test</item>
<item quantity="few">%d nowé testë</item>
<item quantity="other">%d nowëch testów</item>
</plurals>
<plurals name="exam_number_item">
<item quantity="one">%d test</item>
<item quantity="few">%d testë</item>
<item quantity="other">%d testów</item>
</plurals>
<!--Message-->
<string name="message_inbox">Òdebróné</string>
<string name="message_sent">Wësłóno</string>
<string name="message_trash">Wãbórk</string>
<string name="message_no_subject">(Niżôdny témat)</string>
<string name="message_no_items">Ni ma wiadów</string>
<string name="message_from">Òd:</string>
<string name="message_to">Do:</string>
<string name="message_date">Data: %1$s</string>
<string name="message_reply">Òdrzekni</string>
<string name="message_forward">Wëslë dali</string>
<string name="message_select_all">Zamérkô wszëtkò</string>
<string name="message_unselect_all">Òdmérkô wszëtkò</string>
<string name="message_restore_from_trash">Przëwrócë z wãbórka</string>
<string name="message_move_to_trash">Przeniesë do wãbórka</string>
<string name="message_delete_forever">Rëmni na wiedno</string>
<string name="message_restore_success">Wiada òsta przëwróconô z sukcesã</string>
<string name="message_delete_success">Wiada òsta rëmniãtô z sukcesã</string>
<string name="message_mailbox_type_student">ùczeń</string>
<string name="message_mailbox_type_parent">rodzëc</string>
<string name="message_mailbox_type_guardian">òpiekùn</string>
<string name="message_mailbox_type_employee">robòtnik</string>
<string name="message_share">Ùdostãpni</string>
<string name="message_print">Drukùj</string>
<string name="message_subject">Témat</string>
<string name="message_content">Tresc</string>
<string name="message_send_successful">Wiada òsta wësłónô z sukcesã</string>
<string name="message_not_exists">Wiada nie jistnieje</string>
<string name="message_required_recipients">Mùszisz wëbrac bënômni 1 adresata</string>
<string name="message_content_min_length">Tresc wiadë mùszi zawierac bënômni 3 znanczi</string>
<string name="message_chip_all_mailboxes">Wszëtczé skrzënie</string>
<string name="message_chip_only_unread">Leno nieprzeczëtóné</string>
<string name="message_chip_only_with_attachments">Leno z lopkama</string>
<string name="message_read">Przeczëtónô: %s</string>
<string name="message_read_by">Przeczëtónô bez: %1$d z %2$d osób</string>
<plurals name="message_number_item">
<item quantity="one">%1$d wiada</item>
<item quantity="few">%1$d wiadë</item>
<item quantity="other">%1$d wiadë</item>
</plurals>
<plurals name="message_new_items">
<item quantity="one">Nowô wiada</item>
<item quantity="few">Nowé wiadë</item>
<item quantity="other">Nowé wiadë</item>
</plurals>
<string name="message_restore_dialog">Chcemë le przëwrócyc robòczą wersëją wiadów?</string>
<string name="message_restore_dialog_with_recipients">Chcemë le przëwrócyc robòczą wersëją wiadów z adresatama? %s?</string>
<plurals name="message_notify_new_items">
<item quantity="one">Môsz %1$d nową wiadã</item>
<item quantity="few">Môsz %1$d nowé wiadë</item>
<item quantity="other">Môsz %1$d nowëch wiadów</item>
</plurals>
<plurals name="message_selected_messages_count">
<item quantity="one">%1$d wëbrónô</item>
<item quantity="few">%1$d wëbróné</item>
<item quantity="other">%1$d wëbrónëch</item>
</plurals>
<string name="message_messages_deleted">Wiadë òstałë rëmniãté</string>
<string name="message_messages_restored">Przewrócono wiadë</string>
<string name="message_mailbox_chooser_title">Wëbierzë skrzënią</string>
<string name="message_incognito_mode_on">Trib incognito je włączony</string>
<string name="message_incognito_description">Dzãka tribòwi incognito nadôwca nié òbôczi, że przeczëtôł jes ną wiadã</string>
<!--Note-->
<string name="note_no_items">Ni ma jinfòrmacëjów ò ùwôgach</string>
<string name="note_points">Pónktë</string>
<plurals name="note_number_item">
<item quantity="one">%d ùwôga</item>
<item quantity="few">%d ùwôdżi</item>
<item quantity="other">%d ùwôgów</item>
</plurals>
<plurals name="note_new_items">
<item quantity="one">Nowô ùwôga</item>
<item quantity="few">Nowé ùwôdżi</item>
<item quantity="other">Nowé ùwôdżi</item>
</plurals>
<plurals name="note_notify_new_items">
<item quantity="one">Môsz %1$d nową ùwôgã</item>
<item quantity="few">Môsz %1$d nowé ùwôdżi</item>
<item quantity="other">Môsz %1$d nowëch ùwôgów</item>
</plurals>
<!--Praise-->
<plurals name="praise_number_item">
<item quantity="one">%d chwôła</item>
<item quantity="few">%d chwałë</item>
<item quantity="other">%d chwôłów</item>
</plurals>
<plurals name="praise_new_items">
<item quantity="one">Nowô chwôła</item>
<item quantity="few">Nowé chwôłë</item>
<item quantity="other">Nowé chwôłë</item>
</plurals>
<plurals name="praise_notify_new_items">
<item quantity="one">Môsz %1$d nową chwôłã</item>
<item quantity="few">Môsz %1$d nowé chwôłë</item>
<item quantity="other">Môsz %1$d nowëch chwôłów</item>
</plurals>
<!--Neutral notes-->
<plurals name="neutral_note_number_item">
<item quantity="one">%d neùtralnô ùwôga</item>
<item quantity="few">%d neùtralné ùwôdżi</item>
<item quantity="other">%d neùtralnëch ùwôgów</item>
</plurals>
<plurals name="neutral_note_new_items">
<item quantity="one">Nowô neùtralnô ùwôga</item>
<item quantity="few">Nowé neùtralné ùwôdżi</item>
<item quantity="other">Nowé neùtralné ùwôdżi</item>
</plurals>
<plurals name="neutral_note_notify_new_items">
<item quantity="one">Môsz %1$d nową neùtralną ùwôgã</item>
<item quantity="few">Môsz %1$d nowé neùtralné ùwôdżi</item>
<item quantity="other">Môsz %1$d nowëch neùtralnëch ùwôgów</item>
</plurals>
<!--Homework-->
<string name="homework_no_items">Ni ma zadaniów dodóm</string>
<string name="homework_mark_as_done">Fardëch</string>
<string name="homework_mark_as_undone">Nié je fardëch</string>
<string name="homework_add">Dodôj Zadanié dodóm</string>
<string name="homework_add_success">Zadanié dodóm dodóné z sukcesã</string>
<string name="homework_delete_success">Zadanié dodóm rëmniãté z sukcesã</string>
<string name="homework_attachments">Lópk</string>
<plurals name="homework_notify_new_item_title">
<item quantity="one">Nowé zadanié dodóm</item>
<item quantity="few">Nowé zadania dodóm</item>
<item quantity="other">Nowé zadania dodóm</item>
</plurals>
<plurals name="homework_notify_new_item_content">
<item quantity="one">Môsz %d nowé zadania dodóm</item>
<item quantity="few">Môsz %d nowé zadania dodóm</item>
<item quantity="other">Môsz %d nowëch zadaniów dodóm</item>
</plurals>
<plurals name="homework_number_item">
<item quantity="one">%d zadanié dodóm</item>
<item quantity="few">%d zadania dodóm</item>
<item quantity="other">%d zadaniów dodóm</item>
</plurals>
<!--Lucky number-->
<string name="lucky_number_title">Szczestlëwi numerk</string>
<string name="lucky_number_header">Dzysészim szczestlëwim numerkã je</string>
<string name="lucky_number_empty">Ni ma jinfòrmacëjów ò szczestlëwim numerkù</string>
<string name="lucky_number_notify_new_item_title">Szczestlëwi numerk na dzysô</string>
<string name="lucky_number_notify_new_item">Dzysészim szczestlëwim numerkã je: %s</string>
<string name="lucky_number_history_button">Pòkôżë historëją</string>
<!--Lucky number history-->
<string name="lucky_number_history_title">Historijô numerków</string>
<string name="lucky_number_history_empty">Ni ma jinfòrmacëjów ò szczestlëwich numerkach</string>
<!--Mobile devices-->
<string name="mobile_devices_title">Przëstãp mòbilny</string>
<string name="mobile_devices_no_items">Ni ma ùrządzeniów</string>
<string name="mobile_devices_unregister">Wërejestruj</string>
<string name="mobile_device_removed">Ùrządzenié òstało rëmniãté</string>
<string name="mobile_device_qr">Kòd QR</string>
<string name="mobile_device_token">Token</string>
<string name="mobile_device_symbol">Symbol</string>
<string name="mobile_device_pin">PIN</string>
<!--School and teachers-->
<string name="schoolandteachers_title">Szkòła i szkólny</string>
<!--School-->
<string name="school_title">Szkòła</string>
<string name="school_no_info">Ni ma jinfòrmacëjów ò szkòle</string>
<string name="school_name">Pòzwa szkòłë</string>
<string name="school_address">Adresa szkòłë</string>
<string name="school_telephone">Telefòn</string>
<string name="school_headmaster">Miono i nôzwëskò direktóra</string>
<string name="school_pedagogue">Miono i nôzwëskò pedagóga</string>
<string name="school_address_button">Pòkôżë na kôrce</string>
<string name="school_telephone_button">Zazwòni</string>
<!--Teacher-->
<string name="teachers_title">Szkólny</string>
<string name="teacher_no_items">Ni ma jinfòrmacëjów ò szkólnëch</string>
<string name="teacher_no_subject">Ni ma zajmë</string>
<!--Conference-->
<string name="conferences_title">Zéńdzenia</string>
<string name="conference_no_items">Ni ma jinfòrmacëjów ò zéńdzeniach</string>
<plurals name="conference_number_item">
<item quantity="one">%d zéńdzenié</item>
<item quantity="few">%d zéńdzenia</item>
<item quantity="other">%d zéńdzeniów</item>
</plurals>
<plurals name="conference_notify_new_item_title">
<item quantity="one">Nowé zéńdzenie</item>
<item quantity="few">Nowé zéńdzenia</item>
<item quantity="other">Nowé zéńdzenia</item>
</plurals>
<plurals name="conference_notify_new_items">
<item quantity="one">Môsz %1$d nowé zéńdzenié</item>
<item quantity="few">Môsz %1$d nowé zéńdzenia</item>
<item quantity="other">Môsz %1$d nowëch zéńdzeniów</item>
</plurals>
<string name="conferences_present">Òbecnosc na zéńdzenim</string>
<string name="conference_agenda">Agenda</string>
<string name="conference_place">Plac</string>
<string name="conference_topic">Témat</string>
<!--Director information-->
<string name="school_announcement_title">Szkòlowi ògłos</string>
<string name="school_announcement_no_items">Ni ma szkòlowich ògłosów</string>
<plurals name="school_announcement_number_item">
<item quantity="one">%d szkòlowi ògłos</item>
<item quantity="few">%d szkòlowé ògłosë</item>
<item quantity="other">%d szkòlowich ògłosów</item>
</plurals>
<plurals name="school_announcement_notify_new_item_title">
<item quantity="one">%d Nowi szkòlowi ògłos</item>
<item quantity="few">%d Nowé szkòlowé ògłosë</item>
<item quantity="other">%d Nowé szkòlowé ògłosë</item>
</plurals>
<plurals name="school_announcement_notify_new_items">
<item quantity="one">Môsz %1$d nowi szkòlowi ògłos</item>
<item quantity="few">Môsz %1$d nowé szkòlowé ògłosë</item>
<item quantity="other">Môsz %1$d nowëch szkòlowich ògłosów</item>
</plurals>
<!--Account-->
<string name="account_add_new">Dodôj kònto</string>
<string name="account_logout">Wëlogùj sã</string>
<string name="account_confirm">Chcemë le wëlogòwac tegò ùcznia?</string>
<string name="account_logout_student">Wëlogòwanié ùcznia</string>
<string name="account_type_student">Kònto ùcznia</string>
<string name="account_type_parent">Rodzëcelsczé kònto</string>
<string name="account_details_edit">Edituj dane</string>
<string name="account_quick_manager">Czerownik kòntów</string>
<string name="account_select_student">Wëbierzë ùcznia</string>
<string name="account_family">Rodzëzna</string>
<string name="account_contact">Kòntakt</string>
<string name="account_address">Adresowé dane</string>
<string name="account_personal_data">Òsobòwé dane</string>
<!--About-->
<string name="about_version">Wersëjô aplikacëje</string>
<string name="about_contributor">Wkłôdôrze</string>
<string name="about_contributor_summary">Lësta programistów Wùlkanowégò</string>
<string name="about_feedback">Zgłosë błãd</string>
<string name="about_feedback_summary">Wëslë zgłoszenié ò błãdze bez e-mail</string>
<string name="about_faq">FAQ</string>
<string name="about_faq_summary">Òbôczë nôczãscy zadawóné pëtania</string>
<string name="about_discord">Serwer Discord</string>
<string name="about_discord_summary">Dołączë do spòlëznë Wùlkanowégò</string>
<string name="about_facebook">Fanpage na Facebookù</string>
<string name="about_twitter">Starna na Twitterze</string>
<string name="about_twitter_summary">Szlachùj nas na Twitterze</string>
<string name="about_facebook_summary">Pòlub najégò fanpage na Facebookù</string>
<string name="about_privacy">Pòlitëka priwatnoscë</string>
<string name="about_privacy_summary">Regle zbieraniégò òsobòwëch danëch</string>
<string name="about_system">Systemòwé nastôwë</string>
<string name="about_system_summary">Òdemkni systemòwé nastôwë</string>
<string name="about_homepage">Domôcô starna</string>
<string name="about_homepage_summary">Òdwiedzë starnã i pòmòżë rozwijac aplikacëją</string>
<string name="about_licenses">Licencëje</string>
<string name="about_licenses_summary">Licencëje ùżitëch biblijotéków w aplikacëje</string>
<!--Licenses-->
<string name="license_dialog_title">Licencëjô</string>
<!--Contributor-->
<string name="contributor_avatar_description">Awatar</string>
<string name="contributor_see_more">Òbôczë wicy na GitHub</string>
<!--Student info-->
<string name="student_info_empty">Ni ma jinfòrmacëjów ò ùczniu abò rodzëznie ùcznia</string>
<string name="student_info_first_name">Miono</string>
<string name="student_info_second_name">Drëdżé miono</string>
<string name="student_info_gender">Płoc</string>
<string name="student_info_polish_citizenship">Pòlsczé òbëwatelstwò</string>
<string name="student_info_family_name">Rodné nazwëskò</string>
<string name="student_info_parents_name">Miono òjca i mùterczi</string>
<string name="student_info_phone">Telefòn</string>
<string name="student_info_cellphone">Mòbilk</string>
<string name="student_info_email">Adresa e-mail</string>
<string name="student_info_address">Adresa zamieszkaniô</string>
<string name="student_info_registered_address">Adresa zameldowaniô</string>
<string name="student_info_correspondence_address">Adresa kòrespòndencëjnë</string>
<string name="student_info_full_name">Nôzwëskò ë miono</string>
<string name="student_info_kinship">Stopień pòkrëwieństwa</string>
<string name="student_info_guardian_address">Adresa</string>
<string name="student_info_phones">Telefònë</string>
<string name="student_info_male">Chłop</string>
<string name="student_info_female">Białka</string>
<string name="student_info_last_name">Nôzwëskò</string>
<string name="student_info_guardian">Òpiekùn</string>
<!--Account edit-->
<string name="account_edit_nick_hint">Pòzwa</string>
<string name="account_edit_header">Dodôj Pòzwã</string>
<string name="account_edit_avatar_title">Wëbierzë farwã profilowégò</string>
<!--Log viewer-->
<string name="logviewer_share">Ùdostãpni logi</string>
<string name="logviewer_refresh">Òdswieżë</string>
<!--Dashboard-->
<string name="dashboard_timetable_title">Ùczbë</string>
<string name="dashboard_timetable_title_tomorrow">(Witro)</string>
<string name="dashboard_timetable_title_today_and_tomorrow">(Dzysô i witro)</string>
<string name="dashboard_timetable_first_lesson_title_moment">Za chwilã:</string>
<string name="dashboard_timetable_first_lesson_title_soon">Wnetka:</string>
<string name="dashboard_timetable_first_lesson_title_first">Pierszi:</string>
<string name="dashboard_timetable_first_lesson_title_now">Terô:</string>
<string name="dashboard_timetable_second_lesson_value_end">Kùńc ùczbë</string>
<string name="dashboard_timetable_second_lessons_title">Pòstãpno:</string>
<string name="dashboard_timetable_third_title">Pòzdze:</string>
<plurals name="dashboard_timetable_third_value">
<item quantity="one">Jesz %1$d ùczba</item>
<item quantity="few">Jesz %1$d ùczbë</item>
<item quantity="other">Jesz %1$d ùczbów</item>
</plurals>
<string name="dashboard_timetable_third_time">do %1$s</string>
<string name="dashboard_timetable_no_lessons">Felënk przińdłich ùczbów</string>
<string name="dashboard_timetable_error">Wëstąpił błãd òbczas ładowaniô ùczbë</string>
<string name="dashboard_homework_title">Zadanié dodóm</string>
<string name="dashboard_homework_no_homework">Ni ma zadaniów dodóm do przërëchtowaniô</string>
<string name="dashboard_homework_error">Wëstąpił błãd òbczas ładowaniô zadaniégò dodóm</string>
<plurals name="dashboard_homework_more">
<item quantity="one">Jesz %1$d zadanié dodóm</item>
<item quantity="few">Jesz %1$d zadaniów dodóm</item>
<item quantity="other">Jesz %1$d zadaniów dodóm</item>
</plurals>
<string name="dashboard_homework_time">do %1$s</string>
<string name="dashboard_grade_title">Slédné taksë</string>
<string name="dashboard_grade_no_grade">Ni ma nowëch taksów</string>
<string name="dashboard_grade_error">Wëstąpił błãd òbczas ładowaniô taksów</string>
<string name="dashboard_announcements_title">Szkòlowé ògłosë</string>
<string name="dashboard_announcements_no_announcements">Ni ma aktualnëch ògłosów</string>
<string name="dashboard_announcements_error">Wëstąpił błãd òbczas ładowaniô ògłosów</string>
<plurals name="dashboard_announcements_more">
<item quantity="one">Jesz %1$d ògłos</item>
<item quantity="few">Jesz %1$d ògłosë</item>
<item quantity="other">Jesz %1$d ògłosów</item>
</plurals>
<string name="dashboard_exams_title">Testë</string>
<string name="dashboard_exams_no_exams">Felënk przińdłich testów</string>
<string name="dashboard_exams_error">Wëstąpił błãd òbczas ładowaniô testów</string>
<plurals name="dashboard_exams_more">
<item quantity="one">Jesz %1$d test</item>
<item quantity="few">Jesz %1$d testë</item>
<item quantity="other">Jesz %1$d testów</item>
</plurals>
<string name="dashboard_conferences_title">Zéńdzenia</string>
<string name="dashboard_conferences_no_conferences">Ni ma przińdłich zéńdzeniów</string>
<string name="dashboard_conferences_error">Wëstąpił błãd òbczas ładowaniô zéńdzeniów</string>
<plurals name="dashboard_conference_more">
<item quantity="one">Jesz %1$d dodôtkòwé zéńdzenié</item>
<item quantity="few">Jesz %1$d dodôtkòwé zéńdzenia</item>
<item quantity="other">Jesz %1$d zéńdzeniów</item>
</plurals>
<string name="dashboard_horizontal_group_error">Wëstąpił błãd òbczas ładowaniô danëch</string>
<string name="dashboard_horizontal_group_no_data">Niżôdny</string>
<!--Error dialog-->
<string name="dialog_error_check_update">Sprôwdzë dostãpnosc aktualizacëjów</string>
<string name="dialog_error_check_update_message">Przed zgłoszenim błãdu sprôwdzë wczesny czë dostãpnô je ju aktualizacëjô z pòprôwką błãdu</string>
<!--Generic-->
<string name="all_content">Tresc</string>
<string name="all_retry">Pònowi</string>
<string name="all_description">Òpisënk</string>
<string name="all_no_description">Felënk òpisënkù</string>
<string name="all_teacher">Szkólny</string>
<string name="all_date">Data</string>
<string name="all_entry_date">Data wpisënkù</string>
<string name="all_color">Farwa</string>
<string name="all_details">Detale</string>
<string name="all_category">Kategòrijô</string>
<string name="all_close">Zamkni</string>
<string name="all_no_data">Ni ma danëch</string>
<string name="all_subject">Témat</string>
<string name="all_prev">Slédny</string>
<string name="all_next">Pòstãpny</string>
<string name="all_search">Szëkôj</string>
<string name="all_search_hint">Szëkôj…</string>
<string name="all_yes">Jo</string>
<string name="all_no">Nié</string>
<string name="all_save">Zapiszë</string>
<string name="all_title">Titel</string>
<string name="all_add">Dodôj</string>
<string name="all_copied">Òstało skòpiérowóné</string>
<string name="all_undo">Cofni</string>
<string name="all_change">Zmieni</string>
<string name="all_add_to_calendar">Dodôj do kaléndarzu</string>
<string name="all_cancel">Anuluj</string>
<!--Timetable Widget-->
<string name="widget_timetable_no_items">Ni ma ùczbów</string>
<string name="widget_timetable_last_synchronization">Zsynchronizowóno %1$s ò %2$s</string>
<string name="widget_timetable_theme_title">Wëbierzë témã</string>
<string name="widget_timetable_theme_light">Jôsny</string>
<string name="widget_timetable_theme_dark">Cemny</string>
<string name="widget_timetable_theme_system">Systemòwô téma</string>
<!--Preferences-->
<string name="pref_view_header">Aplikacëjô</string>
<string name="pref_view_list">Domëslny pòzdrzatk</string>
<string name="pref_view_grade_average_mode">Nastôwë òbliczony strzédny</string>
<string name="pref_view_grade_average_force_calc">Wëmùszë òbliczenié strzédny bez aplikacëją</string>
<string name="pref_view_present">Pòkôżë bëtnosc</string>
<string name="pref_attendance_target">Docélowô bëtnosc</string>
<string name="pref_attendance_calculator_show_empty_subjects">Pòkôżë témë bez frekwencji</string>
<string name="pref_view_attendance_calculator_sorting_mode">Zortowanié kalkulatora bëtnoscë</string>
<string name="pref_view_app_theme">Téma</string>
<string name="pref_view_expand_grade">Rozwijanié taksów</string>
<string name="pref_view_timetable_show_groups">Pòkazuj karno kòl zajmë</string>
<string name="pref_view_timetable_show_additional_lessons">Pòkôżë dodatkòwé ùczbë</string>
<string name="pref_view_timetable_show_gaps">Pòkôzuj pùsté kachle gdze ni ma ùczbów</string>
<string name="pref_view_grade_statistics_list">Pòkôżë lëstã nacéchùnków w klasowich taksach</string>
<string name="pref_view_subjects_without_grades">Pòkôżë zajmë bez taksów</string>
<string name="pref_view_grade_color_scheme">Schemat farwów taksów</string>
<string name="pref_view_grade_sorting_mode">Zortowanié zajmów</string>
<string name="pref_view_app_language">Jãzëk</string>
<string name="pref_view_menu_order_title">Kònfigùracëjô menu</string>
<string name="pref_view_menu_order_summary">Ùstôw kòlejnosc fónkcëje w menu</string>
<string name="pref_notify_header">Wiadła</string>
<string name="pref_notify_header_other">Jiné</string>
<string name="pref_notify_switch">Pòkôżë wiadła</string>
<string name="pref_notify_upcoming_lessons_switch">Pòkôżë wiadła ò przińdłich ùczbach</string>
<string name="pref_notify_upcoming_lessons_persistent_switch">Ùstawi wiadło ò przińdłi ùczbie jakò trwałé</string>
<string name="pref_notify_upcoming_lessons_persistent_summary">Wëłączë ga wiadła nie pòkazëją sã na twòjim zégarkù/òpasce</string>
<string name="pref_notify_open_system_settings">Òdemkô systemòwé nastôwë wiadłów</string>
<string name="pref_notify_fix_sync_issues">Naprawi tôkle z synchronizacëją i wiadłama</string>
<string name="pref_notify_fix_sync_issues_message">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ù.</string>
<string name="pref_notify_debug_switch">Pòkôżë debùgòwanié wiadła</string>
<string name="pref_notify_disabled_summary">Synchronizacja je wëłączonô</string>
<string name="pref_notify_notifications_piggyback_header">Wiadła òficjalny aplikacëje</string>
<string name="pref_notify_notifications_piggyback">Przechwatiwanié wiadłów òficjalny aplikacëje</string>
<string name="pref_notify_notifications_piggyback_cancel_original">Rëmni wiadła òficjalny aplikacëje pò przechwôceniu</string>
<string name="pref_notification_piggyback_popup_title">Przechwatiwanié wiadłów</string>
<string name="pref_notification_piggyback_popup_description">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</string>
<string name="pref_notification_exact_alarm_popup_title">Wiadła ò przińdłich ùczbach</string>
<string name="pref_notification_exact_alarm_popup_descriptions">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.</string>
<string name="pref_notification_go_to_settings">Jidzë do nastôwów</string>
<string name="pref_services_header">Synchronizacja</string>
<string name="pref_services_switch">Automaticznô aktulizacëja</string>
<string name="pref_services_suspended">Wstrzëmónô òbczas wakacjów</string>
<string name="pref_services_interval">Jinterwôł aktualizacëjów</string>
<string name="pref_services_wifi">Leno Wi-Fi</string>
<string name="pref_services_force_sync">Synchronizuj terô</string>
<string name="pref_services_message_sync_success">Zsynchronizowóno!</string>
<string name="pref_services_message_sync_failed">Synchronizacëjô sã nié ùda</string>
<string name="pref_services_sync_in_progress">Synchronizacëjô w tokù</string>
<string name="pref_services_last_full_sync_date">Òstatniô fùl synchronizacëjô: %s</string>
<string name="pref_other_grade_modifier_plus">Wôrtnosc plusa</string>
<string name="pref_other_grade_modifier_minus">Wôrtnosc minusa</string>
<string name="pref_other_fill_message_content">Òdpòwiadôj z historëją wiadów</string>
<string name="pref_other_optional_arithmetic_average">Licz strzédną aritmeticzną, ga niżôdnô taksa ni ma wôdżi</string>
<string name="pref_other_incognito_mode">Trib incognito</string>
<string name="pref_other_incognito_mode_summary">Nie jinfòrmùj ò przeczëtaniu wiadë</string>
<string name="pref_ads_support_category_name">Wspiarcé</string>
<string name="pref_ads_privacy_policy">Pòlitëka priwatnoscë</string>
<string name="pref_ads_agreements">Zgòdë</string>
<string name="pref_ads_consent">Pòkôżë zgòdã na òbrabianié danëch</string>
<string name="pref_ads_show_in_app">Pòkôżë reklamë w aplikacëje</string>
<string name="pref_ads_support">Òbezdrzë jedurną reklamã, bë wesprzec projekt</string>
<string name="pref_ads_privacy_title">Zgòdã na przerôbianié danëch</string>
<string name="pref_ads_privacy_description">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ë</string>
<string name="pref_ads_privacy_agree">Zgôdzóm sã</string>
<string name="pref_ads_privacy_link">Pòlitëka priwatnoscë</string>
<string name="pref_ads_loading">Reklama sã ładuje</string>
<string name="pref_ads_once_per_visit">Dzãkùjemë za wspiarcé, wrócë pózdni pò wicy reklamów</string>
<string name="pref_settings_advanced_title">Zaawansowóné</string>
<string name="pref_settings_appearance_title">Wëzdrzatk i zachòwanié</string>
<string name="pref_settings_notifications_title">Wiadła</string>
<string name="pref_settings_sync_title">Synchronizacëjô</string>
<string name="pref_settings_ads_title">Reklamë</string>
<string name="pref_grades_appearance_header">Taksë</string>
<string name="pref_dashboard_appearance_header">Doma</string>
<string name="pref_dashboard_appearance_tiles_title">Widocznosc kachlów</string>
<string name="pref_attendance_appearance_view">Frekwencjô</string>
<string name="pref_attendance_calculator_appearance_view">Kalkùlator frekwencëje</string>
<string name="pref_attendance_calculator_appearance_settings_title">Nastôwë</string>
<string name="pref_timetable_appearance_view">Plan zajmów</string>
<string name="pref_grades_advanced_header">Taksë</string>
<string name="pref_counted_average_advanced_header">Òbliczonô strzédna</string>
<string name="pref_messages_advanced_header">Wiadë</string>
<string name="pref_appearance_category">Wëzdrzatk i zachòwanié</string>
<string name="pref_appearance_category_summary">Jãzëczi, témë, zortowanié témów</string>
<string name="pref_notifications_category_summary">Wiadła aplikacëje, naprawianié tôklów</string>
<string name="pref_notifications_category">Wiadła</string>
<string name="pref_sync_category">Synchronizacëjô</string>
<string name="pref_sync_category_summary">Aùtomaticznô aktualizacëjô, jinterwôł synchronizacëje</string>
<string name="pref_advanced_category_summary">Wôrtnoscë plusa i minusa, òbliczanié strzédny</string>
<string name="pref_advanced_category">Zaawansowóné</string>
<string name="pref_about_category_summary">Wersëjô aplikacëje, twórcë, spòlëznowé media</string>
<string name="pref_ads_category_summary">Wëswietlanié reklamów, wspiarcé projektu</string>
<!--Notification Channels-->
<string name="channel_new_grades">Nowé taksë</string>
<string name="channel_new_homework">Nowé zadanié dodóm</string>
<string name="channel_new_conference">Nowé zéńdzenia</string>
<string name="channel_new_exam">Nowé testë</string>
<string name="channel_lucky_number">Szczestlëwi numerk</string>
<string name="channel_new_message">Nowé wiadë</string>
<string name="channel_new_notes">Nowé ùwôdżi</string>
<string name="channel_new_school_announcement">Nowé szkòlowé ògłosë</string>
<string name="channel_push">Wiadła push</string>
<string name="channel_upcoming_lessons">Przińdłé ùczbë</string>
<string name="channel_debug">Debùgòwanié</string>
<string name="channel_change_timetable">Pòzmianë planu zajmów</string>
<string name="channel_new_attendance">Nowô frekwencjô</string>
<!--Colors-->
<string name="all_black">Czôrny</string>
<string name="all_red">Czerwiony</string>
<string name="all_blue">Mòdri</string>
<string name="all_green">Zelony</string>
<string name="all_purple">Lilewi</string>
<string name="all_empty_color">Felënk farwë</string>
<!--Update helper-->
<string name="update_download_started">Ładowanié aktualizacëje òstało zôczãté…</string>
<string name="update_download_success">Aktualizacëjô prawie òsta załadowónô.</string>
<string name="update_download_success_button">Restartuj</string>
<string name="update_failed">Aktualizacëjô sã nié pòwiodła! Wùlkanowi mòże nie dzejac richtic. Rozważë aktualizacëjã</string>
<!--Menu order-->
<string name="menu_order_confirm_title">Restartuj aplikacëjã</string>
<string name="menu_order_confirm_content">Żebë zmianë sã zapisałë, aplikacëjô mùszi sã zrestartowac</string>
<string name="menu_order_confirm_restart">Restartuj</string>
<!--Auth-->
<string name="auth_api_error">Autorizacëjô òsta òdrzëconô. Dane chtërne bëłë dóné są niezgòdné z danyma w sekretariace.</string>
<string name="auth_invalid_error">Złi PESEL</string>
<string name="auth_pesel">PESEL</string>
<string name="auth_button">Pòcwierdzë</string>
<string name="auth_success">Autorizacëjô skùńczonô z sukcesã</string>
<string name="auth_title">Autorizacëjô</string>
<string name="auth_description">Drodżi Rodzëcu,&lt;br /&gt;&lt;br /&gt;Żebë pòcwierdzëc a zagwësnic bezpiek dónëch, prosëmë ò wpisanié niżi numru PESEL ùczni &lt;b&gt;%1$s&lt;/b&gt;. 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Ù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.&lt;br /&gt;&lt;br /&gt;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.</string>
<string name="auth_button_skip">Timczasã pòmiń</string>
<!--Captcha-->
<string name="captcha_dialog_title">Starna dzénnika VULCAN wëmôga werëfikacëji</string>
<string name="captcha_dialog_description"><b>Dlôcze to widzã?</b>\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</string>
<string name="captcha_verified_message">Zwerëfikòwóno z sukcesã</string>
<!--Panic mode-->
<string name="panic_mode_title">Awarëjné dostãp</string>
<!--Errors-->
<string name="error_no_internet">Felënk sparłãczëniô z jinternetã</string>
<string name="error_invalid_device_datetime">Wëstąpił błãd. Sprôwdzë twòji ùrządzenia</string>
<string name="error_account_inactive">Kònto je niéaktywné. Spróbùj zalogòwac sã pònowno</string>
<string name="error_timeout">Nie ùdało sã sparłãczëc z dzénnika. Serwerë mògą bëc przecyżoné. Spróbùj pònowno pózdni</string>
<string name="error_login_failed">Ładowanié pòdôwków skùńczoné niezdarã. Proszã spróbòwac znowù pòzdze</string>
<string name="error_password_invalid">Twòjô parola zgôsłô abò òsta zmienionô. Zalogùj sã pònowno</string>
<string name="error_password_change_required">Wëmôgô zmienic parolã do dzénnika</string>
<string name="error_service_unavailable">Trwô technicznô przerwa dzénnika UONET+. Spróbùj pònowno pózdni</string>
<string name="error_unknown_uonet">Nieznóné błãd dzénnika UONET+. Spróbùj znowù pòzdze</string>
<string name="error_unknown_app">Nieznóné błãd aplikacëji. Proszã spróbòwac znowù pòzdze</string>
<string name="error_cloudflare_captcha">Brekòwóna werëfikacëja captcha</string>
<string name="error_unknown">Wëstąpił nieżdónié błãd</string>
<string name="error_feature_disabled">Funkcëjô je wëłączona przez twòją szkòłã</string>
<string name="error_feature_not_available">Funkcëjô nie je dostąpnô. Zalogùj sã w jinszim tribie nigle Móbilné API</string>
<string name="error_field_required">To pòle je brekòwané</string>
<!-- Mute system -->
<string name="message_mute">Wëcëszenié</string>
<string name="message_unmute">Wëłączë wëcëszenié</string>
<string name="message_mute_success">Wëcësził jes tegò brëkòwnika</string>
<string name="message_unmute_success">Wëłącził jes wëcëszenié tegò brëkòwnika</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br /&gt;&lt;br /&gt;Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href=\"https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl\"&gt;Dzienniczek VULCAN&lt;/a&gt;. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -19,6 +19,7 @@
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 Minuten</item>

View File

@ -778,6 +778,8 @@
<string name="captcha_dialog_title">VULCAN\'s Website erfordert Überprüfung</string>
<string name="captcha_dialog_description"><b>Warum sehe ich das?</b>\nDie Website des Registers, von der Wulkanowy Daten herunterlädt, zeigt denselben Bildschirm wie oben an, so dass Wulkanowy ihn ebenfalls anzeigen muss, um Daten von dieser Website herunterladen zu können. Es gibt keinen Ausweg</string>
<string name="captcha_verified_message">Erfolgreich verifiziert</string>
<!--Panic mode-->
<string name="panic_mode_title">Notfallzugriff</string>
<!--Errors-->
<string name="error_no_internet">Keine Internetverbindung</string>
<string name="error_invalid_device_datetime">Es ist ein Fehler aufgetreten. Überprüfen Sie Ihre Geräteuhr</string>
@ -799,4 +801,7 @@
<string name="message_unmute">Stummschaltung aufheben</string>
<string name="message_mute_success">Sie haben diesen Benutzer stummgeschaltet</string>
<string name="message_unmute_success">Sie haben die Stummschaltung dieses Benutzers aufgehoben</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br /&gt;&lt;br /&gt;Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href=\"https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl\"&gt;Dzienniczek VULCAN&lt;/a&gt;. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -19,6 +19,7 @@
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 minut</item>

View File

@ -872,6 +872,8 @@
<string name="captcha_dialog_title">Strona dziennika VULCAN wymaga weryfikacji</string>
<string name="captcha_dialog_description"><b>Dlaczego to widzę?</b>\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ść</string>
<string name="captcha_verified_message">Pomyślnie zweryfikowano</string>
<!--Panic mode-->
<string name="panic_mode_title">Dostęp awaryjny</string>
<!--Errors-->
<string name="error_no_internet">Brak połączenia z internetem</string>
<string name="error_invalid_device_datetime">Wystąpił błąd. Sprawdź poprawność daty w urządzeniu</string>
@ -893,4 +895,7 @@
<string name="message_unmute">Wyłącz wyciszenie</string>
<string name="message_mute_success">Wyciszyleś tego użytkownika</string>
<string name="message_unmute_success">Wyłączyłeś wyciszenie tego użytkownika</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br /&gt;&lt;br /&gt;Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href=\"https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl\"&gt;Dzienniczek VULCAN&lt;/a&gt;. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="sort_alphabetically">Alphabetically</string>
<string name="sort_by_date">By date</string>
<string name="sort_by_average">By average</string>
<string name="sort_by_attendance_percentage">By attendance percentage</string>
<string name="sort_by_subject_attendance_balance">By subject attendance balance</string>
<string name="sort_alphabetically">По алфавиту</string>
<string name="sort_by_date">По дате</string>
<string name="sort_by_average">По средней</string>
<string name="sort_by_attendance_percentage">Согласно проценту посещаемости</string>
<string name="sort_by_subject_attendance_balance">Согласно балансу посещаемости уроков</string>
<string-array name="app_theme_entries" tools:ignore="InconsistentArrays">
<item>Светлая</item>
<item>Тёмная</item>
@ -19,6 +19,7 @@
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 минут</item>
@ -52,14 +53,14 @@
<item>Средняя из оценок со всего года</item>
</string-array>
<string-array name="timetable_show_gaps_entries">
<item>Don\'t show</item>
<item>Only between lessons</item>
<item>Before and between lessons</item>
<item>Не показывать</item>
<item>Только между уроками</item>
<item>Перед и между уроками</item>
</string-array>
<string-array name="timetable_show_additional_lessons_entries">
<item>Don\'t show</item>
<item>Show inline</item>
<item>Show below regular lessons</item>
<item>Не показывать</item>
<item>Показать в строке</item>
<item>Показать ниже обычных уроков</item>
</string-array>
<string-array name="dashboard_tile_entries">
<item>Счастливый номер</item>

View File

@ -13,7 +13,7 @@
<string name="logviewer_title">Просмотр журнала</string>
<string name="debug_title">Отладка</string>
<string name="notification_debug_title">Отладка уведомлений</string>
<string name="debug_cookies_clear">Clear webview cookies</string>
<string name="debug_cookies_clear">Очистить файлы cookie</string>
<string name="contributors_title">Разработчики</string>
<string name="license_title">Лицензии</string>
<string name="message_title">Сообщения</string>
@ -38,14 +38,14 @@
<string name="login_login_pesel_email_hint">Логин, PESEL или электронная почта</string>
<string name="login_password_hint">Пароль</string>
<string name="login_host_hint">Тип дневника UONET+</string>
<string name="login_domain_suffix_hint">Custom domain suffix</string>
<string name="login_domain_suffix_hint">Пользовательский суффикс домена</string>
<string name="login_type_api">Мобильный API</string>
<string name="login_type_scrapper">Scraper</string>
<string name="login_type_hybrid">Hybrid</string>
<string name="login_token_hint">Token</string>
<string name="login_pin_hint">PIN</string>
<string name="login_symbol_hint">Symbol</string>
<string name="login_symbol_placeholder">E.g. \"lodz\" or \"powiatjaroslawski\"</string>
<string name="login_symbol_placeholder">Например: \"lodz\" или \"powiatjaroslawski\"</string>
<string name="login_sign_in">Войти</string>
<string name="login_invalid_password">Пароль слишком короткий</string>
<string name="login_incorrect_password_default">Данные для входа указаны неверно</string>
@ -56,9 +56,9 @@
<string name="login_invalid_email">Неверный e-mail</string>
<string name="login_invalid_login">Используйте назначенный логин вместо e-mail</string>
<string name="login_invalid_custom_email">Используйте назначенный логин или email в @%1$s</string>
<string name="login_invalid_domain_suffix">Invalid domain suffix</string>
<string name="login_invalid_symbol">Invalid symbol. If you cannot find it, please contact the school</string>
<string name="login_invalid_symbol_definitely">Don\'t make this up! If you cannot find it, please contact the school</string>
<string name="login_invalid_domain_suffix">Недопустимый суффикс домена</string>
<string name="login_invalid_symbol">Неверный символ. Если вы не можете найти символ, пожалуйста, свяжитесь со школой</string>
<string name="login_invalid_symbol_definitely">Неверный символ. Если вы не можете найти символ, пожалуйста, свяжитесь со школой</string>
<string name="login_incorrect_symbol">Ученик не найден. Проверьте symbol и выбранный тип дненика UONET+</string>
<string name="login_duplicate_student">Данный ученик уже авторизован</string>
<string name="login_symbol_helper">Symbol можно найти на странице регистрации в &#160;<b>Uczeń</b> →&#160;<b>Dostęp Mobilny</b>&#160;<b>Wygeneruj kod dostępu</b>.\n\nУбедитесь, что вы выбрали соответствующий тип дневника в поле <b>Тип дневника UONET+</b> на первом экране входа</string>
@ -73,7 +73,7 @@
<string name="login_contact_discord">Discord</string>
<string name="login_email_intent_title">Отправить письмо</string>
<string name="login_recover_warning">Убедитесь, что вы выбрали правильный тип дневника UONET+</string>
<string name="login_recover_button">Reset password</string>
<string name="login_recover_button">Сбросить пароль</string>
<string name="login_recover_title">Восстановите свой аккаунт</string>
<string name="login_recover">Восстановить</string>
<string name="login_signed_in">Ученик уже авторизован</string>
@ -81,13 +81,13 @@
<string name="login_other_search_locations">Другие места поиска</string>
<string name="login_no_active_student">Не найдено активных учеников</string>
<string name="login_symbol_enter">Введите другой symbol</string>
<string name="login_support_title">Get help</string>
<string name="login_support_school_hint">Full school name with the town (required)</string>
<string name="login_support_school_placeholder">Np. ZSTiO Jarosław lub SP nr 99 w Łodzi</string>
<string name="login_support_school_invalid">Enter correct name of the school</string>
<string name="login_support_additional_hint">Additional information in Polish (optional)</string>
<string name="login_support_additional_placeholder">Np. \"Ostatnio zmieniłem szkołę i…\" albo \"Jestem rodzicem i nie widzę drugiego dziecka…\"</string>
<string name="login_support_submit">Submit</string>
<string name="login_support_title">Помощь</string>
<string name="login_support_school_hint">Полное название школы с городом (обязательно)</string>
<string name="login_support_school_placeholder">Например: ZSTiO Jarosław или SP nr 99 w Łodzi</string>
<string name="login_support_school_invalid">Введите правильное название школы</string>
<string name="login_support_additional_hint">Дополнительная информация на польском языке (опционально)</string>
<string name="login_support_additional_placeholder">Например: \"Ostatnio zmieniłem szkoł i…\" или \"Jestem rodzicem i nie widz drugiego dziecka…\"</string>
<string name="login_support_submit">Отправить</string>
<!--Notifications-->
<string name="notifications_header_title">Включить уведомления</string>
<string name="notifications_header_description">Включить уведомления, чтобы вы не пропустили сообщение от учителя или новую оценку</string>
@ -98,8 +98,8 @@
<string name="main_log_in">Войти</string>
<string name="main_session_expired">Сеанс истёк</string>
<string name="main_session_relogin">Сеанс истёк, авторизуйтесь снова</string>
<string name="main_expired_credentials_title">Password has expired or been changed</string>
<string name="main_expired_credentials_description">Your account password has expired or been changed. You will need to log in to Wulkanowy again</string>
<string name="main_expired_credentials_title">Срок действия пароля истек или был изменен</string>
<string name="main_expired_credentials_description">Пароль вашей учетной записи устарел или был изменен. Вам нужно будет войти в Wulkanowy снова</string>
<string name="main_support_title">Поддержка приложения</string>
<string name="main_support_description">Вам нравится это приложение? Поддержите его разработку, включив неинвазивную рекламу, которую можно отключить в любое время</string>
<string name="main_support_positive">Включить рекламу</string>
@ -113,17 +113,17 @@
<string name="grade_comment">Комментарий</string>
<string name="grade_number_new_items">Количество новых оценок: %1$d</string>
<string name="grade_average">Средняя оценка: %1$.2f</string>
<string name="grade_average_year">Annual: %1$.2f</string>
<string name="grade_average_year">Годовое: %1$.2f</string>
<string name="grade_points_sum">Баллы: %s</string>
<string name="grade_no_average">Нет средней оценки</string>
<string name="grade_summary_average_semester">Semester average</string>
<string name="grade_summary_average_year">Annual average</string>
<string name="grade_summary_average_semester">Средняя семестра</string>
<string name="grade_summary_average_year">Средняя годовой</string>
<string name="grade_summary_points">Сумма баллов</string>
<string name="grade_summary_final_grade">Итоговая оценка</string>
<string name="grade_summary_predicted_grade">Ожидаемая оценка</string>
<string name="grade_summary_descriptive">Descriptive grade</string>
<string name="grade_summary_calculated_average">Calculated semester average</string>
<string name="grade_summary_calculated_average_annual">Calculated annual average</string>
<string name="grade_summary_descriptive">Описательная оценка</string>
<string name="grade_summary_calculated_average">Рассчитанная средняя семестра</string>
<string name="grade_summary_calculated_average_annual">Рассчитанная средняя оценка</string>
<string name="grade_summary_calculated_average_help_dialog_title">Как работает \"Рассчитанная средняя оценка\"?</string>
<string name="grade_summary_calculated_average_help_dialog_message">Рассчитанная средняя оценка - это среднее арифметическое, рассчитанное на основе средних оценок по предметам. Это позволяет узнать приблизительную итоговую среднюю оценку. Она рассчитывается способом, выбранным пользователем в настройках приложения. Рекомендуется выбрать подходящий вариант, так как каждая школа по разному считает среднюю оценку. Кроме того, если ваша школа выставляет средние оценки по предметам на странице Vulcan, приложение просто загрузит их. Это можно изменить, заставив приложение считать среднюю оценку в настройках.\n\n<b>Средняя из оценок выбранного семестра</b>:\n1. Вычисление средневзвешенного значения по каждому предмету за семестр\n2.Суммирование вычисленных значений\n3. Вычисление среднего арифметического суммированных значений\n\n<b>Средняя из средних оценок семестров</b>:\n1.Расчет средневзвешенного значения для каждого предмета в семестрах. \n2. Вычисление среднего арифметического из средневзвешенных значений для каждого предмета в семестрах.\n3. Суммирование средних арифметических\n4. Вычисление среднего арифматического из суммированных значений\n\n<b>Средняя из оценок со всего года:</b>\n1. Расчет средневзвешенного значения по каждому предмету за год. Итоговое среднее значение за 1 семестр не имеет значения.\n2. Суммирование вычисленных средних\n3. Расчет среднего арифметического суммированных чисел</string>
<string name="grade_summary_final_average_help_dialog_title">Как работает \"Итоговая средняя оценка\"?</string>
@ -167,10 +167,10 @@
<item quantity="other">Новые итоговые оценки</item>
</plurals>
<plurals name="grade_new_items_descriptive">
<item quantity="one">New descriptive grade</item>
<item quantity="few">New descriptive grades</item>
<item quantity="many">New descriptive grades</item>
<item quantity="other">New descriptive grades</item>
<item quantity="one">Новая описательная оценка</item>
<item quantity="few">Новые описательные оценки</item>
<item quantity="many">Новые описательные оценки</item>
<item quantity="other">Новые описательные оценки</item>
</plurals>
<plurals name="grade_notify_new_items">
<item quantity="one">Вы получили %1$d новую оценку</item>
@ -191,14 +191,14 @@
<item quantity="other">Вы получили %1$d новых итоговые оценки</item>
</plurals>
<plurals name="grade_notify_new_items_descriptive">
<item quantity="one">You received %1$d descriptive grade</item>
<item quantity="few">You received %1$d descriptive grades</item>
<item quantity="many">You received %1$d descriptive grades</item>
<item quantity="other">You received %1$d descriptive grades</item>
<item quantity="one">Вы получили %1$d новую описательную оценку</item>
<item quantity="few">Вы получили %1$d новых описательных оценок</item>
<item quantity="many">Вы получили %1$d новых описательных оценок</item>
<item quantity="other">Вы получили %1$d новых описательных оценок</item>
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Урок</string>
<string name="timetable_additional_lesson">Additional lesson</string>
<string name="timetable_additional_lesson">Дополнительный урок</string>
<string name="timetable_room">Аудитория</string>
<string name="timetable_group">Группа</string>
<string name="timetable_time">Часы</string>
@ -217,10 +217,10 @@
<string name="timetable_notify_change_teacher">Учитель изменён с %1$s на %2$s</string>
<string name="timetable_notify_change_subject">Тема изменена с %1$s на %2$s</string>
<plurals name="timetable_no_lesson">
<item quantity="one">No lesson</item>
<item quantity="few">No lessons</item>
<item quantity="many">No lessons</item>
<item quantity="other">No lessons</item>
<item quantity="one">Нет урока</item>
<item quantity="few">Нет урока</item>
<item quantity="many">Нет урока</item>
<item quantity="other">Нет урока</item>
</plurals>
<plurals name="timetable_notify_new_items_title">
<item quantity="one">Изменение расписания</item>
@ -270,12 +270,12 @@
<string name="additional_lessons_end_time_error">Время окончания должно быть больше, чем время начала</string>
<!--Attendance-->
<string name="attendance_summary_button">Итоговая посещаемость</string>
<string name="attendance_calculator_button">Attendance calculator</string>
<string name="attendance_calculator_summary_balance_positive"><b>%1$d</b> over target</string>
<string name="attendance_calculator_summary_balance_neutral">right on target</string>
<string name="attendance_calculator_summary_balance_negative"><b>%1$d</b> under target</string>
<string name="attendance_calculator_summary_values">%1$d/%2$d presences</string>
<string name="attendance_calculator_summary_values_empty">No attendances recorded</string>
<string name="attendance_calculator_button">Калькулятор посещаемости</string>
<string name="attendance_calculator_summary_balance_positive"><b>%1$d</b> выше нормы</string>
<string name="attendance_calculator_summary_balance_neutral">является нормой</string>
<string name="attendance_calculator_summary_balance_negative"><b>%1$d</b> выше нормы</string>
<string name="attendance_calculator_summary_values">%1$d/%2$d посещаемостей</string>
<string name="attendance_calculator_summary_values_empty">Нет зарегистрированных участников</string>
<string name="attendance_absence_school">Отсутствие по школьным причинам</string>
<string name="attendance_absence_excused">Отсутствие по уважительной причине</string>
<string name="attendance_absence_unexcused">Отсутствие по неуважительной причине</string>
@ -347,10 +347,10 @@
<string name="message_forward">Переслать</string>
<string name="message_select_all">Выбрать все</string>
<string name="message_unselect_all">Отменить выбор</string>
<string name="message_restore_from_trash">Restore from trash</string>
<string name="message_restore_from_trash">Восстановить из корзины</string>
<string name="message_move_to_trash">Перенести в корзину</string>
<string name="message_delete_forever">Удалить навсегда</string>
<string name="message_restore_success">Message restored successfully</string>
<string name="message_restore_success">Сообщение успешно восстановлено</string>
<string name="message_delete_success">Сообщение успешно удалено</string>
<string name="message_mailbox_type_student">ученик</string>
<string name="message_mailbox_type_parent">родитель</string>
@ -396,10 +396,10 @@
<item quantity="other">%1$d выбрано</item>
</plurals>
<string name="message_messages_deleted">Сообщение удалено</string>
<string name="message_messages_restored">Messages restored</string>
<string name="message_messages_restored">Сообщения восстановлены</string>
<string name="message_mailbox_chooser_title">Выбрать почтовый ящик</string>
<string name="message_incognito_mode_on">Incognito mode is on</string>
<string name="message_incognito_description">Thanks to incognito mode sender is not notified when you read the message</string>
<string name="message_incognito_mode_on">Режим инкогнито включен</string>
<string name="message_incognito_description">Благодаря режиму инкогнито отправитель не уведомлен о прочтении сообщения</string>
<!--Note-->
<string name="note_no_items">Нет записей о замечаниях и свершениях</string>
<string name="note_points">Баллы</string>
@ -742,14 +742,14 @@
<string name="pref_view_grade_average_mode">Параметры расчёта средних оценок</string>
<string name="pref_view_grade_average_force_calc">Принудительно высчитать среднюю оценку через приложение</string>
<string name="pref_view_present">Показывать присутствия</string>
<string name="pref_attendance_target">Attendance target</string>
<string name="pref_attendance_calculator_show_empty_subjects">Show subjects without any attendances</string>
<string name="pref_view_attendance_calculator_sorting_mode">Attendance calculator sorting</string>
<string name="pref_attendance_target">Норма посещаемости</string>
<string name="pref_attendance_calculator_show_empty_subjects">Показать предметы без посещаемостей</string>
<string name="pref_view_attendance_calculator_sorting_mode">Сортировка рассчитанных посещаемостей</string>
<string name="pref_view_app_theme">Тема</string>
<string name="pref_view_expand_grade">Разворачивание оценок</string>
<string name="pref_view_timetable_show_groups">Показать группы рядом с темами</string>
<string name="pref_view_timetable_show_additional_lessons">Show additional lessons</string>
<string name="pref_view_timetable_show_gaps">Show empty tiles where there\'s no lesson</string>
<string name="pref_view_timetable_show_additional_lessons">Показать дополнительные уроки</string>
<string name="pref_view_timetable_show_gaps">Показать пустые поля, где нет уроков</string>
<string name="pref_view_grade_statistics_list">Показывать диаграммы в оценках класса</string>
<string name="pref_view_subjects_without_grades">Показать предметы без оценок</string>
<string name="pref_view_grade_color_scheme">Цветовая схема оценок</string>
@ -790,12 +790,12 @@
<string name="pref_other_grade_modifier_minus">Стоимость минуса</string>
<string name="pref_other_fill_message_content">Отвечать с историей сообщений</string>
<string name="pref_other_optional_arithmetic_average">Показывать среднее арифметическое при отсутствии стоимости</string>
<string name="pref_other_incognito_mode">Incognito mode</string>
<string name="pref_other_incognito_mode_summary">Do not inform about reading the message</string>
<string name="pref_other_incognito_mode">Режим инкогнито</string>
<string name="pref_other_incognito_mode_summary">Не сообщать о чтении сообщения</string>
<string name="pref_ads_support_category_name">Поддержка</string>
<string name="pref_ads_privacy_policy">Политика приватности</string>
<string name="pref_ads_agreements">Соглашения</string>
<string name="pref_ads_consent">Show consent to data processing</string>
<string name="pref_ads_consent">Показать согласие на обработку данных</string>
<string name="pref_ads_show_in_app">Показать рекламу в приложении</string>
<string name="pref_ads_support">Посмотреть рекламу для поддержки проекта</string>
<string name="pref_ads_privacy_title">Согласие на обработку данных</string>
@ -813,8 +813,8 @@
<string name="pref_dashboard_appearance_header">Главная</string>
<string name="pref_dashboard_appearance_tiles_title">Видимость плиток</string>
<string name="pref_attendance_appearance_view">Посещаемость</string>
<string name="pref_attendance_calculator_appearance_view">Attendance calculator</string>
<string name="pref_attendance_calculator_appearance_settings_title">Settings</string>
<string name="pref_attendance_calculator_appearance_view">Калькулятор посещаемости</string>
<string name="pref_attendance_calculator_appearance_settings_title">Настройки</string>
<string name="pref_timetable_appearance_view">Расписание</string>
<string name="pref_grades_advanced_header">Оценки</string>
<string name="pref_counted_average_advanced_header">Рассчитанная средняя оценка</string>
@ -866,31 +866,36 @@
<string name="auth_button">Авторизовать</string>
<string name="auth_success">Авторизация прошла успешно</string>
<string name="auth_title">Авторизация</string>
<string name="auth_description">Dear Parent,&lt;br /&gt;&lt;br /&gt;To authorize and ensure the security of data, we kindly ask you to enter below PESEL number of student &lt;b&gt;%1$s&lt;/b&gt;. These details are essential for the proper assignment of access and protection of personal data in accordance with applicable regulations.&lt;br /&gt;&lt;br /&gt;After entering the data, it will be verified to ensure that access to the VULCAN system is granted exclusively to authorized individuals. Should you have any doubts or problems, please contact the school diary administrator to clarify the situation.&lt;br /&gt;&lt;br /&gt;We maintain the highest standards of personal data protection and ensure that all information provided is secure. Wulkanowy app does not store or process the PESEL number.&lt;br /&gt;&lt;br /&gt;We remind you that providing full and accurate data is mandatory and necessary for the use of the VULCAN system.</string>
<string name="auth_description">Уважаемый родитель,&lt;br /&gt;&lt;br /&gt;для авторизации и обеспечения безопасности данных, просим Вас ввести ниже номер PESEL &lt;b&gt;%1$s&lt;/b&gt;. Эти данные необходимы для надлежащего доступа к и защиты личных данных в соответствии с действующими нормами.&lt;br /&gt;&lt;br /&gt;После ввода данных мы обеспечим проверку, чтобы доступ к системе VULCAN был предоставлен исключительно уполномоченным лицам. Если у Вас возникли какие-либо сомнения или проблемы, пожалуйста, свяжитесь с администратором школьного дневника для уточнения ситуации.&lt;br /&gt;&lt;br /&gt;Мы соблюдаем наивысшие стандарты защиты персональных данных и гарантируем сохранность всей информации. Приложение Wulkanowy не сохраняет и не обрабатывает номер PESEL.&lt;br /&gt;&lt;br /&gt;Напоминаем, что предоставление точных данных является обязательным и необходимым для использования системы VULCAN.</string>
<string name="auth_button_skip">Пропустить сейчас</string>
<!--Captcha-->
<string name="captcha_dialog_title">VULCAN\'s website requires verification</string>
<string name="captcha_dialog_description"><b>Why am I seeing this?</b>\nThe register website from which Wulkanowy downloads data displays the same screen as above, so Wulkanowy must also show it to be able to download data from this website. There\'s no way around it</string>
<string name="captcha_verified_message">Verified successfully</string>
<string name="captcha_dialog_title">Требуется верификация веб-сайта VULCAN</string>
<string name="captcha_dialog_description"><b>Почему я это вижу?</b>\n Веб-сайт регистрации, с которого Wulkanowy загружает данные, отображает тот же экран, что и выше, поэтому Wulkanowy также должен показать его, чтобы иметь возможность загружать данные с этого веб-сайта. Нет никакого способа обойти это</string>
<string name="captcha_verified_message">Верификация успешна</string>
<!--Panic mode-->
<string name="panic_mode_title">Экстренный доступ</string>
<!--Errors-->
<string name="error_no_internet">Интернет-соединение отсутствует</string>
<string name="error_invalid_device_datetime">Произошла ошибка. Проверьте время на вашем устройстве</string>
<string name="error_account_inactive">This account is inactive. Try logging in again</string>
<string name="error_account_inactive">Эта учетная запись неактивна. Попробуйте войти снова</string>
<string name="error_timeout">Не удалось подключиться к дневнику. Возможно, сервера перегружены, повторите попытку позже</string>
<string name="error_login_failed">Не удалось загрузить данные, повторите попытку позже</string>
<string name="error_password_invalid">Your password has expired or been changed. Please log in again</string>
<string name="error_password_invalid">Ваш пароль устарел или был изменен. Пожалуйста, войдите снова</string>
<string name="error_password_change_required">Необходимо изменить пароль дневника</string>
<string name="error_service_unavailable">UONET+ проводит техническое обслуживание, повторите попытку позже</string>
<string name="error_unknown_uonet">Неизвестная ошибка дневника UONET+, повторите попытку позже</string>
<string name="error_unknown_app">Неизвестная ошибка приложения, повторите попытку позже</string>
<string name="error_cloudflare_captcha">Captcha verification required</string>
<string name="error_cloudflare_captcha">Требуется подтверждение капчи</string>
<string name="error_unknown">Произошла непредвиденная ошибка</string>
<string name="error_feature_disabled">Функция отключена вашей школой</string>
<string name="error_feature_not_available">Функция недоступна в режиме Mobile API. Воспользуйтесь другим режимом</string>
<string name="error_field_required">Это поле обязательно</string>
<!-- Mute system -->
<string name="message_mute">Mute</string>
<string name="message_unmute">Unmute</string>
<string name="message_mute_success">You have muted this user</string>
<string name="message_unmute_success">You have unmuted this user</string>
<string name="message_mute">Отключить уведомления</string>
<string name="message_unmute">Включить уведомления</string>
<string name="message_mute_success">Вы отключили уведомления от этого пользователя</string>
<string name="message_unmute_success">Вы включили уведомления от этого пользователя снова</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br /&gt;&lt;br /&gt;Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href=\"https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl\"&gt;Dzienniczek VULCAN&lt;/a&gt;. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -19,6 +19,7 @@
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 minút</item>

View File

@ -29,7 +29,7 @@
<string name="notifications_center_title">Centrum oznámení</string>
<string name="menu_order_title">Konfigurácia menu</string>
<!--Subtitles-->
<string name="grade_subtitle">Semester %1$d, %2$d/%3$d</string>
<string name="grade_subtitle">Polrok %1$d, %2$d/%3$d</string>
<!--Login-->
<string name="login_header_default">Prihláste sa pomocou žiackeho alebo rodičovského účtu</string>
<string name="login_header_symbol">Zadajte symbol zo stránky denníka: &lt;b&gt;%1$s&lt;/b&gt;</string>
@ -105,8 +105,8 @@
<string name="main_support_positive">Zapnúť reklamy</string>
<!--Grade-->
<string name="grade_header">Známka</string>
<string name="grade_semester">Semester %d</string>
<string name="grade_switch_semester">Zmeniť semester</string>
<string name="grade_semester">Polrok %d</string>
<string name="grade_switch_semester">Zmeniť polrok</string>
<string name="grade_no_items">Žiadne známky</string>
<string name="grade_weight">Váha</string>
<string name="grade_weight_value">Váha: %s</string>
@ -125,16 +125,16 @@
<string name="grade_summary_calculated_average">Vypočítaný polročný priemer</string>
<string name="grade_summary_calculated_average_annual">Vypočítaný ročný priemer</string>
<string name="grade_summary_calculated_average_help_dialog_title">Ako funguje vypočítaný priemer?</string>
<string name="grade_summary_calculated_average_help_dialog_message">Vypočítaný priemer je aritmetický priemer vypočítaný z priemerov predmetov. Umožňuje vám to poznať približný konečný priemer. Vypočítava sa spôsobom zvoleným užívateľom v nastaveniach aplikácii. Odporúča sa vybrať príslušnú možnosť. Dôvodom je rozdielny výpočet školských priemerov. Ak vaša škola navyše uvádza priemer predmetov na stránke denníka Vulcan, aplikácia si ich stiahne a tieto priemery nepočíta. To možno zmeniť vynútením výpočtu priemeru v nastavení aplikácii.\n\n<b>Priemer známok iba z vybraného semestra</b>:\n1. Výpočet váženého priemeru pre každý predmet v danom semestri\n2. Sčítanie vypočítaných priemerov\n3. Výpočet aritmetického priemeru součtených priemerov\n\n<b>Priemer priemerov z oboch semestrov</b>:\n1. Výpočet váženého priemeru pre každý predmet v semestri 1 a 2\n2. Výpočet aritmetického priemeru vypočítaných priemerov za semestre 1 a 2 pre každý predmet.\n3. Sčítanie vypočítaných priemerov\n4. Výpočet aritmetického priemeru součtených priemerov\n\n<b>Priemer známok z celého roka:</b>\n1. Výpočet váženého priemeru za rok pre každý predmet. Konečný priemer v 1. semestri je nepodstatný.\n2. Sčítanie vypočítaných priemerov\n3. Výpočet aritmetického priemeru součtených priemerov</string>
<string name="grade_summary_calculated_average_help_dialog_message">Vypočítaný priemer je aritmetický priemer vypočítaný z priemerov predmetov. Umožňuje vám to poznať približný konečný priemer. Vypočítava sa spôsobom zvoleným užívateľom v 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\n<b>Priemer známok iba z vybraného polroka</b>:\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\n<b>Priemer priemerov z oboch polrokov</b>:\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\n<b>Priemer známok z celého roka:</b>\n1. Výpočet váženého priemeru za rok pre každý predmet. Konečný priemer v 1. polroku je nepodstatný.\n2. Sčítanie vypočítaných priemerov\n3. Výpočet aritmetického priemeru sčítaných priemerov</string>
<string name="grade_summary_final_average_help_dialog_title">Ako funguje konečný priemer?</string>
<string name="grade_summary_final_average_help_dialog_message">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</string>
<string name="grade_summary_final_average_help_dialog_message">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</string>
<string name="grade_summary_final_average">Konečný priemer</string>
<string name="grade_summary_from_subjects">z %1$d z %2$d predmetov</string>
<string name="grade_menu_summary">Zhrnutie</string>
<string name="grade_menu_statistics">Trieda</string>
<string name="grade_menu_read">Označiť ako prečítané</string>
<string name="grade_statistics_partial">Čiastočné</string>
<string name="grade_statistics_semester">Semester</string>
<string name="grade_statistics_semester">Polrok</string>
<string name="grade_statistics_points">Body</string>
<string name="grade_statistics_legend">Vysvetlivky</string>
<string name="grade_statistics_class_average">Priemer triedy: %1$s</string>
@ -499,7 +499,7 @@
<string name="mobile_devices_title">Mobilný prístup</string>
<string name="mobile_devices_no_items">Žiadne zariadenia</string>
<string name="mobile_devices_unregister">Zrušiť registráciu</string>
<string name="mobile_device_removed">Zariadenie odstránenie</string>
<string name="mobile_device_removed">Zariadenie odstránené</string>
<string name="mobile_device_qr">QR kód</string>
<string name="mobile_device_token">Token</string>
<string name="mobile_device_symbol">Symbol</string>
@ -872,6 +872,8 @@
<string name="captcha_dialog_title">Webová stránka denníka VULCAN vyžaduje overenie</string>
<string name="captcha_dialog_description"><b>Prečo sa mi to zobrazuje?</b>\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ť</string>
<string name="captcha_verified_message">Úspešne overené</string>
<!--Panic mode-->
<string name="panic_mode_title">Núdzový prístup</string>
<!--Errors-->
<string name="error_no_internet">Žiadne internetové pripojenie</string>
<string name="error_invalid_device_datetime">Vyskytla sa chyba. Skontrolujte hodiny svojho zariadenia</string>
@ -893,4 +895,7 @@
<string name="message_unmute">Zrušiť stlmenie</string>
<string name="message_mute_success">Stlmili ste tohto používateľa</string>
<string name="message_unmute_success">Zrušili ste stlmenie tohto používateľa</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br /&gt;&lt;br /&gt;Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href=\"https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl\"&gt;Dzienniczek VULCAN&lt;/a&gt;. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -19,6 +19,7 @@
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 хвилин</item>

View File

@ -872,6 +872,8 @@
<string name="captcha_dialog_title">Веб-сайт VULCAN потребує підтвердження</string>
<string name="captcha_dialog_description"><b>Чому я це бачу?</b>\nСайт реєстру, з якого Wulkanowy завантажує дані, відображає той самий екран, що й вище, тому Wulkanowy також повинен показувати його, щоб мати змогу завантажувати дані з цього сайту. Це неможливо обійти</string>
<string name="captcha_verified_message">Верифікація завершена</string>
<!--Panic mode-->
<string name="panic_mode_title">Екстрений доступ</string>
<!--Errors-->
<string name="error_no_internet">Немає з\'єднання з інтернетом</string>
<string name="error_invalid_device_datetime">Сталася помилка. Перевірте годинник пристрою</string>
@ -893,4 +895,7 @@
<string name="message_unmute">Ввімкнути сповіщення</string>
<string name="message_mute_success">Ви ігноруєте цього користувача</string>
<string name="message_unmute_success">Ви не ігноруєте цього користувача</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br /&gt;&lt;br /&gt;Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href=\"https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl\"&gt;Dzienniczek VULCAN&lt;/a&gt;. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -40,6 +40,7 @@
<item>Deutsch</item>
<item>Čeština</item>
<item>Slovenčina</item>
<item>Kaszëbsczi</item>
</string-array>
<string-array name="app_language_values" translatable="false">
<item>system</item>
@ -50,6 +51,7 @@
<item>de</item>
<item>cs</item>
<item>sk</item>
<item>csb</item>
</string-array>
<string-array name="services_interval_entries">

View File

@ -869,6 +869,9 @@
<string name="captcha_dialog_description"><b>Why am I seeing this?</b>\nThe register website from which Wulkanowy downloads data displays the same screen as above, so Wulkanowy must also show it to be able to download data from this website. There\'s no way around it</string>
<string name="captcha_verified_message">Verified successfully</string>
<!--Panic mode-->
<string name="panic_mode_title">Emergency access</string>
<!--Errors-->
<string name="error_no_internet">No internet connection</string>
@ -892,4 +895,8 @@
<string name="message_unmute">Unmute</string>
<string name="message_mute_success">You have muted this user</string>
<string name="message_unmute_success">You have unmuted this user</string>
<!--End-->
<string name="end_title">Koniec Wulkanowego</string>
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.&lt;br />&lt;br />Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji &lt;a href="https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&amp;hl=pl">Dzienniczek VULCAN&lt;/a>. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
</resources>

View File

@ -41,6 +41,7 @@ class WulkanowySdkFactoryTest {
webkitCookieManagerProxy = mockk(),
studentDb = studentDao,
wulkanowyRepository = mockk(relaxed = true),
context = mockk(),
)
)

View File

@ -1,6 +1,6 @@
buildscript {
ext {
kotlin_version = '1.9.23'
kotlin_version = '1.9.24'
about_libraries = '11.1.4'
hilt_version = '2.51.1'
}
@ -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.4.0'
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.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"