diff --git a/.travis.yml b/.travis.yml index 2d65d7bc..8bda02d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ cache: branches: only: - develop - - 0.11.0 + - 0.12.0 android: licenses: diff --git a/app/build.gradle b/app/build.gradle index ee372782..090a643d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { testApplicationId "io.github.tests.wulkanowy" minSdkVersion 16 targetSdkVersion 29 - versionCode 46 - versionName "0.11.0" + versionCode 47 + versionName "0.12.0" multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true @@ -110,9 +110,9 @@ play { } ext { - work_manager = "2.2.0" - room = "2.2.0-rc01" - dagger = "2.24" + work_manager = "2.3.0-alpha03" + room = "2.2.1" + dagger = "2.25.2" chucker = "2.0.4" mockk = "1.9.2" } @@ -123,23 +123,23 @@ configurations.all { } dependencies { - implementation "io.github.wulkanowy:api:0.11.0" + implementation "io.github.wulkanowy:api:0.12.0" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation "androidx.core:core-ktx:1.1.0" - implementation "androidx.activity:activity-ktx:1.0.0" + implementation "androidx.core:core-ktx:1.2.0-beta01" + implementation "androidx.activity:activity-ktx:1.1.0-rc01" implementation "androidx.appcompat:appcompat:1.1.0" implementation "androidx.appcompat:appcompat-resources:1.1.0" - implementation "androidx.fragment:fragment-ktx:1.1.0" + implementation "androidx.fragment:fragment-ktx:1.2.0-rc01" implementation "androidx.annotation:annotation:1.1.0" implementation "androidx.multidex:multidex:2.0.1" implementation "androidx.preference:preference-ktx:1.1.0" - implementation "androidx.recyclerview:recyclerview:1.1.0-beta04" + implementation "androidx.recyclerview:recyclerview:1.1.0-rc01" implementation "androidx.viewpager:viewpager:1.0.0" - implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03" implementation "androidx.constraintlayout:constraintlayout:1.1.3" - implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0-beta01" + implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0-rc01" implementation "com.google.android.material:material:1.1.0-alpha07" implementation "com.github.wulkanowy:material-chips-input:2.0.1" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0" @@ -174,9 +174,9 @@ dependencies { implementation "com.jakewharton.timber:timber:4.7.1" implementation "at.favre.lib:slf4j-timber:1.0.1" implementation "com.squareup.okhttp3:logging-interceptor:3.12.6" - implementation "com.mikepenz:aboutlibraries:7.0.3" + implementation "com.mikepenz:aboutlibraries:7.0.4" - playImplementation "com.google.firebase:firebase-core:17.2.0" + playImplementation "com.google.firebase:firebase-core:17.2.1" playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1" releaseImplementation "fr.o80.chucker:library-no-op:$chucker" diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/18.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/18.json new file mode 100644 index 00000000..4f7497fe --- /dev/null +++ b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/18.json @@ -0,0 +1,1592 @@ +{ + "formatVersion": 1, + "database": { + "version": 18, + "identityHash": "73b1dcfe0cf84170ba102b2818dd0191", + "entities": [ + { + "tableName": "Students", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `endpoint` TEXT NOT NULL, `loginType` TEXT NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "endpoint", + "columnName": "endpoint", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginType", + "columnName": "loginType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentName", + "columnName": "student_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolSymbol", + "columnName": "school_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolName", + "columnName": "school_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "className", + "columnName": "class_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCurrent", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "registrationDate", + "columnName": "registration_date", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Students_email_symbol_student_id_school_id_class_id", + "unique": true, + "columnNames": [ + "email", + "symbol", + "student_id", + "school_id", + "class_id" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Semesters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryName", + "columnName": "diary_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "schoolYear", + "columnName": "school_year", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterName", + "columnName": "semester_name", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCurrent", + "columnName": "is_current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Semesters_student_id_diary_id_semester_id", + "unique": true, + "columnNames": [ + "student_id", + "diary_id", + "semester_id" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Exams", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Timetable", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subjectOld", + "columnName": "subjectOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "room", + "columnName": "room", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roomOld", + "columnName": "roomOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherOld", + "columnName": "teacherOld", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "info", + "columnName": "info", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "changes", + "columnName": "changes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canceled", + "columnName": "canceled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Attendance", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "excused", + "columnName": "excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AttendanceSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subjectId", + "columnName": "subject_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "month", + "columnName": "month", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "presence", + "columnName": "presence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceExcused", + "columnName": "absence_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "absenceForSchoolReasons", + "columnName": "absence_for_school_reasons", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lateness", + "columnName": "lateness", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "latenessExcused", + "columnName": "lateness_excused", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exemption", + "columnName": "exemption", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Grades", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` INTEGER NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "entry", + "columnName": "entry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "modifier", + "columnName": "modifier", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "gradeSymbol", + "columnName": "grade_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weightValue", + "columnName": "weightValue", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesSummary", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "predictedGrade", + "columnName": "predicted_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalGrade", + "columnName": "final_grade", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "proposedPoints", + "columnName": "proposed_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "finalPoints", + "columnName": "final_points", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pointsSum", + "columnName": "points_sum", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "average", + "columnName": "average", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "grade", + "columnName": "grade", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semester", + "columnName": "is_semester", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "GradesPointsStatistics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "others", + "columnName": "others", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "student", + "columnName": "student", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Messages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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_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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "messageId", + "columnName": "message_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sender", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "recipient", + "columnName": "recipient_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "folderId", + "columnName": "folder_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unread", + "columnName": "unread", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unreadBy", + "columnName": "unread_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readBy", + "columnName": "read_by", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "removed", + "columnName": "removed", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Notes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isRead", + "columnName": "is_read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "category", + "columnName": "category", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Homework", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "semesterId", + "columnName": "semester_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "entryDate", + "columnName": "entry_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Subjects", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "LuckyNumbers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isNotified", + "columnName": "is_notified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "luckyNumber", + "columnName": "lucky_number", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "CompletedLesson", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT 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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "diaryId", + "columnName": "diary_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "topic", + "columnName": "topic", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacher", + "columnName": "teacher", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "teacherSymbol", + "columnName": "teacher_symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "substitution", + "columnName": "substitution", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "absence", + "columnName": "absence", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resources", + "columnName": "resources", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ReportingUnits", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT 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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "senderId", + "columnName": "sender_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "senderName", + "columnName": "sender_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Recipients", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT 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)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "realId", + "columnName": "real_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "realName", + "columnName": "real_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "loginId", + "columnName": "login_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unitId", + "columnName": "unit_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "role", + "columnName": "role", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hash", + "columnName": "hash", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "MobileDevices", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "deviceId", + "columnName": "device_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Teachers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortName", + "columnName": "short_name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "School", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "studentId", + "columnName": "student_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "classId", + "columnName": "class_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contact", + "columnName": "contact", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "headmaster", + "columnName": "headmaster", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pedagogue", + "columnName": "pedagogue", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '73b1dcfe0cf84170ba102b2818dd0191')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt index b3686f5e..9c89d507 100644 --- a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt +++ b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt @@ -144,4 +144,8 @@ internal class RepositoryModule { @Singleton @Provides fun provideTeacherDao(database: AppDatabase) = database.teacherDao + + @Singleton + @Provides + fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao } 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 4dcba3e1..b1896c75 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 @@ -22,6 +22,7 @@ import io.github.wulkanowy.data.db.dao.MobileDeviceDao import io.github.wulkanowy.data.db.dao.NoteDao import io.github.wulkanowy.data.db.dao.RecipientDao import io.github.wulkanowy.data.db.dao.ReportingUnitDao +import io.github.wulkanowy.data.db.dao.SchoolDao import io.github.wulkanowy.data.db.dao.SemesterDao import io.github.wulkanowy.data.db.dao.StudentDao import io.github.wulkanowy.data.db.dao.SubjectDao @@ -42,6 +43,7 @@ import io.github.wulkanowy.data.db.entities.MobileDevice import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.School import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Subject @@ -55,6 +57,7 @@ import io.github.wulkanowy.data.db.migrations.Migration14 import io.github.wulkanowy.data.db.migrations.Migration15 import io.github.wulkanowy.data.db.migrations.Migration16 import io.github.wulkanowy.data.db.migrations.Migration17 +import io.github.wulkanowy.data.db.migrations.Migration18 import io.github.wulkanowy.data.db.migrations.Migration2 import io.github.wulkanowy.data.db.migrations.Migration3 import io.github.wulkanowy.data.db.migrations.Migration4 @@ -87,7 +90,8 @@ import javax.inject.Singleton ReportingUnit::class, Recipient::class, MobileDevice::class, - Teacher::class + Teacher::class, + School::class ], version = AppDatabase.VERSION_SCHEMA, exportSchema = true @@ -96,7 +100,7 @@ import javax.inject.Singleton abstract class AppDatabase : RoomDatabase() { companion object { - const val VERSION_SCHEMA = 17 + const val VERSION_SCHEMA = 18 fun getMigrations(): Array { return arrayOf( @@ -115,7 +119,8 @@ abstract class AppDatabase : RoomDatabase() { Migration14(), Migration15(), Migration16(), - Migration17() + Migration17(), + Migration18() ) } @@ -168,4 +173,6 @@ abstract class AppDatabase : RoomDatabase() { abstract val mobileDeviceDao: MobileDeviceDao abstract val teacherDao: TeacherDao + + abstract val schoolDao: SchoolDao } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolDao.kt new file mode 100644 index 00000000..c2b2e0bc --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolDao.kt @@ -0,0 +1,23 @@ +package io.github.wulkanowy.data.db.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.Query +import io.github.wulkanowy.data.db.entities.School +import io.reactivex.Maybe +import javax.inject.Singleton + +@Singleton +@Dao +interface SchoolDao { + + @Insert + fun insert(school: School) + + @Delete + fun delete(school: School) + + @Query("SELECT * FROM School WHERE student_id = :studentId AND class_id = :classId") + fun load(studentId: Int, classId: Int): Maybe +} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt index ad0b8924..e7794248 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt @@ -13,10 +13,10 @@ import javax.inject.Singleton interface TeacherDao { @Insert - fun insertAll(devices: List) + fun insertAll(teachers: List) @Delete - fun deleteAll(devices: List) + fun deleteAll(teachers: List) @Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId") fun loadAll(studentId: Int, classId: Int): Maybe> diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/School.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/School.kt new file mode 100644 index 00000000..20fae450 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/School.kt @@ -0,0 +1,30 @@ +package io.github.wulkanowy.data.db.entities + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import java.io.Serializable + +@Entity(tableName = "School") +data class School( + + @ColumnInfo(name = "student_id") + val studentId: Int, + + @ColumnInfo(name = "class_id") + val classId: Int, + + val name: String, + + val address: String, + + val contact: String, + + val headmaster: String, + + val pedagogue: String +) : Serializable { + + @PrimaryKey(autoGenerate = true) + var id: Long = 0 +} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration18.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration18.kt new file mode 100644 index 00000000..6c5e56c6 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration18.kt @@ -0,0 +1,22 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +class Migration18 : Migration(17, 18) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" + CREATE TABLE IF NOT EXISTS School ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + student_id INTEGER NOT NULL, + class_id INTEGER NOT NULL, + name TEXT NOT NULL, + address TEXT NOT NULL, + contact TEXT NOT NULL, + headmaster TEXT NOT NULL, + pedagogue TEXT NOT NULL + ) + """) + } +} 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 bb9a39b1..e1caf920 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 @@ -12,52 +12,60 @@ class PreferencesRepository @Inject constructor( val context: Context ) { val startMenuIndex: Int - get() = sharedPref.getString(context.getString(R.string.pref_key_start_menu), "0")?.toIntOrNull() ?: 0 + get() = getString(R.string.pref_key_start_menu, R.string.pref_default_startup).toInt() val isShowPresent: Boolean - get() = sharedPref.getBoolean(context.getString(R.string.pref_key_attendance_present), true) + get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present) val gradeAverageMode: String - get() = sharedPref.getString(context.getString(R.string.pref_key_grade_average_mode), "only_one_semester") ?: "only_one_semester" + get() = getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode) val gradeAverageForceCalc: Boolean - get() = sharedPref.getBoolean(context.getString(R.string.pref_key_grade_average_force_calc), false) + get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc) val isGradeExpandable: Boolean - get() = !sharedPref.getBoolean(context.getString(R.string.pref_key_expand_grade), false) + get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade) - val appThemeKey: String = context.getString(R.string.pref_key_app_theme) + val appThemeKey = context.getString(R.string.pref_key_app_theme) val appTheme: String - get() = sharedPref.getString(appThemeKey, "light") ?: "light" + get() = getString(appThemeKey, R.string.pref_default_app_theme) val gradeColorTheme: String - get() = sharedPref.getString(context.getString(R.string.pref_key_grade_color_scheme), "vulcan") ?: "vulcan" + get() = getString(R.string.pref_key_grade_color_scheme, R.string.pref_default_grade_color_scheme) - val serviceEnableKey: String = context.getString(R.string.pref_key_services_enable) + val serviceEnableKey = context.getString(R.string.pref_key_services_enable) val isServiceEnabled: Boolean - get() = sharedPref.getBoolean(serviceEnableKey, true) + get() = getBoolean(serviceEnableKey, R.bool.pref_default_services_enable) - val servicesIntervalKey: String = context.getString(R.string.pref_key_services_interval) + val servicesIntervalKey = context.getString(R.string.pref_key_services_interval) val servicesInterval: Long - get() = sharedPref.getString(servicesIntervalKey, "60")?.toLongOrNull() ?: 60 + get() = getString(servicesIntervalKey, R.string.pref_default_services_interval).toLong() - val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only) + val servicesOnlyWifiKey = context.getString(R.string.pref_key_services_wifi_only) val isServicesOnlyWifi: Boolean - get() = sharedPref.getBoolean(servicesOnlyWifiKey, false) + get() = getBoolean(servicesOnlyWifiKey, R.bool.pref_default_services_wifi_only) val isNotificationsEnable: Boolean - get() = sharedPref.getBoolean(context.getString(R.string.pref_key_notifications_enable), true) + get() = getBoolean(R.string.pref_key_notifications_enable, R.bool.pref_default_notifications_enable) - val isDebugNotificationEnableKey: String = context.getString(R.string.pref_key_notification_debug) + val isDebugNotificationEnableKey = context.getString(R.string.pref_key_notification_debug) val isDebugNotificationEnable: Boolean - get() = sharedPref.getBoolean(isDebugNotificationEnableKey, false) + get() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug) val gradePlusModifier: Double - get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_plus), "0.0")?.toDouble() ?: 0.0 + get() = getString(R.string.pref_key_grade_modifier_plus, R.string.pref_default_grade_modifier_plus).toDouble() val gradeMinusModifier: Double - get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_minus), "0.0")?.toDouble() ?: 0.0 + get() = getString(R.string.pref_key_grade_modifier_minus, R.string.pref_default_grade_modifier_minus).toDouble() val fillMessageContent: Boolean - get() = sharedPref.getBoolean(context.getString(R.string.pref_key_fill_message_content), true) + get() = getBoolean(R.string.pref_key_fill_message_content, R.bool.pref_default_fill_message_content) + + private fun getString(id: Int, default: Int) = getString(context.getString(id), default) + + private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default) + + private fun getBoolean(id: Int, default: Int) = getBoolean(context.getString(id), default) + + private fun getBoolean(id: String, default: Int) = sharedPref.getBoolean(id, context.resources.getBoolean(default)) } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolLocal.kt new file mode 100644 index 00000000..1692e39b --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolLocal.kt @@ -0,0 +1,22 @@ +package io.github.wulkanowy.data.repositories.school + +import io.github.wulkanowy.data.db.dao.SchoolDao +import io.github.wulkanowy.data.db.entities.School +import io.github.wulkanowy.data.db.entities.Semester +import io.reactivex.Maybe +import javax.inject.Inject + +class SchoolLocal @Inject constructor(private val schoolDb: SchoolDao) { + + fun saveSchool(school: School) { + schoolDb.insert(school) + } + + fun deleteSchool(school: School) { + schoolDb.delete(school) + } + + fun getSchool(semester: Semester): Maybe { + return schoolDb.load(semester.studentId, semester.classId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRemote.kt new file mode 100644 index 00000000..86e05f0f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRemote.kt @@ -0,0 +1,26 @@ +package io.github.wulkanowy.data.repositories.school + +import io.github.wulkanowy.api.Api +import io.github.wulkanowy.data.db.entities.School +import io.github.wulkanowy.data.db.entities.Semester +import io.reactivex.Single +import javax.inject.Inject + +class SchoolRemote @Inject constructor(private val api: Api) { + + fun getSchoolInfo(semester: Semester): Single { + return Single.just(api.apply { diaryId = semester.diaryId }) + .flatMap { it.getSchool() } + .map { + School( + studentId = semester.studentId, + classId = semester.classId, + name = it.name, + address = it.address, + contact = it.contact, + headmaster = it.headmaster, + pedagogue = it.pedagogue + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRepository.kt new file mode 100644 index 00000000..a352324d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRepository.kt @@ -0,0 +1,41 @@ +package io.github.wulkanowy.data.repositories.school + +import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork +import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings +import io.github.wulkanowy.data.db.entities.School +import io.github.wulkanowy.data.db.entities.Semester +import io.reactivex.Maybe +import io.reactivex.Single +import java.net.UnknownHostException +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SchoolRepository @Inject constructor( + private val settings: InternetObservingSettings, + private val local: SchoolLocal, + private val remote: SchoolRemote +) { + + fun getSchoolInfo(semester: Semester, forceRefresh: Boolean = false): Maybe { + return local.getSchool(semester).filter { !forceRefresh } + .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) + .flatMap { + if (it) remote.getSchoolInfo(semester) + else Single.error(UnknownHostException()) + }.flatMapMaybe { new -> + local.getSchool(semester) + .doOnSuccess { old -> + if (new != old) { + local.deleteSchool(old) + local.saveSchool(new) + } + } + .doOnComplete { + local.saveSchool(new) + } + }.flatMap({ local.getSchool(semester) }, { Maybe.error(it) }, + { local.getSchool(semester) }) + ) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherLocal.kt index 9ff11b7a..dd2be5e5 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherLocal.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherLocal.kt @@ -6,7 +6,8 @@ import io.github.wulkanowy.data.db.entities.Teacher import io.reactivex.Maybe import javax.inject.Inject -class TeacherLocal @Inject constructor(private val teacherDb: TeacherDao) { +class TeacherLocal @Inject constructor(private val teacherDb: TeacherDao) { + fun saveTeachers(teachers: List) { teacherDb.insertAll(teachers) } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRepository.kt index 8db0b44c..19e7a32b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRepository.kt @@ -16,6 +16,7 @@ class TeacherRepository @Inject constructor( private val local: TeacherLocal, private val remote: TeacherRemote ) { + fun getTeachers(semester: Semester, forceRefresh: Boolean = false): Single> { return local.getTeachers(semester).filter { !forceRefresh } .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) diff --git a/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt b/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt index 7d1b223e..78bdbd8c 100644 --- a/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt +++ b/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt @@ -29,17 +29,15 @@ import javax.inject.Singleton @Suppress("unused") @AssistedModule -@Module(includes = [AssistedInject_ServicesModule::class]) +@Module(includes = [AssistedInject_ServicesModule::class, ServicesModule.Static::class]) abstract class ServicesModule { @Module - companion object { + object Static { - @JvmStatic @Provides fun provideWorkManager(context: Context) = WorkManager.getInstance(context) - @JvmStatic @Singleton @Provides fun provideNotificationManager(context: Context) = NotificationManagerCompat.from(context) diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt index 5b347fe8..50134861 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt @@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.base import android.content.pm.PackageManager.GET_ACTIVITIES import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES import io.github.wulkanowy.R @@ -22,8 +23,12 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer fun applyDefaultTheme() { AppCompatDelegate.setDefaultNightMode( - if (preferencesRepository.appTheme == "light") MODE_NIGHT_NO - else MODE_NIGHT_YES + when (val theme = preferencesRepository.appTheme) { + "light" -> MODE_NIGHT_NO + "dark", "black" -> MODE_NIGHT_YES + "system" -> MODE_NIGHT_FOLLOW_SYSTEM + else -> throw IllegalArgumentException("Wrong theme: $theme") + } ) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt index 52cf087b..6e6ca2d6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeModule.kt @@ -11,13 +11,12 @@ import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment @Suppress("unused") -@Module +@Module(includes = [GradeModule.Static::class]) abstract class GradeModule { @Module - companion object { + object Static { - @JvmStatic @PerFragment @Provides fun provideGradeAdapter(fragment: GradeFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt index a0b98be7..8bcf042b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginModule.kt @@ -11,13 +11,12 @@ import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFrag import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment @Suppress("unused") -@Module +@Module(includes = [LoginModule.Static::class]) internal abstract class LoginModule { @Module - companion object { + object Static { - @JvmStatic @PerActivity @Provides fun provideLoginAdapter(activity: LoginActivity) = BaseFragmentPagerAdapter(activity.supportFragmentManager) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt index 4849b213..1288e299 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt @@ -9,7 +9,6 @@ import android.view.View.VISIBLE import android.view.ViewGroup import android.view.inputmethod.EditorInfo.IME_ACTION_DONE import android.view.inputmethod.EditorInfo.IME_NULL -import android.widget.ArrayAdapter import androidx.core.widget.doOnTextChanged import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Student @@ -17,6 +16,7 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.hideSoftInput +import io.github.wulkanowy.utils.openEmail import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.showSoftInput import kotlinx.android.synthetic.main.fragment_login_form.* @@ -54,26 +54,24 @@ class LoginFormFragment : BaseFragment(), LoginFormView { } override fun initView() { - hostKeys = resources.getStringArray(R.array.endpoints_keys) - hostValues = resources.getStringArray(R.array.endpoints_values) + hostKeys = resources.getStringArray(R.array.hosts_keys) + hostValues = resources.getStringArray(R.array.hosts_values) loginFormName.doOnTextChanged { _, _, _, _ -> presenter.onNameTextChanged() } loginFormPass.doOnTextChanged { _, _, _, _ -> presenter.onPassTextChanged() } loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() } loginFormSignIn.setOnClickListener { presenter.onSignInClick() } loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() } + loginFormContactDiscord.setOnClickListener { presenter.onDiscordClick() } + loginFormContactEmail.setOnClickListener { presenter.onEmailClick() } loginFormPass.setOnEditorActionListener { _, id, _ -> if (id == IME_ACTION_DONE || id == IME_NULL) loginFormSignIn.callOnClick() else false } with(loginFormHost) { - //Bug with filter in ExposedDropdownMenu on restoring state - isSaveEnabled = false - setText(hostKeys.getOrElse(0) { "" }) - setAdapter(ArrayAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys)) - keyListener = null + setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys)) } } @@ -154,8 +152,25 @@ class LoginFormFragment : BaseFragment(), LoginFormView { context?.openInternetBrowser("https://wulkanowy.github.io/polityka-prywatnosci.html", ::showMessage) } + override fun showContact(show: Boolean) { + loginFormContact.visibility = if (show) VISIBLE else GONE + } + override fun onDestroyView() { super.onDestroyView() presenter.onDetachView() } + + override fun openDiscordInvite() { + context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage) + } + + override fun openEmail() { + context?.openEmail( + requireContext().getString(R.string.login_email_intent_title), + "wulkanowyinc@gmail.com", + requireContext().getString(R.string.login_email_subject), + requireContext().getString(R.string.login_email_text, appInfo.systemModel, appInfo.systemVersion.toString(), appInfo.versionName) + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index d5b81b5b..bdab1dad 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -22,6 +22,7 @@ class LoginFormPresenter @Inject constructor( super.onAttachView(view) view.run { initView() + showContact(false) if (appInfo.isDebug) showVersion() else showPrivacyPolicy() loginErrorHandler.onBadCredentials = { @@ -86,9 +87,18 @@ class LoginFormPresenter @Inject constructor( Timber.i("Login result: An exception occurred") analytics.logEvent("registration_form", "success" to false, "students" to -1, "endpoint" to endpoint, "error" to it.message.ifNullOrBlank { "No message" }) loginErrorHandler.dispatch(it) + view?.showContact(true) })) } + fun onDiscordClick() { + view?.openDiscordInvite() + } + + fun onEmailClick() { + view?.openEmail() + } + private fun validateCredentials(login: String, password: String): Boolean { var isCorrect = true diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt index 097b6f62..7eec9477 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt @@ -42,4 +42,10 @@ interface LoginFormView : BaseView { fun notifyParentAccountLogged(students: List, loginData: Triple) fun openPrivacyPolicyPage() + + fun showContact(show: Boolean) + + fun openDiscordInvite() + + fun openEmail() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginSymbolAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginSymbolAdapter.kt new file mode 100644 index 00000000..87fa038e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginSymbolAdapter.kt @@ -0,0 +1,16 @@ +package io.github.wulkanowy.ui.modules.login.form + +import android.content.Context +import android.widget.ArrayAdapter +import android.widget.Filter + +class LoginSymbolAdapter(context: Context, resource: Int, objects: Array) : + ArrayAdapter(context, resource, objects) { + + override fun getFilter() = object : Filter() { + + override fun performFiltering(constraint: CharSequence?) = null + + override fun publishResults(constraint: CharSequence?, results: FilterResults?) {} + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt index 5c48cf2f..dba0c951 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt @@ -13,6 +13,9 @@ import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.openEmail +import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_login_student_select.* import java.io.Serializable @@ -26,6 +29,9 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView { @Inject lateinit var loginAdapter: FlexibleAdapter> + @Inject + lateinit var appInfo: AppInfo + companion object { const val SAVED_STUDENTS = "STUDENTS" @@ -44,6 +50,8 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView { override fun initView() { loginStudentSelectSignIn.setOnClickListener { presenter.onSignIn() } loginAdapter.apply { setOnItemClickListener { presenter.onItemSelected(it) } } + loginStudentSelectContactDiscord.setOnClickListener { presenter.onDiscordClick() } + loginStudentSelectContactEmail.setOnClickListener { presenter.onEmailClick() } loginStudentSelectRecycler.apply { adapter = loginAdapter @@ -80,8 +88,25 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView { outState.putSerializable(SAVED_STUDENTS, presenter.students as Serializable) } + override fun showContact(show: Boolean) { + loginStudentSelectContact.visibility = if (show) VISIBLE else GONE + } + override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() } + + override fun openDiscordInvite() { + context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage) + } + + override fun openEmail() { + context?.openEmail( + requireContext().getString(R.string.login_email_intent_title), + "wulkanowyinc@gmail.com", + requireContext().getString(R.string.login_email_subject), + requireContext().getString(R.string.login_email_text, appInfo.systemModel, appInfo.systemVersion.toString(), appInfo.versionName) + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt index e02227cb..288531dc 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt @@ -27,6 +27,7 @@ class LoginStudentSelectPresenter @Inject constructor( super.onAttachView(view) view.run { initView() + showContact(false) enableSignIn(false) loginErrorHandler.onStudentDuplicate = { showMessage(it) @@ -88,7 +89,16 @@ class LoginStudentSelectPresenter @Inject constructor( view?.apply { showProgress(false) showContent(true) + showContact(true) } })) } + + fun onDiscordClick() { + view?.openDiscordInvite() + } + + fun onEmailClick() { + view?.openEmail() + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt index 3967313c..23877100 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt @@ -15,4 +15,10 @@ interface LoginStudentSelectView : BaseView { fun showContent(show: Boolean) fun enableSignIn(enable: Boolean) + + fun showContact(show: Boolean) + + fun openDiscordInvite() + + fun openEmail() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt index f4f0eb9e..724e3fbb 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt @@ -14,7 +14,10 @@ import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.login.LoginActivity +import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.hideSoftInput +import io.github.wulkanowy.utils.openEmail +import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.showSoftInput import kotlinx.android.synthetic.main.fragment_login_symbol.* import javax.inject.Inject @@ -24,6 +27,9 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView { @Inject lateinit var presenter: LoginSymbolPresenter + @Inject + lateinit var appInfo: AppInfo + companion object { private const val SAVED_LOGIN_DATA = "LOGIN_DATA" @@ -44,6 +50,8 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView { override fun initView() { loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) } + loginSymbolContactDiscord.setOnClickListener { presenter.onDiscordClick() } + loginSymbolContactEmail.setOnClickListener { presenter.onEmailClick() } loginSymbolName.doOnTextChanged { _, _, _, _ -> presenter.onSymbolTextChanged() } @@ -109,8 +117,25 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView { outState.putSerializable(SAVED_LOGIN_DATA, presenter.loginData) } + override fun showContact(show: Boolean) { + loginSymbolContact.visibility = if (show) VISIBLE else GONE + } + override fun onDestroyView() { super.onDestroyView() presenter.onDetachView() } + + override fun openDiscordInvite() { + context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage) + } + + override fun openEmail() { + context?.openEmail( + requireContext().getString(R.string.login_email_intent_title), + "wulkanowyinc@gmail.com", + requireContext().getString(R.string.login_email_subject), + requireContext().getString(R.string.login_email_text, appInfo.systemModel, appInfo.systemVersion.toString(), appInfo.versionName) + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt index 5a7a3777..8e4dd3b0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt @@ -23,7 +23,10 @@ class LoginSymbolPresenter @Inject constructor( @Suppress("UNCHECKED_CAST") fun onAttachView(view: LoginSymbolView, savedLoginData: Serializable?) { super.onAttachView(view) - view.initView() + view.run { + initView() + showContact(false) + } if (savedLoginData is Triple<*, *, *>) { loginData = savedLoginData as Triple } @@ -64,6 +67,7 @@ class LoginSymbolPresenter @Inject constructor( if (it.isEmpty()) { Timber.i("Login with symbol result: Empty student list") setErrorSymbolIncorrect() + view?.showContact(true) } else { Timber.i("Login with symbol result: Success") notifyParentAccountLogged(it) @@ -73,6 +77,7 @@ class LoginSymbolPresenter @Inject constructor( Timber.i("Login with symbol result: An exception occurred") analytics.logEvent("registration_symbol", "success" to false, "students" to -1, "endpoint" to loginData?.third, "symbol" to symbol, "error" to it.message.ifNullOrBlank { "No message" }) loginErrorHandler.dispatch(it) + view?.showContact(true) })) } @@ -83,4 +88,12 @@ class LoginSymbolPresenter @Inject constructor( showSoftKeyboard() } } + + fun onDiscordClick() { + view?.openDiscordInvite() + } + + fun onEmailClick() { + view?.openEmail() + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt index 2e5143ef..9b5340cf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt @@ -26,4 +26,10 @@ interface LoginSymbolView : BaseView { fun showContent(show: Boolean) fun notifyParentAccountLogged(students: List) + + fun showContact(show: Boolean) + + fun openDiscordInvite() + + fun openEmail() } 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 29adcf89..bbaea51c 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 @@ -26,26 +26,25 @@ import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceModule import io.github.wulkanowy.ui.modules.mobiledevice.token.MobileDeviceTokenDialog 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.schoolandteachers.SchoolAndTeachersModule import io.github.wulkanowy.ui.modules.settings.SettingsFragment -import io.github.wulkanowy.ui.modules.teacher.TeacherFragment import io.github.wulkanowy.ui.modules.timetable.TimetableFragment import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment @Suppress("unused") -@Module +@Module(includes = [MainModule.Static::class]) abstract class MainModule { @Module - companion object { + object Static { - @JvmStatic @Provides fun provideFragNavController(activity: MainActivity): FragNavController { return FragNavController(activity.supportFragmentManager, R.id.mainFragmentContainer) } //In activities must be injected as Lazy - @JvmStatic @Provides fun provideElevationOverlayProvider(activity: MainActivity) = ElevationOverlayProvider(activity) } @@ -123,6 +122,6 @@ abstract class MainModule { abstract fun bindLicenseFragment(): LicenseFragment @PerFragment - @ContributesAndroidInjector - abstract fun bindTeacherFragment(): TeacherFragment + @ContributesAndroidInjector(modules = [SchoolAndTeachersModule::class]) + abstract fun bindSchoolAndTeachersFragment(): SchoolAndTeachersFragment } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt index 07e4c8d0..1c0fd39f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt @@ -7,6 +7,7 @@ import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.modules.main.MainView.Section.GRADE import io.github.wulkanowy.ui.modules.main.MainView.Section.MESSAGE +import io.github.wulkanowy.ui.modules.main.MainView.Section.SCHOOL import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import timber.log.Timber @@ -38,7 +39,7 @@ class MainPresenter @Inject constructor( fun onViewChange(section: MainView.Section?) { view?.apply { - showActionBarElevation(section != GRADE && section != MESSAGE) + showActionBarElevation(section != GRADE && section != MESSAGE && section != SCHOOL) currentViewTitle?.let { setViewTitle(it) } currentStackSize?.let { if (it > 1) showHomeArrow(true) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt index c53adc5b..033b6a1f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt @@ -51,6 +51,7 @@ interface MainView : BaseView { NOTE(7), LUCKY_NUMBER(8), SETTINGS(9), - ABOUT(10) + ABOUT(10), + SCHOOL(11) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt index c772466f..b2521902 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageModule.kt @@ -9,13 +9,12 @@ import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment @Suppress("unused") -@Module +@Module(includes = [MessageModule.Static::class]) abstract class MessageModule { @Module - companion object { + object Static { - @JvmStatic @PerFragment @Provides fun provideMessageAdapter(fragment: MessageFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager) 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 93ef502f..4f881e8f 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 @@ -143,7 +143,7 @@ class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.Titl } override fun notifyParentMessageDeleted(message: Message) { - fragmentManager?.fragments?.forEach { if (it is MessageFragment) it.onDeleteMessage(message) } + parentFragmentManager.fragments.forEach { if (it is MessageFragment) it.onDeleteMessage(message) } } override fun onSaveInstanceState(outState: Bundle) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt index 8d26bfc3..7a9625c0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreFragment.kt @@ -18,8 +18,9 @@ import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.message.MessageFragment import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment import io.github.wulkanowy.ui.modules.note.NoteFragment +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment import io.github.wulkanowy.ui.modules.settings.SettingsFragment -import io.github.wulkanowy.ui.modules.teacher.TeacherFragment +import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment import io.github.wulkanowy.utils.getCompatDrawable import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_more.* @@ -55,8 +56,8 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai override val mobileDevicesRes: Pair? get() = context?.run { getString(R.string.mobile_devices_title) to getCompatDrawable(R.drawable.ic_more_mobile_devices) } - override val teachersRes: Pair? - get() = context?.run { getString(R.string.teachers_title) to getCompatDrawable((R.drawable.ic_more_teacher)) } + override val schoolAndTeachersRes: Pair? + get() = context?.run { getString(R.string.schoolandteachers_title) to getCompatDrawable((R.drawable.ic_more_schoolandteachers)) } override val settingsRes: Pair? get() = context?.run { getString(R.string.settings_title) to getCompatDrawable(R.drawable.ic_more_settings) } @@ -110,8 +111,8 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai (activity as? MainActivity)?.pushView(MobileDeviceFragment.newInstance()) } - override fun openTeachersView() { - (activity as? MainActivity)?.pushView(TeacherFragment.newInstance()) + override fun openSchoolAndTeachersView() { + (activity as? MainActivity)?.pushView(SchoolAndTeachersFragment.newInstance()) } override fun openSettingsView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt index b77b7c01..096f89e9 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt @@ -31,7 +31,7 @@ class MorePresenter @Inject constructor( noteRes?.first -> openNoteView() luckyNumberRes?.first -> openLuckyNumberView() mobileDevicesRes?.first -> openMobileDevicesView() - teachersRes?.first -> openTeachersView() + schoolAndTeachersRes?.first -> openSchoolAndTeachersView() settingsRes?.first -> openSettingsView() aboutRes?.first -> openAboutView() } @@ -52,7 +52,7 @@ class MorePresenter @Inject constructor( noteRes?.let { MoreItem(it.first, it.second) }, luckyNumberRes?.let { MoreItem(it.first, it.second) }, mobileDevicesRes?.let { MoreItem(it.first, it.second) }, - teachersRes?.let { MoreItem(it.first, it.second) }, + schoolAndTeachersRes?.let { MoreItem(it.first, it.second) }, settingsRes?.let { MoreItem(it.first, it.second) }, aboutRes?.let { MoreItem(it.first, it.second) }) ) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt index 247705de..41008176 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt @@ -15,7 +15,7 @@ interface MoreView : BaseView { val mobileDevicesRes: Pair? - val teachersRes: Pair? + val schoolAndTeachersRes: Pair? val settingsRes: Pair? @@ -41,5 +41,5 @@ interface MoreView : BaseView { fun openMobileDevicesView() - fun openTeachersView() + fun openSchoolAndTeachersView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersChildView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersChildView.kt new file mode 100644 index 00000000..b5eedb6f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersChildView.kt @@ -0,0 +1,8 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers + +interface SchoolAndTeachersChildView { + + fun notifyParentDataLoaded() + + fun onParentLoadData(forceRefresh: Boolean) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersFragment.kt new file mode 100644 index 00000000..5f9c0b9a --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersFragment.kt @@ -0,0 +1,87 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.View.INVISIBLE +import android.view.View.VISIBLE +import android.view.ViewGroup +import io.github.wulkanowy.R +import io.github.wulkanowy.ui.base.BaseFragment +import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment +import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment +import io.github.wulkanowy.utils.dpToPx +import io.github.wulkanowy.utils.setOnSelectPageListener +import kotlinx.android.synthetic.main.fragment_schoolandteachers.* +import javax.inject.Inject + +class SchoolAndTeachersFragment : BaseFragment(), SchoolAndTeachersView, MainView.TitledView { + + @Inject + lateinit var presenter: SchoolAndTeachersPresenter + + @Inject + lateinit var pagerAdapter: BaseFragmentPagerAdapter + + companion object { + fun newInstance() = SchoolAndTeachersFragment() + } + + override val titleStringId: Int get() = R.string.schoolandteachers_title + + override val currentPageIndex get() = schoolandteachersViewPager.currentItem + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_schoolandteachers, container, false) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + presenter.onAttachView(this) + } + + override fun initView() { + with(pagerAdapter) { + containerId = schoolandteachersViewPager.id + addFragmentsWithTitle(mapOf( + SchoolFragment.newInstance() to getString(R.string.school_title), + TeacherFragment.newInstance() to getString(R.string.teachers_title) + )) + } + + with(schoolandteachersViewPager) { + adapter = pagerAdapter + offscreenPageLimit = 2 + setOnSelectPageListener(presenter::onPageSelected) + } + + with(schoolandteachersTabLayout) { + setupWithViewPager(schoolandteachersViewPager) + setElevationCompat(context.dpToPx(4f)) + } + } + + override fun showContent(show: Boolean) { + schoolandteachersViewPager.visibility = if (show) VISIBLE else INVISIBLE + schoolandteachersTabLayout.visibility = if (show) VISIBLE else INVISIBLE + } + + override fun showProgress(show: Boolean) { + schoolandteachersProgress.visibility = if (show) VISIBLE else INVISIBLE + } + + fun onChildFragmentLoaded() { + presenter.onChildViewLoaded() + } + + override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) { + (pagerAdapter.getFragmentInstance(index) as? SchoolAndTeachersChildView)?.onParentLoadData(forceRefresh) + } + + override fun onDestroyView() { + presenter.onDetachView() + super.onDestroyView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersModule.kt new file mode 100644 index 00000000..62803a28 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersModule.kt @@ -0,0 +1,31 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers + +import dagger.Module +import dagger.Provides +import dagger.android.ContributesAndroidInjector +import io.github.wulkanowy.di.scopes.PerChildFragment +import io.github.wulkanowy.di.scopes.PerFragment +import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter +import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment +import io.github.wulkanowy.ui.modules.schoolandteachers.teacher.TeacherFragment + +@Suppress("unused") +@Module(includes = [SchoolAndTeachersModule.Static::class]) +abstract class SchoolAndTeachersModule { + + @Module + object Static { + + @PerFragment + @Provides + fun provideSchoolAndTeachersAdapter(fragment: SchoolAndTeachersFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager) + } + + @PerChildFragment + @ContributesAndroidInjector + abstract fun provideSchoolFragment(): SchoolFragment + + @PerChildFragment + @ContributesAndroidInjector + abstract fun provideTeacherFragment(): TeacherFragment +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersPresenter.kt new file mode 100644 index 00000000..1856803c --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersPresenter.kt @@ -0,0 +1,47 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers + +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.SchedulersProvider +import io.reactivex.Completable +import timber.log.Timber +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +class SchoolAndTeachersPresenter @Inject constructor( + schedulers: SchedulersProvider, + errorHandler: ErrorHandler, + studentRepository: StudentRepository +) : BasePresenter(errorHandler, studentRepository, schedulers) { + + override fun onAttachView(view: SchoolAndTeachersView) { + super.onAttachView(view) + disposable.add(Completable.timer(150, TimeUnit.MILLISECONDS, schedulers.mainThread) + .subscribe { + view.initView() + Timber.i("Message view was initialized") + loadData() + }) + } + + fun onPageSelected(index: Int) { + loadChild(index) + } + + private fun loadData() { + view?.run { loadChild(currentPageIndex) } + } + + private fun loadChild(index: Int, forceRefresh: Boolean = false) { + Timber.i("Load schoolandteachers child view index: $index") + view?.notifyChildLoadData(index, forceRefresh) + } + + fun onChildViewLoaded() { + view?.apply { + showContent(true) + showProgress(false) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersView.kt new file mode 100644 index 00000000..594441ec --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersView.kt @@ -0,0 +1,16 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers + +import io.github.wulkanowy.ui.base.BaseView + +interface SchoolAndTeachersView : BaseView { + + val currentPageIndex: Int + + fun initView() + + fun showContent(show: Boolean) + + fun showProgress(show: Boolean) + + fun notifyChildLoadData(index: Int, forceRefresh: Boolean) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt new file mode 100644 index 00000000..92f74ca8 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt @@ -0,0 +1,95 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers.school + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.School +import io.github.wulkanowy.ui.base.BaseFragment +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment +import io.github.wulkanowy.utils.dialPhone +import io.github.wulkanowy.utils.openMapLocation +import kotlinx.android.synthetic.main.fragment_school.* +import javax.inject.Inject + +class SchoolFragment : BaseFragment(), SchoolView, MainView.TitledView, SchoolAndTeachersChildView { + + @Inject + lateinit var presenter: SchoolPresenter + + override val titleStringId get() = R.string.school_title + + companion object { + fun newInstance() = SchoolFragment() + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_school, container, false) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + presenter.onAttachView(this) + } + + override fun initView() { + schoolSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } + + schoolAddressButton.setOnClickListener { presenter.onAddressSelected() } + schoolTelephoneButton.setOnClickListener { presenter.onTelephoneSelected() } + } + + override fun updateData(data: School) { + schoolName.text = data.name + schoolAddress.text = data.address.ifBlank { "-" } + schoolAddressButton.visibility = if (data.address.isNotBlank()) View.VISIBLE else View.GONE + schoolTelephone.text = data.contact.ifBlank { "-" } + schoolTelephoneButton.visibility = if (data.contact.isNotBlank()) View.VISIBLE else View.GONE + schoolHeadmaster.text = data.headmaster + schoolPedagogue.text = data.pedagogue + } + + override fun showEmpty(show: Boolean) { + schoolEmpty.visibility = if (show) View.VISIBLE else View.GONE + } + + override fun showProgress(show: Boolean) { + schoolProgress.visibility = if (show) View.VISIBLE else View.GONE + } + + override fun enableSwipe(enable: Boolean) { + schoolSwipe.isEnabled = enable + } + + override fun showContent(show: Boolean) { + schoolContent.visibility = if (show) View.VISIBLE else View.GONE + } + + override fun hideRefresh() { + schoolSwipe.isRefreshing = false + } + + override fun notifyParentDataLoaded() { + (parentFragment as? SchoolAndTeachersFragment)?.onChildFragmentLoaded() + } + + override fun onParentLoadData(forceRefresh: Boolean) { + presenter.onParentViewLoadData(forceRefresh) + } + + override fun onDestroyView() { + presenter.onDetachView() + super.onDestroyView() + } + + override fun openMapsLocation(location: String) { + context?.openMapLocation(location) + } + + override fun dialPhone(phone: String) { + context?.dialPhone(phone) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolPresenter.kt new file mode 100644 index 00000000..2b0a37b1 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolPresenter.kt @@ -0,0 +1,84 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers.school + +import io.github.wulkanowy.data.repositories.school.SchoolRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +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 timber.log.Timber +import javax.inject.Inject + +class SchoolPresenter @Inject constructor( + schedulers: SchedulersProvider, + errorHandler: ErrorHandler, + studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository, + private val schoolRepository: SchoolRepository, + private val analytics: FirebaseAnalyticsHelper +) : BasePresenter(errorHandler, studentRepository, schedulers) { + + private var address: String? = null + + private var contact: String? = null + + override fun onAttachView(view: SchoolView) { + super.onAttachView(view) + view.initView() + Timber.i("School view was initialized") + loadData() + } + + fun onSwipeRefresh() { + loadData(true) + } + + fun onParentViewLoadData(forceRefresh: Boolean) { + loadData(forceRefresh) + } + + fun onAddressSelected() { + address?.let{ view?.openMapsLocation(it) } + } + + fun onTelephoneSelected() { + contact?.let { view?.dialPhone(it) } + } + + private fun loadData(forceRefresh: Boolean = false) { + Timber.i("Loading school info started") + disposable.add(studentRepository.getCurrentStudent() + .flatMap { semesterRepository.getCurrentSemester(it) } + .flatMapMaybe { schoolRepository.getSchoolInfo(it, forceRefresh) } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .doFinally { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) + notifyParentDataLoaded() + } + }.subscribe({ + Timber.i("Loading teachers result: Success") + view?.run { + address = it.address.ifBlank { null } + contact = it.contact.ifBlank { null } + updateData(it) + showContent(true) + showEmpty(false) + } + analytics.logEvent("load_school", "force_refresh" to forceRefresh) + }, { + Timber.i("Loading school result: An exception occurred") + errorHandler.dispatch(it) + }, { + Timber.i("Loading school result: No school info found") + view?.run { + showContent(false) + showEmpty(true) + } + })) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolView.kt new file mode 100644 index 00000000..39e7b805 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolView.kt @@ -0,0 +1,26 @@ +package io.github.wulkanowy.ui.modules.schoolandteachers.school + +import io.github.wulkanowy.data.db.entities.School +import io.github.wulkanowy.ui.base.BaseView +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView + +interface SchoolView : BaseView, SchoolAndTeachersChildView { + + fun initView() + + fun updateData(data: School) + + fun showEmpty(show: Boolean) + + fun showProgress(show: Boolean) + + fun enableSwipe(enable: Boolean) + + fun showContent(show: Boolean) + + fun hideRefresh() + + fun openMapsLocation(location: String) + + fun dialPhone(phone: String) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherFragment.kt similarity index 84% rename from app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherFragment.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherFragment.kt index d096f23b..842e50fe 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherFragment.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.teacher +package io.github.wulkanowy.ui.modules.schoolandteachers.teacher import android.os.Bundle import android.view.LayoutInflater @@ -11,10 +11,13 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.R import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment import kotlinx.android.synthetic.main.fragment_teacher.* import javax.inject.Inject -class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView { +class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView, SchoolAndTeachersChildView { + @Inject lateinit var presenter: TeacherPresenter @@ -86,6 +89,14 @@ class TeacherFragment : BaseFragment(), TeacherView, MainView.TitledView { teacherSwipe.isRefreshing = false } + override fun notifyParentDataLoaded() { + (parentFragment as? SchoolAndTeachersFragment)?.onChildFragmentLoaded() + } + + override fun onParentLoadData(forceRefresh: Boolean) { + presenter.onParentViewLoadData(forceRefresh) + } + override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherItem.kt similarity index 97% rename from app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherItem.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherItem.kt index c5625138..36831774 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherItem.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.teacher +package io.github.wulkanowy.ui.modules.schoolandteachers.teacher import android.annotation.SuppressLint import android.view.View diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherPresenter.kt similarity index 89% rename from app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherPresenter.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherPresenter.kt index 8b504f8b..aabcff28 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherPresenter.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.teacher +package io.github.wulkanowy.ui.modules.schoolandteachers.teacher import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.data.repositories.student.StudentRepository @@ -14,7 +14,6 @@ class TeacherPresenter @Inject constructor( schedulers: SchedulersProvider, errorHandler: ErrorHandler, studentRepository: StudentRepository, - private val semesterRepository: SemesterRepository, private val teacherRepository: TeacherRepository, private val analytics: FirebaseAnalyticsHelper @@ -31,12 +30,16 @@ class TeacherPresenter @Inject constructor( loadData(true) } + fun onParentViewLoadData(forceRefresh: Boolean) { + loadData(forceRefresh) + } + private fun loadData(forceRefresh: Boolean = false) { Timber.i("Loading teachers data started") disposable.add(studentRepository.getCurrentStudent() .flatMap { semesterRepository.getCurrentSemester(it) } .flatMap { teacherRepository.getTeachers(it, forceRefresh) } - .map { it.filter { teacher -> teacher.name.isNotBlank() } } + .map { it.filter { teacher -> teacher.name.isNotBlank() } } .map { items -> items.map { TeacherItem(it, view?.noSubjectString.orEmpty()) } } .subscribeOn(schedulers.backgroundThread) .observeOn(schedulers.mainThread) @@ -45,6 +48,7 @@ class TeacherPresenter @Inject constructor( hideRefresh() showProgress(false) enableSwipe(true) + notifyParentDataLoaded() } }.subscribe({ Timber.i("Loading teachers result: Success") diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherView.kt similarity index 69% rename from app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherView.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherView.kt index 91fa995d..2cc1139c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/teacher/TeacherView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherView.kt @@ -1,9 +1,10 @@ -package io.github.wulkanowy.ui.modules.teacher +package io.github.wulkanowy.ui.modules.schoolandteachers.teacher import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import io.github.wulkanowy.ui.base.BaseView +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView -interface TeacherView : BaseView { +interface TeacherView : BaseView, SchoolAndTeachersChildView { val isViewEmpty: Boolean diff --git a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt index a941c6fa..5110b067 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt @@ -2,6 +2,7 @@ package io.github.wulkanowy.utils import android.content.Context import android.content.Intent +import android.net.Uri import android.util.DisplayMetrics.DENSITY_DEFAULT import androidx.annotation.AttrRes import androidx.annotation.ColorInt @@ -31,4 +32,26 @@ fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) - } } +fun Context.openEmail(chooserTitle: String, email: String, subject: String?, body: String?) { + val emailIntent = Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", email, null)) + emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(email)) + if (subject != null) emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject) + if (body != null) emailIntent.putExtra(Intent.EXTRA_TEXT, body) + startActivity(Intent.createChooser(emailIntent, chooserTitle)) +} + +fun Context.openMapLocation(location: String) { + val intentUri = Uri.parse("geo:0,0?q=${Uri.encode(location)}") + val intent = Intent(Intent.ACTION_VIEW, intentUri) + if (intent.resolveActivity(packageManager) != null) { + startActivity(intent) + } +} + +fun Context.dialPhone(phone: String) { + val intentUri = Uri.parse("tel:$phone") + val intent = Intent(Intent.ACTION_DIAL, intentUri) + startActivity(intent) +} + fun Context.dpToPx(dp: Float) = dp * resources.displayMetrics.densityDpi / DENSITY_DEFAULT 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 1fc3185c..0b71c964 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt @@ -11,6 +11,7 @@ import io.github.wulkanowy.ui.modules.main.MainView 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.settings.SettingsFragment import io.github.wulkanowy.ui.modules.timetable.TimetableFragment @@ -27,6 +28,7 @@ fun Fragment.toSection(): MainView.Section? { is LuckyNumberFragment -> MainView.Section.LUCKY_NUMBER is SettingsFragment -> MainView.Section.SETTINGS is AboutFragment -> MainView.Section.ABOUT + is SchoolAndTeachersFragment -> MainView.Section.SCHOOL else -> null } } diff --git a/app/src/main/play/release-notes/pl-PL/default.txt b/app/src/main/play/release-notes/pl-PL/default.txt index c656698c..68608c38 100644 --- a/app/src/main/play/release-notes/pl-PL/default.txt +++ b/app/src/main/play/release-notes/pl-PL/default.txt @@ -1,10 +1,9 @@ -Wersja 0.11.0 +Wersja 0.12.0 -- ciemny motyw dla widżetów -- lista nauczycieli -- statystyka ocen punktowych ucznia na tle klasy i lepsze wyświetlanie punktów na liście ocen -- ładniejsza nawigacja między datami w planie lekcji i nie tylko -- naprawiony szczęśliwy numerek -- naprawione logowanie do dziennika Resman +- wsparcie dla dziennika Lubelskiego Portalu Oświatowego +- naprawa problemów z wyświetlaniem ocen punktowych +- automatyczne przełączanie motywu na androidzie 10 +- wyświetlanie pomocy przy problemach z logowaniem +- wyświetlanie informacji o szkole Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases diff --git a/app/src/main/res/drawable/ic_more_schoolandteachers.xml b/app/src/main/res/drawable/ic_more_schoolandteachers.xml new file mode 100644 index 00000000..9cb9aee0 --- /dev/null +++ b/app/src/main/res/drawable/ic_more_schoolandteachers.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_more_teacher.xml b/app/src/main/res/drawable/ic_more_teacher.xml deleted file mode 100644 index bc8f93e4..00000000 --- a/app/src/main/res/drawable/ic_more_teacher.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_school_directions.xml b/app/src/main/res/drawable/ic_school_directions.xml new file mode 100644 index 00000000..c48db1da --- /dev/null +++ b/app/src/main/res/drawable/ic_school_directions.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_school_phone.xml b/app/src/main/res/drawable/ic_school_phone.xml new file mode 100644 index 00000000..7e3d7991 --- /dev/null +++ b/app/src/main/res/drawable/ic_school_phone.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 84007c77..d07dbbd8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -10,7 +10,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> - + + + + + + + + + + + + + + @@ -127,7 +192,8 @@ android:id="@+id/loginFormHost" android:layout_width="match_parent" android:layout_height="wrap_content" - tools:ignore="LabelFor" /> + android:editable="false" + tools:ignore="Deprecated,LabelFor" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + android:text="@string/send_message_title" + app:icon="@drawable/ic_menu_message_write" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_schoolandteachers.xml b/app/src/main/res/layout/fragment_schoolandteachers.xml new file mode 100644 index 00000000..2b3f2203 --- /dev/null +++ b/app/src/main/res/layout/fragment_schoolandteachers.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_teacher.xml b/app/src/main/res/layout/fragment_teacher.xml index af3b76a1..01cf8726 100644 --- a/app/src/main/res/layout/fragment_teacher.xml +++ b/app/src/main/res/layout/fragment_teacher.xml @@ -18,6 +18,7 @@ android:layout_height="match_parent"> @@ -36,7 +37,7 @@ diff --git a/app/src/main/res/layout/item_teacher.xml b/app/src/main/res/layout/item_teacher.xml index 55679dce..3bac0573 100644 --- a/app/src/main/res/layout/item_teacher.xml +++ b/app/src/main/res/layout/item_teacher.xml @@ -1,5 +1,4 @@ + tools:context=".ui.modules.schoolandteachers.teacher.TeacherItem"> + + + Motyw systemu + Jasny + Ciemny + Czarny (AMOLED) + + diff --git a/app/src/main/res/values-pl/value_prefernces.xml b/app/src/main/res/values-pl/preferences_values.xml similarity index 88% rename from app/src/main/res/values-pl/value_prefernces.xml rename to app/src/main/res/values-pl/preferences_values.xml index 868ead4d..e4c30eb0 100644 --- a/app/src/main/res/values-pl/value_prefernces.xml +++ b/app/src/main/res/values-pl/preferences_values.xml @@ -1,5 +1,5 @@ - + 15 minut 30 minut @@ -10,7 +10,7 @@ 24 godziny - + Jasny Ciemny Czarny (AMOLED) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 33e0a787..8ff4d307 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -36,6 +36,10 @@ Symbol znajdziesz na stronie dziennika w Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne Wybierz uczniów do zalogowania w aplikacji Polityka prywatności + Problemy z logowaniem? Napisz do nas! + Email + Discord + Wyślij email @@ -217,6 +221,21 @@ PIN + + Szkoła i nauczyciele + + + + Szkoła + Nazwa szkoły + Adres szkoły + Telefon + Imię i nazwisko dyrektora + Imię i nazwisko pedagoga + Pokaż na mpaie + Zadzwoń + + Nauczyciele Brak informacji o nauczycielach diff --git a/app/src/main/res/values-v29/preferences_defaults.xml b/app/src/main/res/values-v29/preferences_defaults.xml new file mode 100644 index 00000000..bb573d66 --- /dev/null +++ b/app/src/main/res/values-v29/preferences_defaults.xml @@ -0,0 +1,4 @@ + + + system + diff --git a/app/src/main/res/values-v29/preferences_values.xml b/app/src/main/res/values-v29/preferences_values.xml new file mode 100644 index 00000000..f27c1c69 --- /dev/null +++ b/app/src/main/res/values-v29/preferences_values.xml @@ -0,0 +1,15 @@ + + + + System theme + Light + Dark + Black (AMOLED) + + + system + light + dark + black + + diff --git a/app/src/main/res/values/api_endpoints.xml b/app/src/main/res/values/api_hosts.xml similarity index 79% rename from app/src/main/res/values/api_endpoints.xml rename to app/src/main/res/values/api_hosts.xml index e07f2b4b..df42f592 100644 --- a/app/src/main/res/values/api_endpoints.xml +++ b/app/src/main/res/values/api_hosts.xml @@ -1,17 +1,19 @@ - + Vulcan Opolska eSzkoła Gdańska Platforma Edukacyjna + Lubelski Portal Oświatowy EduNet Miasta Tarnowa ResMan Rzeszów Fakelog - + https://vulcan.net.pl https://eszkola.opolskie.pl https://edu.gdansk.pl + https://edu.lublin.eu https://umt.tarnow.pl https://resman.pl http://fakelog.cf diff --git a/app/src/main/res/values/preferences_defaults.xml b/app/src/main/res/values/preferences_defaults.xml new file mode 100644 index 00000000..53b5c2ab --- /dev/null +++ b/app/src/main/res/values/preferences_defaults.xml @@ -0,0 +1,18 @@ + + + 0 + true + only_one_semester + false + false + light + vulcan + true + 60 + false + true + false + 0.0 + 0.0 + true + diff --git a/app/src/main/res/values/value_prefernces.xml b/app/src/main/res/values/preferences_values.xml similarity index 91% rename from app/src/main/res/values/value_prefernces.xml rename to app/src/main/res/values/preferences_values.xml index 97396baa..289f14f3 100644 --- a/app/src/main/res/values/value_prefernces.xml +++ b/app/src/main/res/values/preferences_values.xml @@ -1,5 +1,5 @@ - + @string/grade_title @string/attendance_title @@ -13,12 +13,12 @@ 3 - + Light Dark Black (AMOLED) - + light dark black diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 27e43dc5..4660f9fe 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -36,6 +36,12 @@ The symbol can be found on the register page in Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne Select students to log in to the application Privacy policy + Trouble signing in? Contact us! + Email + Discord + Send email + Zgłoszenie: Problemy z logowaniem + Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\n\nOpis problemu: @@ -201,6 +207,21 @@ PIN + + School and teachers + + + + School + School name + School address + Telephone + Name of headmaster + Name of pedagogue + Show on map + Call + + Teachers No info about teachers diff --git a/app/src/main/res/xml/scheme_preferences.xml b/app/src/main/res/xml/scheme_preferences.xml index d762066a..28229f41 100644 --- a/app/src/main/res/xml/scheme_preferences.xml +++ b/app/src/main/res/xml/scheme_preferences.xml @@ -4,7 +4,7 @@ app:iconSpaceReserved="false" app:title="@string/pref_view_header"> @@ -81,7 +81,7 @@ app:iconSpaceReserved="false" app:title="@string/pref_other_header"> diff --git a/build.gradle b/build.gradle index c3abf9ad..6c004f6f 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.android.tools.build:gradle:3.5.1' classpath 'com.google.gms:google-services:4.3.2' - classpath "io.fabric.tools:gradle:1.31.1" + classpath "io.fabric.tools:gradle:1.31.2" classpath "com.github.triplet.gradle:play-publisher:2.4.2" classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8" classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"