diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/Notification.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/Notification.kt new file mode 100644 index 000000000..ba003f3ab --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/pojos/Notification.kt @@ -0,0 +1,35 @@ +package io.github.wulkanowy.data.pojos + +import androidx.annotation.DrawableRes +import androidx.annotation.PluralsRes +import androidx.annotation.StringRes +import io.github.wulkanowy.ui.modules.main.MainView + +sealed interface Notification { + val channelId: String + val startMenu: MainView.Section + val icon: Int + val titleStringRes: Int + val contentStringRes: Int +} + +data class MultipleNotifications( + override val channelId: String, + override val startMenu: MainView.Section, + @DrawableRes override val icon: Int, + @PluralsRes override val titleStringRes: Int, + @PluralsRes override val contentStringRes: Int, + + @PluralsRes val summaryStringRes: Int, + val lines: List, +) : Notification + +data class OneNotification( + override val channelId: String, + override val startMenu: MainView.Section, + @DrawableRes override val icon: Int, + @StringRes override val titleStringRes: Int, + @StringRes override val contentStringRes: Int, + + val contentValues: List, +) : Notification diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt index 715b7a0ef..0d20d5a56 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt @@ -12,7 +12,6 @@ import io.github.wulkanowy.utils.init import io.github.wulkanowy.utils.networkBoundResource import io.github.wulkanowy.utils.uniqueSubtract import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map import kotlinx.coroutines.sync.Mutex import javax.inject.Inject import javax.inject.Singleton @@ -60,13 +59,9 @@ class ConferenceRepository @Inject constructor( refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester)) } ) - fun getNotNotifiedConference(semester: Semester): Flow> { - return conferenceDb.loadAll( - diaryId = semester.diaryId, - studentId = semester.studentId - ).map { - it.filter { conference -> !conference.isNotified } - } + + fun getConferenceFromDatabase(semester: Semester): Flow> { + return conferenceDb.loadAll(semester.diaryId, semester.studentId) } suspend fun updateConference(conference: List) = conferenceDb.updateAll(conference) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt index c05203d13..9406c77c6 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt @@ -14,7 +14,6 @@ import io.github.wulkanowy.utils.networkBoundResource import io.github.wulkanowy.utils.startExamsDay import io.github.wulkanowy.utils.uniqueSubtract import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map import kotlinx.coroutines.sync.Mutex import java.time.LocalDate import javax.inject.Inject @@ -69,15 +68,13 @@ class ExamRepository @Inject constructor( filterResult = { it.filter { item -> item.date in start..end } } ) - fun getNotNotifiedExam(semester: Semester, start: LocalDate): Flow> { + fun getExamsFromDatabase(semester: Semester, start: LocalDate): Flow> { return examDb.loadAll( diaryId = semester.diaryId, studentId = semester.studentId, from = start.startExamsDay, end = start.endExamsDay - ).map { - it.filter { exam -> !exam.isNotified } - } + ) } suspend fun updateExam(exam: List) = examDb.updateAll(exam) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt index 9880e4641..0b8a0e710 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt @@ -104,22 +104,16 @@ class GradeRepository @Inject constructor( } } - fun getNotNotifiedGrades(semester: Semester): Flow> { - return gradeDb.loadAll(semester.semesterId, semester.studentId).map { - it.filter { grade -> !grade.isNotified } - } + fun getGradesFromDatabase(semester: Semester): Flow> { + return gradeDb.loadAll(semester.semesterId, semester.studentId) } - fun getNotNotifiedPredictedGrades(semester: Semester): Flow> { - return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).map { - it.filter { gradeSummary -> !gradeSummary.isPredictedGradeNotified } - } + fun getGradesPredictedFromDatabase(semester: Semester): Flow> { + return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId) } - fun getNotNotifiedFinalGrades(semester: Semester): Flow> { - return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).map { - it.filter { gradeSummary -> !gradeSummary.isFinalGradeNotified } - } + fun getGradesFinalFromDatabase(semester: Semester): Flow> { + return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId) } suspend fun updateGrade(grade: Grade) { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/HomeworkRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/HomeworkRepository.kt index 84014ce62..476a810c9 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/HomeworkRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/HomeworkRepository.kt @@ -13,7 +13,6 @@ import io.github.wulkanowy.utils.monday import io.github.wulkanowy.utils.networkBoundResource import io.github.wulkanowy.utils.sunday import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.map import kotlinx.coroutines.sync.Mutex import java.time.LocalDate import javax.inject.Inject @@ -31,12 +30,9 @@ class HomeworkRepository @Inject constructor( private val cacheKey = "homework" fun getHomework( - student: Student, - semester: Semester, - start: LocalDate, - end: LocalDate, - forceRefresh: Boolean, - notify: Boolean = false + student: Student, semester: Semester, + start: LocalDate, end: LocalDate, + forceRefresh: Boolean, notify: Boolean = false ) = networkBoundResource( mutex = saveFetchResultMutex, shouldFetch = { @@ -74,14 +70,8 @@ class HomeworkRepository @Inject constructor( })) } - fun getNotNotifiedHomework( - semester: Semester, - start: LocalDate, - end: LocalDate - ) = homeworkDb.loadAll(semester.semesterId, semester.studentId, start.monday, end.sunday) - .map { - it.filter { homework -> !homework.isNotified } - } + fun getHomeworkFromDatabase(semester: Semester, start: LocalDate, end: LocalDate) = + homeworkDb.loadAll(semester.semesterId, semester.studentId, start.monday, end.sunday) suspend fun updateHomework(homework: List) = homeworkDb.updateAll(homework) -} \ No newline at end of file +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt index 5f5554187..1b718ff71 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt @@ -77,8 +77,8 @@ class MessageRepository @Inject constructor( } ) - fun getNotNotifiedMessages(student: Student): Flow> { - return messagesDb.loadAll(student.id.toInt(), RECEIVED.id).map { it.filter { message -> !message.isNotified && message.unread } } + fun getMessagesFromDatabase(student: Student): Flow> { + return messagesDb.loadAll(student.id.toInt(), RECEIVED.id) } suspend fun updateMessages(messages: List) { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt index 85339dfa9..d43cdbc0c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt @@ -50,8 +50,8 @@ class NoteRepository @Inject constructor( } ) - fun getNotNotifiedNotes(student: Student): Flow> { - return noteDb.loadAll(student.studentId).map { it.filter { note -> !note.isNotified } } + fun getNotesFromDatabase(student: Student): Flow> { + return noteDb.loadAll(student.studentId) } suspend fun updateNote(note: Note) { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolAnnouncementRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolAnnouncementRepository.kt index 8579db7d7..62d806ac2 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolAnnouncementRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolAnnouncementRepository.kt @@ -57,12 +57,8 @@ class SchoolAnnouncementRepository @Inject constructor( refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student)) } ) - fun getNotNotifiedSchoolAnnouncement(semester: Semester): Flow> { - return schoolAnnouncementDb.loadAll( - studentId = semester.studentId - ).map { - it.filter { schoolAnnouncement -> !schoolAnnouncement.isNotified } - } + fun getSchoolAnnouncementFromDatabase(student: Student): Flow> { + return schoolAnnouncementDb.loadAll(student.studentId) } suspend fun updateSchoolAnnouncement(schoolAnnouncement: List) = schoolAnnouncementDb.updateAll(schoolAnnouncement) diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/BaseNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/BaseNotification.kt new file mode 100644 index 000000000..089924f6d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/BaseNotification.kt @@ -0,0 +1,70 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.app.PendingIntent +import android.content.Context +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import io.github.wulkanowy.R +import io.github.wulkanowy.data.pojos.MultipleNotifications +import io.github.wulkanowy.data.pojos.Notification +import io.github.wulkanowy.data.pojos.OneNotification +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.utils.getCompatBitmap +import io.github.wulkanowy.utils.getCompatColor +import kotlin.random.Random + +abstract class BaseNotification( + private val context: Context, + private val notificationManager: NotificationManagerCompat, +) { + + protected fun sendNotification(notification: Notification) { + notificationManager.notify( + Random.nextInt(Int.MAX_VALUE), + NotificationCompat.Builder(context, notification.channelId) + .setLargeIcon(context.getCompatBitmap(notification.icon, R.color.colorPrimary)) + .setSmallIcon(R.drawable.ic_stat_all) + .setAutoCancel(true) + .setDefaults(NotificationCompat.DEFAULT_ALL) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setColor(context.getCompatColor(R.color.colorPrimary)) + .setContentIntent( + PendingIntent.getActivity( + context, notification.startMenu.id, + MainActivity.getStartIntent(context, notification.startMenu, true), + PendingIntent.FLAG_UPDATE_CURRENT + ) + ) + .apply { + when (notification) { + is OneNotification -> buildForOneNotification(notification) + is MultipleNotifications -> buildForMultipleNotification(notification) + } + } + .build() + ) + } + + private fun NotificationCompat.Builder.buildForOneNotification(n: OneNotification) { + val content = context.getString(n.contentStringRes, *n.contentValues.toTypedArray()) + setContentTitle(context.getString(n.titleStringRes)) + setContentText(content) + setStyle(NotificationCompat.BigTextStyle().run { + bigText(content) + this + }) + } + + private fun NotificationCompat.Builder.buildForMultipleNotification(n: MultipleNotifications) { + val lines = n.lines.size + setContentTitle(context.resources.getQuantityString(n.titleStringRes, lines, lines)) + setContentText(context.resources.getQuantityString(n.contentStringRes, lines, lines)) + setStyle(NotificationCompat.InboxStyle().run { + setSummaryText( + context.resources.getQuantityString(n.summaryStringRes, n.lines.size, n.lines.size) + ) + n.lines.forEach(::addLine) + this + }) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt new file mode 100644 index 000000000..8e8431f7d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +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.pojos.MultipleNotifications +import io.github.wulkanowy.services.sync.channels.NewConferencesChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewConferenceNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notify(items: List) { + val notification = MultipleNotifications( + channelId = NewConferencesChannel.CHANNEL_ID, + icon = R.drawable.ic_more_conferences, + titleStringRes = R.plurals.conference_notify_new_item_title, + contentStringRes = R.plurals.conference_notify_new_items, + summaryStringRes = R.plurals.conference_number_item, + startMenu = MainView.Section.CONFERENCE, + lines = items.map { + "${it.title}: ${it.subject}" + } + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewExamNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewExamNotification.kt new file mode 100644 index 000000000..a2d9da564 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewExamNotification.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Exam +import io.github.wulkanowy.data.pojos.MultipleNotifications +import io.github.wulkanowy.services.sync.channels.NewExamChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewExamNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notify(items: List) { + val notification = MultipleNotifications( + channelId = NewExamChannel.CHANNEL_ID, + icon = R.drawable.ic_main_exam, + titleStringRes = R.plurals.exam_notify_new_item_title, + contentStringRes = R.plurals.grade_notify_new_items, // TODO add missing string + summaryStringRes = R.plurals.exam_number_item, + startMenu = MainView.Section.EXAM, + lines = items.map { + "${it.subject}: ${it.description}" + } + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewGradeNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewGradeNotification.kt new file mode 100644 index 000000000..4a2eacad0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewGradeNotification.kt @@ -0,0 +1,66 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Grade +import io.github.wulkanowy.data.db.entities.GradeSummary +import io.github.wulkanowy.data.pojos.MultipleNotifications +import io.github.wulkanowy.services.sync.channels.NewGradesChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewGradeNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notifyDetails(items: List) { + val notification = MultipleNotifications( + channelId = NewGradesChannel.CHANNEL_ID, + icon = R.drawable.ic_stat_grade, + titleStringRes = R.plurals.grade_new_items, + contentStringRes = R.plurals.grade_notify_new_items, + summaryStringRes = R.plurals.grade_number_item, + startMenu = MainView.Section.GRADE, + lines = items.map { + "${it.subject}: ${it.entry}" + } + ) + + sendNotification(notification) + } + + fun notifyPredicted(items: List) { + val notification = MultipleNotifications( + channelId = NewGradesChannel.CHANNEL_ID, + icon = R.drawable.ic_stat_grade, + titleStringRes = R.plurals.grade_new_items_predicted, + contentStringRes = R.plurals.grade_notify_new_items_predicted, + summaryStringRes = R.plurals.grade_number_item, + startMenu = MainView.Section.GRADE, + lines = items.map { + "${it.subject}: ${it.predictedGrade}" + } + ) + + sendNotification(notification) + } + + fun notifyFinal(items: List) { + val notification = MultipleNotifications( + channelId = NewGradesChannel.CHANNEL_ID, + icon = R.drawable.ic_stat_grade, + titleStringRes = R.plurals.grade_new_items_final, + contentStringRes = R.plurals.grade_notify_new_items_final, + summaryStringRes = R.plurals.grade_number_item, + startMenu = MainView.Section.GRADE, + lines = items.map { + "${it.subject}: ${it.finalGrade}" + } + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewHomeworkNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewHomeworkNotification.kt new file mode 100644 index 000000000..228ca668d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewHomeworkNotification.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Homework +import io.github.wulkanowy.data.pojos.MultipleNotifications +import io.github.wulkanowy.services.sync.channels.NewHomeworkChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewHomeworkNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notify(items: List) { + val notification = MultipleNotifications( + channelId = NewHomeworkChannel.CHANNEL_ID, + icon = R.drawable.ic_more_homework, + titleStringRes = R.plurals.homework_notify_new_item_title, + contentStringRes = R.plurals.homework_notify_new_item_title, // todo: you received %d new homework + summaryStringRes = R.plurals.homework_number_item, + startMenu = MainView.Section.HOMEWORK, + lines = items.map { + "${it.subject}: ${it.content}" + } + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewLuckyNumberNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewLuckyNumberNotification.kt new file mode 100644 index 000000000..4bbffa9d0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewLuckyNumberNotification.kt @@ -0,0 +1,30 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.LuckyNumber +import io.github.wulkanowy.data.pojos.OneNotification +import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewLuckyNumberNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notify(item: LuckyNumber) { + val notification = OneNotification( + channelId = LuckyNumberChannel.CHANNEL_ID, + icon = R.drawable.ic_stat_luckynumber, + titleStringRes = R.string.lucky_number_notify_new_item_title, + contentStringRes = R.string.lucky_number_notify_new_item, + startMenu = MainView.Section.LUCKY_NUMBER, + contentValues = listOf(item.luckyNumber.toString()) + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt new file mode 100644 index 000000000..f52fe8574 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.pojos.MultipleNotifications +import io.github.wulkanowy.services.sync.channels.NewMessagesChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewMessageNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notify(items: List) { + val notification = MultipleNotifications( + channelId = NewMessagesChannel.CHANNEL_ID, + icon = R.drawable.ic_stat_message, + titleStringRes = R.plurals.message_new_items, + contentStringRes = R.plurals.message_notify_new_items, + summaryStringRes = R.plurals.message_number_item, + startMenu = MainView.Section.MESSAGE, + lines = items.map { + "${it.sender}: ${it.subject}" + } + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewNoteNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewNoteNotification.kt new file mode 100644 index 000000000..e6e22a44c --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewNoteNotification.kt @@ -0,0 +1,46 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Note +import io.github.wulkanowy.data.pojos.MultipleNotifications +import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory +import io.github.wulkanowy.services.sync.channels.NewMessagesChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewNoteNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notify(items: List) { + val notification = MultipleNotifications( + channelId = NewMessagesChannel.CHANNEL_ID, + icon = R.drawable.ic_stat_note, + titleStringRes = when (NoteCategory.getByValue(items.first().categoryType)) { + NoteCategory.POSITIVE -> R.plurals.praise_new_items + NoteCategory.NEUTRAL -> R.plurals.neutral_note_new_items + else -> R.plurals.note_new_items + }, + contentStringRes = when (NoteCategory.getByValue(items.first().categoryType)) { + NoteCategory.POSITIVE -> R.plurals.praise_notify_new_items + NoteCategory.NEUTRAL -> R.plurals.neutral_note_notify_new_items + else -> R.plurals.note_notify_new_items + }, + summaryStringRes = when (NoteCategory.getByValue(items.first().categoryType)) { + NoteCategory.POSITIVE -> R.plurals.praise_number_item + NoteCategory.NEUTRAL -> R.plurals.neutral_note_number_item + else -> R.plurals.note_number_item + }, + startMenu = MainView.Section.NOTE, + lines = items.map { + "${it.teacher}: ${it.category}" + } + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewSchoolAnnouncementNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewSchoolAnnouncementNotification.kt new file mode 100644 index 000000000..e49289277 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewSchoolAnnouncementNotification.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.services.sync.notifications + +import android.content.Context +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.pojos.MultipleNotifications +import io.github.wulkanowy.services.sync.channels.NewSchoolAnnouncementsChannel +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +class NewSchoolAnnouncementNotification @Inject constructor( + @ApplicationContext private val context: Context, + notificationManager: NotificationManagerCompat, +) : BaseNotification(context, notificationManager) { + + fun notify(items: List) { + val notification = MultipleNotifications( + channelId = NewSchoolAnnouncementsChannel.CHANNEL_ID, + icon = R.drawable.ic_all_about, + titleStringRes = R.plurals.school_announcement_notify_new_item_title, + contentStringRes = R.plurals.school_announcement_notify_new_items, + summaryStringRes = R.plurals.school_announcement_number_item, + startMenu = MainView.Section.SCHOOL_ANNOUNCEMENT, + lines = items.map { + "${it.subject}: ${it.content}" + } + ) + + sendNotification(notification) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/ConferenceWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/ConferenceWork.kt index 90345abf9..5625c549d 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/ConferenceWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/ConferenceWork.kt @@ -1,31 +1,18 @@ 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.services.sync.notifications.NewConferenceNotification 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 + private val preferencesRepository: PreferencesRepository, + private val newConferenceNotification: NewConferenceNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { @@ -36,44 +23,13 @@ class ConferenceWork @Inject constructor( notify = preferencesRepository.isNotificationsEnable ).waitForResult() - conferenceRepository.getNotNotifiedConference(semester).first().let { - if (it.isNotEmpty()) notify(it) + conferenceRepository.getConferenceFromDatabase(semester).first() + .filter { !it.isNotified }.let { + if (it.isNotEmpty()) newConferenceNotification.notify(it) - conferenceRepository.updateConference(it.onEach { conference -> conference.isNotified = true }) - } - } - - private fun notify(conference: List) { - 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 + conferenceRepository.updateConference(it.onEach { conference -> + conference.isNotified = true }) - .build() - ) + } } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt index 0eb3efd87..cc522c385 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt @@ -1,32 +1,19 @@ 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.Exam import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.ExamRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.services.sync.channels.NewExamChannel -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.services.sync.notifications.NewExamNotification import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import java.time.LocalDate.now import javax.inject.Inject -import kotlin.random.Random class ExamWork @Inject constructor( - @ApplicationContext private val context: Context, private val examRepository: ExamRepository, - private val notificationManager: NotificationManagerCompat, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val newExamNotification: NewExamNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { @@ -39,49 +26,11 @@ class ExamWork @Inject constructor( notify = preferencesRepository.isNotificationsEnable ).waitForResult() - examRepository.getNotNotifiedExam(semester, now()).first().let { - if (it.isNotEmpty()) notify(it) + examRepository.getExamsFromDatabase(semester, now()).first() + .filter { !it.isNotified }.let { + if (it.isNotEmpty()) newExamNotification.notify(it) - examRepository.updateExam(it.onEach { exam -> exam.isNotified = true }) - } - } - - private fun notify(exam: List) { - notificationManager.notify( - Random.nextInt(Int.MAX_VALUE), - NotificationCompat.Builder(context, NewExamChannel.CHANNEL_ID) - .setContentTitle( - context.resources.getQuantityString( - R.plurals.exam_notify_new_item_title, exam.size, exam.size - ) - ) - .setSmallIcon(R.drawable.ic_stat_all) - .setLargeIcon( - context.getCompatBitmap(R.drawable.ic_main_exam, 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.MESSAGE.id, - MainActivity.getStartIntent(context, MainView.Section.EXAM, true), - PendingIntent.FLAG_UPDATE_CURRENT - ) - ) - .setStyle(NotificationCompat.InboxStyle().run { - setSummaryText( - context.resources.getQuantityString( - R.plurals.exam_number_item, - exam.size, - exam.size - ) - ) - exam.forEach { addLine("${it.subject}: ${it.description}") } - this - }) - .build() - ) + examRepository.updateExam(it.onEach { exam -> exam.isNotified = true }) + } } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt index 87799705a..d2e04e7c3 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt @@ -1,111 +1,51 @@ package io.github.wulkanowy.services.sync.works -import android.app.PendingIntent -import android.app.PendingIntent.FLAG_UPDATE_CURRENT -import android.content.Context -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationCompat.DEFAULT_ALL -import androidx.core.app.NotificationCompat.PRIORITY_HIGH -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.GradeRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.services.sync.channels.NewGradesChannel -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.services.sync.notifications.NewGradeNotification import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import javax.inject.Inject -import kotlin.random.Random class GradeWork @Inject constructor( - @ApplicationContext private val context: Context, - private val notificationManager: NotificationManagerCompat, private val gradeRepository: GradeRepository, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val newGradeNotification: NewGradeNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { - gradeRepository.getGrades(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult() + gradeRepository.getGrades( + student = student, + semester = semester, + forceRefresh = true, + notify = preferencesRepository.isNotificationsEnable + ).waitForResult() - gradeRepository.getNotNotifiedGrades(semester).first().let { - if (it.isNotEmpty()) notifyDetails(it) - gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true }) - } + gradeRepository.getGradesFromDatabase(semester).first() + .filter { !it.isNotified }.let { + if (it.isNotEmpty()) newGradeNotification.notifyDetails(it) - gradeRepository.getNotNotifiedPredictedGrades(semester).first().let { - if (it.isNotEmpty()) notifyPredicted(it) - gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isPredictedGradeNotified = true }) - } + gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true }) + } - gradeRepository.getNotNotifiedFinalGrades(semester).first().let { - if (it.isNotEmpty()) notifyFinal(it) - gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isFinalGradeNotified = true }) - } - } + gradeRepository.getGradesPredictedFromDatabase(semester).first() + .filter { !it.isPredictedGradeNotified }.let { + if (it.isNotEmpty()) newGradeNotification.notifyPredicted(it) - private fun notifyDetails(grades: List) { - notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder() - .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size)) - .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size)) - .setStyle(NotificationCompat.InboxStyle().run { - setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, grades.size, grades.size)) - grades.forEach { addLine("${it.subject}: ${it.entry}") } - this - }) - .build() - ) - } + gradeRepository.updateGradesSummary(it.onEach { grade -> + grade.isPredictedGradeNotified = true + }) + } - private fun notifyPredicted(gradesSummary: List) { - notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder() - .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_predicted, gradesSummary.size, gradesSummary.size)) - .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_predicted, gradesSummary.size, gradesSummary.size)) - .setStyle(NotificationCompat.InboxStyle().run { - setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size)) - gradesSummary.forEach { addLine("${it.subject}: ${it.predictedGrade}") } - this - }) - .build() - ) - } + gradeRepository.getGradesFinalFromDatabase(semester).first() + .filter { !it.isFinalGradeNotified }.let { + if (it.isNotEmpty()) newGradeNotification.notifyFinal(it) - private fun notifyFinal(gradesSummary: List) { - notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder() - .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_final, gradesSummary.size, gradesSummary.size)) - .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_final, gradesSummary.size, gradesSummary.size)) - .setStyle(NotificationCompat.InboxStyle().run { - setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size)) - gradesSummary.forEach { addLine("${it.subject}: ${it.finalGrade}") } - this - }) - .build() - ) - } - - private fun getNotificationBuilder(): NotificationCompat.Builder { - return NotificationCompat.Builder(context, NewGradesChannel.CHANNEL_ID) - .setSmallIcon(R.drawable.ic_stat_all) - .setLargeIcon( - context.getCompatBitmap(R.drawable.ic_stat_grade, R.color.colorPrimary) - ) - .setAutoCancel(true) - .setPriority(PRIORITY_HIGH) - .setDefaults(DEFAULT_ALL) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setContentIntent( - PendingIntent.getActivity( - context, MainView.Section.GRADE.id, - MainActivity.getStartIntent(context, MainView.Section.GRADE, true), - FLAG_UPDATE_CURRENT - ) - ) + gradeRepository.updateGradesSummary(it.onEach { grade -> + grade.isFinalGradeNotified = true + }) + } } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt index a2fed98dd..f87789e36 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt @@ -1,34 +1,21 @@ 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.Homework import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.HomeworkRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.services.sync.channels.NewHomeworkChannel -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.services.sync.notifications.NewHomeworkNotification import io.github.wulkanowy.utils.monday import io.github.wulkanowy.utils.sunday import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import java.time.LocalDate.now import javax.inject.Inject -import kotlin.random.Random class HomeworkWork @Inject constructor( - @ApplicationContext private val context: Context, private val homeworkRepository: HomeworkRepository, - private val notificationManager: NotificationManagerCompat, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val newHomeworkNotification: NewHomeworkNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { @@ -41,50 +28,13 @@ class HomeworkWork @Inject constructor( notify = preferencesRepository.isNotificationsEnable ).waitForResult() - homeworkRepository.getNotNotifiedHomework(semester, now().monday, now().sunday).first() - .let { - if (it.isNotEmpty()) notify(it) + homeworkRepository.getHomeworkFromDatabase(semester, now().monday, now().sunday).first() + .filter { !it.isNotified }.let { + if (it.isNotEmpty()) newHomeworkNotification.notify(it) homeworkRepository.updateHomework(it.onEach { homework -> homework.isNotified = true }) } } - - private fun notify(homework: List) { - notificationManager.notify( - Random.nextInt(Int.MAX_VALUE), - NotificationCompat.Builder(context, NewHomeworkChannel.CHANNEL_ID) - .setContentTitle( - context.resources.getQuantityString( - R.plurals.homework_notify_new_item_title, homework.size, homework.size - ) - ) - .setSmallIcon(R.drawable.ic_stat_all) - .setLargeIcon( - context.getCompatBitmap(R.drawable.ic_more_homework, 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.MESSAGE.id, - MainActivity.getStartIntent(context, MainView.Section.HOMEWORK, true), - PendingIntent.FLAG_UPDATE_CURRENT - ) - ) - .setStyle(NotificationCompat.InboxStyle().run { - setSummaryText( - context.resources.getQuantityString( - R.plurals.homework_number_item, homework.size, homework.size - ) - ) - homework.forEach { addLine("${it.subject}: ${it.content}") } - this - }) - .build() - ) - } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt index 6ae32abfa..c42327104 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt @@ -1,59 +1,29 @@ package io.github.wulkanowy.services.sync.works -import android.app.PendingIntent -import android.app.PendingIntent.FLAG_UPDATE_CURRENT -import android.content.Context -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationCompat.DEFAULT_ALL -import androidx.core.app.NotificationCompat.PRIORITY_HIGH -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.LuckyNumber import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.LuckyNumberRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel -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.services.sync.notifications.NewLuckyNumberNotification import io.github.wulkanowy.utils.waitForResult import javax.inject.Inject -import kotlin.random.Random class LuckyNumberWork @Inject constructor( - @ApplicationContext private val context: Context, - private val notificationManager: NotificationManagerCompat, private val luckyNumberRepository: LuckyNumberRepository, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val newLuckyNumberNotification: NewLuckyNumberNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { - luckyNumberRepository.getLuckyNumber(student, true, preferencesRepository.isNotificationsEnable).waitForResult() + luckyNumberRepository.getLuckyNumber( + student = student, + forceRefresh = true, + notify = preferencesRepository.isNotificationsEnable + ).waitForResult() luckyNumberRepository.getNotNotifiedLuckyNumber(student)?.let { - notify(it) + newLuckyNumberNotification.notify(it) luckyNumberRepository.updateLuckyNumber(it.apply { isNotified = true }) } } - - private fun notify(luckyNumber: LuckyNumber) { - notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, LuckyNumberChannel.CHANNEL_ID) - .setContentTitle(context.getString(R.string.lucky_number_notify_new_item_title)) - .setContentText(context.getString(R.string.lucky_number_notify_new_item, luckyNumber.luckyNumber)) - .setSmallIcon(R.drawable.ic_stat_all) - .setLargeIcon( - context.getCompatBitmap(R.drawable.ic_stat_luckynumber, R.color.colorPrimary) - ) - .setAutoCancel(true) - .setDefaults(DEFAULT_ALL) - .setPriority(PRIORITY_HIGH) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setContentIntent( - PendingIntent.getActivity(context, MainView.Section.MESSAGE.id, - MainActivity.getStartIntent(context, MainView.Section.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT)) - .build()) - } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt index 011e0c3f6..2bcfd98c7 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt @@ -1,67 +1,34 @@ package io.github.wulkanowy.services.sync.works -import android.app.PendingIntent -import android.app.PendingIntent.FLAG_UPDATE_CURRENT -import android.content.Context -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationCompat.DEFAULT_ALL -import androidx.core.app.NotificationCompat.PRIORITY_HIGH -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED import io.github.wulkanowy.data.repositories.MessageRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.services.sync.channels.NewMessagesChannel -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.services.sync.notifications.NewMessageNotification import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import javax.inject.Inject -import kotlin.random.Random class MessageWork @Inject constructor( - @ApplicationContext private val context: Context, - private val notificationManager: NotificationManagerCompat, private val messageRepository: MessageRepository, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val newMessageNotification: NewMessageNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { - messageRepository.getMessages(student, semester, RECEIVED, true, preferencesRepository.isNotificationsEnable).waitForResult() + messageRepository.getMessages( + student = student, + semester = semester, + folder = RECEIVED, + forceRefresh = true, + notify = preferencesRepository.isNotificationsEnable + ).waitForResult() - messageRepository.getNotNotifiedMessages(student).first().let { - if (it.isNotEmpty()) notify(it) - messageRepository.updateMessages(it.onEach { message -> message.isNotified = true }) - } - } - - private fun notify(messages: List) { - notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewMessagesChannel.CHANNEL_ID) - .setContentTitle(context.resources.getQuantityString(R.plurals.message_new_items, messages.size, messages.size)) - .setContentText(context.resources.getQuantityString(R.plurals.message_notify_new_items, messages.size, messages.size)) - .setSmallIcon(R.drawable.ic_stat_all) - .setLargeIcon( - context.getCompatBitmap(R.drawable.ic_stat_message, R.color.colorPrimary) - ) - .setAutoCancel(true) - .setDefaults(DEFAULT_ALL) - .setPriority(PRIORITY_HIGH) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setContentIntent( - PendingIntent.getActivity(context, MainView.Section.MESSAGE.id, - MainActivity.getStartIntent(context, MainView.Section.MESSAGE, true), FLAG_UPDATE_CURRENT) - ) - .setStyle(NotificationCompat.InboxStyle().run { - setSummaryText(context.resources.getQuantityString(R.plurals.message_number_item, messages.size, messages.size)) - messages.forEach { addLine("${it.sender}: ${it.subject}") } - this - }) - .build()) + messageRepository.getMessagesFromDatabase(student).first() + .filter { !it.isNotified && it.unread }.let { + if (it.isNotEmpty()) newMessageNotification.notify(it) + messageRepository.updateMessages(it.onEach { message -> message.isNotified = true }) + } } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt index 34e1610e2..fec969ead 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt @@ -1,87 +1,34 @@ package io.github.wulkanowy.services.sync.works -import android.app.PendingIntent -import android.app.PendingIntent.FLAG_UPDATE_CURRENT -import android.content.Context -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationCompat.DEFAULT_ALL -import androidx.core.app.NotificationCompat.PRIORITY_HIGH -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.NoteRepository import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory -import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory.NEUTRAL -import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory.POSITIVE -import io.github.wulkanowy.services.sync.channels.NewNotesChannel -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.services.sync.notifications.NewNoteNotification import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import javax.inject.Inject -import kotlin.random.Random class NoteWork @Inject constructor( - @ApplicationContext private val context: Context, - private val notificationManager: NotificationManagerCompat, private val noteRepository: NoteRepository, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val newNoteNotification: NewNoteNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { - noteRepository.getNotes(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult() + noteRepository.getNotes( + student = student, + semester = semester, + forceRefresh = true, + notify = preferencesRepository.isNotificationsEnable + ).waitForResult() - noteRepository.getNotNotifiedNotes(student).first().let { - if (it.isNotEmpty()) notify(it) - noteRepository.updateNotes(it.onEach { note -> note.isNotified = true }) - } - } + noteRepository.getNotesFromDatabase(student).first() + .filter { !it.isNotified }.let { + if (it.isNotEmpty()) newNoteNotification.notify(it) - private fun notify(notes: List) { - notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewNotesChannel.CHANNEL_ID) - .setContentTitle( - when (NoteCategory.getByValue(notes.first().categoryType)) { - POSITIVE -> context.resources.getQuantityString(R.plurals.praise_new_items, notes.size, notes.size) - NEUTRAL -> context.resources.getQuantityString(R.plurals.neutral_note_new_items, notes.size, notes.size) - else -> context.resources.getQuantityString(R.plurals.note_new_items, notes.size, notes.size) - } - ) - .setContentText( - when (NoteCategory.getByValue(notes.first().categoryType)) { - POSITIVE -> context.resources.getQuantityString(R.plurals.praise_notify_new_items, notes.size, notes.size) - NEUTRAL -> context.resources.getQuantityString(R.plurals.neutral_note_notify_new_items, notes.size, notes.size) - else -> context.resources.getQuantityString(R.plurals.note_notify_new_items, notes.size, notes.size) - } - ) - .setSmallIcon(R.drawable.ic_stat_all) - .setLargeIcon( - context.getCompatBitmap(R.drawable.ic_stat_note, R.color.colorPrimary) - ) - .setAutoCancel(true) - .setDefaults(DEFAULT_ALL) - .setPriority(PRIORITY_HIGH) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setContentIntent( - PendingIntent.getActivity(context, MainView.Section.NOTE.id, - MainActivity.getStartIntent(context, MainView.Section.NOTE, true), FLAG_UPDATE_CURRENT)) - .setStyle(NotificationCompat.InboxStyle().run { - setSummaryText( - when (NoteCategory.getByValue(notes.first().categoryType)) { - POSITIVE -> context.resources.getQuantityString(R.plurals.praise_number_item, notes.size, notes.size) - NEUTRAL -> context.resources.getQuantityString(R.plurals.neutral_note_number_item, notes.size, notes.size) - else -> context.resources.getQuantityString(R.plurals.note_number_item, notes.size, notes.size) - } - ) - notes.forEach { addLine("${it.teacher}: ${it.category}") } - this - }) - .build()) + noteRepository.updateNotes(it.onEach { note -> note.isNotified = true }) + } } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/SchoolAnnouncementWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/SchoolAnnouncementWork.kt index f5463e8c4..57480c76e 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/SchoolAnnouncementWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/SchoolAnnouncementWork.kt @@ -1,83 +1,35 @@ 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.Student -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.data.repositories.SchoolAnnouncementRepository +import io.github.wulkanowy.services.sync.notifications.NewSchoolAnnouncementNotification import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import javax.inject.Inject -import kotlin.random.Random class SchoolAnnouncementWork @Inject constructor( - @ApplicationContext private val context: Context, private val schoolAnnouncementRepository: SchoolAnnouncementRepository, - private val notificationManager: NotificationManagerCompat, - private val preferencesRepository: PreferencesRepository + private val preferencesRepository: PreferencesRepository, + private val newSchoolAnnouncementNotification: NewSchoolAnnouncementNotification, ) : Work { override suspend fun doWork(student: Student, semester: Semester) { schoolAnnouncementRepository.getSchoolAnnouncements( - student, - true, + student = student, + forceRefresh = true, notify = preferencesRepository.isNotificationsEnable ).waitForResult() - schoolAnnouncementRepository.getNotNotifiedSchoolAnnouncement(semester).first().let { - if (it.isNotEmpty()) notify(it) + schoolAnnouncementRepository.getSchoolAnnouncementFromDatabase(student).first() + .filter { !it.isNotified }.let { + if (it.isNotEmpty()) newSchoolAnnouncementNotification.notify(it) - schoolAnnouncementRepository.updateSchoolAnnouncement(it.onEach { schoolAnnouncement -> schoolAnnouncement.isNotified = true }) - } -} - - private fun notify(schoolAnnouncement: List) { - 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 + schoolAnnouncementRepository.updateSchoolAnnouncement(it.onEach { schoolAnnouncement -> + schoolAnnouncement.isNotified = true }) - .build() - ) + } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt index 1c613800d..b491dfc7c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt @@ -10,7 +10,7 @@ import io.github.wulkanowy.databinding.FragmentAboutBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment import io.github.wulkanowy.ui.modules.about.license.LicenseFragment -import io.github.wulkanowy.ui.modules.about.logviewer.LogViewerFragment +import io.github.wulkanowy.ui.modules.debug.DebugFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.utils.AppInfo @@ -37,34 +37,60 @@ class AboutFragment : BaseFragment(R.layout.fragment_about override val versionRes: Triple? get() = context?.run { - val buildTimestamp = appInfo.buildTimestamp.toLocalDateTime().toFormattedString("yyyy-MM-dd") - val versionSignature = "${appInfo.versionName}-${appInfo.buildFlavor} (${appInfo.versionCode}), $buildTimestamp" - Triple(getString(R.string.about_version), versionSignature, getCompatDrawable(R.drawable.ic_all_about)) + val buildTimestamp = + appInfo.buildTimestamp.toLocalDateTime().toFormattedString("yyyy-MM-dd") + val versionSignature = + "${appInfo.versionName}-${appInfo.buildFlavor} (${appInfo.versionCode}), $buildTimestamp" + Triple( + getString(R.string.about_version), + versionSignature, + getCompatDrawable(R.drawable.ic_all_about) + ) } override val creatorsRes: Triple? get() = context?.run { - Triple(getString(R.string.about_contributor), getString(R.string.about_contributor_summary), getCompatDrawable(R.drawable.ic_about_creator)) + Triple( + getString(R.string.about_contributor), + getString(R.string.about_contributor_summary), + getCompatDrawable(R.drawable.ic_about_creator) + ) } override val feedbackRes: Triple? get() = context?.run { - Triple(getString(R.string.about_feedback), getString(R.string.about_feedback_summary), getCompatDrawable(R.drawable.ic_about_feedback)) + Triple( + getString(R.string.about_feedback), + getString(R.string.about_feedback_summary), + getCompatDrawable(R.drawable.ic_about_feedback) + ) } override val faqRes: Triple? get() = context?.run { - Triple(getString(R.string.about_faq), getString(R.string.about_faq_summary), getCompatDrawable(R.drawable.ic_about_faq)) + Triple( + getString(R.string.about_faq), + getString(R.string.about_faq_summary), + getCompatDrawable(R.drawable.ic_about_faq) + ) } override val discordRes: Triple? get() = context?.run { - Triple(getString(R.string.about_discord), getString(R.string.about_discord_summary), getCompatDrawable(R.drawable.ic_about_discord)) + Triple( + getString(R.string.about_discord), + getString(R.string.about_discord_summary), + getCompatDrawable(R.drawable.ic_about_discord) + ) } override val facebookRes: Triple? get() = context?.run { - Triple(getString(R.string.about_facebook), getString(R.string.about_facebook_summary), getCompatDrawable(R.drawable.ic_about_facebook)) + Triple( + getString(R.string.about_facebook), + getString(R.string.about_facebook_summary), + getCompatDrawable(R.drawable.ic_about_facebook) + ) } override val homepageRes: Triple? @@ -78,12 +104,20 @@ class AboutFragment : BaseFragment(R.layout.fragment_about override val licensesRes: Triple? get() = context?.run { - Triple(getString(R.string.about_licenses), getString(R.string.about_licenses_summary), getCompatDrawable(R.drawable.ic_about_licenses)) + Triple( + getString(R.string.about_licenses), + getString(R.string.about_licenses_summary), + getCompatDrawable(R.drawable.ic_about_licenses) + ) } override val privacyRes: Triple? get() = context?.run { - Triple(getString(R.string.about_privacy), getString(R.string.about_privacy_summary), getCompatDrawable(R.drawable.ic_about_privacy)) + Triple( + getString(R.string.about_privacy), + getString(R.string.about_privacy_summary), + getCompatDrawable(R.drawable.ic_about_privacy) + ) } override val titleStringId get() = R.string.about_title @@ -118,8 +152,8 @@ class AboutFragment : BaseFragment(R.layout.fragment_about context?.openAppInMarket(::showMessage) } - override fun openLogViewer() { - (activity as? MainActivity)?.pushView(LogViewerFragment.newInstance()) + override fun openDebugScreen() { + (activity as? MainActivity)?.pushView(DebugFragment.newInstance()) } override fun openDiscordInvite() { @@ -155,7 +189,10 @@ class AboutFragment : BaseFragment(R.layout.fragment_about } override fun openFaqPage() { - context?.openInternetBrowser("https://wulkanowy.github.io/czesto-zadawane-pytania", ::showMessage) + context?.openInternetBrowser( + "https://wulkanowy.github.io/czesto-zadawane-pytania", + ::showMessage + ) } override fun openLicenses() { @@ -167,7 +204,10 @@ class AboutFragment : BaseFragment(R.layout.fragment_about } override fun openPrivacyPolicy() { - context?.openInternetBrowser("https://wulkanowy.github.io/polityka-prywatnosci.html", ::showMessage) + context?.openInternetBrowser( + "https://wulkanowy.github.io/polityka-prywatnosci.html", + ::showMessage + ) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt index fde20267d..22be8d41d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt @@ -26,10 +26,10 @@ class AboutPresenter @Inject constructor( view?.run { when (name) { versionRes?.first -> { - Timber.i("Opening log viewer") - if (appInfo.isDebug) openLogViewer() + Timber.i("Opening debug screen") + if (appInfo.isDebug) openDebugScreen() else openAppInMarket() - analytics.logEvent("about_open", "name" to "log_viewer") + analytics.logEvent("about_open", "name" to "debug_screen") } feedbackRes?.first -> { Timber.i("Opening email client") diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt index 54882b302..7c7c0663b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt @@ -29,7 +29,7 @@ interface AboutView : BaseView { fun openAppInMarket() - fun openLogViewer() + fun openDebugScreen() fun openDiscordInvite() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugAdapter.kt new file mode 100644 index 000000000..36f99ca30 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugAdapter.kt @@ -0,0 +1,32 @@ +package io.github.wulkanowy.ui.modules.debug + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import io.github.wulkanowy.databinding.ItemDebugBinding + +class DebugAdapter : RecyclerView.Adapter() { + + var items = emptyList() + + var onItemClickListener: (DebugItem) -> Unit = {} + + override fun getItemCount() = items.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + ItemDebugBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + val item = items[position] + with(holder.binding) { + debugItemName.setText(item.title) + + root.setOnClickListener { + onItemClickListener(item) + } + } + } + + class ItemViewHolder(val binding: ItemDebugBinding) : RecyclerView.ViewHolder(binding.root) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugFragment.kt new file mode 100644 index 000000000..000916b17 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugFragment.kt @@ -0,0 +1,65 @@ +package io.github.wulkanowy.ui.modules.debug + +import android.os.Bundle +import android.view.View +import androidx.recyclerview.widget.LinearLayoutManager +import dagger.hilt.android.AndroidEntryPoint +import io.github.wulkanowy.R +import io.github.wulkanowy.databinding.FragmentDebugBinding +import io.github.wulkanowy.ui.base.BaseFragment +import io.github.wulkanowy.ui.modules.debug.logviewer.LogViewerFragment +import io.github.wulkanowy.ui.modules.debug.notification.NotificationDebugFragment +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +@AndroidEntryPoint +class DebugFragment : BaseFragment(R.layout.fragment_debug), DebugView, + MainView.TitledView { + + @Inject + lateinit var presenter: DebugPresenter + + private val debugAdapter = DebugAdapter() + + override val titleStringId: Int + get() = R.string.debug_title + + companion object { + fun newInstance() = DebugFragment() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding = FragmentDebugBinding.bind(view) + presenter.onAttachView(this) + } + + override fun initView() { + debugAdapter.onItemClickListener = presenter::onItemSelect + with(binding.debugRecycler) { + layoutManager = LinearLayoutManager(context) + adapter = debugAdapter + } + } + + override fun setItems(itemList: List) { + with(debugAdapter) { + items = itemList + notifyDataSetChanged() + } + } + + override fun openLogViewer() { + (activity as? MainActivity)?.pushView(LogViewerFragment.newInstance()) + } + + override fun openNotificationsDebug() { + (activity as? MainActivity)?.pushView(NotificationDebugFragment.newInstance()) + } + + override fun onDestroyView() { + presenter.onDetachView() + super.onDestroyView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugItem.kt new file mode 100644 index 000000000..2273294ef --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugItem.kt @@ -0,0 +1,7 @@ +package io.github.wulkanowy.ui.modules.debug + +import androidx.annotation.StringRes + +data class DebugItem( + @StringRes val title: Int, +) \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugPresenter.kt new file mode 100644 index 000000000..67ac88861 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugPresenter.kt @@ -0,0 +1,37 @@ +package io.github.wulkanowy.ui.modules.debug + +import io.github.wulkanowy.R +import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import timber.log.Timber +import javax.inject.Inject + +class DebugPresenter @Inject constructor( + errorHandler: ErrorHandler, + studentRepository: StudentRepository, +) : BasePresenter(errorHandler, studentRepository) { + + val items = listOf( + DebugItem(R.string.logviewer_title), + DebugItem(R.string.notification_debug_title), + ) + + override fun onAttachView(view: DebugView) { + super.onAttachView(view) + Timber.i("Debug view was initialized") + + with(view) { + initView() + setItems(items) + } + } + + fun onItemSelect(item: DebugItem) { + when (item.title) { + R.string.logviewer_title -> view?.openLogViewer() + R.string.notification_debug_title -> view?.openNotificationsDebug() + else -> Timber.d("Unknown debug item: $item") + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugView.kt new file mode 100644 index 000000000..9396ec6ac --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugView.kt @@ -0,0 +1,14 @@ +package io.github.wulkanowy.ui.modules.debug + +import io.github.wulkanowy.ui.base.BaseView + +interface DebugView : BaseView { + + fun initView() + + fun setItems(itemList: List) + + fun openLogViewer() + + fun openNotificationsDebug() +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerAdapter.kt similarity index 91% rename from app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerAdapter.kt index 45c304aae..5a0e21046 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerAdapter.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.about.logviewer +package io.github.wulkanowy.ui.modules.debug.logviewer import android.view.ViewGroup import android.widget.TextView diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt similarity index 98% rename from app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt index 09572c971..1e11c874b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.about.logviewer +package io.github.wulkanowy.ui.modules.debug.logviewer import android.content.Intent import android.content.Intent.EXTRA_EMAIL diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerPresenter.kt similarity index 97% rename from app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerPresenter.kt index 80020c81d..4310ff87c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerPresenter.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.about.logviewer +package io.github.wulkanowy.ui.modules.debug.logviewer import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.repositories.LoggerRepository diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerView.kt similarity index 78% rename from app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerView.kt index bd98c24fd..3d138ecec 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerView.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.about.logviewer +package io.github.wulkanowy.ui.modules.debug.logviewer import io.github.wulkanowy.ui.base.BaseView import java.io.File diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugAdapter.kt new file mode 100644 index 000000000..78107d436 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugAdapter.kt @@ -0,0 +1,31 @@ +package io.github.wulkanowy.ui.modules.debug.notification + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import io.github.wulkanowy.databinding.ItemDebugNotificationsBinding + +class NotificationDebugAdapter : RecyclerView.Adapter() { + + var items = emptyList() + + override fun getItemCount() = items.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + ItemDebugNotificationsBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + val item = items[position] + + with(holder.binding) { + title.setText(item.title) + button1.setOnClickListener { item.onClickCallback(1) } + button2.setOnClickListener { item.onClickCallback(3) } + button3.setOnClickListener { item.onClickCallback(10) } + } + } + + class ItemViewHolder(val binding: ItemDebugNotificationsBinding) : + RecyclerView.ViewHolder(binding.root) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugFragment.kt new file mode 100644 index 000000000..c5c797d0b --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugFragment.kt @@ -0,0 +1,54 @@ +package io.github.wulkanowy.ui.modules.debug.notification + +import android.os.Bundle +import android.view.View +import androidx.recyclerview.widget.LinearLayoutManager +import dagger.hilt.android.AndroidEntryPoint +import io.github.wulkanowy.R +import io.github.wulkanowy.databinding.FragmentDebugNotificationsBinding +import io.github.wulkanowy.ui.base.BaseFragment +import io.github.wulkanowy.ui.modules.main.MainView +import javax.inject.Inject + +@AndroidEntryPoint +class NotificationDebugFragment : + BaseFragment(R.layout.fragment_debug_notifications), + NotificationDebugView, MainView.TitledView { + + @Inject + lateinit var presenter: NotificationDebugPresenter + + private val notificationDebugAdapter = NotificationDebugAdapter() + + override val titleStringId: Int + get() = R.string.notification_debug_title + + companion object { + fun newInstance() = NotificationDebugFragment() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding = FragmentDebugNotificationsBinding.bind(view) + presenter.onAttachView(this) + } + + override fun initView() { + with(binding.recyclerView) { + adapter = notificationDebugAdapter + layoutManager = LinearLayoutManager(requireContext()) + } + } + + override fun setItems(notificationDebugs: List) { + with(notificationDebugAdapter) { + items = notificationDebugs + notifyDataSetChanged() + } + } + + override fun onDestroyView() { + presenter.onDetachView() + super.onDestroyView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugItem.kt new file mode 100644 index 000000000..5a5287873 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugItem.kt @@ -0,0 +1,8 @@ +package io.github.wulkanowy.ui.modules.debug.notification + +import androidx.annotation.StringRes + +data class NotificationDebugItem( + @StringRes val title: Int, + val onClickCallback: (numberOfNotifications: Int) -> Unit, +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugPresenter.kt new file mode 100644 index 000000000..6d24bf91b --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugPresenter.kt @@ -0,0 +1,83 @@ +package io.github.wulkanowy.ui.modules.debug.notification + +import io.github.wulkanowy.R +import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.services.sync.notifications.NewConferenceNotification +import io.github.wulkanowy.services.sync.notifications.NewExamNotification +import io.github.wulkanowy.services.sync.notifications.NewGradeNotification +import io.github.wulkanowy.services.sync.notifications.NewHomeworkNotification +import io.github.wulkanowy.services.sync.notifications.NewLuckyNumberNotification +import io.github.wulkanowy.services.sync.notifications.NewMessageNotification +import io.github.wulkanowy.services.sync.notifications.NewNoteNotification +import io.github.wulkanowy.services.sync.notifications.NewSchoolAnnouncementNotification +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugConferenceItems +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugExamItems +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugGradeDetailsItems +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugGradeSummaryItems +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugHomeworkItems +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugLuckyNumber +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugMessageItems +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugNoteItems +import io.github.wulkanowy.ui.modules.debug.notification.mock.debugSchoolAnnouncementItems +import timber.log.Timber +import javax.inject.Inject + +class NotificationDebugPresenter @Inject constructor( + errorHandler: ErrorHandler, + studentRepository: StudentRepository, + private val newGradeNotification: NewGradeNotification, + private val newHomeworkNotification: NewHomeworkNotification, + private val newConferenceNotification: NewConferenceNotification, + private val newExamNotification: NewExamNotification, + private val newMessageNotification: NewMessageNotification, + private val newNoteNotification: NewNoteNotification, + private val newSchoolAnnouncementNotification: NewSchoolAnnouncementNotification, + private val newLuckyNumberNotification: NewLuckyNumberNotification, +) : BasePresenter(errorHandler, studentRepository) { + + private val items = listOf( + NotificationDebugItem(R.string.grade_title) { + newGradeNotification.notifyDetails(debugGradeDetailsItems.take(it)) + }, + NotificationDebugItem(R.string.grade_summary_predicted_grade) { + newGradeNotification.notifyPredicted(debugGradeSummaryItems.take(it)) + }, + NotificationDebugItem(R.string.grade_summary_final_grade) { + newGradeNotification.notifyFinal(debugGradeSummaryItems.take(it)) + }, + NotificationDebugItem(R.string.homework_title) { + newHomeworkNotification.notify(debugHomeworkItems.take(it)) + }, + NotificationDebugItem(R.string.conferences_title) { + newConferenceNotification.notify(debugConferenceItems.take(it)) + }, + NotificationDebugItem(R.string.exam_title) { + newExamNotification.notify(debugExamItems.take(it)) + }, + NotificationDebugItem(R.string.message_title) { + newMessageNotification.notify(debugMessageItems.take(it)) + }, + NotificationDebugItem(R.string.note_title) { + newNoteNotification.notify(debugNoteItems.take(it)) + }, + NotificationDebugItem(R.string.school_announcement_title) { + newSchoolAnnouncementNotification.notify(debugSchoolAnnouncementItems.take(it)) + }, + NotificationDebugItem(R.string.lucky_number_title) { + repeat(it) { + newLuckyNumberNotification.notify(debugLuckyNumber) + } + }, + ) + + override fun onAttachView(view: NotificationDebugView) { + super.onAttachView(view) + Timber.i("Notification debug view was initialized") + with(view) { + initView() + setItems(items) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugView.kt new file mode 100644 index 000000000..e2c043c3b --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugView.kt @@ -0,0 +1,10 @@ +package io.github.wulkanowy.ui.modules.debug.notification + +import io.github.wulkanowy.ui.base.BaseView + +interface NotificationDebugView : BaseView { + + fun initView() + + fun setItems(notificationDebugs: List) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/conference.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/conference.kt new file mode 100644 index 000000000..969b1cf23 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/conference.kt @@ -0,0 +1,58 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.Conference +import java.time.LocalDateTime + +val debugConferenceItems = listOf( + generateConference( + title = "Spotkanie z rodzicami/opiekunami", + subject = "Podsumowanie I semestru - średnia klasy, oceny, frekwencja, zachowanie" + ), + generateConference( + title = "ZSW", + subject = "Pierwsze - organizacyjne zebranie z rodzicami klas pierwszych" + ), + generateConference( + title = "Spotkanie z rodzicami w sprawie bójki", + subject = "Pierwsze - i miejmy nadzieję ostatnie - zebranie w takiej sprawie" + ), + generateConference( + title = "Spotkanie z rodzicami w sprawie kolejnej bójki", + subject = "Kolejne - ale miejmy jeszcze nadzieję, że ostatnie - zebranie w takiej sprawie" + ), + generateConference( + title = "Spotkanie z rodzicami w sprawie jeszcze jednej bójki", + subject = "Proszę państwa, proszę uspokoić swoje dzieci" + ), + generateConference( + title = "Spotkanie w sprawie wydalenia części uczniów", + subject = "Proszę państwa, to jest krok ostateczny, którego nikt nie chciał się podjąć, ale ktoś musi" + ), + generateConference( + title = "Spotkanie organizacyjne w drugim semestrze", + subject = "Prezentacja na temat projektu 'Spokojnej szkoły'" + ), + generateConference( + title = "Spotkanie z pierwszakami", + subject = "Mamy sobie do pogadania" + ), + generateConference( + title = "Spotkanie z rodzicami szóstoklaistów", + subject = "Musimy przygotować dzieci do ważnej uroczystości" + ), + generateConference( + title = "Spotkanie podsumowujące pracę w ciągu ostatniego roku szkolnego", + subject = "Proszę państwa, zapraszam serdecznie na spotkanie" + ), +) + +private fun generateConference(title: String, subject: String) = Conference( + title = title, + subject = subject, + studentId = 0, + diaryId = 0, + agenda = "", + conferenceId = 0, + date = LocalDateTime.now(), + presentOnConference = "", +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/exam.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/exam.kt new file mode 100644 index 000000000..45700c29a --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/exam.kt @@ -0,0 +1,30 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.Exam +import java.time.LocalDate + +val debugExamItems = listOf( + generateExam("Matematyka", "Figury na płaszczyźnie"), + generateExam("Język angielski", "czasowniki nieregularne 1 część"), + generateExam("Geografia", "Opolszczyzna - mapa"), + generateExam("Sieci komputerowe", "Zaciskanie erjotek"), + generateExam("Systemy operacyjne", "Instalacja ubuntu 16.04"), + generateExam("Język niemiecki", "oral exam"), + generateExam("Biologia", "Budowa koniczyny"), + generateExam("Chemia", "synteza płynnego zaliczenia"), + generateExam("Fizyka", "telekineza"), + generateExam("Matematyka", "Liczby zespolone i pochodne piątego rzędu"), +) + +private fun generateExam(subject: String, description: String) = Exam( + subject = subject, + description = description, + studentId = 0, + diaryId = 0, + date = LocalDate.now(), + entryDate = LocalDate.now(), + group = "", + type = "", + teacher = "", + teacherSymbol = "" +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDetails.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDetails.kt new file mode 100644 index 000000000..f9c481e39 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDetails.kt @@ -0,0 +1,35 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.Grade +import java.time.LocalDate + +val debugGradeDetailsItems = listOf( + generateGrade("Matematyka", "+"), + generateGrade("Matematyka", "2="), + generateGrade("Fizyka", "-"), + generateGrade("Geografia", "4+"), + generateGrade("Sieci komputerowe", "1"), + generateGrade("Systemy operacyjne", "3+"), + generateGrade("Język polski", "2-"), + generateGrade("Język angielski", "4+"), + generateGrade("Religia", "6"), + generateGrade("Język niemiecki", "1!"), + generateGrade("Wychowanie fizyczne", "5"), +) + +private fun generateGrade(subject: String, entry: String) = Grade( + subject = subject, + entry = entry, + semesterId = 0, + studentId = 0, + value = 0.0, + modifier = 0.0, + comment = "", + color = "", + gradeSymbol = "", + description = "", + weight = "", + weightValue = 0.0, + date = LocalDate.now(), + teacher = "" +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeSummary.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeSummary.kt new file mode 100644 index 000000000..c452204b9 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeSummary.kt @@ -0,0 +1,30 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.GradeSummary + +val debugGradeSummaryItems = listOf( + generateSummary("Matematyka", "2-", "2"), + generateSummary("Fizyka", "1", "2"), + generateSummary("Geografia", "4+", "5"), + generateSummary("Sieci komputerowe", "2", "5"), + generateSummary("Systemy operacyjne", "3", "4"), + generateSummary("Język polski", "1", "3"), + generateSummary("Język angielski", "4", "3"), + generateSummary("Religia", "5", "6"), + generateSummary("Język niemiecki", "2", "2"), + generateSummary("Wychowanie fizyczne", "5", "5"), + generateSummary("Biologia", "4", "4"), +) + +private fun generateSummary(subject: String, predicted: String, final: String) = GradeSummary( + semesterId = 0, + studentId = 0, + position = 0, + subject = subject, + predictedGrade = predicted, + finalGrade = final, + proposedPoints = "", + finalPoints = "", + pointsSum = "", + average = .0 +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/homework.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/homework.kt new file mode 100644 index 000000000..6c7d7fac6 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/homework.kt @@ -0,0 +1,30 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.Homework +import java.time.LocalDate + +val debugHomeworkItems = listOf( + generateHomework("Chemia", "Test diagnozujący i Rozdział I do 30.10"), + generateHomework("Etyka", "Notatka własna do zajęć o ks. Jerzym Popiełuszko"), + generateHomework("Język angielski", "Zadania egzaminacyjne"), + generateHomework("Metodologia programowania", "Wszystkie instrukcje"), + generateHomework("Język polski", "Notatka własna na temat Wokulskiego z lektury Lalka"), + generateHomework("Systemy operacyjne", "Sprawozdanie z wykonania ćwiczenia nr 21.137"), + generateHomework("Matematyka", "Zadania od strony 1 do 128"), + generateHomework("Język niemiecki", "Opis swoich wakacji - dialog z kolegą"), + generateHomework("Język angielski", "Opis swoich wakacji - dialog z kolegą"), + generateHomework("Wychowanie fizyczne", "Notatka na temat skoku w dald"), + generateHomework("Biologia", "Notatka na temat grzechotnika"), +) + +private fun generateHomework(subject: String, content: String) = Homework( + subject = subject, + content = content, + semesterId = 0, + studentId = 0, + date = LocalDate.now(), + entryDate = LocalDate.now(), + teacher = "", + teacherSymbol = "", + attachments = listOf(), +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/luckyNumber.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/luckyNumber.kt new file mode 100644 index 000000000..e929a0904 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/luckyNumber.kt @@ -0,0 +1,12 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.LuckyNumber +import java.time.LocalDate +import kotlin.random.Random + +val debugLuckyNumber + get() = LuckyNumber( + studentId = 0, + date = LocalDate.now(), + luckyNumber = Random.nextInt(1, 128), + ) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt new file mode 100644 index 000000000..f506d2f6e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt @@ -0,0 +1,32 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.Message +import java.time.LocalDateTime + +val debugMessageItems = listOf( + generateMessage("Kowalski Jan", "Tytuł"), + generateMessage("Nazwisko Imię", "Tytuł wiadomości"), + generateMessage("Malinowski Kazimierz", "Nakrętki"), + generateMessage("Jastębowszki Orest", "Prośba do uczniów o pomoc przy projekcie"), + generateMessage("Metylowy Oranż", "Pozew o plagiat"), + generateMessage("VULCAN", "Uwaga na nieautoryzowane aplikacje"), + generateMessage("Mama", "Zacznij się w końcu uczyć do matury!!!11"), + generateMessage("Tata", "Kupisz mi coś w sklepie?"), + generateMessage("Wychowawca", "Upomnienie od wychowawcy za nieobecności"), + generateMessage("Kochanowska Joanna", "Poprawa rozprawki - termin"), +) + +private fun generateMessage(sender: String, subject: String) = Message( + sender = sender, + subject = subject, + studentId = 0, + realId = 0, + messageId = 0, + senderId = 0, + recipient = "", + date = LocalDateTime.now(), + folderId = 0, + unread = true, + removed = false, + hasAttachments = false +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/note.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/note.kt new file mode 100644 index 000000000..b287a508b --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/note.kt @@ -0,0 +1,29 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.Note +import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory +import java.time.LocalDate + +val debugNoteItems = listOf( + generateNote("Aleksadra Krajewska", "Przeszkadzanie na lekcjach", NoteCategory.NEGATIVE), + generateNote("Zofia Czerwińska", "Udział w konkursie szkolnym", NoteCategory.POSITIVE), + generateNote("Stanisław Krupa", "Kultura języka", NoteCategory.NEUTRAL), + generateNote("Karolina Kowalska", "Wypełnianie obowiązków ucznia", NoteCategory.NEUTRAL), + generateNote("Joanna Krupa", "Umycie tablicy cifem", NoteCategory.POSITIVE), + generateNote("Duchowicz Maksymilian", "Reprezentowanie szkoły", NoteCategory.POSITIVE), + generateNote("Michał Mazur", "Przeszkadzanie na lekcji", NoteCategory.NEGATIVE), + generateNote("Karolina Kowalska", "Wypełnianie obowiązków ucznia", NoteCategory.NEGATIVE), + generateNote("Aleksandra Krajewska", "Wysadzenie klasy w powietrze", NoteCategory.NEGATIVE), +) + +private fun generateNote(teacher: String, category: String, type: NoteCategory) = Note( + teacher = teacher, + category = category, + categoryType = type.id, + studentId = 0, + date = LocalDate.now(), + teacherSymbol = "", + isPointsShow = false, + points = 0, + content = "" +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/schoolAnnouncement.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/schoolAnnouncement.kt new file mode 100644 index 000000000..42524e6e0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/schoolAnnouncement.kt @@ -0,0 +1,24 @@ +package io.github.wulkanowy.ui.modules.debug.notification.mock + +import io.github.wulkanowy.data.db.entities.SchoolAnnouncement +import java.time.LocalDate + +val debugSchoolAnnouncementItems = listOf( + generateAnnouncement("Dzień wolny od zajęć dydaktycznych", "Dzień wolny od zajęć dydaktycznych\n03.05.2021 - poniedziałek"), + generateAnnouncement("Zasady bezpieczeństwa", "Wszyscy uczniowie są zobowiązani do noszenia maseczek"), + generateAnnouncement("Święto szkoły", "W najbliższych dniach obchodzimy święto szkoły, podczas którego..."), + generateAnnouncement("Rocznica odzyskania przez szkołę sztandaru", "Juz niedługo, bo za tydzień, a dokładnie za 8 dni..."), + generateAnnouncement("Ogłoszenie w sprawie otwarcia stołówki", "Wszyscy uczniowie zainteresowani obiadami w szkole..."), + generateAnnouncement("Uczniowie proszeni do sekretariatu", "Kuba i Jacek z klasy czwartej proszeni do dyrektora w trybie pilnym"), + generateAnnouncement("Dzień wolny od zajęć dydaktycznych", "Dzień wolny od zajęć dydaktycznych\n21.06.2021 - poniedziałek"), + generateAnnouncement("Zasady bezpieczeństwa", "Wszyscy uczniowie są zobowiązani do zdjęcia maseczek"), + generateAnnouncement("Święto państwowe", "W najbliższych dniach obchodzimy święto państwowe, podczas którego..."), + generateAnnouncement("Uczniowie proszeni do sekretariatu", "Kuba i Jacek z klasy czwartej proszeni do dyrektora w trybie wolnym"), +) + +private fun generateAnnouncement(subject: String, content: String) = SchoolAnnouncement( + subject = subject, + content = content, + studentId = 0, + date = LocalDate.now() +) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt index bea9847f7..65b6ba542 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt @@ -32,6 +32,7 @@ import io.github.wulkanowy.databinding.ActivityMainBinding import io.github.wulkanowy.ui.base.BaseActivity import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment +import io.github.wulkanowy.ui.modules.conference.ConferenceFragment import io.github.wulkanowy.ui.modules.exam.ExamFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment import io.github.wulkanowy.ui.modules.homework.HomeworkFragment @@ -39,6 +40,7 @@ import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment import io.github.wulkanowy.ui.modules.message.MessageFragment import io.github.wulkanowy.ui.modules.more.MoreFragment import io.github.wulkanowy.ui.modules.note.NoteFragment +import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment import io.github.wulkanowy.ui.modules.timetable.TimetableFragment import io.github.wulkanowy.utils.AnalyticsHelper import io.github.wulkanowy.utils.AppInfo @@ -107,7 +109,9 @@ class MainActivity : BaseActivity(), MainVie MainView.Section.MESSAGE.id to MessageFragment.newInstance(), MainView.Section.HOMEWORK.id to HomeworkFragment.newInstance(), MainView.Section.NOTE.id to NoteFragment.newInstance(), - MainView.Section.LUCKY_NUMBER.id to LuckyNumberFragment.newInstance() + MainView.Section.LUCKY_NUMBER.id to LuckyNumberFragment.newInstance(), + MainView.Section.SCHOOL_ANNOUNCEMENT.id to SchoolAnnouncementFragment.newInstance(), + MainView.Section.CONFERENCE.id to ConferenceFragment.newInstance(), ) @SuppressLint("NewApi") diff --git a/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt index a49360d7a..4651dffd2 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt @@ -5,6 +5,7 @@ import io.github.wulkanowy.ui.modules.about.AboutFragment import io.github.wulkanowy.ui.modules.account.AccountFragment import io.github.wulkanowy.ui.modules.account.accountdetails.AccountDetailsFragment import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment +import io.github.wulkanowy.ui.modules.conference.ConferenceFragment import io.github.wulkanowy.ui.modules.exam.ExamFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment import io.github.wulkanowy.ui.modules.homework.HomeworkFragment @@ -14,6 +15,7 @@ import io.github.wulkanowy.ui.modules.message.MessageFragment import io.github.wulkanowy.ui.modules.more.MoreFragment import io.github.wulkanowy.ui.modules.note.NoteFragment import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment +import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment import io.github.wulkanowy.ui.modules.settings.SettingsFragment import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoFragment import io.github.wulkanowy.ui.modules.timetable.TimetableFragment @@ -35,6 +37,8 @@ fun Fragment.toSection(): MainView.Section? { is AccountFragment -> MainView.Section.ACCOUNT is AccountDetailsFragment -> MainView.Section.ACCOUNT is StudentInfoFragment -> MainView.Section.STUDENT_INFO + is ConferenceFragment -> MainView.Section.CONFERENCE + is SchoolAnnouncementFragment -> MainView.Section.SCHOOL_ANNOUNCEMENT else -> null } } diff --git a/app/src/main/res/layout/fragment_debug.xml b/app/src/main/res/layout/fragment_debug.xml new file mode 100644 index 000000000..2d71d89ca --- /dev/null +++ b/app/src/main/res/layout/fragment_debug.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_debug_notifications.xml b/app/src/main/res/layout/fragment_debug_notifications.xml new file mode 100644 index 000000000..372e10552 --- /dev/null +++ b/app/src/main/res/layout/fragment_debug_notifications.xml @@ -0,0 +1,6 @@ + diff --git a/app/src/main/res/layout/fragment_logviewer.xml b/app/src/main/res/layout/fragment_logviewer.xml index f8ec37d2f..e03124a43 100644 --- a/app/src/main/res/layout/fragment_logviewer.xml +++ b/app/src/main/res/layout/fragment_logviewer.xml @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context=".ui.modules.about.logviewer.LogViewerFragment"> + tools:context=".ui.modules.debug.logviewer.LogViewerFragment"> + android:layout_height="match_parent" + tools:listitem="@layout/item_more" /> diff --git a/app/src/main/res/layout/item_debug.xml b/app/src/main/res/layout/item_debug.xml new file mode 100644 index 000000000..f0f9f09fc --- /dev/null +++ b/app/src/main/res/layout/item_debug.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/app/src/main/res/layout/item_debug_notifications.xml b/app/src/main/res/layout/item_debug_notifications.xml new file mode 100644 index 000000000..204f70005 --- /dev/null +++ b/app/src/main/res/layout/item_debug_notifications.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 349e2fa31..8929f6c20 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -324,7 +324,7 @@ Dnešní šťastné číslo je Žádné informace o šťastném čísle Šťastné číslo pro dnešek - Dnes je šťastným číslem: %d + Dnes je šťastným číslem: %s Zobrazit historii Historie šťastných čísel diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 318510235..7399e1dea 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -278,7 +278,7 @@ Die heutige Glücksnummer ist Keine Information über die Glücksnummer. Glücksnummer für heute - Die heutige Glücksnummer ist: %d + Die heutige Glücksnummer ist: %s Verlauf anzeigen Glücksnummerverlauf diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index ec51f3c98..cf9d44d11 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -324,7 +324,7 @@ Today\'s lucky number is No info about the lucky number Lucky number for today - Today\'s lucky number is: %d + Today\'s lucky number is: %s Show history Lucky number history diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 106badc7d..a855ebd1c 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -324,7 +324,7 @@ Dzisiejszym szczęśliwym numerkiem jest Brak informacji o szczęśliwym numerku Szczęśliwy numerek na dzisiaj - Dziś szczęśliwym numerkiem jest: %d + Dziś szczęśliwym numerkiem jest: %s Pokaż historię Historia numerków diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9c5afb1b6..1c67d2841 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -324,7 +324,7 @@ Сегодняшний счастливый номер это Нет данных о счастливом номере Сегодняшний счастливый номер - Сегодняшний счастливый номер это: %d + Сегодняшний счастливый номер это: %s Показать историю История удачных чисел diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 262073d53..a9656eab7 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -324,7 +324,7 @@ Dnešné šťastné číslo je Žiadne informácie o šťastnom čísle Šťastné číslo pre dnešok - Dnes je šťastným číslom: %d + Dnes je šťastným číslom: %s Zobraziť históriu História šťastných čísel diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 8c3a4c501..8bc1b8e31 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -324,7 +324,7 @@ Сьогоднішній щасливий номер Брак інформації о щасливому номері Сьогоднішній щасливий номер - Сьогоднішнім щасливим номером є %d + Сьогоднішнім щасливим номером є %s Показати історію Історія щасливих чисел diff --git a/app/src/main/res/values/api_hosts.xml b/app/src/main/res/values/api_hosts.xml index 158490471..dac94c3ff 100644 --- a/app/src/main/res/values/api_hosts.xml +++ b/app/src/main/res/values/api_hosts.xml @@ -40,7 +40,7 @@ https://vulcan.net.pl/?login https://vulcan.net.pl/?login https://vulcan.net.pl/?login - http://fakelog.cf/?email + http://fakelog.tk/?email Default diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 86a86663b..248de3f4d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -11,6 +11,8 @@ More About Log viewer + Debug + Notification debug Contributors Licenses Messages @@ -310,7 +312,7 @@ Today\'s lucky number is No info about the lucky number Lucky number for today - Today\'s lucky number is: %d + Today\'s lucky number is: %s Show history