Фикс невозможности запуска службы переднего плана из LinkUpdateWorker.

Небольшие визуальные изменения.
This commit is contained in:
2024-10-10 01:27:26 +04:00
parent 3da65a3327
commit 2a7e63dce4
21 changed files with 388 additions and 103 deletions

View File

@@ -2,11 +2,20 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- bruh -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- For posting notifications from FCM and CLV services -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- For CLV service able to work -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<!-- For schedule CLV service-->
<!-- <uses-permission android:name="android.permission.USE_EXACT_ALARM" />-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".PolytechnicApplication"
android:allowBackup="true"
@@ -18,6 +27,16 @@
android:theme="@style/Theme.PolytechnicNext"
tools:targetApi="35">
<receiver
android:name=".receiver.BootCompletedBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.AlarmReceiver" />
<service
android:name=".service.MyFirebaseMessagingService"
android:exported="false">

View File

@@ -0,0 +1,5 @@
package ru.n08i40k.polytechnic.next
object IntentRequestCodes {
const val ALARM_CLV = 1337
}

View File

@@ -1,13 +1,20 @@
package ru.n08i40k.polytechnic.next
import android.Manifest
import android.app.AlarmManager
import android.app.Application
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.content.ContextCompat
import dagger.hilt.android.HiltAndroidApp
import ru.n08i40k.polytechnic.next.data.AppContainer
import ru.n08i40k.polytechnic.next.model.Group
import ru.n08i40k.polytechnic.next.receiver.AlarmReceiver
import ru.n08i40k.polytechnic.next.utils.or
import java.util.Calendar
import javax.inject.Inject
@HiltAndroidApp
@@ -27,4 +34,84 @@ class PolytechnicApplication : Application() {
|| ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
== PackageManager.PERMISSION_GRANTED)
}
private fun getDate(group: Group): Calendar? {
val javaCalendar = Calendar.getInstance()
val currentMinutes = javaCalendar.get(Calendar.HOUR_OF_DAY) * 60 +
javaCalendar.get(Calendar.MINUTE)
var startDayIdx = javaCalendar.get(Calendar.DAY_OF_WEEK) - 2
println("Current day is $startDayIdx")
val currentDay = group.days[startDayIdx]
if (currentDay != null) {
val firstLesson = currentDay.first
if (firstLesson == null || firstLesson.time.start < currentMinutes) {
println("Current day already started or ended!")
++startDayIdx
}
}
for (dayIdx in startDayIdx..5) {
println("Trying $dayIdx day...")
val day = group.days[dayIdx] ?: continue
println("Day isn't null")
val firstLesson = day.first ?: continue
println("Day isn't empty")
val executeMinutes = (firstLesson.time.start - 15).coerceAtLeast(0)
println("Schedule minutes at $executeMinutes")
return Calendar.getInstance().apply {
set(Calendar.DAY_OF_WEEK, dayIdx + 2) // sunday is first + index from 0
set(Calendar.HOUR_OF_DAY, executeMinutes / 60)
set(Calendar.MINUTE, executeMinutes % 60)
set(Calendar.SECOND, 0)
// set(Calendar.MINUTE, get(Calendar.MINUTE) + 1)
}
}
return null
}
fun scheduleClvService(group: Group) {
// -1 = вс
// 0 = пн
// 1 = вт
// 2 = ср
// 3 = чт
// 4 = пт
// 5 = сб
println("Getting date...")
val date = getDate(group) ?: return
println("Alarm on this week!")
val alarmManager = applicationContext
.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
val pendingIntent =
Intent(applicationContext, AlarmReceiver::class.java).let {
PendingIntent.getBroadcast(
applicationContext,
IntentRequestCodes.ALARM_CLV,
it,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
}
if (alarmManager != null)
println("Alarm manager isn't null.")
alarmManager?.cancel(pendingIntent)
alarmManager?.set(
AlarmManager.RTC_WAKEUP,
date.timeInMillis,
pendingIntent
)
}
}

View File

@@ -3,10 +3,11 @@ package ru.n08i40k.polytechnic.next.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import ru.n08i40k.polytechnic.next.utils.getDayMinutes
import java.util.Calendar
@Parcelize
@Suppress("unused")
@Suppress("unused", "MemberVisibilityCanBePrivate")
@Serializable
class Day(
val name: String,
@@ -15,7 +16,7 @@ class Day(
val customIndices: ArrayList<Int>,
val lessons: ArrayList<Lesson?>
) : Parcelable {
fun getDistanceToNextByMinutes(from: Int): Map.Entry<Int, Int>? {
fun distanceToNextByMinutes(from: Int): Pair<Int, Int>? {
val toIdx = lessons
.map { if (it?.time == null) null else it.time.start }
.indexOfFirst { if (it == null) false else it > from }
@@ -23,53 +24,79 @@ class Day(
if (toIdx == -1)
return null
return object : Map.Entry<Int, Int> {
override val key: Int
get() = toIdx
override val value: Int
get() = lessons[toIdx]!!.time!!.start - from
}
return Pair(toIdx, lessons[toIdx]!!.time.start - from)
}
fun getDistanceToNextByIdx(from: Int? = null): Map.Entry<Int, Int>? {
fun distanceToNextByIdx(from: Int? = null): Pair<Int, Int>? {
val fromLesson = if (from != null) lessons[from] else null
if (from != null && fromLesson?.time == null)
if (from != null && fromLesson == null)
throw NullPointerException("Lesson (by given index) and it's time should be non-null!")
val fromTime =
if (from != null)
fromLesson!!.time!!.end
fromLesson!!.time.end
else
Calendar.getInstance()
.get(Calendar.HOUR_OF_DAY) * 60 + Calendar.getInstance()
.get(Calendar.MINUTE)
return getDistanceToNextByMinutes(fromTime)
return distanceToNextByMinutes(fromTime)
}
fun getCurrentLesson(): Map.Entry<Int, Lesson>? {
val minutes = Calendar.getInstance()
.get(Calendar.HOUR_OF_DAY) * 60 + Calendar.getInstance()
.get(Calendar.MINUTE)
// current
val currentIdx: Int?
get() {
val minutes = Calendar.getInstance().getDayMinutes()
for (lessonIdx in 0..<lessons.size) {
val lesson = lessons[lessonIdx] ?: continue
for (lessonIdx in nonNullIndices) {
val lesson = lessons[lessonIdx]!!
if (lesson.time == null
|| minutes < lesson.time.start
|| minutes >= lesson.time.end
)
continue
return object : Map.Entry<Int, Lesson> {
override val key: Int
get() = lessonIdx
override val value: Lesson
get() = lesson
if (lesson.time.start <= minutes && minutes < lesson.time.end)
return lessonIdx
}
return null
}
return null
}
val current: Lesson?
get() {
return lessons[currentIdx ?: return null]
}
val currentKV: Pair<Int, Lesson>?
get() {
val idx = currentIdx ?: return null
return Pair(idx, lessons[idx]!!)
}
// first
val firstIdx: Int?
get() = nonNullIndices.getOrNull(0)
val first: Lesson?
get() {
return lessons[firstIdx ?: return null]!!
}
val firstKV: Pair<Int, Lesson>?
get() {
val idx = firstIdx ?: return null
return Pair(idx, lessons[idx]!!)
}
// last
val lastIdx: Int?
get() = nonNullIndices.getOrNull(nonNullIndices.size - 1)
val last: Lesson?
get() {
return lessons[lastIdx ?: return null]!!
}
val lastKV: Pair<Int, Lesson>?
get() {
val idx = lastIdx ?: return null
return Pair(idx, lessons[idx]!!)
}
}

View File

@@ -5,23 +5,31 @@ import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import java.util.Calendar
@Suppress("MemberVisibilityCanBePrivate")
@Parcelize
@Serializable
data class Group(
val name: String,
val days: ArrayList<Day?>
) : Parcelable {
fun getCurrentDay(): Map.Entry<Int, Day?>? {
val currentDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2)
val currentIdx: Int?
get() {
val currentDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2)
if (currentDay < 0 || currentDay > days.size - 1)
return null
if (currentDay < 0 || currentDay > days.size - 1)
return null
return object : Map.Entry<Int, Day?> {
override val key: Int
get() = currentDay
override val value: Day?
get() = days[currentDay]
return currentDay
}
val current: Day?
get() {
return days.getOrNull(currentIdx ?: return null)
}
val currentKV: Pair<Int, Day?>?
get() {
val idx = currentIdx ?: return null
return Pair(idx, days[idx])
}
}
}

View File

@@ -13,16 +13,14 @@ data class Lesson(
val type: LessonType,
val defaultIndex: Int,
val name: String,
val time: LessonTime?,
val time: LessonTime,
val cabinets: ArrayList<String>,
val teacherNames: ArrayList<String>
) : Parcelable {
fun getDuration(): Int? {
if (this.time == null)
return null
return time.end - time.start
}
val duration: Int
get() {
return time.end - time.start
}
fun getNameAndCabinetsShort(context: Context): String {
val limitedName = name limit 15

View File

@@ -0,0 +1,42 @@
package ru.n08i40k.polytechnic.next.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.work.Constraints
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import ru.n08i40k.polytechnic.next.service.CurrentLessonViewService
import ru.n08i40k.polytechnic.next.work.ScheduleClvAlarm
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
println("Hi from AlarmReceiver")
if (intent == null) {
println("No intend provided!")
return
}
if (context == null) {
println("No context provided!")
return
}
println(intent.action)
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val rescheduleRequest = OneTimeWorkRequestBuilder<ScheduleClvAlarm>()
.setConstraints(constraints)
.build()
WorkManager
.getInstance(context)
.enqueue(rescheduleRequest)
CurrentLessonViewService.startService(context.applicationContext)
}
}

View File

@@ -0,0 +1,45 @@
package ru.n08i40k.polytechnic.next.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.work.Constraints
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import ru.n08i40k.polytechnic.next.work.ScheduleClvAlarm
import java.util.logging.Logger
class BootCompletedBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val logger = Logger.getLogger("BootCompletedBroadcastReceiver")
if (context == null) {
logger.warning("No context provided!")
return
}
if (intent == null) {
logger.warning("No intend provided!")
return
}
if (intent.action != "android.intent.action.BOOT_COMPLETED") {
logger.warning("Strange intent action passed!")
logger.warning(intent.action)
return
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val request = OneTimeWorkRequestBuilder<ScheduleClvAlarm>()
.setConstraints(constraints)
.build()
WorkManager
.getInstance(context)
.enqueue(request)
}
}

View File

@@ -19,9 +19,11 @@ import ru.n08i40k.polytechnic.next.model.Day
import ru.n08i40k.polytechnic.next.model.Group
import ru.n08i40k.polytechnic.next.model.Lesson
import ru.n08i40k.polytechnic.next.utils.fmtAsClock
import ru.n08i40k.polytechnic.next.utils.getDayMinutes
import ru.n08i40k.polytechnic.next.work.StartClvService
import java.util.Calendar
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
class CurrentLessonViewService : Service() {
companion object {
private const val NOTIFICATION_STATUS_ID = 1337
@@ -58,16 +60,16 @@ class CurrentLessonViewService : Service() {
.get(Calendar.HOUR_OF_DAY) * 60 + Calendar.getInstance()
.get(Calendar.MINUTE)
val currentLessonEntry = day!!.getCurrentLesson()
val currentLessonIdx: Int? = currentLessonEntry?.key
val currentLesson: Lesson? = currentLessonEntry?.value
val currentLessonEntry = day!!.currentKV
val currentLessonIdx: Int? = currentLessonEntry?.first
val currentLesson: Lesson? = currentLessonEntry?.second
val nextLessonEntry = day!!.getDistanceToNextByIdx(currentLessonIdx)
val nextLessonEntry = day!!.distanceToNextByIdx(currentLessonIdx)
val nextLesson =
if (nextLessonEntry == null)
null
else
day!!.lessons[nextLessonEntry.key]
day!!.lessons[nextLessonEntry.first]
if (currentLesson == null && nextLesson == null) {
val notification = NotificationCompat
@@ -83,13 +85,13 @@ class CurrentLessonViewService : Service() {
return
}
val firstLessonIdx = day!!.getDistanceToNextByMinutes(0)?.key
val firstLessonIdx = day!!.distanceToNextByMinutes(0)?.first
?: throw NullPointerException("Is this even real?")
val distanceToFirst = day!!.lessons[firstLessonIdx]!!.time!!.start - currentMinutes
val currentLessonDelay =
if (currentLesson == null) // Если эта пара - перемена, то конец перемены через (результат getDistanceToNext)
nextLessonEntry!!.value
nextLessonEntry!!.second
else // Если эта пара - обычная пара, то конец пары через (конец этой пары - текущее кол-во минут)
currentLesson.time!!.end - currentMinutes
@@ -157,32 +159,29 @@ class CurrentLessonViewService : Service() {
return getSystemService(NOTIFICATION_SERVICE) as NotificationManager
}
fun updateSchedule(group: Group?): Boolean {
private fun updateSchedule(group: Group?): Boolean {
if (group == null) {
stopSelf()
return false
}
val day = group.getCurrentDay()
if (day?.value == null) {
val currentDay = group.current
if (currentDay == null || currentDay.nonNullIndices.isEmpty()) {
stopSelf()
return false
}
val dayValue = day.value!!
if (this.day == null) {
if (dayValue.lessons[dayValue.defaultIndices[dayValue.defaultIndices.lastIndex]]!!.time!!.end
<= Calendar.getInstance()
.get(Calendar.HOUR_OF_DAY) * 60 + Calendar.getInstance()
.get(Calendar.MINUTE)
) {
val nowMinutes = Calendar.getInstance().getDayMinutes()
if (currentDay.first!!.time.start - nowMinutes > 30
|| currentDay.last!!.time.end < nowMinutes) {
stopSelf()
return false
}
}
this.day = dayValue
this.day = currentDay
this.handler.removeCallbacks(updateRunnable)
updateRunnable.run()

View File

@@ -20,6 +20,7 @@ import com.google.firebase.messaging.RemoteMessage
import ru.n08i40k.polytechnic.next.NotificationChannels
import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.work.FcmSetTokenWorker
import ru.n08i40k.polytechnic.next.work.ScheduleClvAlarm
import java.time.Duration
class MyFirebaseMessagingService : FirebaseMessagingService() {
@@ -100,6 +101,18 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
NotificationCompat.PRIORITY_DEFAULT,
message.data["etag"]
)
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val request = OneTimeWorkRequestBuilder<ScheduleClvAlarm>()
.setConstraints(constraints)
.build()
WorkManager
.getInstance(applicationContext)
.enqueue(request)
}
"app-update" -> {

View File

@@ -10,6 +10,7 @@ import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -18,6 +19,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material3.Card
import androidx.compose.material3.CardColors
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
@@ -30,6 +33,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Composable
@@ -53,7 +57,8 @@ fun ExpandableCard(
onExpandedChange()
transitionState.targetState = expanded
},
shape = RectangleShape
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
border = BorderStroke(Dp.Hairline, MaterialTheme.colorScheme.inverseSurface)
) {
Column {
ExpandableCardHeader(title, transition)

View File

@@ -3,7 +3,6 @@ package ru.n08i40k.polytechnic.next.ui
import android.Manifest
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
@@ -38,7 +37,6 @@ import ru.n08i40k.polytechnic.next.NotificationChannels
import ru.n08i40k.polytechnic.next.PolytechnicApplication
import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.data.MyResult
import ru.n08i40k.polytechnic.next.service.CurrentLessonViewService
import ru.n08i40k.polytechnic.next.settings.settingsDataStore
import ru.n08i40k.polytechnic.next.work.FcmUpdateCallbackWorker
import ru.n08i40k.polytechnic.next.work.LinkUpdateWorker
@@ -103,10 +101,7 @@ class MainActivity : ComponentActivity() {
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
private fun startTestService() {
if (!(applicationContext as PolytechnicApplication).hasNotificationPermission())
return
private fun scheduleAlarm() {
lifecycleScope.launch {
val schedule = (applicationContext as PolytechnicApplication)
.container
@@ -116,11 +111,8 @@ class MainActivity : ComponentActivity() {
if (schedule is MyResult.Failure)
return@launch
val intent = Intent(this@MainActivity, CurrentLessonViewService::class.java)
.apply {
putExtra("group", (schedule as MyResult.Success).data)
}
startForegroundService(intent)
(applicationContext as PolytechnicApplication)
.scheduleClvService((schedule as MyResult.Success).data)
}
}
@@ -190,7 +182,7 @@ class MainActivity : ComponentActivity() {
setupFirebaseConfig()
handleUpdate()
startTestService()
scheduleAlarm()
setContent {
Box(Modifier.windowInsetsPadding(WindowInsets.safeContent.only(WindowInsetsSides.Top))) {

View File

@@ -7,8 +7,9 @@ import androidx.activity.ComponentActivity
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
@@ -95,19 +96,25 @@ private fun NavHostContainer(
enterTransition = {
slideIn(
animationSpec = tween(
500,
400,
delayMillis = 250,
easing = LinearOutSlowInEasing
)
) { fullSize -> IntOffset(-fullSize.width, 0) }
) { fullSize -> IntOffset(0, fullSize.height / 16) } + fadeIn(
animationSpec = tween(
400,
delayMillis = 250,
easing = LinearOutSlowInEasing
)
)
},
exitTransition = {
slideOut(
fadeOut(
animationSpec = tween(
500,
250,
easing = FastOutSlowInEasing
)
) { fullSize -> IntOffset(fullSize.width, 0) }
)
},
builder = {
composable("profile") {

View File

@@ -66,9 +66,7 @@ fun calculateCurrentLessonIdx(lessons: ArrayList<Lesson?>): Int {
val filteredLessons = lessons
.filterNotNull()
.filter {
it.time != null
&& it.time.start <= currentMinutes
&& it.time.end >= currentMinutes
it.time.start <= currentMinutes && it.time.end >= currentMinutes
}
if (filteredLessons.isEmpty())
@@ -101,16 +99,20 @@ fun DayCard(
modifier = modifier,
colors = CardDefaults.cardColors(
containerColor =
if (current) MaterialTheme.colorScheme.surfaceContainerHighest
else MaterialTheme.colorScheme.surfaceContainerLowest
)
if (current) MaterialTheme.colorScheme.inverseSurface
else MaterialTheme.colorScheme.surface
),
border = BorderStroke(1.dp, MaterialTheme.colorScheme.inverseSurface)
) {
if (day == null) {
Text(
modifier = Modifier.fillMaxWidth(),
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
text = stringResource(R.string.day_null)
text = stringResource(R.string.day_null),
color =
if (current) MaterialTheme.colorScheme.inverseOnSurface
else MaterialTheme.colorScheme.onSurface
)
return@Card
}

View File

@@ -37,10 +37,10 @@ fun DayPager(group: Group = FakeScheduleRepository.exampleGroup) {
val offset = pagerState.getOffsetDistanceInPages(page).absoluteValue
lerp(
start = 0.95f, stop = 1f, fraction = 1f - offset.coerceIn(0f, 1f)
start = 1f, stop = 0.95f, fraction = 1f - offset.coerceIn(0f, 1f)
).also { scale ->
scaleX = 1F - scale + 0.95F
scaleY = 1F - scale + 0.95F
scaleX = scale
scaleY = scale
}
alpha = lerp(
start = 0.5f, stop = 1f, fraction = 1f - offset.coerceIn(0f, 1f)

View File

@@ -79,7 +79,7 @@ fun LessonExtraInfo(
append(stringResource(R.string.lesson_duration))
append(" - ")
val duration =
if (lesson.time != null) lesson.time.end - lesson.time.start else 0
lesson.time.end - lesson.time.start
append(duration / 60)
append(stringResource(R.string.hours))
@@ -215,9 +215,7 @@ fun FreeLessonRow(
) {
LessonViewRow(
-1,
if (lesson.time != null && nextLesson.time != null) LessonTime(
lesson.time.end, nextLesson.time.start
) else null,
LessonTime(lesson.time.end, nextLesson.time.start),
LessonTimeFormat.ONLY_MINUTES_DURATION,
stringResource(R.string.lesson_break),
arrayListOf(),

View File

@@ -2,7 +2,9 @@ package ru.n08i40k.polytechnic.next.ui.main.schedule
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
@@ -15,6 +17,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
@@ -79,6 +82,7 @@ fun ScheduleScreen(
val hasSchedule = uiState as ScheduleUiState.HasSchedule
UpdateInfo(hasSchedule.lastUpdateAt, hasSchedule.updateDates)
Spacer(Modifier.height(10.dp))
DayPager(hasSchedule.group)
}
}

View File

@@ -1,5 +1,7 @@
package ru.n08i40k.polytechnic.next.utils
import java.util.Calendar
infix fun <T> T?.or(data: T): T {
if (this == null)
return data
@@ -25,4 +27,7 @@ infix fun String.limit(count: Int): String {
.substring(0, count - 1)
.trimEnd()
.plus("")
}
}
fun Calendar.getDayMinutes(): Int =
this.get(Calendar.HOUR_OF_DAY) * 60 + this.get(Calendar.MINUTE)

View File

@@ -17,7 +17,7 @@ class LinkUpdateWorker(context: Context, params: WorkerParameters) :
.getGroup()
}
CurrentLessonViewService.startService(applicationContext)
// CurrentLessonViewService.startService(applicationContext)
return Result.success()
}

View File

@@ -0,0 +1,29 @@
package ru.n08i40k.polytechnic.next.work
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.PolytechnicApplication
import ru.n08i40k.polytechnic.next.data.MyResult
class ScheduleClvAlarm(context: Context, workerParams: WorkerParameters) :
Worker(context, workerParams) {
override fun doWork(): Result {
val application = applicationContext as PolytechnicApplication
val result = runBlocking {
application
.container
.scheduleRepository
.getGroup()
}
if (result is MyResult.Failure)
return Result.failure()
application.scheduleClvService((result as MyResult.Success).data)
return Result.success()
}
}