mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-31 23:02:45 +01:00
Merge branch 'release/1.1.3'
This commit is contained in:
commit
3c48264539
@ -32,7 +32,7 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
|
|||||||
* powiadomienia np. o nowej ocenie
|
* powiadomienia np. o nowej ocenie
|
||||||
* obsługa wielu kont wraz z możliwością zmiany nazwy ucznia
|
* obsługa wielu kont wraz z możliwością zmiany nazwy ucznia
|
||||||
* ciemny i czarny (AMOLED) motyw
|
* ciemny i czarny (AMOLED) motyw
|
||||||
* tryb offilne
|
* tryb offline
|
||||||
* brak reklam
|
* brak reklam
|
||||||
|
|
||||||
## Pobierz
|
## Pobierz
|
||||||
|
@ -20,8 +20,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 17
|
minSdkVersion 17
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 88
|
versionCode 89
|
||||||
versionName "1.1.2"
|
versionName "1.1.3"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
@ -137,20 +137,20 @@ play {
|
|||||||
serviceAccountCredentials = file('key.p12')
|
serviceAccountCredentials = file('key.p12')
|
||||||
defaultToAppBundles = false
|
defaultToAppBundles = false
|
||||||
track = 'production'
|
track = 'production'
|
||||||
updatePriority = 5
|
updatePriority = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
work_manager = "2.5.0"
|
work_manager = "2.5.0"
|
||||||
work_hilt = "1.0.0-beta01"
|
work_hilt = "1.0.0-beta01"
|
||||||
room = "2.3.0-beta03"
|
room = "2.3.0-rc01"
|
||||||
chucker = "3.4.0"
|
chucker = "3.4.0"
|
||||||
mockk = "1.10.6"
|
mockk = "1.11.0"
|
||||||
moshi = "1.11.0"
|
moshi = "1.11.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:sdk:1.1.2"
|
implementation "io.github.wulkanowy:sdk:1.1.3"
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
|
|
||||||
@ -158,11 +158,11 @@ dependencies {
|
|||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'
|
||||||
|
|
||||||
implementation "androidx.core:core-ktx:1.3.2"
|
implementation "androidx.core:core-ktx:1.3.2"
|
||||||
implementation "androidx.activity:activity-ktx:1.2.1"
|
implementation "androidx.activity:activity-ktx:1.2.2"
|
||||||
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"
|
||||||
implementation "androidx.fragment:fragment-ktx:1.3.1"
|
implementation "androidx.fragment:fragment-ktx:1.3.2"
|
||||||
implementation "androidx.annotation:annotation:1.1.0"
|
implementation "androidx.annotation:annotation:1.2.0"
|
||||||
implementation "androidx.multidex:multidex:2.0.1"
|
implementation "androidx.multidex:multidex:2.0.1"
|
||||||
|
|
||||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
implementation "androidx.preference:preference-ktx:1.1.1"
|
||||||
@ -179,7 +179,7 @@ dependencies {
|
|||||||
implementation "androidx.work:work-runtime-ktx:$work_manager"
|
implementation "androidx.work:work-runtime-ktx:$work_manager"
|
||||||
playImplementation "androidx.work:work-gcm:$work_manager"
|
playImplementation "androidx.work:work-gcm:$work_manager"
|
||||||
|
|
||||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0"
|
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
|
||||||
|
|
||||||
implementation "androidx.room:room-runtime:$room"
|
implementation "androidx.room:room-runtime:$room"
|
||||||
implementation "androidx.room:room-ktx:$room"
|
implementation "androidx.room:room-ktx:$room"
|
||||||
@ -208,15 +208,12 @@ dependencies {
|
|||||||
|
|
||||||
playImplementation platform('com.google.firebase:firebase-bom:26.7.0')
|
playImplementation platform('com.google.firebase:firebase-bom:26.7.0')
|
||||||
playImplementation 'com.google.firebase:firebase-analytics-ktx'
|
playImplementation 'com.google.firebase:firebase-analytics-ktx'
|
||||||
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx'
|
|
||||||
playImplementation "com.google.firebase:firebase-inappmessaging-ktx"
|
|
||||||
playImplementation 'com.google.firebase:firebase-messaging:'
|
playImplementation 'com.google.firebase:firebase-messaging:'
|
||||||
playImplementation 'com.google.firebase:firebase-crashlytics:'
|
playImplementation 'com.google.firebase:firebase-crashlytics:'
|
||||||
playImplementation 'com.google.android.play:core-ktx:1.8.1'
|
playImplementation 'com.google.android.play:core-ktx:1.8.1'
|
||||||
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
|
||||||
|
|
||||||
hmsImplementation 'com.huawei.hms:hianalytics:5.2.0.300'
|
hmsImplementation 'com.huawei.hms:hianalytics:5.2.0.301'
|
||||||
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.5.0.300'
|
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.5.1.200'
|
||||||
|
|
||||||
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
||||||
|
|
||||||
|
@ -9,6 +9,6 @@ import javax.inject.Singleton
|
|||||||
@Dao
|
@Dao
|
||||||
interface RecipientDao : BaseDao<Recipient> {
|
interface RecipientDao : BaseDao<Recipient> {
|
||||||
|
|
||||||
@Query("SELECT * FROM Recipients WHERE student_id = :userLoginId AND unit_id = :unitId AND role = :role")
|
@Query("SELECT * FROM Recipients WHERE student_id = :studentId AND unit_id = :unitId AND role = :role")
|
||||||
suspend fun loadAll(userLoginId: Int, unitId: Int, role: Int): List<Recipient>
|
suspend fun loadAll(studentId: Int, unitId: Int, role: Int): List<Recipient>
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import java.io.Serializable
|
|||||||
data class Recipient(
|
data class Recipient(
|
||||||
|
|
||||||
@ColumnInfo(name = "student_id")
|
@ColumnInfo(name = "student_id")
|
||||||
val userLoginId: Int,
|
val studentId: Int,
|
||||||
|
|
||||||
@ColumnInfo(name = "real_id")
|
@ColumnInfo(name = "real_id")
|
||||||
val realId: String,
|
val realId: String,
|
||||||
|
@ -5,7 +5,7 @@ import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
|
|||||||
|
|
||||||
fun List<SdkRecipient>.mapToEntities(userLoginId: Int) = map {
|
fun List<SdkRecipient>.mapToEntities(userLoginId: Int) = map {
|
||||||
Recipient(
|
Recipient(
|
||||||
userLoginId = userLoginId,
|
studentId = userLoginId,
|
||||||
realId = it.id,
|
realId = it.id,
|
||||||
realName = it.name,
|
realName = it.name,
|
||||||
name = it.shortName,
|
name = it.shortName,
|
||||||
|
@ -6,7 +6,7 @@ import io.github.wulkanowy.sdk.pojo.ReportingUnit as SdkReportingUnit
|
|||||||
|
|
||||||
fun List<SdkReportingUnit>.mapToEntities(student: Student) = map {
|
fun List<SdkReportingUnit>.mapToEntities(student: Student) = map {
|
||||||
ReportingUnit(
|
ReportingUnit(
|
||||||
studentId = student.studentId,
|
studentId = student.id.toInt(),
|
||||||
unitId = it.id,
|
unitId = it.id,
|
||||||
roles = it.roles,
|
roles = it.roles,
|
||||||
senderId = it.senderId,
|
senderId = it.senderId,
|
||||||
|
@ -2,6 +2,7 @@ package io.github.wulkanowy.data.repositories
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import androidx.core.content.edit
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
|
||||||
@ -145,6 +146,10 @@ class PreferencesRepository @Inject constructor(
|
|||||||
R.bool.pref_default_subjects_without_grades
|
R.bool.pref_default_subjects_without_grades
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var isKitkatDialogDisabled: Boolean
|
||||||
|
get() = sharedPref.getBoolean("kitkat_dialog_disabled", false)
|
||||||
|
set(value) = sharedPref.edit { putBoolean("kitkat_dialog_disabled", value) }
|
||||||
|
|
||||||
private fun getString(id: Int, default: Int) = getString(context.getString(id), default)
|
private fun getString(id: Int, default: Int) = getString(context.getString(id), default)
|
||||||
|
|
||||||
private fun getString(id: String, default: Int) =
|
private fun getString(id: String, default: Int) =
|
||||||
|
@ -19,22 +19,22 @@ class RecipientRepository @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun refreshRecipients(student: Student, unit: ReportingUnit, role: Int) {
|
suspend fun refreshRecipients(student: Student, unit: ReportingUnit, role: Int) {
|
||||||
val new = sdk.init(student).getRecipients(unit.unitId, role).mapToEntities(unit.senderId)
|
val new = sdk.init(student).getRecipients(unit.unitId, role).mapToEntities(unit.studentId)
|
||||||
val old = recipientDb.loadAll(unit.senderId, unit.unitId, role)
|
val old = recipientDb.loadAll(unit.studentId, unit.unitId, role)
|
||||||
|
|
||||||
recipientDb.deleteAll(old uniqueSubtract new)
|
recipientDb.deleteAll(old uniqueSubtract new)
|
||||||
recipientDb.insertAll(new uniqueSubtract old)
|
recipientDb.insertAll(new uniqueSubtract old)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getRecipients(student: Student, unit: ReportingUnit, role: Int): List<Recipient> {
|
suspend fun getRecipients(student: Student, unit: ReportingUnit, role: Int): List<Recipient> {
|
||||||
return recipientDb.loadAll(unit.senderId, unit.unitId, role).ifEmpty {
|
return recipientDb.loadAll(unit.studentId, unit.unitId, role).ifEmpty {
|
||||||
refreshRecipients(student, unit, role)
|
refreshRecipients(student, unit, role)
|
||||||
|
|
||||||
recipientDb.loadAll(unit.senderId, unit.unitId, role)
|
recipientDb.loadAll(unit.studentId, unit.unitId, role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getMessageRecipients(student: Student, message: Message): List<Recipient> {
|
suspend fun getMessageRecipients(student: Student, message: Message): List<Recipient> {
|
||||||
return sdk.init(student).getMessageRecipients(message.messageId, message.senderId).mapToEntities(student.userLoginId)
|
return sdk.init(student).getMessageRecipients(message.messageId, message.senderId).mapToEntities(student.studentId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,25 +18,25 @@ class ReportingUnitRepository @Inject constructor(
|
|||||||
|
|
||||||
suspend fun refreshReportingUnits(student: Student) {
|
suspend fun refreshReportingUnits(student: Student) {
|
||||||
val new = sdk.init(student).getReportingUnits().mapToEntities(student)
|
val new = sdk.init(student).getReportingUnits().mapToEntities(student)
|
||||||
val old = reportingUnitDb.load(student.studentId)
|
val old = reportingUnitDb.load(student.id.toInt())
|
||||||
|
|
||||||
reportingUnitDb.deleteAll(old.uniqueSubtract(new))
|
reportingUnitDb.deleteAll(old.uniqueSubtract(new))
|
||||||
reportingUnitDb.insertAll(new.uniqueSubtract(old))
|
reportingUnitDb.insertAll(new.uniqueSubtract(old))
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getReportingUnits(student: Student): List<ReportingUnit> {
|
suspend fun getReportingUnits(student: Student): List<ReportingUnit> {
|
||||||
return reportingUnitDb.load(student.studentId).ifEmpty {
|
return reportingUnitDb.load(student.id.toInt()).ifEmpty {
|
||||||
refreshReportingUnits(student)
|
refreshReportingUnits(student)
|
||||||
|
|
||||||
reportingUnitDb.load(student.studentId)
|
reportingUnitDb.load(student.id.toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getReportingUnit(student: Student, unitId: Int): ReportingUnit? {
|
suspend fun getReportingUnit(student: Student, unitId: Int): ReportingUnit? {
|
||||||
return reportingUnitDb.loadOne(student.studentId, unitId) ?: run {
|
return reportingUnitDb.loadOne(student.id.toInt(), unitId) ?: run {
|
||||||
refreshReportingUnits(student)
|
refreshReportingUnits(student)
|
||||||
|
|
||||||
return reportingUnitDb.loadOne(student.studentId, unitId)
|
return reportingUnitDb.loadOne(student.id.toInt(), unitId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.PorterDuff
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.databinding.ItemAccountBinding
|
import io.github.wulkanowy.databinding.ItemAccountBinding
|
||||||
|
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
import io.github.wulkanowy.utils.nickOrName
|
import io.github.wulkanowy.utils.nickOrName
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class WidgetConfigureAdapter @Inject constructor() : RecyclerView.Adapter<WidgetConfigureAdapter.ItemViewHolder>() {
|
class WidgetConfigureAdapter @Inject constructor() :
|
||||||
|
RecyclerView.Adapter<WidgetConfigureAdapter.ItemViewHolder>() {
|
||||||
|
|
||||||
var items = emptyList<Pair<Student, Boolean>>()
|
var items = emptyList<StudentWithSemesters>()
|
||||||
|
|
||||||
|
var selectedId = -1L
|
||||||
|
|
||||||
var onClickListener: (Student) -> Unit = {}
|
var onClickListener: (Student) -> Unit = {}
|
||||||
|
|
||||||
@ -26,17 +31,33 @@ class WidgetConfigureAdapter @Inject constructor() : RecyclerView.Adapter<Widget
|
|||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||||
val (student, isCurrent) = items[position]
|
val (student, semesters) = items[position]
|
||||||
|
val semester = semesters.maxByOrNull { it.semesterId }
|
||||||
|
val context = holder.binding.root.context
|
||||||
|
val checkBackgroundColor = context.getThemeAttrColor(R.attr.colorSurface)
|
||||||
|
val avatar = context.createNameInitialsDrawable(student.nickOrName, student.avatarColor)
|
||||||
|
val isDuplicatedStudent = items.filter {
|
||||||
|
val studentToCompare = it.student
|
||||||
|
|
||||||
|
studentToCompare.studentId == student.studentId
|
||||||
|
&& studentToCompare.schoolSymbol == student.schoolSymbol
|
||||||
|
&& studentToCompare.symbol == student.symbol
|
||||||
|
}.size > 1
|
||||||
|
|
||||||
with(holder.binding) {
|
with(holder.binding) {
|
||||||
accountItemName.text = "${student.nickOrName} ${student.className}"
|
accountItemName.text = "${student.nickOrName} ${semester?.diaryName.orEmpty()}"
|
||||||
accountItemSchool.text = student.schoolName
|
accountItemSchool.text = student.schoolName
|
||||||
|
accountItemImage.setImageDrawable(avatar)
|
||||||
|
|
||||||
with(accountItemImage) {
|
with(accountItemAccountType) {
|
||||||
val colorImage = if (isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
|
setText(if (student.isParent) R.string.account_type_parent else R.string.account_type_student)
|
||||||
else context.getThemeAttrColor(R.attr.colorOnSurface, 153)
|
isVisible = isDuplicatedStudent
|
||||||
|
}
|
||||||
|
|
||||||
setColorFilter(colorImage, PorterDuff.Mode.SRC_IN)
|
with(accountItemCheck) {
|
||||||
|
isVisible = student.id == selectedId
|
||||||
|
borderColor = checkBackgroundColor
|
||||||
|
circleColor = checkBackgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
root.setOnClickListener { onClickListener(student) }
|
root.setOnClickListener { onClickListener(student) }
|
||||||
|
@ -74,9 +74,8 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.V
|
|||||||
studentWithSemesters: StudentWithSemesters
|
studentWithSemesters: StudentWithSemesters
|
||||||
) {
|
) {
|
||||||
val context = binding.root.context
|
val context = binding.root.context
|
||||||
val student = studentWithSemesters.student
|
val (student, semesters) = studentWithSemesters
|
||||||
val semesters = studentWithSemesters.semesters
|
val semester = semesters.maxByOrNull { it.semesterId }
|
||||||
val diary = semesters.maxByOrNull { it.semesterId }
|
|
||||||
val avatar = context.createNameInitialsDrawable(student.nickOrName, student.avatarColor)
|
val avatar = context.createNameInitialsDrawable(student.nickOrName, student.avatarColor)
|
||||||
val checkBackgroundColor =
|
val checkBackgroundColor =
|
||||||
context.getThemeAttrColor(if (isAccountQuickDialogMode) R.attr.colorBackgroundFloating else R.attr.colorSurface)
|
context.getThemeAttrColor(if (isAccountQuickDialogMode) R.attr.colorBackgroundFloating else R.attr.colorSurface)
|
||||||
@ -90,7 +89,7 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.V
|
|||||||
}.size > 1 && isAccountQuickDialogMode
|
}.size > 1 && isAccountQuickDialogMode
|
||||||
|
|
||||||
with(binding) {
|
with(binding) {
|
||||||
accountItemName.text = "${student.nickOrName} ${diary?.diaryName.orEmpty()}"
|
accountItemName.text = "${student.nickOrName} ${semester?.diaryName.orEmpty()}"
|
||||||
accountItemSchool.text = studentWithSemesters.student.schoolName
|
accountItemSchool.text = studentWithSemesters.student.schoolName
|
||||||
accountItemImage.setImageDrawable(avatar)
|
accountItemImage.setImageDrawable(avatar)
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
view?.setErrorEmailRequired()
|
view?.setErrorEmailRequired()
|
||||||
isCorrect = false
|
isCorrect = false
|
||||||
}
|
}
|
||||||
if ("@" in login && "login" !in host && "email" !in host) {
|
if ("@" in login && "||" !in login && "login" !in host && "email" !in host) {
|
||||||
val emailHost = login.substringAfter("@")
|
val emailHost = login.substringAfter("@")
|
||||||
val emailDomain = URL(host).host
|
val emailDomain = URL(host).host
|
||||||
if (emailHost != emailDomain) {
|
if (emailHost != emailDomain) {
|
||||||
|
@ -9,6 +9,7 @@ import android.view.View.VISIBLE
|
|||||||
import android.webkit.JavascriptInterface
|
import android.webkit.JavascriptInterface
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.webkit.WebViewClient
|
import android.webkit.WebViewClient
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.widget.doOnTextChanged
|
import androidx.core.widget.doOnTextChanged
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
@ -42,10 +43,12 @@ class LoginRecoverFragment :
|
|||||||
private lateinit var hostSymbols: Array<String>
|
private lateinit var hostSymbols: Array<String>
|
||||||
|
|
||||||
override val recoverHostValue: String
|
override val recoverHostValue: String
|
||||||
get() = hostValues.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())).orEmpty()
|
get() = hostValues.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString()))
|
||||||
|
.orEmpty()
|
||||||
|
|
||||||
override val formHostSymbol: String
|
override val formHostSymbol: String
|
||||||
get() = hostSymbols.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())).orEmpty()
|
get() = hostSymbols.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString()))
|
||||||
|
.orEmpty()
|
||||||
|
|
||||||
override val recoverNameValue: String
|
override val recoverNameValue: String
|
||||||
get() = bindingLocal.loginRecoverName.text.toString().trim()
|
get() = bindingLocal.loginRecoverName.text.toString().trim()
|
||||||
@ -82,7 +85,9 @@ class LoginRecoverFragment :
|
|||||||
|
|
||||||
with(bindingLocal.loginRecoverHost) {
|
with(bindingLocal.loginRecoverHost) {
|
||||||
setText(hostKeys.getOrNull(0).orEmpty())
|
setText(hostKeys.getOrNull(0).orEmpty())
|
||||||
setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
|
setAdapter(
|
||||||
|
LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys)
|
||||||
|
)
|
||||||
setOnClickListener { if (bindingLocal.loginRecoverFormContainer.visibility == GONE) dismissDropDown() }
|
setOnClickListener { if (bindingLocal.loginRecoverFormContainer.visibility == GONE) dismissDropDown() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +132,7 @@ class LoginRecoverFragment :
|
|||||||
|
|
||||||
override fun showErrorView(show: Boolean) {
|
override fun showErrorView(show: Boolean) {
|
||||||
bindingLocal.loginRecoverError.visibility = if (show) VISIBLE else GONE
|
bindingLocal.loginRecoverError.visibility = if (show) VISIBLE else GONE
|
||||||
|
bindingLocal.loginRecoverErrorDetails.isVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setErrorDetails(message: String) {
|
override fun setErrorDetails(message: String) {
|
||||||
@ -166,7 +172,7 @@ class LoginRecoverFragment :
|
|||||||
with(bindingLocal.loginRecoverWebView) {
|
with(bindingLocal.loginRecoverWebView) {
|
||||||
settings.javaScriptEnabled = true
|
settings.javaScriptEnabled = true
|
||||||
webViewClient = object : WebViewClient() {
|
webViewClient = object : WebViewClient() {
|
||||||
private var recoverWebViewSuccess: Boolean = true
|
private var recoverWebViewSuccess = true
|
||||||
|
|
||||||
override fun onPageFinished(view: WebView?, url: String?) {
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
if (recoverWebViewSuccess) {
|
if (recoverWebViewSuccess) {
|
||||||
@ -175,10 +181,16 @@ class LoginRecoverFragment :
|
|||||||
} else {
|
} else {
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
showErrorView(true)
|
showErrorView(true)
|
||||||
|
bindingLocal.loginRecoverErrorDetails.isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) {
|
override fun onReceivedError(
|
||||||
|
view: WebView,
|
||||||
|
errorCode: Int,
|
||||||
|
description: String,
|
||||||
|
failingUrl: String
|
||||||
|
) {
|
||||||
recoverWebViewSuccess = false
|
recoverWebViewSuccess = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
|
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
|
||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.base.WidgetConfigureAdapter
|
import io.github.wulkanowy.ui.base.WidgetConfigureAdapter
|
||||||
@ -38,7 +38,9 @@ class LuckyNumberWidgetConfigureActivity :
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setResult(RESULT_CANCELED)
|
setResult(RESULT_CANCELED)
|
||||||
setContentView(ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root)
|
setContentView(
|
||||||
|
ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root
|
||||||
|
)
|
||||||
|
|
||||||
intent.extras.let {
|
intent.extras.let {
|
||||||
presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID))
|
presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID))
|
||||||
@ -70,8 +72,9 @@ class LuckyNumberWidgetConfigureActivity :
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateData(data: List<Pair<Student, Boolean>>) {
|
override fun updateData(data: List<StudentWithSemesters>, selectedStudentId: Long) {
|
||||||
with(configureAdapter) {
|
with(configureAdapter) {
|
||||||
|
selectedId = selectedStudentId
|
||||||
items = data
|
items = data
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
@ -51,16 +51,17 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
|||||||
when (it.status) {
|
when (it.status) {
|
||||||
Status.LOADING -> Timber.d("Lucky number widget configure students data load")
|
Status.LOADING -> Timber.d("Lucky number widget configure students data load")
|
||||||
Status.SUCCESS -> {
|
Status.SUCCESS -> {
|
||||||
val widgetId = appWidgetId?.let { id -> sharedPref.getLong(getStudentWidgetKey(id), 0) }
|
val selectedStudentId = appWidgetId?.let { id ->
|
||||||
|
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
||||||
|
} ?: -1
|
||||||
|
|
||||||
when {
|
when {
|
||||||
it.data!!.isEmpty() -> view?.openLoginView()
|
it.data!!.isEmpty() -> view?.openLoginView()
|
||||||
it.data.size == 1 -> {
|
it.data.size == 1 -> {
|
||||||
selectedStudent = it.data.single().student
|
selectedStudent = it.data.single().student
|
||||||
view?.showThemeDialog()
|
view?.showThemeDialog()
|
||||||
}
|
}
|
||||||
else -> view?.updateData(it.data.map { entity ->
|
else -> view?.updateData(it.data, selectedStudentId)
|
||||||
entity.student to (entity.student.id == widgetId)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.luckynumberwidget
|
package io.github.wulkanowy.ui.modules.luckynumberwidget
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface LuckyNumberWidgetConfigureView : BaseView {
|
interface LuckyNumberWidgetConfigureView : BaseView {
|
||||||
@ -9,7 +9,7 @@ interface LuckyNumberWidgetConfigureView : BaseView {
|
|||||||
|
|
||||||
fun showThemeDialog()
|
fun showThemeDialog()
|
||||||
|
|
||||||
fun updateData(data: List<Pair<Student, Boolean>>)
|
fun updateData(data: List<StudentWithSemesters>, selectedStudentId: Long)
|
||||||
|
|
||||||
fun updateLuckyNumberWidget(widgetId: Int)
|
fun updateLuckyNumberWidget(widgetId: Int)
|
||||||
|
|
||||||
|
@ -324,9 +324,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showAccountPicker(studentWithSemesters: List<StudentWithSemesters>) {
|
override fun showAccountPicker(studentWithSemesters: List<StudentWithSemesters>) {
|
||||||
if (supportFragmentManager.isStateSaved) return
|
showDialogFragment(AccountQuickDialog.newInstance(studentWithSemesters))
|
||||||
|
|
||||||
navController.showDialogFragment(AccountQuickDialog.newInstance(studentWithSemesters))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showActionBarElevation(show: Boolean) {
|
override fun showActionBarElevation(show: Boolean) {
|
||||||
@ -342,9 +340,18 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
(navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentChanged()
|
(navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
fun showDialogFragment(dialog: DialogFragment) {
|
fun showDialogFragment(dialog: DialogFragment) {
|
||||||
if (supportFragmentManager.isStateSaved) return
|
if (supportFragmentManager.isStateSaved) return
|
||||||
|
|
||||||
|
//Deprecated method is used here to avoid fragnav bug
|
||||||
|
if (navController.currentDialogFrag?.fragmentManager == null) {
|
||||||
|
FragNavController::class.java.getDeclaredField("mCurrentDialogFrag").apply {
|
||||||
|
isAccessible = true
|
||||||
|
set(navController, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
navController.showDialogFragment(dialog)
|
navController.showDialogFragment(dialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,17 +3,23 @@ package io.github.wulkanowy.ui.modules.splash
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.widget.Toast.LENGTH_LONG
|
import android.widget.Toast.LENGTH_LONG
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SplashActivity : BaseActivity<SplashPresenter, ViewBinding>(), SplashView {
|
class SplashActivity : BaseActivity<SplashPresenter, ViewBinding>(), SplashView {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
override lateinit var presenter: SplashPresenter
|
override lateinit var presenter: SplashPresenter
|
||||||
|
|
||||||
@ -40,4 +46,14 @@ class SplashActivity : BaseActivity<SplashPresenter, ViewBinding>(), SplashView
|
|||||||
override fun showError(text: String, error: Throwable) {
|
override fun showError(text: String, error: Throwable) {
|
||||||
Toast.makeText(this, text, LENGTH_LONG).show()
|
Toast.makeText(this, text, LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun showKitkatView() {
|
||||||
|
AlertDialog.Builder(this)
|
||||||
|
.setTitle(R.string.drop_kitkat_title)
|
||||||
|
.setMessage(R.string.drop_kitkat_content)
|
||||||
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
|
.setNeutralButton(R.string.drop_kitkat_again) { _, _ -> presenter.onNeutralButtonSelected() }
|
||||||
|
.setOnDismissListener { presenter.onKitkatViewDismissed() }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.splash
|
package io.github.wulkanowy.ui.modules.splash
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.Status
|
||||||
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
import io.github.wulkanowy.utils.flowWithResource
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -11,25 +14,47 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
class SplashPresenter @Inject constructor(
|
class SplashPresenter @Inject constructor(
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository
|
studentRepository: StudentRepository,
|
||||||
|
private val preferencesRepository: PreferencesRepository,
|
||||||
|
private val appInfo: AppInfo
|
||||||
) : BasePresenter<SplashView>(errorHandler, studentRepository) {
|
) : BasePresenter<SplashView>(errorHandler, studentRepository) {
|
||||||
|
|
||||||
|
private var externalUrl: String? = null
|
||||||
|
|
||||||
fun onAttachView(view: SplashView, externalUrl: String?) {
|
fun onAttachView(view: SplashView, externalUrl: String?) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
this.externalUrl = externalUrl
|
||||||
|
|
||||||
|
if (appInfo.systemVersion < Build.VERSION_CODES.LOLLIPOP && !preferencesRepository.isKitkatDialogDisabled) {
|
||||||
|
view.showKitkatView()
|
||||||
|
} else {
|
||||||
|
loadCorrectDataOrUser()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadCorrectDataOrUser() {
|
||||||
if (!externalUrl.isNullOrBlank()) {
|
if (!externalUrl.isNullOrBlank()) {
|
||||||
return view.openExternalUrlAndFinish(externalUrl)
|
view?.openExternalUrlAndFinish(externalUrl!!)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
flowWithResource { studentRepository.isCurrentStudentSet() }.onEach {
|
flowWithResource { studentRepository.isCurrentStudentSet() }.onEach {
|
||||||
when (it.status) {
|
when (it.status) {
|
||||||
Status.LOADING -> Timber.d("Is current user set check started")
|
Status.LOADING -> Timber.d("Is current user set check started")
|
||||||
Status.SUCCESS -> with(view) {
|
Status.SUCCESS -> {
|
||||||
if (it.data!!) openMainView()
|
if (it.data!!) view?.openMainView()
|
||||||
else openLoginView()
|
else view?.openLoginView()
|
||||||
}
|
}
|
||||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
||||||
}
|
}
|
||||||
}.launch()
|
}.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onKitkatViewDismissed() {
|
||||||
|
loadCorrectDataOrUser()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onNeutralButtonSelected() {
|
||||||
|
preferencesRepository.isKitkatDialogDisabled = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,6 @@ interface SplashView : BaseView {
|
|||||||
fun openMainView()
|
fun openMainView()
|
||||||
|
|
||||||
fun openExternalUrlAndFinish(url: String)
|
fun openExternalUrlAndFinish(url: String)
|
||||||
|
|
||||||
|
fun showKitkatView()
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
|
import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding
|
||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.base.WidgetConfigureAdapter
|
import io.github.wulkanowy.ui.base.WidgetConfigureAdapter
|
||||||
@ -37,13 +37,19 @@ class TimetableWidgetConfigureActivity :
|
|||||||
|
|
||||||
private var dialog: AlertDialog? = null
|
private var dialog: AlertDialog? = null
|
||||||
|
|
||||||
override public fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setResult(RESULT_CANCELED)
|
setResult(RESULT_CANCELED)
|
||||||
setContentView(ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root)
|
setContentView(
|
||||||
|
ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root
|
||||||
|
)
|
||||||
|
|
||||||
intent.extras.let {
|
intent.extras.let {
|
||||||
presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID), it?.getBoolean(EXTRA_FROM_PROVIDER))
|
presenter.onAttachView(
|
||||||
|
this,
|
||||||
|
it?.getInt(EXTRA_APPWIDGET_ID),
|
||||||
|
it?.getBoolean(EXTRA_FROM_PROVIDER)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +67,7 @@ class TimetableWidgetConfigureActivity :
|
|||||||
getString(R.string.widget_timetable_theme_light),
|
getString(R.string.widget_timetable_theme_light),
|
||||||
getString(R.string.widget_timetable_theme_dark)
|
getString(R.string.widget_timetable_theme_dark)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (appInfo.systemVersion >= Build.VERSION_CODES.Q) items += getString(R.string.widget_timetable_theme_system)
|
if (appInfo.systemVersion >= Build.VERSION_CODES.Q) items += getString(R.string.widget_timetable_theme_system)
|
||||||
|
|
||||||
dialog = AlertDialog.Builder(this, R.style.WulkanowyTheme_WidgetAccountSwitcher)
|
dialog = AlertDialog.Builder(this, R.style.WulkanowyTheme_WidgetAccountSwitcher)
|
||||||
@ -72,8 +79,9 @@ class TimetableWidgetConfigureActivity :
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateData(data: List<Pair<Student, Boolean>>) {
|
override fun updateData(data: List<StudentWithSemesters>, selectedStudentId: Long) {
|
||||||
with(configureAdapter) {
|
with(configureAdapter) {
|
||||||
|
selectedId = selectedStudentId
|
||||||
items = data
|
items = data
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,11 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
|
|||||||
|
|
||||||
private var selectedStudent: Student? = null
|
private var selectedStudent: Student? = null
|
||||||
|
|
||||||
fun onAttachView(view: TimetableWidgetConfigureView, appWidgetId: Int?, isFromProvider: Boolean?) {
|
fun onAttachView(
|
||||||
|
view: TimetableWidgetConfigureView,
|
||||||
|
appWidgetId: Int?,
|
||||||
|
isFromProvider: Boolean?
|
||||||
|
) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
this.appWidgetId = appWidgetId
|
this.appWidgetId = appWidgetId
|
||||||
this.isFromProvider = isFromProvider ?: false
|
this.isFromProvider = isFromProvider ?: false
|
||||||
@ -56,16 +60,17 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
|
|||||||
when (it.status) {
|
when (it.status) {
|
||||||
Status.LOADING -> Timber.d("Timetable widget configure students data load")
|
Status.LOADING -> Timber.d("Timetable widget configure students data load")
|
||||||
Status.SUCCESS -> {
|
Status.SUCCESS -> {
|
||||||
val widgetId = appWidgetId?.let { id -> sharedPref.getLong(getStudentWidgetKey(id), 0) }
|
val selectedStudentId = appWidgetId?.let { id ->
|
||||||
|
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
||||||
|
} ?: -1
|
||||||
|
|
||||||
when {
|
when {
|
||||||
it.data!!.isEmpty() -> view?.openLoginView()
|
it.data!!.isEmpty() -> view?.openLoginView()
|
||||||
it.data.size == 1 && !isFromProvider -> {
|
it.data.size == 1 && !isFromProvider -> {
|
||||||
selectedStudent = it.data.single().student
|
selectedStudent = it.data.single().student
|
||||||
view?.showThemeDialog()
|
view?.showThemeDialog()
|
||||||
}
|
}
|
||||||
else -> view?.updateData(it.data.map { entity ->
|
else -> view?.updateData(it.data, selectedStudentId)
|
||||||
entity.student to (entity.student.id == widgetId)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.timetablewidget
|
package io.github.wulkanowy.ui.modules.timetablewidget
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface TimetableWidgetConfigureView : BaseView {
|
interface TimetableWidgetConfigureView : BaseView {
|
||||||
|
|
||||||
fun initView()
|
fun initView()
|
||||||
|
|
||||||
fun updateData(data: List<Pair<Student, Boolean>>)
|
fun updateData(data: List<StudentWithSemesters>, selectedStudentId: Long)
|
||||||
|
|
||||||
fun updateTimetableWidget(widgetId: Int)
|
fun updateTimetableWidget(widgetId: Int)
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ import android.content.Intent
|
|||||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
@ -25,6 +27,8 @@ import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
|||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
|
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.nextSchoolDay
|
import io.github.wulkanowy.utils.nextSchoolDay
|
||||||
import io.github.wulkanowy.utils.nickOrName
|
import io.github.wulkanowy.utils.nickOrName
|
||||||
@ -72,7 +76,8 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
|
|
||||||
fun getThemeWidgetKey(appWidgetId: Int) = "timetable_widget_theme_$appWidgetId"
|
fun getThemeWidgetKey(appWidgetId: Int) = "timetable_widget_theme_$appWidgetId"
|
||||||
|
|
||||||
fun getCurrentThemeWidgetKey(appWidgetId: Int) = "timetable_widget_current_theme_$appWidgetId"
|
fun getCurrentThemeWidgetKey(appWidgetId: Int) =
|
||||||
|
"timetable_widget_current_theme_$appWidgetId"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
@ -88,21 +93,29 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
private suspend fun onUpdate(context: Context, intent: Intent) {
|
private suspend fun onUpdate(context: Context, intent: Intent) {
|
||||||
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
|
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
|
||||||
intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId ->
|
intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId ->
|
||||||
val student = getStudent(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)
|
val student =
|
||||||
|
getStudent(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)
|
||||||
updateWidget(context, appWidgetId, now().nextOrSameSchoolDay, student)
|
updateWidget(context, appWidgetId, now().nextOrSameSchoolDay, student)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
|
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
|
||||||
val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)
|
val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)
|
||||||
val student = getStudent(sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0), toggledWidgetId)
|
val student = getStudent(
|
||||||
val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(toggledWidgetId), 0))
|
sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0),
|
||||||
|
toggledWidgetId
|
||||||
|
)
|
||||||
|
val savedDate =
|
||||||
|
LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(toggledWidgetId), 0))
|
||||||
val date = when (buttonType) {
|
val date = when (buttonType) {
|
||||||
BUTTON_RESET -> now().nextOrSameSchoolDay
|
BUTTON_RESET -> now().nextOrSameSchoolDay
|
||||||
BUTTON_NEXT -> savedDate.nextSchoolDay
|
BUTTON_NEXT -> savedDate.nextSchoolDay
|
||||||
BUTTON_PREV -> savedDate.previousSchoolDay
|
BUTTON_PREV -> savedDate.previousSchoolDay
|
||||||
else -> now().nextOrSameSchoolDay
|
else -> now().nextOrSameSchoolDay
|
||||||
}
|
}
|
||||||
if (!buttonType.isNullOrBlank()) analytics.logEvent("changed_timetable_widget_day", "button" to buttonType)
|
if (!buttonType.isNullOrBlank()) analytics.logEvent(
|
||||||
|
"changed_timetable_widget_day",
|
||||||
|
"button" to buttonType
|
||||||
|
)
|
||||||
updateWidget(context, toggledWidgetId, date, student)
|
updateWidget(context, toggledWidgetId, date, student)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,9 +134,15 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate, student: Student?) {
|
private fun updateWidget(
|
||||||
|
context: Context,
|
||||||
|
appWidgetId: Int,
|
||||||
|
date: LocalDate,
|
||||||
|
student: Student?
|
||||||
|
) {
|
||||||
val savedConfigureTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0)
|
val savedConfigureTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0)
|
||||||
val isSystemDarkMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
val isSystemDarkMode =
|
||||||
|
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||||
var currentTheme = 0L
|
var currentTheme = 0L
|
||||||
var layoutId = R.layout.widget_timetable
|
var layoutId = R.layout.widget_timetable
|
||||||
|
|
||||||
@ -134,21 +153,28 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
|
|
||||||
val nextNavIntent = createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT)
|
val nextNavIntent = createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT)
|
||||||
val prevNavIntent = createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV)
|
val prevNavIntent = createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV)
|
||||||
val resetNavIntent = createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET)
|
val resetNavIntent =
|
||||||
|
createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET)
|
||||||
val adapterIntent = Intent(context, TimetableWidgetService::class.java)
|
val adapterIntent = Intent(context, TimetableWidgetService::class.java)
|
||||||
.apply {
|
.apply {
|
||||||
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
||||||
//make Intent unique
|
//make Intent unique
|
||||||
action = appWidgetId.toString()
|
action = appWidgetId.toString()
|
||||||
}
|
}
|
||||||
val accountIntent = PendingIntent.getActivity(context, -Int.MAX_VALUE + appWidgetId,
|
val accountIntent = PendingIntent.getActivity(
|
||||||
|
context, -Int.MAX_VALUE + appWidgetId,
|
||||||
Intent(context, TimetableWidgetConfigureActivity::class.java).apply {
|
Intent(context, TimetableWidgetConfigureActivity::class.java).apply {
|
||||||
addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK)
|
addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK)
|
||||||
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
||||||
putExtra(EXTRA_FROM_PROVIDER, true)
|
putExtra(EXTRA_FROM_PROVIDER, true)
|
||||||
}, FLAG_UPDATE_CURRENT)
|
}, FLAG_UPDATE_CURRENT
|
||||||
val appIntent = PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id,
|
)
|
||||||
MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT)
|
val appIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
MainView.Section.TIMETABLE.id,
|
||||||
|
MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true),
|
||||||
|
FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
|
||||||
val remoteView = RemoteViews(context.packageName, layoutId).apply {
|
val remoteView = RemoteViews(context.packageName, layoutId).apply {
|
||||||
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
||||||
@ -160,6 +186,11 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
R.id.timetableWidgetName,
|
R.id.timetableWidgetName,
|
||||||
student?.nickOrName ?: context.getString(R.string.all_no_data)
|
student?.nickOrName ?: context.getString(R.string.all_no_data)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
student?.let {
|
||||||
|
setImageViewBitmap(R.id.timetableWidgetAccount, context.createAvatarBitmap(it))
|
||||||
|
}
|
||||||
|
|
||||||
setRemoteAdapter(R.id.timetableWidgetList, adapterIntent)
|
setRemoteAdapter(R.id.timetableWidgetList, adapterIntent)
|
||||||
setOnClickPendingIntent(R.id.timetableWidgetNext, nextNavIntent)
|
setOnClickPendingIntent(R.id.timetableWidgetNext, nextNavIntent)
|
||||||
setOnClickPendingIntent(R.id.timetableWidgetPrev, prevNavIntent)
|
setOnClickPendingIntent(R.id.timetableWidgetPrev, prevNavIntent)
|
||||||
@ -181,13 +212,20 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNavIntent(context: Context, code: Int, appWidgetId: Int, buttonType: String): PendingIntent {
|
private fun createNavIntent(
|
||||||
return PendingIntent.getBroadcast(context, code,
|
context: Context,
|
||||||
|
code: Int,
|
||||||
|
appWidgetId: Int,
|
||||||
|
buttonType: String
|
||||||
|
): PendingIntent {
|
||||||
|
return PendingIntent.getBroadcast(
|
||||||
|
context, code,
|
||||||
Intent(context, TimetableWidgetProvider::class.java).apply {
|
Intent(context, TimetableWidgetProvider::class.java).apply {
|
||||||
action = ACTION_APPWIDGET_UPDATE
|
action = ACTION_APPWIDGET_UPDATE
|
||||||
putExtra(EXTRA_BUTTON_TYPE, buttonType)
|
putExtra(EXTRA_BUTTON_TYPE, buttonType)
|
||||||
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
|
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
|
||||||
}, FLAG_UPDATE_CURRENT)
|
}, FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
|
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
|
||||||
@ -208,4 +246,29 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Context.createAvatarBitmap(student: Student): Bitmap {
|
||||||
|
val avatarColor = if (student.avatarColor == -2937041L) {
|
||||||
|
getCompatColor(R.color.colorPrimaryLight).toLong()
|
||||||
|
} else {
|
||||||
|
student.avatarColor
|
||||||
|
}
|
||||||
|
val avatarDrawable = createNameInitialsDrawable(student.nickOrName, avatarColor, 0.5f)
|
||||||
|
|
||||||
|
val avatarBitmap =
|
||||||
|
if (avatarDrawable.intrinsicWidth <= 0 || avatarDrawable.intrinsicHeight <= 0) {
|
||||||
|
Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
|
||||||
|
} else {
|
||||||
|
Bitmap.createBitmap(
|
||||||
|
avatarDrawable.intrinsicWidth,
|
||||||
|
avatarDrawable.intrinsicHeight,
|
||||||
|
Bitmap.Config.ARGB_8888
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val canvas = Canvas(avatarBitmap)
|
||||||
|
avatarDrawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||||
|
avatarDrawable.draw(canvas)
|
||||||
|
return avatarBitmap
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
Wersja 1.1.2
|
Wersja 1.1.3
|
||||||
|
|
||||||
- naprawiliśmy wyświetlanie planu lekcji i lekcji dodatkowych
|
Oprócz tego naprawiliśmy:
|
||||||
- naprawiliśmy kilka rzadkich problemów ze stabilnością
|
- rzadkie problemy ze stabilnością przy logowaniu i w innych miejscach
|
||||||
|
- brakujące awatary przy zmianie konta z poziomu widżetu
|
||||||
|
- wysyłanie wiadomości gdy w aplikacji jest zalogowany jednocześnie uczeń i rodzic
|
||||||
|
|
||||||
|
Ta wersja jest ostatnią, która będzie działać na starszych urządzeniach z Androidem 4.
|
||||||
|
Od tej pory do końca roku bedziemy dla nich udostępniać wyłącznie krytyczne poprawki błędów
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
android:visibility="visible">
|
android:visibility="gone">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/loginFormHeader"
|
android:id="@+id/loginFormHeader"
|
||||||
@ -85,9 +85,9 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:autofillHints="emailAddress"
|
android:autofillHints="emailAddress"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
android:inputType="textEmailAddress"
|
android:inputType="textEmailAddress"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:imeOptions="actionDone"
|
|
||||||
tools:targetApi="o" />
|
tools:targetApi="o" />
|
||||||
|
|
||||||
<requestFocus />
|
<requestFocus />
|
||||||
@ -156,7 +156,7 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
tools:ignore="UseCompoundDrawables"
|
tools:ignore="UseCompoundDrawables"
|
||||||
tools:visibility="invisible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="100dp"
|
android:layout_width="100dp"
|
||||||
@ -175,12 +175,10 @@
|
|||||||
android:text="@string/error_unknown"
|
android:text="@string/error_unknown"
|
||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp">
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/loginRecoverErrorDetails"
|
android:id="@+id/loginRecoverErrorDetails"
|
||||||
@ -189,14 +187,21 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_marginRight="8dp"
|
||||||
android:text="@string/all_details" />
|
android:text="@string/all_details"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/loginRecoverErrorRetry"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/loginRecoverErrorRetry"
|
android:id="@+id/loginRecoverErrorRetry"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/all_retry" />
|
android:text="@string/all_retry"
|
||||||
</LinearLayout>
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/loginRecoverErrorDetails"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
@ -206,7 +211,7 @@
|
|||||||
android:fillViewport="true"
|
android:fillViewport="true"
|
||||||
android:scrollbars="none"
|
android:scrollbars="none"
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
tools:visibility="invisible">
|
tools:visibility="gone">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -253,6 +258,5 @@
|
|||||||
android:layout_marginBottom="30dp"
|
android:layout_marginBottom="30dp"
|
||||||
android:text="@android:string/ok" />
|
android:text="@android:string/ok" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
@ -506,6 +506,10 @@
|
|||||||
<string name="channel_push">Push upozornění</string>
|
<string name="channel_push">Push upozornění</string>
|
||||||
<string name="channel_upcoming_lessons">Nadcházející lekce</string>
|
<string name="channel_upcoming_lessons">Nadcházející lekce</string>
|
||||||
<string name="channel_debug">Ladění</string>
|
<string name="channel_debug">Ladění</string>
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">Konec podpory</string>
|
||||||
|
<string name="drop_kitkat_content">Ukončujeme podporu pro vaše zařízení. V Wulkanovým už pro něj nebudou žádné nové funkce. Kritické opravy však budeme vydávat až do konce roku 2021, abyste měli čas přejít na novější model</string>
|
||||||
|
<string name="drop_kitkat_again">Nezobrazovat znovu</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Černý</string>
|
<string name="all_black">Černý</string>
|
||||||
<string name="all_red">Červený</string>
|
<string name="all_red">Červený</string>
|
||||||
|
@ -176,7 +176,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Abwesenheitsgrund (optional)</string>
|
<string name="attendance_excuse_dialog_reason">Abwesenheitsgrund (optional)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Senden</string>
|
<string name="attendance_excuse_dialog_submit">Senden</string>
|
||||||
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
<string name="attendance_excuse_success">Abwesenheitsentschuldigungsanfrage erfolgreich gesendet!</string>
|
||||||
<string name="attendance_excuse_no_selection">Sie müssen mindestens eine Abwesenheit auswählen!</string>
|
<string name="attendance_excuse_no_selection">Sie müssen mindestens eine Abwesenheit auswählen!</string>
|
||||||
<string name="attendance_excuse_title">Verzeihung</string>
|
<string name="attendance_excuse_title">Verzeihung</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
@ -466,6 +466,10 @@
|
|||||||
<string name="channel_push">Push-Benachrichtigungen</string>
|
<string name="channel_push">Push-Benachrichtigungen</string>
|
||||||
<string name="channel_upcoming_lessons">Bevorstehende Lektionen</string>
|
<string name="channel_upcoming_lessons">Bevorstehende Lektionen</string>
|
||||||
<string name="channel_debug">Debuggen</string>
|
<string name="channel_debug">Debuggen</string>
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">Ende der Unterstützung</string>
|
||||||
|
<string name="drop_kitkat_content">Wir beenden die Unterstützung für dein Gerät. Es werden keine neuen Funktionen mehr in Wulkanowy erscheinen. Allerdings werden wir bis Ende 2021 kritische Patches veröffentlichen, so dass du Zeit hast, zu einem neueren Modell zu wechseln</string>
|
||||||
|
<string name="drop_kitkat_again">Nicht mehr fragen</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Schwarz</string>
|
<string name="all_black">Schwarz</string>
|
||||||
<string name="all_red">Rot</string>
|
<string name="all_red">Rot</string>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Login</string>
|
<string name="login_title">Prisijungti</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
<string name="grade_title">Laipsnis</string>
|
<string name="grade_title">Laipsnis</string>
|
||||||
<string name="attendance_title">Attendance</string>
|
<string name="attendance_title">Attendance</string>
|
||||||
@ -506,6 +506,10 @@
|
|||||||
<string name="channel_push">Push notifications</string>
|
<string name="channel_push">Push notifications</string>
|
||||||
<string name="channel_upcoming_lessons">Upcoming lessons</string>
|
<string name="channel_upcoming_lessons">Upcoming lessons</string>
|
||||||
<string name="channel_debug">Debug</string>
|
<string name="channel_debug">Debug</string>
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">End of support</string>
|
||||||
|
<string name="drop_kitkat_content">We are ending support for your device. No more new features will appear for it in Wulkanowy. However, we will be releasing critical patches until the end of 2021 so you have time to switch to a newer model</string>
|
||||||
|
<string name="drop_kitkat_again">Don\'t show again</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Black</string>
|
<string name="all_black">Black</string>
|
||||||
<string name="all_red">Red</string>
|
<string name="all_red">Red</string>
|
||||||
|
@ -49,4 +49,12 @@
|
|||||||
<item name="android:navigationBarColor" tools:targetApi="lollipop">?colorSurface</item>
|
<item name="android:navigationBarColor" tools:targetApi="lollipop">?colorSurface</item>
|
||||||
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/black</item>
|
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/black</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="WulkanowyTheme.WidgetAccountSwitcher" parent="Theme.MaterialComponents.Dialog">
|
||||||
|
<item name="colorPrimary">@color/colorPrimaryLight</item>
|
||||||
|
<item name="colorSecondary">@color/colorPrimaryLight</item>
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="android:textColor">?android:textColorPrimary</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -506,6 +506,10 @@
|
|||||||
<string name="channel_push">Powiadomienia push</string>
|
<string name="channel_push">Powiadomienia push</string>
|
||||||
<string name="channel_upcoming_lessons">Nadchodzące lekcje</string>
|
<string name="channel_upcoming_lessons">Nadchodzące lekcje</string>
|
||||||
<string name="channel_debug">Debugowanie</string>
|
<string name="channel_debug">Debugowanie</string>
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">Koniec wsparcia</string>
|
||||||
|
<string name="drop_kitkat_content">Kończymy wsparcie dla Twojego urządzenia. Nie pojawią się już dla niego żadne nowe funkcje w Wulkanowym. Będziemy jednak wypuszczać krytyczne poprawki do końca 2021 roku, abyś miał czas na przeniesienie się na nowszy model</string>
|
||||||
|
<string name="drop_kitkat_again">Nie pokazuj ponownie</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Czarny</string>
|
<string name="all_black">Czarny</string>
|
||||||
<string name="all_red">Czerwony</string>
|
<string name="all_red">Czerwony</string>
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Причина отсутствия (необязательно)</string>
|
<string name="attendance_excuse_dialog_reason">Причина отсутствия (необязательно)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Послать</string>
|
<string name="attendance_excuse_dialog_submit">Послать</string>
|
||||||
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
<string name="attendance_excuse_success">Запрос на освобождение оправдания успешно отправлен!</string>
|
||||||
<string name="attendance_excuse_no_selection">Выберите хотя-бы одно отсутствие</string>
|
<string name="attendance_excuse_no_selection">Выберите хотя-бы одно отсутствие</string>
|
||||||
<string name="attendance_excuse_title">Изменить статус</string>
|
<string name="attendance_excuse_title">Изменить статус</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
@ -506,6 +506,10 @@
|
|||||||
<string name="channel_push">Показывать push-уведомления</string>
|
<string name="channel_push">Показывать push-уведомления</string>
|
||||||
<string name="channel_upcoming_lessons">Будущие уроки</string>
|
<string name="channel_upcoming_lessons">Будущие уроки</string>
|
||||||
<string name="channel_debug">Дебаг</string>
|
<string name="channel_debug">Дебаг</string>
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">Конец поддержки</string>
|
||||||
|
<string name="drop_kitkat_content">Поддержка заканчивается на вашем устройстве. В Wulkanowy больше не появятся новые возможности. Однако до конца 2021 года мы выпустим критические патчи, чтобы у вас было время перейти на новую модель</string>
|
||||||
|
<string name="drop_kitkat_again">Не показывать снова</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Чёрный</string>
|
<string name="all_black">Чёрный</string>
|
||||||
<string name="all_red">Красный</string>
|
<string name="all_red">Красный</string>
|
||||||
|
@ -506,6 +506,10 @@
|
|||||||
<string name="channel_push">Push upozornenia</string>
|
<string name="channel_push">Push upozornenia</string>
|
||||||
<string name="channel_upcoming_lessons">Nadchádzajúce lekcie</string>
|
<string name="channel_upcoming_lessons">Nadchádzajúce lekcie</string>
|
||||||
<string name="channel_debug">Ladenie</string>
|
<string name="channel_debug">Ladenie</string>
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">Koniec podpory</string>
|
||||||
|
<string name="drop_kitkat_content">Ukončujeme podporu pre vaše zariadenie. V Wulkanovým už pre neho nebudú žiadne nové funkcie. Kritické opravy však budeme vydávať až do konca roka 2021, aby ste mali čas prejsť na novší model</string>
|
||||||
|
<string name="drop_kitkat_again">Nezobrazovať znovu</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Čierny</string>
|
<string name="all_black">Čierny</string>
|
||||||
<string name="all_red">Červený</string>
|
<string name="all_red">Červený</string>
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
<string name="login_expired_token">Минув термін дії токену</string>
|
<string name="login_expired_token">Минув термін дії токену</string>
|
||||||
<string name="login_invalid_email">Недійсна адреса електронної пошти</string>
|
<string name="login_invalid_email">Недійсна адреса електронної пошти</string>
|
||||||
<string name="login_invalid_login">Використовуйте призначений логін замість електронної пошти</string>
|
<string name="login_invalid_login">Використовуйте призначений логін замість електронної пошти</string>
|
||||||
<string name="login_invalid_custom_email">Використовуйте призначений логін або електронну адресу в @% 1 $ s</string>
|
<string name="login_invalid_custom_email">Використовуйте призначений логін або електронну адресу в @%1$s</string>
|
||||||
<string name="login_invalid_symbol">Неправильний симбвол</string>
|
<string name="login_invalid_symbol">Неправильний симбвол</string>
|
||||||
<string name="login_incorrect_symbol">Студента не знайдено Перевірте символ та обраний варіант реєстру UONET+</string>
|
<string name="login_incorrect_symbol">Студента не знайдено Перевірте символ та обраний варіант реєстру UONET+</string>
|
||||||
<string name="login_field_required">Обов\'язкове поле</string>
|
<string name="login_field_required">Обов\'язкове поле</string>
|
||||||
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Причина відсутності (необов’язково)</string>
|
<string name="attendance_excuse_dialog_reason">Причина відсутності (необов’язково)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Надіслати</string>
|
<string name="attendance_excuse_dialog_submit">Надіслати</string>
|
||||||
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
<string name="attendance_excuse_success">Запит на виправдання відсутності успішно надіслано!</string>
|
||||||
<string name="attendance_excuse_no_selection">Оберіть хоча б одну відсутність</string>
|
<string name="attendance_excuse_no_selection">Оберіть хоча б одну відсутність</string>
|
||||||
<string name="attendance_excuse_title">Змінити статус</string>
|
<string name="attendance_excuse_title">Змінити статус</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
@ -506,6 +506,10 @@
|
|||||||
<string name="channel_push">Показувати push-повідомлення</string>
|
<string name="channel_push">Показувати push-повідомлення</string>
|
||||||
<string name="channel_upcoming_lessons">Наступні уроки</string>
|
<string name="channel_upcoming_lessons">Наступні уроки</string>
|
||||||
<string name="channel_debug">Дебаг</string>
|
<string name="channel_debug">Дебаг</string>
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">Кінець підтримки</string>
|
||||||
|
<string name="drop_kitkat_content">Ми завершуємо підтримку вашого пристрою. Більше нових функцій не з\'явиться у Wulkanowy. Однак ми виробляємо критичні патчі до кінця 2021, тому у вас буде час перейти на новішу модель</string>
|
||||||
|
<string name="drop_kitkat_again">Не показувати знову</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Чорний</string>
|
<string name="all_black">Чорний</string>
|
||||||
<string name="all_red">Червоний</string>
|
<string name="all_red">Червоний</string>
|
||||||
|
@ -541,6 +541,12 @@
|
|||||||
<string name="channel_debug">Debug</string>
|
<string name="channel_debug">Debug</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Drop kitkat alert dialog strings-->
|
||||||
|
<string name="drop_kitkat_title">End of support</string>
|
||||||
|
<string name="drop_kitkat_content">We are ending support for your device. No more new features will appear for it in Wulkanowy. However, we will be releasing critical patches until the end of 2021 so you have time to switch to a newer model</string>
|
||||||
|
<string name="drop_kitkat_again">Don\'t show again</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Black</string>
|
<string name="all_black">Black</string>
|
||||||
<string name="all_red">Red</string>
|
<string name="all_red">Red</string>
|
||||||
@ -554,6 +560,7 @@
|
|||||||
<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-->
|
<!--Update helper-->
|
||||||
<string name="update_download_started">Download of updates has started…</string>
|
<string name="update_download_started">Download of updates has started…</string>
|
||||||
<string name="update_download_success">An update has just been downloaded.</string>
|
<string name="update_download_success">An update has just been downloaded.</string>
|
||||||
|
@ -26,7 +26,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.DayNight.Dialog">
|
<style name="WulkanowyTheme.WidgetAccountSwitcher" parent="Theme.MaterialComponents.Light.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>
|
||||||
|
@ -54,7 +54,7 @@ class RecipientLocalTest {
|
|||||||
coEvery { recipientDb.deleteAll(any()) } just Runs
|
coEvery { recipientDb.deleteAll(any()) } just Runs
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { recipientRepository.getRecipients(student, ReportingUnit(1, 123, "", 4, "", listOf()), 7) }
|
val res = runBlocking { recipientRepository.getRecipients(student, ReportingUnit(4, 123, "", 4, "", listOf()), 7) }
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(3, res.size)
|
assertEquals(3, res.size)
|
||||||
@ -73,7 +73,7 @@ class RecipientLocalTest {
|
|||||||
coEvery { recipientDb.deleteAll(any()) } just Runs
|
coEvery { recipientDb.deleteAll(any()) } just Runs
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
val res = runBlocking { recipientRepository.getRecipients(student, ReportingUnit(1, 123, "", 4, "", listOf()), 7) }
|
val res = runBlocking { recipientRepository.getRecipients(student, ReportingUnit(4, 123, "", 4, "", listOf()), 7) }
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
assertEquals(3, res.size)
|
assertEquals(3, res.size)
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.splash
|
package io.github.wulkanowy.ui.modules.splash
|
||||||
|
|
||||||
import io.github.wulkanowy.MainCoroutineRule
|
import io.github.wulkanowy.MainCoroutineRule
|
||||||
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -22,6 +25,12 @@ class SplashPresenterTest {
|
|||||||
@MockK
|
@MockK
|
||||||
lateinit var studentRepository: StudentRepository
|
lateinit var studentRepository: StudentRepository
|
||||||
|
|
||||||
|
@MockK
|
||||||
|
lateinit var preferencesRepository: PreferencesRepository
|
||||||
|
|
||||||
|
@MockK
|
||||||
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
@MockK(relaxed = true)
|
@MockK(relaxed = true)
|
||||||
lateinit var errorHandler: ErrorHandler
|
lateinit var errorHandler: ErrorHandler
|
||||||
|
|
||||||
@ -30,19 +39,25 @@ class SplashPresenterTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
presenter = SplashPresenter(errorHandler, studentRepository)
|
presenter = SplashPresenter(errorHandler, studentRepository, preferencesRepository, appInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testOpenLoginView() {
|
fun testOpenLoginView() {
|
||||||
|
every { appInfo.systemVersion } returns 30
|
||||||
|
every { preferencesRepository.isKitkatDialogDisabled } returns true
|
||||||
coEvery { studentRepository.isCurrentStudentSet() } returns false
|
coEvery { studentRepository.isCurrentStudentSet() } returns false
|
||||||
|
|
||||||
presenter.onAttachView(splashView, null)
|
presenter.onAttachView(splashView, null)
|
||||||
verify { splashView.openLoginView() }
|
verify { splashView.openLoginView() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMainMainView() {
|
fun testMainMainView() {
|
||||||
|
every { appInfo.systemVersion } returns 30
|
||||||
|
every { preferencesRepository.isKitkatDialogDisabled } returns true
|
||||||
coEvery { studentRepository.isCurrentStudentSet() } returns true
|
coEvery { studentRepository.isCurrentStudentSet() } returns true
|
||||||
|
|
||||||
presenter.onAttachView(splashView, null)
|
presenter.onAttachView(splashView, null)
|
||||||
verify { splashView.openMainView() }
|
verify { splashView.openMainView() }
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
kotlin_version = '1.4.31'
|
kotlin_version = '1.4.32'
|
||||||
about_libraries = '8.8.4'
|
about_libraries = '8.8.4'
|
||||||
hilt_version = "2.33-beta"
|
hilt_version = "2.33-beta"
|
||||||
}
|
}
|
||||||
@ -13,10 +13,10 @@ 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.1.2'
|
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||||
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.5'
|
classpath 'com.google.gms:google-services:4.3.5'
|
||||||
classpath 'com.huawei.agconnect:agcp:1.5.0.300'
|
classpath 'com.huawei.agconnect:agcp:1.5.1.200'
|
||||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.1'
|
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.1'
|
||||||
classpath "com.github.triplet.gradle:play-publisher:2.8.0"
|
classpath "com.github.triplet.gradle:play-publisher:2.8.0"
|
||||||
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.1.1"
|
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.1.1"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user