mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2024-11-22 11:06:05 -06:00
Add end (#2574)
This commit is contained in:
parent
fc549309d8
commit
3e106d5af0
@ -1,5 +1,6 @@
|
||||
package io.github.wulkanowy.data
|
||||
|
||||
import io.github.wulkanowy.data.repositories.isEndDateReached
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -267,7 +268,8 @@ inline fun <DatabaseType, ApiType, OutputType> networkBoundResource(
|
||||
emit(Resource.Loading())
|
||||
|
||||
val data = query().first()
|
||||
if (shouldFetch(data)) {
|
||||
val updatedShouldFetch = if (isEndDateReached) false else shouldFetch(data)
|
||||
if (updatedShouldFetch) {
|
||||
emit(Resource.Intermediate(data))
|
||||
|
||||
try {
|
||||
|
@ -12,9 +12,13 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filterNot
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import timber.log.Timber
|
||||
import java.time.LocalDate
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
private val endDate = LocalDate.of(2024, 6, 25)
|
||||
val isEndDateReached = LocalDate.now() >= endDate
|
||||
|
||||
@Singleton
|
||||
class WulkanowyRepository @Inject constructor(
|
||||
private val wulkanowyService: WulkanowyService,
|
||||
@ -24,7 +28,6 @@ class WulkanowyRepository @Inject constructor(
|
||||
) {
|
||||
|
||||
private val saveFetchResultMutex = Mutex()
|
||||
|
||||
private val cacheKey = "mapping_refresh_key"
|
||||
|
||||
fun getAdminMessages(): Flow<Resource<List<AdminMessage>>> =
|
||||
|
@ -4,19 +4,27 @@ import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.Build.VERSION_CODES.O
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.work.*
|
||||
import androidx.work.BackoffPolicy.EXPONENTIAL
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.Data
|
||||
import androidx.work.ExistingPeriodicWorkPolicy.KEEP
|
||||
import androidx.work.ExistingPeriodicWorkPolicy.UPDATE
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.NetworkType.CONNECTED
|
||||
import androidx.work.NetworkType.UNMETERED
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||
import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.isEndDateReached
|
||||
import io.github.wulkanowy.services.sync.channels.Channel
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.isHolidays
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import timber.log.Timber
|
||||
import java.time.LocalDate.now
|
||||
import java.util.concurrent.TimeUnit.MINUTES
|
||||
@ -34,7 +42,9 @@ class SyncManager @Inject constructor(
|
||||
) {
|
||||
|
||||
init {
|
||||
if (now().isHolidays) stopSyncWorker()
|
||||
if (now().isHolidays || isEndDateReached) {
|
||||
stopSyncWorker()
|
||||
}
|
||||
|
||||
if (SDK_INT >= O) {
|
||||
channels.forEach { it.create() }
|
||||
@ -50,7 +60,7 @@ class SyncManager @Inject constructor(
|
||||
}
|
||||
|
||||
fun startPeriodicSyncWorker(restart: Boolean = false) {
|
||||
if (preferencesRepository.isServiceEnabled && !now().isHolidays) {
|
||||
if (preferencesRepository.isServiceEnabled && !now().isHolidays && isEndDateReached) {
|
||||
val serviceInterval = preferencesRepository.servicesInterval
|
||||
|
||||
workManager.enqueueUniquePeriodicWork(
|
||||
@ -70,6 +80,10 @@ class SyncManager @Inject constructor(
|
||||
|
||||
// if quiet, no notifications will be sent
|
||||
fun startOneTimeSyncWorker(quiet: Boolean = false): Flow<WorkInfo?> {
|
||||
if (isEndDateReached) {
|
||||
return flowOf(null)
|
||||
}
|
||||
|
||||
val work = OneTimeWorkRequestBuilder<SyncWorker>()
|
||||
.setInputData(
|
||||
Data.Builder()
|
||||
|
@ -15,6 +15,7 @@ import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.isEndDateReached
|
||||
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||
import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
|
||||
import io.github.wulkanowy.sdk.scrapper.exception.FeatureUnavailableException
|
||||
@ -42,7 +43,9 @@ class SyncWorker @AssistedInject constructor(
|
||||
override suspend fun doWork(): Result = withContext(dispatchersProvider.io) {
|
||||
Timber.i("SyncWorker is starting")
|
||||
|
||||
if (!studentRepository.isCurrentStudentSet()) return@withContext Result.failure()
|
||||
if (!studentRepository.isCurrentStudentSet() || isEndDateReached) {
|
||||
return@withContext Result.failure()
|
||||
}
|
||||
|
||||
val (student, semester) = try {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
@ -91,6 +94,7 @@ class SyncWorker @AssistedInject constructor(
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
errors.isNotEmpty() -> Result.retry()
|
||||
else -> {
|
||||
preferencesRepository.lasSyncDate = Instant.now()
|
||||
|
@ -0,0 +1,31 @@
|
||||
package io.github.wulkanowy.ui.modules.end
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.text.HtmlCompat
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.databinding.FragmentEndBinding
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
|
||||
@AndroidEntryPoint
|
||||
class EndFragment : BaseFragment<FragmentEndBinding>(R.layout.fragment_end), EndView {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentEndBinding.bind(view)
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback {
|
||||
requireActivity().finishAffinity()
|
||||
}
|
||||
|
||||
binding.endClose.setOnClickListener { requireActivity().finishAffinity() }
|
||||
|
||||
val message = getString(R.string.end_message)
|
||||
binding.endDescription.movementMethod = LinkMovementMethod.getInstance()
|
||||
binding.endDescription.text =
|
||||
HtmlCompat.fromHtml(message, HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.end
|
||||
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface EndView : BaseView
|
@ -15,6 +15,7 @@ import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||
import io.github.wulkanowy.databinding.ActivityLoginBinding
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.modules.end.EndFragment
|
||||
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
|
||||
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
||||
import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
|
||||
@ -115,9 +116,14 @@ class LoginActivity : BaseActivity<LoginPresenter, ActivityLoginBinding>(), Logi
|
||||
}
|
||||
}
|
||||
|
||||
override fun navigateToEnd() {
|
||||
openFragment(EndFragment(), clearBackStack = true)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
inAppUpdateHelper.onResume()
|
||||
presenter.updateSdkMappings()
|
||||
presenter.checkIfEnd()
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package io.github.wulkanowy.ui.modules.login
|
||||
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.WulkanowyRepository
|
||||
import io.github.wulkanowy.data.repositories.isEndDateReached
|
||||
import io.github.wulkanowy.services.sync.SyncManager
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import kotlinx.coroutines.launch
|
||||
@ -11,7 +13,8 @@ import javax.inject.Inject
|
||||
class LoginPresenter @Inject constructor(
|
||||
private val wulkanowyRepository: WulkanowyRepository,
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository
|
||||
studentRepository: StudentRepository,
|
||||
private val syncManager: SyncManager
|
||||
) : BasePresenter<LoginView>(errorHandler, studentRepository) {
|
||||
|
||||
override fun onAttachView(view: LoginView) {
|
||||
@ -26,4 +29,11 @@ class LoginPresenter @Inject constructor(
|
||||
.onFailure { Timber.e(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun checkIfEnd() {
|
||||
if (isEndDateReached) {
|
||||
syncManager.stopSyncWorker()
|
||||
view?.navigateToEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,4 +5,6 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
interface LoginView : BaseView {
|
||||
|
||||
fun initView()
|
||||
|
||||
fun navigateToEnd()
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.dataOrThrow
|
||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.isEndDateReached
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||
@ -35,6 +37,9 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
|
||||
@Inject
|
||||
lateinit var sharedPref: SharedPrefProvider
|
||||
|
||||
@Inject
|
||||
lateinit var preferencesRepository: PreferencesRepository
|
||||
|
||||
companion object {
|
||||
private const val LUCKY_NUMBER_WIDGET_MAX_SIZE = 196
|
||||
|
||||
@ -130,6 +135,10 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
|
||||
}
|
||||
|
||||
private fun getLuckyNumber(studentId: Long, appWidgetId: Int) = runBlocking {
|
||||
if (isEndDateReached) {
|
||||
return@runBlocking null
|
||||
}
|
||||
|
||||
try {
|
||||
val students = studentRepository.getSavedStudents()
|
||||
val student = students.singleOrNull { it.student.id == studentId }?.student
|
||||
|
@ -33,6 +33,7 @@ import io.github.wulkanowy.ui.modules.Destination
|
||||
import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.ui.modules.captcha.CaptchaDialog
|
||||
import io.github.wulkanowy.ui.modules.end.EndFragment
|
||||
import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
@ -139,6 +140,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
super.onResume()
|
||||
inAppUpdateHelper.onResume()
|
||||
presenter.updateSdkMappings()
|
||||
presenter.checkIfEnd()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
@ -362,4 +364,10 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
super.onSaveInstanceState(outState)
|
||||
navController.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun navigateToEnd() {
|
||||
binding.mainToolbar.isVisible = false
|
||||
pushView(EndFragment())
|
||||
onBackCallback?.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import io.github.wulkanowy.data.onResourceSuccess
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.WulkanowyRepository
|
||||
import io.github.wulkanowy.data.repositories.isEndDateReached
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.services.sync.SyncManager
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
@ -15,6 +16,7 @@ import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import io.github.wulkanowy.ui.modules.account.AccountView
|
||||
import io.github.wulkanowy.ui.modules.account.accountdetails.AccountDetailsView
|
||||
import io.github.wulkanowy.ui.modules.end.EndView
|
||||
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
|
||||
import io.github.wulkanowy.utils.AdsHelper
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
@ -110,6 +112,7 @@ class MainPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun shouldShowBottomNavigation(destination: BaseView) = when (destination) {
|
||||
is EndView,
|
||||
is AccountView,
|
||||
is StudentInfoView,
|
||||
is AccountDetailsView -> false
|
||||
@ -208,4 +211,11 @@ class MainPresenter @Inject constructor(
|
||||
.onFailure { Timber.e(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun checkIfEnd() {
|
||||
if (isEndDateReached) {
|
||||
syncManager.stopSyncWorker()
|
||||
view?.navigateToEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ interface MainView : BaseView {
|
||||
|
||||
fun openMoreDestination(destination: Destination)
|
||||
|
||||
fun navigateToEnd()
|
||||
|
||||
interface MainChildView {
|
||||
|
||||
fun onFragmentReselected()
|
||||
|
@ -22,6 +22,7 @@ import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.TimetableRepository
|
||||
import io.github.wulkanowy.data.repositories.isEndDateReached
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getDateWidgetKey
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey
|
||||
@ -71,6 +72,8 @@ class TimetableWidgetFactory(
|
||||
|
||||
items = emptyList()
|
||||
|
||||
if (isEndDateReached) return
|
||||
|
||||
runBlocking {
|
||||
runCatching {
|
||||
val student = getStudent(studentId) ?: return@runBlocking
|
||||
|
63
app/src/main/res/layout/fragment_end.xml
Normal file
63
app/src/main/res/layout/fragment_end.xml
Normal file
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/endIcon"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
app:layout_constraintBottom_toTopOf="@id/endText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/endText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:gravity="center"
|
||||
android:text="@string/end_title"
|
||||
android:textSize="28sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/endDescription"
|
||||
app:layout_constraintTop_toBottomOf="@id/endIcon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/endDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/endClose"
|
||||
app:layout_constraintTop_toBottomOf="@id/endText"
|
||||
tools:maxLines="15"
|
||||
tools:text="@string/end_message" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/endClose"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="32dp"
|
||||
android:layout_marginTop="48dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="ZAMKNIJ APLIKACJĘ"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/endDescription"
|
||||
app:layout_constraintVertical_bias="0" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string-array name="app_theme_entries" tools:ignore="InconsistentArrays">
|
||||
<item>Motiw systemu</item>
|
||||
<item>Jôsny</item>
|
||||
<item>Cemny</item>
|
||||
<item>Cemny (AMOLED)</item>
|
||||
</string-array>
|
||||
</resources>
|
@ -895,4 +895,8 @@
|
||||
<string name="message_unmute">Unmute</string>
|
||||
<string name="message_mute_success">You have muted this user</string>
|
||||
<string name="message_unmute_success">You have unmuted this user</string>
|
||||
|
||||
<!--End-->
|
||||
<string name="end_title">Koniec Wulkanowego</string>
|
||||
<string name="end_message">Jak zapewne niektórzy z Was się domyślali zbliża się ten moment, aby zakończyć pewien etap. Wraz z końcem tego roku szkolnego zamykamy projekt Wulkanowy. Stworzenie apki było ekscytującym wyzwaniem, ale skala projektu jest tak duża, że nie jesteśmy w stanie odpowiedzialnie utrzymywać aplikacji. Wulkanowy był fajną przygodą, ale sytuacja wymknęła się nam spod kontroli – zarówno pod względem technicznym, jak i społecznym. Nie akceptujemy pojawiającego się hejtu wobec nas ani wobec innych, także Vulcana. Nie chcemy brać udziału w tych działaniach i być z nimi utożsamiani. Prosimy Was o powściągliwość i rozwagę w publikowanych komentarzach i nieprzekraczanie dopuszczalnych granic.<br /><br />Prosimy Was też o uszanowanie naszej decyzji, jest ona przemyślana i ostateczna. Wszystkim dotychczasowym użytkownikom Wulkanowego rekomendujemy użycie oficjalnej aplikacji <a href="https://play.google.com/store/apps/details?id=pl.edu.vulcan.hebe&hl=pl">Dzienniczek VULCAN</a>. Jeszcze raz dziękujemy wszystkim użytkownikom za lata wsparcia, pomoc i miłe słowa!</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user