From ba76453e45cd452677014dcb943f2088b2281bf7 Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Sun, 17 Mar 2019 21:02:41 +0100 Subject: [PATCH] Add replying to messages (#263) --- app/build.gradle | 4 +- .../data/repositories/grade/GradeLocalTest.kt | 3 +- .../repositories/grade/GradeRepositoryTest.kt | 3 - .../GradeStatisticsLocalTest.kt | 2 +- app/src/main/AndroidManifest.xml | 11 ++ .../github/wulkanowy/data/db/AppDatabase.kt | 8 +- .../wulkanowy/data/db/dao/GradeSummaryDao.kt | 2 +- .../wulkanowy/data/db/dao/MessagesDao.kt | 2 +- .../data/db/entities/GradeSummary.kt | 2 +- .../wulkanowy/data/db/entities/Message.kt | 5 +- .../data/db/migrations/Migration10.kt | 11 ++ .../data/db/migrations/Migration2.kt | 14 +- .../data/db/migrations/Migration3.kt | 28 ++-- .../data/db/migrations/Migration4.kt | 40 ++--- .../data/db/migrations/Migration5.kt | 26 +-- .../data/db/migrations/Migration6.kt | 40 +++-- .../data/db/migrations/Migration7.kt | 18 +- .../data/db/migrations/Migration8.kt | 6 +- .../data/db/migrations/Migration9.kt | 30 ++++ .../repositories/grade/GradeRepository.kt | 3 +- .../repositories/homework/HomeworkLocal.kt | 3 +- .../repositories/message/MessageRemote.kt | 1 - .../repositories/message/MessageRepository.kt | 6 +- .../preferences/PreferencesRepository.kt | 16 +- .../repositories/recipient/RecipientRemote.kt | 37 +++-- .../recipient/RecipientRepository.kt | 10 ++ .../io/github/wulkanowy/di/BuilderModule.kt | 6 +- .../wulkanowy/ui/modules/main/MainModule.kt | 5 - .../ui/modules/message/MessageFragment.kt | 5 +- .../message/preview/MessagePreviewFragment.kt | 59 +++++-- .../preview/MessagePreviewPresenter.kt | 18 +- .../message/preview/MessagePreviewView.kt | 13 +- .../ui/modules/message/send/RecipientChip.kt | 30 ++++ .../message/send/SendMessageActivity.kt | 127 +++++++++++++++ .../message/send/SendMessageFragment.kt | 154 ------------------ .../message/send/SendMessagePresenter.kt | 106 +++++++----- .../modules/message/send/SendMessageView.kt | 20 ++- .../modules/message/tab/MessageTabFragment.kt | 2 +- .../res/drawable/ic_message_reply_24dp.xml | 10 ++ ..._message.xml => activity_send_message.xml} | 56 ++++--- .../res/layout/fragment_message_preview.xml | 19 +-- .../res/menu/action_menu_message_preview.xml | 10 ++ app/src/main/res/values-night/styles.xml | 7 +- app/src/main/res/values-pl/strings.xml | 28 ++-- app/src/main/res/values/colors.xml | 7 +- app/src/main/res/values/preferences_keys.xml | 5 +- app/src/main/res/values/strings.xml | 28 ++-- app/src/main/res/values/styles.xml | 3 +- app/src/main/res/xml/scheme_preferences.xml | 41 +++-- .../modules/message/send/TestRecipientChip.kt | 20 +++ 50 files changed, 676 insertions(+), 434 deletions(-) create mode 100644 app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration9.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChip.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt delete mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageFragment.kt create mode 100644 app/src/main/res/drawable/ic_message_reply_24dp.xml rename app/src/main/res/layout/{fragment_send_message.xml => activity_send_message.xml} (75%) create mode 100644 app/src/main/res/menu/action_menu_message_preview.xml create mode 100644 app/src/test/java/io/github/wulkanowy/ui/modules/message/send/TestRecipientChip.kt diff --git a/app/build.gradle b/app/build.gradle index 57e88e96..1e342caf 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:29d24ca1ff') { exclude module: "threetenbp" } + implementation('com.github.wulkanowy:api:a8d05df1ab') { exclude module: "threetenbp" } implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.appcompat:appcompat:1.0.2" @@ -107,7 +107,7 @@ dependencies { implementation "com.aurelhubert:ahbottomnavigation:2.3.4" implementation 'com.ncapdevi:frag-nav:3.1.0' - implementation "com.hootsuite.android:nachos:1.1.1" + implementation 'com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f' implementation 'com.github.PhilJay:MPAndroidChart:971640b29d' implementation 'com.github.pwittchen:reactivenetwork-rx2:3.0.2' diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt index 2756723f..e50a52ff 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt @@ -21,7 +21,8 @@ class GradeLocalTest { @Before fun createDb() { - testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() + testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() gradeLocal = GradeLocal(testDb.gradeDao) } diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt index 6b419178..7da2d455 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt @@ -7,9 +7,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SdkSuppress import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import io.github.wulkanowy.api.Api -import io.github.wulkanowy.api.toDate import io.github.wulkanowy.data.db.AppDatabase -import io.github.wulkanowy.data.db.entities.Grade import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy @@ -22,7 +20,6 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate.of import org.threeten.bp.LocalDateTime import kotlin.test.assertFalse diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt index 6c0bd417..5c0590e7 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt @@ -39,7 +39,7 @@ class GradeStatisticsLocalTest { )) val stats = gradeStatisticsLocal.getGradesStatistics( - Semester(2, 2, "", 1, 2, true, 1 ,1), false, + Semester(2, 2, "", 1, 2, true, 1, 1), false, "Matematyka" ).blockingGet() assertEquals(1, stats.size) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bb206699..43b94805 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,7 +39,18 @@ android:name=".ui.modules.main.MainActivity" android:configChanges="orientation|screenSize" android:label="@string/main_title" + android:launchMode="singleTop" android:theme="@style/WulkanowyTheme.NoActionBar" /> + + + ) - @Query("SELECT * FROM grades_summary WHERE student_id = :studentId AND semester_id = :semesterId") + @Query("SELECT * FROM GradesSummary WHERE student_id = :studentId AND semester_id = :semesterId") fun loadAll(semesterId: Int, studentId: Int): Maybe> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt index 11d456b9..3ef5d690 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt @@ -20,7 +20,7 @@ interface MessagesDao { @Update fun updateAll(messages: List) - @Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder ORDER BY date DESC") + @Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC") fun loadAll(studentId: Int, folder: Int): Maybe> @Query("SELECT * FROM Messages WHERE student_id = :studentId AND real_id = :id") diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt index 7221785c..e6ac4926 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey -@Entity(tableName = "Grades_Summary") +@Entity(tableName = "GradesSummary") data class GradeSummary( @ColumnInfo(name = "semester_id") diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt index 11804394..48b4fd02 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt @@ -24,9 +24,6 @@ data class Message( @ColumnInfo(name = "sender_id") val senderId: Int, - @ColumnInfo(name = "recipient_id") - val recipientId: Int, - @ColumnInfo(name = "recipient_name") val recipient: String, @@ -39,8 +36,10 @@ data class Message( var unread: Boolean, + @ColumnInfo(name = "unread_by") val unreadBy: Int, + @ColumnInfo(name = "read_by") val readBy: Int, val removed: Boolean diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt new file mode 100644 index 00000000..c26a02d1 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt @@ -0,0 +1,11 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration10 : Migration(9, 10) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Grades_Summary RENAME TO GradesSummary") + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt index 30ddc3bb..c5a30991 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt @@ -6,11 +6,13 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration2 : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE LuckyNumbers (" + - "id INTEGER NOT NULL PRIMARY KEY, " + - "is_notified INTEGER NOT NULL, " + - "student_id INTEGER NOT NULL, " + - "date INTEGER NOT NULL, " + - "lucky_number INTEGER NOT NULL)") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS LuckyNumbers ( + id INTEGER PRIMARY KEY NOT NULL, + is_notified INTEGER NOT NULL, + student_id INTEGER NOT NULL, + date INTEGER NOT NULL, + lucky_number INTEGER NOT NULL) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt index 974c33e9..d9699c0f 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt @@ -6,18 +6,20 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration3 : Migration(2, 3) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE CompletedLesson (" + - "id INTEGER NOT NULL PRIMARY KEY, " + - "student_id INTEGER NOT NULL, " + - "diary_id INTEGER NOT NULL, " + - "date INTEGER NOT NULL, " + - "number INTEGER NOT NULL, " + - "subject TEXT NOT NULL, " + - "topic TEXT NOT NULL, " + - "teacher TEXT NOT NULL, " + - "teacher_symbol TEXT NOT NULL, " + - "substitution TEXT NOT NULL, " + - "absence TEXT NOT NULL, " + - "resources TEXT NOT NULL)") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS CompletedLesson ( + id INTEGER PRIMARY KEY NOT NULL, + student_id INTEGER NOT NULL, + diary_id INTEGER NOT NULL, + date INTEGER NOT NULL, + number INTEGER NOT NULL, + subject TEXT NOT NULL, + topic TEXT NOT NULL, + teacher TEXT NOT NULL, + teacher_symbol TEXT NOT NULL, + substitution TEXT NOT NULL, + absence TEXT NOT NULL, + resources TEXT NOT NULL) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt index f21c212d..0ae89bdd 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt @@ -6,24 +6,26 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration4 : Migration(3, 4) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("DROP TABLE IF EXISTS `Messages`") - database.execSQL("CREATE TABLE IF NOT EXISTS `Messages` (" + - "`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + - "`is_notified` INTEGER NOT NULL," + - "`content` TEXT," + - "`student_id` INTEGER NOT NULL," + - "`real_id` INTEGER NOT NULL," + - "`message_id` INTEGER NOT NULL," + - "`sender_name` TEXT NOT NULL," + - "`sender_id` INTEGER NOT NULL," + - "`recipient_id` INTEGER NOT NULL," + - "`recipient_name` TEXT NOT NULL," + - "`subject` TEXT NOT NULL," + - "`date` INTEGER NOT NULL," + - "`folder_id` INTEGER NOT NULL," + - "`unread` INTEGER NOT NULL," + - "`unreadBy` INTEGER NOT NULL," + - "`readBy` INTEGER NOT NULL," + - "`removed` INTEGER NOT NULL)") + database.execSQL("DROP TABLE IF EXISTS Messages") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS Messages ( + id INTEGER PRIMARY KEY NOT NULL, + is_notified INTEGER NOT NULL, + content TEXT, + student_id INTEGER NOT NULL, + real_id INTEGER NOT NULL, + message_id INTEGER NOT NULL, + sender_name TEXT NOT NULL, + sender_id INTEGER NOT NULL, + recipient_id INTEGER NOT NULL, + recipient_name TEXT NOT NULL, + subject TEXT NOT NULL, + date INTEGER NOT NULL, + folder_id INTEGER NOT NULL, + unread INTEGER NOT NULL, + unreadBy INTEGER NOT NULL, + readBy INTEGER NOT NULL, + removed INTEGER NOT NULL) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt index ff215fc3..fe0dec48 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt @@ -8,17 +8,19 @@ import org.threeten.bp.ZoneOffset class Migration5 : Migration(4, 5) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("ALTER TABLE Students ADD COLUMN `registration_date` INTEGER NOT NULL DEFAULT 0") - database.execSQL("UPDATE Students SET `registration_date` = '${now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli()}'") - database.execSQL("DROP TABLE IF EXISTS `Notes`") - database.execSQL("CREATE TABLE IF NOT EXISTS `Notes` (" + - "`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + - "`is_read` INTEGER NOT NULL," + - "`is_notified` INTEGER NOT NULL," + - "`student_id` INTEGER NOT NULL," + - "`date` INTEGER NOT NULL," + - "`teacher` TEXT NOT NULL," + - "`category` TEXT NOT NULL," + - "`content` TEXT NOT NULL)") + database.execSQL("ALTER TABLE Students ADD COLUMN registration_date INTEGER DEFAULT 0 NOT NULL") + database.execSQL("UPDATE Students SET registration_date = '${now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli()}'") + database.execSQL("DROP TABLE IF EXISTS Notes") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS Notes ( + id INTEGER PRIMARY KEY NOT NULL, + is_read INTEGER NOT NULL, + is_notified INTEGER NOT NULL, + student_id INTEGER NOT NULL, + date INTEGER NOT NULL, + teacher TEXT NOT NULL, + category TEXT NOT NULL, + content TEXT NOT NULL) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt index fec1eada..fa943618 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt @@ -6,25 +6,29 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration6 : Migration(5, 6) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE ReportingUnits (" + - "id INTEGER NOT NULL PRIMARY KEY," + - "student_id INTEGER NOT NULL," + - "real_id INTEGER NOT NULL," + - "short TEXT NOT NULL," + - "sender_id INTEGER NOT NULL," + - "sender_name TEXT NOT NULL," + - "roles TEXT NOT NULL)") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS ReportingUnits ( + id INTEGER PRIMARY KEY NOT NULL, + student_id INTEGER NOT NULL, + real_id INTEGER NOT NULL, + short TEXT NOT NULL, + sender_id INTEGER NOT NULL, + sender_name TEXT NOT NULL, + roles TEXT NOT NULL) + """) - database.execSQL("CREATE TABLE Recipients (" + - "id INTEGER NOT NULL PRIMARY KEY," + - "student_id INTEGER NOT NULL," + - "real_id TEXT NOT NULL," + - "name TEXT NOT NULL," + - "real_name TEXT NOT NULL," + - "login_id INTEGER NOT NULL," + - "unit_id INTEGER NOT NULL," + - "role INTEGER NOT NULL," + - "hash TEXT NOT NULL)") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS Recipients ( + id INTEGER PRIMARY KEY NOT NULL, + student_id INTEGER NOT NULL, + real_id TEXT NOT NULL, + name TEXT NOT NULL, + real_name TEXT NOT NULL, + login_id INTEGER NOT NULL, + unit_id INTEGER NOT NULL, + role INTEGER NOT NULL, + hash TEXT NOT NULL) + """) database.execSQL("DELETE FROM Semesters WHERE 1") database.execSQL("ALTER TABLE Semesters ADD COLUMN class_id INTEGER DEFAULT 0 NOT NULL") diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt index 68305124..120716c8 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt @@ -6,13 +6,15 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration7 : Migration(6, 7) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("CREATE TABLE IF NOT EXISTS `GradesStatistics` (" + - "`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + - "`student_id` INTEGER NOT NULL," + - "`semester_id` INTEGER NOT NULL," + - "`subject` TEXT NOT NULL," + - "`grade` INTEGER NOT NULL," + - "`amount` INTEGER NOT NULL," + - "`is_semester` INTEGER NOT NULL)") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS GradesStatistics ( + id INTEGER PRIMARY KEY NOT NULL, + student_id INTEGER NOT NULL, + semester_id INTEGER NOT NULL, + subject TEXT NOT NULL, + grade INTEGER NOT NULL, + amount INTEGER NOT NULL, + is_semester INTEGER NOT NULL) + """) } } 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 index 024a0c9f..7009ee12 100644 --- 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 @@ -6,8 +6,8 @@ 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") + 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/db/migrations/Migration9.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration9.kt new file mode 100644 index 00000000..d79a5706 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration9.kt @@ -0,0 +1,30 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration9 : Migration(8, 9) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE IF EXISTS Messages") + database.execSQL(""" + CREATE TABLE IF NOT EXISTS Messages ( + id INTEGER PRIMARY KEY NOT NULL, + student_id INTEGER NOT NULL, + real_id INTEGER NOT NULL, + message_id INTEGER NOT NULL, + sender_name TEXT NOT NULL, + sender_id INTEGER NOT NULL, + recipient_name TEXT NOT NULL, + subject TEXT NOT NULL, + date INTEGER NOT NULL, + folder_id INTEGER NOT NULL, + unread INTEGER NOT NULL, + unread_by INTEGER NOT NULL, + read_by INTEGER NOT NULL, + removed INTEGER NOT NULL, + is_notified INTEGER NOT NULL, + content TEXT) + """) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt index d268a46c..3dd456bf 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt @@ -27,7 +27,8 @@ class GradeRepository @Inject constructor( }.flatMap { newGrades -> local.getGrades(semester).toSingle(emptyList()) .doOnSuccess { oldGrades -> - val notifyBreakDate = oldGrades.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate() + val notifyBreakDate = oldGrades.maxBy { it.date }?.date + ?: student.registrationDate.toLocalDate() local.deleteGrades(oldGrades - newGrades) local.saveGrades((newGrades - oldGrades) .onEach { diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt index 7af94842..671ecafd 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt @@ -20,6 +20,7 @@ class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) { } fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> { - return homeworkDb.loadAll(semester.semesterId, semester.studentId, startDate, endDate).filter { it.isNotEmpty() } + return homeworkDb.loadAll(semester.semesterId, semester.studentId, startDate, endDate) + .filter { it.isNotEmpty() } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt index f4ccde0d..3fb01d30 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt @@ -26,7 +26,6 @@ class MessageRemote @Inject constructor(private val api: Api) { sender = it.sender.orEmpty(), senderId = it.senderId ?: 0, recipient = it.recipient.orEmpty(), - recipientId = 0, subject = it.subject.trim(), date = it.date?.toLocalDateTime() ?: now(), folderId = it.folderId, diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt index 9f9a7bdf..d319689e 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt @@ -83,6 +83,10 @@ class MessageRepository @Inject constructor( } fun sendMessage(subject: String, content: String, recipients: List): Single { - return remote.sendMessage(subject, content, recipients) + return ReactiveNetwork.checkInternetConnectivity(settings) + .flatMap { + if (it) remote.sendMessage(subject, content, recipients) + else Single.error(UnknownHostException()) + } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt index 9dad2278..d51fc495 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt @@ -24,12 +24,6 @@ class PreferencesRepository @Inject constructor( val currentTheme: Int get() = sharedPref.getString(currentThemeKey, "1")?.toIntOrNull() ?: 1 - val gradePlusModifier: Double - get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_plus), "0.0")?.toDoubleOrNull() ?: 0.0 - - val gradeMinusModifier: Double - get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_minus), "0.0")?.toDoubleOrNull() ?: 0.0 - val gradeColorTheme: String get() = sharedPref.getString(context.getString(R.string.pref_key_grade_color_scheme), "vulcan") ?: "vulcan" @@ -51,4 +45,14 @@ class PreferencesRepository @Inject constructor( val isDebugNotificationEnableKey: String = context.getString(R.string.pref_key_notification_debug) val isDebugNotificationEnable: Boolean get() = sharedPref.getBoolean(isDebugNotificationEnableKey, false) + + val gradePlusModifier: Double + get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_plus), "0.0")?.toDouble() ?: 0.0 + + val gradeMinusModifier: Double + get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_minus), "0.0")?.toDouble() + ?: 0.0 + + val fillMessageContent: Boolean + get() = sharedPref.getBoolean(context.getString(R.string.pref_key_fill_message_content), true) } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRemote.kt index 21f49649..b726edda 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRemote.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRemote.kt @@ -1,30 +1,41 @@ package io.github.wulkanowy.data.repositories.recipient import io.github.wulkanowy.api.Api +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.ReportingUnit import io.reactivex.Single import javax.inject.Inject import javax.inject.Singleton +import io.github.wulkanowy.api.messages.Recipient as ApiRecipient @Singleton class RecipientRemote @Inject constructor(private val api: Api) { fun getRecipients(role: Int, unit: ReportingUnit): Single> { - return api.getRecipients(role, unit.realId) + return api.getRecipients(unit.realId, role) .map { recipients -> - recipients.map { - Recipient( - studentId = api.studentId, - name = it.name, - realName = it.name, - realId = it.id, - hash = it.hash, - loginId = it.loginId, - role = it.role, - unitId = it.reportingUnitId ?: 0 - ) - } + recipients.map { it.toRecipient() } } } + + fun getMessageRecipients(message: Message): Single> { + return api.getMessageRecipients(message.messageId, message.senderId) + .map { recipients -> + recipients.map { it.toRecipient() } + } + } + + private fun ApiRecipient.toRecipient(): Recipient { + return Recipient( + studentId = api.studentId, + realId = id, + realName = name, + name = shortName, + hash = hash, + loginId = loginId, + role = role, + unitId = reportingUnitId ?: 0 + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRepository.kt index 37b1631e..0b02721f 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRepository.kt @@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.recipient import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import io.github.wulkanowy.data.ApiHelper +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.Student @@ -39,4 +40,13 @@ class RecipientRepository @Inject constructor( ) } } + + fun getMessageRecipients(student: Student, message: Message): Single> { + return Single.just(apiHelper.initApi(student)) + .flatMap { ReactiveNetwork.checkInternetConnectivity(settings) } + .flatMap { + if (it) remote.getMessageRecipients(message) + else Single.error(UnknownHostException()) + } + } } diff --git a/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt b/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt index 359ac45c..2616acc3 100644 --- a/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt +++ b/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt @@ -8,6 +8,7 @@ import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.login.LoginModule import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainModule +import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import io.github.wulkanowy.ui.modules.splash.SplashActivity import io.github.wulkanowy.ui.widgets.timetable.TimetableWidgetProvider @@ -15,7 +16,7 @@ import io.github.wulkanowy.ui.widgets.timetable.TimetableWidgetProvider internal abstract class BuilderModule { @PerActivity - @ContributesAndroidInjector() + @ContributesAndroidInjector abstract fun bindSplashActivity(): SplashActivity @PerActivity @@ -26,6 +27,9 @@ internal abstract class BuilderModule { @ContributesAndroidInjector(modules = [MainModule::class]) abstract fun bindMainActivity(): MainActivity + @ContributesAndroidInjector + abstract fun bindMessageSendActivity(): SendMessageActivity + @ContributesAndroidInjector abstract fun bindTimetableWidgetService(): TimetableWidgetService diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt index 625176aa..d1afd9c0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt @@ -20,7 +20,6 @@ import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment import io.github.wulkanowy.ui.modules.message.MessageFragment import io.github.wulkanowy.ui.modules.message.MessageModule import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment -import io.github.wulkanowy.ui.modules.message.send.SendMessageFragment import io.github.wulkanowy.ui.modules.more.MoreFragment import io.github.wulkanowy.ui.modules.note.NoteFragment import io.github.wulkanowy.ui.modules.settings.SettingsFragment @@ -97,10 +96,6 @@ abstract class MainModule { @ContributesAndroidInjector abstract fun bindCompletedLessonsFragment(): CompletedLessonsFragment - @PerFragment - @ContributesAndroidInjector - abstract fun bindSendMessageFragment(): SendMessageFragment - @PerFragment @ContributesAndroidInjector abstract fun bindAccountDialog(): AccountDialog diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt index d8f4b61d..d8a6bc84 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt @@ -12,9 +12,8 @@ import io.github.wulkanowy.data.repositories.message.MessageFolder.SENT import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter -import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.modules.message.send.SendMessageFragment +import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment import io.github.wulkanowy.utils.setOnSelectPageListener import kotlinx.android.synthetic.main.fragment_message.* @@ -85,7 +84,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView { } override fun openSendMessage() { - (activity as? MainActivity)?.pushView(SendMessageFragment.newInstance()) + context?.let { it.startActivity(SendMessageActivity.getStartIntent(it)) } } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt index f104d87a..102567ed 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt @@ -1,20 +1,31 @@ package io.github.wulkanowy.ui.modules.message.preview +import android.annotation.SuppressLint import android.os.Bundle import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE import android.view.ViewGroup import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.ui.base.session.BaseSessionFragment import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import kotlinx.android.synthetic.main.fragment_message_preview.* import javax.inject.Inject +@SuppressLint("SetTextI18n") class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainView.TitledView { @Inject lateinit var presenter: MessagePreviewPresenter + private var menuReplyButton: MenuItem? = null + override val titleStringId: Int get() = R.string.message_title @@ -31,42 +42,66 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi } } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setHasOptionsMenu(true) + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_message_preview, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - messageContainer = message + messageContainer = messagePreviewContainer presenter.onAttachView(this, (savedInstanceState ?: arguments)?.getInt(MESSAGE_ID_KEY) ?: 0) } + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + inflater?.inflate(R.menu.action_menu_message_preview, menu) + menuReplyButton = menu?.findItem(R.id.messagePreviewMenuReply) + presenter.onCreateOptionsMenu() + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + return if (item?.itemId == R.id.messagePreviewMenuReply) presenter.onReply() + else false + } + override fun setSubject(subject: String) { - messageSubject.text = subject + messagePreviewSubject.text = subject } - override fun setRecipient(recipient: String?) { - messageAuthor.text = getString(R.string.message_to, recipient) + override fun setRecipient(recipient: String) { + messagePreviewAuthor.text = "${getString(R.string.message_to)} $recipient" } - override fun setSender(sender: String?) { - messageAuthor.text = getString(R.string.message_from, sender) + override fun setSender(sender: String) { + messagePreviewAuthor.text = "${getString(R.string.message_from)} $sender" } - override fun setDate(date: String?) { - messageDate.text = getString(R.string.message_date, date) + override fun setDate(date: String) { + messagePreviewDate.text = getString(R.string.message_date, date) } - override fun setContent(content: String?) { - messageContent.text = content + override fun setContent(content: String) { + messagePreviewContent.text = content } override fun showProgress(show: Boolean) { - messageProgress.visibility = if (show) View.VISIBLE else View.GONE + messagePreviewProgress.visibility = if (show) VISIBLE else GONE + } + + override fun showReplyButton(show: Boolean) { + menuReplyButton?.isVisible = show } override fun showMessageError() { - messageError.visibility = View.VISIBLE + messagePreviewError.visibility = VISIBLE + } + + override fun openMessageReply(message: Message?) { + context?.let { it.startActivity(SendMessageActivity.getStartIntent(it, message)) } } override fun onSaveInstanceState(outState: Bundle) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt index 88c9f39a..a5ed9f28 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt @@ -1,6 +1,7 @@ package io.github.wulkanowy.ui.modules.message.preview import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.repositories.message.MessageRepository import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.session.BaseSessionPresenter @@ -21,6 +22,8 @@ class MessagePreviewPresenter @Inject constructor( var messageId: Int = 0 + private var replyMessage: Message? = null + fun onAttachView(view: MessagePreviewView, id: Int) { super.onAttachView(view) loadData(id) @@ -38,11 +41,13 @@ class MessagePreviewPresenter @Inject constructor( .doFinally { view?.showProgress(false) } .subscribe({ message -> Timber.i("Loading message $id preview result: Success ") + replyMessage = message view?.run { message.let { setSubject(if (it.subject.isNotBlank()) it.subject else noSubjectString) setDate(it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")) - setContent(it.content) + setContent(it.content.orEmpty()) + showReplyButton(true) if (it.recipient.isNotBlank()) setRecipient(it.recipient) else setSender(it.sender) @@ -56,4 +61,15 @@ class MessagePreviewPresenter @Inject constructor( }) } } + + fun onReply(): Boolean { + return if (replyMessage != null) { + view?.openMessageReply(replyMessage) + true + } else false + } + + fun onCreateOptionsMenu() { + view?.showReplyButton(replyMessage != null) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt index d8dd8965..464ea168 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.message.preview +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.ui.base.session.BaseSessionView interface MessagePreviewView : BaseSessionView { @@ -8,15 +9,19 @@ interface MessagePreviewView : BaseSessionView { fun setSubject(subject: String) - fun setRecipient(recipient: String?) + fun setRecipient(recipient: String) - fun setSender(sender: String?) + fun setSender(sender: String) - fun setDate(date: String?) + fun setDate(date: String) - fun setContent(content: String?) + fun setContent(content: String) fun showProgress(show: Boolean) + fun showReplyButton(show: Boolean) + fun showMessageError() + + fun openMessageReply(message: Message?) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChip.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChip.kt new file mode 100644 index 00000000..be433b00 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChip.kt @@ -0,0 +1,30 @@ +package io.github.wulkanowy.ui.modules.message.send + +import android.graphics.drawable.Drawable +import android.net.Uri +import com.pchmn.materialchips.model.ChipInterface +import io.github.wulkanowy.data.db.entities.Recipient + +class RecipientChip(var recipient: Recipient) : ChipInterface { + + override fun getAvatarDrawable(): Drawable? = null + + override fun getAvatarUri(): Uri? = null + + override fun getId(): Any = recipient.id + + override fun getLabel(): String = recipient.name + + override fun getInfo(): String { + return recipient.realName.run { + substringBeforeLast("-").let { sub -> + when { + (sub == this) -> this + (sub.indexOf('(') != -1) -> indexOf("(").let { substring(if (it != -1) it else 0) } + (sub.indexOf('[') != -1) -> indexOf("[").let { substring(if (it != -1) it else 0) } + else -> substringAfter('-') + } + }.trim() + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt new file mode 100644 index 00000000..7cb470e1 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt @@ -0,0 +1,127 @@ +package io.github.wulkanowy.ui.modules.message.send + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.view.Menu +import android.view.MenuItem +import android.view.View.GONE +import android.view.View.VISIBLE +import android.widget.Toast +import android.widget.Toast.LENGTH_LONG +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.ui.base.BaseActivity +import io.github.wulkanowy.utils.hideSoftInput +import io.github.wulkanowy.utils.showSoftInput +import kotlinx.android.synthetic.main.activity_send_message.* +import javax.inject.Inject + +class SendMessageActivity : BaseActivity(), SendMessageView { + + @Inject + lateinit var presenter: SendMessagePresenter + + companion object { + private const val EXTRA_MESSAGE = "EXTRA_MESSAGE" + + fun getStartIntent(context: Context) = Intent(context, SendMessageActivity::class.java) + + fun getStartIntent(context: Context, message: Message?): Intent { + return getStartIntent(context).putExtra(EXTRA_MESSAGE, message) + } + } + + override val formRecipientsData: List + get() = (sendMessageRecipientsInput.selectedChipList).map { (it as RecipientChip).recipient } + + override val formSubjectValue: String + get() = sendMessageSubjectInput.text.toString() + + override val formContentValue: String + get() = sendMessageContentInput.text.toString() + + override val messageRequiredRecipients: String + get() = getString(R.string.message_required_recipients) + + override val messageContentMinLength: String + get() = getString(R.string.message_content_min_length) + + override val messageSuccess: String + get() = getString(R.string.message_send_successful) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_send_message) + setSupportActionBar(sendMessageToolbar) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + messageContainer = sendMessageContainer + + presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message) + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.action_menu_send_message, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + return if (item?.itemId == R.id.sendMessageMenuSend) presenter.onSend() + else false + } + + override fun setReportingUnit(unit: ReportingUnit) { + sendMessageFromTextView.setText(unit.senderName) + } + + override fun setRecipients(recipients: List) { + sendMessageRecipientsInput.filterableList = recipients.map { RecipientChip(it) } + } + + override fun setSelectedRecipients(recipients: List) { + recipients.map { sendMessageRecipientsInput.addChip(RecipientChip(it)) } + } + + override fun showProgress(show: Boolean) { + sendMessageProgress.visibility = if (show) VISIBLE else GONE + } + + override fun showContent(show: Boolean) { + sendMessageContent.visibility = if (show) VISIBLE else GONE + } + + override fun showEmpty(show: Boolean) { + sendMessageEmpty.visibility = if (show) VISIBLE else GONE + } + + override fun showActionBar(show: Boolean) { + supportActionBar?.apply { if (show) show() else hide() } + } + + override fun setSubject(subject: String) { + sendMessageSubjectInput.setText(subject) + } + + override fun setContent(content: String) { + sendMessageContentInput.setText(content) + } + + override fun showMessage(text: String) { + Toast.makeText(this, text, LENGTH_LONG).show() + } + + override fun showSoftInput(show: Boolean) { + if (show) showSoftInput() else hideSoftInput() + } + + override fun popView() { + onBackPressed() + } + + override fun onDestroy() { + presenter.onDetachView() + super.onDestroy() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageFragment.kt deleted file mode 100644 index c61691db..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageFragment.kt +++ /dev/null @@ -1,154 +0,0 @@ -package io.github.wulkanowy.ui.modules.message.send - -import android.content.Context -import android.os.Bundle -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup -import android.widget.ArrayAdapter -import android.widget.Toast -import androidx.core.content.ContextCompat -import com.hootsuite.nachos.ChipConfiguration -import com.hootsuite.nachos.chip.ChipSpan -import com.hootsuite.nachos.chip.ChipSpanChipCreator -import com.hootsuite.nachos.tokenizer.SpanChipTokenizer -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Recipient -import io.github.wulkanowy.data.db.entities.ReportingUnit -import io.github.wulkanowy.ui.base.session.BaseSessionFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.hideSoftInput -import io.github.wulkanowy.utils.setOnTextChangedListener -import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.android.synthetic.main.fragment_send_message.* -import javax.inject.Inject - -class SendMessageFragment : BaseSessionFragment(), SendMessageView, MainView.TitledView { - - @Inject - lateinit var presenter: SendMessagePresenter - - private var recipients: List = emptyList() - - private lateinit var recipientsAdapter: ArrayAdapter - - companion object { - fun newInstance() = SendMessageFragment() - } - - override val titleStringId: Int - get() = R.string.send_message_title - - override val formRecipientsData: List - get() = sendMessageRecipientInput.allChips.map { it.data as Recipient } - - override val formSubjectValue: String - get() = sendMessageSubjectInput.text.toString() - - override val formContentValue: String - get() = sendMessageContentInput.text.toString() - - override val messageRequiredRecipients: String - get() = getString(R.string.send_message_required_recipients) - - override val messageContentMinLength: String - get() = getString(R.string.send_message_content_min_length) - - override val messageSuccess: String - get() = getString(R.string.send_message_successful) - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_send_message, container, false) - } - - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - presenter.onAttachView(this) - } - - override fun initView() { - context?.let { - sendMessageRecipientInput.chipTokenizer = SpanChipTokenizer(it, object : ChipSpanChipCreator() { - override fun createChip(context: Context, text: CharSequence, data: Any?): ChipSpan { - return ChipSpan(context, text, ContextCompat.getDrawable(context, R.drawable.ic_all_account_24dp), data) - } - - override fun configureChip(chip: ChipSpan, chipConfiguration: ChipConfiguration) { - super.configureChip(chip, chipConfiguration) - chip.setShowIconOnLeft(true) - } - }, ChipSpan::class.java) - recipientsAdapter = ArrayAdapter(it, android.R.layout.simple_dropdown_item_1line) - } - - sendMessageRecipientInput.setAdapter(recipientsAdapter) - sendMessageRecipientInput.setOnTextChangedListener { presenter.onTypingRecipients() } - } - - override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { - inflater?.inflate(R.menu.action_menu_send_message, menu) - } - - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - return if (item?.itemId == R.id.sendMessageMenuSend) presenter.onSend() - else false - } - - override fun setReportingUnit(unit: ReportingUnit) { - sendMessageFromTextView.setText(unit.senderName) - } - - override fun setRecipients(recipients: List) { - this.recipients = recipients - } - - override fun refreshRecipientsAdapter() { - recipientsAdapter.run { - clear() - addAll(recipients - sendMessageRecipientInput.allChips.map { it.data as Recipient }) - notifyDataSetChanged() - } - } - - override fun showProgress(show: Boolean) { - sendMessageProgress.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showContent(show: Boolean) { - sendMessageContent.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showEmpty(show: Boolean) { - sendMessageEmpty.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun popView() { - (activity as? MainActivity)?.popView() - } - - override fun hideSoftInput() { - activity?.hideSoftInput() - } - - override fun showBottomNav(show: Boolean) { - (activity as? MainActivity)?.mainBottomNav?.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showMessage(text: String) { - Toast.makeText(context, text, Toast.LENGTH_LONG).show() - } - - override fun onDestroyView() { - super.onDestroyView() - presenter.onDetachView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt index 05cfc7a4..18f8d43a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt @@ -1,50 +1,77 @@ package io.github.wulkanowy.ui.modules.message.send +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.repositories.message.MessageRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.recipient.RecipientRepository import io.github.wulkanowy.data.repositories.reportingunit.ReportingUnitRepository import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.data.repositories.student.StudentRepository -import io.github.wulkanowy.ui.base.session.BaseSessionPresenter -import io.github.wulkanowy.ui.base.session.SessionErrorHandler +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider +import io.github.wulkanowy.utils.toFormattedString +import io.reactivex.Completable import timber.log.Timber import javax.inject.Inject class SendMessagePresenter @Inject constructor( - private val errorHandler: SessionErrorHandler, + private val errorHandler: ErrorHandler, private val schedulers: SchedulersProvider, private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, private val messageRepository: MessageRepository, private val reportingUnitRepository: ReportingUnitRepository, private val recipientRepository: RecipientRepository, + private val preferencesRepository: PreferencesRepository, private val analytics: FirebaseAnalyticsHelper -) : BaseSessionPresenter(errorHandler) { +) : BasePresenter(errorHandler) { - private lateinit var reportingUnit: ReportingUnit - - override fun onAttachView(view: SendMessageView) { + fun onAttachView(view: SendMessageView, message: Message?) { super.onAttachView(view) Timber.i("Send message view is attached") - view.run { - initView() - showBottomNav(false) + loadData(message) + view.apply { + message?.let { + setSubject("RE: ${message.subject}") + if (preferencesRepository.fillMessageContent) { + setContent(when (message.sender.isNotEmpty()) { + true -> "\n\nOd: ${message.sender}\n" + false -> "\n\nDo: ${message.recipient}\n" + } + "Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${message.content}") + } + } } - loadRecipients() } - private fun loadRecipients() { + private fun loadData(message: Message?) { + var reportingUnit: ReportingUnit? = null + var recipients: List = emptyList() + var selectedRecipient: List = emptyList() + Timber.i("Loading recipients started") disposable.add(studentRepository.getCurrentStudent() - .flatMapMaybe { student -> - semesterRepository.getCurrentSemester(student) - .flatMapMaybe { reportingUnitRepository.getReportingUnit(student, it.unitId) } + .flatMap { semesterRepository.getCurrentSemester(it).map { semester -> it to semester } } + .flatMapCompletable { (student, semester) -> + reportingUnitRepository.getReportingUnit(student, semester.unitId) .doOnSuccess { reportingUnit = it } .flatMap { recipientRepository.getRecipients(student, 2, it).toMaybe() } + .doOnSuccess { + Timber.i("Loading recipients result: Success, fetched %d recipients", it.size) + recipients = it + } + .flatMapCompletable { + if (message == null) Completable.complete() + else recipientRepository.getMessageRecipients(student, message) + .doOnSuccess { + Timber.i("Loaded message recipients to reply result: Success, fetched %d recipients", it.size) + selectedRecipient = it + } + .ignoreElement() + } } .subscribeOn(schedulers.backgroundThread) .observeOn(schedulers.mainThread) @@ -54,28 +81,24 @@ class SendMessagePresenter @Inject constructor( showContent(false) } } - .doFinally { - view?.run { - showProgress(false) - } - } + .doFinally { view?.run { showProgress(false) } } .subscribe({ - Timber.i("Loading recipients result: Success, fetched %s recipients", it.size.toString()) view?.apply { - setReportingUnit(reportingUnit) - setRecipients(it) - refreshRecipientsAdapter() - showContent(true) + if (reportingUnit !== null) { + reportingUnit?.let { setReportingUnit(it) } + setRecipients(recipients) + if (selectedRecipient.isNotEmpty()) setSelectedRecipients(selectedRecipient) + showContent(true) + } else { + Timber.e("Loading recipients result: Can't find the reporting unit") + view?.showEmpty(true) + } } }, { - Timber.i("Loading recipients result: An exception occurred") + Timber.e("Loading recipients result: An exception occurred") view?.showContent(true) errorHandler.dispatch(it) - }, { - Timber.i("Loading recipients result: Can't find the reporting unit") - view?.showEmpty(true) - }) - ) + })) } private fun sendMessage(subject: String, content: String, recipients: List) { @@ -85,14 +108,12 @@ class SendMessagePresenter @Inject constructor( .observeOn(schedulers.mainThread) .doOnSubscribe { view?.run { - hideSoftInput() + showSoftInput(false) showContent(false) showProgress(true) + showActionBar(false) } } - .doFinally { - view?.showProgress(false) - } .subscribe({ Timber.i("Sending message result: Success") analytics.logEvent("send_message", "recipients" to recipients.size) @@ -102,16 +123,16 @@ class SendMessagePresenter @Inject constructor( } }, { Timber.i("Sending message result: An exception occurred") - view?.showContent(true) + view?.run { + showContent(true) + showProgress(false) + showActionBar(true) + } errorHandler.dispatch(it) }) ) } - fun onTypingRecipients() { - view?.refreshRecipientsAdapter() - } - fun onSend(): Boolean { view?.run { when { @@ -129,9 +150,4 @@ class SendMessagePresenter @Inject constructor( } return false } - - override fun onDetachView() { - view?.showBottomNav(true) - super.onDetachView() - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt index ded96b07..8a2cb4f6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt @@ -2,9 +2,9 @@ package io.github.wulkanowy.ui.modules.message.send import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.ReportingUnit -import io.github.wulkanowy.ui.base.session.BaseSessionView +import io.github.wulkanowy.ui.base.BaseView -interface SendMessageView : BaseSessionView { +interface SendMessageView : BaseView { val formRecipientsData: List @@ -18,13 +18,11 @@ interface SendMessageView : BaseSessionView { val messageSuccess: String - fun initView() - fun setReportingUnit(unit: ReportingUnit) fun setRecipients(recipients: List) - fun refreshRecipientsAdapter() + fun setSelectedRecipients(recipients: List) fun showProgress(show: Boolean) @@ -32,9 +30,13 @@ interface SendMessageView : BaseSessionView { fun showEmpty(show: Boolean) + fun showActionBar(show: Boolean) + + fun setSubject(subject: String) + + fun setContent(content: String) + + fun showSoftInput(show: Boolean) + fun popView() - - fun hideSoftInput() - - fun showBottomNav(show: Boolean) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt index eb5bbe67..047f2a34 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt @@ -57,7 +57,7 @@ class MessageTabFragment : BaseSessionFragment(), MessageTabView, MessageView.Me super.onActivityCreated(savedInstanceState) messageContainer = messageTabRecycler presenter.onAttachView(this, MessageFolder.valueOf( - (savedInstanceState ?: arguments)?.getString(MessageTabFragment.MESSAGE_TAB_FOLDER_ID) ?: "" + (savedInstanceState ?: arguments)?.getString(MessageTabFragment.MESSAGE_TAB_FOLDER_ID).orEmpty() )) } diff --git a/app/src/main/res/drawable/ic_message_reply_24dp.xml b/app/src/main/res/drawable/ic_message_reply_24dp.xml new file mode 100644 index 00000000..010cb250 --- /dev/null +++ b/app/src/main/res/drawable/ic_message_reply_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_send_message.xml b/app/src/main/res/layout/activity_send_message.xml similarity index 75% rename from app/src/main/res/layout/fragment_send_message.xml rename to app/src/main/res/layout/activity_send_message.xml index 1919720f..00b0e77c 100644 --- a/app/src/main/res/layout/fragment_send_message.xml +++ b/app/src/main/res/layout/activity_send_message.xml @@ -3,13 +3,28 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" + android:id="@+id/sendMessageContainer" android:layout_height="match_parent" android:orientation="vertical"> + + + + + + tools:ignore="RtlSymmetry"> - + app:horizontalScroll="true" + tools:layout_height="30dp"> + + @@ -97,7 +112,7 @@ android:layout_height="match_parent" android:background="@android:color/transparent" android:gravity="top|start" - android:hint="@string/send_message_content" + android:hint="@string/message_content" android:inputType="textMultiLine" android:paddingStart="14dp" android:paddingLeft="14dp" @@ -107,9 +122,10 @@ android:singleLine="false" /> - + android:layout_height="match_parent" + android:layout_below="@id/sendMessageAppBarContainer"> - + diff --git a/app/src/main/res/layout/fragment_message_preview.xml b/app/src/main/res/layout/fragment_message_preview.xml index c0f96045..7150c03a 100644 --- a/app/src/main/res/layout/fragment_message_preview.xml +++ b/app/src/main/res/layout/fragment_message_preview.xml @@ -1,22 +1,22 @@ - - - + + + + diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index bf2162c3..7eaf4e5e 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -7,9 +7,12 @@ @style/PreferenceThemeOverlay.v14.Material @color/bottom_nav_background @color/bottom_nav_background - @color/chip_material_background_inverse - @color/chip_default_text_color_inverse @color/divider_inverse + @color/chip_backgroundColor_inverse + @color/chip_labelColor_inverse + @color/chip_backgroundColor_inverse + @color/filterable_list_backgroundColor_inverse + @color/filterable_list_textColor_inverse @color/about_libraries_window_background_dark diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d2e5a35f..dcc73526 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -13,6 +13,7 @@ Więcej O aplikacji Wiadomości + Nowa wiadomość Uwagi i osiągnięcia Zadania domowe Wybierz konto @@ -135,9 +136,15 @@ (brak tematu) Brak wiadomości Wystąpił błąd podczas pobierania treści wiadomości - Od: %s - Do: %s + Od: + Do: Data: %s + Odpowiedz + Temat + Treść + Wiadomość wysłana pomyślnie + Musisz wybrać co najmniej 1 adresata + Treść wiadomości musi zawierać co najmniej 3 znaki %d wiadomość %d wiadomości @@ -154,16 +161,6 @@ Dostałeś %1$d wiadomości - - Wyślij - Od: - Do: - Temat - Treść - Wiadomość wysłana pomyślnie - Musisz wybrać co najmniej 1 adresata - Treść wiadomości musi zawierać co najmniej 3 znaki - Brak informacji o uwagach @@ -241,8 +238,6 @@ Pokazuj podsumowanie w ocenach Pokazuj obecność we frekwencji Ciemny motyw (Beta) - Wartość plusa - Wartość minusa Rozwiń oceny Schemat kolorów ocen @@ -256,6 +251,11 @@ Interwał aktualizacji Tylko WiFi + Inne + Wartość plusa + Wartość minusa + Odpowiadaj z historią wiadomości + Nowe wpisy w dzienniku diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 30909eba..49854955 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -32,8 +32,11 @@ #303030 #ffffff - #595959 - #fefefe + #595959 + #fefefe + #fefefe + #393939 + #fefefe #cccccc #777777 diff --git a/app/src/main/res/values/preferences_keys.xml b/app/src/main/res/values/preferences_keys.xml index 0a2f8ea8..427cca56 100644 --- a/app/src/main/res/values/preferences_keys.xml +++ b/app/src/main/res/values/preferences_keys.xml @@ -3,8 +3,6 @@ start_menu attendance_present theme - grade_modifier_plus - grade_modifier_minus grade_color_scheme expand_grade services_enable @@ -12,4 +10,7 @@ services_disable_wifi_only notifications_enable notification_debug + grade_modifier_plus + grade_modifier_minus + fill_message_content diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 56c9f2c0..1debed7b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,6 +13,7 @@ More About Messages + New message Notes and achievements Homework Choose account @@ -129,9 +130,15 @@ (no subject) No messages An error occurred while downloading message content - From: %s - To: %s + From: + To: Date: %s + Reply + Subject + Content + Message sent successfully + You need to choose at least 1 recipient + The message content must be at least 3 characters %d message %d messages @@ -145,16 +152,6 @@ You received %1$d messages - - Send - From: - To: - Subject - Content - Message sent successfully - You need to choose at least 1 recipient - The message content must be at least 3 characters - No info about notes @@ -226,8 +223,6 @@ Show the summary in the grades Show presence in attendance Dark theme (Beta) - Value of the plus - Value of the minus Expand grades Grades color scheme @@ -241,6 +236,11 @@ Updates interval Wi-Fi only + Other + Value of the plus + Value of the minus + Reply with message history + New entries in register diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 4735fd2f..4bbe3bc1 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -14,9 +14,8 @@ @android:color/primary_text_dark @android:color/white @color/bottom_nav_background_inverse - @color/chip_material_background - @color/chip_default_text_color @color/divider + @color/chip_detailed_backgroundColor @color/about_libraries_window_background diff --git a/app/src/main/res/xml/scheme_preferences.xml b/app/src/main/res/xml/scheme_preferences.xml index f3b9ae2d..08c24124 100644 --- a/app/src/main/res/xml/scheme_preferences.xml +++ b/app/src/main/res/xml/scheme_preferences.xml @@ -38,22 +38,6 @@ android:summary="%s" android:title="@string/pref_grade_color_scheme" app:iconSpaceReserved="false" /> - - + + + + + diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/message/send/TestRecipientChip.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/message/send/TestRecipientChip.kt new file mode 100644 index 00000000..943fb190 --- /dev/null +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/message/send/TestRecipientChip.kt @@ -0,0 +1,20 @@ +package io.github.wulkanowy.ui.modules.message.send + +import io.github.wulkanowy.data.db.entities.Recipient +import org.junit.Assert.assertEquals +import org.junit.Test + +class TestRecipientChip { + + @Test + fun testRecipientChipInfo() { + assertEquals("Uczeń", getRecipientChip("Kowalski Jan - Uczeń").info) + assertEquals("(JK) - pracownik [Fake123456]", getRecipientChip("Kowalski Jan (JK) - pracownik [Fake123456]").info) + assertEquals("[KK] - pracownik (Fake123456)", getRecipientChip("Kowalska Karolina [KK] - pracownik (Fake123456)").info) + assertEquals("(BK) - Nauczyciel [Fake123456]", getRecipientChip("Kowal-Mazur Barbara (BK) - Nauczyciel [Fake123456]").info) + } + + private fun getRecipientChip(realName: String): RecipientChip { + return RecipientChip(Recipient(0, "", "", realName, 0, 0, 0, "")) + } +}