1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 00:39:08 -05:00

Merge branch 'release/0.22.0' into master

This commit is contained in:
Mikołaj Pich 2020-10-15 17:54:22 +02:00
commit ddac1d0f98
48 changed files with 1097 additions and 197 deletions

View File

@ -3,8 +3,8 @@ jdk: oraclejdk8
env: env:
global: global:
- ANDROID_API_LEVEL=29 - ANDROID_API_LEVEL=30
- ANDROID_BUILD_TOOLS_VERSION=29.0.3 - ANDROID_BUILD_TOOLS_VERSION=30.0.2
cache: cache:
directories: directories:
@ -14,7 +14,7 @@ cache:
branches: branches:
only: only:
- develop - develop
- 0.21.2 - 0.22.0
android: android:
licenses: licenses:
@ -28,22 +28,26 @@ android:
- build-tools-$ANDROID_BUILD_TOOLS_VERSION - build-tools-$ANDROID_BUILD_TOOLS_VERSION
# The SDK version used to compile your project # The SDK version used to compile your project
- android-$ANDROID_API_LEVEL - android-$ANDROID_API_LEVEL
# Additional components # Additional components
- extra-google-google_play_services - extra-google-google_play_services
- extra-google-m2repository - extra-google-m2repository
- extra-android-m2repository - extra-android-m2repository
- addon-google_apis-google-$ANDROID_API_LEVEL - addon-google_apis-google-$ANDROID_API_LEVEL
# Android emulator # Android emulator
- android-22 - android-22
- sys-img-armeabi-v7a-android-22 - sys-img-armeabi-v7a-android-22
before_install:
- yes | sdkmanager "platforms;android-30"
- yes | sdkmanager "build-tools;30.0.2"
before_script: before_script:
# Launch emulator before the execution # Launch emulator before the execution
- echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a - echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a
- emulator -avd test -no-audio -no-window & - emulator -avd test -no-audio -no-window &
- android-wait-for-emulator - android-wait-for-emulator
- adb shell input keyevent 82 & - adb shell input keyevent 82 &
- "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | sudo bash" - "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | sudo bash"
script: script:
- ./gradlew dependencies --stacktrace --daemon - ./gradlew dependencies --stacktrace --daemon

View File

@ -32,14 +32,17 @@ Unofficial android VULCAN UONET+ register client for both students and their par
## Download ## Download
You can download the current beta version from the Google Play or the F-Droid store You can download the current beta version from the Google Play, F-Droid or Huawei AppGallery store
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play" alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy) height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" [<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid" alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/) height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="appgallery_badge.png"
alt="Explore it on AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features being prepared for the next release You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features being prepared for the next release

View File

@ -32,14 +32,17 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
## Pobierz ## Pobierz
Aktualną wersję beta możesz pobrać ze sklepu Google Play lub F-Droid Aktualną wersję beta możesz pobrać ze sklepu Google Play, F-Droid lub Huawei AppGallery
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Pobierz z Google Play" alt="Pobierz z Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy) height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" [<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Pobierz z F-Droid" alt="Pobierz z F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/) height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="appgallery_badge.png"
alt="Odkrywaj w AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania

View File

@ -10,16 +10,16 @@ apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle' apply from: 'hooks.gradle'
android { android {
compileSdkVersion 29 compileSdkVersion 30
buildToolsVersion '29.0.3' buildToolsVersion '30.0.2'
defaultConfig { defaultConfig {
applicationId "io.github.wulkanowy" applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy" testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 17 minSdkVersion 17
targetSdkVersion 29 targetSdkVersion 30
versionCode 72 versionCode 73
versionName "0.21.2" versionName "0.22.0"
multiDexEnabled true multiDexEnabled true
resValue "string", "app_name", "Wulkanowy" resValue "string", "app_name", "Wulkanowy"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -112,14 +112,15 @@ play {
serviceAccountCredentials = file('key.p12') serviceAccountCredentials = file('key.p12')
defaultToAppBundles = false defaultToAppBundles = false
track = 'alpha' track = 'alpha'
updatePriority = 0
} }
ext { ext {
work_manager = "2.4.0" work_manager = "2.4.0"
room = "2.2.5" room = "2.2.5"
chucker = "3.2.0" chucker = "3.3.0"
mockk = "1.10.0" mockk = "1.10.2"
moshi = "1.9.3" moshi = "1.11.0"
} }
configurations.all { configurations.all {
@ -127,14 +128,14 @@ configurations.all {
} }
dependencies { dependencies {
implementation "io.github.wulkanowy:sdk:0.21.2" implementation "io.github.wulkanowy:sdk:0.22.0"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
implementation "androidx.core:core-ktx:1.3.1" implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.activity:activity-ktx:1.1.0" implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.appcompat:appcompat:1.2.0" implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.appcompat:appcompat-resources:1.2.0" implementation "androidx.appcompat:appcompat-resources:1.2.0"
@ -179,15 +180,16 @@ dependencies {
implementation "fr.bipi.treessence:treessence:0.3.2" implementation "fr.bipi.treessence:treessence:0.3.2"
implementation "com.mikepenz:aboutlibraries-core:$about_libraries" implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3' implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "io.coil-kt:coil:1.0.0-rc2" implementation "io.coil-kt:coil:1.0.0-rc3"
implementation "io.github.wulkanowy:AppKillerManager:3.0.0" implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
implementation 'me.xdrop:fuzzywuzzy:1.3.1' implementation 'me.xdrop:fuzzywuzzy:1.3.1'
playImplementation 'com.google.firebase:firebase-analytics:17.5.0' playImplementation 'com.google.firebase:firebase-analytics:17.6.0'
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.1.1' playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.1.1'
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.1.1" playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.1.1"
playImplementation 'com.google.firebase:firebase-messaging:20.2.4' playImplementation 'com.google.firebase:firebase-messaging:20.3.0'
playImplementation 'com.google.firebase:firebase-crashlytics:17.2.1' playImplementation 'com.google.firebase:firebase-crashlytics:17.2.2'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava' playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker" releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"

View File

@ -0,0 +1,17 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.view.View
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER")
class UpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates(activity: Activity) {}
fun onActivityResult(requestCode: Int, resultCode: Int) {}
fun onResume(activity: Activity) {}
}

View File

@ -33,7 +33,11 @@ internal class RepositoryModule {
setSimpleHttpLogger { Timber.d(it) } setSimpleHttpLogger { Timber.d(it) }
// for debug only // for debug only
addInterceptor(ChuckerInterceptor(context, chuckerCollector), true) addInterceptor(ChuckerInterceptor(
context = context,
collector = chuckerCollector,
alwaysReadResponseBody = true
), true)
} }
} }

View File

@ -72,18 +72,22 @@ class TimetableNotificationSchedulerHelper @Inject constructor(
withContext(dispatchersProvider.backgroundThread) { withContext(dispatchersProvider.backgroundThread) {
lessons.groupBy { it.date } lessons.groupBy { it.date }
.map { it.value.sortedBy { lesson -> lesson.start } } .map { it.value.sortedBy { lesson -> lesson.start } }
.map { it.filter { lesson -> !lesson.canceled && lesson.isStudentPlan } } .map { it.filter { lesson -> lesson.isStudentPlan } }
.map { day -> .map { day ->
day.forEachIndexed { index, lesson -> val canceled = day.filter { it.canceled }
val intent = createIntent(student, lesson, day.getOrNull(index + 1)) val active = day.filter { !it.canceled }
cancelScheduled(canceled)
active.forEachIndexed { index, lesson ->
val intent = createIntent(student, lesson, active.getOrNull(index + 1))
if (lesson.start > now()) { if (lesson.start > now()) {
scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_UPCOMING, getUpcomingLessonTime(index, day, lesson)) scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_UPCOMING, getUpcomingLessonTime(index, active, lesson))
} }
if (lesson.end > now()) { if (lesson.end > now()) {
scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_CURRENT, lesson.start) scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_CURRENT, lesson.start)
if (day.lastIndex == index) { if (active.lastIndex == index) {
scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION, lesson.end) scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION, lesson.end)
} }
} }

View File

@ -22,9 +22,11 @@ import io.github.wulkanowy.utils.getString
import io.github.wulkanowy.utils.openAppInMarket import io.github.wulkanowy.utils.openAppInMarket
import io.github.wulkanowy.utils.openEmailClient import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.openInternetBrowser
import okhttp3.internal.http2.StreamResetException
import java.io.InterruptedIOException import java.io.InterruptedIOException
import java.io.PrintWriter import java.io.PrintWriter
import java.io.StringWriter import java.io.StringWriter
import java.net.ConnectException
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
import java.net.UnknownHostException import java.net.UnknownHostException
import javax.inject.Inject import javax.inject.Inject
@ -85,6 +87,8 @@ class ErrorDialog : BaseDialogFragment<DialogErrorBinding>() {
errorDialogReport.isEnabled = when (error) { errorDialogReport.isEnabled = when (error) {
is UnknownHostException, is UnknownHostException,
is InterruptedIOException, is InterruptedIOException,
is ConnectException,
is StreamResetException,
is SocketTimeoutException, is SocketTimeoutException,
is ServiceUnavailableException, is ServiceUnavailableException,
is FeatureDisabledException, is FeatureDisabledException,

View File

@ -81,7 +81,10 @@ class GradeDetailsPresenter @Inject constructor(
}.onEach { }.onEach {
when (it.status) { when (it.status) {
Status.LOADING -> Timber.i("Select mark grades as read") Status.LOADING -> Timber.i("Select mark grades as read")
Status.SUCCESS -> Timber.i("Mark as read result: Success") Status.SUCCESS -> {
Timber.i("Mark as read result: Success")
loadData(currentSemesterId, false)
}
Status.ERROR -> { Status.ERROR -> {
Timber.i("Mark as read result: An exception occurred") Timber.i("Mark as read result: An exception occurred")
errorHandler.dispatch(it.error!!) errorHandler.dispatch(it.error!!)

View File

@ -14,6 +14,7 @@ import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
import io.github.wulkanowy.utils.UpdateHelper
import io.github.wulkanowy.utils.setOnSelectPageListener import io.github.wulkanowy.utils.setOnSelectPageListener
import javax.inject.Inject import javax.inject.Inject
@ -25,6 +26,9 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
private val loginAdapter = BaseFragmentPagerAdapter(supportFragmentManager) private val loginAdapter = BaseFragmentPagerAdapter(supportFragmentManager)
@Inject
lateinit var updateHelper: UpdateHelper
companion object { companion object {
fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java) fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
@ -37,8 +41,20 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
setContentView(ActivityLoginBinding.inflate(layoutInflater).apply { binding = this }.root) setContentView(ActivityLoginBinding.inflate(layoutInflater).apply { binding = this }.root)
setSupportActionBar(binding.loginToolbar) setSupportActionBar(binding.loginToolbar)
messageContainer = binding.loginContainer messageContainer = binding.loginContainer
updateHelper.messageContainer = binding.loginContainer
presenter.onAttachView(this) presenter.onAttachView(this)
updateHelper.checkAndInstallUpdates(this)
}
override fun onResume() {
super.onResume()
updateHelper.onResume(this)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
updateHelper.onActivityResult(requestCode, resultCode)
} }
override fun initView() { override fun initView() {

View File

@ -40,6 +40,7 @@ import io.github.wulkanowy.ui.modules.note.NoteFragment
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.UpdateHelper
import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.safelyPopFragments import io.github.wulkanowy.utils.safelyPopFragments
@ -56,6 +57,9 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
@Inject @Inject
lateinit var analytics: FirebaseAnalyticsHelper lateinit var analytics: FirebaseAnalyticsHelper
@Inject
lateinit var updateHelper: UpdateHelper
@Inject @Inject
lateinit var appInfo: AppInfo lateinit var appInfo: AppInfo
@ -100,6 +104,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
setContentView(ActivityMainBinding.inflate(layoutInflater).apply { binding = this }.root) setContentView(ActivityMainBinding.inflate(layoutInflater).apply { binding = this }.root)
setSupportActionBar(binding.mainToolbar) setSupportActionBar(binding.mainToolbar)
messageContainer = binding.mainFragmentContainer messageContainer = binding.mainFragmentContainer
updateHelper.messageContainer = binding.mainFragmentContainer
presenter.onAttachView(this, MainView.Section.values().singleOrNull { it.id == intent.getIntExtra(EXTRA_START_MENU, -1) }) presenter.onAttachView(this, MainView.Section.values().singleOrNull { it.id == intent.getIntExtra(EXTRA_START_MENU, -1) })
@ -107,6 +112,18 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
initialize(startMenuIndex, savedInstanceState) initialize(startMenuIndex, savedInstanceState)
pushFragment(moreMenuFragments[startMenuMoreIndex]) pushFragment(moreMenuFragments[startMenuMoreIndex])
} }
updateHelper.checkAndInstallUpdates(this)
}
override fun onResume() {
super.onResume()
updateHelper.onResume(this)
}
@SuppressLint("NewApi")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
updateHelper.onActivityResult(requestCode, resultCode)
if (appInfo.systemVersion >= Build.VERSION_CODES.N_MR1) initShortcuts() if (appInfo.systemVersion >= Build.VERSION_CODES.N_MR1) initShortcuts()
} }
@ -181,8 +198,8 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
analytics.setCurrentScreen(this, name) analytics.setCurrentScreen(this, name)
} }
override fun onOptionsItemSelected(item: MenuItem?): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item?.itemId == R.id.mainMenuAccount) presenter.onAccountManagerSelected() return if (item.itemId == R.id.mainMenuAccount) presenter.onAccountManagerSelected()
else false else false
} }

View File

@ -174,7 +174,7 @@ class MessagePreviewFragment :
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun printDocument(html: String, jobName: String) { override fun printDocument(html: String, jobName: String) {
val webView = WebView(activity) val webView = WebView(requireContext())
webView.webViewClient = object : WebViewClient() { webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.message.send package io.github.wulkanowy.ui.modules.message.send
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Rect import android.graphics.Rect
@ -74,6 +75,7 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as? Boolean) presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as? Boolean)
} }
@SuppressLint("ClickableViewAccessibility")
override fun initView() { override fun initView() {
setUpExtendedHitArea() setUpExtendedHitArea()
with(binding) { with(binding) {
@ -87,8 +89,8 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
return true return true
} }
override fun onOptionsItemSelected(item: MenuItem?): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item?.itemId == R.id.sendMessageMenuSend) presenter.onSend() return if (item.itemId == R.id.sendMessageMenuSend) presenter.onSend()
else false else false
} }

View File

@ -22,7 +22,6 @@ import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import timber.log.Timber import timber.log.Timber
import java.lang.NullPointerException
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDate.now import java.time.LocalDate.now
import java.time.LocalDate.of import java.time.LocalDate.of

View File

@ -22,32 +22,32 @@ private fun Bundle?.checkSavedState() = if (this == null) "(STATE IS NULL)" else
class ActivityLifecycleLogger : Application.ActivityLifecycleCallbacks { class ActivityLifecycleLogger : Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity?) { override fun onActivityPaused(activity: Activity) {
activity?.let { Timber.d("${it::class.java.simpleName} PAUSED") } Timber.d("${activity::class.java.simpleName} PAUSED")
} }
override fun onActivityResumed(activity: Activity?) { override fun onActivityResumed(activity: Activity) {
activity?.let { Timber.d("${it::class.java.simpleName} RESUMED") } Timber.d("${activity::class.java.simpleName} RESUMED")
} }
override fun onActivityStarted(activity: Activity?) { override fun onActivityStarted(activity: Activity) {
activity?.let { Timber.d("${it::class.java.simpleName} STARTED") } Timber.d("${activity::class.java.simpleName} STARTED")
} }
override fun onActivityDestroyed(activity: Activity?) { override fun onActivityDestroyed(activity: Activity) {
activity?.let { Timber.d("${it::class.java.simpleName} DESTROYED") } Timber.d("${activity::class.java.simpleName} DESTROYED")
} }
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) { override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
activity?.let { Timber.d("${it::class.java.simpleName} SAVED INSTANCE STATE") } Timber.d("${activity::class.java.simpleName} SAVED INSTANCE STATE")
} }
override fun onActivityStopped(activity: Activity?) { override fun onActivityStopped(activity: Activity) {
activity?.let { Timber.d("${it::class.java.simpleName} STOPPED") } Timber.d("${activity::class.java.simpleName} STOPPED")
} }
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) { override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
activity?.let { Timber.d("${it::class.java.simpleName} CREATED ${savedInstanceState.checkSavedState()}") } Timber.d("${activity::class.java.simpleName} CREATED ${savedInstanceState.checkSavedState()}")
} }
} }

View File

@ -4,20 +4,26 @@ import android.content.res.Resources
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException
import io.github.wulkanowy.sdk.scrapper.exception.ServiceUnavailableException import io.github.wulkanowy.sdk.scrapper.exception.ServiceUnavailableException
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException
import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException
import okhttp3.internal.http2.StreamResetException
import java.io.InterruptedIOException import java.io.InterruptedIOException
import java.net.ConnectException
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
import java.net.UnknownHostException import java.net.UnknownHostException
fun Resources.getString(error: Throwable) = when (error) { fun Resources.getString(error: Throwable) = when (error) {
is UnknownHostException -> getString(R.string.error_no_internet) is UnknownHostException -> getString(R.string.error_no_internet)
is SocketTimeoutException, is InterruptedIOException -> getString(R.string.error_timeout) is SocketTimeoutException, is InterruptedIOException, is ConnectException, is StreamResetException -> getString(R.string.error_timeout)
is NotLoggedInException -> getString(R.string.error_login_failed) is NotLoggedInException -> getString(R.string.error_login_failed)
is PasswordChangeRequiredException -> getString(R.string.error_password_change_required) is PasswordChangeRequiredException -> getString(R.string.error_password_change_required)
is ServiceUnavailableException -> getString(R.string.error_service_unavailable) is ServiceUnavailableException -> getString(R.string.error_service_unavailable)
is FeatureDisabledException -> getString(R.string.error_feature_disabled) is FeatureDisabledException -> getString(R.string.error_feature_disabled)
is FeatureNotAvailableException -> getString(R.string.error_feature_not_available) is FeatureNotAvailableException -> getString(R.string.error_feature_not_available)
is VulcanException -> getString(R.string.error_unknown_uonet)
is ScrapperException -> getString(R.string.error_unknown_app)
else -> getString(R.string.error_unknown) else -> getString(R.string.error_unknown)
} }

View File

@ -1,10 +1,7 @@
Wersja 0.21.2 Wersja 0.22
- naprawiliśmy logowanie do tarnowskiego dziennika - naprawiliśmy krytyczny błąd ze stabilnością przy ładowaniu danych
- naprawiliśmy wyświetlanie podsumowania punktów klasy - naprawiliśmy skalowanie tekstu przy bardzo dużych jego rozmiarach
- dodaliśmy skróty aplikacji - naprawiliśmy wyświetlanie powiadomień o odwołanych lekcjach (nie powinny się już pokazywać)
- dodaliśmy opcję pokazywania nazwy grupy w planie lekcji na liście - dodaliśmy informowanie o dostępności aktualizacji w aplikacji
- dodaliśmy opcję pokazywania w ocenach przedmiotów bez ocen
- dodaliśmy dodatkowe opcje sortowania ocen
- dodaliśmy rozróżnianie powiadomień dla pochwał i uwag
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/mainContainer" android:id="@+id/mainContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -10,18 +10,19 @@
style="@style/Widget.MaterialComponents.Toolbar.Surface" style="@style/Widget.MaterialComponents.Toolbar.Surface"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:contentInsetStartWithNavigation="0dp" /> app:contentInsetStartWithNavigation="0dp"
app:layout_constraintTop_toTopOf="parent" />
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/mainFragmentContainer" android:id="@+id/mainFragmentContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:layout_marginTop="?actionBarSize" app:layout_constraintBottom_toTopOf="@id/mainBottomNav"
android:layout_marginBottom="@dimen/bottom_navigation_height" /> app:layout_constraintTop_toBottomOf="@id/mainToolbar" />
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation <com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="@+id/mainBottomNav" android:id="@+id/mainBottomNav"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" /> app:layout_constraintBottom_toBottomOf="parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -33,7 +33,8 @@
<TextView <TextView
android:id="@+id/aboutItemSummary" android:id="@+id/aboutItemSummary"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp" android:layout_height="wrap_content"
android:minHeight="20dp"
android:layout_below="@id/aboutItemTitle" android:layout_below="@id/aboutItemTitle"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_toEndOf="@id/aboutItemImage" android:layout_toEndOf="@id/aboutItemImage"

View File

@ -1,4 +1,4 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/attendanceItemContainer" android:id="@+id/attendanceItemContainer"
@ -15,10 +15,17 @@
<LinearLayout <LinearLayout
android:id="@+id/attendanceItemNumberContainer" android:id="@+id/attendanceItemNumberContainer"
android:layout_width="40dp" android:layout_width="wrap_content"
android:layout_height="40dp" android:layout_height="wrap_content"
android:minWidth="40dp"
android:minHeight="40dp"
android:gravity="center" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="@+id/attendanceItemDetailsContainer"
app:layout_constraintEnd_toStartOf="@+id/attendanceItemDetailsContainer"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/attendanceItemDetailsContainer">
<TextView <TextView
android:id="@+id/attendanceItemNumber" android:id="@+id/attendanceItemNumber"
@ -48,38 +55,52 @@
app:tint="?attr/colorOnSurface" /> app:tint="?attr/colorOnSurface" />
</LinearLayout> </LinearLayout>
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/attendanceItemSubject" android:id="@+id/attendanceItemDetailsContainer"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_marginEnd="40dp" android:layout_marginEnd="10dp"
android:layout_toStartOf="@id/attendanceItemAlert" app:layout_constraintEnd_toStartOf="@+id/attendanceItemAlert"
android:layout_toEndOf="@+id/attendanceItemNumberContainer" app:layout_constraintHorizontal_bias="0.5"
android:ellipsize="end" app:layout_constraintStart_toEndOf="@+id/attendanceItemNumberContainer"
android:maxLines="1" app:layout_constraintTop_toTopOf="parent">
android:textSize="17sp"
tools:text="Matematyka" />
<TextView <TextView
android:id="@+id/attendanceItemDescription" android:id="@+id/attendanceItemSubject"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignStart="@id/attendanceItemSubject" android:layout_alignParentTop="true"
android:layout_alignBottom="@+id/attendanceItemNumberContainer" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textColor="?android:textColorSecondary" android:textSize="17sp"
android:textSize="12sp" app:layout_constraintStart_toStartOf="parent"
tools:text="Present" /> app:layout_constraintTop_toTopOf="parent"
tools:text="Matematyka" />
<TextView
android:id="@+id/attendanceItemDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@id/attendanceItemDetailsContainer"
app:layout_constraintStart_toStartOf="@id/attendanceItemDetailsContainer"
app:layout_constraintTop_toBottomOf="@id/attendanceItemSubject"
tools:text="Present" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView <ImageView
android:id="@+id/attendanceItemAlert" android:id="@+id/attendanceItemAlert"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" app:layout_constraintBottom_toBottomOf="@+id/attendanceItemDetailsContainer"
android:layout_marginTop="10dp" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/attendanceItemDetailsContainer"
app:layout_constraintTop_toTopOf="@+id/attendanceItemDetailsContainer"
app:srcCompat="@drawable/ic_all_mark" app:srcCompat="@drawable/ic_all_mark"
app:tint="?colorPrimary" app:tint="?colorPrimary"
tools:ignore="contentDescription" /> tools:ignore="contentDescription" />
</RelativeLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/attendanceSummaryItemSubject" android:id="@+id/attendanceSummaryItemSubject"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="wrap_content"
android:minHeight="48dp"
android:gravity="start" android:gravity="start"
android:maxLines="1" android:maxLines="1"
android:paddingLeft="16dp" android:paddingLeft="16dp"

View File

@ -12,8 +12,11 @@
<TextView <TextView
android:id="@+id/completedLessonItemNumber" android:id="@+id/completedLessonItemNumber"
android:layout_width="40dp" android:layout_width="wrap_content"
android:layout_height="40dp" android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:minWidth="40dp"
android:minHeight="40dp"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:gravity="center" android:gravity="center"
android:includeFontPadding="false" android:includeFontPadding="false"
@ -40,9 +43,9 @@
android:id="@+id/completedLessonItemTopic" android:id="@+id/completedLessonItemTopic"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/completedLessonItemSubject"
android:layout_alignStart="@id/completedLessonItemSubject" android:layout_alignStart="@id/completedLessonItemSubject"
android:layout_alignEnd="@+id/completedLessonItemAlert" android:layout_alignEnd="@+id/completedLessonItemAlert"
android:layout_alignBottom="@+id/completedLessonItemNumber"
android:layout_marginEnd="40dp" android:layout_marginEnd="40dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
@ -56,7 +59,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:tint="?colorTimetableChange"
app:srcCompat="@drawable/ic_timetable_swap" app:srcCompat="@drawable/ic_timetable_swap"
app:tint="?colorTimetableChange"
tools:ignore="contentDescription" /> tools:ignore="contentDescription" />
</RelativeLayout> </RelativeLayout>

View File

@ -18,62 +18,82 @@
<TextView <TextView
android:id="@+id/gradeItemValue" android:id="@+id/gradeItemValue"
android:layout_width="45dp" android:layout_width="wrap_content"
android:layout_height="40dp" android:layout_height="wrap_content"
android:background="@color/grade_material_default" android:background="@color/grade_material_default"
android:gravity="center" android:gravity="center"
android:maxLength="5" android:maxLength="5"
android:minWidth="45dp"
android:minHeight="40dp"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="16sp" android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="@+id/gradeDetailsContainer"
app:layout_constraintEnd_toStartOf="@+id/gradeDetailsContainer"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="@+id/gradeDetailsContainer"
tools:text="6" /> tools:text="6" />
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/gradeItemDescription" android:id="@+id/gradeDetailsContainer"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="10dp" app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="20dp" app:layout_constraintEnd_toStartOf="@+id/gradeItemNote"
android:ellipsize="end" app:layout_constraintHorizontal_bias="0.5"
android:maxLines="1"
android:textSize="14sp"
app:layout_constraintEnd_toStartOf="@id/gradeItemNote"
app:layout_constraintStart_toEndOf="@+id/gradeItemValue" app:layout_constraintStart_toEndOf="@+id/gradeItemValue"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent">
tools:text="@tools:sample/lorem" />
<TextView <TextView
android:id="@+id/gradeItemDate" android:id="@+id/gradeItemDescription"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1" android:layout_marginStart="10dp"
android:textSize="12sp" android:layout_marginEnd="20dp"
app:layout_constraintBottom_toBottomOf="@+id/gradeItemValue" android:ellipsize="end"
app:layout_constraintStart_toStartOf="@+id/gradeItemDescription" android:maxLines="1"
tools:text="@tools:sample/date/ddmmyy" /> android:textSize="14sp"
app:layout_constraintEnd_toEndOf="@id/gradeDetailsContainer"
app:layout_constraintStart_toStartOf="@id/gradeDetailsContainer"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
<TextView <TextView
android:id="@+id/gradeItemWeight" android:id="@+id/gradeItemDate"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="10dp" android:maxLines="1"
android:layout_marginEnd="20dp" android:textSize="12sp"
android:maxLines="1" app:layout_constraintBottom_toBottomOf="@+id/gradeDetailsContainer"
android:textSize="12sp" app:layout_constraintStart_toStartOf="@+id/gradeItemDescription"
app:layout_constraintBottom_toBottomOf="@+id/gradeItemValue" app:layout_constraintTop_toBottomOf="@+id/gradeItemDescription"
app:layout_constraintEnd_toStartOf="@id/gradeItemNote" tools:text="@tools:sample/date/ddmmyy" />
app:layout_constraintStart_toEndOf="@+id/gradeItemDate"
tools:text="@tools:sample/lorem" /> <TextView
android:id="@+id/gradeItemWeight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="20dp"
android:maxLines="1"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/gradeDetailsContainer"
app:layout_constraintEnd_toEndOf="@id/gradeDetailsContainer"
app:layout_constraintStart_toEndOf="@+id/gradeItemDate"
app:layout_constraintTop_toBottomOf="@+id/gradeItemDescription"
tools:text="@tools:sample/lorem" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView <ImageView
android:id="@+id/gradeItemNote" android:id="@+id/gradeItemNote"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" app:layout_constraintBottom_toBottomOf="@+id/gradeDetailsContainer"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/gradeDetailsContainer"
app:layout_constraintTop_toTopOf="@+id/gradeDetailsContainer"
app:srcCompat="@drawable/ic_all_round_mark" app:srcCompat="@drawable/ic_all_round_mark"
app:tint="?colorPrimary" app:tint="?colorPrimary"
tools:ignore="contentDescription" /> tools:ignore="contentDescription" />

View File

@ -2,7 +2,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="64dp" android:layout_height="wrap_content"
android:minHeight="64dp"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:orientation="vertical" android:orientation="vertical"
android:paddingStart="16dp" android:paddingStart="16dp"
@ -14,7 +15,8 @@
<TextView <TextView
android:id="@+id/licenseItemName" android:id="@+id/licenseItemName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="28dp" android:layout_height="wrap_content"
android:minHeight="28dp"
android:ellipsize="end" android:ellipsize="end"
android:gravity="bottom" android:gravity="bottom"
android:singleLine="true" android:singleLine="true"
@ -24,7 +26,8 @@
<TextView <TextView
android:id="@+id/licenseItemSummary" android:id="@+id/licenseItemSummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="wrap_content"
android:minHeight="20dp"
android:gravity="bottom" android:gravity="bottom"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorSecondary"
android:textSize="14sp" android:textSize="14sp"

View File

@ -48,7 +48,8 @@
<TextView <TextView
android:id="@+id/loginItemSignedIn" android:id="@+id/loginItemSignedIn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="20dp" android:layout_height="wrap_content"
android:minHeight="20dp"
android:layout_below="@id/loginItemSchool" android:layout_below="@id/loginItemSchool"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_toEndOf="@id/loginItemCheck" android:layout_toEndOf="@id/loginItemCheck"

View File

@ -3,25 +3,30 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobileDevice_subitem_container" android:id="@+id/mobileDevice_subitem_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="64dp" android:layout_height="wrap_content"
android:minHeight="64dp"
tools:context=".ui.modules.mobiledevice.MobileDeviceAdapter"> tools:context=".ui.modules.mobiledevice.MobileDeviceAdapter">
<TextView <TextView
android:id="@+id/mobileDeviceItemName" android:id="@+id/mobileDeviceItemName"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="32dp" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="0dp"
android:layout_toStartOf="@id/mobileDeviceItemUnregister" android:layout_toStartOf="@id/mobileDeviceItemUnregister"
android:ellipsize="end" android:ellipsize="end"
android:gravity="bottom" android:gravity="bottom"
android:maxLines="1" android:maxLines="1"
android:minHeight="32dp"
android:textSize="16sp" android:textSize="16sp"
tools:text="@tools:sample/lorem/random" /> tools:text="@tools:sample/lorem/random" />
<TextView <TextView
android:id="@+id/mobileDeviceItemDate" android:id="@+id/mobileDeviceItemDate"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="wrap_content"
android:minHeight="20dp"
android:layout_below="@id/mobileDeviceItemName" android:layout_below="@id/mobileDeviceItemName"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_toStartOf="@id/mobileDeviceItemUnregister" android:layout_toStartOf="@id/mobileDeviceItemUnregister"

View File

@ -13,8 +13,10 @@
<TextView <TextView
android:id="@+id/timetableItemNumber" android:id="@+id/timetableItemNumber"
android:layout_width="40dp" android:layout_width="wrap_content"
android:layout_height="40dp" android:layout_height="wrap_content"
android:minWidth="40dp"
android:minHeight="40dp"
android:gravity="center" android:gravity="center"
android:includeFontPadding="false" android:includeFontPadding="false"
android:maxLength="2" android:maxLength="2"

View File

@ -7,7 +7,8 @@
<TextView <TextView
android:id="@+id/timetableSmallItemNumber" android:id="@+id/timetableSmallItemNumber"
android:layout_width="40dp" android:layout_width="wrap_content"
android:minWidth="40dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:gravity="center" android:gravity="center"

View File

@ -19,8 +19,10 @@
<TextView <TextView
android:id="@+id/timetableWidgetItemNumber" android:id="@+id/timetableWidgetItemNumber"
android:layout_width="40dp" android:layout_width="wrap_content"
android:layout_height="40dp" android:layout_height="wrap_content"
android:minWidth="40dp"
android:minHeight="40dp"
android:gravity="center" android:gravity="center"
android:includeFontPadding="false" android:includeFontPadding="false"
android:maxLength="2" android:maxLength="2"

View File

@ -16,7 +16,8 @@
<TextView <TextView
android:id="@+id/timetableWidgetItemNumber" android:id="@+id/timetableWidgetItemNumber"
android:layout_width="40dp" android:layout_width="wrap_content"
android:minWidth="40dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:maxLength="2" android:maxLength="2"

View File

@ -16,7 +16,8 @@
<TextView <TextView
android:id="@+id/timetableWidgetItemNumber" android:id="@+id/timetableWidgetItemNumber"
android:layout_width="40dp" android:layout_width="wrap_content"
android:minWidth="40dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:maxLength="2" android:maxLength="2"
@ -29,7 +30,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:layout_marginLeft="6dp"
android:maxLines="1" android:maxLines="1"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="13sp" android:textSize="13sp"
@ -46,7 +46,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textColor="@android:color/white" android:textColor="@android:color/white"
@ -58,7 +57,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:maxLines="1" android:maxLines="1"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="15sp" android:textSize="15sp"
@ -69,7 +67,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textColor="@android:color/white" android:textColor="@android:color/white"

View File

@ -3,7 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="104dp" android:layout_height="wrap_content"
android:minHeight="104dp"
android:orientation="vertical" android:orientation="vertical"
tools:context=".ui.modules.about.AboutAdapter"> tools:context=".ui.modules.about.AboutAdapter">

View File

@ -0,0 +1,52 @@
<?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>Světlý</item>
<item>Tmavý</item>
<item>Černý (AMOLED)</item>
</string-array>
<string-array name="app_language_entries">
<item>Jazyk systému</item>
<item>Polski</item>
<item>English</item>
<item>Pусский</item>
<item>Українська</item>
<item>Deutsch</item>
<item>Čeština</item>
</string-array>
<string-array name="services_interval_entries">
<item>15 minut</item>
<item>30 minut</item>
<item>1 hodina</item>
<item>2 hodiny</item>
<item>6 hodin</item>
<item>12 hodin</item>
<item>24 hodin</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_sorting_mode_entries">
<item>Abecedně</item>
<item>Podle data</item>
</string-array>
<string-array name="grade_color_scheme_entries">
<item>Dzienniczek+</item>
<item>Wulkanowy</item>
<item>Barvy známek v deníku</item>
</string-array>
<string-array name="grade_average_mode_entries">
<item>Průměrná známka od druhého semestru</item>
<item>Průměr známek z obou semestrů</item>
<item>Průměr známek z celého roku</item>
</string-array>
<string-array name="timetable_show_whole_class_entries">
<item>Neukaž</item>
<item>Ukázat vše</item>
<item>Ukázat menší</item>
</string-array>
</resources>

View File

@ -0,0 +1,457 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Activity/Fragment title-->
<string name="login_title">Přihlásit se</string>
<string name="main_title">Wulkanowy</string>
<string name="grade_title">Známky</string>
<string name="attendance_title">Prezence</string>
<string name="exam_title">Zkoušky</string>
<string name="timetable_title">Plán lekce</string>
<string name="settings_title">Nastavení</string>
<string name="more_title">Více</string>
<string name="about_title">O aplikaci</string>
<string name="logviewer_title">Prohlížeč protokolů</string>
<string name="contributors_title">Tvůrci</string>
<string name="license_title">Licence</string>
<string name="message_title">Zprávy</string>
<string name="send_message_title">Nová zpráva</string>
<string name="note_title">Poznámky a úspěchy</string>
<string name="homework_title">Domácí práce</string>
<string name="account_title">Vyberte účet</string>
<!--Subtitles-->
<string name="grade_subtitle">Semestr %1$d, %2$d/%3$d</string>
<!--Login-->
<string name="login_header_default">Přihlaste se pomocí studentského nebo nadřazeného účtu</string>
<string name="login_header_symbol">Zadejte symbol</string>
<string name="login_nickname_hint">Uživatelské jméno</string>
<string name="login_email_hint">Email</string>
<string name="login_login_pesel_email_hint">Přihlášení, číslo PESEL nebo e-mail</string>
<string name="login_password_hint">Heslo</string>
<string name="login_host_hint">Deník UONET+</string>
<string name="login_type_api">Mobile API</string>
<string name="login_type_scrapper">Scraper</string>
<string name="login_type_hybrid">Hybridní</string>
<string name="login_token_hint">Token</string>
<string name="login_pin_hint">PIN</string>
<string name="login_api_key_hint">Klíč API</string>
<string name="login_symbol_hint">Symbol</string>
<string name="login_sign_in">Přihlásit</string>
<string name="login_invalid_password">Toto heslo je příliš krátké</string>
<string name="login_incorrect_password">Přihlašovací údaje jsou nesprávné. Zkontrolujte, zda je v poli níže vybrán správný deník UONET+</string>
<string name="login_invalid_pin">Neplatný PIN</string>
<string name="login_invalid_token">Neplatný token</string>
<string name="login_expired_token">Platnost tokenu vypršela</string>
<string name="login_invalid_email">Nesprávná e-mailová adresa</string>
<string name="login_invalid_login">Neplatné přihlášení</string>
<string name="login_invalid_symbol">Neplatný symbol</string>
<string name="login_incorrect_symbol">Student nebyl nalezen. Zkontrolujte symbol</string>
<string name="login_field_required">Toto pole je povinné</string>
<string name="login_duplicate_student">Vybraný student je již přihlášen</string>
<string name="login_symbol_helper">Symbol najdete na stránce deníku v&#160;<b>Uczeń</b>&#160;<b>Dostęp Mobilny</b>&#160;<b>Zarejestruj urządzenie mobilne</b></string>
<string name="login_select_student">Vyberte studenty k přihlášení do aplikace</string>
<string name="login_advanced">Jiné možnosti</string>
<string name="login_advanced_warning_mobile_api">V tomto režimu nefungují následující: šťastné číslo, statistiky třídy, shrnutí docházky, ospravedlnění nepřítomnosti, absolvované lekce, informace o škole a prohlížení seznamu registrovaných zařízení</string>
<string name="login_advanced_warning_scraper">Tento režim zobrazuje stejná data, která se zobrazují na webových stránkách deníka</string>
<string name="login_advanced_warning_hybrid">Kombinace nejlepších vlastností ostatních dvou režimů. Funguje rychleji než scraper a poskytuje funkce, které nejsou k dispozici v režimu Mobile API. Je to v experimentální fázi</string>
<string name="login_privacy_policy">Zásady ochrany osobních údajů</string>
<string name="login_contact_header">Problémy s přihlášením? Napište nám!</string>
<string name="login_contact_email">Email</string>
<string name="login_contact_discord">Discord</string>
<string name="login_email_intent_title">Poslat e-mail</string>
<string name="login_email_details">Popište podrobnosti problému:</string>
<string name="login_recover_warning">Ujistěte se, že je vybrán správný UONET+ deník!</string>
<string name="login_recover_button">Zapomněl jsem své heslo</string>
<string name="login_recover_title">Obnovte svůj účet</string>
<string name="login_recover">Obnovit</string>
<string name="login_signed_in">Student je již přihlášen</string>
<!--Main-->
<string name="main_account_picker">Správce účtu</string>
<string name="main_log_in">Přihlásit se</string>
<string name="main_session_expired">Platnost relace vypršela</string>
<string name="main_session_relogin">Vaše relace vypršela, přihlaste se prosím znovu</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_no_items">Žádné známky</string>
<string name="grade_weight">Váha</string>
<string name="grade_weight_value">Váha: %s</string>
<string name="grade_comment">Komentář</string>
<string name="grade_no_new_items">Žádné nové známky</string>
<string name="grade_number_new_items">Počet nových známek: %1$d</string>
<string name="grade_average">Průměrný: %1$.2f</string>
<string name="grade_points_sum">Body: %s</string>
<string name="grade_no_average">Žádný průměr</string>
<string name="grade_predicted">Předpovězeno: %1$s</string>
<string name="grade_final">Konečná: %1$s</string>
<string name="grade_summary_points">Celkem bodů</string>
<string name="grade_summary_final_grade">Konečná známka</string>
<string name="grade_summary_predicted_grade">Předpokládaná známka</string>
<string name="grade_summary_calculated_average">Vypočítaný průměr</string>
<string name="grade_summary_final_average">Konečný průměr</string>
<string name="grade_menu_summary">Souhrn</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_points">Body</string>
<plurals name="grade_number_item">
<item quantity="one">%d známka</item>
<item quantity="few">%d známky</item>
<item quantity="many">%d známky</item>
<item quantity="other">%d známky</item>
</plurals>
<plurals name="grade_new_items">
<item quantity="one">Nová známka</item>
<item quantity="few">Nové známky</item>
<item quantity="many">Nové známky</item>
<item quantity="other">Nové známky</item>
</plurals>
<plurals name="grade_new_items_predicted">
<item quantity="one">Nová předpokládaná známka</item>
<item quantity="few">Nové předpovídané známky</item>
<item quantity="many">Nové předpovídané známky</item>
<item quantity="other">Nové předpovídané známky</item>
</plurals>
<plurals name="grade_new_items_final">
<item quantity="one">Nová konečná známka</item>
<item quantity="few">Nové konečné známky</item>
<item quantity="many">Nové konečné známky</item>
<item quantity="other">Nové konečné známky</item>
</plurals>
<plurals name="grade_notify_new_items">
<item quantity="one">Máte %1$d novou známku</item>
<item quantity="few">Máte %1$d nové známky</item>
<item quantity="many">Máte %1$d nové známky</item>
<item quantity="other">Máte %1$d nové známky</item>
</plurals>
<plurals name="grade_notify_new_items_predicted">
<item quantity="one">Máte %1$d novou konečnou známku</item>
<item quantity="few">Máte %1$d nové konečné známky</item>
<item quantity="many">Máte %1$d nové konečné známky</item>
<item quantity="other">Máte %1$d nové konečné známky</item>
</plurals>
<plurals name="grade_notify_new_items_final">
<item quantity="one">Máte %1$d novou konečnou známku</item>
<item quantity="few">Máte %1$d nové konečné známky</item>
<item quantity="many">Máte %1$d nové konečné známky</item>
<item quantity="other">Máte %1$d nové konečné známky</item>
</plurals>
<!--Timetable-->
<string name="timetable_lesson">Lekce</string>
<string name="timetable_room">Pokoj</string>
<string name="timetable_group">Skupina</string>
<string name="timetable_time">Hodiny</string>
<string name="timetable_changes">Změny</string>
<string name="timetable_no_items">Dnes žádné lekce</string>
<string name="timetable_minutes">%s min</string>
<string name="timetable_seconds">%s sek</string>
<string name="timetable_time_left">dosud %1$s</string>
<string name="timetable_time_until">za %1$s</string>
<string name="timetable_finished">Lekce skončila</string>
<string name="timetable_now">Nyní: %s</string>
<string name="timetable_next">Okamžik: %s</string>
<string name="timetable_later">Později: %s</string>
<!--Completed lessons-->
<string name="completed_lessons_title">Dokončené lekce</string>
<string name="completed_lessons_button">Zobrazit dokončené lekce</string>
<string name="completed_lessons_no_items">Žádné informace o absolvovaných lekcích</string>
<string name="completed_lessons_topic">Téma</string>
<string name="completed_lessons_absence">Absence</string>
<string name="completed_lessons_resources">Zdroje</string>
<!--Attendance-->
<string name="attendance_summary_button">Souhrn docházky</string>
<string name="attendance_absence_school">Nepřítomen ze školních důvodů</string>
<string name="attendance_absence_excused">Omluvená absence</string>
<string name="attendance_absence_unexcused">Neomluvená absence</string>
<string name="attendance_exemption">Osvobození</string>
<string name="attendance_excused_lateness">Oprávněné zpoždění</string>
<string name="attendance_unexcused_lateness">Neomluvená zpoždění</string>
<string name="attendance_present">Přítomnost</string>
<string name="attendance_deleted">Smazáno</string>
<string name="attendance_unknown">Neznámý</string>
<string name="attendance_number">Číslo lekce</string>
<string name="attendance_no_items">Žádné položky</string>
<plurals name="attendance_number_absences">
<item quantity="one">%1$d absence</item>
<item quantity="few">%1$d absence</item>
<item quantity="many">%1$d absence</item>
<item quantity="other">%1$d absence</item>
</plurals>
<string name="attendance_excuse_dialog_reason">Důvod absence (volitelný)</string>
<string name="attendance_excuse_dialog_submit">Poslat</string>
<string name="attendance_excuse_success">Absence úspěšně omluvena!</string>
<string name="attendance_excuse_no_selection">Musíte vybrat alespoň jednu nepřítomnost!</string>
<string name="attendance_excuse_title">Ospravedlnit</string>
<!--Attendance summary-->
<string name="attendance_summary_final">Účast</string>
<string name="attendance_summary_total">Celkový</string>
<!--Exam-->
<string name="exam_no_items">Tento týden žádné testy</string>
<string name="exam_type">Typ</string>
<string name="exam_entry_date">Datum vstupu</string>
<!--Message-->
<string name="message_inbox">Doručená pošta</string>
<string name="message_sent">Odesláno</string>
<string name="message_trash">Koš</string>
<string name="message_no_subject">(žádné téma)</string>
<string name="message_no_items">Žádné zprávy</string>
<string name="message_preview_error">Při stahování obsahu zprávy došlo k chybě</string>
<string name="message_from">Od:</string>
<string name="message_to">Do:</string>
<string name="message_date">Datum: %s</string>
<string name="message_reply">Odpověď</string>
<string name="message_forward">Poslat dále</string>
<string name="message_delete">Vymazat</string>
<string name="message_move_to_bin">Přesunout do koše</string>
<string name="message_delete_forever">Trvale smazat</string>
<string name="message_delete_success">Zpráva byla úspěšně smazána</string>
<string name="message_share">Podíl</string>
<string name="message_print">Vytisknout</string>
<string name="message_subject">Téma</string>
<string name="message_content">Obsah</string>
<string name="message_send_successful">Zpráva úspěšně odeslána</string>
<string name="message_required_recipients">Musíte vybrat alespoň 1 příjemce</string>
<string name="message_content_min_length">Obsah zprávy musí mít alespoň 3 znaky</string>
<plurals name="message_number_item">
<item quantity="one">%d zpráva</item>
<item quantity="few">%d zprávy</item>
<item quantity="many">%d zprávy</item>
<item quantity="other">%d zprávy</item>
</plurals>
<plurals name="message_new_items">
<item quantity="one">Nová zpráva</item>
<item quantity="few">Nové zprávy</item>
<item quantity="many">Nové zprávy</item>
<item quantity="other">Nové zprávy</item>
</plurals>
<plurals name="message_notify_new_items">
<item quantity="one">Obdrželi jste %1$d zprávu</item>
<item quantity="few">Obdrželi jste %1$d zpráv</item>
<item quantity="many">Obdrželi jste %1$d zpráv</item>
<item quantity="other">Obdrželi jste %1$d zpráv</item>
</plurals>
<!--Note-->
<string name="note_no_items">Žádné informace o poznámkách</string>
<string name="note_points">Body</string>
<plurals name="note_number_item">
<item quantity="one">%d poznámka</item>
<item quantity="few">%d poznámky</item>
<item quantity="many">%d poznámky</item>
<item quantity="other">%d poznámky</item>
</plurals>
<plurals name="note_new_items">
<item quantity="one">Nová poznámka</item>
<item quantity="few">Nové poznámky</item>
<item quantity="many">Nové poznámky</item>
<item quantity="other">Nové poznámky</item>
</plurals>
<plurals name="note_notify_new_items">
<item quantity="one">Máte %1$d novou poznámku</item>
<item quantity="few">Máte %1$d nové poznámky</item>
<item quantity="many">Máte %1$d nové poznámky</item>
<item quantity="other">Máte %1$d nové poznámky</item>
</plurals>
<!--Praise-->
<plurals name="praise_number_item">
<item quantity="one">%d chvála</item>
<item quantity="few">%d chvály</item>
<item quantity="many">%d chvály</item>
<item quantity="other">%d chvály</item>
</plurals>
<plurals name="praise_new_items">
<item quantity="one">Nová chvála</item>
<item quantity="few">Nové chvály</item>
<item quantity="many">Nové chvály</item>
<item quantity="other">Nové chvály</item>
</plurals>
<plurals name="praise_notify_new_items">
<item quantity="one">Máte %1$d novou chválu</item>
<item quantity="few">Máte %1$d nové chvály</item>
<item quantity="many">Máte %1$d nové chvály</item>
<item quantity="other">Máte %1$d nové chvály</item>
</plurals>
<!--Neutral notes-->
<plurals name="neutral_note_number_item">
<item quantity="one">%d neutrální poznámka</item>
<item quantity="few">%d neutrální poznámky</item>
<item quantity="many">%d neutrální poznámky</item>
<item quantity="other">%d neutrální poznámky</item>
</plurals>
<plurals name="neutral_note_new_items">
<item quantity="one">Nová neutrální poznámka</item>
<item quantity="few">Nové neutrální poznámky</item>
<item quantity="many">Nové neutrální poznámky</item>
<item quantity="other">Nové neutrální poznámky</item>
</plurals>
<plurals name="neutral_note_notify_new_items">
<item quantity="one">Máte %1$d novou neutrální pozornost</item>
<item quantity="few">Máte %1$d nové neutrální komentáře</item>
<item quantity="many">Máte %1$d nové neutrální komentáře</item>
<item quantity="other">Máte %1$d nové neutrální komentáře</item>
</plurals>
<!--Homework-->
<string name="homework_no_items">Žádný domácí úkol</string>
<string name="homework_mark_as_done">Označit jako hotové</string>
<string name="homework_mark_as_undone">Neudělané</string>
<string name="homework_attachments">Přílohy</string>
<!--Lucky number-->
<string name="lucky_number_title">Šťastné číslo</string>
<string name="lucky_number_header">Dnešní šťastné číslo je</string>
<string name="lucky_number_empty">Žádné informace o šťastném čísle</string>
<string name="lucky_number_notify_new_item_title">Šťastné číslo pro dnešek</string>
<string name="lucky_number_notify_new_item">Dnes je šťastným číslem: %d</string>
<!--Mobile devices-->
<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ě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>
<string name="mobile_device_pin">PIN</string>
<!--School and teachers-->
<string name="schoolandteachers_title">Škola a učitelé</string>
<!--School-->
<string name="school_title">Škola</string>
<string name="school_no_info">Žádné informace o škole</string>
<string name="school_name">Školní jméno</string>
<string name="school_address">Adresa školy</string>
<string name="school_telephone">Telefon</string>
<string name="school_headmaster">Jméno ředitele</string>
<string name="school_pedagogue">Jméno pedagoga</string>
<string name="school_address_button">Zobrazit na mapě</string>
<string name="school_telephone_button">Volání</string>
<!--Teacher-->
<string name="teachers_title">Učitelé</string>
<string name="teacher_no_items">Žádné informace o učitelích</string>
<string name="teacher_no_subject">Žádný předmět</string>
<!--Account-->
<string name="account_add_new">Přidat účet</string>
<string name="account_logout">Odhlásit se</string>
<string name="account_confirm">Chcete se odhlásit z aktivního studenta?</string>
<string name="account_logout_student">Odhlášení studentů</string>
<string name="account_type_student">Studentský účet</string>
<string name="account_type_parent">Rodičovský účet</string>
<string name="account_login_mobile_api">Režimu Mobíle API</string>
<string name="account_login_hybrid">Hybridní režim</string>
<!--About-->
<string name="about_version">Verze aplikace</string>
<string name="about_contributor">Tvůrci</string>
<string name="about_contributor_summary">Seznam vývojářů Wulkanowy</string>
<string name="about_feedback">Nahlásit chybu</string>
<string name="about_feedback_summary">Pošlete hlášení o chybě e-mailem</string>
<string name="about_faq">FAQ</string>
<string name="about_faq_summary">Přečtěte si často kladené otázky</string>
<string name="about_discord">Server Discord</string>
<string name="about_discord_summary">Připojte se ke komunitě Wulkanowy</string>
<string name="about_privacy">Zásady ochrany osobních údajů</string>
<string name="about_privacy_summary">Pravidla pro shromažďování osobních údajů</string>
<string name="about_homepage">Domovská stránka</string>
<string name="about_homepage_summary">Navštivte web a pomozte s vývojem aplikace</string>
<string name="about_licenses">Licence</string>
<string name="about_licenses_summary">Licence knihoven použitých v aplikaci</string>
<!--Licenses-->
<string name="license_dialog_title">Licence</string>
<!--Contributor-->
<string name="contributor_avatar_description">Avatar</string>
<string name="contributor_see_more">Zobrazit více na GitHub</string>
<!--Log viewer-->
<string name="logviewer_share">Sdílejte protokoly</string>
<string name="logviewer_refresh">Obnovit</string>
<!--Error dialog-->
<string name="dialog_error_check_update">Kontrola aktualizací</string>
<string name="dialog_error_check_update_message">Před nahlášením chyby nejprve zkontrolujte, zda je k dispozici aktualizace s opravou chyby</string>
<!--Generic-->
<string name="all_content">Obsah</string>
<string name="all_retry">Zkuste to znovu</string>
<string name="all_description">Popis</string>
<string name="all_no_description">Bez popisu</string>
<string name="all_teacher">Učitel</string>
<string name="all_date">Datum</string>
<string name="all_entry_date">Datum vstupu</string>
<string name="all_color">Barva</string>
<string name="all_details">Detaily</string>
<string name="all_category">Kategorie</string>
<string name="all_close">Zavřít</string>
<string name="all_no_data">Žádná data</string>
<string name="all_subject">Předmět</string>
<string name="all_prev">Předchozí</string>
<string name="all_next">Další</string>
<string name="all_search">Vyhledávání</string>
<string name="all_search_hint">Vyhledávání…</string>
<!--Timetable Widget-->
<string name="widget_timetable_no_items">Žádné lekce</string>
<string name="widget_timetable_theme_title">Vyberte téma</string>
<string name="widget_timetable_theme_light">Světlý</string>
<string name="widget_timetable_theme_dark">Tmavý</string>
<string name="widget_timetable_theme_system">Téma systému</string>
<!--Preferences-->
<string name="pref_view_header">Vzhled</string>
<string name="pref_view_list">Výchozí zobrazení</string>
<string name="pref_view_grade_average_mode">Výpočet koncoročního průměru</string>
<string name="pref_view_grade_average_force_calc">Vynutit průměrný výpočet podle aplikace</string>
<string name="pref_view_present">Zobrazit přítomnost v účasti</string>
<string name="pref_view_app_theme">Téma aplikace</string>
<string name="pref_view_expand_grade">Rozbalit známky</string>
<string name="pref_view_timetable_show_timers">Označte aktuální lekci v plánu lekce</string>
<string name="pref_view_timetable_show_groups">Ukázat skupiny vedle předmětů v plánu lekce</string>
<string name="pref_view_grade_statistics_list">Ukázat seznam grafů ve třídních známkách</string>
<string name="pref_view_timetable_show_whole_class">Ukázat lekce pro celou třídu</string>
<string name="pref_view_subjects_without_grades">Ukázat předměty bez známek v \"Známky\"</string>
<string name="pref_view_grade_color_scheme">Známky barevné schéma</string>
<string name="pref_view_grade_sorting_mode">Předměty seřazené v \"Známky\"</string>
<string name="pref_view_app_language">Jazyk aplikace</string>
<string name="pref_notify_header">Oznámení</string>
<string name="pref_notify_switch">Ukázat notifikace</string>
<string name="pref_notify_upcoming_lessons_switch">Ukázat nadcházející oznámení o lekci</string>
<string name="pref_notify_fix_sync_issues">Opravte problémy se synchronizací a upozorněním</string>
<string name="pref_notify_fix_sync_issues_message">Ve vašem zařízení mohou nastat problémy se synchronizací dat a oznámenímii.\n\nChcete-li je opravit, přidejte Wulkanowy do funkce Autostart a vypněte optimalizaci/úsporu baterie v nastavení systému telefonu.</string>
<string name="pref_notify_fix_sync_issues_settings_button">Jdi do nastavení</string>
<string name="pref_notify_debug_switch">Ukázat oznámení o ladění</string>
<string name="pref_services_header">Synchronizace</string>
<string name="pref_services_switch">Automatická aktualizace</string>
<string name="pref_services_suspended">Pozastaveno na dovolené</string>
<string name="pref_services_interval">Interval aktualizací</string>
<string name="pref_services_wifi">Pouze Wi-Fi</string>
<string name="pref_services_force_sync">Nyní synchronizovat</string>
<string name="pref_services_message_sync_success">Synchronizováno!</string>
<string name="pref_services_message_sync_failed">Synchronizace se nezdařila</string>
<string name="pref_services_sync_in_progress">Probíhá synchronizace</string>
<string name="pref_services_dialog_force_sync_title">Synchronizace</string>
<string name="pref_services_dialog_force_sync_summary"> Ruční synchronizace neobnoví zobrazení aplikace.
\nChcete-li zobrazit synchronizovaná data, restartujte aplikaci po synchronizaci.
</string>
<string name="pref_other_header">Jiný</string>
<string name="pref_other_grade_modifier_plus">Hodnota plusu</string>
<string name="pref_other_grade_modifier_minus">Hodnota mínusu</string>
<string name="pref_other_fill_message_content">Odpovědět s historií zpráv</string>
<!--Notification Channels-->
<string name="channel_new_entries">Nové položky v deník</string>
<string name="channel_new_grades">Nové známky</string>
<string name="channel_lucky_number">Šťastné číslo</string>
<string name="channel_new_message">Nové zprávy</string>
<string name="channel_new_notes">Nové poznámky</string>
<string name="channel_push">Oznámení push</string>
<string name="channel_upcoming_lessons">Nadcházející lekce</string>
<string name="channel_debug">Ladění</string>
<!--Colors-->
<string name="all_black">Černý</string>
<string name="all_red">Červený</string>
<string name="all_blue">Modrý</string>
<string name="all_green">Zelený</string>
<string name="all_purple">Nachový</string>
<string name="all_empty_color">Žádná barva</string>
<!--Others-->
<string name="all_copied">Zkopírováno</string>
<string name="all_undo">Vrátit</string>
<!--Errors-->
<string name="error_no_internet">Žádné internetové připojení</string>
<string name="error_timeout">Vypršel časový limit připojení k denik</string>
<string name="error_login_failed">Přihlášení selhalo. Zkuste to znovu nebo restartujte aplikaci</string>
<string name="error_password_change_required">Je vyžadována změna hesla</string>
<string name="error_service_unavailable">Probíhá údržba UONET+ deník. Zkuste to později znovu</string>
<string name="error_unknown">Došlo k neočekávané chybě</string>
<string name="error_feature_disabled">Funkce deaktivována vaší školou</string>
<string name="error_feature_not_available">Funkce není k dispozici. Přihlaste se v jiném režimu než Mobile API</string>
</resources>

View File

@ -12,6 +12,7 @@
<item>Pусский</item> <item>Pусский</item>
<item>Українська</item> <item>Українська</item>
<item>Deutsch</item> <item>Deutsch</item>
<item>Čeština</item>
</string-array> </string-array>
<string-array name="services_interval_entries"> <string-array name="services_interval_entries">
<item>15 Minuten</item> <item>15 Minuten</item>
@ -29,6 +30,10 @@
<item>0,5</item> <item>0,5</item>
<item>0,75</item> <item>0,75</item>
</string-array> </string-array>
<string-array name="grade_sorting_mode_entries">
<item>Alphabetic</item>
<item>By date</item>
</string-array>
<string-array name="grade_color_scheme_entries"> <string-array name="grade_color_scheme_entries">
<item>Dzienniczek+</item> <item>Dzienniczek+</item>
<item>Wulkanowy</item> <item>Wulkanowy</item>

View File

@ -154,6 +154,8 @@
<string name="attendance_excused_lateness">Entschuldigte Verspätung</string> <string name="attendance_excused_lateness">Entschuldigte Verspätung</string>
<string name="attendance_unexcused_lateness">Unentschuldigte Verspätung</string> <string name="attendance_unexcused_lateness">Unentschuldigte Verspätung</string>
<string name="attendance_present">Anwesend</string> <string name="attendance_present">Anwesend</string>
<string name="attendance_deleted">Deleted</string>
<string name="attendance_unknown">Unknown</string>
<string name="attendance_number">Lektion Nummer</string> <string name="attendance_number">Lektion Nummer</string>
<string name="attendance_no_items">Keine Einträgen</string> <string name="attendance_no_items">Keine Einträgen</string>
<plurals name="attendance_number_absences"> <plurals name="attendance_number_absences">
@ -222,6 +224,32 @@
<item quantity="one">Du hast %1$d Eintrag bekommen</item> <item quantity="one">Du hast %1$d Eintrag bekommen</item>
<item quantity="other">Du hast %1$d Eintragen bekommen</item> <item quantity="other">Du hast %1$d Eintragen bekommen</item>
</plurals> </plurals>
<!--Praise-->
<plurals name="praise_number_item">
<item quantity="one">%d praise</item>
<item quantity="other">%d praises</item>
</plurals>
<plurals name="praise_new_items">
<item quantity="one">New praise</item>
<item quantity="other">New praises</item>
</plurals>
<plurals name="praise_notify_new_items">
<item quantity="one">You received %1$d praise</item>
<item quantity="other">You received %1$d praises</item>
</plurals>
<!--Neutral notes-->
<plurals name="neutral_note_number_item">
<item quantity="one">%d neutral note</item>
<item quantity="other">%d neutral notes</item>
</plurals>
<plurals name="neutral_note_new_items">
<item quantity="one">New neutral note</item>
<item quantity="other">New neutral notes</item>
</plurals>
<plurals name="neutral_note_notify_new_items">
<item quantity="one">You received %1$d neutral note</item>
<item quantity="other">You received %1$d neutral notes</item>
</plurals>
<!--Homework--> <!--Homework-->
<string name="homework_no_items">Keine Informationen über Hausaufgaben</string> <string name="homework_no_items">Keine Informationen über Hausaufgaben</string>
<string name="homework_mark_as_done">Gemacht</string> <string name="homework_mark_as_done">Gemacht</string>
@ -327,9 +355,12 @@
<string name="pref_view_app_theme">Thema der Anwendung</string> <string name="pref_view_app_theme">Thema der Anwendung</string>
<string name="pref_view_expand_grade">Noten erweitern</string> <string name="pref_view_expand_grade">Noten erweitern</string>
<string name="pref_view_timetable_show_timers">Aktuelle Lektion im Stundenplan markieren</string> <string name="pref_view_timetable_show_timers">Aktuelle Lektion im Stundenplan markieren</string>
<string name="pref_view_timetable_show_groups">Show groups next to subjects in timetable</string>
<string name="pref_view_grade_statistics_list">Liste der Diagramme in Klassenbewertungen anzeigen</string> <string name="pref_view_grade_statistics_list">Liste der Diagramme in Klassenbewertungen anzeigen</string>
<string name="pref_view_timetable_show_whole_class">Unterricht der ganzen Klasse anzeigen</string> <string name="pref_view_timetable_show_whole_class">Unterricht der ganzen Klasse anzeigen</string>
<string name="pref_view_subjects_without_grades">Show subjects without grades in Grades</string>
<string name="pref_view_grade_color_scheme">Farbschema der Noten</string> <string name="pref_view_grade_color_scheme">Farbschema der Noten</string>
<string name="pref_view_grade_sorting_mode">Subjects sorting in \"Grades\"</string>
<string name="pref_view_app_language">App Sprache</string> <string name="pref_view_app_language">App Sprache</string>
<string name="pref_notify_header">Benachrichtigungen</string> <string name="pref_notify_header">Benachrichtigungen</string>
<string name="pref_notify_switch">Benachrichtigungen anzeigen</string> <string name="pref_notify_switch">Benachrichtigungen anzeigen</string>

View File

@ -12,6 +12,7 @@
<item>Pусский</item> <item>Pусский</item>
<item>Українська</item> <item>Українська</item>
<item>Deutsch</item> <item>Deutsch</item>
<item>Čeština</item>
</string-array> </string-array>
<string-array name="services_interval_entries"> <string-array name="services_interval_entries">
<item>15 minut</item> <item>15 minut</item>

View File

@ -400,7 +400,7 @@
<string name="pref_view_timetable_show_whole_class">Pokazuj lekcje całej klasy</string> <string name="pref_view_timetable_show_whole_class">Pokazuj lekcje całej klasy</string>
<string name="pref_view_subjects_without_grades">Pokazuj przedmioty bez ocen w Oceny</string> <string name="pref_view_subjects_without_grades">Pokazuj przedmioty bez ocen w Oceny</string>
<string name="pref_view_grade_color_scheme">Schemat kolorów ocen</string> <string name="pref_view_grade_color_scheme">Schemat kolorów ocen</string>
<string name="pref_view_grade_sorting_mode">Sortowanie przedmiotów w "Oceny"</string> <string name="pref_view_grade_sorting_mode">Sortowanie przedmiotów w \"Oceny\"</string>
<string name="pref_view_app_language">Język aplikacji</string> <string name="pref_view_app_language">Język aplikacji</string>
<string name="pref_notify_header">Powiadomienia</string> <string name="pref_notify_header">Powiadomienia</string>
<string name="pref_notify_switch">Pokazuj powiadomienia</string> <string name="pref_notify_switch">Pokazuj powiadomienia</string>
@ -448,9 +448,11 @@
<!--Errors--> <!--Errors-->
<string name="error_no_internet">Brak połączenia z internetem</string> <string name="error_no_internet">Brak połączenia z internetem</string>
<string name="error_timeout">Upłynął limit czasu na połączenie z dziennikiem</string> <string name="error_timeout">Upłynął limit czasu na połączenie z dziennikiem</string>
<string name="error_login_failed">Logowanie nie powiodło się. Spróbuj ponownie lub zrestartuj aplikację</string> <string name="error_login_failed">Logowanie nie powiodło się. Spróbuj ponownie</string>
<string name="error_password_change_required">Wymagana zmiana hasła</string> <string name="error_password_change_required">Wymagana zmiana hasła</string>
<string name="error_service_unavailable">Trwa przerwa techniczna dziennika UONET+. Spróbuj ponownie później</string> <string name="error_service_unavailable">Trwa przerwa techniczna dziennika UONET+. Spróbuj ponownie później</string>
<string name="error_unknown_uonet">Wystąpił nieznany błąd dziennika UONET+. Spróbuj ponownie później</string>
<string name="error_unknown_app">Wystąpił nieznany błąd aplikacji</string>
<string name="error_unknown">Wystąpił nieoczekiwany błąd</string> <string name="error_unknown">Wystąpił nieoczekiwany błąd</string>
<string name="error_feature_disabled">Funkcja wyłączona przez szkołę</string> <string name="error_feature_disabled">Funkcja wyłączona przez szkołę</string>
<string name="error_feature_not_available">Funkcja niedostępna. Zaloguj się w trybie innym niż Mobilne API</string> <string name="error_feature_not_available">Funkcja niedostępna. Zaloguj się w trybie innym niż Mobilne API</string>

View File

@ -12,6 +12,7 @@
<item>Pусский</item> <item>Pусский</item>
<item>Українська</item> <item>Українська</item>
<item>Deutsch</item> <item>Deutsch</item>
<item>Čeština</item>
</string-array> </string-array>
<string-array name="services_interval_entries"> <string-array name="services_interval_entries">
<item>15 минут</item> <item>15 минут</item>
@ -29,6 +30,10 @@
<item>0,5</item> <item>0,5</item>
<item>0,75</item> <item>0,75</item>
</string-array> </string-array>
<string-array name="grade_sorting_mode_entries">
<item>Алфавитный</item>
<item>По дате</item>
</string-array>
<string-array name="grade_color_scheme_entries"> <string-array name="grade_color_scheme_entries">
<item>Dzienniczek+</item> <item>Dzienniczek+</item>
<item>Wulkanowy</item> <item>Wulkanowy</item>
@ -36,8 +41,8 @@
</string-array> </string-array>
<string-array name="grade_average_mode_entries"> <string-array name="grade_average_mode_entries">
<item>Средняя оценка со 2 семестра</item> <item>Средняя оценка со 2 семестра</item>
<item>Average of grades from both semesters</item> <item>Средняя оценка с двух семестров</item>
<item>Average of grades from the whole year</item> <item>Средняя оценок со всего года</item>
</string-array> </string-array>
<string-array name="timetable_show_whole_class_entries"> <string-array name="timetable_show_whole_class_entries">
<item>Не показывать</item> <item>Не показывать</item>

View File

@ -108,16 +108,16 @@
<item quantity="other">Новые оценки</item> <item quantity="other">Новые оценки</item>
</plurals> </plurals>
<plurals name="grade_new_items_predicted"> <plurals name="grade_new_items_predicted">
<item quantity="one">New predicted grade</item> <item quantity="one">Новая ожидаемая оценка</item>
<item quantity="few">New predicted grades</item> <item quantity="few">Новые ожидаемые оценки</item>
<item quantity="many">New predicted grades</item> <item quantity="many">Новые ожидаемые оценки</item>
<item quantity="other">New predicted grades</item> <item quantity="other">Новые ожидаемые оценки</item>
</plurals> </plurals>
<plurals name="grade_new_items_final"> <plurals name="grade_new_items_final">
<item quantity="one">New final grade</item> <item quantity="one">Новая итоговая оценка</item>
<item quantity="few">New final grades</item> <item quantity="few">Новые итоговые оценки</item>
<item quantity="many">New final grades</item> <item quantity="many">Новые итоговые оценки</item>
<item quantity="other">New final grades</item> <item quantity="other">Новые итоговые оценки</item>
</plurals> </plurals>
<plurals name="grade_notify_new_items"> <plurals name="grade_notify_new_items">
<item quantity="one">Вы получили %1$d оценку</item> <item quantity="one">Вы получили %1$d оценку</item>
@ -126,16 +126,16 @@
<item quantity="other">Вы получили %1$d оценок</item> <item quantity="other">Вы получили %1$d оценок</item>
</plurals> </plurals>
<plurals name="grade_notify_new_items_predicted"> <plurals name="grade_notify_new_items_predicted">
<item quantity="one">You received %1$d predicted grade</item> <item quantity="one">Вы получили %1$d ожидаемую оценку</item>
<item quantity="few">You received %1$d predicted grades</item> <item quantity="few">Вы получили %1$d ожидаемые оценки</item>
<item quantity="many">You received %1$d predicted grades</item> <item quantity="many">Вы получили %1$d ожидаемых оценок</item>
<item quantity="other">You received %1$d predicted grades</item> <item quantity="other">Вы получили %1$d ожидаемых оценок</item>
</plurals> </plurals>
<plurals name="grade_notify_new_items_final"> <plurals name="grade_notify_new_items_final">
<item quantity="one">You received %1$d final grade</item> <item quantity="one">Вы получили %1$d финальную оценку</item>
<item quantity="few">You received %1$d final grades</item> <item quantity="few">Вы получили %1$d итоговых оценки</item>
<item quantity="many">You received %1$d final grades</item> <item quantity="many">Вы получили %1$d итоговых оценок</item>
<item quantity="other">You received %1$d final grades</item> <item quantity="other">Вы получили %1$d финальные оценки</item>
</plurals> </plurals>
<!--Timetable--> <!--Timetable-->
<string name="timetable_lesson">Урок</string> <string name="timetable_lesson">Урок</string>
@ -168,6 +168,8 @@
<string name="attendance_excused_lateness">Опоздание по уважительным причинам</string> <string name="attendance_excused_lateness">Опоздание по уважительным причинам</string>
<string name="attendance_unexcused_lateness">Опоздание по неуважительным причинам</string> <string name="attendance_unexcused_lateness">Опоздание по неуважительным причинам</string>
<string name="attendance_present">Присутствие</string> <string name="attendance_present">Присутствие</string>
<string name="attendance_deleted">Удалено</string>
<string name="attendance_unknown">Неизвестно</string>
<string name="attendance_number">Урок №</string> <string name="attendance_number">Урок №</string>
<string name="attendance_no_items">Данные не найдены</string> <string name="attendance_no_items">Данные не найдены</string>
<plurals name="attendance_number_absences"> <plurals name="attendance_number_absences">
@ -204,8 +206,8 @@
<string name="message_move_to_bin">Перенести в корзину</string> <string name="message_move_to_bin">Перенести в корзину</string>
<string name="message_delete_forever">Удалить навсегда</string> <string name="message_delete_forever">Удалить навсегда</string>
<string name="message_delete_success">Сообщение успешно удалено</string> <string name="message_delete_success">Сообщение успешно удалено</string>
<string name="message_share">Share</string> <string name="message_share">Поделиться</string>
<string name="message_print">Print</string> <string name="message_print">Печать</string>
<string name="message_subject">Тема</string> <string name="message_subject">Тема</string>
<string name="message_content">Текст</string> <string name="message_content">Текст</string>
<string name="message_send_successful">Сообщение успешно отправлено</string> <string name="message_send_successful">Сообщение успешно отправлено</string>
@ -250,6 +252,44 @@
<item quantity="many">Вы получили %1$d предупреждений</item> <item quantity="many">Вы получили %1$d предупреждений</item>
<item quantity="other">Вы получили %1$d предупреждений</item> <item quantity="other">Вы получили %1$d предупреждений</item>
</plurals> </plurals>
<!--Praise-->
<plurals name="praise_number_item">
<item quantity="one">%d похвала</item>
<item quantity="few">%d похвала</item>
<item quantity="many">%d похвала</item>
<item quantity="other">%d похвала</item>
</plurals>
<plurals name="praise_new_items">
<item quantity="one">Новая похвала</item>
<item quantity="few">Новые похвалы</item>
<item quantity="many">Новые свершения</item>
<item quantity="other">Новые похвалы</item>
</plurals>
<plurals name="praise_notify_new_items">
<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>
<!--Neutral notes-->
<plurals name="neutral_note_number_item">
<item quantity="one">%d нейтральное замечание</item>
<item quantity="few">%d нейтральных замечания</item>
<item quantity="many">%d нейтральных замечаний</item>
<item quantity="other">%d нейтральных замечаний</item>
</plurals>
<plurals name="neutral_note_new_items">
<item quantity="one">Новое нейтральное замечание</item>
<item quantity="few">Новые нейтральные замечания</item>
<item quantity="many">Новые нейтральные замечания</item>
<item quantity="other">Новые нейтральные замечания</item>
</plurals>
<plurals name="neutral_note_notify_new_items">
<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>
<!--Homework--> <!--Homework-->
<string name="homework_no_items">Нет домашних заданий</string> <string name="homework_no_items">Нет домашних заданий</string>
<string name="homework_mark_as_done">сделанный</string> <string name="homework_mark_as_done">сделанный</string>
@ -291,10 +331,10 @@
<string name="account_logout">Выйти</string> <string name="account_logout">Выйти</string>
<string name="account_confirm">Вы точно хотите выйти из данного аккаунта?</string> <string name="account_confirm">Вы точно хотите выйти из данного аккаунта?</string>
<string name="account_logout_student">Выйти</string> <string name="account_logout_student">Выйти</string>
<string name="account_type_student">Student account</string> <string name="account_type_student">Профиль ученика</string>
<string name="account_type_parent">Parent account</string> <string name="account_type_parent">Профиль родителя</string>
<string name="account_login_mobile_api">Mobile API mode</string> <string name="account_login_mobile_api">Режим Mobile API</string>
<string name="account_login_hybrid">Hybrid mode</string> <string name="account_login_hybrid">Гибридный режим</string>
<!--About--> <!--About-->
<string name="about_version">Версия приложения</string> <string name="about_version">Версия приложения</string>
<string name="about_contributor">Разработчики</string> <string name="about_contributor">Разработчики</string>
@ -353,11 +393,14 @@
<string name="pref_view_grade_average_force_calc">Принудительно высчитать среднюю оценку через приложение</string> <string name="pref_view_grade_average_force_calc">Принудительно высчитать среднюю оценку через приложение</string>
<string name="pref_view_present">Показывать присутствия в посещаемости</string> <string name="pref_view_present">Показывать присутствия в посещаемости</string>
<string name="pref_view_app_theme">Тема приложения</string> <string name="pref_view_app_theme">Тема приложения</string>
<string name="pref_view_expand_grade">Больше оценок</string> <string name="pref_view_expand_grade">Разворачивать оценки</string>
<string name="pref_view_timetable_show_timers">Отмечать текущий урок в расписании</string> <string name="pref_view_timetable_show_timers">Отмечать текущий урок в расписании</string>
<string name="pref_view_timetable_show_groups">Показать группу возле предмета в расписании</string>
<string name="pref_view_grade_statistics_list">Показывать диаграммы в оценках класса</string> <string name="pref_view_grade_statistics_list">Показывать диаграммы в оценках класса</string>
<string name="pref_view_timetable_show_whole_class">Показать уроки всего класса</string> <string name="pref_view_timetable_show_whole_class">Показать уроки всего класса</string>
<string name="pref_view_subjects_without_grades">Показывать предметы без оценок в \"Оценках\"</string>
<string name="pref_view_grade_color_scheme">Схема цветов оценок</string> <string name="pref_view_grade_color_scheme">Схема цветов оценок</string>
<string name="pref_view_grade_sorting_mode">Сортировка предметов в \"Оценках\"</string>
<string name="pref_view_app_language">Язык приложения</string> <string name="pref_view_app_language">Язык приложения</string>
<string name="pref_notify_header">Уведомления</string> <string name="pref_notify_header">Уведомления</string>
<string name="pref_notify_switch">Показывать уведомления</string> <string name="pref_notify_switch">Показывать уведомления</string>

View File

@ -12,6 +12,7 @@
<item>Pусский</item> <item>Pусский</item>
<item>Українська</item> <item>Українська</item>
<item>Deutsch</item> <item>Deutsch</item>
<item>Čeština</item>
</string-array> </string-array>
<string-array name="services_interval_entries"> <string-array name="services_interval_entries">
<item>15 хвилин</item> <item>15 хвилин</item>
@ -29,6 +30,10 @@
<item>0,5</item> <item>0,5</item>
<item>0,75</item> <item>0,75</item>
</string-array> </string-array>
<string-array name="grade_sorting_mode_entries">
<item>Alphabetic</item>
<item>By date</item>
</string-array>
<string-array name="grade_color_scheme_entries"> <string-array name="grade_color_scheme_entries">
<item>Dzienniczek+</item> <item>Dzienniczek+</item>
<item>Wulkanowy</item> <item>Wulkanowy</item>

View File

@ -168,6 +168,8 @@
<string name="attendance_excused_lateness">Спізнення з поважних причин</string> <string name="attendance_excused_lateness">Спізнення з поважних причин</string>
<string name="attendance_unexcused_lateness">Спізнення з не поважних причин</string> <string name="attendance_unexcused_lateness">Спізнення з не поважних причин</string>
<string name="attendance_present">Присутність</string> <string name="attendance_present">Присутність</string>
<string name="attendance_deleted">Deleted</string>
<string name="attendance_unknown">Unknown</string>
<string name="attendance_number">Номер уроку</string> <string name="attendance_number">Номер уроку</string>
<string name="attendance_no_items">Брак записів</string> <string name="attendance_no_items">Брак записів</string>
<plurals name="attendance_number_absences"> <plurals name="attendance_number_absences">
@ -250,6 +252,44 @@
<item quantity="many">%1$d нових зауважень</item> <item quantity="many">%1$d нових зауважень</item>
<item quantity="other">%1$d нових зауважень</item> <item quantity="other">%1$d нових зауважень</item>
</plurals> </plurals>
<!--Praise-->
<plurals name="praise_number_item">
<item quantity="one">%d praise</item>
<item quantity="few">%d praises</item>
<item quantity="many">%d praises</item>
<item quantity="other">%d praises</item>
</plurals>
<plurals name="praise_new_items">
<item quantity="one">New praise</item>
<item quantity="few">New praises</item>
<item quantity="many">New praises</item>
<item quantity="other">New praises</item>
</plurals>
<plurals name="praise_notify_new_items">
<item quantity="one">You received %1$d praise</item>
<item quantity="few">You received %1$d praises</item>
<item quantity="many">You received %1$d praises</item>
<item quantity="other">You received %1$d praises</item>
</plurals>
<!--Neutral notes-->
<plurals name="neutral_note_number_item">
<item quantity="one">%d neutral note</item>
<item quantity="few">%d neutral notes</item>
<item quantity="many">%d neutral notes</item>
<item quantity="other">%d neutral notes</item>
</plurals>
<plurals name="neutral_note_new_items">
<item quantity="one">New neutral note</item>
<item quantity="few">New neutral notes</item>
<item quantity="many">New neutral notes</item>
<item quantity="other">New neutral notes</item>
</plurals>
<plurals name="neutral_note_notify_new_items">
<item quantity="one">You received %1$d neutral note</item>
<item quantity="few">You received %1$d neutral notes</item>
<item quantity="many">You received %1$d neutral notes</item>
<item quantity="other">You received %1$d neutral notes</item>
</plurals>
<!--Homework--> <!--Homework-->
<string name="homework_no_items">Брак домашніх завдань</string> <string name="homework_no_items">Брак домашніх завдань</string>
<string name="homework_mark_as_done">Позначити як зроблене</string> <string name="homework_mark_as_done">Позначити як зроблене</string>
@ -355,9 +395,12 @@
<string name="pref_view_app_theme">Тема додатку</string> <string name="pref_view_app_theme">Тема додатку</string>
<string name="pref_view_expand_grade">Більше оцінок</string> <string name="pref_view_expand_grade">Більше оцінок</string>
<string name="pref_view_timetable_show_timers">Позначити поточний урок у розкладі</string> <string name="pref_view_timetable_show_timers">Позначити поточний урок у розкладі</string>
<string name="pref_view_timetable_show_groups">Show groups next to subjects in timetable</string>
<string name="pref_view_grade_statistics_list">Показувати діаграми в оцінках класу</string> <string name="pref_view_grade_statistics_list">Показувати діаграми в оцінках класу</string>
<string name="pref_view_timetable_show_whole_class">Показати уроки всього класу</string> <string name="pref_view_timetable_show_whole_class">Показати уроки всього класу</string>
<string name="pref_view_subjects_without_grades">Show subjects without grades in Grades</string>
<string name="pref_view_grade_color_scheme">Схема кольорів оцінок</string> <string name="pref_view_grade_color_scheme">Схема кольорів оцінок</string>
<string name="pref_view_grade_sorting_mode">Subjects sorting in \"Grades\"</string>
<string name="pref_view_app_language">Мова додатку</string> <string name="pref_view_app_language">Мова додатку</string>
<string name="pref_notify_header">Повідомлення</string> <string name="pref_notify_header">Повідомлення</string>
<string name="pref_notify_switch">Показувати повідомлення</string> <string name="pref_notify_switch">Показувати повідомлення</string>

View File

@ -31,6 +31,7 @@
<item>Pусский</item> <item>Pусский</item>
<item>Українська</item> <item>Українська</item>
<item>Deutsch</item> <item>Deutsch</item>
<item>Čeština</item>
</string-array> </string-array>
<string-array name="app_language_values" translatable="false"> <string-array name="app_language_values" translatable="false">
<item>system</item> <item>system</item>
@ -39,6 +40,7 @@
<item>ru</item> <item>ru</item>
<item>uk</item> <item>uk</item>
<item>de</item> <item>de</item>
<item>cs</item>
</string-array> </string-array>
<string-array name="services_interval_entries"> <string-array name="services_interval_entries">

View File

@ -472,13 +472,21 @@
<string name="all_copied">Copied</string> <string name="all_copied">Copied</string>
<string name="all_undo">Undo</string> <string name="all_undo">Undo</string>
<!--Update helper-->
<string name="update_download_started">Start downloading update…</string>
<string name="update_download_success">An update has just been downloaded.</string>
<string name="update_download_success_button">Restart</string>
<string name="update_failed">Update failed! Wulkanowy may not function properly. Consider updating</string>
<!--Errors--> <!--Errors-->
<string name="error_no_internet">No internet connection</string> <string name="error_no_internet">No internet connection</string>
<string name="error_timeout">Connection to the register timed out</string> <string name="error_timeout">Connection to the register timed out</string>
<string name="error_login_failed">Login failed. Try again or restart the app</string> <string name="error_login_failed">Login failed. Try again</string>
<string name="error_password_change_required">Password change required</string> <string name="error_password_change_required">Password change required</string>
<string name="error_service_unavailable">Maintenance underway UONET + register. Try again later</string> <string name="error_service_unavailable">Maintenance underway UONET + register. Try again later</string>
<string name="error_unknown_uonet">Unknown UONET + register error. Try again later</string>
<string name="error_unknown_app">Unknown application error</string>
<string name="error_unknown">An unexpected error occurred</string> <string name="error_unknown">An unexpected error occurred</string>
<string name="error_feature_disabled">Feature disabled by your school</string> <string name="error_feature_disabled">Feature disabled by your school</string>
<string name="error_feature_not_available">Feature not available. Login in a mode other than Mobile API</string> <string name="error_feature_not_available">Feature not available. Login in a mode other than Mobile API</string>

View File

@ -23,7 +23,7 @@
<item name="android:windowBackground">@drawable/layer_splash_background</item> <item name="android:windowBackground">@drawable/layer_splash_background</item>
</style> </style>
<style name="WulkanowyTheme.WidgetAccountSwitcher" parent="Theme.MaterialComponents.Light.Dialog"> <style name="WulkanowyTheme.WidgetAccountSwitcher" parent="Theme.MaterialComponents.DayNight.Dialog">
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorSecondary">@color/colorPrimary</item> <item name="colorSecondary">@color/colorPrimary</item>
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>

View File

@ -0,0 +1,105 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.app.Activity.RESULT_OK
import android.content.Context
import android.view.View
import android.widget.Toast
import com.google.android.material.snackbar.Snackbar
import com.google.android.play.core.appupdate.AppUpdateInfo
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.install.InstallStateUpdatedListener
import com.google.android.play.core.install.model.AppUpdateType.FLEXIBLE
import com.google.android.play.core.install.model.AppUpdateType.IMMEDIATE
import com.google.android.play.core.install.model.InstallStatus.DOWNLOADED
import com.google.android.play.core.install.model.InstallStatus.PENDING
import com.google.android.play.core.install.model.UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
import com.google.android.play.core.install.model.UpdateAvailability.UPDATE_AVAILABLE
import com.google.android.play.core.ktx.isFlexibleUpdateAllowed
import com.google.android.play.core.ktx.isImmediateUpdateAllowed
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class UpdateHelper @Inject constructor(@ApplicationContext private val context: Context) {
lateinit var messageContainer: View
companion object {
const val IN_APP_UPDATE_REQUEST_CODE = 1721
const val DAYS_FOR_FLEXIBLE_UPDATE = 7
const val HIGH_PRIORITY_UPDATE = 4
}
private val appUpdateManager by lazy { AppUpdateManagerFactory.create(context) }
private val flexibleUpdateListener = InstallStateUpdatedListener { state ->
when (state.installStatus()) {
PENDING -> Toast.makeText(context, R.string.update_download_started, Toast.LENGTH_SHORT).show()
DOWNLOADED -> popupSnackBarForCompleteUpdate()
else -> Timber.d("Update state: ${state.installStatus()}")
}
}
private inline val AppUpdateInfo.isImmediateUpdateAvailable: Boolean
get() = updateAvailability() == UPDATE_AVAILABLE && isImmediateUpdateAllowed &&
updatePriority() >= HIGH_PRIORITY_UPDATE
private inline val AppUpdateInfo.isFlexibleUpdateAvailable: Boolean
get() = updateAvailability() == UPDATE_AVAILABLE && isFlexibleUpdateAllowed &&
clientVersionStalenessDays() ?: 0 >= DAYS_FOR_FLEXIBLE_UPDATE
fun checkAndInstallUpdates(activity: Activity) {
Timber.d("Checking for updates...")
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
when {
appUpdateInfo.isImmediateUpdateAvailable -> startUpdate(activity, appUpdateInfo, IMMEDIATE)
appUpdateInfo.isFlexibleUpdateAvailable -> {
appUpdateManager.registerListener(flexibleUpdateListener)
startUpdate(activity, appUpdateInfo, FLEXIBLE)
}
else -> Timber.d("No update available")
}
}
}
private fun startUpdate(activity: Activity, appUpdateInfo: AppUpdateInfo, updateType: Int) {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo, updateType, activity, IN_APP_UPDATE_REQUEST_CODE
)
}
fun onActivityResult(requestCode: Int, resultCode: Int) {
if (requestCode == IN_APP_UPDATE_REQUEST_CODE && resultCode != RESULT_OK) {
Timber.e("Update failed! Result code: $resultCode")
Toast.makeText(context, R.string.update_failed, Toast.LENGTH_LONG).show()
}
}
fun onResume(activity: Activity) {
appUpdateManager.appUpdateInfo.addOnSuccessListener { info ->
Timber.d("InAppUpdate.onResume() listener: $info")
when {
DOWNLOADED == info.installStatus() -> popupSnackBarForCompleteUpdate()
DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS == info.updateAvailability() -> {
startUpdate(activity, info, if (info.isImmediateUpdateAvailable) IMMEDIATE else FLEXIBLE)
}
}
}
}
private fun popupSnackBarForCompleteUpdate() {
Snackbar.make(messageContainer, R.string.update_download_success, Snackbar.LENGTH_INDEFINITE).apply {
setAction(R.string.update_download_success_button) {
appUpdateManager.completeUpdate()
appUpdateManager.unregisterListener(flexibleUpdateListener)
}
show()
}
}
}

BIN
appgallery_badge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -1,7 +1,7 @@
buildscript { buildscript {
ext { ext {
kotlin_version = '1.4.10' kotlin_version = '1.4.10'
about_libraries = '8.3.0' about_libraries = '8.4.2'
hilt_version = "2.29.1-alpha" hilt_version = "2.29.1-alpha"
} }
repositories { repositories {
@ -12,11 +12,11 @@ buildscript {
} }
dependencies { dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:4.0.1' classpath 'com.android.tools.build:gradle:4.0.2'
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version" classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath 'com.google.gms:google-services:4.3.3' classpath 'com.google.gms:google-services:4.3.4'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
classpath "com.github.triplet.gradle:play-publisher:2.7.5" classpath "com.github.triplet.gradle:play-publisher:2.8.0"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0" classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0" classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:$about_libraries" classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:$about_libraries"