forked from github/wulkanowy-mirror
Add conferences and announcements notifications (#1330)
This commit is contained in:
parent
59cf4fb222
commit
983dcd8656
@ -151,7 +151,7 @@ huaweiPublish {
|
|||||||
|
|
||||||
ext {
|
ext {
|
||||||
work_manager = "2.5.0"
|
work_manager = "2.5.0"
|
||||||
work_hilt = "1.0.0"
|
android_hilt = "1.0.0"
|
||||||
room = "2.3.0"
|
room = "2.3.0"
|
||||||
chucker = "3.4.0"
|
chucker = "3.4.0"
|
||||||
mockk = "1.11.0"
|
mockk = "1.11.0"
|
||||||
@ -195,7 +195,8 @@ dependencies {
|
|||||||
|
|
||||||
implementation "com.google.dagger:hilt-android:$hilt_version"
|
implementation "com.google.dagger:hilt-android:$hilt_version"
|
||||||
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
|
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
|
||||||
implementation "androidx.hilt:hilt-work:$work_hilt"
|
kapt "androidx.hilt:hilt-compiler:$android_hilt"
|
||||||
|
implementation "androidx.hilt:hilt-work:$android_hilt"
|
||||||
|
|
||||||
implementation "com.ncapdevi:frag-nav:3.3.0"
|
implementation "com.ncapdevi:frag-nav:3.3.0"
|
||||||
implementation "com.github.YarikSOffice:lingver:1.3.0"
|
implementation "com.github.YarikSOffice:lingver:1.3.0"
|
||||||
|
2260
app/schemas/io.github.wulkanowy.data.db.AppDatabase/39.json
Normal file
2260
app/schemas/io.github.wulkanowy.data.db.AppDatabase/39.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -93,6 +93,7 @@ import io.github.wulkanowy.data.db.migrations.Migration35
|
|||||||
import io.github.wulkanowy.data.db.migrations.Migration36
|
import io.github.wulkanowy.data.db.migrations.Migration36
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration37
|
import io.github.wulkanowy.data.db.migrations.Migration37
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration38
|
import io.github.wulkanowy.data.db.migrations.Migration38
|
||||||
|
import io.github.wulkanowy.data.db.migrations.Migration39
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration5
|
import io.github.wulkanowy.data.db.migrations.Migration5
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration6
|
import io.github.wulkanowy.data.db.migrations.Migration6
|
||||||
@ -141,7 +142,7 @@ import javax.inject.Singleton
|
|||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VERSION_SCHEMA = 38
|
const val VERSION_SCHEMA = 39
|
||||||
|
|
||||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
||||||
Migration2(),
|
Migration2(),
|
||||||
@ -181,6 +182,7 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
Migration36(),
|
Migration36(),
|
||||||
Migration37(),
|
Migration37(),
|
||||||
Migration38(),
|
Migration38(),
|
||||||
|
Migration39(),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun newInstance(
|
fun newInstance(
|
||||||
|
@ -32,4 +32,7 @@ data class Conference(
|
|||||||
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
|
|
||||||
|
@ColumnInfo(name = "is_notified")
|
||||||
|
var isNotified: Boolean = true
|
||||||
}
|
}
|
||||||
|
@ -21,4 +21,7 @@ data class SchoolAnnouncement(
|
|||||||
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
|
|
||||||
|
@ColumnInfo(name = "is_notified")
|
||||||
|
var isNotified: Boolean = true
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package io.github.wulkanowy.data.db.migrations
|
||||||
|
|
||||||
|
import androidx.room.migration.Migration
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
|
||||||
|
class Migration39 : Migration(38, 39) {
|
||||||
|
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
database.execSQL("ALTER TABLE Conferences ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
|
||||||
|
database.execSQL("ALTER TABLE SchoolAnnouncements ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.wulkanowy.data.repositories
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.dao.ConferenceDao
|
import io.github.wulkanowy.data.db.dao.ConferenceDao
|
||||||
|
import io.github.wulkanowy.data.db.entities.Conference
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
@ -10,6 +11,8 @@ import io.github.wulkanowy.utils.getRefreshKey
|
|||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
import io.github.wulkanowy.utils.networkBoundResource
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -25,19 +28,46 @@ class ConferenceRepository @Inject constructor(
|
|||||||
|
|
||||||
private val cacheKey = "conference"
|
private val cacheKey = "conference"
|
||||||
|
|
||||||
fun getConferences(student: Student, semester: Semester, forceRefresh: Boolean) = networkBoundResource(
|
fun getConferences(
|
||||||
|
student: Student,
|
||||||
|
semester: Semester,
|
||||||
|
forceRefresh: Boolean,
|
||||||
|
notify: Boolean = false
|
||||||
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
shouldFetch = { it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester)) },
|
shouldFetch = {
|
||||||
query = { conferenceDb.loadAll(semester.diaryId, student.studentId) },
|
it.isEmpty() || forceRefresh
|
||||||
|
|| refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||||
|
},
|
||||||
|
query = {
|
||||||
|
conferenceDb.loadAll(
|
||||||
|
semester.diaryId,
|
||||||
|
student.studentId
|
||||||
|
)
|
||||||
|
},
|
||||||
fetch = {
|
fetch = {
|
||||||
sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
.getConferences()
|
.getConferences()
|
||||||
.mapToEntities(semester)
|
.mapToEntities(semester)
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
|
val conferencesToSave = (new uniqueSubtract old).onEach {
|
||||||
|
if (notify) it.isNotified = false
|
||||||
|
}
|
||||||
|
|
||||||
conferenceDb.deleteAll(old uniqueSubtract new)
|
conferenceDb.deleteAll(old uniqueSubtract new)
|
||||||
conferenceDb.insertAll(new uniqueSubtract old)
|
conferenceDb.insertAll(conferencesToSave)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
fun getNotNotifiedConference(semester: Semester): Flow<List<Conference>> {
|
||||||
|
return conferenceDb.loadAll(
|
||||||
|
diaryId = semester.diaryId,
|
||||||
|
studentId = semester.studentId
|
||||||
|
).map {
|
||||||
|
it.filter { conference -> !conference.isNotified }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun updateConference(conference: List<Conference>) = conferenceDb.updateAll(conference)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package io.github.wulkanowy.data.repositories
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao
|
import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao
|
||||||
|
import io.github.wulkanowy.data.db.entities.Conference
|
||||||
|
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
@ -9,6 +12,8 @@ import io.github.wulkanowy.utils.getRefreshKey
|
|||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
import io.github.wulkanowy.utils.networkBoundResource
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -24,20 +29,42 @@ class SchoolAnnouncementRepository @Inject constructor(
|
|||||||
|
|
||||||
private val cacheKey = "school_announcement"
|
private val cacheKey = "school_announcement"
|
||||||
|
|
||||||
fun getSchoolAnnouncements(student: Student, forceRefresh: Boolean) = networkBoundResource(
|
fun getSchoolAnnouncements(
|
||||||
|
student: Student,
|
||||||
|
forceRefresh: Boolean,
|
||||||
|
notify: Boolean = false
|
||||||
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
it.isEmpty() || forceRefresh || refreshHelper.isShouldBeRefreshed(
|
it.isEmpty() || forceRefresh
|
||||||
getRefreshKey(cacheKey, student)
|
|| refreshHelper.isShouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||||
)
|
},
|
||||||
|
query = {
|
||||||
|
schoolAnnouncementDb.loadAll(
|
||||||
|
student.studentId)
|
||||||
|
},
|
||||||
|
fetch = {
|
||||||
|
sdk.init(student)
|
||||||
|
.getDirectorInformation()
|
||||||
|
.mapToEntities(student)
|
||||||
},
|
},
|
||||||
query = { schoolAnnouncementDb.loadAll(student.studentId) },
|
|
||||||
fetch = { sdk.init(student).getDirectorInformation().mapToEntities(student) },
|
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
schoolAnnouncementDb.deleteAll(old uniqueSubtract new)
|
val schoolAnnouncementsToSave = (new uniqueSubtract old).onEach {
|
||||||
schoolAnnouncementDb.insertAll(new uniqueSubtract old)
|
if (notify) it.isNotified = false
|
||||||
|
}
|
||||||
|
|
||||||
|
schoolAnnouncementDb.deleteAll(old uniqueSubtract new)
|
||||||
|
schoolAnnouncementDb.insertAll(schoolAnnouncementsToSave)
|
||||||
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
fun getNotNotifiedSchoolAnnouncement(semester: Semester): Flow<List<SchoolAnnouncement>> {
|
||||||
|
return schoolAnnouncementDb.loadAll(
|
||||||
|
studentId = semester.studentId
|
||||||
|
).map {
|
||||||
|
it.filter { schoolAnnouncement -> !schoolAnnouncement.isNotified }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun updateSchoolAnnouncement(schoolAnnouncement: List<SchoolAnnouncement>) = schoolAnnouncementDb.updateAll(schoolAnnouncement)
|
||||||
}
|
}
|
||||||
|
@ -15,16 +15,19 @@ import dagger.multibindings.IntoSet
|
|||||||
import io.github.wulkanowy.services.sync.channels.Channel
|
import io.github.wulkanowy.services.sync.channels.Channel
|
||||||
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel
|
import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewConferencesChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewExamChannel
|
import io.github.wulkanowy.services.sync.channels.NewExamChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewGradesChannel
|
import io.github.wulkanowy.services.sync.channels.NewGradesChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewHomeworkChannel
|
import io.github.wulkanowy.services.sync.channels.NewHomeworkChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewMessagesChannel
|
import io.github.wulkanowy.services.sync.channels.NewMessagesChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewNotesChannel
|
import io.github.wulkanowy.services.sync.channels.NewNotesChannel
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewSchoolAnnouncementsChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.PushChannel
|
import io.github.wulkanowy.services.sync.channels.PushChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel
|
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel
|
||||||
import io.github.wulkanowy.services.sync.works.AttendanceSummaryWork
|
import io.github.wulkanowy.services.sync.works.AttendanceSummaryWork
|
||||||
import io.github.wulkanowy.services.sync.works.AttendanceWork
|
import io.github.wulkanowy.services.sync.works.AttendanceWork
|
||||||
import io.github.wulkanowy.services.sync.works.CompletedLessonWork
|
import io.github.wulkanowy.services.sync.works.CompletedLessonWork
|
||||||
|
import io.github.wulkanowy.services.sync.works.ConferenceWork
|
||||||
import io.github.wulkanowy.services.sync.works.ExamWork
|
import io.github.wulkanowy.services.sync.works.ExamWork
|
||||||
import io.github.wulkanowy.services.sync.works.GradeStatisticsWork
|
import io.github.wulkanowy.services.sync.works.GradeStatisticsWork
|
||||||
import io.github.wulkanowy.services.sync.works.GradeWork
|
import io.github.wulkanowy.services.sync.works.GradeWork
|
||||||
@ -73,6 +76,10 @@ abstract class ServicesModule {
|
|||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun provideAttendanceWork(work: AttendanceWork): Work
|
abstract fun provideAttendanceWork(work: AttendanceWork): Work
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideConferenceWork(work: ConferenceWork): Work
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun provideExamWork(work: ExamWork): Work
|
abstract fun provideExamWork(work: ExamWork): Work
|
||||||
@ -125,6 +132,10 @@ abstract class ServicesModule {
|
|||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun provideLuckyNumberChannel(channel: LuckyNumberChannel): Channel
|
abstract fun provideLuckyNumberChannel(channel: LuckyNumberChannel): Channel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideNewConferenceChannel(channel: NewConferencesChannel): Channel
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun provideNewExamChannel(channel: NewExamChannel): Channel
|
abstract fun provideNewExamChannel(channel: NewExamChannel): Channel
|
||||||
@ -145,6 +156,10 @@ abstract class ServicesModule {
|
|||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun provideNewNotesChannel(channel: NewNotesChannel): Channel
|
abstract fun provideNewNotesChannel(channel: NewNotesChannel): Channel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideNewSchoolAnnouncementChannel(channel: NewSchoolAnnouncementsChannel): Channel
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun providePushChannel(channel: PushChannel): Channel
|
abstract fun providePushChannel(channel: PushChannel): Channel
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.channels
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.app.Notification
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@TargetApi(26)
|
||||||
|
class NewConferencesChannel @Inject constructor(
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
@ApplicationContext private val context: Context
|
||||||
|
) : Channel {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CHANNEL_ID = "new_conferences_channel"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun create() {
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_conference), NotificationManager.IMPORTANCE_HIGH)
|
||||||
|
.apply {
|
||||||
|
enableLights(true)
|
||||||
|
enableVibration(true)
|
||||||
|
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.channels
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.app.Notification
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@TargetApi(26)
|
||||||
|
class NewSchoolAnnouncementsChannel @Inject constructor(
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
@ApplicationContext private val context: Context
|
||||||
|
) : Channel {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CHANNEL_ID = "new_schoolAnnouncements_channel"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun create() {
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_school_announcement), NotificationManager.IMPORTANCE_HIGH)
|
||||||
|
.apply {
|
||||||
|
enableLights(true)
|
||||||
|
enableVibration(true)
|
||||||
|
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Conference
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.ConferenceRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewConferencesChannel
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.getCompatBitmap
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
|
import io.github.wulkanowy.utils.waitForResult
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class ConferenceWork @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val conferenceRepository: ConferenceRepository,
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val preferencesRepository: PreferencesRepository
|
||||||
|
) : Work {
|
||||||
|
|
||||||
|
override suspend fun doWork(student: Student, semester: Semester) {
|
||||||
|
conferenceRepository.getConferences(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
forceRefresh = true,
|
||||||
|
notify = preferencesRepository.isNotificationsEnable
|
||||||
|
).waitForResult()
|
||||||
|
|
||||||
|
conferenceRepository.getNotNotifiedConference(semester).first().let {
|
||||||
|
if (it.isNotEmpty()) notify(it)
|
||||||
|
|
||||||
|
conferenceRepository.updateConference(it.onEach { conference -> conference.isNotified = true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notify(conference: List<Conference>) {
|
||||||
|
notificationManager.notify(
|
||||||
|
Random.nextInt(Int.MAX_VALUE),
|
||||||
|
NotificationCompat.Builder(context, NewConferencesChannel.CHANNEL_ID)
|
||||||
|
.setContentTitle(context.resources.getQuantityString(R.plurals.conference_notify_new_item_title, conference.size, conference.size))
|
||||||
|
.setContentText(context.resources.getQuantityString(R.plurals.conference_notify_new_items, conference.size, conference.size))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_all)
|
||||||
|
.setLargeIcon(context.getCompatBitmap(R.drawable.ic_more_conferences, R.color.colorPrimary))
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
|
.setContentIntent(
|
||||||
|
PendingIntent.getActivity(
|
||||||
|
context, MainView.Section.CONFERENCE.id,
|
||||||
|
MainActivity.getStartIntent(context, MainView.Section.CONFERENCE, true),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
|
setSummaryText(
|
||||||
|
context.resources.getQuantityString(
|
||||||
|
R.plurals.conference_number_item,
|
||||||
|
conference.size,
|
||||||
|
conference.size
|
||||||
|
)
|
||||||
|
)
|
||||||
|
conference.forEach { addLine("${it.title}: ${it.subject}") }
|
||||||
|
this
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,83 @@
|
|||||||
package io.github.wulkanowy.services.sync.works
|
package io.github.wulkanowy.services.sync.works
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository
|
import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.NewSchoolAnnouncementsChannel
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.getCompatBitmap
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
import io.github.wulkanowy.utils.waitForResult
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
class SchoolAnnouncementWork @Inject constructor(
|
class SchoolAnnouncementWork @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
private val schoolAnnouncementRepository: SchoolAnnouncementRepository,
|
private val schoolAnnouncementRepository: SchoolAnnouncementRepository,
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val preferencesRepository: PreferencesRepository
|
||||||
) : Work {
|
) : Work {
|
||||||
|
|
||||||
override suspend fun doWork(student: Student, semester: Semester) {
|
override suspend fun doWork(student: Student, semester: Semester) {
|
||||||
schoolAnnouncementRepository.getSchoolAnnouncements(student, true).waitForResult()
|
schoolAnnouncementRepository.getSchoolAnnouncements(
|
||||||
|
student,
|
||||||
|
true,
|
||||||
|
notify = preferencesRepository.isNotificationsEnable
|
||||||
|
).waitForResult()
|
||||||
|
|
||||||
|
|
||||||
|
schoolAnnouncementRepository.getNotNotifiedSchoolAnnouncement(semester).first().let {
|
||||||
|
if (it.isNotEmpty()) notify(it)
|
||||||
|
|
||||||
|
schoolAnnouncementRepository.updateSchoolAnnouncement(it.onEach { schoolAnnouncement -> schoolAnnouncement.isNotified = true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notify(schoolAnnouncement: List<SchoolAnnouncement>) {
|
||||||
|
notificationManager.notify(
|
||||||
|
Random.nextInt(Int.MAX_VALUE),
|
||||||
|
NotificationCompat.Builder(context, NewSchoolAnnouncementsChannel.CHANNEL_ID)
|
||||||
|
.setContentTitle(context.resources.getQuantityString(
|
||||||
|
R.plurals.school_announcement_notify_new_item_title,
|
||||||
|
schoolAnnouncement.size,
|
||||||
|
schoolAnnouncement.size
|
||||||
|
))
|
||||||
|
.setContentText(context.resources.getQuantityString(R.plurals.school_announcement_notify_new_items, schoolAnnouncement.size, schoolAnnouncement.size))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_all)
|
||||||
|
.setLargeIcon(context.getCompatBitmap(R.drawable.ic_all_about, R.color.colorPrimary))
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setDefaults(NotificationCompat.DEFAULT_ALL)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
|
.setContentIntent(
|
||||||
|
PendingIntent.getActivity(
|
||||||
|
context, MainView.Section.SCHOOL_ANNOUNCEMENT.id,
|
||||||
|
MainActivity.getStartIntent(context, MainView.Section.SCHOOL_ANNOUNCEMENT, true),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
|
setSummaryText(
|
||||||
|
context.resources.getQuantityString(
|
||||||
|
R.plurals.school_announcement_number_item,
|
||||||
|
schoolAnnouncement.size,
|
||||||
|
schoolAnnouncement.size
|
||||||
|
)
|
||||||
|
)
|
||||||
|
schoolAnnouncement.forEach { addLine("${it.subject}: ${it.content}") }
|
||||||
|
this
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,8 @@ interface MainView : BaseView {
|
|||||||
ABOUT(10),
|
ABOUT(10),
|
||||||
SCHOOL(11),
|
SCHOOL(11),
|
||||||
ACCOUNT(12),
|
ACCOUNT(12),
|
||||||
STUDENT_INFO(13)
|
STUDENT_INFO(13),
|
||||||
|
CONFERENCE(14),
|
||||||
|
SCHOOL_ANNOUNCEMENT(15)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF000000"
|
android:fillColor="#FFF"
|
||||||
android:pathData="M9,13.75c-2.34,0 -7,1.17 -7,3.5L2,19h14v-1.75c0,-2.33 -4.66,-3.5 -7,-3.5zM4.34,17c0.84,-0.58 2.87,-1.25 4.66,-1.25s3.82,0.67 4.66,1.25L4.34,17zM9,12c1.93,0 3.5,-1.57 3.5,-3.5S10.93,5 9,5 5.5,6.57 5.5,8.5 7.07,12 9,12zM9,7c0.83,0 1.5,0.67 1.5,1.5S9.83,10 9,10s-1.5,-0.67 -1.5,-1.5S8.17,7 9,7zM16.04,13.81c1.16,0.84 1.96,1.96 1.96,3.44L18,19h4v-1.75c0,-2.02 -3.5,-3.17 -5.96,-3.44zM15,12c1.93,0 3.5,-1.57 3.5,-3.5S16.93,5 15,5c-0.54,0 -1.04,0.13 -1.5,0.35 0.63,0.89 1,1.98 1,3.15s-0.37,2.26 -1,3.15c0.46,0.22 0.96,0.35 1.5,0.35z" />
|
android:pathData="M9,13.75c-2.34,0 -7,1.17 -7,3.5L2,19h14v-1.75c0,-2.33 -4.66,-3.5 -7,-3.5zM4.34,17c0.84,-0.58 2.87,-1.25 4.66,-1.25s3.82,0.67 4.66,1.25L4.34,17zM9,12c1.93,0 3.5,-1.57 3.5,-3.5S10.93,5 9,5 5.5,6.57 5.5,8.5 7.07,12 9,12zM9,7c0.83,0 1.5,0.67 1.5,1.5S9.83,10 9,10s-1.5,-0.67 -1.5,-1.5S8.17,7 9,7zM16.04,13.81c1.16,0.84 1.96,1.96 1.96,3.44L18,19h4v-1.75c0,-2.02 -3.5,-3.17 -5.96,-3.44zM15,12c1.93,0 3.5,-1.57 3.5,-3.5S16.93,5 15,5c-0.54,0 -1.04,0.13 -1.5,0.35 0.63,0.89 1,1.98 1,3.15s-0.37,2.26 -1,3.15c0.46,0.22 0.96,0.35 1.5,0.35z" />
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -353,11 +353,35 @@
|
|||||||
<!--Conference-->
|
<!--Conference-->
|
||||||
<string name="conferences_title">Conferences</string>
|
<string name="conferences_title">Conferences</string>
|
||||||
<string name="conference_no_items">No info about conferences</string>
|
<string name="conference_no_items">No info about conferences</string>
|
||||||
|
<plurals name="conference_number_item">
|
||||||
|
<item quantity="one">%d conference</item>
|
||||||
|
<item quantity="other">%d conferences</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="conference_notify_new_item_title">
|
||||||
|
<item quantity="one">New conference</item>
|
||||||
|
<item quantity="other">New conferences</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="conference_notify_new_items">
|
||||||
|
<item quantity="one">You have %1$d new conference</item>
|
||||||
|
<item quantity="other">You have %1$d new conferences</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
|
||||||
<!--Director information-->
|
<!--Director information-->
|
||||||
<string name="school_announcement_title">School announcements</string>
|
<string name="school_announcement_title">School announcements</string>
|
||||||
<string name="school_announcement_no_items">No school announcements</string>
|
<string name="school_announcement_no_items">No school announcements</string>
|
||||||
|
<plurals name="school_announcement_number_item">
|
||||||
|
<item quantity="one">%d school announcement</item>
|
||||||
|
<item quantity="other">%d school announcements</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="school_announcement_notify_new_item_title">
|
||||||
|
<item quantity="one">New school announcement</item>
|
||||||
|
<item quantity="other">New school announcements</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="school_announcement_notify_new_items">
|
||||||
|
<item quantity="one">You have %1$d new school announcement</item>
|
||||||
|
<item quantity="other">You have %1$d new school announcements</item>
|
||||||
|
</plurals>
|
||||||
|
|
||||||
|
|
||||||
<!--Account-->
|
<!--Account-->
|
||||||
@ -545,10 +569,12 @@
|
|||||||
<!--Notification Channels-->
|
<!--Notification Channels-->
|
||||||
<string name="channel_new_grades">New grades</string>
|
<string name="channel_new_grades">New grades</string>
|
||||||
<string name="channel_new_homework">New homework</string>
|
<string name="channel_new_homework">New homework</string>
|
||||||
|
<string name="channel_new_conference">New conferences</string>
|
||||||
<string name="channel_new_exam">New exams</string>
|
<string name="channel_new_exam">New exams</string>
|
||||||
<string name="channel_lucky_number">Lucky number</string>
|
<string name="channel_lucky_number">Lucky number</string>
|
||||||
<string name="channel_new_message">New messages</string>
|
<string name="channel_new_message">New messages</string>
|
||||||
<string name="channel_new_notes">New notes</string>
|
<string name="channel_new_notes">New notes</string>
|
||||||
|
<string name="channel_new_school_announcement">New school announcements</string>
|
||||||
<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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user