mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-02-20 21:34:45 +01:00
Merge branch 'release/0.19.0'
This commit is contained in:
commit
9f87b92937
@ -14,7 +14,7 @@ cache:
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- 0.18.3
|
||||
- 0.19.0
|
||||
|
||||
android:
|
||||
licenses:
|
||||
|
@ -17,8 +17,8 @@ android {
|
||||
testApplicationId "io.github.tests.wulkanowy"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 29
|
||||
versionCode 62
|
||||
versionName "0.18.3"
|
||||
versionCode 63
|
||||
versionName "0.19.0"
|
||||
multiDexEnabled true
|
||||
resValue "string", "app_name", "Wulkanowy"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@ -77,8 +77,8 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
viewBinding {
|
||||
enabled = true
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
@ -124,14 +124,14 @@ configurations.all {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:0.18.3"
|
||||
implementation "io.github.wulkanowy:sdk:0.19.0"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation "androidx.core:core-ktx:1.2.0"
|
||||
implementation "androidx.activity:activity-ktx:1.1.0"
|
||||
implementation "androidx.appcompat:appcompat:1.2.0-rc01"
|
||||
implementation "androidx.appcompat:appcompat-resources:1.1.0"
|
||||
implementation "androidx.fragment:fragment-ktx:1.2.4"
|
||||
implementation "androidx.fragment:fragment-ktx:1.2.5"
|
||||
implementation "androidx.annotation:annotation:1.1.0"
|
||||
implementation "androidx.multidex:multidex:2.0.1"
|
||||
|
||||
@ -142,7 +142,7 @@ dependencies {
|
||||
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
||||
implementation "com.google.android.material:material:1.1.0"
|
||||
implementation "com.github.wulkanowy:material-chips-input:2.0.1"
|
||||
implementation "com.github.wulkanowy:material-chips-input:2.1.1"
|
||||
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
||||
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
|
||||
|
||||
@ -180,12 +180,13 @@ dependencies {
|
||||
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
|
||||
implementation "io.coil-kt:coil:0.11.0"
|
||||
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
||||
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
|
||||
|
||||
playImplementation 'com.google.firebase:firebase-analytics:17.4.2'
|
||||
playImplementation 'com.google.firebase:firebase-analytics:17.4.3'
|
||||
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.7'
|
||||
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.7"
|
||||
playImplementation 'com.google.firebase:firebase-messaging:20.2.0'
|
||||
playImplementation 'com.google.firebase:firebase-crashlytics:17.0.0'
|
||||
playImplementation 'com.google.firebase:firebase-crashlytics:17.0.1'
|
||||
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
||||
|
||||
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
||||
|
@ -1741,4 +1741,4 @@
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd101f5a26a024f62e6fee161e421b882')"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1768
app/schemas/io.github.wulkanowy.data.db.AppDatabase/26.json
Normal file
1768
app/schemas/io.github.wulkanowy.data.db.AppDatabase/26.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -120,23 +120,23 @@ class Migration13Test : AbstractMigrationTest() {
|
||||
assertEquals(2, first.diaryId)
|
||||
}
|
||||
|
||||
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
|
||||
assertTrue { it.single { it.second }.second }
|
||||
assertEquals(1970, it[0].first.schoolYear)
|
||||
assertEquals(of(1970, 1, 1), it[0].first.end)
|
||||
assertEquals(of(1970, 1, 1), it[0].first.start)
|
||||
assertFalse(it[0].second)
|
||||
assertFalse(it[1].second)
|
||||
assertFalse(it[2].second)
|
||||
assertTrue(it[3].second)
|
||||
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let { semesters ->
|
||||
assertTrue { semesters.single { it.second }.second }
|
||||
assertEquals(1970, semesters[0].first.schoolYear)
|
||||
assertEquals(of(1970, 1, 1), semesters[0].first.end)
|
||||
assertEquals(of(1970, 1, 1), semesters[0].first.start)
|
||||
assertFalse(semesters[0].second)
|
||||
assertFalse(semesters[1].second)
|
||||
assertFalse(semesters[2].second)
|
||||
assertTrue(semesters[3].second)
|
||||
}
|
||||
|
||||
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
|
||||
assertTrue { it.single { it.second }.second }
|
||||
assertFalse(it[0].second)
|
||||
assertFalse(it[1].second)
|
||||
assertFalse(it[2].second)
|
||||
assertTrue(it[3].second)
|
||||
getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let { semesters ->
|
||||
assertTrue { semesters.single { it.second }.second }
|
||||
assertFalse(semesters[0].second)
|
||||
assertFalse(semesters[1].second)
|
||||
assertFalse(semesters[2].second)
|
||||
assertTrue(semesters[3].second)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import org.threeten.bp.LocalDate.of
|
||||
import kotlin.test.assertEquals
|
||||
@ -35,9 +36,18 @@ class AttendanceLocalTest {
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
attendanceLocal.saveAttendance(listOf(
|
||||
Attendance(1, 2, 3, of(2018, 9, 10), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name),
|
||||
Attendance(1, 2, 3, of(2018, 9, 14), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.WAITING.name),
|
||||
Attendance(1, 2, 3, of(2018, 9, 17), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name)
|
||||
getAttendanceEntity(
|
||||
of(2018, 9, 10),
|
||||
SentExcuseStatus.ACCEPTED
|
||||
),
|
||||
getAttendanceEntity(
|
||||
of(2018, 9, 14),
|
||||
SentExcuseStatus.WAITING
|
||||
),
|
||||
getAttendanceEntity(
|
||||
of(2018, 9, 17),
|
||||
SentExcuseStatus.ACCEPTED
|
||||
)
|
||||
))
|
||||
|
||||
val attendance = attendanceLocal
|
||||
@ -50,4 +60,25 @@ class AttendanceLocalTest {
|
||||
assertEquals(attendance[0].date, of(2018, 9, 10))
|
||||
assertEquals(attendance[1].date, of(2018, 9, 14))
|
||||
}
|
||||
|
||||
private fun getAttendanceEntity(
|
||||
date: LocalDate,
|
||||
excuseStatus: SentExcuseStatus
|
||||
) = Attendance(
|
||||
studentId = 1,
|
||||
diaryId = 2,
|
||||
timeId = 3,
|
||||
date = date,
|
||||
number = 0,
|
||||
subject = "",
|
||||
name = "",
|
||||
presence = false,
|
||||
absence = false,
|
||||
exemption = false,
|
||||
lateness = false,
|
||||
excused = false,
|
||||
deleted = false,
|
||||
excusable = false,
|
||||
excuseStatus = excuseStatus.name
|
||||
)
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.content.Context
|
||||
import timber.log.Timber
|
||||
|
||||
open class TimberTreeNoOp : Timber.Tree() {
|
||||
|
94
app/src/main/assets/message-print-page.html
Normal file
94
app/src/main/assets/message-print-page.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!doctype html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>%SUBJECT% | Wulkanowy</title>
|
||||
<style>
|
||||
@page {
|
||||
margin: 2.5cm;
|
||||
size: A4;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.title {
|
||||
line-height: 1.5;
|
||||
letter-spacing: 1pt;
|
||||
font-size: 24pt;
|
||||
font-weight: 200;
|
||||
margin: 0 0 0.5cm;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin: 0.5cm 0;
|
||||
}
|
||||
|
||||
.info div {
|
||||
font-size: 14pt;
|
||||
font-weight: 400;
|
||||
margin: 0.5cm 0;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight: 200;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1pt;
|
||||
font-size: 10pt;
|
||||
margin: 0;
|
||||
margin-bottom: 0.25cm;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 0.5cm;
|
||||
font-size: 14pt;
|
||||
font-weight: 400;
|
||||
text-align: justify;
|
||||
font-family: serif;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.content p {
|
||||
page-break-after: auto;
|
||||
page-break-inside: auto;
|
||||
margin-bottom: 0.6cm;
|
||||
}
|
||||
|
||||
.footer {
|
||||
font-size: 11pt;
|
||||
font-weight: 200;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: rgba(0, 0, 0, 0.5)
|
||||
margin: 0;
|
||||
margin-bottom: 0.5cm;
|
||||
}
|
||||
|
||||
.footer .logo {
|
||||
height: 0.5cm;
|
||||
width: 0.5cm;
|
||||
display: block;
|
||||
margin-right: 0.2cm;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="title">%SUBJECT%</h1>
|
||||
<hr>
|
||||
<div class="info">
|
||||
%INFO%
|
||||
</div>
|
||||
<div class="footer">
|
||||
<img src="wulkanowy-logo-black.svg" class="logo">
|
||||
Wulkanowy Dzienniczek
|
||||
</div>
|
||||
<hr>
|
||||
<div class="content">
|
||||
<h4>Treść wiadomości</h4>
|
||||
%CONTENT%
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
74
app/src/main/assets/wulkanowy-logo-black.svg
Normal file
74
app/src/main/assets/wulkanowy-logo-black.svg
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 1024 1024"
|
||||
xml:space="preserve"
|
||||
width="1024"
|
||||
height="1024"><metadata
|
||||
id="metadata15"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs13" /><style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{fill:#D32F2F;}
|
||||
.st1{fill:#AD2A2A;}
|
||||
.st2{fill:#FFFFFF;}
|
||||
</style><g
|
||||
id="layer4"
|
||||
style="display:none;fill:#808080"><rect
|
||||
id="XMLID_57_"
|
||||
x="0"
|
||||
y="0"
|
||||
class="st0"
|
||||
width="3584"
|
||||
height="1024"
|
||||
style="display:inline;fill:#808080;stroke-width:1.02195609" /></g><g
|
||||
id="layer3"
|
||||
style="display:none;fill:#808080"><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="M 3046.8164,390.66602 3134.3164,542 v 91.33398 L 3524.9824,1024 H 3584 V 732.18359 L 3242.4824,390.66602 h -23.666 l -53.0352,94.63086 -94.6308,-94.63086 z"
|
||||
id="path18992" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="m 2746.9824,390.66602 62,242.66796 L 3199.6484,1024 H 3584 V 940.68359 L 3033.9824,390.66602 h -21 l -21.9043,90.92773 -90.9277,-90.92773 h -18.5 l -25.4043,88.26367 -88.2637,-88.26367 z"
|
||||
id="path18990" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="m 2620.8164,387.33398 c -18.6667,0 -35.1667,4.60982 -49.5,13.83204 -14.3333,9.11111 -25.4451,22.22287 -33.334,39.33398 -7.7778,17 -11.666,36.5549 -11.666,58.66602 v 25 c 0,34.44444 8.7216,61.83463 26.166,82.16796 L 2970.1484,1024 h 323.168 l -623.166,-623.16602 c -14.2222,-9 -30.6673,-13.5 -49.334,-13.5 z"
|
||||
id="path18988" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="M 2293.4824,390.66602 V 633.33398 L 2684.1484,1024 h 423.336 l -633.334,-633.33398 h -20.334 v 139.66601 l -139.666,-139.66601 z"
|
||||
id="path18984" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="M 1864.8164,390.66602 V 633.33398 L 2255.4824,1024 h 413.334 l -633.334,-633.33398 h -25.832 l -60.584,63.75 -63.75,-63.75 z"
|
||||
id="path18978" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="M 1684.8164,390.66602 V 633.33398 L 2075.4824,1024 h 263.334 l -633.334,-633.33398 z"
|
||||
id="path18976" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="m 1133.6504,390.66602 62,242.66796 L 1586.3164,1024 h 467.668 l -633.334,-633.33398 h -21 l -21.9043,90.92773 -90.9277,-90.92773 h -18.5 l -25.4043,88.26367 -88.2637,-88.26367 z"
|
||||
id="path19059" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="m 1456.4824,390.66602 v 167.16796 c 0.5556,24.66667 8.5007,44 23.834,58 L 1888.4824,1024 h 372.168 l -633.334,-633.33398 h -20.666 V 520.5 l -129.834,-129.83398 z"
|
||||
id="path18966" /><path
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;display:inline;fill:#808080;fill-opacity:1;stroke:none"
|
||||
d="M 2146.3164,390.66602 2054.4824,633.33398 2445.1484,1024 h 354.002 l -633.334,-633.33398 z"
|
||||
id="path18982" /><path
|
||||
style="display:inline;fill:#808080;stroke-width:0.78179646"
|
||||
d="M 637.15234,214.95703 487.75,364.35742 466.01562,386.0918 c 0.31273,0.31271 0.54872,0.54666 0.70508,0.85937 0.0782,0.23454 0.23432,0.54671 0.3125,0.78125 0.31272,0.54726 0.47071,1.17339 0.47071,1.79883 0.0782,0.54726 -0.0799,1.01725 -0.31446,1.48633 -0.23454,0.54725 -0.70285,1.40597 -1.09375,1.79687 l 150.8086,149.71485 -23.68946,23.6875 -12.74414,-12.74219 -13.44726,-13.44727 -78.80469,-78.80664 -11.17969,-11.17968 -7.5039,-7.50391 -35.41602,-35.17969 -3.08984,-0.98047 -4.33594,4.26367 v 0.46876 c 0,7.34888 0.38998,15.00865 -1.48633,22.20117 -0.85998,3.28355 -2.34444,6.25595 -4.14258,8.91406 -0.15636,0.15636 -0.23627,0.23426 -0.31445,0.39062 -1.87631,2.57993 -4.06471,4.84619 -6.48828,6.95704 -5.3944,4.53442 -11.25752,8.67896 -17.27734,12.50976 -0.15637,0.0782 -0.23427,0.1562 -0.39063,0.23438 -2.11085,1.40723 -4.3012,2.7354 -6.49023,4.06445 -8.91248,5.39439 -18.37192,10.08772 -28.37891,13.13672 -1.25087,0.31272 -2.42317,-0.001 -3.36133,-0.70508 l -6.01953,5.94141 c 1.25087,0.62543 2.03136,1.87776 1.875,3.51953 -10e-6,0.15636 -0.0762,0.23231 -0.0762,0.38867 0,0.0782 -0.0781,0.23628 -0.0781,0.31445 -1.32905,4.45624 -2.34505,8.98897 -3.2832,13.60156 -0.15636,0.70363 -0.23622,1.33154 -0.39258,2.03516 -0.85997,4.37806 -1.64209,8.83288 -2.3457,13.21094 0.23453,5.3944 0.39263,11.0234 0.31445,16.65234 v 0.39258 c -0.0782,7.66161 -0.78373,15.32114 -2.8164,22.51367 -2.26721,8.28704 -6.64376,15.63728 -10.55274,23.22071 -0.0782,0.15636 -0.15815,0.23426 -0.23633,0.39062 -1.25088,2.42357 -2.49924,4.92399 -3.59375,7.50391 -4.84714,11.33605 -7.42749,23.92328 -10.55468,35.88476 -0.23454,0.70362 -0.39046,1.48578 -0.625,2.26758 0,0.15636 -0.0801,0.23427 -0.0801,0.39063 -2.97082,11.10151 -6.09819,22.28173 -10.94532,32.75781 -1.40724,2.97082 -2.81531,5.86322 -4.3789,8.75586 -0.15636,0.23454 -0.23231,0.46858 -0.38867,0.70312 -0.62544,1.09451 -1.25152,2.26871 -1.87696,3.44141 -0.0782,0.15636 -0.15619,0.23426 -0.23437,0.39062 -3.51809,6.25438 -7.27098,12.43118 -10.78906,18.68555 -5.0035,8.8343 -8.99075,18.13635 -13.83789,27.04883 -0.0782,0.15636 -0.1562,0.23426 -0.23438,0.39062 -0.70362,1.32905 -1.48579,2.65728 -2.26758,3.98633 -5.0035,8.20887 -10.63256,16.0279 -16.57422,23.61133 -0.15635,0.15636 -0.23426,0.3124 -0.39062,0.46875 -0.7818,1.01634 -1.48578,1.95443 -2.26758,2.89258 -3.90898,4.92532 -7.97378,9.85009 -11.96094,14.77539 -0.0782,0.15637 -0.23432,0.23622 -0.3125,0.39258 -8.75612,10.71061 -17.35628,21.49761 -24.54883,33.30273 0,0.70362 -0.15602,1.33159 -0.46874,1.95703 -1.25087,2.42357 -2.65734,4.68971 -3.90821,7.11328 -0.0782,0.15636 0.62511,1.24989 0.46875,1.40625 L 429.86133,1024 H 1463.0215 L 661.85547,222.92969 c -0.93816,2.11087 -5.23681,1.40935 -7.34766,-0.23242 -1.71995,-1.32906 -3.12603,-3.05147 -4.45508,-4.84961 -0.62544,-0.31271 -1.25168,-0.62288 -1.64257,-0.85743 -2.89265,-1.40723 -6.09933,-1.48632 -9.30469,-1.48632 -0.7818,-0.0782 -1.40588,-0.23416 -1.95313,-0.54688 z m -206.12304,191.41992 0.11914,-0.11523 -0.23438,0.0781 z"
|
||||
id="XMLID_64_" /></g><g
|
||||
id="layer2"
|
||||
style="display:inline;fill:#000000;fill-opacity:0.49803922"><path
|
||||
id="XMLID_42_"
|
||||
d="m 295.17362,965.05417 c 1.0692,3.47527 0.5346,7.21786 -1.3367,10.29214 l -25.7972,41.83679 c -2.5396,4.1436 -7.2178,6.8169 -12.297,6.8169 H 14.345318 C 3.1176178,1024 -3.6991822,1012.2376 2.3157178,1003.4158 L 157.76692,774.44928 c 0.9356,-1.33663 1.4704,-2.80694 1.8713,-4.27723 l 71.2428,-304.21933 c 0.8021,-3.60893 3.2081,-6.6832 6.6833,-8.55449 l 96.5054,-52.93096 c 3.4753,-1.8713 5.8812,-4.94557 6.6832,-8.68816 l 12.9654,-56.53988 c 2.6733,-11.76242 19.5151,-14.30205 26.1981,-4.00991 l 4.6783,7.48519 c 2.0049,3.20793 2.5396,7.21785 1.2031,10.82678 l -87.9511,254.22895 c -0.6683,2.00497 -0.9355,4.1436 -0.5346,6.28223 l 21.9209,121.63426 c 0.401,2.40595 0.1334,4.94556 -0.9357,7.21785 l -52.2625,117.357 c -1.203,2.80696 -1.4704,5.88123 -0.5347,8.68817 z M 1009.7413,1024 H 843.46322 c -4.8117,0 -9.2228,-2.4059 -11.8959,-6.1485 L 719.69042,860.52891 c -0.6683,-1.0693 -1.3366,-2.13861 -1.7375,-3.3416 l -55.4707,-162.00078 c -1.0692,-3.20793 -3.6088,-6.01489 -6.8169,-7.61886 l -135.8026,-68.56965 c -3.7426,-1.87127 -6.4159,-5.34655 -7.2179,-9.22281 l -20.0495,-99.44603 c -0.2674,-1.60396 -0.9357,-3.20793 -2.005,-4.67824 l -46.1141,-67.76766 c -2.5396,-3.74259 -2.9405,-8.28717 -1.0693,-12.2971 l 28.0694,-60.01513 c 2.1387,-4.54457 6.817,-7.61886 12.1634,-7.88619 l 52.129,-3.07427 c 3.0742,-0.1337 5.8812,-1.20296 8.1536,-3.07427 l 38.3615,-29.80707 c 7.2178,-5.61388 18.1784,-3.20794 22.0546,4.67824 l 132.1937,268.93201 c 0.5346,1.20297 0.9357,2.40595 1.2029,3.60894 l 16.3072,108.13418 c 0.4009,2.53963 1.4701,4.8119 3.2079,6.6832 l 263.31808,288.17958 c 7.7525,8.5545 1.203,22.0546 -10.8269,22.0546 z M 363.20852,182.58501 c 0,-30.60907 19.3812,-56.94088 47.1834,-69.23798 -2.005,-3.3416 -3.2079,-6.95052 -3.2079,-10.82678 0,-14.836705 17.109,-26.866465 38.0942,-26.866465 0.5346,0 0.9356,0 1.4704,0 8.688,-14.43572 25.2624,-24.19318 44.2426,-24.19318 1.3367,0 2.6733,0 4.01,0.1337 1.7377,0.13369 3.4753,-0.66833 4.4109,-2.00497 14.0347,-21.38624 49.5894,-36.62394 91.159,-36.62394 15.3712,0 29.9406,2.13863 42.906,5.74756 3.0744,-5.07924 9.8911,-8.5545 17.7773,-8.5545 8.9556,0 16.5744,4.54458 18.8466,10.82678 10.9606,-12.69809 29.5398,-20.98524 50.6587,-20.98524 33.6834,0 60.9508,21.25257 60.9508,47.45072 0,3.20793 -0.401,6.2822 -1.203,9.35647 -0.5346,2.13864 0.6683,4.27725 2.9407,5.07924 21.5199,7.88618 36.0893,22.85655 36.0893,39.965535 0,19.51495 -18.8466,36.22296 -45.4458,42.77249 -2.1387,0.53466 -3.4753,2.40595 -3.4753,4.41092 0,0.1337 0,0.26731 0,0.40098 0,15.10404 -14.9704,27.5348 -34.218,28.87144 0.1333,0.66833 0.1333,1.33663 0.1333,2.13862 0,29.00509 -55.2031,52.3963 -123.2382,52.3963 -14.7029,0 -28.7377,-1.06932 -41.7031,-3.07427 0,0.26733 0,0.40099 0,0.66832 0,12.02975 -15.5051,21.78723 -34.4854,21.78723 -1.0692,0 -2.0049,0 -2.9405,-0.13369 1.3367,2.9406 2.005,6.01487 2.005,9.22281 0,18.71296 -23.6586,33.81699 -52.9311,33.81699 -3.2079,0 -6.2821,-0.1337 -9.3563,-0.53466 -2.4061,-0.26731 -4.6783,1.20299 -5.2131,3.47529 -2.5396,9.35647 -10.693,16.17333 -20.4504,16.17333 -11.7625,0 -21.119,-10.0248 -21.119,-22.32189 0,-5.74755 2.005,-10.96045 5.3466,-14.83671 1.203,-1.33663 1.6039,-3.20793 0.8019,-4.81191 -1.8713,-3.47526 -2.6733,-7.08419 -2.6733,-10.96044 v 0 c 0,-2.13862 -1.7376,-3.87626 -3.8763,-4.4109 -36.2228,-8.01985 -63.4903,-38.22792 -63.4903,-74.3172 z m 306.8925,726.06294 c 0.5348,1.60398 0.6683,3.20796 0.6683,4.94558 l -7.7525,97.97577 c -0.5346,6.9505 -6.6832,12.4307 -14.1683,12.4307 h -250.219 c -5.3466,0 -10.2921,-3.0743 -12.6982,-7.4852 l -41.3021,-76.72312 c -0.2673,-0.401 -0.401,-0.80199 -0.5347,-1.20298 l -38.8962,-94.23313 c -1.4702,-3.3416 -1.203,-7.21785 0.4011,-10.42581 l 64.5596,-126.31249 c 1.604,-3.07427 1.8712,-6.6832 0.6683,-9.89114 l -31.5447,-87.41626 c -1.0693,-3.07428 -0.9356,-6.54955 0.4011,-9.49015 l 52.6636,-112.14412 c 5.3464,-11.22778 22.8565,-10.29212 26.5991,1.47031 l 16.4407,51.05965 50.124,134.19868 c 1.3367,3.7426 4.5446,6.6832 8.5545,8.01985 l 106.9312,36.49027 c 4.1435,1.47032 7.3516,4.54458 8.6881,8.42084 z"
|
||||
style="fill:#000000;stroke-width:0.78179646;fill-opacity:0.49803922" /><g
|
||||
aria-label="WULKANOWY"
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:341.33334351px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:'Roboto Light';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:0.49803922;stroke:none"
|
||||
id="text4752" /></g></svg>
|
After Width: | Height: | Size: 13 KiB |
@ -1,17 +1,15 @@
|
||||
package io.github.wulkanowy.data
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.AssetManager
|
||||
import android.content.res.Resources
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
|
||||
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||
import com.chuckerteam.chucker.api.RetentionManager
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
|
@ -68,6 +68,7 @@ import io.github.wulkanowy.data.db.migrations.Migration22
|
||||
import io.github.wulkanowy.data.db.migrations.Migration23
|
||||
import io.github.wulkanowy.data.db.migrations.Migration24
|
||||
import io.github.wulkanowy.data.db.migrations.Migration25
|
||||
import io.github.wulkanowy.data.db.migrations.Migration26
|
||||
import io.github.wulkanowy.data.db.migrations.Migration3
|
||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||
import io.github.wulkanowy.data.db.migrations.Migration5
|
||||
@ -110,7 +111,7 @@ import javax.inject.Singleton
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
const val VERSION_SCHEMA = 25
|
||||
const val VERSION_SCHEMA = 26
|
||||
|
||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array<Migration> {
|
||||
return arrayOf(
|
||||
@ -137,7 +138,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
Migration22(),
|
||||
Migration23(),
|
||||
Migration24(),
|
||||
Migration25()
|
||||
Migration25(),
|
||||
Migration26()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.db.entities
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import org.threeten.bp.LocalDateTime
|
||||
|
||||
@Entity(tableName = "GradesSummary")
|
||||
data class GradeSummary(
|
||||
@ -36,4 +37,16 @@ data class GradeSummary(
|
||||
) {
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0
|
||||
|
||||
@ColumnInfo(name = "is_predicted_grade_notified")
|
||||
var isPredictedGradeNotified: Boolean = true
|
||||
|
||||
@ColumnInfo(name = "is_final_grade_notified")
|
||||
var isFinalGradeNotified: Boolean = true
|
||||
|
||||
@ColumnInfo(name = "predicted_grade_last_change")
|
||||
var predictedGradeLastChange: LocalDateTime = LocalDateTime.now()
|
||||
|
||||
@ColumnInfo(name = "final_grade_last_change")
|
||||
var finalGradeLastChange: LocalDateTime = LocalDateTime.now()
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package io.github.wulkanowy.data.db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration26 : Migration(25, 26) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_predicted_grade_notified INTEGER NOT NULL DEFAULT 1")
|
||||
database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_final_grade_notified INTEGER NOT NULL DEFAULT 1")
|
||||
database.execSQL("ALTER TABLE GradesSummary ADD COLUMN predicted_grade_last_change INTEGER NOT NULL DEFAULT 0")
|
||||
database.execSQL("ALTER TABLE GradesSummary ADD COLUMN final_grade_last_change INTEGER NOT NULL DEFAULT 0")
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class AppCreatorRepository @Inject constructor(private val assets: AssetManager) {
|
||||
fun getAppCreators(): Single<List<Contributor>> {
|
||||
return Single.fromCallable<List<Contributor>> {
|
||||
return Single.fromCallable {
|
||||
Gson().fromJson(
|
||||
assets.open("contributors.json").bufferedReader().use { it.readText() },
|
||||
Array<Contributor>::class.java
|
||||
|
@ -13,7 +13,7 @@ class ExamLocal @Inject constructor(private val examDb: ExamDao) {
|
||||
|
||||
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe<List<Exam>> {
|
||||
return examDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate)
|
||||
.filter { !it.isEmpty() }
|
||||
.filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
fun saveExams(exams: List<Exam>) {
|
||||
|
@ -27,6 +27,10 @@ class GradeLocal @Inject constructor(
|
||||
gradeDb.updateAll(grades)
|
||||
}
|
||||
|
||||
fun updateGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||
gradeSummaryDb.updateAll(gradesSummary)
|
||||
}
|
||||
|
||||
fun getGradesDetails(semester: Semester): Maybe<List<Grade>> {
|
||||
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
import org.threeten.bp.LocalDateTime
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -43,7 +44,31 @@ class GradeRepository @Inject constructor(
|
||||
local.getGradesSummary(semester).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
local.deleteGradesSummary(old.uniqueSubtract(newSummary))
|
||||
local.saveGradesSummary(newSummary.uniqueSubtract(old))
|
||||
local.saveGradesSummary(newSummary.uniqueSubtract(old)
|
||||
.onEach { summary ->
|
||||
val oldSummary = old.find { oldSummary -> oldSummary.subject == summary.subject }
|
||||
summary.isPredictedGradeNotified = when {
|
||||
summary.predictedGrade.isEmpty() -> true
|
||||
notify && oldSummary?.predictedGrade != summary.predictedGrade -> false
|
||||
else -> true
|
||||
}
|
||||
summary.isFinalGradeNotified = when {
|
||||
summary.finalGrade.isEmpty() -> true
|
||||
notify && oldSummary?.finalGrade != summary.finalGrade -> false
|
||||
else -> true
|
||||
}
|
||||
|
||||
summary.predictedGradeLastChange = when {
|
||||
oldSummary == null -> LocalDateTime.now()
|
||||
summary.predictedGrade != oldSummary.predictedGrade -> LocalDateTime.now()
|
||||
else -> oldSummary.predictedGradeLastChange
|
||||
}
|
||||
summary.finalGradeLastChange = when {
|
||||
oldSummary == null -> LocalDateTime.now()
|
||||
summary.finalGrade != oldSummary.finalGrade -> LocalDateTime.now()
|
||||
else -> oldSummary.finalGradeLastChange
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}.flatMap {
|
||||
@ -63,6 +88,14 @@ class GradeRepository @Inject constructor(
|
||||
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun getNotNotifiedPredictedGrades(semester: Semester): Single<List<GradeSummary>> {
|
||||
return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isPredictedGradeNotified } }.toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun getNotNotifiedFinalGrades(semester: Semester): Single<List<GradeSummary>> {
|
||||
return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isFinalGradeNotified } }.toSingle(emptyList())
|
||||
}
|
||||
|
||||
fun updateGrade(grade: Grade): Completable {
|
||||
return Completable.fromCallable { local.updateGrades(listOf(grade)) }
|
||||
}
|
||||
@ -70,4 +103,8 @@ class GradeRepository @Inject constructor(
|
||||
fun updateGrades(grades: List<Grade>): Completable {
|
||||
return Completable.fromCallable { local.updateGrades(grades) }
|
||||
}
|
||||
|
||||
fun updateGradesSummary(gradesSummary: List<GradeSummary>): Completable {
|
||||
return Completable.fromCallable { local.updateGradesSummary(gradesSummary) }
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import javax.inject.Singleton
|
||||
class RecipientLocal @Inject constructor(private val recipientDb: RecipientDao) {
|
||||
|
||||
fun getRecipients(student: Student, role: Int, unit: ReportingUnit): Maybe<List<Recipient>> {
|
||||
return recipientDb.load(student.studentId, role, unit.realId).filter { !it.isEmpty() }
|
||||
return recipientDb.load(student.studentId, role, unit.realId).filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
fun saveRecipients(recipients: List<Recipient>): List<Long> {
|
||||
|
@ -11,7 +11,7 @@ import javax.inject.Singleton
|
||||
class ReportingUnitLocal @Inject constructor(private val reportingUnitDb: ReportingUnitDao) {
|
||||
|
||||
fun getReportingUnits(student: Student): Maybe<List<ReportingUnit>> {
|
||||
return reportingUnitDb.load(student.studentId).filter { !it.isEmpty() }
|
||||
return reportingUnitDb.load(student.studentId).filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
fun getReportingUnit(student: Student, unitId: Int): Maybe<ReportingUnit> {
|
||||
|
@ -14,7 +14,7 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
|
||||
private fun mapStudents(students: List<SdkStudent>, email: String, password: String): List<Student> {
|
||||
return students.map { student ->
|
||||
Student(
|
||||
email = email,
|
||||
email = email.ifBlank { student.email },
|
||||
password = password,
|
||||
isParent = student.isParent,
|
||||
symbol = student.symbol,
|
||||
|
@ -9,7 +9,7 @@ import javax.inject.Inject
|
||||
class GradeStatisticsWork @Inject constructor(private val gradeStatisticsRepository: GradeStatisticsRepository) : Work {
|
||||
|
||||
override fun create(student: Student, semester: Semester): Completable {
|
||||
return gradeStatisticsRepository.getGradesStatistics(student, semester, "Wszystkie", false, true)
|
||||
return gradeStatisticsRepository.getGradesStatistics(student, semester, "Wszystkie", false, forceRefresh = true)
|
||||
.ignoreElement()
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import androidx.core.app.NotificationCompat.PRIORITY_HIGH
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Grade
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
||||
@ -30,17 +31,21 @@ class GradeWork @Inject constructor(
|
||||
|
||||
override fun create(student: Student, semester: Semester): Completable {
|
||||
return gradeRepository.getGrades(student, semester, true, preferencesRepository.isNotificationsEnable)
|
||||
.flatMap { gradeRepository.getNotNotifiedGrades(semester) }
|
||||
.flatMapCompletable {
|
||||
if (it.isNotEmpty()) notify(it)
|
||||
.ignoreElement()
|
||||
.concatWith(Completable.concatArray(gradeRepository.getNotNotifiedGrades(semester).flatMapCompletable {
|
||||
if (it.isNotEmpty()) notifyDetails(it)
|
||||
gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true })
|
||||
}
|
||||
}, gradeRepository.getNotNotifiedPredictedGrades(semester).flatMapCompletable {
|
||||
if (it.isNotEmpty()) notifyPredicted(it)
|
||||
gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isPredictedGradeNotified = true })
|
||||
}, gradeRepository.getNotNotifiedFinalGrades(semester).flatMapCompletable {
|
||||
if (it.isNotEmpty()) notifyFinal(it)
|
||||
gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isFinalGradeNotified = true })
|
||||
}))
|
||||
}
|
||||
|
||||
private fun notify(grades: List<Grade>) {
|
||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewGradesChannel.CHANNEL_ID)
|
||||
.setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size))
|
||||
.setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size))
|
||||
private fun getNotificationBuilder(): NotificationCompat.Builder {
|
||||
return NotificationCompat.Builder(context, NewGradesChannel.CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_stat_grade)
|
||||
.setAutoCancel(true)
|
||||
.setPriority(PRIORITY_HIGH)
|
||||
@ -49,6 +54,12 @@ class GradeWork @Inject constructor(
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(context, MainView.Section.GRADE.id,
|
||||
MainActivity.getStartIntent(context, MainView.Section.GRADE, true), FLAG_UPDATE_CURRENT))
|
||||
}
|
||||
|
||||
private fun notifyDetails(grades: List<Grade>) {
|
||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder()
|
||||
.setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size))
|
||||
.setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size))
|
||||
.setStyle(NotificationCompat.InboxStyle().run {
|
||||
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, grades.size, grades.size))
|
||||
grades.forEach { addLine("${it.subject}: ${it.entry}") }
|
||||
@ -57,4 +68,30 @@ class GradeWork @Inject constructor(
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun notifyPredicted(gradesSummary: List<GradeSummary>) {
|
||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder()
|
||||
.setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_predicted, gradesSummary.size, gradesSummary.size))
|
||||
.setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_predicted, gradesSummary.size, gradesSummary.size))
|
||||
.setStyle(NotificationCompat.InboxStyle().run {
|
||||
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size))
|
||||
gradesSummary.forEach { addLine("${it.subject}: ${it.predictedGrade}") }
|
||||
this
|
||||
})
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun notifyFinal(gradesSummary: List<GradeSummary>) {
|
||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder()
|
||||
.setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_final, gradesSummary.size, gradesSummary.size))
|
||||
.setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_final, gradesSummary.size, gradesSummary.size))
|
||||
.setStyle(NotificationCompat.InboxStyle().run {
|
||||
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size))
|
||||
gradesSummary.forEach { addLine("${it.subject}: ${it.finalGrade}") }
|
||||
this
|
||||
})
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ class LogViewerPresenter @Inject constructor(
|
||||
disposable.add(loggerRepository.getLogFiles()
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.subscribe({
|
||||
Timber.i("Loading logs files result: ${it.joinToString { it.name }}")
|
||||
view?.shareLogs(it)
|
||||
.subscribe({ files ->
|
||||
Timber.i("Loading logs files result: ${files.joinToString { it.name }}")
|
||||
view?.shareLogs(files)
|
||||
}, {
|
||||
Timber.i("Loading logs files result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
|
@ -0,0 +1,3 @@
|
||||
package io.github.wulkanowy.ui.modules.account
|
||||
|
||||
data class Account(val email: String, val isParent: Boolean)
|
@ -3,33 +3,72 @@ package io.github.wulkanowy.ui.modules.account
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.PorterDuff
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.databinding.HeaderAccountBinding
|
||||
import io.github.wulkanowy.databinding.ItemAccountBinding
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||
import javax.inject.Inject
|
||||
|
||||
class AccountAdapter @Inject constructor() : RecyclerView.Adapter<AccountAdapter.ItemViewHolder>() {
|
||||
class AccountAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
var items = emptyList<Student>()
|
||||
var items = emptyList<AccountItem<*>>()
|
||||
|
||||
var onClickListener: (Student) -> Unit = {}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
|
||||
ItemAccountBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
)
|
||||
override fun getItemViewType(position: Int) = items[position].viewType.id
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
|
||||
return when (viewType) {
|
||||
AccountItem.ViewType.HEADER.id -> HeaderViewHolder(HeaderAccountBinding.inflate(inflater, parent, false))
|
||||
AccountItem.ViewType.ITEM.id -> ItemViewHolder(ItemAccountBinding.inflate(inflater, parent, false))
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is HeaderViewHolder -> bindHeaderViewHolder(holder.binding, items[position].value as Account)
|
||||
is ItemViewHolder -> bindItemViewHolder(holder.binding, items[position].value as Student)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindHeaderViewHolder(binding: HeaderAccountBinding, account: Account) {
|
||||
with(binding) {
|
||||
accountHeaderEmail.text = account.email
|
||||
accountHeaderType.setText(if (account.isParent) R.string.account_type_parent else R.string.account_type_student)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||
val student = items[position]
|
||||
|
||||
with(holder.binding) {
|
||||
private fun bindItemViewHolder(binding: ItemAccountBinding, student: Student) {
|
||||
with(binding) {
|
||||
accountItemName.text = "${student.studentName} ${student.className}"
|
||||
accountItemSchool.text = student.schoolName
|
||||
with(accountItemLoginMode) {
|
||||
visibility = when (Sdk.Mode.valueOf(student.loginMode)) {
|
||||
Sdk.Mode.API -> {
|
||||
setText(R.string.account_login_mobile_api)
|
||||
VISIBLE
|
||||
}
|
||||
Sdk.Mode.HYBRID -> {
|
||||
setText(R.string.account_login_hybrid)
|
||||
VISIBLE
|
||||
}
|
||||
Sdk.Mode.SCRAPPER -> {
|
||||
GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
with(accountItemImage) {
|
||||
val colorImage = if (student.isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
|
||||
@ -42,5 +81,8 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter<AccountAdapter
|
||||
}
|
||||
}
|
||||
|
||||
class HeaderViewHolder(val binding: HeaderAccountBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
class ItemViewHolder(val binding: ItemAccountBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import android.widget.Toast.LENGTH_LONG
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.databinding.DialogAccountBinding
|
||||
import io.github.wulkanowy.ui.base.BaseDialogFragment
|
||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||
@ -54,7 +53,7 @@ class AccountDialog : BaseDialogFragment<DialogAccountBinding>(), AccountView {
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateData(data: List<Student>) {
|
||||
override fun updateData(data: List<AccountItem<*>>) {
|
||||
with(accountAdapter) {
|
||||
items = data
|
||||
notifyDataSetChanged()
|
||||
|
@ -0,0 +1,9 @@
|
||||
package io.github.wulkanowy.ui.modules.account
|
||||
|
||||
data class AccountItem<out T>(val value: T, val viewType: ViewType) {
|
||||
|
||||
enum class ViewType(val id: Int) {
|
||||
HEADER(1),
|
||||
ITEM(2)
|
||||
}
|
||||
}
|
@ -83,11 +83,20 @@ class AccountPresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun createAccountItems(items: List<Student>): List<AccountItem<*>> {
|
||||
return items.groupBy { Account(it.email, it.isParent) }.map { (account, students) ->
|
||||
listOf(AccountItem(account, AccountItem.ViewType.HEADER)) + students.map { student ->
|
||||
AccountItem(student, AccountItem.ViewType.ITEM)
|
||||
}
|
||||
}.flatten()
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
Timber.i("Loading account data started")
|
||||
disposable.add(studentRepository.getSavedStudents(false)
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.map { createAccountItems(it) }
|
||||
.subscribe({
|
||||
Timber.i("Loading account result: Success")
|
||||
view?.updateData(it)
|
||||
|
@ -1,13 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.account
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface AccountView : BaseView {
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<Student>)
|
||||
fun updateData(data: List<AccountItem<*>>)
|
||||
|
||||
fun dismissView()
|
||||
|
||||
|
@ -20,7 +20,6 @@ import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import org.threeten.bp.LocalDate.ofEpochDay
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||
import javax.inject.Inject
|
||||
|
||||
class AttendancePresenter @Inject constructor(
|
||||
|
@ -98,7 +98,7 @@ class GradeAverageProvider @Inject constructor(
|
||||
}
|
||||
|
||||
private fun List<GradeSummary>.emulateEmptySummaries(student: Student, semester: Semester, grades: List<Pair<String, List<Grade>>>, calcAverage: Boolean): List<GradeSummary> {
|
||||
if (isNotEmpty() && size == grades.size) return this
|
||||
if (isNotEmpty() && size > grades.size) return this
|
||||
|
||||
return grades.mapIndexed { i, (subject, details) ->
|
||||
singleOrNull { it.subject == subject }?.let { return@mapIndexed it }
|
||||
|
@ -63,7 +63,7 @@ class MessagePreviewAdapter @Inject constructor() :
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun bindMessage(holder: MessageViewHolder, message: Message) {
|
||||
with(holder.binding) {
|
||||
messagePreviewSubject.text = if (message.subject.isNotBlank()) message.subject else root.context.getString(R.string.message_no_subject)
|
||||
messagePreviewSubject.text = message.subject.ifBlank { root.context.getString(R.string.message_no_subject) }
|
||||
messagePreviewDate.text = root.context.getString(R.string.message_date, message.date.toFormattedString("yyyy-MM-dd HH:mm:ss"))
|
||||
messagePreviewContent.text = message.content
|
||||
messagePreviewAuthor.text = if (message.folderId == MessageFolder.SENT.id) "${root.context.getString(R.string.message_to)} ${message.recipient}"
|
||||
|
@ -1,12 +1,20 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.print.PrintAttributes
|
||||
import android.print.PrintManager
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
@ -17,6 +25,8 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.shareText
|
||||
import javax.inject.Inject
|
||||
|
||||
class MessagePreviewFragment :
|
||||
@ -29,18 +39,31 @@ class MessagePreviewFragment :
|
||||
@Inject
|
||||
lateinit var previewAdapter: MessagePreviewAdapter
|
||||
|
||||
@Inject
|
||||
lateinit var appInfo: AppInfo
|
||||
|
||||
private var menuReplyButton: MenuItem? = null
|
||||
|
||||
private var menuForwardButton: MenuItem? = null
|
||||
|
||||
private var menuDeleteButton: MenuItem? = null
|
||||
|
||||
private var menuShareButton: MenuItem? = null
|
||||
|
||||
private var menuPrintButton: MenuItem? = null
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.message_title
|
||||
|
||||
override val deleteMessageSuccessString: String
|
||||
get() = getString(R.string.message_delete_success)
|
||||
|
||||
override val messageNoSubjectString: String
|
||||
get() = getString(R.string.message_no_subject)
|
||||
|
||||
override val printHTML: String
|
||||
get() = requireContext().assets.open("message-print-page.html").bufferedReader().use { it.readText() }
|
||||
|
||||
companion object {
|
||||
const val MESSAGE_ID_KEY = "message_id"
|
||||
|
||||
@ -77,6 +100,8 @@ class MessagePreviewFragment :
|
||||
menuReplyButton = menu.findItem(R.id.messagePreviewMenuReply)
|
||||
menuForwardButton = menu.findItem(R.id.messagePreviewMenuForward)
|
||||
menuDeleteButton = menu.findItem(R.id.messagePreviewMenuDelete)
|
||||
menuShareButton = menu.findItem(R.id.messagePreviewMenuShare)
|
||||
menuPrintButton = menu.findItem(R.id.messagePreviewMenuPrint)
|
||||
presenter.onCreateOptionsMenu()
|
||||
}
|
||||
|
||||
@ -85,6 +110,8 @@ class MessagePreviewFragment :
|
||||
R.id.messagePreviewMenuReply -> presenter.onReply()
|
||||
R.id.messagePreviewMenuForward -> presenter.onForward()
|
||||
R.id.messagePreviewMenuDelete -> presenter.onMessageDelete()
|
||||
R.id.messagePreviewMenuShare -> presenter.onShare()
|
||||
R.id.messagePreviewMenuPrint -> presenter.onPrint()
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@ -108,6 +135,8 @@ class MessagePreviewFragment :
|
||||
menuReplyButton?.isVisible = show
|
||||
menuForwardButton?.isVisible = show
|
||||
menuDeleteButton?.isVisible = show
|
||||
menuShareButton?.isVisible = show
|
||||
menuPrintButton?.isVisible = show && appInfo.systemVersion >= Build.VERSION_CODES.LOLLIPOP
|
||||
}
|
||||
|
||||
override fun setDeletedOptionsLabels() {
|
||||
@ -138,6 +167,38 @@ class MessagePreviewFragment :
|
||||
context?.let { it.startActivity(SendMessageActivity.getStartIntent(it, message)) }
|
||||
}
|
||||
|
||||
override fun shareText(text: String, subject: String) {
|
||||
context?.shareText(text, subject)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
override fun printDocument(html: String, jobName: String) {
|
||||
val webView = WebView(activity)
|
||||
webView.webViewClient = object : WebViewClient() {
|
||||
|
||||
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false
|
||||
|
||||
override fun onPageFinished(view: WebView, url: String) {
|
||||
createWebPrintJob(view, jobName)
|
||||
}
|
||||
}
|
||||
|
||||
webView.loadDataWithBaseURL("file:///android_asset/", html, "text/HTML", "UTF-8", null)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private fun createWebPrintJob(webView: WebView, jobName: String) {
|
||||
activity?.getSystemService<PrintManager>()?.let { printManager ->
|
||||
val printAdapter = webView.createPrintDocumentAdapter(jobName)
|
||||
|
||||
printManager.print(
|
||||
jobName,
|
||||
printAdapter,
|
||||
PrintAttributes.Builder().build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun popView() {
|
||||
(activity as MainActivity).popView()
|
||||
}
|
||||
|
@ -1,12 +1,17 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
||||
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.AppInfo
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -15,11 +20,14 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository,
|
||||
private val messageRepository: MessageRepository,
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
private val analytics: FirebaseAnalyticsHelper,
|
||||
private var appInfo: AppInfo
|
||||
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository, schedulers) {
|
||||
|
||||
var message: Message? = null
|
||||
|
||||
var attachments: List<MessageAttachment>? = null
|
||||
|
||||
private lateinit var lastError: Throwable
|
||||
|
||||
private var retryCallback: () -> Unit = {}
|
||||
@ -56,6 +64,7 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
.subscribe({ message ->
|
||||
Timber.i("Loading message ${message.message.messageId} preview result: Success ")
|
||||
this@MessagePreviewPresenter.message = message.message
|
||||
this@MessagePreviewPresenter.attachments = message.attachments
|
||||
view?.apply {
|
||||
setMessageWithAttachment(message)
|
||||
initOptions()
|
||||
@ -87,6 +96,60 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
} else false
|
||||
}
|
||||
|
||||
fun onShare(): Boolean {
|
||||
message?.let {
|
||||
var text = "Temat: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}\n" + when (it.sender.isNotEmpty()) {
|
||||
true -> "Od: ${it.sender}\n"
|
||||
false -> "Do: ${it.recipient}\n"
|
||||
} + "Data: ${it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${it.content}"
|
||||
|
||||
attachments?.let { attachments ->
|
||||
if (attachments.isNotEmpty()) {
|
||||
text += "\n\nZałączniki:"
|
||||
|
||||
attachments.forEach { attachment ->
|
||||
text += "\n${attachment.filename}: ${attachment.url}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view?.shareText(text, "FW: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
fun onPrint(): Boolean {
|
||||
if (appInfo.systemVersion < Build.VERSION_CODES.LOLLIPOP) return false
|
||||
message?.let {
|
||||
val dateString = it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")
|
||||
val infoContent = "<div><h4>Data wysłania</h4>$dateString</div>" + when {
|
||||
it.sender.isNotEmpty() -> "<div><h4>Od</h4>${it.sender}</div>"
|
||||
else -> "<div><h4>Do</h4>${it.recipient}</div>"
|
||||
}
|
||||
|
||||
val messageContent = "<p>${it.content}</p>"
|
||||
.replace(Regex("[\\n\\r]{2,}"), "</p><p>")
|
||||
.replace(Regex("[\\n\\r]"), "<br>")
|
||||
|
||||
val jobName = "Wiadomość " + when {
|
||||
it.sender.isNotEmpty() -> "od ${it.sender}"
|
||||
else -> "do ${it.recipient}"
|
||||
} + " $dateString: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }} | Wulkanowy"
|
||||
|
||||
view?.apply {
|
||||
val html = printHTML
|
||||
.replace("%SUBJECT%", it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() })
|
||||
.replace("%CONTENT%", messageContent)
|
||||
.replace("%INFO%", infoContent)
|
||||
printDocument(html, jobName)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun deleteMessage() {
|
||||
message?.let { message ->
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
@ -8,6 +10,10 @@ interface MessagePreviewView : BaseView {
|
||||
|
||||
val deleteMessageSuccessString: String
|
||||
|
||||
val messageNoSubjectString: String
|
||||
|
||||
val printHTML: String
|
||||
|
||||
fun initView()
|
||||
|
||||
fun setMessageWithAttachment(item: MessageWithAttachment)
|
||||
@ -34,5 +40,10 @@ interface MessagePreviewView : BaseView {
|
||||
|
||||
fun openMessageForward(message: Message?)
|
||||
|
||||
fun shareText(text: String, subject: String)
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
fun printDocument(html: String, jobName: String)
|
||||
|
||||
fun popView()
|
||||
}
|
||||
|
@ -4,10 +4,9 @@ import android.graphics.Typeface
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
|
||||
import androidx.recyclerview.widget.SortedList
|
||||
import androidx.recyclerview.widget.SortedListAdapterCallback
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder
|
||||
@ -20,39 +19,23 @@ class MessageTabAdapter @Inject constructor() :
|
||||
|
||||
var onClickListener: (Message, position: Int) -> Unit = { _, _ -> }
|
||||
|
||||
private val items = SortedList(Message::class.java, object :
|
||||
SortedListAdapterCallback<Message>(this) {
|
||||
private var items = mutableListOf<Message>()
|
||||
|
||||
override fun compare(item1: Message, item2: Message): Int {
|
||||
return item2.date.compareTo(item1.date)
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: Message?, newItem: Message?): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
|
||||
override fun areItemsTheSame(item1: Message, item2: Message): Boolean {
|
||||
return item1 == item2
|
||||
}
|
||||
})
|
||||
|
||||
fun replaceAll(models: List<Message>) {
|
||||
items.beginBatchedUpdates()
|
||||
for (i in items.size() - 1 downTo 0) {
|
||||
val model = items.get(i)
|
||||
if (model !in models) {
|
||||
items.remove(model)
|
||||
}
|
||||
}
|
||||
items.addAll(models)
|
||||
items.endBatchedUpdates()
|
||||
fun setDataItems(data: List<Message>) {
|
||||
val diffResult = DiffUtil.calculateDiff(MessageTabDiffUtil(items, data))
|
||||
items = data.toMutableList()
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
fun updateItem(position: Int, item: Message) {
|
||||
items.updateItemAt(position, item)
|
||||
val currentItem = items[position]
|
||||
items[position] = item
|
||||
if (item != currentItem) {
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size()
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
|
||||
ItemMessageBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
@ -85,4 +68,19 @@ class MessageTabAdapter @Inject constructor() :
|
||||
}
|
||||
|
||||
class ItemViewHolder(val binding: ItemMessageBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
private class MessageTabDiffUtil(private val old: List<Message>, private val new: List<Message>) :
|
||||
DiffUtil.Callback() {
|
||||
override fun getOldListSize(): Int = old.size
|
||||
|
||||
override fun getNewListSize(): Int = new.size
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
return old[oldItemPosition].id == new[newItemPosition].id
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
return old[oldItemPosition] == new[newItemPosition]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class MessageTabFragment : BaseFragment<FragmentMessageTabBinding>(R.layout.frag
|
||||
}
|
||||
|
||||
override fun updateData(data: List<Message>) {
|
||||
tabAdapter.replaceAll(data)
|
||||
tabAdapter.setDataItems(data)
|
||||
}
|
||||
|
||||
override fun updateItem(item: Message, position: Int) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.message.tab
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.repositories.message.MessageFolder
|
||||
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
||||
@ -11,8 +10,13 @@ import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||
import timber.log.Timber
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.pow
|
||||
|
||||
class MessageTabPresenter @Inject constructor(
|
||||
schedulers: SchedulersProvider,
|
||||
@ -31,9 +35,12 @@ class MessageTabPresenter @Inject constructor(
|
||||
|
||||
private var messages = emptyList<Message>()
|
||||
|
||||
private val searchQuery = PublishSubject.create<String>()
|
||||
|
||||
fun onAttachView(view: MessageTabView, folder: MessageFolder) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
initializeSearchStream()
|
||||
errorHandler.showErrorMessage = ::showErrorViewOnError
|
||||
this.folder = folder
|
||||
}
|
||||
@ -76,38 +83,35 @@ class MessageTabPresenter @Inject constructor(
|
||||
|
||||
private fun loadData(forceRefresh: Boolean) {
|
||||
Timber.i("Loading $folder message data started")
|
||||
disposable.apply {
|
||||
clear()
|
||||
add(studentRepository.getCurrentStudent()
|
||||
.flatMap { student ->
|
||||
semesterRepository.getCurrentSemester(student)
|
||||
.flatMap { messageRepository.getMessages(student, it, folder, forceRefresh) }
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { student ->
|
||||
semesterRepository.getCurrentSemester(student)
|
||||
.flatMap { messageRepository.getMessages(student, it, folder, forceRefresh) }
|
||||
}
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
}
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
}
|
||||
}
|
||||
.subscribe({
|
||||
Timber.i("Loading $folder message result: Success")
|
||||
messages = it
|
||||
onSearchQueryTextChange(lastSearchQuery)
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "messages",
|
||||
"items" to it.size,
|
||||
"folder" to folder.name
|
||||
)
|
||||
}) {
|
||||
Timber.i("Loading $folder message result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
}
|
||||
}
|
||||
.subscribe({
|
||||
Timber.i("Loading $folder message result: Success")
|
||||
messages = it
|
||||
view?.updateData(getFilteredData(lastSearchQuery))
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "messages",
|
||||
"items" to it.size,
|
||||
"folder" to folder.name
|
||||
)
|
||||
}) {
|
||||
Timber.i("Loading $folder message result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
@ -121,25 +125,36 @@ class MessageTabPresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
fun onSearchQueryTextChange(query: String) {
|
||||
lastSearchQuery = query
|
||||
if (query != searchQuery.toString())
|
||||
searchQuery.onNext(query)
|
||||
}
|
||||
|
||||
val lowerCaseQuery = query.toLowerCase()
|
||||
val filteredList = mutableListOf<Message>()
|
||||
messages.forEach {
|
||||
if (lowerCaseQuery in it.subject.toLowerCase() ||
|
||||
lowerCaseQuery in it.sender.toLowerCase() ||
|
||||
lowerCaseQuery in it.recipient.toLowerCase() ||
|
||||
lowerCaseQuery in it.date.toFormattedString()
|
||||
) {
|
||||
filteredList.add(it)
|
||||
private fun initializeSearchStream() {
|
||||
disposable.add(searchQuery
|
||||
.debounce(250, TimeUnit.MILLISECONDS)
|
||||
.map { query ->
|
||||
lastSearchQuery = query
|
||||
getFilteredData(query)
|
||||
}
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.subscribe({
|
||||
Timber.d("Applying filter. Full list: ${messages.size}, filtered: ${it.size}")
|
||||
updateData(it)
|
||||
}) { Timber.e(it) })
|
||||
}
|
||||
|
||||
private fun getFilteredData(query: String): List<Message> {
|
||||
return if (query.trim().isEmpty()) {
|
||||
messages.sortedByDescending { it.date }
|
||||
} else {
|
||||
messages
|
||||
.map { it to calculateMatchRatio(it, query) }
|
||||
.sortedByDescending { it.second }
|
||||
.filter { it.second > 5000 }
|
||||
.map { it.first }
|
||||
}
|
||||
|
||||
Timber.d("Applying filter. Full list: ${messages.size}, filtered: ${filteredList.size}")
|
||||
|
||||
updateData(filteredList)
|
||||
}
|
||||
|
||||
private fun updateData(data: List<Message>) {
|
||||
@ -151,4 +166,42 @@ class MessageTabPresenter @Inject constructor(
|
||||
resetListPosition()
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateMatchRatio(message: Message, query: String): Int {
|
||||
val subjectRatio = FuzzySearch.tokenSortPartialRatio(
|
||||
query.toLowerCase(Locale.getDefault()),
|
||||
message.subject
|
||||
)
|
||||
|
||||
val senderOrRecipientRatio = FuzzySearch.tokenSortPartialRatio(
|
||||
query.toLowerCase(Locale.getDefault()),
|
||||
if (message.sender.isNotEmpty()) message.sender.toLowerCase(Locale.getDefault())
|
||||
else message.recipient.toLowerCase(Locale.getDefault())
|
||||
)
|
||||
|
||||
val dateRatio = listOf(
|
||||
FuzzySearch.ratio(
|
||||
query.toLowerCase(Locale.getDefault()),
|
||||
message.date.toFormattedString("dd.MM").toLowerCase(Locale.getDefault())
|
||||
),
|
||||
FuzzySearch.ratio(
|
||||
query.toLowerCase(Locale.getDefault()),
|
||||
message.date.toFormattedString("dd.MM.yyyy").toLowerCase(Locale.getDefault())
|
||||
),
|
||||
FuzzySearch.ratio(
|
||||
query.toLowerCase(Locale.getDefault()),
|
||||
message.date.toFormattedString("d MMMM").toLowerCase(Locale.getDefault())
|
||||
),
|
||||
FuzzySearch.ratio(
|
||||
query.toLowerCase(Locale.getDefault()),
|
||||
message.date.toFormattedString("d MMMM yyyy").toLowerCase(Locale.getDefault())
|
||||
)
|
||||
).max() ?: 0
|
||||
|
||||
|
||||
return (subjectRatio.toDouble().pow(2)
|
||||
+ senderOrRecipientRatio.toDouble().pow(2)
|
||||
+ dateRatio.toDouble().pow(2) * 2
|
||||
).toInt()
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class CompletedLessonsPresenter @Inject constructor(
|
||||
completedLessonsErrorHandler.showErrorMessage = ::showErrorViewOnError
|
||||
completedLessonsErrorHandler.onFeatureDisabled = {
|
||||
this.view?.showFeatureDisabled()
|
||||
this.view?.showEmpty(true);
|
||||
this.view?.showEmpty(true)
|
||||
Timber.i("Completed lessons feature disabled by school")
|
||||
}
|
||||
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
|
||||
|
@ -71,4 +71,17 @@ fun Context.openDialer(phone: String) {
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
fun Context.shareText(text: String, subject: String?) {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_TEXT, text)
|
||||
if (subject != null) {
|
||||
putExtra(Intent.EXTRA_SUBJECT, subject)
|
||||
}
|
||||
type = "text/plain"
|
||||
}
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
startActivity(shareIntent)
|
||||
}
|
||||
|
||||
fun Context.dpToPx(dp: Float) = dp * resources.displayMetrics.densityDpi / DENSITY_DEFAULT
|
||||
|
@ -52,4 +52,4 @@ class LifecycleAwareVariableActivity<T : Any> : ReadWriteProperty<AppCompatActiv
|
||||
@Suppress("unused")
|
||||
fun <T : Any> Fragment.lifecycleAwareVariable() = LifecycleAwareVariable<T>()
|
||||
|
||||
fun <T : Any> AppCompatActivity.lifecycleAwareVariable() = LifecycleAwareVariableActivity<T>()
|
||||
fun <T : Any> lifecycleAwareVariable() = LifecycleAwareVariableActivity<T>()
|
||||
|
@ -23,6 +23,8 @@ fun Sdk.init(student: Student): Sdk {
|
||||
certKey = student.certificateKey
|
||||
privateKey = student.privateKey
|
||||
|
||||
emptyCookieJarInterceptor = true
|
||||
|
||||
Timber.d("Sdk in ${student.loginMode} mode reinitialized")
|
||||
|
||||
return this
|
||||
|
@ -1,6 +1,8 @@
|
||||
Wersja 0.18.3
|
||||
- poprawiliśmy liczenie średniej i dodaliśmy nowy sposób jej liczenia w ustawieniach
|
||||
- naprawiliśmy usuwanie wiadomości
|
||||
- naprawiliśmy wysyłanie wiadomości na Lubelskim Portalu Oświatowym
|
||||
Wersja 0.19.0
|
||||
- naprawiliśmy pokazywanie brakujących przedmiotów na liście podsumowania ocen
|
||||
- ulepszyliśmy wygląd menadżera kont
|
||||
- ulepszyliśmy wyszukiwarkę wiadomości
|
||||
- dodaliśmy powiadomienia o proponowanych i końcowych ocenach
|
||||
- dodaliśmy opcję udostępniania i drukowania wiadomości
|
||||
|
||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||
|
13
app/src/main/res/drawable/ic_menu_message_print.xml
Normal file
13
app/src/main/res/drawable/ic_menu_message_print.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,8h-1L18,3L6,3v5L5,8c-1.66,0 -3,1.34 -3,3v6h4v4h12v-4h4v-6c0,-1.66 -1.34,-3 -3,-3zM8,5h8v3L8,8L8,5zM16,17v2L8,19v-4h8v2zM18,15v-2L6,13v2L4,15v-4c0,-0.55 0.45,-1 1,-1h14c0.55,0 1,0.45 1,1v4h-2z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18,11.5m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0" />
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_menu_message_share.xml
Normal file
10
app/src/main/res/drawable/ic_menu_message_share.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92s2.92,-1.31 2.92,-2.92c0,-1.61 -1.31,-2.92 -2.92,-2.92zM18,4c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM6,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1zM18,20.02c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1z" />
|
||||
</vector>
|
@ -5,45 +5,60 @@
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accountDialogTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:text="@string/account_title"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
app:firstBaselineToTopHeight="40dp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/accountDialogRecycler"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/accountDialogTitle"
|
||||
android:overScrollMode="never"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/item_account" />
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/accountDialogAdd"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/accountDialogRecycler"
|
||||
android:layout_margin="8dp"
|
||||
android:text="@string/account_add_new"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
<TextView
|
||||
android:id="@+id/accountDialogTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:text="@string/account_title"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
app:firstBaselineToTopHeight="40dp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/accountDialogRemove"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/accountDialogRecycler"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_margin="8dp"
|
||||
android:text="@string/account_logout" />
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/accountDialogRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_weight="1"
|
||||
android:overScrollMode="never"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/item_account" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/accountDialogAdd"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:text="@string/account_add_new"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/accountDialogRemove"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:text="@string/account_logout" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
28
app/src/main/res/layout/header_account.xml
Normal file
28
app/src/main/res/layout/header_account.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
tools:context=".ui.modules.account.AccountAdapter">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accountHeaderEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="14sp"
|
||||
tools:text="jan@fakelog.cf" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accountHeaderType"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="12sp"
|
||||
tools:text="Konto ucznia" />
|
||||
</LinearLayout>
|
@ -3,20 +3,17 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:paddingHorizontal="16dp"
|
||||
tools:context=".ui.modules.account.AccountAdapter">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/accountItemImage"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_all_account"
|
||||
@ -27,7 +24,7 @@
|
||||
android:id="@+id/accountItemName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="16sp"
|
||||
@ -40,7 +37,7 @@
|
||||
android:id="@+id/accountItemSchool"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
@ -50,4 +47,21 @@
|
||||
app:layout_constraintStart_toEndOf="@id/accountItemImage"
|
||||
app:layout_constraintTop_toBottomOf="@id/accountItemName"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accountItemLoginMode"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/accountItemImage"
|
||||
app:layout_constraintTop_toBottomOf="@id/accountItemSchool"
|
||||
tools:text="Tryb API mobilne"
|
||||
tools:visibility="visible" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -22,4 +22,18 @@
|
||||
android:title="@string/message_delete"
|
||||
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/messagePreviewMenuShare"
|
||||
android:icon="@drawable/ic_menu_message_share"
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/message_share"
|
||||
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/messagePreviewMenuPrint"
|
||||
android:icon="@drawable/ic_menu_message_print"
|
||||
android:orderInCategory="1"
|
||||
android:title="@string/message_print"
|
||||
app:iconTint="@color/material_on_surface_emphasis_medium"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
|
@ -36,8 +36,8 @@
|
||||
</string-array>
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Durchschnittsnote für das 2. Semester</item>
|
||||
<item>Average of grades from both semesters</item>
|
||||
<item>Durchschnitt der Bewertungen für das ganze Jahr</item>
|
||||
<item>Durchschnitt der Noten aus beiden Semestern</item>
|
||||
<item>Durchschnitt der Noten aus dem ganzen Jahr</item>
|
||||
</string-array>
|
||||
<string-array name="timetable_show_whole_class_entries">
|
||||
<item>Nicht zeigen</item>
|
||||
|
@ -103,10 +103,26 @@
|
||||
<item quantity="one">Neue Note</item>
|
||||
<item quantity="other">Neue Noten</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_predicted">
|
||||
<item quantity="one">New predicted grade</item>
|
||||
<item quantity="other">New predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_final">
|
||||
<item quantity="one">New final grade</item>
|
||||
<item quantity="other">New final grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items">
|
||||
<item quantity="one">Du hast %1$d Note bekommen</item>
|
||||
<item quantity="other">Du hast %1$d Noten bekommen</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_predicted">
|
||||
<item quantity="one">You received %1$d predicted grade</item>
|
||||
<item quantity="other">You received %1$d predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_final">
|
||||
<item quantity="one">You received %1$d final grade</item>
|
||||
<item quantity="other">You received %1$d final grades</item>
|
||||
</plurals>
|
||||
<!--Timetable-->
|
||||
<string name="timetable_lesson">Lektion</string>
|
||||
<string name="timetable_room">Klassenzimmer</string>
|
||||
@ -172,6 +188,8 @@
|
||||
<string name="message_move_to_bin">In den Korb wandern</string>
|
||||
<string name="message_delete_forever">Dauerhaft löschen</string>
|
||||
<string name="message_delete_success">Nachricht erfolgreich gelöscht</string>
|
||||
<string name="message_share">Share</string>
|
||||
<string name="message_print">Print</string>
|
||||
<string name="message_subject">Thema</string>
|
||||
<string name="message_content">Inhalt</string>
|
||||
<string name="message_send_successful">Nachricht erfolgreich gesendet</string>
|
||||
@ -214,7 +232,7 @@
|
||||
<string name="lucky_number_header">Die heutige Glücksnummer ist </string>
|
||||
<string name="lucky_number_empty">Keine Information über die Glücksnummer.</string>
|
||||
<string name="lucky_number_notify_new_item_title">Glücksnummer für heute</string>
|
||||
<string name="lucky_number_notify_new_item">Die heutige Glücksnummer ist: </string>
|
||||
<string name="lucky_number_notify_new_item">Die heutige Glücksnummer ist: %d</string>
|
||||
<!--Mobile devices-->
|
||||
<string name="mobile_devices_title">Mobile Geräte</string>
|
||||
<string name="mobile_devices_no_items">Keine Geräte</string>
|
||||
@ -245,6 +263,10 @@
|
||||
<string name="account_logout">Abmelden</string>
|
||||
<string name="account_confirm">Wollen Sie sich von einem aktiven Studenten abmelden?</string>
|
||||
<string name="account_logout_student">Abmeldung von Student</string>
|
||||
<string name="account_type_student">Student account</string>
|
||||
<string name="account_type_parent">Parent account</string>
|
||||
<string name="account_login_mobile_api">Mobile API mode</string>
|
||||
<string name="account_login_hybrid">Hybrid mode</string>
|
||||
<!--About-->
|
||||
<string name="about_version">Version der App</string>
|
||||
<string name="about_contributor">Mitarbeiter</string>
|
||||
@ -270,8 +292,8 @@
|
||||
<string name="logviewer_share">Logs teilen</string>
|
||||
<string name="logviewer_refresh">Aktualisieren</string>
|
||||
<!--Error dialog-->
|
||||
<string name="dialog_error_check_update">Check for updates</string>
|
||||
<string name="dialog_error_check_update_message">Before reporting a bug, check first if an update with the bug fix is available</string>
|
||||
<string name="dialog_error_check_update">Auf Updates prüfen</string>
|
||||
<string name="dialog_error_check_update_message">Bevor Sie einen Fehler melden, prüfen Sie zuerst, ob ein Update mit der Fehlerbehebung verfügbar ist</string>
|
||||
<!--Generic-->
|
||||
<string name="all_content">Inhalt</string>
|
||||
<string name="all_retry">Wiederhol</string>
|
||||
@ -289,7 +311,7 @@
|
||||
<string name="all_prev">Zurück</string>
|
||||
<string name="all_next">Nächste</string>
|
||||
<string name="all_search">Suchen</string>
|
||||
<string name="all_search_hint">Suchen...</string>
|
||||
<string name="all_search_hint">Suchen…</string>
|
||||
<!--Timetable Widget-->
|
||||
<string name="widget_timetable_no_items">Keine Lektionen</string>
|
||||
<string name="widget_timetable_theme_title">Thema wählen</string>
|
||||
|
@ -107,12 +107,36 @@
|
||||
<item quantity="many">Nowe oceny</item>
|
||||
<item quantity="other">Nowe oceny</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_predicted">
|
||||
<item quantity="one">Nowa ocena przewidywana</item>
|
||||
<item quantity="few">Nowe oceny przewidywane</item>
|
||||
<item quantity="many">Nowe oceny przewidywane</item>
|
||||
<item quantity="other">Nowe oceny przewidywane</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_final">
|
||||
<item quantity="one">Nowa ocena końcowa</item>
|
||||
<item quantity="few">Nowe oceny końcowe</item>
|
||||
<item quantity="many">Nowe oceny końcowe</item>
|
||||
<item quantity="other">Nowe oceny końcowe</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items">
|
||||
<item quantity="one">Masz %1$d nową ocenę</item>
|
||||
<item quantity="few">Masz %1$d nowe oceny</item>
|
||||
<item quantity="many">Masz %1$d nowych ocen</item>
|
||||
<item quantity="other">Masz %1$d nowych ocen</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_predicted">
|
||||
<item quantity="one">Masz %1$d nową przewidywaną ocenę</item>
|
||||
<item quantity="few">Masz %1$d nowe przewidywane oceny</item>
|
||||
<item quantity="many">Masz %1$d nowych przewidywanych ocen</item>
|
||||
<item quantity="other">Masz %1$d nowych przewidywanych ocen</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_final">
|
||||
<item quantity="one">Masz %1$d nową końcową ocenę</item>
|
||||
<item quantity="few">Masz %1$d nowe końcowe oceny</item>
|
||||
<item quantity="many">Masz %1$d nowych końcowych ocen</item>
|
||||
<item quantity="other">Masz %1$d nowych końcowych ocen</item>
|
||||
</plurals>
|
||||
<!--Timetable-->
|
||||
<string name="timetable_lesson">Lekcja</string>
|
||||
<string name="timetable_room">Sala</string>
|
||||
@ -180,6 +204,8 @@
|
||||
<string name="message_move_to_bin">Przenieś do kosza</string>
|
||||
<string name="message_delete_forever">Usuń trwale</string>
|
||||
<string name="message_delete_success">Wiadomość usunięta pomyślnie</string>
|
||||
<string name="message_share">Udostępnij</string>
|
||||
<string name="message_print">Drukuj</string>
|
||||
<string name="message_subject">Temat</string>
|
||||
<string name="message_content">Treść</string>
|
||||
<string name="message_send_successful">Wiadomość wysłana pomyślnie</string>
|
||||
@ -265,6 +291,10 @@
|
||||
<string name="account_logout">Wyloguj</string>
|
||||
<string name="account_confirm">Czy chcesz wylogować aktualnego ucznia?</string>
|
||||
<string name="account_logout_student">Wylogowanie ucznia</string>
|
||||
<string name="account_type_student">Konto ucznia</string>
|
||||
<string name="account_type_parent">Konto rodzica</string>
|
||||
<string name="account_login_mobile_api">Tryb API mobilne</string>
|
||||
<string name="account_login_hybrid">Tryb hybrydowy</string>
|
||||
<!--About-->
|
||||
<string name="about_version">Wersja aplikacji</string>
|
||||
<string name="about_contributor">Twórcy</string>
|
||||
@ -309,7 +339,7 @@
|
||||
<string name="all_prev">Poprzedni</string>
|
||||
<string name="all_next">Następny</string>
|
||||
<string name="all_search">Szukaj</string>
|
||||
<string name="all_search_hint">Szukaj...</string>
|
||||
<string name="all_search_hint">Szukaj…</string>
|
||||
<!--Timetable Widget-->
|
||||
<string name="widget_timetable_no_items">Brak lekcji</string>
|
||||
<string name="widget_timetable_theme_title">Wybierz motyw</string>
|
||||
|
@ -37,7 +37,7 @@
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Средняя оценка со 2 семестра</item>
|
||||
<item>Average of grades from both semesters</item>
|
||||
<item>Средняя оценка с целого года</item>
|
||||
<item>Average of grades from the whole year</item>
|
||||
</string-array>
|
||||
<string-array name="timetable_show_whole_class_entries">
|
||||
<item>Не показывать</item>
|
||||
|
@ -107,12 +107,36 @@
|
||||
<item quantity="many">Новые оценки</item>
|
||||
<item quantity="other">Новые оценки</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_predicted">
|
||||
<item quantity="one">New predicted grade</item>
|
||||
<item quantity="few">New predicted grades</item>
|
||||
<item quantity="many">New predicted grades</item>
|
||||
<item quantity="other">New predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_final">
|
||||
<item quantity="one">New final grade</item>
|
||||
<item quantity="few">New final grades</item>
|
||||
<item quantity="many">New final grades</item>
|
||||
<item quantity="other">New final grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items">
|
||||
<item quantity="one">Вы получили %1$d оценку</item>
|
||||
<item quantity="few">Вы получили %1$d оценки</item>
|
||||
<item quantity="many">Вы получили %1$d оценок</item>
|
||||
<item quantity="other">Вы получили %1$d оценок</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_predicted">
|
||||
<item quantity="one">You received %1$d predicted grade</item>
|
||||
<item quantity="few">You received %1$d predicted grades</item>
|
||||
<item quantity="many">You received %1$d predicted grades</item>
|
||||
<item quantity="other">You received %1$d predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_final">
|
||||
<item quantity="one">You received %1$d final grade</item>
|
||||
<item quantity="few">You received %1$d final grades</item>
|
||||
<item quantity="many">You received %1$d final grades</item>
|
||||
<item quantity="other">You received %1$d final grades</item>
|
||||
</plurals>
|
||||
<!--Timetable-->
|
||||
<string name="timetable_lesson">Урок</string>
|
||||
<string name="timetable_room">Аудитория</string>
|
||||
@ -180,6 +204,8 @@
|
||||
<string name="message_move_to_bin">Перенести в корзину</string>
|
||||
<string name="message_delete_forever">Удалить навсегда</string>
|
||||
<string name="message_delete_success">Сообщение успешно удалено</string>
|
||||
<string name="message_share">Share</string>
|
||||
<string name="message_print">Print</string>
|
||||
<string name="message_subject">Тема</string>
|
||||
<string name="message_content">Текст</string>
|
||||
<string name="message_send_successful">Сообщение успешно отправлено</string>
|
||||
@ -265,6 +291,10 @@
|
||||
<string name="account_logout">Выйти</string>
|
||||
<string name="account_confirm">Вы точно хотите выйти из данного аккаунта?</string>
|
||||
<string name="account_logout_student">Выйти</string>
|
||||
<string name="account_type_student">Student account</string>
|
||||
<string name="account_type_parent">Parent account</string>
|
||||
<string name="account_login_mobile_api">Mobile API mode</string>
|
||||
<string name="account_login_hybrid">Hybrid mode</string>
|
||||
<!--About-->
|
||||
<string name="about_version">Версия приложения</string>
|
||||
<string name="about_contributor">Разработчики</string>
|
||||
@ -309,7 +339,7 @@
|
||||
<string name="all_prev">Предыдущий</string>
|
||||
<string name="all_next">Следующий</string>
|
||||
<string name="all_search">Поиск</string>
|
||||
<string name="all_search_hint">Поиск...</string>
|
||||
<string name="all_search_hint">Поиск…</string>
|
||||
<!--Timetable Widget-->
|
||||
<string name="widget_timetable_no_items">Нет уроков</string>
|
||||
<string name="widget_timetable_theme_title">Выбрать тему</string>
|
||||
|
@ -37,7 +37,7 @@
|
||||
<string-array name="grade_average_mode_entries">
|
||||
<item>Середня оцінка з 2 семестру</item>
|
||||
<item>Average of grades from both semesters</item>
|
||||
<item>Середня оцінка за весь рік</item>
|
||||
<item>Average of grades from the whole year</item>
|
||||
</string-array>
|
||||
<string-array name="timetable_show_whole_class_entries">
|
||||
<item>Не показувати</item>
|
||||
|
@ -107,12 +107,36 @@
|
||||
<item quantity="many">Нові оцінки</item>
|
||||
<item quantity="other">Нові оцінки</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_predicted">
|
||||
<item quantity="one">New predicted grade</item>
|
||||
<item quantity="few">New predicted grades</item>
|
||||
<item quantity="many">New predicted grades</item>
|
||||
<item quantity="other">New predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_final">
|
||||
<item quantity="one">New final grade</item>
|
||||
<item quantity="few">New final grades</item>
|
||||
<item quantity="many">New final grades</item>
|
||||
<item quantity="other">New final grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items">
|
||||
<item quantity="one">Ви отримали %1$d оцінку</item>
|
||||
<item quantity="few">Ви отримали %1$d оцінки</item>
|
||||
<item quantity="many">Ви отримали %1$d оцінок</item>
|
||||
<item quantity="other">Ви отримали %1$d оцінок</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_predicted">
|
||||
<item quantity="one">You received %1$d predicted grade</item>
|
||||
<item quantity="few">You received %1$d predicted grades</item>
|
||||
<item quantity="many">You received %1$d predicted grades</item>
|
||||
<item quantity="other">You received %1$d predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_final">
|
||||
<item quantity="one">You received %1$d final grade</item>
|
||||
<item quantity="few">You received %1$d final grades</item>
|
||||
<item quantity="many">You received %1$d final grades</item>
|
||||
<item quantity="other">You received %1$d final grades</item>
|
||||
</plurals>
|
||||
<!--Timetable-->
|
||||
<string name="timetable_lesson">Урок</string>
|
||||
<string name="timetable_room">Аудиторія</string>
|
||||
@ -180,6 +204,8 @@
|
||||
<string name="message_move_to_bin">Перемістити у кошик</string>
|
||||
<string name="message_delete_forever">Видалити назавжди</string>
|
||||
<string name="message_delete_success">Повідомлення було успішно видалено</string>
|
||||
<string name="message_share">Share</string>
|
||||
<string name="message_print">Print</string>
|
||||
<string name="message_subject">Тема</string>
|
||||
<string name="message_content">Зміст</string>
|
||||
<string name="message_send_successful">Повідомлення було успішно відправлено</string>
|
||||
@ -265,6 +291,10 @@
|
||||
<string name="account_logout">Вийти</string>
|
||||
<string name="account_confirm">Ви впевнені, що хочете вийти з цього аккаунту?</string>
|
||||
<string name="account_logout_student">Вийти з аккаунту учня</string>
|
||||
<string name="account_type_student">Student account</string>
|
||||
<string name="account_type_parent">Parent account</string>
|
||||
<string name="account_login_mobile_api">Mobile API mode</string>
|
||||
<string name="account_login_hybrid">Hybrid mode</string>
|
||||
<!--About-->
|
||||
<string name="about_version">Версія додатка</string>
|
||||
<string name="about_contributor">Розробники</string>
|
||||
@ -309,7 +339,7 @@
|
||||
<string name="all_prev">Попередній</string>
|
||||
<string name="all_next">Наступний</string>
|
||||
<string name="all_search">Пошук</string>
|
||||
<string name="all_search_hint">Пошук...</string>
|
||||
<string name="all_search_hint">Пошук…</string>
|
||||
<!--Timetable Widget-->
|
||||
<string name="widget_timetable_no_items">Брак уроків</string>
|
||||
<string name="widget_timetable_theme_title">Увібрати тему</string>
|
||||
|
@ -113,10 +113,26 @@
|
||||
<item quantity="one">New grade</item>
|
||||
<item quantity="other">New grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_predicted">
|
||||
<item quantity="one">New predicted grade</item>
|
||||
<item quantity="other">New predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_new_items_final">
|
||||
<item quantity="one">New final grade</item>
|
||||
<item quantity="other">New final grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items">
|
||||
<item quantity="one">You received %1$d grade</item>
|
||||
<item quantity="other">You received %1$d grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_predicted">
|
||||
<item quantity="one">You received %1$d predicted grade</item>
|
||||
<item quantity="other">You received %1$d predicted grades</item>
|
||||
</plurals>
|
||||
<plurals name="grade_notify_new_items_final">
|
||||
<item quantity="one">You received %1$d final grade</item>
|
||||
<item quantity="other">You received %1$d final grades</item>
|
||||
</plurals>
|
||||
|
||||
|
||||
<!--Timetable-->
|
||||
@ -194,6 +210,8 @@
|
||||
<string name="message_move_to_bin">Move to trash</string>
|
||||
<string name="message_delete_forever">Delete permanently</string>
|
||||
<string name="message_delete_success">Message deleted successfully</string>
|
||||
<string name="message_share">Share</string>
|
||||
<string name="message_print">Print</string>
|
||||
<string name="message_subject">Subject</string>
|
||||
<string name="message_content">Content</string>
|
||||
<string name="message_send_successful">Message sent successfully</string>
|
||||
@ -282,6 +300,10 @@
|
||||
<string name="account_logout">Logout</string>
|
||||
<string name="account_confirm">Do you want to log out of an active student?</string>
|
||||
<string name="account_logout_student">Student logout</string>
|
||||
<string name="account_type_student">Student account</string>
|
||||
<string name="account_type_parent">Parent account</string>
|
||||
<string name="account_login_mobile_api">Mobile API mode</string>
|
||||
<string name="account_login_hybrid">Hybrid mode</string>
|
||||
|
||||
|
||||
<!--About-->
|
||||
@ -339,7 +361,7 @@
|
||||
<string name="all_prev">Prev</string>
|
||||
<string name="all_next">Next</string>
|
||||
<string name="all_search">Search</string>
|
||||
<string name="all_search_hint">Search...</string>
|
||||
<string name="all_search_hint">Search…</string>
|
||||
|
||||
|
||||
<!--Timetable Widget-->
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.wulkanowy
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.Timetable
|
||||
@ -72,3 +73,25 @@ fun getTimetableEntity(
|
||||
teacher = "",
|
||||
teacherOld = ""
|
||||
)
|
||||
|
||||
fun getMessageEntity(
|
||||
messageId: Int,
|
||||
content: String,
|
||||
unread: Boolean
|
||||
) = Message(
|
||||
studentId = 1,
|
||||
realId = 1,
|
||||
messageId = messageId,
|
||||
sender = "",
|
||||
senderId = 1,
|
||||
recipient = "",
|
||||
subject = "",
|
||||
content = content,
|
||||
date = now(),
|
||||
folderId = 1,
|
||||
unread = unread,
|
||||
unreadBy = 1,
|
||||
readBy = 1,
|
||||
removed = false,
|
||||
hasAttachments = false
|
||||
)
|
||||
|
@ -2,10 +2,10 @@ package io.github.wulkanowy.data.repositories.message
|
||||
|
||||
import androidx.room.EmptyResultSetException
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy
|
||||
import io.github.wulkanowy.getMessageEntity
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.observers.TestObserver
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -15,7 +15,6 @@ import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.threeten.bp.LocalDateTime.now
|
||||
import java.net.UnknownHostException
|
||||
|
||||
class MessageRepositoryTest {
|
||||
@ -44,7 +43,7 @@ class MessageRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun `throw error when message is not in the db`() {
|
||||
val testMessage = Message(1, 1, 1, "", 1, "", "", "", now(), 1, false, 1, 1, false, false)
|
||||
val testMessage = getMessageEntity(1, "", false)
|
||||
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.error(EmptyResultSetException("No message in database")))
|
||||
|
||||
val message = repo.getMessage(student, testMessage)
|
||||
@ -55,7 +54,7 @@ class MessageRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun `get message when content already in db`() {
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "Test", now(), 1, false, 1, 1, false, false)
|
||||
val testMessage = getMessageEntity(123, "Test", false)
|
||||
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
|
||||
|
||||
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.just(messageWithAttachment))
|
||||
@ -67,7 +66,7 @@ class MessageRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun `get message when content in db is empty`() {
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false, false)
|
||||
val testMessage = getMessageEntity(123, "", true)
|
||||
val testMessageWithContent = testMessage.copy(content = "Test")
|
||||
|
||||
val mWa = MessageWithAttachment(testMessage, emptyList())
|
||||
@ -86,7 +85,7 @@ class MessageRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun `get message when content in db is empty and there is no internet connection`() {
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, false, 1, 1, false, false)
|
||||
val testMessage = getMessageEntity(123, "", false)
|
||||
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
|
||||
|
||||
testObservingStrategy.isInternetConnection = false
|
||||
@ -100,7 +99,7 @@ class MessageRepositoryTest {
|
||||
|
||||
@Test
|
||||
fun `get message when content in db is empty, unread and there is no internet connection`() {
|
||||
val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false, false)
|
||||
val testMessage = getMessageEntity(123, "", true)
|
||||
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
|
||||
|
||||
testObservingStrategy.isInternetConnection = false
|
||||
|
@ -1,6 +1,6 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.72'
|
||||
ext.about_libraries = '8.1.6'
|
||||
ext.about_libraries = '8.2.0'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
@ -13,7 +13,7 @@ buildscript {
|
||||
classpath 'com.google.gms:google-services:4.3.3'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
|
||||
classpath "com.github.triplet.gradle:play-publisher:2.7.5"
|
||||
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
|
||||
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
|
||||
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
|
||||
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${about_libraries}"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user