diff --git a/app/build.gradle b/app/build.gradle index 955781d4..57e88e96 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,7 +77,7 @@ play { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation('com.github.wulkanowy:api:a875c1de3b') { exclude module: "threetenbp" } + implementation('com.github.wulkanowy:api:29d24ca1ff') { exclude module: "threetenbp" } implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.appcompat:appcompat:1.0.2" diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt index 8c8bb4c1..438e95f4 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt @@ -16,9 +16,12 @@ fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", s end = now(), date = start.toLocalDate(), subject = subject, + subjectOld = "", group = "", room = room, + roomOld = "", teacher = "", + teacherOld = "", info = "", changes = false, canceled = false diff --git a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt index d075b3f3..8e4bafb5 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt @@ -46,6 +46,7 @@ import io.github.wulkanowy.data.db.migrations.Migration4 import io.github.wulkanowy.data.db.migrations.Migration5 import io.github.wulkanowy.data.db.migrations.Migration6 import io.github.wulkanowy.data.db.migrations.Migration7 +import io.github.wulkanowy.data.db.migrations.Migration8 import javax.inject.Singleton @Singleton @@ -76,7 +77,7 @@ import javax.inject.Singleton abstract class AppDatabase : RoomDatabase() { companion object { - const val VERSION_SCHEMA = 7 + const val VERSION_SCHEMA = 8 fun newInstance(context: Context): AppDatabase { return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database") @@ -89,7 +90,8 @@ abstract class AppDatabase : RoomDatabase() { Migration4(), Migration5(), Migration6(), - Migration7() + Migration7(), + Migration8() ) .build() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt index acccb7c3..9bc3d214 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt @@ -26,12 +26,18 @@ data class Timetable( val subject: String, + val subjectOld: String, + val group: String, val room: String, + val roomOld: String, + val teacher: String, + val teacherOld: String, + val info: String, val changes: Boolean, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration8.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration8.kt new file mode 100644 index 00000000..024a0c9f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration8.kt @@ -0,0 +1,13 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration8 : Migration(7, 8) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE `Timetable` ADD COLUMN subjectOld TEXT DEFAULT \"\" NOT NULL") + database.execSQL("ALTER TABLE `Timetable` ADD COLUMN roomOld TEXT DEFAULT \"\" NOT NULL") + database.execSQL("ALTER TABLE `Timetable` ADD COLUMN teacherOld TEXT DEFAULT \"\" NOT NULL") + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt index 5e048103..77742e7b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt @@ -26,9 +26,12 @@ class TimetableRemote @Inject constructor(private val api: Api) { end = it.end.toLocalDateTime(), date = it.date.toLocalDate(), subject = it.subject, + subjectOld = it.subjectOld, group = it.group, room = it.room, + roomOld = it.roomOld, teacher = it.teacher, + teacherOld = it.teacherOld, info = it.info, changes = it.changes, canceled = it.canceled diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt index 722fc322..460d55fd 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt @@ -19,33 +19,31 @@ class TimetableRepository @Inject constructor( private val remote: TimetableRemote ) { - fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean = false) - : Single> { - return Single.fromCallable { startDate.monday to endDate.friday } - .flatMap { dates -> - local.getTimetable(semester, dates.first, dates.second).filter { !forceRefresh } - .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) - .flatMap { - if (it) remote.getTimetable(semester, dates.first, dates.second) - else Single.error(UnknownHostException()) - }.flatMap { newTimetable -> - local.getTimetable(semester, dates.first, dates.second) - .toSingle(emptyList()) - .doOnSuccess { oldTimetable -> - local.deleteTimetable(oldTimetable - newTimetable) - local.saveTimetable((newTimetable - oldTimetable).map { item -> - item.apply { - if (room.isEmpty()) { - oldTimetable.singleOrNull { it.start == this.start && it.room.isNotEmpty() } - ?.let { return@map copy(room = it.room) } - } - } - }) + fun getTimetable(semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single> { + return Single.fromCallable { start.monday to end.friday }.flatMap { (monday, friday) -> + local.getTimetable(semester, monday, friday).filter { !forceRefresh } + .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap { + if (it) remote.getTimetable(semester, monday, friday) + else Single.error(UnknownHostException()) + }.flatMap { newTimetable -> + local.getTimetable(semester, monday, friday) + .toSingle(emptyList()) + .doOnSuccess { oldTimetable -> + local.deleteTimetable(oldTimetable - newTimetable) + local.saveTimetable((newTimetable - oldTimetable).map { item -> + item.apply { + oldTimetable.singleOrNull { this.start == it.start }?.let { + return@map copy( + room = if (room.isEmpty()) it.room else room, + teacher = if (teacher.isEmpty()) it.teacher else teacher + ) + } } - }.flatMap { - local.getTimetable(semester, dates.first, dates.second) - .toSingle(emptyList()) - }).map { list -> list.filter { it.date in startDate..endDate } } - } + }) + } + }.flatMap { + local.getTimetable(semester, monday, friday).toSingle(emptyList()) + }).map { list -> list.filter { it.date in start..end } } + } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt index 743f37e5..7e286c92 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt @@ -1,16 +1,19 @@ package io.github.wulkanowy.ui.modules.timetable import android.annotation.SuppressLint +import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.View.GONE +import android.view.View.VISIBLE import android.view.ViewGroup import androidx.fragment.app.DialogFragment import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.utils.toFormattedString import kotlinx.android.synthetic.main.dialog_timetable.* +import org.threeten.bp.LocalDateTime class TimetableDialog : DialogFragment() { @@ -38,41 +41,110 @@ class TimetableDialog : DialogFragment() { return inflater.inflate(R.layout.dialog_timetable, container, false) } - @SuppressLint("SetTextI18n") override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - timetableDialogSubject.text = lesson.subject - timetableDialogTime.text = "${lesson.start.toFormattedString("HH:mm")} - ${lesson.end.toFormattedString("HH:mm")}" - - lesson.group.let { - if (it.isBlank()) { - timetableDialogGroupTitle.visibility = GONE - timetableDialogGroup.visibility = GONE - } else timetableDialogGroup.text = it - } - - lesson.room.let { - if (it.isBlank()) { - timetableDialogRoomTitle.visibility = GONE - timetableDialogRoom.visibility = GONE - } else timetableDialogRoom.text = it - } - - lesson.teacher.let { - if (it.isBlank()) { - timetableDialogTeacherTitle.visibility = GONE - timetableDialogTeacher.visibility = GONE - } else timetableDialogTeacher.text = it - } - - lesson.info.let { - if (it.isBlank()) { - timetableDialogChangesTitle.visibility = GONE - timetableDialogChanges.visibility = GONE - } else timetableDialogChanges.text = it + lesson.run { + setInfo(info, teacher, canceled, changes) + setSubject(subject, subjectOld) + setTeacher(teacher, teacherOld) + setGroup(group) + setRoom(room, roomOld) + setTime(start, end) } timetableDialogClose.setOnClickListener { dismiss() } } + + private fun setSubject(subject: String, subjectOld: String) { + timetableDialogSubject.text = subject + if (subjectOld.isNotBlank() && subjectOld != subject) { + timetableDialogSubject.run { + paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG + text = subjectOld + } + timetableDialogSubjectNew.run { + visibility = VISIBLE + text = subject + } + } + } + + private fun setInfo(info: String, teacher: String, canceled: Boolean, changes: Boolean) { + when { + info.isNotBlank() -> timetableDialogChanges.text = when { + canceled && !changes -> "Lekcja odwołana: $info" + changes && teacher.isNotBlank() -> "Zastępstwo: $teacher" + changes && teacher.isBlank() -> "Zastępstwo, ${info.decapitalize()}" + else -> info.capitalize() + } + else -> { + timetableDialogChangesTitle.visibility = GONE + timetableDialogChanges.visibility = GONE + } + } + } + + private fun setTeacher(teacher: String, teacherOld: String) { + when { + teacherOld.isNotBlank() && teacherOld != teacher -> { + timetableDialogTeacher.run { + visibility = VISIBLE + paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG + text = teacherOld + } + if (teacher.isNotBlank()) { + timetableDialogTeacherNew.run { + visibility = VISIBLE + text = teacher + } + } + } + teacher.isNotBlank() -> timetableDialogTeacher.text = teacher + else -> { + timetableDialogTeacherTitle.visibility = GONE + timetableDialogTeacher.visibility = GONE + } + } + } + + private fun setGroup(group: String) { + group.let { + when { + it.isNotBlank() -> timetableDialogGroup.text = it + else -> { + timetableDialogGroupTitle.visibility = GONE + timetableDialogGroup.visibility = GONE + } + } + } + } + + private fun setRoom(room: String, roomOld: String) { + when { + roomOld.isNotBlank() && roomOld != room -> { + timetableDialogRoom.run { + visibility = VISIBLE + paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG + text = roomOld + } + if (room.isNotBlank()) { + timetableDialogRoomNew.run { + visibility = VISIBLE + text = room + } + } + } + room.isNotBlank() -> timetableDialogRoom.text = room + else -> { + timetableDialogRoomTitle.visibility = GONE + timetableDialogRoom.visibility = GONE + } + } + } + + @SuppressLint("SetTextI18n") + private fun setTime(start: LocalDateTime, end: LocalDateTime) { + timetableDialogTime.text = "${start.toFormattedString("HH:mm")} - ${end.toFormattedString("HH:mm")}" + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt index ce23a11f..63560807 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt @@ -79,7 +79,14 @@ class TimetableWidgetFactory( if (it.info.isNotBlank()) { setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE) - setTextViewText(R.id.timetableWidgetItemDescription, it.info.capitalize()) + setTextViewText(R.id.timetableWidgetItemDescription, it.run { + when (true) { + canceled && !changes -> "Lekcja odwołana: $info" + changes && teacher.isNotBlank() -> "Zastępstwo: $teacher" + changes && teacher.isBlank() -> "Zastępstwo, ${info.decapitalize()}" + else -> it.info.capitalize() + } + }) } else setViewVisibility(R.id.timetableWidgetItemDescription, GONE) if (it.canceled) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt index 79d34c70..290007e4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt @@ -121,6 +121,3 @@ class TimetableWidgetProvider : BroadcastReceiver() { }, FLAG_UPDATE_CURRENT) } } - - - diff --git a/app/src/main/res/layout/dialog_timetable.xml b/app/src/main/res/layout/dialog_timetable.xml index c9c8ec06..1cb65026 100644 --- a/app/src/main/res/layout/dialog_timetable.xml +++ b/app/src/main/res/layout/dialog_timetable.xml @@ -51,6 +51,17 @@ android:textIsSelectable="true" android:textSize="12sp" /> + + + + + + + android:orientation="horizontal" + tools:context=".ui.widgets.timetable.TimetableWidgetFactory"> + tools:text="1" /> + android:textSize="13sp" + tools:text="08:00 - 08:45" /> + android:textSize="13sp" + tools:text="Język polski" /> + android:textSize="12sp" + tools:text="Lekcja odwołana: uczniowie zwolnieni do domu" /> + android:textSize="12sp" + tools:text="Sala 25" /> diff --git a/app/src/main/res/layout/widget_timetable.xml b/app/src/main/res/layout/widget_timetable.xml index 8d415f66..3edcc276 100644 --- a/app/src/main/res/layout/widget_timetable.xml +++ b/app/src/main/res/layout/widget_timetable.xml @@ -1,8 +1,10 @@ + android:background="@android:color/white" + tools:context=".ui.widgets.timetable.TimetableWidgetProvider"> + android:src="@drawable/ic_widget_chevron_24dp" + tools:targetApi="lollipop" /> + android:textSize="15sp" + tools:text="Poniedziałek" /> + android:textSize="14sp" + tools:text="12.03.2019" /> + android:src="@drawable/ic_widget_chevron_24dp" + tools:targetApi="lollipop" /> @@ -73,7 +77,8 @@ android:id="@+id/timetableWidgetList" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="@dimen/timetable_widget_bar_height" /> + android:layout_marginTop="@dimen/timetable_widget_bar_height" + tools:listitem="@layout/item_widget_timetable" /> + android:textSize="20sp" + tools:visibility="invisible" />