forked from github/wulkanowy-mirror
Merge branch 'release/0.10.0'
This commit is contained in:
commit
750fa9a76d
19
.idea/codeStyles/Project.xml
generated
19
.idea/codeStyles/Project.xml
generated
@ -1,9 +1,6 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
<code_scheme name="Project" version="173">
|
<code_scheme name="Project" version="173">
|
||||||
<option name="LINE_SEPARATOR" value=" " />
|
<option name="LINE_SEPARATOR" value=" " />
|
||||||
<AndroidXmlCodeStyleSettings>
|
|
||||||
<option name="USE_CUSTOM_SETTINGS" value="true" />
|
|
||||||
</AndroidXmlCodeStyleSettings>
|
|
||||||
<JetCodeStyleSettings>
|
<JetCodeStyleSettings>
|
||||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||||
<value>
|
<value>
|
||||||
@ -24,13 +21,7 @@
|
|||||||
<MarkdownNavigatorCodeStyleSettings>
|
<MarkdownNavigatorCodeStyleSettings>
|
||||||
<option name="RIGHT_MARGIN" value="72" />
|
<option name="RIGHT_MARGIN" value="72" />
|
||||||
</MarkdownNavigatorCodeStyleSettings>
|
</MarkdownNavigatorCodeStyleSettings>
|
||||||
<XML>
|
|
||||||
<option name="XML_KEEP_LINE_BREAKS" value="false" />
|
|
||||||
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
|
|
||||||
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
|
||||||
</XML>
|
|
||||||
<codeStyleSettings language="XML">
|
<codeStyleSettings language="XML">
|
||||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
</indentOptions>
|
</indentOptions>
|
||||||
@ -41,6 +32,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>xmlns:android</NAME>
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -51,6 +43,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>xmlns:.*</NAME>
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -62,6 +55,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*:id</NAME>
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -72,6 +66,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*:name</NAME>
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -82,6 +77,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>name</NAME>
|
<NAME>name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -92,6 +88,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>style</NAME>
|
<NAME>style</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -102,6 +99,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -113,6 +111,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -124,6 +123,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -141,7 +141,6 @@
|
|||||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
</indentOptions>
|
</indentOptions>
|
||||||
|
@ -14,7 +14,7 @@ cache:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- develop
|
- develop
|
||||||
- 0.9.4
|
- 0.10.0
|
||||||
|
|
||||||
android:
|
android:
|
||||||
licenses:
|
licenses:
|
||||||
|
@ -17,8 +17,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 42
|
versionCode 43
|
||||||
versionName "0.9.4"
|
versionName "0.10.0"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
@ -28,7 +28,8 @@ android {
|
|||||||
]
|
]
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
|
arguments = ["room.schemaLocation": "$projectDir/schemas".toString(),
|
||||||
|
"room.incremental" : "true"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,6 +66,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flavorDimensions "platform"
|
flavorDimensions "platform"
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
play {
|
play {
|
||||||
dimension "platform"
|
dimension "platform"
|
||||||
@ -84,6 +86,15 @@ android {
|
|||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
packagingOptions {
|
||||||
|
exclude 'META-INF/library_release.kotlin_module'
|
||||||
|
exclude 'META-INF/library-core_release.kotlin_module'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
androidExtensions {
|
androidExtensions {
|
||||||
@ -98,38 +109,49 @@ play {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
work_manager = "2.1.0"
|
work_manager = "2.2.0"
|
||||||
room = "2.1.0"
|
room = "2.2.0-beta01"
|
||||||
dagger = "2.24"
|
dagger = "2.24"
|
||||||
chucker = "2.0.4"
|
chucker = "2.0.4"
|
||||||
mockk = "1.9.2"
|
mockk = "1.9.2"
|
||||||
mockito_core = "3.0.4"
|
mockito_core = "3.0.6"
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||||
|
resolutionStrategy.force "com.google.android.material:material:1.1.0-alpha07"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:api:0.9.4"
|
implementation "io.github.wulkanowy:api:0.10.0"
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "androidx.core:core:1.0.2"
|
implementation "androidx.core:core-ktx:1.1.0-rc03"
|
||||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
implementation "androidx.activity:activity-ktx:1.0.0-rc01"
|
||||||
implementation "androidx.fragment:fragment:1.0.0"
|
implementation "androidx.appcompat:appcompat:1.1.0-rc01"
|
||||||
|
implementation "androidx.appcompat:appcompat-resources:1.1.0-rc01"
|
||||||
|
implementation "androidx.fragment:fragment-ktx:1.1.0-rc04"
|
||||||
implementation "androidx.annotation:annotation:1.1.0"
|
implementation "androidx.annotation:annotation:1.1.0"
|
||||||
implementation "androidx.multidex:multidex:2.0.1"
|
implementation "androidx.multidex:multidex:2.0.1"
|
||||||
|
|
||||||
implementation "androidx.recyclerview:recyclerview:1.0.0"
|
implementation "androidx.preference:preference-ktx:1.1.0-rc01"
|
||||||
|
implementation "androidx.recyclerview:recyclerview:1.1.0-beta03"
|
||||||
implementation "androidx.viewpager:viewpager:1.0.0"
|
implementation "androidx.viewpager:viewpager:1.0.0"
|
||||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||||
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.0.0"
|
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0-beta01"
|
||||||
implementation "com.google.android.material:material:1.1.0-alpha07"
|
implementation "com.google.android.material:material:1.1.0-alpha07"
|
||||||
implementation "com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f"
|
implementation "com.github.wulkanowy:material-chips-input:2.0.1"
|
||||||
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
||||||
|
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
|
||||||
|
|
||||||
implementation "androidx.work:work-runtime:$work_manager"
|
implementation "androidx.work:work-runtime-ktx:$work_manager"
|
||||||
implementation "androidx.work:work-rxjava2:$work_manager"
|
implementation "androidx.work:work-rxjava2:$work_manager"
|
||||||
|
implementation "androidx.work:work-gcm:$work_manager"
|
||||||
|
|
||||||
implementation "androidx.room:room-runtime:$room"
|
implementation "androidx.room:room-runtime:$room"
|
||||||
implementation "androidx.room:room-rxjava2:$room"
|
implementation "androidx.room:room-rxjava2:$room"
|
||||||
|
implementation "androidx.room:room-ktx:$room"
|
||||||
kapt "androidx.room:room-compiler:$room"
|
kapt "androidx.room:room-compiler:$room"
|
||||||
|
|
||||||
implementation "com.google.dagger:dagger-android-support:$dagger"
|
implementation "com.google.dagger:dagger-android-support:$dagger"
|
||||||
@ -143,20 +165,18 @@ dependencies {
|
|||||||
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
|
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
|
||||||
implementation "com.ncapdevi:frag-nav:3.3.0"
|
implementation "com.ncapdevi:frag-nav:3.3.0"
|
||||||
|
|
||||||
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.4"
|
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6"
|
||||||
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
||||||
implementation "io.reactivex.rxjava2:rxjava:2.2.11"
|
implementation "io.reactivex.rxjava2:rxjava:2.2.12"
|
||||||
|
|
||||||
implementation "com.google.code.gson:gson:2.8.5"
|
implementation "com.google.code.gson:gson:2.8.5"
|
||||||
implementation "com.jakewharton.threetenabp:threetenabp:1.2.1"
|
implementation "com.jakewharton.threetenabp:threetenabp:1.2.1"
|
||||||
implementation "com.jakewharton.timber:timber:4.7.1"
|
implementation "com.jakewharton.timber:timber:4.7.1"
|
||||||
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
||||||
implementation "com.squareup.okhttp3:logging-interceptor:3.12.3"
|
implementation "com.squareup.okhttp3:logging-interceptor:3.12.3"
|
||||||
|
implementation "com.mikepenz:aboutlibraries:7.0.3"
|
||||||
|
|
||||||
implementation "com.mikepenz:aboutlibraries:6.2.3"
|
playImplementation "com.google.firebase:firebase-core:17.2.0"
|
||||||
implementation "com.takisoft.preferencex:preferencex:1.0.0"
|
|
||||||
|
|
||||||
playImplementation "com.google.firebase:firebase-core:17.0.1"
|
|
||||||
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
|
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
|
||||||
|
|
||||||
releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
|
releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
|
||||||
@ -168,7 +188,7 @@ dependencies {
|
|||||||
testImplementation "io.mockk:mockk:$mockk"
|
testImplementation "io.mockk:mockk:$mockk"
|
||||||
testImplementation "org.threeten:threetenbp:1.4.0"
|
testImplementation "org.threeten:threetenbp:1.4.0"
|
||||||
testImplementation "org.mockito:mockito-core:$mockito_core"
|
testImplementation "org.mockito:mockito-core:$mockito_core"
|
||||||
testImplementation("org.mockito:mockito-inline:3.0.4") {
|
testImplementation("org.mockito:mockito-inline:3.0.6") {
|
||||||
exclude group: "org.mockito", module: "mockito-core"
|
exclude group: "org.mockito", module: "mockito-core"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +199,7 @@ dependencies {
|
|||||||
androidTestImplementation "androidx.room:room-testing:$room"
|
androidTestImplementation "androidx.room:room-testing:$room"
|
||||||
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
androidTestImplementation "org.mockito:mockito-core:$mockito_core"
|
androidTestImplementation "org.mockito:mockito-core:$mockito_core"
|
||||||
androidTestImplementation("org.mockito:mockito-android:3.0.4") {
|
androidTestImplementation("org.mockito:mockito-android:3.0.6") {
|
||||||
exclude group: 'org.mockito', module: 'mockito-core'
|
exclude group: 'org.mockito', module: 'mockito-core'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
apply plugin: "jacoco"
|
apply plugin: "jacoco"
|
||||||
|
|
||||||
jacoco {
|
jacoco {
|
||||||
toolVersion "0.8.3"
|
toolVersion "0.8.4"
|
||||||
reportsDir = file("$buildDir/reports")
|
reportsDir = file("$buildDir/reports")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
app/proguard-rules.pro
vendored
9
app/proguard-rules.pro
vendored
@ -11,6 +11,10 @@
|
|||||||
-verbose
|
-verbose
|
||||||
|
|
||||||
|
|
||||||
|
#Keep all wulkanowy files
|
||||||
|
-keep class io.github.wulkanowy.** {*;}
|
||||||
|
|
||||||
|
|
||||||
#Config for anallitycs
|
#Config for anallitycs
|
||||||
-keepattributes *Annotation*
|
-keepattributes *Annotation*
|
||||||
-keepattributes SourceFile,LineNumberTable
|
-keepattributes SourceFile,LineNumberTable
|
||||||
@ -32,11 +36,10 @@
|
|||||||
-dontwarn rx.internal.util.**
|
-dontwarn rx.internal.util.**
|
||||||
-dontwarn sun.misc.Unsafe
|
-dontwarn sun.misc.Unsafe
|
||||||
|
|
||||||
|
|
||||||
#Config for MPAndroidChart
|
#Config for MPAndroidChart
|
||||||
-keep class com.github.mikephil.charting.** { *; }
|
-keep class com.github.mikephil.charting.** { *; }
|
||||||
|
|
||||||
#Config for API
|
|
||||||
-keep class io.github.wulkanowy.api.** {*;}
|
|
||||||
|
|
||||||
#Config for Material Components
|
#Config for Material Components
|
||||||
-keep class com.google.android.material.tabs.** {*;}
|
-keep class com.google.android.material.tabs.**
|
@ -5,7 +5,7 @@ import androidx.room.Room
|
|||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import io.github.wulkanowy.data.db.AppDatabase
|
import io.github.wulkanowy.data.db.AppDatabase
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -21,14 +21,14 @@ class StudentLocalTest {
|
|||||||
|
|
||||||
private lateinit var testDb: AppDatabase
|
private lateinit var testDb: AppDatabase
|
||||||
|
|
||||||
private lateinit var sharedHelper: SharedPrefHelper
|
private lateinit var sharedProvider: SharedPrefProvider
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun createDb() {
|
fun createDb() {
|
||||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||||
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
||||||
.build()
|
.build()
|
||||||
sharedHelper = SharedPrefHelper(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
|
sharedProvider = SharedPrefProvider(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
|
||||||
studentLocal = StudentLocal(testDb.studentDao, context)
|
studentLocal = StudentLocal(testDb.studentDao, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import org.threeten.bp.LocalDateTime.now
|
|||||||
import io.github.wulkanowy.api.timetable.Timetable as TimetableRemote
|
import io.github.wulkanowy.api.timetable.Timetable as TimetableRemote
|
||||||
import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal
|
import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal
|
||||||
|
|
||||||
fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", subject: String = "", teacher: String = ""): TimetableLocal {
|
fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableLocal {
|
||||||
return TimetableLocal(
|
return TimetableLocal(
|
||||||
studentId = 1,
|
studentId = 1,
|
||||||
diaryId = 2,
|
diaryId = 2,
|
||||||
@ -23,12 +23,12 @@ fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", s
|
|||||||
teacher = teacher,
|
teacher = teacher,
|
||||||
teacherOld = "",
|
teacherOld = "",
|
||||||
info = "",
|
info = "",
|
||||||
changes = false,
|
changes = changes,
|
||||||
canceled = false
|
canceled = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subject: String = "", teacher: String = ""): TimetableRemote {
|
fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subject: String = "", teacher: String = "", changes: Boolean = false): TimetableRemote {
|
||||||
return TimetableRemote(
|
return TimetableRemote(
|
||||||
number = number,
|
number = number,
|
||||||
start = start.toDate(),
|
start = start.toDate(),
|
||||||
@ -39,7 +39,7 @@ fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subje
|
|||||||
room = room,
|
room = room,
|
||||||
teacher = teacher,
|
teacher = teacher,
|
||||||
info = "",
|
info = "",
|
||||||
changes = false,
|
changes = changes,
|
||||||
canceled = false
|
canceled = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ class TimetableRepositoryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun copyDetailsToCompletedFromPrevious() {
|
fun copyRoomToCompletedFromPrevious() {
|
||||||
timetableLocal.saveTimetable(listOf(
|
timetableLocal.saveTimetable(listOf(
|
||||||
createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda"),
|
createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda"),
|
||||||
createTimetableLocal(2, of(2019, 3, 5, 8, 50), "321", "Religia"),
|
createTimetableLocal(2, of(2019, 3, 5, 8, 50), "321", "Religia"),
|
||||||
@ -83,7 +83,32 @@ class TimetableRepositoryTest {
|
|||||||
assertEquals("123", lessons[0].room)
|
assertEquals("123", lessons[0].room)
|
||||||
assertEquals("321", lessons[1].room)
|
assertEquals("321", lessons[1].room)
|
||||||
assertEquals("213", lessons[2].room)
|
assertEquals("213", lessons[2].room)
|
||||||
|
}
|
||||||
|
|
||||||
assertEquals("", lessons[3].teacher)
|
@Test
|
||||||
|
fun copyTeacherToCompletedFromPrevious() {
|
||||||
|
timetableLocal.saveTimetable(listOf(
|
||||||
|
createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda", "Jan Garnkiewicz", false),
|
||||||
|
createTimetableLocal(2, of(2019, 3, 5, 8, 50), "321", "Religia", "Paweł Jumper", false),
|
||||||
|
createTimetableLocal(3, of(2019, 3, 5, 9, 40), "213", "W-F", "", true),
|
||||||
|
createTimetableLocal(4, of(2019, 3, 5, 10, 30), "213", "W-F", "", false)
|
||||||
|
))
|
||||||
|
|
||||||
|
every { mockApi.getTimetable(any(), any()) } returns Single.just(listOf(
|
||||||
|
createTimetableRemote(1, of(2019, 3, 5, 8, 0), "", "Przyroda", "", true), // should override local
|
||||||
|
createTimetableRemote(2, of(2019, 3, 5, 8, 50), "", "Religia", "", false),
|
||||||
|
createTimetableRemote(3, of(2019, 3, 5, 9, 40), "", "W-F", "Jan Garnkiewicz", false),
|
||||||
|
createTimetableRemote(4, of(2019, 3, 5, 10, 30), "", "W-F", "Paweł Jumper", false)
|
||||||
|
))
|
||||||
|
|
||||||
|
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
|
||||||
|
.getTimetable(semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
|
||||||
|
.blockingGet()
|
||||||
|
|
||||||
|
assertEquals(4, lessons.size)
|
||||||
|
assertEquals("", lessons[0].teacher)
|
||||||
|
assertEquals("Paweł Jumper", lessons[1].teacher)
|
||||||
|
assertEquals("Jan Garnkiewicz", lessons[2].teacher)
|
||||||
|
assertEquals("Paweł Jumper", lessons[3].teacher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="1926.9231"
|
|
||||||
android:viewportHeight="1926.9231">
|
|
||||||
<group android:translateX="462.46155"
|
|
||||||
android:translateY="462.46155">
|
|
||||||
<path
|
|
||||||
android:pathData="M2000,1440.1V2002H1240.1L238.1,1000v0l-120,-120c0.2,-0.2 -0.7,-1.6 -0.6,-1.8 1.6,-3.1 3.4,-6 5,-9.1 0.4,-0.8 0.6,-1.6 0.6,-2.5 9.2,-15.1 20.2,-28.9 31.4,-42.6 0.1,-0.2 0.3,-0.3 0.4,-0.5 5.1,-6.3 10.3,-12.6 15.3,-18.9 1,-1.2 1.9,-2.4 2.9,-3.7 0.2,-0.2 0.3,-0.4 0.5,-0.6 7.6,-9.7 14.8,-19.7 21.2,-30.2 1,-1.7 2,-3.4 2.9,-5.1 0.1,-0.2 0.2,-0.3 0.3,-0.5 6.2,-11.4 11.3,-23.3 17.7,-34.6 4.5,-8 9.3,-15.9 13.8,-23.9 0.1,-0.2 0.2,-0.3 0.3,-0.5 0.8,-1.5 1.6,-3 2.4,-4.4 0.2,-0.3 0.3,-0.6 0.5,-0.9 2,-3.7 3.8,-7.4 5.6,-11.2 6.2,-13.4 10.2,-27.7 14,-41.9 0,-0.2 0.1,-0.3 0.1,-0.5 0.3,-1 0.5,-2 0.8,-2.9 4,-15.3 7.3,-31.4 13.5,-45.9 1.4,-3.3 3,-6.5 4.6,-9.6 0.1,-0.2 0.2,-0.3 0.3,-0.5 5,-9.7 10.6,-19.1 13.5,-29.7 2.6,-9.2 3.5,-19 3.6,-28.8 0,-0.2 0,-0.3 0,-0.5 0.1,-7.2 -0.1,-14.4 -0.4,-21.3 0.9,-5.6 1.9,-11.3 3,-16.9 0.2,-0.9 0.3,-1.7 0.5,-2.6 1.2,-5.9 2.5,-11.7 4.2,-17.4 0,-0.1 0.1,-0.3 0.1,-0.4 0,-0.2 0.1,-0.3 0.1,-0.5 0.2,-2.1 -0.8,-3.7 -2.4,-4.5l7.7,-7.6c1.2,0.9 2.7,1.3 4.3,0.9 12.8,-3.9 24.9,-9.9 36.3,-16.8 2.8,-1.7 5.6,-3.4 8.3,-5.2 0.2,-0.1 0.3,-0.2 0.5,-0.3 7.7,-4.9 15.2,-10.2 22.1,-16 3.1,-2.7 5.9,-5.6 8.3,-8.9 0.1,-0.2 0.2,-0.3 0.4,-0.5 2.3,-3.4 4.2,-7.2 5.3,-11.4 2.4,-9.2 1.9,-19 1.9,-28.4 0,-0.2 0,-0.4 0,-0.6l5.7,-5.6 -0.3,0.1 4.1,1.3 45.3,45 9.6,9.6 14.3,14.3 100.8,100.8 17.2,17.2 16.3,16.3 30.3,-30.3 -192.9,-191.5c0.5,-0.5 1.1,-1.6 1.4,-2.3 0.3,-0.6 0.5,-1.2 0.4,-1.9 0,-0.8 -0.2,-1.6 -0.6,-2.3 -0.1,-0.3 -0.3,-0.7 -0.4,-1 -0.2,-0.4 -0.5,-0.7 -0.9,-1.1l27.8,-27.8 191.1,-191.1c0.7,0.4 1.5,0.6 2.5,0.7 4.1,0 8.2,0.1 11.9,1.9 0.5,0.3 1.3,0.7 2.1,1.1 1.7,2.3 3.5,4.5 5.7,6.2 2.7,2.1 8.2,3 9.4,0.3z"
|
|
||||||
android:fillColor="#AD2A2A"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m616.3,796.7c0.4,1.2 0.5,2.4 0.5,3.7l-5.8,73.3c-0.4,5.2 -5,9.3 -10.6,9.3h-187.2c-4,0 -7.7,-2.3 -9.5,-5.6l-30.9,-57.4c-0.2,-0.3 -0.3,-0.6 -0.4,-0.9l-29.1,-70.5c-1.1,-2.5 -0.9,-5.4 0.3,-7.8l48.3,-94.5c1.2,-2.3 1.4,-5 0.5,-7.4l-23.6,-65.4c-0.8,-2.3 -0.7,-4.9 0.3,-7.1l39.4,-83.9c4,-8.4 17.1,-7.7 19.9,1.1l12.3,38.2 37.5,100.4c1,2.8 3.4,5 6.4,6l80,27.3c3.1,1.1 5.5,3.4 6.5,6.3z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m386.7,253.5c0,-22.9 14.5,-42.6 35.3,-51.8 -1.5,-2.5 -2.4,-5.2 -2.4,-8.1 0,-11.1 12.8,-20.1 28.5,-20.1 0.4,0 0.7,0 1.1,0 6.5,-10.8 18.9,-18.1 33.1,-18.1 1,0 2,0 3,0.1 1.3,0.1 2.6,-0.5 3.3,-1.5 10.5,-16 37.1,-27.4 68.2,-27.4 11.5,0 22.4,1.6 32.1,4.3 2.3,-3.8 7.4,-6.4 13.3,-6.4 6.7,0 12.4,3.4 14.1,8.1 8.2,-9.5 22.1,-15.7 37.9,-15.7 25.2,0 45.6,15.9 45.6,35.5 0,2.4 -0.3,4.7 -0.9,7 -0.4,1.6 0.5,3.2 2.2,3.8 16.1,5.9 27,17.1 27,29.9 0,14.6 -14.1,27.1 -34,32 -1.6,0.4 -2.6,1.8 -2.6,3.3 0,0.1 0,0.2 0,0.3 0,11.3 -11.2,20.6 -25.6,21.6 0.1,0.5 0.1,1 0.1,1.6 0,21.7 -41.3,39.2 -92.2,39.2 -11,0 -21.5,-0.8 -31.2,-2.3 0,0.2 0,0.3 0,0.5 0,9 -11.6,16.3 -25.8,16.3 -0.8,0 -1.5,0 -2.2,-0.1 1,2.2 1.5,4.5 1.5,6.9 0,14 -17.7,25.3 -39.6,25.3 -2.4,0 -4.7,-0.1 -7,-0.4 -1.8,-0.2 -3.5,0.9 -3.9,2.6 -1.9,7 -8,12.1 -15.3,12.1 -8.8,0 -15.8,-7.5 -15.8,-16.7 0,-4.3 1.5,-8.2 4,-11.1 0.9,-1 1.2,-2.4 0.6,-3.6 -1.4,-2.6 -2,-5.3 -2,-8.2v0c0,-1.6 -1.3,-2.9 -2.9,-3.3 -27.1,-6 -47.5,-28.6 -47.5,-55.6z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m870.4,883h-124.4c-3.6,0 -6.9,-1.8 -8.9,-4.6l-83.7,-117.7c-0.5,-0.8 -1,-1.6 -1.3,-2.5l-41.5,-121.2c-0.8,-2.4 -2.7,-4.5 -5.1,-5.7l-101.6,-51.3c-2.8,-1.4 -4.8,-4 -5.4,-6.9l-15,-74.4c-0.2,-1.2 -0.7,-2.4 -1.5,-3.5l-34.5,-50.7c-1.9,-2.8 -2.2,-6.2 -0.8,-9.2l21,-44.9c1.6,-3.4 5.1,-5.7 9.1,-5.9l39,-2.3c2.3,-0.1 4.4,-0.9 6.1,-2.3l28.7,-22.3c5.4,-4.2 13.6,-2.4 16.5,3.5l98.9,201.2c0.4,0.9 0.7,1.8 0.9,2.7l12.2,80.9c0.3,1.9 1.1,3.6 2.4,5l197,215.6c5.8,6.4 0.9,16.5 -8.1,16.5z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m335.8,838.9c0.8,2.6 0.4,5.4 -1,7.7l-19.3,31.3c-1.9,3.1 -5.4,5.1 -9.2,5.1h-180.6c-8.4,0 -13.5,-8.8 -9,-15.4l116.3,-171.3c0.7,-1 1.1,-2.1 1.4,-3.2l53.3,-227.6c0.6,-2.7 2.4,-5 5,-6.4l72.2,-39.6c2.6,-1.4 4.4,-3.7 5,-6.5l9.7,-42.3c2,-8.8 14.6,-10.7 19.6,-3l3.5,5.6c1.5,2.4 1.9,5.4 0.9,8.1l-65.8,190.2c-0.5,1.5 -0.7,3.1 -0.4,4.7l16.4,91c0.3,1.8 0.1,3.7 -0.7,5.4l-39.1,87.8c-0.9,2.1 -1.1,4.4 -0.4,6.5z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m424.22,657.05 l1580.54,-0.05c0.54,0 0,292 0,292l-1580.54,-0.03c-10.78,0 -19.46,-8.68 -19.46,-19.46l0,-252.99c0,-10.78 8.68,-19.46 19.46,-19.46z"
|
|
||||||
android:strokeAlpha="0.49803922"
|
|
||||||
android:strokeLineJoin="round"
|
|
||||||
android:strokeWidth="4"
|
|
||||||
android:fillColor="#3f3f3f"
|
|
||||||
android:strokeColor="#00000000"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:fillAlpha="1"
|
|
||||||
android:strokeLineCap="square"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m728.71,710.91l0,19.89l-88.7,0l0,59.3l77.04,0L717.05,810l-77.04,0l0,65.39l89.84,0l0,19.9L616.56,895.29L616.56,791.16l-52.35,-52.35 -0.77,-0.18c5.41,6.64 9.65,14.32 12.69,23.09 3.72,10.39 5.62,21.92 5.7,34.6L581.84,809.87c-0.08,12.67 -1.98,24.25 -5.7,34.72 -3.63,10.39 -8.95,19.35 -15.97,26.87 -6.93,7.43 -15.46,13.26 -25.6,17.49 -7.54,3.1 -15.86,5.07 -24.97,5.89 -3.04,0.27 -6.16,0.42 -9.37,0.45L457.53,895.29l0,-6.55l-0.37,6.82 53.8,53.45l415.85,0c0.24,0 0.47,-0.02 0.69,-0.05L1132.91,948.97L953.5,769.55l-58.39,-58.39 -0.28,0.06 -58.03,184.06l-20.4,0l-44.66,-141.34zM783.29,711.07 L826.41,857.52 850.08,777.86zM509.6,711.29c1.52,0.15 3.01,0.33 4.49,0.54 -1.47,-0.21 -2.97,-0.39 -4.49,-0.54zM481.35,730.04l0,146.11l18.88,0c9.97,-0.08 18.59,-1.81 25.85,-5.19 7.27,-3.46 13.26,-8.15 17.99,-14.07 4.82,-5.91 8.36,-12.88 10.64,-20.91 2.37,-8.03 3.59,-16.73 3.68,-26.11l0,-13.81c-0.08,-9.38 -1.31,-18.04 -3.68,-25.98 -2.37,-8.03 -5.91,-14.95 -10.64,-20.78 -4.73,-5.91 -10.73,-10.56 -17.99,-13.94 -7.27,-3.38 -15.88,-5.15 -25.85,-5.32zM560.17,734.86c0.65,0.69 1.26,1.4 1.88,2.11 -0.61,-0.72 -1.23,-1.42 -1.88,-2.11z"
|
|
||||||
android:strokeAlpha="1"
|
|
||||||
android:strokeLineJoin="miter"
|
|
||||||
android:strokeWidth="1.94642854"
|
|
||||||
android:fillColor="#000000"
|
|
||||||
android:strokeColor="#00000000"
|
|
||||||
android:fillAlpha="0.18431373"
|
|
||||||
android:strokeLineCap="butt"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m457.53,895.28l0,-184.51l42.7,0q19.26,0.25 34.34,6.59 15.21,6.21 25.6,17.49 10.52,11.15 15.97,26.86 5.58,15.59 5.7,34.59l0,13.56q-0.13,19.01 -5.7,34.72 -5.45,15.59 -15.97,26.86 -10.39,11.15 -25.6,17.49 -15.08,6.21 -34.34,6.34zM481.35,730.04l0,146.11l18.88,0q14.95,-0.13 25.85,-5.2 10.9,-5.2 17.99,-14.07 7.22,-8.87 10.64,-20.91 3.55,-12.04 3.67,-26.1l0,-13.81q-0.13,-14.07 -3.67,-25.98 -3.55,-12.04 -10.64,-20.78 -7.1,-8.87 -17.99,-13.94 -10.9,-5.07 -25.85,-5.32z"
|
|
||||||
android:fillColor="#ffffff"
|
|
||||||
android:strokeColor="#00000000"
|
|
||||||
android:fillAlpha="1"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M717.05,810L640.01,810l0,65.39l89.84,0l0,19.9l-113.29,0l0,-184.51l112.15,0l0,20.02L640.01,730.8l0,59.31l77.05,0z"
|
|
||||||
android:fillColor="#ffffff"
|
|
||||||
android:strokeColor="#00000000"
|
|
||||||
android:fillAlpha="1"/>
|
|
||||||
<path
|
|
||||||
android:pathData="m826.41,857.52 l43.59,-146.74l24.96,0l-58.16,184.51L816.4,895.28l-58.29,-184.51l25.09,0z"
|
|
||||||
android:fillColor="#ffffff"
|
|
||||||
android:strokeColor="#00000000"
|
|
||||||
android:fillAlpha="1"/>
|
|
||||||
</group>
|
|
||||||
</vector>
|
|
34
app/src/debug/res/drawable/ic_launcher_foreground_dev.xml
Normal file
34
app/src/debug/res/drawable/ic_launcher_foreground_dev.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="1926"
|
||||||
|
android:viewportHeight="1926">
|
||||||
|
<path
|
||||||
|
android:fillColor="#ad2a2a"
|
||||||
|
android:pathData="M2465,1904v561h-759L704,1463l-120,-120 -1,-1 5,-9 1,-3c9,-15 20,-29 31,-43l16,-19 3,-4 21,-30 3,-6c7,-11 12,-23 18,-35l14,-24 3,-4v-1a234,234 0,0 0,20 -53v-1l1,-3c4,-15 7,-31 13,-46l5,-9v-1c5,-10 11,-19 14, -30 2,-9 3,-19 3,-28v-1,-21l3,-17v-3l4,-17h1v-1c0,-2 -1,-4 -3,-4l8,-8 4,1c13,-4 25,-10 37,-17l8,-5 22,-16 9,-9v-1l5, -11c3,-9 2,-19 2,-29l6,-6 4,2 45,45 10,9 14,14 101,101 17,17 16,17 31,-31 -193,-191 1,-2 1,-2 -1,-3v-1l-1,-1 27,-27 192,-192 2,1a27,27 0,0 1,14 3l6,6c2,2 8,3 9,1l1310,1310z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#fff"
|
||||||
|
android:pathData="M1082,1260v4l-6,73c0,5 -5,9 -10,9H879c-4,0 -8,-2 -10,-5l-31,-58 -29,-71v-8l48,-94c2,-3 2,-5 1, -8l-24,-65c-1,-2 0,-5 1,-7l39,-84c4,-8 17,-8 20,1l12,38 38,101c1,2 3,5 6,6l80,27c3,1 6,3 7,6l45,135zM852,717c0,-23 15,-43 35,-52l-2,-8c0,-11 13,-20 29,-20h1a38,38 0,0 1,36 -18l3,-2c11,-16 37,-27 68,-27 12,0 23,2 32,4 3,-3 8,-6 14,-6s12,3 14,8c8,-9 22,-16 38,-16 25,0 45,16 45,36l-1,7 3,4c16,6 27,17 27,30 0,14 -15,27 -34,32 -2,0 -3,1 -3,3 0,11 -11,21 -26,22v1c0,22 -41,40 -92,40 -11,0 -21,-1 -31,-3v1c0,9 -12,16 -26,16h-2l2,7c0,14 -18,25 -40,25h-7l-4, 2c-2,7 -8,12 -15,12 -9,0 -16,-7 -16,-16 0,-5 1,-8 4,-11l1,-4c-2,-3 -2,-5 -2,-8 0,-2 -2,-3 -3,-3 -27,-6 -48,-29 -48,-56z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#fff"
|
||||||
|
android:pathData="M1336,1346h-125c-3,0 -6,-1 -8,-4l-84,-118 -1,-2 -42,-122 -5,-5 -102,-52 -5,-6 -15,-75 -2,-3 -34,-51c-2,-3 -2,-6 -1,-9l21,-45c2,-4 5,-6 9,-6l39,-2c3,0 5,-1 6,-3l29,-22c5,-4 14,-2 17,4l98,201 1,2 13,81 2,5 197,216c6,6 1,16 -8,16zM801,1302c1,3 1,6 -1,8l-19,31c-2,3 -5,5 -9,5H591c-8,0 -13,-8 -9,-15l116,-171 2,-3 53, -228c1,-3 3,-5 5,-6l72,-40c3,-1 5,-4 5,-7l10,-42c2,-9 15,-11 20,-3l3,6c2,2 2,5 1,8l-66,190v5l16,91v5l-40,88v6l22,72z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#3f3f3f"
|
||||||
|
android:pathData="M886.7,1119.5h1580.5c0.6,0 0,292 0,292H886.7a19.4,19.4 0,0 1,-19.5 -19.5v-253c0,-10.8 8.7,-19.5 19.5,-19.5z"
|
||||||
|
android:strokeWidth="4"
|
||||||
|
android:strokeAlpha=".5"
|
||||||
|
android:strokeColor="#000"
|
||||||
|
android:strokeLineCap="square"
|
||||||
|
android:strokeLineJoin="round" />
|
||||||
|
<path
|
||||||
|
android:fillAlpha=".2"
|
||||||
|
android:fillColor="#000"
|
||||||
|
android:pathData="M1191.2,1173.4v19.9h-88.7v59.3h77v19.9h-77v65.4h89.8v19.9L1079,1357.8v-104.2l-52.3,-52.3 -0.8, -0.2a75.1,75.1 0,0 1,12.7 23,104 104,0 0,1 5.7,34.7v13.5c0,12.7 -2,24.3 -5.7,34.8a72.8,72.8 0,0 1,-41.6 44.4,85.5 85.5,0 0,1 -34.3,6.3L920,1357.8v-6.6l-0.4,6.8 53.8,53.5h622L1416,1232l-58.4,-58.4h-0.3l-58,184.1h -20.4l-44.7,-141.3zM1245.8,1173.5l43,146.5 23.7,-79.7zM972.1,1173.8zM943.8,1192.5v146.1h18.9a62,62 0,0 0,25.8 -5.2,50.3 50.3,0 0,0 18,-14c4.9,-6 8.4,-13 10.7,-21 2.3,-8 3.6,-16.7 3.7,-26v-13.9c-0.1,-9.4 -1.4,-18 -3.7,-26 -2.4,-8 -6,-15 -10.7,-20.7a49.3,49.3 0,0 0,-18 -14,63.4 63.4,0 0,0 -25.8,-5.3zM1022.6,1197.3l2,2.1 -2,-2z"
|
||||||
|
android:strokeWidth="1.9"
|
||||||
|
android:strokeColor="#000" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#fff"
|
||||||
|
android:pathData="M920,1357.7v-184.5h42.7q19.3,0.3 34.3,6.6 15.2,6.2 25.6,17.5 10.6,11.2 16,26.9 5.6,15.6 5.7, 34.6v13.5q-0.1,19 -5.7,34.7 -5.4,15.6 -16,26.9 -10.4,11.2 -25.6,17.5 -15,6.2 -34.3,6.3zM943.8,1192.5v146.1h18.9q15, -0.1 25.8,-5.2 11,-5.2 18,-14 7.3,-9 10.7,-21 3.5,-12 3.6,-26v-13.9q0,-14 -3.6,-26t-10.7,-20.7q-7,-9 -18,-14 -10.9,-5 -25.8,-5.3zM1179.5,1272.5h-77v65.4h89.8v19.9L1079,1357.8v-184.6h112.2v20h-88.7v59.4h77zM1288.9, 1320l43.6,-146.8h25l-58.2,184.6h-20.4l-58.3,-184.6h25z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#000" />
|
||||||
|
</vector>
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
<background android:drawable="@color/colorPrimary" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
<background android:drawable="@color/colorPrimary" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="ic_launcher_background">#D32F2F</color>
|
|
||||||
</resources>
|
|
@ -43,6 +43,7 @@
|
|||||||
android:name=".ui.modules.message.send.SendMessageActivity"
|
android:name=".ui.modules.message.send.SendMessageActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:label="@string/send_message_title"
|
android:label="@string/send_message_title"
|
||||||
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
|
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
|
||||||
|
@ -5,7 +5,6 @@ import android.util.Log.INFO
|
|||||||
import android.util.Log.VERBOSE
|
import android.util.Log.VERBOSE
|
||||||
import androidx.multidex.MultiDex
|
import androidx.multidex.MultiDex
|
||||||
import androidx.work.Configuration
|
import androidx.work.Configuration
|
||||||
import androidx.work.WorkManager
|
|
||||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.support.DaggerApplication
|
import dagger.android.support.DaggerApplication
|
||||||
@ -13,6 +12,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||||||
import eu.davidea.flexibleadapter.utils.Log
|
import eu.davidea.flexibleadapter.utils.Log
|
||||||
import io.github.wulkanowy.di.DaggerAppComponent
|
import io.github.wulkanowy.di.DaggerAppComponent
|
||||||
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
||||||
|
import io.github.wulkanowy.ui.base.ThemeManager
|
||||||
import io.github.wulkanowy.utils.ActivityLifecycleLogger
|
import io.github.wulkanowy.utils.ActivityLifecycleLogger
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.CrashlyticsTree
|
import io.github.wulkanowy.utils.CrashlyticsTree
|
||||||
@ -24,11 +24,14 @@ import timber.log.Timber
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class WulkanowyApp : DaggerApplication() {
|
class WulkanowyApp : DaggerApplication(), Configuration.Provider {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var workerFactory: SyncWorkerFactory
|
lateinit var workerFactory: SyncWorkerFactory
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var themeManager: ThemeManager
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var appInfo: AppInfo
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
@ -41,20 +44,12 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
super.onCreate()
|
super.onCreate()
|
||||||
AndroidThreeTen.init(this)
|
AndroidThreeTen.init(this)
|
||||||
RxJavaPlugins.setErrorHandler(::onError)
|
RxJavaPlugins.setErrorHandler(::onError)
|
||||||
|
themeManager.applyDefaultTheme()
|
||||||
|
|
||||||
initWorkManager()
|
|
||||||
initLogging()
|
initLogging()
|
||||||
initCrashlytics(this, appInfo)
|
initCrashlytics(this, appInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initWorkManager() {
|
|
||||||
WorkManager.initialize(this,
|
|
||||||
Configuration.Builder()
|
|
||||||
.setWorkerFactory(workerFactory)
|
|
||||||
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
|
|
||||||
.build())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initLogging() {
|
private fun initLogging() {
|
||||||
if (appInfo.isDebug) {
|
if (appInfo.isDebug) {
|
||||||
Timber.plant(DebugLogTree())
|
Timber.plant(DebugLogTree())
|
||||||
@ -76,4 +71,9 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
|
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
|
||||||
return DaggerAppComponent.factory().create(this)
|
return DaggerAppComponent.factory().create(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getWorkManagerConfiguration() = Configuration.Builder()
|
||||||
|
.setWorkerFactory(workerFactory)
|
||||||
|
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
package io.github.wulkanowy.data.db
|
package io.github.wulkanowy.data.db
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import androidx.core.content.edit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@SuppressLint("ApplySharedPref")
|
class SharedPrefProvider @Inject constructor(private val sharedPref: SharedPreferences) {
|
||||||
class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPreferences) {
|
|
||||||
|
|
||||||
fun putLong(key: String, value: Long, sync: Boolean = false) {
|
fun putLong(key: String, value: Long, sync: Boolean = false) {
|
||||||
sharedPref.edit().putLong(key, value).apply {
|
sharedPref.edit(sync) { putLong(key, value) }
|
||||||
if (sync) commit() else apply()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue)
|
fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue)
|
@ -32,10 +32,11 @@ class TimetableRepository @Inject constructor(
|
|||||||
.doOnSuccess { old ->
|
.doOnSuccess { old ->
|
||||||
local.deleteTimetable(old.uniqueSubtract(new))
|
local.deleteTimetable(old.uniqueSubtract(new))
|
||||||
local.saveTimetable(new.uniqueSubtract(old).map { item ->
|
local.saveTimetable(new.uniqueSubtract(old).map { item ->
|
||||||
item.apply {
|
item.also { new ->
|
||||||
old.singleOrNull { this.start == it.start }?.let {
|
old.singleOrNull { new.start == it.start }?.let { old ->
|
||||||
return@map copy(
|
return@map new.copy(
|
||||||
room = if (room.isEmpty()) it.room else room
|
room = if (new.room.isEmpty()) old.room else new.room,
|
||||||
|
teacher = if (new.teacher.isEmpty() && !new.changes) old.teacher else new.teacher
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import javax.inject.Singleton
|
|||||||
AppModule::class,
|
AppModule::class,
|
||||||
RepositoryModule::class,
|
RepositoryModule::class,
|
||||||
ServicesModule::class,
|
ServicesModule::class,
|
||||||
BuilderModule::class])
|
BindingModule::class])
|
||||||
interface AppComponent : AndroidInjector<WulkanowyApp> {
|
interface AppComponent : AndroidInjector<WulkanowyApp> {
|
||||||
|
|
||||||
@Component.Factory
|
@Component.Factory
|
||||||
|
@ -6,16 +6,17 @@ import io.github.wulkanowy.di.scopes.PerActivity
|
|||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginModule
|
import io.github.wulkanowy.ui.modules.login.LoginModule
|
||||||
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity
|
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainModule
|
import io.github.wulkanowy.ui.modules.main.MainModule
|
||||||
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
||||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||||
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider
|
|
||||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureActivity
|
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureActivity
|
||||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider
|
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
@Module
|
@Module
|
||||||
internal abstract class BuilderModule {
|
internal abstract class BindingModule {
|
||||||
|
|
||||||
@PerActivity
|
@PerActivity
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
@ -1,8 +1,6 @@
|
|||||||
package io.github.wulkanowy.services
|
package io.github.wulkanowy.services
|
||||||
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Context.NOTIFICATION_SERVICE
|
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import com.squareup.inject.assisted.dagger2.AssistedModule
|
import com.squareup.inject.assisted.dagger2.AssistedModule
|
||||||
@ -28,6 +26,7 @@ import io.github.wulkanowy.services.sync.works.Work
|
|||||||
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
@AssistedModule
|
@AssistedModule
|
||||||
@Module(includes = [AssistedInject_ServicesModule::class])
|
@Module(includes = [AssistedInject_ServicesModule::class])
|
||||||
abstract class ServicesModule {
|
abstract class ServicesModule {
|
||||||
@ -37,17 +36,12 @@ abstract class ServicesModule {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Provides
|
@Provides
|
||||||
fun provideWorkManager() = WorkManager.getInstance()
|
fun provideWorkManager(context: Context) = WorkManager.getInstance(context)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideNotificationManagerCompat(context: Context) = NotificationManagerCompat.from(context)
|
fun provideNotificationManager(context: Context) = NotificationManagerCompat.from(context)
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
@Singleton
|
|
||||||
@Provides
|
|
||||||
fun provideNotificationManager(context: Context) = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
|
@ -8,9 +8,9 @@ import androidx.work.ExistingPeriodicWorkPolicy.KEEP
|
|||||||
import androidx.work.ExistingPeriodicWorkPolicy.REPLACE
|
import androidx.work.ExistingPeriodicWorkPolicy.REPLACE
|
||||||
import androidx.work.NetworkType.CONNECTED
|
import androidx.work.NetworkType.CONNECTED
|
||||||
import androidx.work.NetworkType.UNMETERED
|
import androidx.work.NetworkType.UNMETERED
|
||||||
import androidx.work.PeriodicWorkRequest
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
@ -26,14 +26,13 @@ import javax.inject.Singleton
|
|||||||
class SyncManager @Inject constructor(
|
class SyncManager @Inject constructor(
|
||||||
private val workManager: WorkManager,
|
private val workManager: WorkManager,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
sharedPrefHelper: SharedPrefHelper,
|
sharedPrefProvider: SharedPrefProvider,
|
||||||
newEntriesChannel: NewEntriesChannel,
|
newEntriesChannel: NewEntriesChannel,
|
||||||
debugChannel: DebugChannel,
|
debugChannel: DebugChannel,
|
||||||
appInfo: AppInfo
|
appInfo: AppInfo
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val APP_VERSION_CODE_KEY = "app_version_code"
|
private const val APP_VERSION_CODE_KEY = "app_version_code"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,18 +44,18 @@ class SyncManager @Inject constructor(
|
|||||||
if (appInfo.isDebug) debugChannel.create()
|
if (appInfo.isDebug) debugChannel.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sharedPrefHelper.getLong(APP_VERSION_CODE_KEY, -1L) != appInfo.versionCode.toLong()) {
|
if (sharedPrefProvider.getLong(APP_VERSION_CODE_KEY, -1L) != appInfo.versionCode.toLong()) {
|
||||||
startSyncWorker(true)
|
startSyncWorker(true)
|
||||||
sharedPrefHelper.putLong(APP_VERSION_CODE_KEY, appInfo.versionCode.toLong(), true)
|
sharedPrefProvider.putLong(APP_VERSION_CODE_KEY, appInfo.versionCode.toLong(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
Timber.i("SyncManager was initialized")
|
Timber.i("SyncManager was initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startSyncWorker(restart: Boolean = false) {
|
fun startSyncWorker(restart: Boolean = false) {
|
||||||
if (preferencesRepository.isServiceEnabled && !now().isHolidays) {
|
if (preferencesRepository.isServiceEnabled && !now().isHolidays) {
|
||||||
workManager.enqueueUniquePeriodicWork(SyncWorker::class.java.simpleName, if (restart) REPLACE else KEEP,
|
workManager.enqueueUniquePeriodicWork(SyncWorker::class.java.simpleName, if (restart) REPLACE else KEEP,
|
||||||
PeriodicWorkRequest.Builder(SyncWorker::class.java, preferencesRepository.servicesInterval, MINUTES, 10, MINUTES)
|
PeriodicWorkRequestBuilder<SyncWorker>(preferencesRepository.servicesInterval, MINUTES)
|
||||||
|
.setInitialDelay(10, MINUTES)
|
||||||
.setBackoffCriteria(EXPONENTIAL, 30, MINUTES)
|
.setBackoffCriteria(EXPONENTIAL, 30, MINUTES)
|
||||||
.setConstraints(Constraints.Builder()
|
.setConstraints(Constraints.Builder()
|
||||||
.setRequiredNetworkType(if (preferencesRepository.isServicesOnlyWifi) UNMETERED else CONNECTED)
|
.setRequiredNetworkType(if (preferencesRepository.isServicesOnlyWifi) UNMETERED else CONNECTED)
|
||||||
|
@ -64,7 +64,7 @@ class SyncWorker @AssistedInject constructor(
|
|||||||
private fun notify(result: Result) {
|
private fun notify(result: Result) {
|
||||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(applicationContext, DebugChannel.CHANNEL_ID)
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(applicationContext, DebugChannel.CHANNEL_ID)
|
||||||
.setContentTitle("Debug notification")
|
.setContentTitle("Debug notification")
|
||||||
.setSmallIcon(R.drawable.ic_more_settings_24dp)
|
.setSmallIcon(R.drawable.ic_more_settings)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setColor(applicationContext.getCompatColor(R.color.colorPrimary))
|
.setColor(applicationContext.getCompatColor(R.color.colorPrimary))
|
||||||
.setStyle(BigTextStyle().bigText("${SyncWorker::class.java.simpleName} result: $result"))
|
.setStyle(BigTextStyle().bigText("${SyncWorker::class.java.simpleName} result: $result"))
|
||||||
|
@ -3,15 +3,15 @@ package io.github.wulkanowy.services.sync.channels
|
|||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
import android.app.Notification.VISIBILITY_PUBLIC
|
import android.app.Notification.VISIBILITY_PUBLIC
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.NotificationManager.IMPORTANCE_DEFAULT
|
import android.app.NotificationManager.IMPORTANCE_DEFAULT
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@TargetApi(26)
|
@TargetApi(26)
|
||||||
class DebugChannel @Inject constructor(
|
class DebugChannel @Inject constructor(
|
||||||
private val notificationManager: NotificationManager,
|
private val notificationManager: NotificationManagerCompat,
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -21,8 +21,9 @@ class DebugChannel @Inject constructor(
|
|||||||
|
|
||||||
fun create() {
|
fun create() {
|
||||||
notificationManager.createNotificationChannel(
|
notificationManager.createNotificationChannel(
|
||||||
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_debug), IMPORTANCE_DEFAULT).apply {
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_debug), IMPORTANCE_DEFAULT)
|
||||||
lockscreenVisibility = VISIBILITY_PUBLIC
|
.apply {
|
||||||
})
|
lockscreenVisibility = VISIBILITY_PUBLIC
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,15 @@ package io.github.wulkanowy.services.sync.channels
|
|||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
import android.app.Notification.VISIBILITY_PUBLIC
|
import android.app.Notification.VISIBILITY_PUBLIC
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.NotificationManager.IMPORTANCE_HIGH
|
import android.app.NotificationManager.IMPORTANCE_HIGH
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@TargetApi(26)
|
@TargetApi(26)
|
||||||
class NewEntriesChannel @Inject constructor(
|
class NewEntriesChannel @Inject constructor(
|
||||||
private val notificationManager: NotificationManager,
|
private val notificationManager: NotificationManagerCompat,
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -21,10 +21,11 @@ class NewEntriesChannel @Inject constructor(
|
|||||||
|
|
||||||
fun create() {
|
fun create() {
|
||||||
notificationManager.createNotificationChannel(
|
notificationManager.createNotificationChannel(
|
||||||
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_entries), IMPORTANCE_HIGH).apply {
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_entries), IMPORTANCE_HIGH)
|
||||||
enableLights(true)
|
.apply {
|
||||||
enableVibration(true)
|
enableLights(true)
|
||||||
lockscreenVisibility = VISIBILITY_PUBLIC
|
enableVibration(true)
|
||||||
})
|
lockscreenVisibility = VISIBILITY_PUBLIC
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
|||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView.MenuView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -41,14 +41,14 @@ class GradeWork @Inject constructor(
|
|||||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
.setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size))
|
.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))
|
.setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size))
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_grade)
|
.setSmallIcon(R.drawable.ic_stat_grade)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setPriority(PRIORITY_HIGH)
|
.setPriority(PRIORITY_HIGH)
|
||||||
.setDefaults(DEFAULT_ALL)
|
.setDefaults(DEFAULT_ALL)
|
||||||
.setColor(context.getCompatColor(R.color.colorPrimary))
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
.setContentIntent(
|
.setContentIntent(
|
||||||
PendingIntent.getActivity(context, MenuView.GRADE.id,
|
PendingIntent.getActivity(context, MainView.Section.GRADE.id,
|
||||||
MainActivity.getStartIntent(context, MenuView.GRADE, true), FLAG_UPDATE_CURRENT))
|
MainActivity.getStartIntent(context, MainView.Section.GRADE, true), FLAG_UPDATE_CURRENT))
|
||||||
.setStyle(NotificationCompat.InboxStyle().run {
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, grades.size, grades.size))
|
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, grades.size, grades.size))
|
||||||
grades.forEach { addLine("${it.subject}: ${it.entry}") }
|
grades.forEach { addLine("${it.subject}: ${it.entry}") }
|
||||||
|
@ -15,7 +15,7 @@ import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository
|
|||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView.MenuView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -41,14 +41,14 @@ class LuckyNumberWork @Inject constructor(
|
|||||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
.setContentTitle(context.getString(R.string.lucky_number_notify_new_item_title))
|
.setContentTitle(context.getString(R.string.lucky_number_notify_new_item_title))
|
||||||
.setContentText(context.getString(R.string.lucky_number_notify_new_item, luckyNumber.luckyNumber))
|
.setContentText(context.getString(R.string.lucky_number_notify_new_item, luckyNumber.luckyNumber))
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_lucky_number)
|
.setSmallIcon(R.drawable.ic_stat_luckynumber)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setDefaults(DEFAULT_ALL)
|
.setDefaults(DEFAULT_ALL)
|
||||||
.setPriority(PRIORITY_HIGH)
|
.setPriority(PRIORITY_HIGH)
|
||||||
.setColor(context.getCompatColor(R.color.colorPrimary))
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
.setContentIntent(
|
.setContentIntent(
|
||||||
PendingIntent.getActivity(context, MenuView.MESSAGE.id,
|
PendingIntent.getActivity(context, MainView.Section.MESSAGE.id,
|
||||||
MainActivity.getStartIntent(context, MenuView.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT))
|
MainActivity.getStartIntent(context, MainView.Section.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT))
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import io.github.wulkanowy.data.repositories.message.MessageRepository
|
|||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView.MenuView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -42,14 +42,14 @@ class MessageWork @Inject constructor(
|
|||||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
.setContentTitle(context.resources.getQuantityString(R.plurals.message_new_items, messages.size, messages.size))
|
.setContentTitle(context.resources.getQuantityString(R.plurals.message_new_items, messages.size, messages.size))
|
||||||
.setContentText(context.resources.getQuantityString(R.plurals.message_notify_new_items, messages.size, messages.size))
|
.setContentText(context.resources.getQuantityString(R.plurals.message_notify_new_items, messages.size, messages.size))
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_message)
|
.setSmallIcon(R.drawable.ic_stat_message)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setDefaults(DEFAULT_ALL)
|
.setDefaults(DEFAULT_ALL)
|
||||||
.setPriority(PRIORITY_HIGH)
|
.setPriority(PRIORITY_HIGH)
|
||||||
.setColor(context.getCompatColor(R.color.colorPrimary))
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
.setContentIntent(
|
.setContentIntent(
|
||||||
PendingIntent.getActivity(context, MenuView.MESSAGE.id,
|
PendingIntent.getActivity(context, MainView.Section.MESSAGE.id,
|
||||||
MainActivity.getStartIntent(context, MenuView.MESSAGE, true), FLAG_UPDATE_CURRENT)
|
MainActivity.getStartIntent(context, MainView.Section.MESSAGE, true), FLAG_UPDATE_CURRENT)
|
||||||
)
|
)
|
||||||
.setStyle(NotificationCompat.InboxStyle().run {
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
setSummaryText(context.resources.getQuantityString(R.plurals.message_number_item, messages.size, messages.size))
|
setSummaryText(context.resources.getQuantityString(R.plurals.message_number_item, messages.size, messages.size))
|
||||||
|
@ -15,7 +15,7 @@ import io.github.wulkanowy.data.repositories.note.NoteRepository
|
|||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView.MenuView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -41,14 +41,14 @@ class NoteWork @Inject constructor(
|
|||||||
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewEntriesChannel.CHANNEL_ID)
|
||||||
.setContentTitle(context.resources.getQuantityString(R.plurals.note_new_items, notes.size, notes.size))
|
.setContentTitle(context.resources.getQuantityString(R.plurals.note_new_items, notes.size, notes.size))
|
||||||
.setContentText(context.resources.getQuantityString(R.plurals.note_notify_new_items, notes.size, notes.size))
|
.setContentText(context.resources.getQuantityString(R.plurals.note_notify_new_items, notes.size, notes.size))
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify_note)
|
.setSmallIcon(R.drawable.ic_stat_note)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setDefaults(DEFAULT_ALL)
|
.setDefaults(DEFAULT_ALL)
|
||||||
.setPriority(PRIORITY_HIGH)
|
.setPriority(PRIORITY_HIGH)
|
||||||
.setColor(context.getCompatColor(R.color.colorPrimary))
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
.setContentIntent(
|
.setContentIntent(
|
||||||
PendingIntent.getActivity(context, MenuView.NOTE.id,
|
PendingIntent.getActivity(context, MainView.Section.NOTE.id,
|
||||||
MainActivity.getStartIntent(context, MenuView.NOTE, true), FLAG_UPDATE_CURRENT))
|
MainActivity.getStartIntent(context, MainView.Section.NOTE, true), FLAG_UPDATE_CURRENT))
|
||||||
.setStyle(NotificationCompat.InboxStyle().run {
|
.setStyle(NotificationCompat.InboxStyle().run {
|
||||||
setSummaryText(context.resources.getQuantityString(R.plurals.note_number_item, notes.size, notes.size))
|
setSummaryText(context.resources.getQuantityString(R.plurals.note_number_item, notes.size, notes.size))
|
||||||
notes.forEach { addLine("${it.teacher}: ${it.category}") }
|
notes.forEach { addLine("${it.teacher}: ${it.category}") }
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.widgets
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.widget.RemoteViewsService
|
import android.widget.RemoteViewsService
|
||||||
import dagger.android.AndroidInjection
|
import dagger.android.AndroidInjection
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
||||||
@ -23,7 +23,7 @@ class TimetableWidgetService : RemoteViewsService() {
|
|||||||
lateinit var semesterRepo: SemesterRepository
|
lateinit var semesterRepo: SemesterRepository
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var sharedPref: SharedPrefHelper
|
lateinit var sharedPref: SharedPrefProvider
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var schedulers: SchedulersProvider
|
lateinit var schedulers: SchedulersProvider
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
|
import android.app.ActivityManager
|
||||||
|
import android.os.Build.VERSION.SDK_INT
|
||||||
|
import android.os.Build.VERSION_CODES.LOLLIPOP
|
||||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -16,6 +19,7 @@ import dagger.android.HasAndroidInjector
|
|||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.utils.FragmentLifecycleLogger
|
import io.github.wulkanowy.utils.FragmentLifecycleLogger
|
||||||
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView, HasAndroidInjector {
|
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView, HasAndroidInjector {
|
||||||
@ -35,10 +39,15 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity
|
|||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
AndroidInjection.inject(this)
|
AndroidInjection.inject(this)
|
||||||
themeManager.applyTheme(this)
|
themeManager.applyActivityTheme(this)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleLogger, true)
|
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleLogger, true)
|
||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||||
|
|
||||||
|
if (SDK_INT >= LOLLIPOP) {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
setTaskDescription(ActivityManager.TaskDescription(null, null, getThemeAttrColor(R.attr.colorSurface)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showError(text: String, error: Throwable) {
|
override fun showError(text: String, error: Throwable) {
|
||||||
|
@ -4,14 +4,15 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import androidx.fragment.app.FragmentPagerAdapter
|
import androidx.fragment.app.FragmentPagerAdapter
|
||||||
|
|
||||||
class BaseFragmentPagerAdapter(private val fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
|
class BaseFragmentPagerAdapter(private val fragmentManager: FragmentManager) :
|
||||||
|
FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||||
|
|
||||||
private val pages = mutableMapOf<Fragment, String?>()
|
private val pages = mutableMapOf<Fragment, String?>()
|
||||||
|
|
||||||
var containerId = 0
|
var containerId = 0
|
||||||
|
|
||||||
fun getFragmentInstance(position: Int): Fragment? {
|
fun getFragmentInstance(position: Int): Fragment? {
|
||||||
if (containerId == 0) throw IllegalArgumentException("Container id is 0")
|
require(containerId != 0) { "Container id is 0" }
|
||||||
return fragmentManager.findFragmentByTag("android:switcher:$containerId:$position")
|
return fragmentManager.findFragmentByTag("android:switcher:$containerId:$position")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@ package io.github.wulkanowy.ui.base
|
|||||||
|
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context.CLIPBOARD_SERVICE
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.widget.Toast.LENGTH_LONG
|
import android.widget.Toast.LENGTH_LONG
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import kotlinx.android.synthetic.main.dialog_error.*
|
import kotlinx.android.synthetic.main.dialog_error.*
|
||||||
@ -49,7 +49,7 @@ class ErrorDialog : DialogFragment() {
|
|||||||
errorDialogContent.text = writer.toString()
|
errorDialogContent.text = writer.toString()
|
||||||
errorDialogCopy.setOnClickListener {
|
errorDialogCopy.setOnClickListener {
|
||||||
ClipData.newPlainText("wulkanowyError", writer.toString()).let { clip ->
|
ClipData.newPlainText("wulkanowyError", writer.toString()).let { clip ->
|
||||||
(activity?.getSystemService(CLIPBOARD_SERVICE) as? ClipboardManager)?.primaryClip = clip
|
activity?.getSystemService<ClipboardManager>()?.primaryClip = clip
|
||||||
}
|
}
|
||||||
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
|
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
@ -2,29 +2,31 @@ package io.github.wulkanowy.ui.base
|
|||||||
|
|
||||||
import android.content.pm.PackageManager.GET_ACTIVITIES
|
import android.content.pm.PackageManager.GET_ACTIVITIES
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
|
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
|
||||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
|
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
class ThemeManager @Inject constructor(private val preferencesRepository: PreferencesRepository) {
|
class ThemeManager @Inject constructor(private val preferencesRepository: PreferencesRepository) {
|
||||||
|
|
||||||
fun applyTheme(activity: AppCompatActivity) {
|
fun applyActivityTheme(activity: AppCompatActivity) {
|
||||||
if (isThemeApplicable(activity)) {
|
if (isThemeApplicable(activity)) {
|
||||||
activity.delegate.apply {
|
applyDefaultTheme()
|
||||||
when (preferencesRepository.appTheme) {
|
if (preferencesRepository.appTheme == "black") activity.setTheme(R.style.WulkanowyTheme_Black)
|
||||||
"light" -> setLocalNightMode(MODE_NIGHT_NO)
|
|
||||||
"dark" -> setLocalNightMode(MODE_NIGHT_YES)
|
|
||||||
"black" -> {
|
|
||||||
setLocalNightMode(MODE_NIGHT_YES)
|
|
||||||
activity.setTheme(R.style.WulkanowyTheme_Black)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun applyDefaultTheme() {
|
||||||
|
AppCompatDelegate.setDefaultNightMode(
|
||||||
|
if (preferencesRepository.appTheme == "light") MODE_NIGHT_NO
|
||||||
|
else MODE_NIGHT_YES
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun isThemeApplicable(activity: AppCompatActivity): Boolean {
|
private fun isThemeApplicable(activity: AppCompatActivity): Boolean {
|
||||||
return activity.packageManager.getPackageInfo(activity.packageName, GET_ACTIVITIES)
|
return activity.packageManager.getPackageInfo(activity.packageName, GET_ACTIVITIES)
|
||||||
.activities.singleOrNull { it.name == activity::class.java.canonicalName }?.theme
|
.activities.singleOrNull { it.name == activity::class.java.canonicalName }?.theme
|
||||||
|
@ -1,19 +1,29 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about
|
package io.github.wulkanowy.ui.modules.about
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.Intent.ACTION_SENDTO
|
||||||
|
import android.content.Intent.EXTRA_EMAIL
|
||||||
|
import android.content.Intent.EXTRA_SUBJECT
|
||||||
|
import android.content.Intent.EXTRA_TEXT
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import com.mikepenz.aboutlibraries.LibsFragmentCompat
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.about.license.LicenseFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
|
import io.github.wulkanowy.utils.getCompatDrawable
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import io.github.wulkanowy.utils.withOnExtraListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
|
import kotlinx.android.synthetic.main.fragment_about.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
||||||
@ -22,63 +32,94 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
|||||||
lateinit var presenter: AboutPresenter
|
lateinit var presenter: AboutPresenter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var fragmentCompat: LibsFragmentCompat
|
lateinit var aboutAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var appInfo: AppInfo
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
|
override val versionRes: Triple<String, String, Drawable?>?
|
||||||
|
get() = context?.run {
|
||||||
|
Triple(getString(R.string.about_version), "${appInfo.versionName} (${appInfo.versionCode})", getCompatDrawable(R.drawable.ic_all_about))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val feedbackRes: Triple<String, String, Drawable?>?
|
||||||
|
get() = context?.run {
|
||||||
|
Triple(getString(R.string.about_feedback), getString(R.string.about_feedback_summary), getCompatDrawable(R.drawable.ic_about_feedback))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val discordRes: Triple<String, String, Drawable?>?
|
||||||
|
get() = context?.run {
|
||||||
|
Triple(getString(R.string.about_discord), getString(R.string.about_discord_summary), getCompatDrawable(R.drawable.ic_about_discord))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val homepageRes: Triple<String, String, Drawable?>?
|
||||||
|
get() = context?.run {
|
||||||
|
Triple(getString(R.string.about_homepage), getString(R.string.about_homepage_summary), getCompatDrawable(R.drawable.ic_about_homepage))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val licensesRes: Triple<String, String, Drawable?>?
|
||||||
|
get() = context?.run {
|
||||||
|
Triple(getString(R.string.about_licenses), getString(R.string.about_licenses_summary), getCompatDrawable(R.drawable.ic_about_licenses))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val privacyRes: Triple<String, String, Drawable?>?
|
||||||
|
get() = context?.run {
|
||||||
|
Triple(getString(R.string.about_privacy), getString(R.string.about_privacy_summary), getCompatDrawable(R.drawable.ic_about_privacy))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val titleStringId get() = R.string.about_title
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = AboutFragment()
|
fun newInstance() = AboutFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
|
||||||
get() = R.string.about_title
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
presenter.onAttachView(this)
|
return inflater.inflate(R.layout.fragment_about, container, false)
|
||||||
return Bundle().apply {
|
|
||||||
putSerializable("data", LibsBuilder()
|
|
||||||
.withAboutAppName(getString(R.string.app_name))
|
|
||||||
.withAboutVersionShown(true)
|
|
||||||
.withAboutIconShown(true)
|
|
||||||
.withLicenseShown(true)
|
|
||||||
.withAboutSpecial1(getString(R.string.about_discord_invite))
|
|
||||||
.withAboutSpecial2(getString(R.string.about_homepage))
|
|
||||||
.withAboutSpecial3(getString(R.string.about_feedback))
|
|
||||||
.withFields(R.string::class.java.fields)
|
|
||||||
.withCheckCachedDetection(false)
|
|
||||||
.withExcludedLibraries("fastadapter", "AndroidIconics", "Jsoup", "Retrofit", "okio",
|
|
||||||
"Butterknife", "CircleImageView")
|
|
||||||
.withOnExtraListener { presenter.onExtraSelect(it) })
|
|
||||||
}.let {
|
|
||||||
fragmentCompat.onCreateView(inflater.context, inflater, container, savedInstanceState, it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
fragmentCompat.onViewCreated(view, savedInstanceState)
|
presenter.onAttachView(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openDiscordInviteView() {
|
override fun initView() {
|
||||||
|
aboutAdapter.setOnItemClickListener(presenter::onItemSelected)
|
||||||
|
|
||||||
|
with(aboutRecycler) {
|
||||||
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
|
adapter = aboutAdapter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateData(header: AboutScrollableHeader, items: List<AboutItem>) {
|
||||||
|
with(aboutAdapter) {
|
||||||
|
removeAllScrollableHeaders()
|
||||||
|
addScrollableHeader(header)
|
||||||
|
updateDataSet(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openDiscordInvite() {
|
||||||
context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage)
|
context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openHomepageWebView() {
|
override fun openHomepage() {
|
||||||
context?.openInternetBrowser("https://wulkanowy.github.io/", ::showMessage)
|
context?.openInternetBrowser("https://wulkanowy.github.io/", ::showMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openEmailClientView() {
|
override fun openEmailClient() {
|
||||||
val intent = Intent(Intent.ACTION_SENDTO).apply {
|
val intent = Intent(ACTION_SENDTO)
|
||||||
data = Uri.parse("mailto:")
|
.apply {
|
||||||
putExtra(Intent.EXTRA_EMAIL, Array(1) { "wulkanowyinc@gmail.com" })
|
data = Uri.parse("mailto:")
|
||||||
putExtra(Intent.EXTRA_SUBJECT, "Zgłoszenie błędu")
|
putExtra(EXTRA_EMAIL, arrayOf("wulkanowyinc@gmail.com"))
|
||||||
putExtra(Intent.EXTRA_TEXT, "Tu umieść treść zgłoszenia\n\n" + "-".repeat(40) + "\n" + """
|
putExtra(EXTRA_SUBJECT, "Zgłoszenie błędu")
|
||||||
Build: ${appInfo.versionCode}
|
putExtra(EXTRA_TEXT, "Tu umieść treść zgłoszenia\n\n${"-".repeat(40)}\n " +
|
||||||
SDK: ${appInfo.systemVersion}
|
"""
|
||||||
Device: ${appInfo.systemManufacturer} ${appInfo.systemModel}
|
Build: ${appInfo.versionCode}
|
||||||
""".trimIndent())
|
SDK: ${appInfo.systemVersion}
|
||||||
}
|
Device: ${appInfo.systemManufacturer} ${appInfo.systemModel}
|
||||||
|
""".trimIndent())
|
||||||
|
}
|
||||||
|
|
||||||
context?.let {
|
context?.let {
|
||||||
if (intent.resolveActivity(it.packageManager) != null) {
|
if (intent.resolveActivity(it.packageManager) != null) {
|
||||||
@ -89,8 +130,15 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun openLicenses() {
|
||||||
|
(activity as? MainActivity)?.pushView(LicenseFragment.newInstance())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openPrivacyPolicy() {
|
||||||
|
context?.openInternetBrowser("https://wulkanowy.github.io/polityka-prywatnosci.html", ::showMessage)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
fragmentCompat.onDestroyView()
|
|
||||||
presenter.onDetachView()
|
presenter.onDetachView()
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.view.View
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
import kotlinx.android.synthetic.main.item_about.*
|
||||||
|
|
||||||
|
class AboutItem(
|
||||||
|
val title: String,
|
||||||
|
private val summary: String,
|
||||||
|
private val image: Drawable?
|
||||||
|
) : AbstractFlexibleItem<AboutItem.ViewHolder>() {
|
||||||
|
|
||||||
|
override fun getLayoutRes() = R.layout.item_about
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) = ViewHolder(view, adapter)
|
||||||
|
|
||||||
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
|
||||||
|
with(holder) {
|
||||||
|
aboutItemImage.setImageDrawable(image)
|
||||||
|
aboutItemTitle.text = title
|
||||||
|
aboutItemSummary.text = summary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as AboutItem
|
||||||
|
|
||||||
|
if (title != other.title) return false
|
||||||
|
if (summary != other.summary) return false
|
||||||
|
if (image != other.image) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = title.hashCode()
|
||||||
|
result = 31 * result + summary.hashCode()
|
||||||
|
result = 31 * result + (image?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) : FlexibleViewHolder(view, adapter),
|
||||||
|
LayoutContainer {
|
||||||
|
|
||||||
|
override val containerView: View? get() = contentView
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about
|
|
||||||
|
|
||||||
import com.mikepenz.aboutlibraries.LibsFragmentCompat
|
|
||||||
import dagger.Module
|
|
||||||
import dagger.Provides
|
|
||||||
import io.github.wulkanowy.di.scopes.PerFragment
|
|
||||||
|
|
||||||
@Module
|
|
||||||
class AboutModule {
|
|
||||||
|
|
||||||
@PerFragment
|
|
||||||
@Provides
|
|
||||||
fun provideLibsFragmentCompat() = LibsFragmentCompat()
|
|
||||||
}
|
|
@ -1,9 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about
|
package io.github.wulkanowy.ui.modules.about
|
||||||
|
|
||||||
import com.mikepenz.aboutlibraries.Libs
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL1
|
|
||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL2
|
|
||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL3
|
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
@ -21,28 +18,53 @@ class AboutPresenter @Inject constructor(
|
|||||||
|
|
||||||
override fun onAttachView(view: AboutView) {
|
override fun onAttachView(view: AboutView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
view.initView()
|
||||||
Timber.i("About view was initialized")
|
Timber.i("About view was initialized")
|
||||||
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onExtraSelect(type: Libs.SpecialButton?) {
|
fun onItemSelected(item: AbstractFlexibleItem<*>) {
|
||||||
|
if (item !is AboutItem) return
|
||||||
view?.run {
|
view?.run {
|
||||||
when (type) {
|
when (item.title) {
|
||||||
SPECIAL1 -> {
|
feedbackRes?.first -> {
|
||||||
Timber.i("Opening discord invide page")
|
Timber.i("Opening email client ")
|
||||||
analytics.logEvent("open_page", "name" to "discord")
|
openEmailClient()
|
||||||
openDiscordInviteView()
|
analytics.logEvent("about_open", "name" to "feedback")
|
||||||
}
|
}
|
||||||
SPECIAL2 -> {
|
discordRes?.first -> {
|
||||||
Timber.i("Opening home page")
|
Timber.i("Opening discord")
|
||||||
analytics.logEvent("open_page", "name" to "home")
|
openDiscordInvite()
|
||||||
openHomepageWebView()
|
analytics.logEvent("about_open", "name" to "discord")
|
||||||
}
|
}
|
||||||
SPECIAL3 -> {
|
homepageRes?.first -> {
|
||||||
Timber.i("Opening email client")
|
Timber.i("Opening homepage")
|
||||||
analytics.logEvent("open_page", "name" to "email")
|
openHomepage()
|
||||||
openEmailClientView()
|
analytics.logEvent("about_open", "name" to "homepage")
|
||||||
|
}
|
||||||
|
licensesRes?.first -> {
|
||||||
|
Timber.i("Opening licenses view")
|
||||||
|
openLicenses()
|
||||||
|
analytics.logEvent("about_open", "name" to "licenses")
|
||||||
|
}
|
||||||
|
privacyRes?.first -> {
|
||||||
|
Timber.i("Opening privacy page ")
|
||||||
|
openPrivacyPolicy()
|
||||||
|
analytics.logEvent("about_open", "name" to "privacy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadData() {
|
||||||
|
view?.run {
|
||||||
|
updateData(AboutScrollableHeader(), listOfNotNull(
|
||||||
|
versionRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
||||||
|
feedbackRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
||||||
|
discordRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
||||||
|
homepageRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
||||||
|
licensesRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
||||||
|
privacyRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
import kotlinx.android.synthetic.main.scrollable_header_about.*
|
||||||
|
|
||||||
|
class AboutScrollableHeader : AbstractFlexibleItem<AboutScrollableHeader.ViewHolder>() {
|
||||||
|
|
||||||
|
override fun getLayoutRes() = R.layout.scrollable_header_about
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) = ViewHolder(view, adapter)
|
||||||
|
|
||||||
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
|
||||||
|
with(holder) {
|
||||||
|
val context = contentView.context
|
||||||
|
val drawable = ResourcesCompat.getDrawableForDensity(context.resources, context.applicationInfo.icon, 640, null)
|
||||||
|
|
||||||
|
aboutScrollableHeaderIcon.setImageDrawable(drawable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode() = javaClass.hashCode()
|
||||||
|
|
||||||
|
class ViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) : FlexibleViewHolder(view, adapter),
|
||||||
|
LayoutContainer {
|
||||||
|
|
||||||
|
override val containerView: View? get() = contentView
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,33 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about
|
package io.github.wulkanowy.ui.modules.about
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface AboutView : BaseView {
|
interface AboutView : BaseView {
|
||||||
|
|
||||||
fun openDiscordInviteView()
|
val versionRes: Triple<String, String, Drawable?>?
|
||||||
|
|
||||||
fun openEmailClientView()
|
val feedbackRes: Triple<String, String, Drawable?>?
|
||||||
|
|
||||||
fun openHomepageWebView()
|
val discordRes: Triple<String, String, Drawable?>?
|
||||||
|
|
||||||
|
val homepageRes: Triple<String, String, Drawable?>?
|
||||||
|
|
||||||
|
val licensesRes: Triple<String, String, Drawable?>?
|
||||||
|
|
||||||
|
val privacyRes: Triple<String, String, Drawable?>?
|
||||||
|
|
||||||
|
fun initView()
|
||||||
|
|
||||||
|
fun updateData(header: AboutScrollableHeader, items: List<AboutItem>)
|
||||||
|
|
||||||
|
fun openDiscordInvite()
|
||||||
|
|
||||||
|
fun openEmailClient()
|
||||||
|
|
||||||
|
fun openHomepage()
|
||||||
|
|
||||||
|
fun openLicenses()
|
||||||
|
|
||||||
|
fun openPrivacyPolicy()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about.license
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.View.GONE
|
||||||
|
import android.view.View.VISIBLE
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.text.parseAsHtml
|
||||||
|
import com.mikepenz.aboutlibraries.Libs
|
||||||
|
import com.mikepenz.aboutlibraries.entity.Library
|
||||||
|
import dagger.Lazy
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
|
import kotlinx.android.synthetic.main.fragment_license.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LicenseFragment : BaseFragment(), LicenseView, MainView.TitledView {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var presenter: LicensePresenter
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var licenseAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var libs: Lazy<Libs>
|
||||||
|
|
||||||
|
override val titleStringId get() = R.string.license_title
|
||||||
|
|
||||||
|
override val appLibraries: ArrayList<Library>?
|
||||||
|
get() = context?.let {
|
||||||
|
libs.get().prepareLibraries(it, emptyArray(), emptyArray(), autoDetect = true, checkCachedDetection = true, sort = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = LicenseFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.fragment_license, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
presenter.onAttachView(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
with(licenseRecycler) {
|
||||||
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
|
adapter = licenseAdapter
|
||||||
|
}
|
||||||
|
licenseAdapter.setOnItemClickListener(presenter::onItemSelected)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateData(data: List<LicenseItem>) {
|
||||||
|
licenseAdapter.updateDataSet(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openLicense(licenseHtml: String) {
|
||||||
|
context?.let {
|
||||||
|
AlertDialog.Builder(it).apply {
|
||||||
|
setTitle(R.string.license_dialog_title)
|
||||||
|
setMessage(licenseHtml.parseAsHtml())
|
||||||
|
setPositiveButton(android.R.string.ok) { _, _ -> }
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showProgress(show: Boolean) {
|
||||||
|
licenseProgress.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
presenter.onDetachView()
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about.license
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.mikepenz.aboutlibraries.entity.Library
|
||||||
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
import kotlinx.android.synthetic.main.item_license.*
|
||||||
|
|
||||||
|
class LicenseItem(val library: Library) : AbstractFlexibleItem<LicenseItem.ViewHolder>() {
|
||||||
|
|
||||||
|
override fun getLayoutRes() = R.layout.item_license
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) = ViewHolder(view, adapter)
|
||||||
|
|
||||||
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
|
||||||
|
with(holder) {
|
||||||
|
licenseItemName.text = library.libraryName
|
||||||
|
licenseItemSummary.text = library.license?.licenseName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as LicenseItem
|
||||||
|
|
||||||
|
if (library != other.library) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode() = library.hashCode()
|
||||||
|
|
||||||
|
class ViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) : FlexibleViewHolder(view, adapter),
|
||||||
|
LayoutContainer {
|
||||||
|
|
||||||
|
override val containerView: View? get() = contentView
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about.license
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.mikepenz.aboutlibraries.Libs
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import io.github.wulkanowy.di.scopes.PerFragment
|
||||||
|
|
||||||
|
@Module
|
||||||
|
class LicenseModule {
|
||||||
|
|
||||||
|
@PerFragment
|
||||||
|
@Provides
|
||||||
|
fun provideLibs(context: Context) = Libs(context)
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about.license
|
||||||
|
|
||||||
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.reactivex.Single
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LicensePresenter @Inject constructor(
|
||||||
|
schedulers: SchedulersProvider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository
|
||||||
|
) : BasePresenter<LicenseView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
|
override fun onAttachView(view: LicenseView) {
|
||||||
|
super.onAttachView(view)
|
||||||
|
view.initView()
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onItemSelected(item: AbstractFlexibleItem<*>) {
|
||||||
|
if (item !is LicenseItem) return
|
||||||
|
view?.run { item.library.license?.licenseDescription?.let { openLicense(it) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadData() {
|
||||||
|
disposable.add(Single.fromCallable { view?.appLibraries }
|
||||||
|
.map {
|
||||||
|
val exclude = listOf("Android-Iconics", "CircleImageView", "FastAdapter", "Jsoup", "okio", "Retrofit")
|
||||||
|
it.filter { library -> !exclude.contains(library.libraryName) }
|
||||||
|
}
|
||||||
|
.map { it.map { library -> LicenseItem(library) } }
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.doOnEvent { _, _ -> view?.showProgress(false) }
|
||||||
|
.subscribe({ view?.run { updateData(it) } }, { errorHandler.dispatch(it) }))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about.license
|
||||||
|
|
||||||
|
import com.mikepenz.aboutlibraries.entity.Library
|
||||||
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
|
interface LicenseView : BaseView {
|
||||||
|
|
||||||
|
val appLibraries: ArrayList<Library>?
|
||||||
|
|
||||||
|
fun initView()
|
||||||
|
|
||||||
|
fun updateData(data: List<LicenseItem>)
|
||||||
|
|
||||||
|
fun openLicense(licenseHtml: String)
|
||||||
|
|
||||||
|
fun showProgress(show: Boolean)
|
||||||
|
}
|
@ -1,13 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account
|
package io.github.wulkanowy.ui.modules.account
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.graphics.PorterDuff
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.graphics.ColorUtils
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
import kotlinx.android.synthetic.main.item_account.*
|
import kotlinx.android.synthetic.main.item_account.*
|
||||||
|
|
||||||
@ -15,16 +18,19 @@ class AccountItem(val student: Student) : AbstractFlexibleItem<AccountItem.ViewH
|
|||||||
|
|
||||||
override fun getLayoutRes() = R.layout.item_account
|
override fun getLayoutRes() = R.layout.item_account
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>): ViewHolder {
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) = ViewHolder(view, adapter)
|
||||||
return ViewHolder(view, adapter)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>?) {
|
||||||
holder.apply {
|
val context = holder.contentView.context
|
||||||
|
|
||||||
|
val colorImage = if (student.isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
|
||||||
|
else ColorUtils.setAlphaComponent(context.getThemeAttrColor(R.attr.colorOnSurface), 153)
|
||||||
|
|
||||||
|
with(holder) {
|
||||||
accountItemName.text = "${student.studentName} ${student.className}"
|
accountItemName.text = "${student.studentName} ${student.className}"
|
||||||
accountItemSchool.text = student.schoolName
|
accountItemSchool.text = student.schoolName
|
||||||
accountItemImage.setBackgroundResource(if (student.isCurrent) R.drawable.ic_account_circular_border else 0)
|
accountItemImage.setColorFilter(colorImage, PorterDuff.Mode.SRC_IN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,8 +51,9 @@ class AccountItem(val student: Student) : AbstractFlexibleItem<AccountItem.ViewH
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter), LayoutContainer {
|
class ViewHolder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter),
|
||||||
override val containerView: View
|
LayoutContainer {
|
||||||
get() = contentView
|
|
||||||
|
override val containerView: View? get() = contentView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,13 @@ import io.github.wulkanowy.ui.base.BaseFragment
|
|||||||
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
|
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_attendance.*
|
import kotlinx.android.synthetic.main.fragment_attendance.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView, MainView.TitledView {
|
class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView,
|
||||||
|
MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: AttendancePresenter
|
lateinit var presenter: AttendancePresenter
|
||||||
@ -35,14 +37,11 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
|
|||||||
fun newInstance() = AttendanceFragment()
|
fun newInstance() = AttendanceFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.attendance_title
|
||||||
get() = R.string.attendance_title
|
|
||||||
|
|
||||||
override val isViewEmpty: Boolean
|
override val isViewEmpty get() = attendanceAdapter.isEmpty
|
||||||
get() = attendanceAdapter.isEmpty
|
|
||||||
|
|
||||||
override val currentStackSize: Int?
|
override val currentStackSize get() = (activity as? MainActivity)?.currentStackSize
|
||||||
get() = (activity as? MainActivity)?.currentStackSize
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -60,21 +59,21 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
attendanceAdapter.apply {
|
attendanceAdapter.setOnItemClickListener(presenter::onAttendanceItemSelected)
|
||||||
setOnItemClickListener { presenter.onAttendanceItemSelected(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
attendanceRecycler.run {
|
with(attendanceRecycler) {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
adapter = attendanceAdapter
|
adapter = attendanceAdapter
|
||||||
addItemDecoration(FlexibleItemDecoration(context)
|
addItemDecoration(FlexibleItemDecoration(context)
|
||||||
.withDefaultDivider()
|
.withDefaultDivider()
|
||||||
.withDrawDividerOnLastItem(false)
|
.withDrawDividerOnLastItem(false))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
attendanceSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
|
||||||
|
attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
||||||
attendanceNextButton.setOnClickListener { presenter.onNextDay() }
|
attendanceNextButton.setOnClickListener { presenter.onNextDay() }
|
||||||
|
|
||||||
|
attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
@ -15,6 +15,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
||||||
import kotlinx.android.synthetic.main.fragment_attendance_summary.*
|
import kotlinx.android.synthetic.main.fragment_attendance_summary.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -35,11 +36,9 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie
|
|||||||
fun newInstance() = AttendanceSummaryFragment()
|
fun newInstance() = AttendanceSummaryFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.attendance_title
|
||||||
get() = R.string.attendance_title
|
|
||||||
|
|
||||||
override val isViewEmpty
|
override val isViewEmpty get() = attendanceSummaryAdapter.isEmpty
|
||||||
get() = attendanceSummaryAdapter.isEmpty
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_attendance_summary, container, false)
|
return inflater.inflate(R.layout.fragment_attendance_summary, container, false)
|
||||||
@ -52,25 +51,26 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
attendanceSummaryRecycler.run {
|
with(attendanceSummaryRecycler) {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
adapter = attendanceSummaryAdapter
|
adapter = attendanceSummaryAdapter
|
||||||
}
|
}
|
||||||
attendanceSummarySwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
|
||||||
|
|
||||||
context?.let {
|
attendanceSummarySwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
subjectsAdapter = ArrayAdapter(it, android.R.layout.simple_spinner_item, ArrayList<String>())
|
|
||||||
subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject)
|
|
||||||
}
|
|
||||||
|
|
||||||
attendanceSummarySubjects.run {
|
subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf())
|
||||||
|
subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject)
|
||||||
|
|
||||||
|
with(attendanceSummarySubjects) {
|
||||||
adapter = subjectsAdapter
|
adapter = subjectsAdapter
|
||||||
setOnItemSelectedListener { presenter.onSubjectSelected((it as TextView).text.toString()) }
|
setOnItemSelectedListener<TextView> { presenter.onSubjectSelected(it?.text?.toString()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attendanceSummarySubjectsContainer.setElevationCompat(requireContext().dpToPx(1f))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateSubjects(data: ArrayList<String>) {
|
override fun updateSubjects(data: ArrayList<String>) {
|
||||||
subjectsAdapter.run {
|
with(subjectsAdapter) {
|
||||||
clear()
|
clear()
|
||||||
addAll(data)
|
addAll(data)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
@ -78,9 +78,9 @@ class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun updateDataSet(data: List<AttendanceSummaryItem>, header: AttendanceSummaryScrollableHeader) {
|
override fun updateDataSet(data: List<AttendanceSummaryItem>, header: AttendanceSummaryScrollableHeader) {
|
||||||
attendanceSummaryAdapter.apply {
|
with(attendanceSummaryAdapter) {
|
||||||
updateDataSet(data, true)
|
updateDataSet(data, true)
|
||||||
removeAllScrollableHeaders()
|
removeAllScrollableFooters()
|
||||||
addScrollableHeader(header)
|
addScrollableHeader(header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class AttendanceSummaryPresenter @Inject constructor(
|
|||||||
loadData(currentSubjectId, true)
|
loadData(currentSubjectId, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSubjectSelected(name: String) {
|
fun onSubjectSelected(name: String?) {
|
||||||
Timber.i("Select attendance summary subject $name")
|
Timber.i("Select attendance summary subject $name")
|
||||||
view?.run {
|
view?.run {
|
||||||
showContent(false)
|
showContent(false)
|
||||||
|
@ -16,6 +16,7 @@ import io.github.wulkanowy.data.db.entities.Exam
|
|||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_exam.*
|
import kotlinx.android.synthetic.main.fragment_exam.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -34,11 +35,9 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.
|
|||||||
fun newInstance() = ExamFragment()
|
fun newInstance() = ExamFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.exam_title
|
||||||
get() = R.string.exam_title
|
|
||||||
|
|
||||||
override val isViewEmpty: Boolean
|
override val isViewEmpty get() = examAdapter.isEmpty
|
||||||
get() = examAdapter.isEmpty
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_exam, container, false)
|
return inflater.inflate(R.layout.fragment_exam, container, false)
|
||||||
@ -51,20 +50,21 @@ class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
examAdapter.run {
|
examAdapter.setOnItemClickListener(presenter::onExamItemSelected)
|
||||||
setOnItemClickListener { presenter.onExamItemSelected(it) }
|
|
||||||
}
|
with(examRecycler) {
|
||||||
examRecycler.run {
|
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
adapter = examAdapter
|
adapter = examAdapter
|
||||||
addItemDecoration(FlexibleItemDecoration(context)
|
addItemDecoration(FlexibleItemDecoration(context)
|
||||||
.withDefaultDivider(R.layout.item_exam)
|
.withDefaultDivider(R.layout.item_exam)
|
||||||
.withDrawDividerOnLastItem(false)
|
.withDrawDividerOnLastItem(false))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
examSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
|
||||||
|
examSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
examPreviousButton.setOnClickListener { presenter.onPreviousWeek() }
|
examPreviousButton.setOnClickListener { presenter.onPreviousWeek() }
|
||||||
examNextButton.setOnClickListener { presenter.onNextWeek() }
|
examNextButton.setOnClickListener { presenter.onNextWeek() }
|
||||||
|
|
||||||
|
examNavContainer.setElevationCompat(requireContext().dpToPx(8f))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hideRefresh() {
|
override fun hideRefresh() {
|
||||||
|
@ -17,6 +17,7 @@ import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
|
|||||||
import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment
|
import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
|
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.setOnSelectPageListener
|
import io.github.wulkanowy.utils.setOnSelectPageListener
|
||||||
import kotlinx.android.synthetic.main.fragment_grade.*
|
import kotlinx.android.synthetic.main.fragment_grade.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -37,11 +38,9 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
|
|||||||
fun newInstance() = GradeFragment()
|
fun newInstance() = GradeFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.grade_title
|
||||||
get() = R.string.grade_title
|
|
||||||
|
|
||||||
override val currentPageIndex: Int
|
override val currentPageIndex get() = gradeViewPager.currentItem
|
||||||
get() = gradeViewPager.currentItem
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -64,7 +63,7 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
pagerAdapter.apply {
|
with(pagerAdapter) {
|
||||||
containerId = gradeViewPager.id
|
containerId = gradeViewPager.id
|
||||||
addFragmentsWithTitle(mapOf(
|
addFragmentsWithTitle(mapOf(
|
||||||
GradeDetailsFragment.newInstance() to getString(R.string.all_details),
|
GradeDetailsFragment.newInstance() to getString(R.string.all_details),
|
||||||
@ -73,13 +72,18 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
gradeViewPager.run {
|
with(gradeViewPager) {
|
||||||
adapter = pagerAdapter
|
adapter = pagerAdapter
|
||||||
offscreenPageLimit = 3
|
offscreenPageLimit = 3
|
||||||
setOnSelectPageListener { presenter.onPageSelected(it) }
|
setOnSelectPageListener(presenter::onPageSelected)
|
||||||
}
|
}
|
||||||
gradeTabLayout.setupWithViewPager(gradeViewPager)
|
|
||||||
gradeSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
with(gradeTabLayout) {
|
||||||
|
setupWithViewPager(gradeViewPager)
|
||||||
|
setElevationCompat(context.dpToPx(4f))
|
||||||
|
}
|
||||||
|
|
||||||
|
gradeSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
@ -117,19 +121,19 @@ class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showSemesterDialog(selectedIndex: Int) {
|
override fun showSemesterDialog(selectedIndex: Int) {
|
||||||
arrayOf(getString(R.string.grade_semester, 1),
|
val choices = arrayOf(
|
||||||
getString(R.string.grade_semester, 2)).also { array ->
|
getString(R.string.grade_semester, 1),
|
||||||
context?.let {
|
getString(R.string.grade_semester, 2)
|
||||||
AlertDialog.Builder(it)
|
)
|
||||||
.setSingleChoiceItems(array, selectedIndex) { dialog, which ->
|
|
||||||
presenter.onSemesterSelected(which)
|
AlertDialog.Builder(requireContext())
|
||||||
dialog.dismiss()
|
.setSingleChoiceItems(choices, selectedIndex) { dialog, which ->
|
||||||
}
|
presenter.onSemesterSelected(which)
|
||||||
.setTitle(R.string.grade_switch_semester)
|
dialog.dismiss()
|
||||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
.setTitle(R.string.grade_switch_semester)
|
||||||
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onChildRefresh() {
|
fun onChildRefresh() {
|
||||||
|
@ -10,6 +10,7 @@ import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
|
|||||||
import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment
|
import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
|
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
@Module
|
@Module
|
||||||
abstract class GradeModule {
|
abstract class GradeModule {
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import io.github.wulkanowy.data.db.entities.GradeStatistics
|
|||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeView
|
import io.github.wulkanowy.ui.modules.grade.GradeView
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
||||||
import kotlinx.android.synthetic.main.fragment_grade_statistics.*
|
import kotlinx.android.synthetic.main.fragment_grade_statistics.*
|
||||||
@ -37,8 +38,7 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
|||||||
fun newInstance() = GradeStatisticsFragment()
|
fun newInstance() = GradeStatisticsFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isViewEmpty
|
override val isViewEmpty get() = gradeStatisticsChart.isEmpty
|
||||||
get() = gradeStatisticsChart.isEmpty
|
|
||||||
|
|
||||||
private lateinit var gradeColors: List<Pair<Int, Int>>
|
private lateinit var gradeColors: List<Pair<Int, Int>>
|
||||||
|
|
||||||
@ -75,32 +75,30 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
gradeStatisticsChart.run {
|
with(gradeStatisticsChart) {
|
||||||
description.isEnabled = false
|
description.isEnabled = false
|
||||||
setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground))
|
setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground))
|
||||||
setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary))
|
setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary))
|
||||||
animateXY(1000, 1000)
|
animateXY(1000, 1000)
|
||||||
minAngleForSlices = 25f
|
minAngleForSlices = 25f
|
||||||
legend.apply {
|
legend.textColor = context.getThemeAttrColor(android.R.attr.textColorPrimary)
|
||||||
textColor = context.getThemeAttrColor(android.R.attr.textColorPrimary)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context?.let {
|
subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf())
|
||||||
subjectsAdapter = ArrayAdapter(it, android.R.layout.simple_spinner_item, ArrayList<String>())
|
subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject)
|
||||||
subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject)
|
|
||||||
}
|
|
||||||
|
|
||||||
gradeStatisticsSubjects.run {
|
with(gradeStatisticsSubjects) {
|
||||||
adapter = subjectsAdapter
|
adapter = subjectsAdapter
|
||||||
setOnItemSelectedListener { presenter.onSubjectSelected((it as TextView).text.toString()) }
|
setOnItemSelectedListener<TextView> { presenter.onSubjectSelected(it?.text?.toString()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
gradeStatisticsSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
gradeStatisticsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
|
|
||||||
|
gradeStatisticsSubjectsContainer.setElevationCompat(requireContext().dpToPx(1f))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateSubjects(data: ArrayList<String>) {
|
override fun updateSubjects(data: ArrayList<String>) {
|
||||||
subjectsAdapter.run {
|
with(subjectsAdapter) {
|
||||||
clear()
|
clear()
|
||||||
addAll(data)
|
addAll(data)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
@ -204,7 +202,7 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
|||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putBoolean(GradeStatisticsFragment.SAVED_CHART_TYPE, presenter.currentIsSemester)
|
outState.putBoolean(SAVED_CHART_TYPE, presenter.currentIsSemester)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -62,7 +62,7 @@ class GradeStatisticsPresenter @Inject constructor(
|
|||||||
view?.notifyParentRefresh()
|
view?.notifyParentRefresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSubjectSelected(name: String) {
|
fun onSubjectSelected(name: String?) {
|
||||||
Timber.i("Select grade stats subject $name")
|
Timber.i("Select grade stats subject $name")
|
||||||
view?.run {
|
view?.run {
|
||||||
showContent(false)
|
showContent(false)
|
||||||
@ -71,8 +71,8 @@ class GradeStatisticsPresenter @Inject constructor(
|
|||||||
showEmpty(false)
|
showEmpty(false)
|
||||||
clearView()
|
clearView()
|
||||||
}
|
}
|
||||||
(subjects.singleOrNull { it.name == name }?.name).let {
|
(subjects.singleOrNull { it.name == name }?.name)?.let {
|
||||||
if (it != currentSubjectName) loadData(currentSemesterId, name, currentIsSemester)
|
if (it != currentSubjectName) loadData(currentSemesterId, it, currentIsSemester)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import io.github.wulkanowy.data.db.entities.Homework
|
|||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_homework.*
|
import kotlinx.android.synthetic.main.fragment_homework.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -31,8 +32,7 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView {
|
|||||||
fun newInstance() = HomeworkFragment()
|
fun newInstance() = HomeworkFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.homework_title
|
||||||
get() = R.string.homework_title
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_homework, container, false)
|
return inflater.inflate(R.layout.fragment_homework, container, false)
|
||||||
@ -45,21 +45,21 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
homeworkAdapter.run {
|
homeworkAdapter.setOnItemClickListener(presenter::onHomeworkItemSelected)
|
||||||
setOnItemClickListener { presenter.onHomeworkItemSelected(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
homeworkRecycler.run {
|
with(homeworkRecycler) {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
adapter = homeworkAdapter
|
adapter = homeworkAdapter
|
||||||
addItemDecoration(FlexibleItemDecoration(context)
|
addItemDecoration(FlexibleItemDecoration(context)
|
||||||
.withDefaultDivider()
|
.withDefaultDivider()
|
||||||
.withDrawDividerOnLastItem(false)
|
.withDrawDividerOnLastItem(false))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
homeworkSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
|
||||||
|
homeworkSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
homeworkPreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
homeworkPreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
||||||
homeworkNextButton.setOnClickListener { presenter.onNextDay() }
|
homeworkNextButton.setOnClickListener { presenter.onNextDay() }
|
||||||
|
|
||||||
|
homeworkNavContainer.setElevationCompat(requireContext().dpToPx(8f))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateData(data: List<HomeworkItem>) {
|
override fun updateData(data: List<HomeworkItem>) {
|
||||||
@ -110,7 +110,7 @@ class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView {
|
|||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putLong(HomeworkFragment.SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -10,6 +10,7 @@ import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
|||||||
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
@Module
|
@Module
|
||||||
internal abstract class LoginModule {
|
internal abstract class LoginModule {
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import android.view.ViewGroup
|
|||||||
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
||||||
import android.view.inputmethod.EditorInfo.IME_NULL
|
import android.view.inputmethod.EditorInfo.IME_NULL
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.core.widget.doOnTextChanged
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
@ -17,8 +18,6 @@ import io.github.wulkanowy.ui.modules.login.LoginActivity
|
|||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.hideSoftInput
|
import io.github.wulkanowy.utils.hideSoftInput
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
|
||||||
import io.github.wulkanowy.utils.setOnTextChangedListener
|
|
||||||
import io.github.wulkanowy.utils.showSoftInput
|
import io.github.wulkanowy.utils.showSoftInput
|
||||||
import kotlinx.android.synthetic.main.fragment_login_form.*
|
import kotlinx.android.synthetic.main.fragment_login_form.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -35,14 +34,16 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
fun newInstance() = LoginFormFragment()
|
fun newInstance() = LoginFormFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val formNameValue: String
|
override val formNameValue get() = loginFormName.text.toString()
|
||||||
get() = loginFormName.text.toString()
|
|
||||||
|
|
||||||
override val formPassValue: String
|
override val formPassValue get() = loginFormPass.text.toString()
|
||||||
get() = loginFormPass.text.toString()
|
|
||||||
|
|
||||||
override val formHostValue: String?
|
override val formHostValue
|
||||||
get() = resources.getStringArray(R.array.endpoints_values)[loginFormHost.selectedItemPosition]
|
get() = hostValues.getOrNull(hostKeys.indexOf(loginFormHost.text.toString()))
|
||||||
|
|
||||||
|
private lateinit var hostKeys: Array<String>
|
||||||
|
|
||||||
|
private lateinit var hostValues: Array<String>
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_login_form, container, false)
|
return inflater.inflate(R.layout.fragment_login_form, container, false)
|
||||||
@ -54,9 +55,12 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
loginFormName.setOnTextChangedListener { presenter.onNameTextChanged() }
|
hostKeys = resources.getStringArray(R.array.endpoints_keys)
|
||||||
loginFormPass.setOnTextChangedListener { presenter.onPassTextChanged() }
|
hostValues = resources.getStringArray(R.array.endpoints_values)
|
||||||
loginFormHost.setOnItemSelectedListener { presenter.onHostSelected() }
|
|
||||||
|
loginFormName.doOnTextChanged { _, _, _, _ -> presenter.onNameTextChanged() }
|
||||||
|
loginFormPass.doOnTextChanged { _, _, _, _ -> presenter.onPassTextChanged() }
|
||||||
|
loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
|
||||||
loginFormSignIn.setOnClickListener { presenter.onSignInClick() }
|
loginFormSignIn.setOnClickListener { presenter.onSignInClick() }
|
||||||
loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() }
|
loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() }
|
||||||
|
|
||||||
@ -64,40 +68,44 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
if (id == IME_ACTION_DONE || id == IME_NULL) loginFormSignIn.callOnClick() else false
|
if (id == IME_ACTION_DONE || id == IME_NULL) loginFormSignIn.callOnClick() else false
|
||||||
}
|
}
|
||||||
|
|
||||||
context?.let {
|
with(loginFormHost) {
|
||||||
loginFormHost.adapter = ArrayAdapter.createFromResource(it, R.array.endpoints_keys, android.R.layout.simple_spinner_item)
|
//Bug with filter in ExposedDropdownMenu on restoring state
|
||||||
.apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) }
|
isSaveEnabled = false
|
||||||
|
|
||||||
|
setText(hostKeys.getOrElse(0) { "" })
|
||||||
|
setAdapter(ArrayAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
|
||||||
|
keyListener = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setDefaultCredentials(name: String, pass: String) {
|
override fun setCredentials(name: String, pass: String) {
|
||||||
loginFormName.setText(name)
|
loginFormName.setText(name)
|
||||||
loginFormPass.setText(pass)
|
loginFormPass.setText(pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setErrorNameRequired() {
|
override fun setErrorNameRequired() {
|
||||||
loginFormNameLayout.run {
|
with(loginFormNameLayout) {
|
||||||
requestFocus()
|
requestFocus()
|
||||||
error = getString(R.string.login_field_required)
|
error = getString(R.string.login_field_required)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setErrorPassRequired(focus: Boolean) {
|
override fun setErrorPassRequired(focus: Boolean) {
|
||||||
loginFormPassLayout.run {
|
with(loginFormPassLayout) {
|
||||||
if (focus) requestFocus()
|
if (focus) requestFocus()
|
||||||
error = getString(R.string.login_field_required)
|
error = getString(R.string.login_field_required)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setErrorPassInvalid(focus: Boolean) {
|
override fun setErrorPassInvalid(focus: Boolean) {
|
||||||
loginFormPassLayout.run {
|
with(loginFormPassLayout) {
|
||||||
if (focus) requestFocus()
|
if (focus) requestFocus()
|
||||||
error = getString(R.string.login_invalid_password)
|
error = getString(R.string.login_invalid_password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setErrorPassIncorrect() {
|
override fun setErrorPassIncorrect() {
|
||||||
loginFormPassLayout.run {
|
with(loginFormPassLayout) {
|
||||||
requestFocus()
|
requestFocus()
|
||||||
error = getString(R.string.login_incorrect_password)
|
error = getString(R.string.login_incorrect_password)
|
||||||
}
|
}
|
||||||
@ -129,7 +137,7 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun showVersion() {
|
override fun showVersion() {
|
||||||
loginFormVersion.apply {
|
with(loginFormVersion) {
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
text = "${getString(R.string.app_name)} ${appInfo.versionName}"
|
text = "${getString(R.string.app_name)} ${appInfo.versionName}"
|
||||||
}
|
}
|
||||||
@ -140,11 +148,12 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun notifyParentAccountLogged(students: List<Student>) {
|
override fun notifyParentAccountLogged(students: List<Student>) {
|
||||||
(activity as? LoginActivity)?.onFormFragmentAccountLogged(students, Triple(
|
(activity as? LoginActivity)?.onFormFragmentAccountLogged(students,
|
||||||
loginFormName.text.toString(),
|
Triple(
|
||||||
loginFormPass.text.toString(),
|
loginFormName.text.toString(),
|
||||||
resources.getStringArray(R.array.endpoints_values)[loginFormHost.selectedItemPosition]
|
loginFormPass.text.toString(),
|
||||||
))
|
resources.getStringArray(R.array.endpoints_values)[1]
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openPrivacyPolicyPage() {
|
override fun openPrivacyPolicyPage() {
|
||||||
|
@ -40,7 +40,7 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
view?.apply {
|
view?.apply {
|
||||||
clearPassError()
|
clearPassError()
|
||||||
clearNameError()
|
clearNameError()
|
||||||
if (formHostValue?.contains("fakelog") == true) setDefaultCredentials("jan@fakelog.cf", "jan123")
|
if (formHostValue?.contains("fakelog") == true) setCredentials("jan@fakelog.cf", "jan123")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ interface LoginFormView : BaseView {
|
|||||||
|
|
||||||
val formHostValue: String?
|
val formHostValue: String?
|
||||||
|
|
||||||
fun setDefaultCredentials(name: String, pass: String)
|
fun setCredentials(name: String, pass: String)
|
||||||
|
|
||||||
fun setErrorNameRequired()
|
fun setErrorNameRequired()
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class LoginStudentSelectItem(val student: Student) : AbstractFlexibleItem<LoginS
|
|||||||
get() = itemView
|
get() = itemView
|
||||||
|
|
||||||
init {
|
init {
|
||||||
loginItemCheck.setOnClickListener { super.onClick(loginItemContainer) }
|
loginItemCheck.keyListener = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(view: View?) {
|
override fun onClick(view: View?) {
|
||||||
|
@ -9,12 +9,12 @@ import android.view.ViewGroup
|
|||||||
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
||||||
import android.view.inputmethod.EditorInfo.IME_NULL
|
import android.view.inputmethod.EditorInfo.IME_NULL
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.core.widget.doOnTextChanged
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.utils.hideSoftInput
|
import io.github.wulkanowy.utils.hideSoftInput
|
||||||
import io.github.wulkanowy.utils.setOnTextChangedListener
|
|
||||||
import io.github.wulkanowy.utils.showSoftInput
|
import io.github.wulkanowy.utils.showSoftInput
|
||||||
import kotlinx.android.synthetic.main.fragment_login_symbol.*
|
import kotlinx.android.synthetic.main.fragment_login_symbol.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -45,7 +45,7 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
|
|||||||
override fun initView() {
|
override fun initView() {
|
||||||
loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) }
|
loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) }
|
||||||
|
|
||||||
loginSymbolName.setOnTextChangedListener { presenter.onSymbolTextChanged() }
|
loginSymbolName.doOnTextChanged { _, _, _, _ -> presenter.onSymbolTextChanged() }
|
||||||
|
|
||||||
loginSymbolName.apply {
|
loginSymbolName.apply {
|
||||||
setOnEditorActionListener { _, id, _ ->
|
setOnEditorActionListener { _, id, _ ->
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.modules.luckynumberwidget
|
package io.github.wulkanowy.ui.modules.luckynumberwidget
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
@ -14,7 +14,7 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
|||||||
schedulers: SchedulersProvider,
|
schedulers: SchedulersProvider,
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
private val sharedPref: SharedPrefHelper
|
private val sharedPref: SharedPrefProvider
|
||||||
) : BasePresenter<LuckyNumberWidgetConfigureView>(errorHandler, studentRepository, schedulers) {
|
) : BasePresenter<LuckyNumberWidgetConfigureView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
private var appWidgetId: Int? = null
|
private var appWidgetId: Int? = null
|
||||||
|
@ -21,13 +21,14 @@ import android.view.View.VISIBLE
|
|||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import dagger.android.AndroidInjection
|
import dagger.android.AndroidInjection
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
|
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||||
import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository
|
import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView.MenuView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -51,7 +52,7 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() {
|
|||||||
lateinit var appWidgetManager: AppWidgetManager
|
lateinit var appWidgetManager: AppWidgetManager
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var sharedPref: SharedPrefHelper
|
lateinit var sharedPref: SharedPrefProvider
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getStudentWidgetKey(appWidgetId: Int) = "lucky_number_widget_student_$appWidgetId"
|
fun getStudentWidgetKey(appWidgetId: Int) = "lucky_number_widget_student_$appWidgetId"
|
||||||
@ -74,8 +75,8 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() {
|
|||||||
getLuckyNumber(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)?.luckyNumber?.toString() ?: "#"
|
getLuckyNumber(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)?.luckyNumber?.toString() ?: "#"
|
||||||
)
|
)
|
||||||
setOnClickPendingIntent(R.id.luckyNumberWidgetContainer,
|
setOnClickPendingIntent(R.id.luckyNumberWidgetContainer,
|
||||||
PendingIntent.getActivity(context, MenuView.LUCKY_NUMBER.id,
|
PendingIntent.getActivity(context, MainView.Section.LUCKY_NUMBER.id,
|
||||||
MainActivity.getStartIntent(context, MenuView.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT))
|
MainActivity.getStartIntent(context, MainView.Section.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT))
|
||||||
}.also {
|
}.also {
|
||||||
setStyles(it, intent)
|
setStyles(it, intent)
|
||||||
appWidgetManager.updateAppWidget(appWidgetId, it)
|
appWidgetManager.updateAppWidget(appWidgetId, it)
|
||||||
@ -114,7 +115,9 @@ class LuckyNumberWidgetProvider : BroadcastReceiver() {
|
|||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "An error has occurred in lucky number provider")
|
if (e.cause !is NoCurrentStudentException) {
|
||||||
|
Timber.e(e, "An error has occurred in lucky number provider")
|
||||||
|
}
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,21 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
import android.os.Build.VERSION.SDK_INT
|
||||||
|
import android.os.Build.VERSION_CODES.LOLLIPOP
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.graphics.ColorUtils
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.aurelhubert.ahbottomnavigation.AHBottomNavigation.TitleState.ALWAYS_SHOW
|
import com.aurelhubert.ahbottomnavigation.AHBottomNavigation.TitleState.ALWAYS_SHOW
|
||||||
import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem
|
import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem
|
||||||
|
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||||
import com.ncapdevi.fragnav.FragNavController
|
import com.ncapdevi.fragnav.FragNavController
|
||||||
import com.ncapdevi.fragnav.FragNavController.Companion.HIDE
|
import com.ncapdevi.fragnav.FragNavController.Companion.HIDE
|
||||||
|
import dagger.Lazy
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.modules.account.AccountDialog
|
import io.github.wulkanowy.ui.modules.account.AccountDialog
|
||||||
@ -26,8 +31,9 @@ import io.github.wulkanowy.ui.modules.message.MessageFragment
|
|||||||
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||||
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
||||||
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
import io.github.wulkanowy.utils.safelyPopFragment
|
import io.github.wulkanowy.utils.safelyPopFragments
|
||||||
import io.github.wulkanowy.utils.setOnViewChangeListener
|
import io.github.wulkanowy.utils.setOnViewChangeListener
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -40,10 +46,13 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var navController: FragNavController
|
lateinit var navController: FragNavController
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var overlayProvider: Lazy<ElevationOverlayProvider>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTRA_START_MENU = "extraStartMenu"
|
const val EXTRA_START_MENU = "extraStartMenu"
|
||||||
|
|
||||||
fun getStartIntent(context: Context, startMenu: MainView.MenuView? = null, clear: Boolean = false): Intent {
|
fun getStartIntent(context: Context, startMenu: MainView.Section? = null, clear: Boolean = false): Intent {
|
||||||
return Intent(context, MainActivity::class.java)
|
return Intent(context, MainActivity::class.java)
|
||||||
.apply {
|
.apply {
|
||||||
if (clear) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
|
if (clear) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
|
||||||
@ -52,24 +61,21 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isRootView: Boolean
|
override val isRootView get() = navController.isRootFragment
|
||||||
get() = navController.isRootFragment
|
|
||||||
|
|
||||||
override val currentViewTitle: String?
|
override val currentStackSize get() = navController.currentStack?.size
|
||||||
get() = (navController.currentFrag as? MainView.TitledView)?.titleStringId?.let { getString(it) }
|
|
||||||
|
|
||||||
override val currentStackSize: Int?
|
override val currentViewTitle get() = (navController.currentFrag as? MainView.TitledView)?.titleStringId?.let { getString(it) }
|
||||||
get() = navController.currentStack?.size
|
|
||||||
|
|
||||||
override var startMenuIndex = 0
|
override var startMenuIndex = 0
|
||||||
|
|
||||||
override var startMenuMoreIndex = -1
|
override var startMenuMoreIndex = -1
|
||||||
|
|
||||||
private val moreMenuFragments = listOf<Fragment>(
|
private val moreMenuFragments = mapOf<Int, Fragment>(
|
||||||
MessageFragment.newInstance(),
|
MainView.Section.MESSAGE.id to MessageFragment.newInstance(),
|
||||||
HomeworkFragment.newInstance(),
|
MainView.Section.HOMEWORK.id to HomeworkFragment.newInstance(),
|
||||||
NoteFragment.newInstance(),
|
MainView.Section.NOTE.id to NoteFragment.newInstance(),
|
||||||
LuckyNumberFragment.newInstance()
|
MainView.Section.LUCKY_NUMBER.id to LuckyNumberFragment.newInstance()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -78,11 +84,11 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
|
|||||||
setSupportActionBar(mainToolbar)
|
setSupportActionBar(mainToolbar)
|
||||||
messageContainer = mainFragmentContainer
|
messageContainer = mainFragmentContainer
|
||||||
|
|
||||||
presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_START_MENU) as? MainView.MenuView)
|
presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_START_MENU) as? MainView.Section)
|
||||||
|
|
||||||
navController.run {
|
with(navController) {
|
||||||
initialize(startMenuIndex, savedInstanceState)
|
initialize(startMenuIndex, savedInstanceState)
|
||||||
pushFragment(moreMenuFragments.getOrNull(startMenuMoreIndex))
|
pushFragment(moreMenuFragments[startMenuMoreIndex])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,30 +98,31 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
mainBottomNav.run {
|
with(mainToolbar) {
|
||||||
addItems(
|
if (SDK_INT >= LOLLIPOP) stateListAnimator = null
|
||||||
listOf(
|
setBackgroundColor(overlayProvider.get().getSurfaceColorWithOverlayIfNeeded(dpToPx(4f)))
|
||||||
AHBottomNavigationItem(R.string.grade_title, R.drawable.ic_menu_main_grade_26dp, 0),
|
}
|
||||||
AHBottomNavigationItem(R.string.attendance_title, R.drawable.ic_menu_main_attendance_24dp, 0),
|
|
||||||
AHBottomNavigationItem(R.string.exam_title, R.drawable.ic_menu_main_exam_24dp, 0),
|
with(mainBottomNav) {
|
||||||
AHBottomNavigationItem(R.string.timetable_title, R.drawable.ic_menu_main_timetable_24dp, 0),
|
addItems(listOf(
|
||||||
AHBottomNavigationItem(R.string.more_title, R.drawable.ic_menu_main_more_24dp, 0)
|
AHBottomNavigationItem(R.string.grade_title, R.drawable.ic_main_grade, 0),
|
||||||
)
|
AHBottomNavigationItem(R.string.attendance_title, R.drawable.ic_main_attendance, 0),
|
||||||
)
|
AHBottomNavigationItem(R.string.exam_title, R.drawable.ic_main_exam, 0),
|
||||||
accentColor = ContextCompat.getColor(context, R.color.colorPrimary)
|
AHBottomNavigationItem(R.string.timetable_title, R.drawable.ic_main_timetable, 0),
|
||||||
inactiveColor = getThemeAttrColor(android.R.attr.textColorSecondary)
|
AHBottomNavigationItem(R.string.more_title, R.drawable.ic_main_more, 0)
|
||||||
defaultBackgroundColor = getThemeAttrColor(R.attr.bottomNavBackground)
|
))
|
||||||
|
accentColor = getThemeAttrColor(R.attr.colorPrimary)
|
||||||
|
inactiveColor = ColorUtils.setAlphaComponent(getThemeAttrColor(R.attr.colorOnSurface), 153)
|
||||||
|
defaultBackgroundColor = overlayProvider.get().getSurfaceColorWithOverlayIfNeeded(dpToPx(8f))
|
||||||
titleState = ALWAYS_SHOW
|
titleState = ALWAYS_SHOW
|
||||||
currentItem = startMenuIndex
|
currentItem = startMenuIndex
|
||||||
isBehaviorTranslationEnabled = false
|
isBehaviorTranslationEnabled = false
|
||||||
setTitleTextSizeInSp(10f, 10f)
|
setTitleTextSizeInSp(10f, 10f)
|
||||||
setOnTabSelectedListener { position, wasSelected ->
|
setOnTabSelectedListener(presenter::onTabSelected)
|
||||||
presenter.onTabSelected(position, wasSelected)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
navController.run {
|
with(navController) {
|
||||||
setOnViewChangeListener { presenter.onViewChange() }
|
setOnViewChangeListener(presenter::onViewChange)
|
||||||
fragmentHideStrategy = HIDE
|
fragmentHideStrategy = HIDE
|
||||||
rootFragments = listOf(
|
rootFragments = listOf(
|
||||||
GradeFragment.newInstance(),
|
GradeFragment.newInstance(),
|
||||||
@ -152,6 +159,10 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
|
|||||||
navController.showDialogFragment(AccountDialog.newInstance())
|
navController.showDialogFragment(AccountDialog.newInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun showActionBarElevation(show: Boolean) {
|
||||||
|
ViewCompat.setElevation(mainToolbar, if (show) dpToPx(4f) else 0f)
|
||||||
|
}
|
||||||
|
|
||||||
override fun notifyMenuViewReselected() {
|
override fun notifyMenuViewReselected() {
|
||||||
(navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentReselected()
|
(navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentReselected()
|
||||||
}
|
}
|
||||||
@ -164,8 +175,8 @@ class MainActivity : BaseActivity<MainPresenter>(), MainView {
|
|||||||
navController.pushFragment(fragment)
|
navController.pushFragment(fragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popView() {
|
override fun popView(depth: Int) {
|
||||||
navController.safelyPopFragment()
|
navController.safelyPopFragments(depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.main
|
package io.github.wulkanowy.ui.modules.main
|
||||||
|
|
||||||
|
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||||
import com.ncapdevi.fragnav.FragNavController
|
import com.ncapdevi.fragnav.FragNavController
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
@ -7,7 +8,8 @@ import dagger.android.ContributesAndroidInjector
|
|||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.di.scopes.PerFragment
|
import io.github.wulkanowy.di.scopes.PerFragment
|
||||||
import io.github.wulkanowy.ui.modules.about.AboutFragment
|
import io.github.wulkanowy.ui.modules.about.AboutFragment
|
||||||
import io.github.wulkanowy.ui.modules.about.AboutModule
|
import io.github.wulkanowy.ui.modules.about.license.LicenseFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.about.license.LicenseModule
|
||||||
import io.github.wulkanowy.ui.modules.account.AccountDialog
|
import io.github.wulkanowy.ui.modules.account.AccountDialog
|
||||||
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
||||||
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
|
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
|
||||||
@ -19,15 +21,16 @@ import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
|||||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||||
import io.github.wulkanowy.ui.modules.message.MessageModule
|
import io.github.wulkanowy.ui.modules.message.MessageModule
|
||||||
import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment
|
import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment
|
||||||
import io.github.wulkanowy.ui.modules.mobiledevice.token.MobileDeviceTokenDialog
|
|
||||||
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
|
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
|
||||||
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceModule
|
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceModule
|
||||||
|
import io.github.wulkanowy.ui.modules.mobiledevice.token.MobileDeviceTokenDialog
|
||||||
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||||
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
||||||
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
||||||
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||||
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
|
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
@Module
|
@Module
|
||||||
abstract class MainModule {
|
abstract class MainModule {
|
||||||
|
|
||||||
@ -39,6 +42,11 @@ abstract class MainModule {
|
|||||||
fun provideFragNavController(activity: MainActivity): FragNavController {
|
fun provideFragNavController(activity: MainActivity): FragNavController {
|
||||||
return FragNavController(activity.supportFragmentManager, R.id.mainFragmentContainer)
|
return FragNavController(activity.supportFragmentManager, R.id.mainFragmentContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//In activities must be injected as Lazy
|
||||||
|
@JvmStatic
|
||||||
|
@Provides
|
||||||
|
fun provideElevationOverlayProvider(activity: MainActivity) = ElevationOverlayProvider(activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@PerFragment
|
@PerFragment
|
||||||
@ -74,7 +82,7 @@ abstract class MainModule {
|
|||||||
abstract fun bindTimetableFragment(): TimetableFragment
|
abstract fun bindTimetableFragment(): TimetableFragment
|
||||||
|
|
||||||
@PerFragment
|
@PerFragment
|
||||||
@ContributesAndroidInjector(modules = [AboutModule::class])
|
@ContributesAndroidInjector
|
||||||
abstract fun bindAboutFragment(): AboutFragment
|
abstract fun bindAboutFragment(): AboutFragment
|
||||||
|
|
||||||
@PerFragment
|
@PerFragment
|
||||||
@ -108,4 +116,8 @@ abstract class MainModule {
|
|||||||
@PerFragment
|
@PerFragment
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindMobileDeviceDialog(): MobileDeviceTokenDialog
|
abstract fun bindMobileDeviceDialog(): MobileDeviceTokenDialog
|
||||||
|
|
||||||
|
@PerFragment
|
||||||
|
@ContributesAndroidInjector(modules = [LicenseModule::class])
|
||||||
|
abstract fun bindLicenseFragment(): LicenseFragment
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
|
|||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView.Section.GRADE
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView.Section.MESSAGE
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -19,7 +21,7 @@ class MainPresenter @Inject constructor(
|
|||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<MainView>(errorHandler, studentRepository, schedulers) {
|
) : BasePresenter<MainView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
fun onAttachView(view: MainView, initMenu: MainView.MenuView?) {
|
fun onAttachView(view: MainView, initMenu: MainView.Section?) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.apply {
|
view.apply {
|
||||||
getProperViewIndexes(initMenu).let { (main, more) ->
|
getProperViewIndexes(initMenu).let { (main, more) ->
|
||||||
@ -34,8 +36,9 @@ class MainPresenter @Inject constructor(
|
|||||||
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onViewChange() {
|
fun onViewChange(section: MainView.Section?) {
|
||||||
view?.apply {
|
view?.apply {
|
||||||
|
showActionBarElevation(section != GRADE && section != MESSAGE)
|
||||||
currentViewTitle?.let { setViewTitle(it) }
|
currentViewTitle?.let { setViewTitle(it) }
|
||||||
currentStackSize?.let {
|
currentStackSize?.let {
|
||||||
if (it > 1) showHomeArrow(true)
|
if (it > 1) showHomeArrow(true)
|
||||||
@ -77,10 +80,10 @@ class MainPresenter @Inject constructor(
|
|||||||
} == true
|
} == true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getProperViewIndexes(initMenu: MainView.MenuView?): Pair<Int, Int> {
|
private fun getProperViewIndexes(initMenu: MainView.Section?): Pair<Int, Int> {
|
||||||
return when {
|
return when (initMenu?.id) {
|
||||||
initMenu?.id in 0..3 -> initMenu!!.id to -1
|
in 0..3 -> initMenu!!.id to -1
|
||||||
(initMenu?.id ?: 0) > 3 -> 4 to initMenu!!.id - 4
|
in 4..10 -> 4 to initMenu!!.id
|
||||||
else -> prefRepository.startMenuIndex to -1
|
else -> prefRepository.startMenuIndex to -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,13 @@ interface MainView : BaseView {
|
|||||||
|
|
||||||
fun showAccountPicker()
|
fun showAccountPicker()
|
||||||
|
|
||||||
|
fun showActionBarElevation(show: Boolean)
|
||||||
|
|
||||||
fun notifyMenuViewReselected()
|
fun notifyMenuViewReselected()
|
||||||
|
|
||||||
fun setViewTitle(title: String)
|
fun setViewTitle(title: String)
|
||||||
|
|
||||||
fun popView()
|
fun popView(depth: Int = 1)
|
||||||
|
|
||||||
interface MainChildView {
|
interface MainChildView {
|
||||||
|
|
||||||
@ -38,14 +40,17 @@ interface MainView : BaseView {
|
|||||||
val titleStringId: Int
|
val titleStringId: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class MenuView(val id: Int) {
|
enum class Section(val id: Int) {
|
||||||
GRADE(0),
|
GRADE(0),
|
||||||
ATTENDANCE(1),
|
ATTENDANCE(1),
|
||||||
EXAM(2),
|
EXAM(2),
|
||||||
TIMETABLE(3),
|
TIMETABLE(3),
|
||||||
MESSAGE(4),
|
MORE(4),
|
||||||
HOMEWORK(5),
|
MESSAGE(5),
|
||||||
NOTE(6),
|
HOMEWORK(6),
|
||||||
LUCKY_NUMBER(7),
|
NOTE(7),
|
||||||
|
LUCKY_NUMBER(8),
|
||||||
|
SETTINGS(9),
|
||||||
|
ABOUT(10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
|||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
||||||
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
|
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.setOnSelectPageListener
|
import io.github.wulkanowy.utils.setOnSelectPageListener
|
||||||
import kotlinx.android.synthetic.main.fragment_message.*
|
import kotlinx.android.synthetic.main.fragment_message.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -32,11 +33,9 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
|
|||||||
fun newInstance() = MessageFragment()
|
fun newInstance() = MessageFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.message_title
|
||||||
get() = R.string.message_title
|
|
||||||
|
|
||||||
override val currentPageIndex: Int
|
override val currentPageIndex get() = messageViewPager.currentItem
|
||||||
get() = messageViewPager.currentItem
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_message, container, false)
|
return inflater.inflate(R.layout.fragment_message, container, false)
|
||||||
@ -48,7 +47,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
pagerAdapter.apply {
|
with(pagerAdapter) {
|
||||||
containerId = messageViewPager.id
|
containerId = messageViewPager.id
|
||||||
addFragmentsWithTitle(mapOf(
|
addFragmentsWithTitle(mapOf(
|
||||||
MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox),
|
MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox),
|
||||||
@ -57,12 +56,16 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
messageViewPager.run {
|
with(messageViewPager) {
|
||||||
adapter = pagerAdapter
|
adapter = pagerAdapter
|
||||||
offscreenPageLimit = 2
|
offscreenPageLimit = 2
|
||||||
setOnSelectPageListener { presenter.onPageSelected(it) }
|
setOnSelectPageListener(presenter::onPageSelected)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(messageTabLayout) {
|
||||||
|
setupWithViewPager(messageViewPager)
|
||||||
|
setElevationCompat(context.dpToPx(4f))
|
||||||
}
|
}
|
||||||
messageTabLayout.setupWithViewPager(messageViewPager)
|
|
||||||
|
|
||||||
openSendMessageButton.setOnClickListener { presenter.onSendMessageButtonClicked() }
|
openSendMessageButton.setOnClickListener { presenter.onSendMessageButtonClicked() }
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import io.github.wulkanowy.di.scopes.PerFragment
|
|||||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||||
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
|
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
@Module
|
@Module
|
||||||
abstract class MessageModule {
|
abstract class MessageModule {
|
||||||
|
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.modules.message.send
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.net.Uri
|
|
||||||
import com.pchmn.materialchips.model.ChipInterface
|
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
|
||||||
|
|
||||||
class RecipientChip(var recipient: Recipient) : ChipInterface {
|
|
||||||
|
|
||||||
override fun getAvatarDrawable(): Drawable? = null
|
|
||||||
|
|
||||||
override fun getAvatarUri(): Uri? = null
|
|
||||||
|
|
||||||
override fun getId(): Any = recipient.id
|
|
||||||
|
|
||||||
override fun getLabel(): String = recipient.name
|
|
||||||
|
|
||||||
override fun getInfo(): String {
|
|
||||||
return recipient.realName.run {
|
|
||||||
substringBeforeLast("-").let { sub ->
|
|
||||||
when {
|
|
||||||
(sub == this) -> this
|
|
||||||
(sub.indexOf('(') != -1) -> indexOf("(").let { substring(if (it != -1) it else 0) }
|
|
||||||
(sub.indexOf('[') != -1) -> indexOf("[").let { substring(if (it != -1) it else 0) }
|
|
||||||
else -> substringAfter('-')
|
|
||||||
}
|
|
||||||
}.trim()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,14 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.message.send
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Recipient
|
||||||
|
import io.github.wulkanowy.materialchipsinput.ChipItem
|
||||||
|
|
||||||
|
data class RecipientChipItem(
|
||||||
|
|
||||||
|
override val title: String,
|
||||||
|
|
||||||
|
override val summary: String,
|
||||||
|
|
||||||
|
val recipient: Recipient
|
||||||
|
|
||||||
|
) : ChipItem
|
@ -2,18 +2,20 @@ package io.github.wulkanowy.ui.modules.message.send
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.graphics.Rect
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.view.TouchDelegate
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.widget.Toast.LENGTH_LONG
|
import android.widget.Toast.LENGTH_LONG
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
|
||||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.hideSoftInput
|
import io.github.wulkanowy.utils.hideSoftInput
|
||||||
import io.github.wulkanowy.utils.showSoftInput
|
import io.github.wulkanowy.utils.showSoftInput
|
||||||
import kotlinx.android.synthetic.main.activity_send_message.*
|
import kotlinx.android.synthetic.main.activity_send_message.*
|
||||||
@ -38,14 +40,18 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val formRecipientsData: List<Recipient>
|
override val isDropdownListVisible: Boolean
|
||||||
get() = (sendMessageRecipientsInput.selectedChipList).map { (it as RecipientChip).recipient }
|
get() = sendMessageTo.isDropdownListVisible
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override val formRecipientsData: List<RecipientChipItem>
|
||||||
|
get() = sendMessageTo.addedChipItems as List<RecipientChipItem>
|
||||||
|
|
||||||
override val formSubjectValue: String
|
override val formSubjectValue: String
|
||||||
get() = sendMessageSubjectInput.text.toString()
|
get() = sendMessageSubject.text.toString()
|
||||||
|
|
||||||
override val formContentValue: String
|
override val formContentValue: String
|
||||||
get() = sendMessageContentInput.text.toString()
|
get() = sendMessageMessageContent.text.toString()
|
||||||
|
|
||||||
override val messageRequiredRecipients: String
|
override val messageRequiredRecipients: String
|
||||||
get() = getString(R.string.message_required_recipients)
|
get() = getString(R.string.message_required_recipients)
|
||||||
@ -66,6 +72,12 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
|
|||||||
presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as? Boolean)
|
presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as? Boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
setUpExtendedHitArea()
|
||||||
|
sendMessageScroll.setOnTouchListener { _, _ -> presenter.onTouchScroll() }
|
||||||
|
sendMessageTo.onTextChangeListener = presenter::onRecipientsTextChange
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
menuInflater.inflate(R.menu.action_menu_send_message, menu)
|
menuInflater.inflate(R.menu.action_menu_send_message, menu)
|
||||||
return true
|
return true
|
||||||
@ -81,15 +93,15 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setReportingUnit(unit: ReportingUnit) {
|
override fun setReportingUnit(unit: ReportingUnit) {
|
||||||
sendMessageFromTextView.setText(unit.senderName)
|
sendMessageFrom.text = unit.senderName
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setRecipients(recipients: List<Recipient>) {
|
override fun setRecipients(recipients: List<RecipientChipItem>) {
|
||||||
sendMessageRecipientsInput.filterableList = recipients.map { RecipientChip(it) }
|
sendMessageTo.filterableChipItems = recipients
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setSelectedRecipients(recipients: List<Recipient>) {
|
override fun setSelectedRecipients(recipients: List<RecipientChipItem>) {
|
||||||
recipients.map { sendMessageRecipientsInput.addChip(RecipientChip(it)) }
|
sendMessageTo.addChips(recipients)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showProgress(show: Boolean) {
|
override fun showProgress(show: Boolean) {
|
||||||
@ -109,11 +121,11 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setSubject(subject: String) {
|
override fun setSubject(subject: String) {
|
||||||
sendMessageSubjectInput.setText(subject)
|
sendMessageSubject.setText(subject)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setContent(content: String) {
|
override fun setContent(content: String) {
|
||||||
sendMessageContentInput.setText(content)
|
sendMessageMessageContent.setText(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showMessage(text: String) {
|
override fun showMessage(text: String) {
|
||||||
@ -124,7 +136,41 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
|
|||||||
if (show) showSoftInput() else hideSoftInput()
|
if (show) showSoftInput() else hideSoftInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun hideDropdownList() {
|
||||||
|
sendMessageTo.hideDropdownList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun scrollToRecipients() {
|
||||||
|
sendMessageScroll.post {
|
||||||
|
sendMessageScroll.scrollTo(0, sendMessageTo.bottom - dpToPx(53f).toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun popView() {
|
override fun popView() {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setUpExtendedHitArea() {
|
||||||
|
fun extendHitArea() {
|
||||||
|
val containerHitRect = Rect().apply {
|
||||||
|
sendMessageContent.getHitRect(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
val contentHitRect = Rect().apply {
|
||||||
|
sendMessageMessageContent.getHitRect(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentHitRect.top = contentHitRect.bottom
|
||||||
|
contentHitRect.bottom = containerHitRect.bottom
|
||||||
|
|
||||||
|
sendMessageContent.touchDelegate = TouchDelegate(contentHitRect, sendMessageMessageContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessageMessageContent.post {
|
||||||
|
sendMessageMessageContent.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
|
||||||
|
extendHitArea()
|
||||||
|
}
|
||||||
|
extendHitArea()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ class SendMessagePresenter @Inject constructor(
|
|||||||
|
|
||||||
fun onAttachView(view: SendMessageView, message: Message?, reply: Boolean?) {
|
fun onAttachView(view: SendMessageView, message: Message?, reply: Boolean?) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
view.initView()
|
||||||
Timber.i("Send message view was initialized")
|
Timber.i("Send message view was initialized")
|
||||||
loadData(message, reply)
|
loadData(message, reply)
|
||||||
view.apply {
|
view.apply {
|
||||||
@ -54,15 +55,47 @@ class SendMessagePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onTouchScroll(): Boolean {
|
||||||
|
return view?.run {
|
||||||
|
if (isDropdownListVisible) {
|
||||||
|
hideDropdownList()
|
||||||
|
true
|
||||||
|
} else false
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onRecipientsTextChange(text: String) {
|
||||||
|
if (text.isBlank()) return
|
||||||
|
view?.scrollToRecipients()
|
||||||
|
}
|
||||||
|
|
||||||
fun onUpNavigate(): Boolean {
|
fun onUpNavigate(): Boolean {
|
||||||
view?.popView()
|
view?.popView()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onSend(): Boolean {
|
||||||
|
view?.run {
|
||||||
|
when {
|
||||||
|
formRecipientsData.isEmpty() -> showMessage(messageRequiredRecipients)
|
||||||
|
formContentValue.length < 3 -> showMessage(messageContentMinLength)
|
||||||
|
else -> {
|
||||||
|
sendMessage(
|
||||||
|
subject = formSubjectValue,
|
||||||
|
content = formContentValue,
|
||||||
|
recipients = formRecipientsData.map { it.recipient }
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadData(message: Message?, reply: Boolean?) {
|
private fun loadData(message: Message?, reply: Boolean?) {
|
||||||
var reportingUnit: ReportingUnit? = null
|
var reportingUnit: ReportingUnit? = null
|
||||||
var recipients: List<Recipient> = emptyList()
|
var recipientChips: List<RecipientChipItem> = emptyList()
|
||||||
var selectedRecipient: List<Recipient> = emptyList()
|
var selectedRecipientChips: List<RecipientChipItem> = emptyList()
|
||||||
|
|
||||||
Timber.i("Loading recipients started")
|
Timber.i("Loading recipients started")
|
||||||
disposable.add(studentRepository.getCurrentStudent()
|
disposable.add(studentRepository.getCurrentStudent()
|
||||||
@ -73,14 +106,14 @@ class SendMessagePresenter @Inject constructor(
|
|||||||
.flatMap { recipientRepository.getRecipients(student, 2, it).toMaybe() }
|
.flatMap { recipientRepository.getRecipients(student, 2, it).toMaybe() }
|
||||||
.doOnSuccess {
|
.doOnSuccess {
|
||||||
Timber.i("Loading recipients result: Success, fetched %d recipients", it.size)
|
Timber.i("Loading recipients result: Success, fetched %d recipients", it.size)
|
||||||
recipients = it
|
recipientChips = createChips(it)
|
||||||
}
|
}
|
||||||
.flatMapCompletable {
|
.flatMapCompletable {
|
||||||
if (message == null || reply != true) Completable.complete()
|
if (message == null || reply != true) Completable.complete()
|
||||||
else recipientRepository.getMessageRecipients(student, message)
|
else recipientRepository.getMessageRecipients(student, message)
|
||||||
.doOnSuccess {
|
.doOnSuccess {
|
||||||
Timber.i("Loaded message recipients to reply result: Success, fetched %d recipients", it.size)
|
Timber.i("Loaded message recipients to reply result: Success, fetched %d recipients", it.size)
|
||||||
selectedRecipient = it
|
selectedRecipientChips = createChips(it)
|
||||||
}
|
}
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
@ -95,11 +128,11 @@ class SendMessagePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
.doFinally { view?.run { showProgress(false) } }
|
.doFinally { view?.run { showProgress(false) } }
|
||||||
.subscribe({
|
.subscribe({
|
||||||
view?.apply {
|
view?.run {
|
||||||
if (reportingUnit !== null) {
|
if (reportingUnit !== null) {
|
||||||
reportingUnit?.let { setReportingUnit(it) }
|
reportingUnit?.let { setReportingUnit(it) }
|
||||||
setRecipients(recipients)
|
setRecipients(recipientChips)
|
||||||
if (selectedRecipient.isNotEmpty()) setSelectedRecipients(selectedRecipient)
|
if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(selectedRecipientChips)
|
||||||
showContent(true)
|
showContent(true)
|
||||||
} else {
|
} else {
|
||||||
Timber.e("Loading recipients result: Can't find the reporting unit")
|
Timber.e("Loading recipients result: Can't find the reporting unit")
|
||||||
@ -145,21 +178,29 @@ class SendMessagePresenter @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSend(): Boolean {
|
private fun createChips(recipients: List<Recipient>): List<RecipientChipItem> {
|
||||||
view?.run {
|
fun generateCorrectSummary(recipientRealName: String): String {
|
||||||
when {
|
val substring = recipientRealName.substringBeforeLast("-")
|
||||||
formRecipientsData.isEmpty() -> showMessage(messageRequiredRecipients)
|
return when {
|
||||||
formContentValue.length < 3 -> showMessage(messageContentMinLength)
|
substring == recipientRealName -> recipientRealName
|
||||||
else -> {
|
substring.indexOf("(") != -1 -> {
|
||||||
sendMessage(
|
recipientRealName.indexOf("(")
|
||||||
subject = formSubjectValue,
|
.let { recipientRealName.substring(if (it != -1) it else 0) }
|
||||||
content = formContentValue,
|
|
||||||
recipients = formRecipientsData
|
|
||||||
)
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
substring.indexOf("[") != -1 -> {
|
||||||
|
recipientRealName.indexOf("[")
|
||||||
|
.let { recipientRealName.substring(if (it != -1) it else 0) }
|
||||||
|
}
|
||||||
|
else -> recipientRealName.substringAfter("-")
|
||||||
|
}.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipients.map {
|
||||||
|
RecipientChipItem(
|
||||||
|
title = it.name,
|
||||||
|
summary = generateCorrectSummary(it.realName),
|
||||||
|
recipient = it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.message.send
|
package io.github.wulkanowy.ui.modules.message.send
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
|
||||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface SendMessageView : BaseView {
|
interface SendMessageView : BaseView {
|
||||||
|
|
||||||
val formRecipientsData: List<Recipient>
|
val isDropdownListVisible: Boolean
|
||||||
|
|
||||||
|
val formRecipientsData: List<RecipientChipItem>
|
||||||
|
|
||||||
val formSubjectValue: String
|
val formSubjectValue: String
|
||||||
|
|
||||||
@ -18,11 +19,13 @@ interface SendMessageView : BaseView {
|
|||||||
|
|
||||||
val messageSuccess: String
|
val messageSuccess: String
|
||||||
|
|
||||||
|
fun initView()
|
||||||
|
|
||||||
fun setReportingUnit(unit: ReportingUnit)
|
fun setReportingUnit(unit: ReportingUnit)
|
||||||
|
|
||||||
fun setRecipients(recipients: List<Recipient>)
|
fun setRecipients(recipients: List<RecipientChipItem>)
|
||||||
|
|
||||||
fun setSelectedRecipients(recipients: List<Recipient>)
|
fun setSelectedRecipients(recipients: List<RecipientChipItem>)
|
||||||
|
|
||||||
fun showProgress(show: Boolean)
|
fun showProgress(show: Boolean)
|
||||||
|
|
||||||
@ -38,5 +41,9 @@ interface SendMessageView : BaseView {
|
|||||||
|
|
||||||
fun showSoftInput(show: Boolean)
|
fun showSoftInput(show: Boolean)
|
||||||
|
|
||||||
|
fun hideDropdownList()
|
||||||
|
|
||||||
|
fun scrollToRecipients()
|
||||||
|
|
||||||
fun popView()
|
fun popView()
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -20,6 +19,7 @@ import io.github.wulkanowy.ui.modules.message.MessageFragment
|
|||||||
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
|
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
|
||||||
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
||||||
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
||||||
|
import io.github.wulkanowy.utils.getCompatDrawable
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_more.*
|
import kotlinx.android.synthetic.main.fragment_more.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -39,60 +39,26 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai
|
|||||||
override val titleStringId: Int
|
override val titleStringId: Int
|
||||||
get() = R.string.more_title
|
get() = R.string.more_title
|
||||||
|
|
||||||
|
|
||||||
override val messagesRes: Pair<String, Drawable?>?
|
override val messagesRes: Pair<String, Drawable?>?
|
||||||
get() {
|
get() = context?.run { getString(R.string.message_title) to getCompatDrawable(R.drawable.ic_more_messages) }
|
||||||
return context?.run {
|
|
||||||
getString(R.string.message_title) to
|
|
||||||
ContextCompat.getDrawable(this, R.drawable.ic_more_messages_24dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val homeworkRes: Pair<String, Drawable?>?
|
override val homeworkRes: Pair<String, Drawable?>?
|
||||||
get() {
|
get() = context?.run { getString(R.string.homework_title) to getCompatDrawable(R.drawable.ic_more_homework) }
|
||||||
return context?.run {
|
|
||||||
getString(R.string.homework_title) to ContextCompat.getDrawable(this, R.drawable.ic_menu_main_homework_24dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val noteRes: Pair<String, Drawable?>?
|
override val noteRes: Pair<String, Drawable?>?
|
||||||
get() {
|
get() = context?.run { getString(R.string.note_title) to getCompatDrawable(R.drawable.ic_more_note) }
|
||||||
return context?.run {
|
|
||||||
getString(R.string.note_title) to ContextCompat.getDrawable(this, R.drawable.ic_menu_main_note_24dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val luckyNumberRes: Pair<String, Drawable?>?
|
override val luckyNumberRes: Pair<String, Drawable?>?
|
||||||
get() {
|
get() = context?.run { getString(R.string.lucky_number_title) to getCompatDrawable(R.drawable.ic_more_lucky_number) }
|
||||||
return context?.run {
|
|
||||||
getString(R.string.lucky_number_title) to
|
|
||||||
ContextCompat.getDrawable(this, R.drawable.ic_more_lucky_number_24dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val mobileDevicesRes: Pair<String, Drawable?>?
|
override val mobileDevicesRes: Pair<String, Drawable?>?
|
||||||
get() {
|
get() = context?.run { getString(R.string.mobile_devices_title) to getCompatDrawable(R.drawable.ic_more_mobile_devices) }
|
||||||
return context?.run {
|
|
||||||
getString(R.string.mobile_devices_title) to
|
|
||||||
ContextCompat.getDrawable(this, R.drawable.ic_menu_main_mobile_devices_24dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val settingsRes: Pair<String, Drawable?>?
|
override val settingsRes: Pair<String, Drawable?>?
|
||||||
get() {
|
get() = context?.run { getString(R.string.settings_title) to getCompatDrawable(R.drawable.ic_more_settings) }
|
||||||
return context?.run {
|
|
||||||
getString(R.string.settings_title) to
|
|
||||||
ContextCompat.getDrawable(this, R.drawable.ic_more_settings_24dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val aboutRes: Pair<String, Drawable?>?
|
override val aboutRes: Pair<String, Drawable?>?
|
||||||
get() {
|
get() = context?.run { getString(R.string.about_title) to getCompatDrawable(R.drawable.ic_all_about) }
|
||||||
return context?.run {
|
|
||||||
getString(R.string.about_title) to
|
|
||||||
ContextCompat.getDrawable(this, R.drawable.ic_all_about_24dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_more, container, false)
|
return inflater.inflate(R.layout.fragment_more, container, false)
|
||||||
@ -104,7 +70,7 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
moreAdapter.run { setOnItemClickListener { presenter.onItemSelected(it) } }
|
moreAdapter.setOnItemClickListener { presenter.onItemSelected(it) }
|
||||||
|
|
||||||
moreRecycler.apply {
|
moreRecycler.apply {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
@ -148,8 +114,8 @@ class MoreFragment : BaseFragment(), MoreView, MainView.TitledView, MainView.Mai
|
|||||||
(activity as? MainActivity)?.pushView(AboutFragment.newInstance())
|
(activity as? MainActivity)?.pushView(AboutFragment.newInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popView() {
|
override fun popView(depth: Int) {
|
||||||
(activity as? MainActivity)?.popView()
|
(activity as? MainActivity)?.popView(depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -22,25 +22,24 @@ class MorePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onItemSelected(item: AbstractFlexibleItem<*>?) {
|
fun onItemSelected(item: AbstractFlexibleItem<*>?) {
|
||||||
if (item is MoreItem) {
|
if (item !is MoreItem) return
|
||||||
Timber.i("Select more item \"${item.title}\"")
|
Timber.i("Select more item \"${item.title}\"")
|
||||||
view?.run {
|
view?.run {
|
||||||
when (item.title) {
|
when (item.title) {
|
||||||
messagesRes?.first -> openMessagesView()
|
messagesRes?.first -> openMessagesView()
|
||||||
homeworkRes?.first -> openHomeworkView()
|
homeworkRes?.first -> openHomeworkView()
|
||||||
noteRes?.first -> openNoteView()
|
noteRes?.first -> openNoteView()
|
||||||
luckyNumberRes?.first -> openLuckyNumberView()
|
luckyNumberRes?.first -> openLuckyNumberView()
|
||||||
mobileDevicesRes?.first -> openMobileDevicesView()
|
mobileDevicesRes?.first -> openMobileDevicesView()
|
||||||
settingsRes?.first -> openSettingsView()
|
settingsRes?.first -> openSettingsView()
|
||||||
aboutRes?.first -> openAboutView()
|
aboutRes?.first -> openAboutView()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onViewReselected() {
|
fun onViewReselected() {
|
||||||
Timber.i("More view is reselected")
|
Timber.i("More view is reselected")
|
||||||
view?.popView()
|
view?.popView(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
|
@ -27,7 +27,7 @@ interface MoreView : BaseView {
|
|||||||
|
|
||||||
fun openAboutView()
|
fun openAboutView()
|
||||||
|
|
||||||
fun popView()
|
fun popView(depth: Int)
|
||||||
|
|
||||||
fun openMessagesView()
|
fun openMessagesView()
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ package io.github.wulkanowy.ui.modules.settings
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.takisoft.preferencex.PreferenceFragmentCompat
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import dagger.android.support.AndroidSupportInjection
|
import dagger.android.support.AndroidSupportInjection
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
@ -24,8 +25,7 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
|
|||||||
fun newInstance() = SettingsFragment()
|
fun newInstance() = SettingsFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.settings_title
|
||||||
get() = R.string.settings_title
|
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
AndroidSupportInjection.inject(this)
|
AndroidSupportInjection.inject(this)
|
||||||
@ -37,9 +37,9 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
|
|||||||
presenter.onAttachView(this)
|
presenter.onAttachView(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
addPreferencesFromResource(R.xml.scheme_preferences)
|
setPreferencesFromResource(R.xml.scheme_preferences, rootKey)
|
||||||
findPreference(getString(R.string.pref_key_notification_debug)).isVisible = appInfo.isDebug
|
findPreference<Preference>(getString(R.string.pref_key_notification_debug))?.isVisible = appInfo.isDebug
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||||
@ -51,7 +51,7 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) {
|
override fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) {
|
||||||
findPreference(serviceEnablesKey).run {
|
findPreference<Preference>(serviceEnablesKey)?.apply {
|
||||||
summary = if (isHolidays) getString(R.string.pref_services_suspended) else ""
|
summary = if (isHolidays) getString(R.string.pref_services_suspended) else ""
|
||||||
isEnabled = !isHolidays
|
isEnabled = !isHolidays
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,14 @@ class SettingsPresenter @Inject constructor(
|
|||||||
|
|
||||||
fun onSharedPreferenceChanged(key: String) {
|
fun onSharedPreferenceChanged(key: String) {
|
||||||
Timber.i("Change settings $key")
|
Timber.i("Change settings $key")
|
||||||
preferencesRepository.apply {
|
|
||||||
|
with(preferencesRepository) {
|
||||||
when (key) {
|
when (key) {
|
||||||
serviceEnableKey -> with(syncManager) { if (isServiceEnabled) startSyncWorker() else stopSyncWorker() }
|
serviceEnableKey -> with(syncManager) { if (isServiceEnabled) startSyncWorker() else stopSyncWorker() }
|
||||||
servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true)
|
servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true)
|
||||||
isDebugNotificationEnableKey -> chuckCollector.showNotification(isDebugNotificationEnable)
|
isDebugNotificationEnableKey -> chuckCollector.showNotification(isDebugNotificationEnable)
|
||||||
appThemeKey -> view?.recreateView()
|
appThemeKey -> view?.recreateView()
|
||||||
|
else -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
analytics.logEvent("setting_changed", "name" to key)
|
analytics.logEvent("setting_changed", "name" to key)
|
||||||
|
@ -17,11 +17,13 @@ import io.github.wulkanowy.ui.base.BaseFragment
|
|||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
|
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_timetable.*
|
import kotlinx.android.synthetic.main.fragment_timetable.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, MainView.TitledView {
|
class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
|
||||||
|
MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: TimetablePresenter
|
lateinit var presenter: TimetablePresenter
|
||||||
@ -35,17 +37,13 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
|
|||||||
fun newInstance() = TimetableFragment()
|
fun newInstance() = TimetableFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.timetable_title
|
||||||
get() = R.string.timetable_title
|
|
||||||
|
|
||||||
override val roomString: String
|
override val roomString get() = getString(R.string.timetable_room)
|
||||||
get() = getString(R.string.timetable_room)
|
|
||||||
|
|
||||||
override val isViewEmpty: Boolean
|
override val isViewEmpty get() = timetableAdapter.isEmpty
|
||||||
get() = timetableAdapter.isEmpty
|
|
||||||
|
|
||||||
override val currentStackSize: Int?
|
override val currentStackSize get() = (activity as? MainActivity)?.currentStackSize
|
||||||
get() = (activity as? MainActivity)?.currentStackSize
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -63,11 +61,9 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
timetableAdapter.run {
|
timetableAdapter.setOnItemClickListener(presenter::onTimetableItemSelected)
|
||||||
setOnItemClickListener { presenter.onTimetableItemSelected(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
timetableRecycler.run {
|
with(timetableRecycler) {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
adapter = timetableAdapter
|
adapter = timetableAdapter
|
||||||
addItemDecoration(FlexibleItemDecoration(context)
|
addItemDecoration(FlexibleItemDecoration(context)
|
||||||
@ -75,9 +71,12 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView,
|
|||||||
.withDrawDividerOnLastItem(false)
|
.withDrawDividerOnLastItem(false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
timetableSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
|
||||||
|
timetableSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
timetablePreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
timetablePreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
||||||
timetableNextButton.setOnClickListener { presenter.onNextDay() }
|
timetableNextButton.setOnClickListener { presenter.onNextDay() }
|
||||||
|
|
||||||
|
timetableNavContainer.setElevationCompat(requireContext().dpToPx(8f))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
@ -75,7 +75,7 @@ class TimetablePresenter @Inject constructor(
|
|||||||
|
|
||||||
fun onTimetableItemSelected(item: AbstractFlexibleItem<*>?) {
|
fun onTimetableItemSelected(item: AbstractFlexibleItem<*>?) {
|
||||||
if (item is TimetableItem) {
|
if (item is TimetableItem) {
|
||||||
Timber.i("Select exam item ${item.lesson.id}")
|
Timber.i("Select timetable item ${item.lesson.id}")
|
||||||
view?.showTimetableDialog(item.lesson)
|
view?.showTimetableDialog(item.lesson)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -13,6 +12,8 @@ import io.github.wulkanowy.data.db.entities.CompletedLesson
|
|||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
|
import io.github.wulkanowy.utils.getCompatDrawable
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_timetable_completed.*
|
import kotlinx.android.synthetic.main.fragment_timetable_completed.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -31,11 +32,9 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.
|
|||||||
fun newInstance() = CompletedLessonsFragment()
|
fun newInstance() = CompletedLessonsFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val titleStringId: Int
|
override val titleStringId get() = R.string.completed_lessons_title
|
||||||
get() = R.string.completed_lessons_title
|
|
||||||
|
|
||||||
override val isViewEmpty
|
override val isViewEmpty get() = completedLessonsAdapter.isEmpty
|
||||||
get() = completedLessonsAdapter.isEmpty
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_timetable_completed, container, false)
|
return inflater.inflate(R.layout.fragment_timetable_completed, container, false)
|
||||||
@ -48,17 +47,18 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
completedLessonsAdapter.run {
|
completedLessonsAdapter.setOnItemClickListener(presenter::onCompletedLessonsItemSelected)
|
||||||
setOnItemClickListener { presenter.onCompletedLessonsItemSelected(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
completedLessonsRecycler.run {
|
with(completedLessonsRecycler) {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = SmoothScrollLinearLayoutManager(context)
|
||||||
adapter = completedLessonsAdapter
|
adapter = completedLessonsAdapter
|
||||||
}
|
}
|
||||||
completedLessonsSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
|
||||||
|
completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||||
completedLessonsPreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
completedLessonsPreviousButton.setOnClickListener { presenter.onPreviousDay() }
|
||||||
completedLessonsNextButton.setOnClickListener { presenter.onNextDay() }
|
completedLessonsNextButton.setOnClickListener { presenter.onNextDay() }
|
||||||
|
|
||||||
|
completedLessonsNavContainer.setElevationCompat(requireContext().dpToPx(8f))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateData(data: List<CompletedLessonItem>) {
|
override fun updateData(data: List<CompletedLessonItem>) {
|
||||||
@ -82,10 +82,8 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showFeatureDisabled() {
|
override fun showFeatureDisabled() {
|
||||||
context?.let {
|
completedLessonsInfo.text = getString(R.string.error_feature_disabled)
|
||||||
completedLessonsInfo.text = getString(R.string.error_feature_disabled)
|
completedLessonsInfoImage.setImageDrawable(requireContext().getCompatDrawable(R.drawable.ic_all_close_circle))
|
||||||
completedLessonsInfoImage.setImageDrawable(ContextCompat.getDrawable(it, R.drawable.ic_all_close_circle_24dp))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showProgress(show: Boolean) {
|
override fun showProgress(show: Boolean) {
|
||||||
@ -114,7 +112,7 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.
|
|||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putLong(CompletedLessonsFragment.SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.modules.timetablewidget
|
package io.github.wulkanowy.ui.modules.timetablewidget
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
@ -14,7 +14,7 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
|
|||||||
schedulers: SchedulersProvider,
|
schedulers: SchedulersProvider,
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
private val sharedPref: SharedPrefHelper
|
private val sharedPref: SharedPrefProvider
|
||||||
) : BasePresenter<TimetableWidgetConfigureView>(errorHandler, studentRepository, schedulers) {
|
) : BasePresenter<TimetableWidgetConfigureView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
private var appWidgetId: Int? = null
|
private var appWidgetId: Int? = null
|
||||||
|
@ -11,7 +11,7 @@ import android.widget.AdapterView.INVALID_POSITION
|
|||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import android.widget.RemoteViewsService
|
import android.widget.RemoteViewsService
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.entities.Timetable
|
import io.github.wulkanowy.data.db.entities.Timetable
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
@ -28,7 +28,7 @@ class TimetableWidgetFactory(
|
|||||||
private val timetableRepository: TimetableRepository,
|
private val timetableRepository: TimetableRepository,
|
||||||
private val studentRepository: StudentRepository,
|
private val studentRepository: StudentRepository,
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val sharedPref: SharedPrefHelper,
|
private val sharedPref: SharedPrefProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
private val schedulers: SchedulersProvider,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val intent: Intent?
|
private val intent: Intent?
|
||||||
@ -60,8 +60,6 @@ class TimetableWidgetFactory(
|
|||||||
.filter { true }
|
.filter { true }
|
||||||
.flatMap { studentRepository.getSavedStudents().toMaybe() }
|
.flatMap { studentRepository.getSavedStudents().toMaybe() }
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (studentId == 0L) throw IllegalArgumentException("Student id is 0")
|
|
||||||
|
|
||||||
it.singleOrNull { student -> student.id == studentId }
|
it.singleOrNull { student -> student.id == studentId }
|
||||||
.let { student ->
|
.let { student ->
|
||||||
if (student != null) Maybe.just(student)
|
if (student != null) Maybe.just(student)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.timetablewidget
|
package io.github.wulkanowy.ui.modules.timetablewidget
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
@ -15,12 +16,13 @@ import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
|||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import dagger.android.AndroidInjection
|
import dagger.android.AndroidInjection
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView.MenuView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
@ -43,7 +45,7 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
lateinit var studentRepository: StudentRepository
|
lateinit var studentRepository: StudentRepository
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var sharedPref: SharedPrefHelper
|
lateinit var sharedPref: SharedPrefProvider
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var schedulers: SchedulersProvider
|
lateinit var schedulers: SchedulersProvider
|
||||||
@ -110,6 +112,7 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("DefaultLocale")
|
||||||
private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate, student: Student?) {
|
private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate, student: Student?) {
|
||||||
RemoteViews(context.packageName, R.layout.widget_timetable).apply {
|
RemoteViews(context.packageName, R.layout.widget_timetable).apply {
|
||||||
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
||||||
@ -130,8 +133,8 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
putExtra(EXTRA_FROM_PROVIDER, true)
|
putExtra(EXTRA_FROM_PROVIDER, true)
|
||||||
}, FLAG_UPDATE_CURRENT))
|
}, FLAG_UPDATE_CURRENT))
|
||||||
setPendingIntentTemplate(R.id.timetableWidgetList,
|
setPendingIntentTemplate(R.id.timetableWidgetList,
|
||||||
PendingIntent.getActivity(context, MenuView.TIMETABLE.id,
|
PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id,
|
||||||
MainActivity.getStartIntent(context, MenuView.TIMETABLE, true), FLAG_UPDATE_CURRENT))
|
MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT))
|
||||||
}.also {
|
}.also {
|
||||||
sharedPref.putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true)
|
sharedPref.putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true)
|
||||||
appWidgetManager.apply {
|
appWidgetManager.apply {
|
||||||
@ -173,7 +176,9 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "An error has occurred in timetable widget provider")
|
if (e.cause !is NoCurrentStudentException) {
|
||||||
|
Timber.e(e, "An error has occurred in timetable widget provider")
|
||||||
|
}
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade
|
package io.github.wulkanowy.ui.widgets
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.google.android.material.tabs.TabLayout
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see <a href="https://stackoverflow.com/a/50382854">Tabs don't fit to screen with tabmode=scrollable, Even with a Custom Tab Layout</a>
|
* @see <a href="https://stackoverflow.com/a/50382854">Tabs don't fit to screen with tabmode=scrollable, Even with a Custom Tab Layout</a>
|
||||||
*/
|
*/
|
||||||
class CustomTabLayout : TabLayout {
|
class FittedScrollableTabLayout : MaterialTabLayout {
|
||||||
|
|
||||||
constructor(context: Context) : super(context)
|
constructor(context: Context) : super(context)
|
||||||
|
|
@ -0,0 +1,39 @@
|
|||||||
|
package io.github.wulkanowy.ui.widgets
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build.VERSION.SDK_INT
|
||||||
|
import android.os.Build.VERSION_CODES.LOLLIPOP
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||||
|
import com.google.android.material.shape.MaterialShapeDrawable
|
||||||
|
|
||||||
|
class MaterialLinearLayout : LinearLayout {
|
||||||
|
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
|
||||||
|
constructor(context: Context, attr: AttributeSet) : super(context, attr)
|
||||||
|
|
||||||
|
constructor(context: Context, attr: AttributeSet, defStyleAttr: Int) : super(context, attr, defStyleAttr)
|
||||||
|
|
||||||
|
init {
|
||||||
|
val drawable = MaterialShapeDrawable.createWithElevationOverlay(context, ViewCompat.getElevation(this))
|
||||||
|
ViewCompat.setBackground(this, drawable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setElevation(elevation: Float) {
|
||||||
|
super.setElevation(elevation)
|
||||||
|
if (background is MaterialShapeDrawable) {
|
||||||
|
(background as MaterialShapeDrawable).elevation = elevation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setElevationCompat(elevation: Float) {
|
||||||
|
if (SDK_INT >= LOLLIPOP) {
|
||||||
|
setElevation(elevation)
|
||||||
|
} else {
|
||||||
|
setBackgroundColor(ElevationOverlayProvider(context).getSurfaceColorWithOverlayIfNeeded(elevation))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package io.github.wulkanowy.ui.widgets
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build.VERSION.SDK_INT
|
||||||
|
import android.os.Build.VERSION_CODES.LOLLIPOP
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
|
||||||
|
open class MaterialTabLayout : TabLayout {
|
||||||
|
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
|
||||||
|
constructor(context: Context, attr: AttributeSet) : super(context, attr)
|
||||||
|
|
||||||
|
constructor(context: Context, attr: AttributeSet, defStyleAttr: Int) : super(context, attr, defStyleAttr)
|
||||||
|
|
||||||
|
fun setElevationCompat(elevation: Float) {
|
||||||
|
if (SDK_INT >= LOLLIPOP) {
|
||||||
|
setElevation(elevation)
|
||||||
|
} else {
|
||||||
|
setBackgroundColor(ElevationOverlayProvider(context).getSurfaceColorWithOverlayIfNeeded(elevation))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,15 @@
|
|||||||
package io.github.wulkanowy.utils
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context.INPUT_METHOD_SERVICE
|
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
|
|
||||||
fun Activity.showSoftInput() {
|
fun Activity.showSoftInput() {
|
||||||
(getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?)?.run {
|
getSystemService<InputMethodManager>()?.let { manager ->
|
||||||
if (currentFocus != null) showSoftInput(currentFocus, 0)
|
currentFocus?.let { manager.showSoftInput(it, 0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Activity.hideSoftInput() {
|
fun Activity.hideSoftInput() {
|
||||||
(getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?)?.run {
|
getSystemService<InputMethodManager>()?.hideSoftInputFromWindow(window.decorView.applicationWindowToken, 0)
|
||||||
hideSoftInputFromWindow(window.decorView.applicationWindowToken, 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ package io.github.wulkanowy.utils
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.util.DisplayMetrics.DENSITY_DEFAULT
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.ColorRes
|
import androidx.annotation.ColorRes
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
@ColorInt
|
@ColorInt
|
||||||
@ -20,9 +22,13 @@ fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int {
|
|||||||
@ColorInt
|
@ColorInt
|
||||||
fun Context.getCompatColor(@ColorRes colorRes: Int) = ContextCompat.getColor(this, colorRes)
|
fun Context.getCompatColor(@ColorRes colorRes: Int) = ContextCompat.getColor(this, colorRes)
|
||||||
|
|
||||||
|
fun Context.getCompatDrawable(@DrawableRes drawableRes: Int) = ContextCompat.getDrawable(this, drawableRes)
|
||||||
|
|
||||||
fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) -> Unit) {
|
fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) -> Unit) {
|
||||||
Intent.parseUri(uri, 0).let {
|
Intent.parseUri(uri, 0).let {
|
||||||
if (it.resolveActivity(packageManager) != null) startActivity(it)
|
if (it.resolveActivity(packageManager) != null) startActivity(it)
|
||||||
else onActivityNotFound(uri)
|
else onActivityNotFound(uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.dpToPx(dp: Float) = dp * resources.displayMetrics.densityDpi / DENSITY_DEFAULT
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
package io.github.wulkanowy.utils
|
|
||||||
|
|
||||||
import android.text.Editable
|
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.widget.EditText
|
|
||||||
|
|
||||||
inline fun EditText.setOnTextChangedListener(crossinline listener: () -> Unit) {
|
|
||||||
addTextChangedListener(object : TextWatcher {
|
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
|
||||||
listener()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun afterTextChanged(s: Editable?) {}
|
|
||||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
|
||||||
})
|
|
||||||
}
|
|
@ -2,19 +2,20 @@ package io.github.wulkanowy.utils
|
|||||||
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.ncapdevi.fragnav.FragNavController
|
import com.ncapdevi.fragnav.FragNavController
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
|
||||||
inline fun FragNavController.setOnViewChangeListener(crossinline listener: (fragment: Fragment?) -> Unit) {
|
inline fun FragNavController.setOnViewChangeListener(crossinline listener: (section: MainView.Section?) -> Unit) {
|
||||||
transactionListener = object : FragNavController.TransactionListener {
|
transactionListener = object : FragNavController.TransactionListener {
|
||||||
override fun onFragmentTransaction(fragment: Fragment?, transactionType: FragNavController.TransactionType) {
|
override fun onFragmentTransaction(fragment: Fragment?, transactionType: FragNavController.TransactionType) {
|
||||||
listener(fragment)
|
listener(fragment?.toSection())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTabTransaction(fragment: Fragment?, index: Int) {
|
override fun onTabTransaction(fragment: Fragment?, index: Int) {
|
||||||
listener(fragment)
|
listener(fragment?.toSection())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FragNavController.safelyPopFragment() {
|
fun FragNavController.safelyPopFragments(depth: Int) {
|
||||||
if (!isRootFragment) popFragment()
|
if (!isRootFragment) popFragments(depth)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import io.github.wulkanowy.ui.modules.about.AboutFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.exam.ExamFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||||
|
|
||||||
|
fun Fragment.toSection(): MainView.Section? {
|
||||||
|
return when (this) {
|
||||||
|
is GradeFragment -> MainView.Section.GRADE
|
||||||
|
is AttendanceFragment -> MainView.Section.ATTENDANCE
|
||||||
|
is ExamFragment -> MainView.Section.EXAM
|
||||||
|
is TimetableFragment -> MainView.Section.TIMETABLE
|
||||||
|
is MoreFragment -> MainView.Section.MORE
|
||||||
|
is MessageFragment -> MainView.Section.MESSAGE
|
||||||
|
is HomeworkFragment -> MainView.Section.HOMEWORK
|
||||||
|
is NoteFragment -> MainView.Section.NOTE
|
||||||
|
is LuckyNumberFragment -> MainView.Section.LUCKY_NUMBER
|
||||||
|
is SettingsFragment -> MainView.Section.SETTINGS
|
||||||
|
is AboutFragment -> MainView.Section.ABOUT
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
package io.github.wulkanowy.utils
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import com.mikepenz.aboutlibraries.Libs
|
|
||||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
|
||||||
import com.mikepenz.aboutlibraries.LibsConfiguration
|
|
||||||
|
|
||||||
inline fun LibsBuilder.withOnExtraListener(crossinline listener: (Libs.SpecialButton?) -> Unit): LibsBuilder {
|
|
||||||
withListener(object : LibsConfiguration.LibsListenerImpl() {
|
|
||||||
override fun onExtraClicked(v: View?, specialButton: Libs.SpecialButton?): Boolean {
|
|
||||||
listener(specialButton)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return this
|
|
||||||
}
|
|
@ -7,14 +7,15 @@ import android.widget.Spinner
|
|||||||
/**
|
/**
|
||||||
* @see <a href="https://stackoverflow.com/a/29602298">How to keep onItemSelected from firing off on a newly instantiated Spinner?</a>
|
* @see <a href="https://stackoverflow.com/a/29602298">How to keep onItemSelected from firing off on a newly instantiated Spinner?</a>
|
||||||
*/
|
*/
|
||||||
inline fun Spinner.setOnItemSelectedListener(crossinline listener: (view: View?) -> Unit) {
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <T : View> Spinner.setOnItemSelectedListener(crossinline listener: (view: T?) -> Unit) {
|
||||||
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||||
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||||
listener(view)
|
listener(view as T?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
Wersja 0.9.4
|
Wersja 0.10.0
|
||||||
|
|
||||||
- naprawienie nawigacji we frekwencji, sprawdzianach, planie lekcji na wakacjach
|
- odświeżyliśmy wygląd aplikacji
|
||||||
- wyświetlanie szczęśliwego numerka po ostatniej aktualizacji dziennika VULCAN (19.06)
|
- poprawiliśmy wyświetlanie nauczycieli w planie lekcji
|
||||||
|
- naprawiliśmy szczęsliwy numerek
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
13
app/src/main/res/drawable-anydpi-v24/ic_stat_grade.xml
Normal file
13
app/src/main/res/drawable-anydpi-v24/ic_stat_grade.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="28.26087"
|
||||||
|
android:viewportHeight="28.26087">
|
||||||
|
<group
|
||||||
|
android:translateX="1.1304348"
|
||||||
|
android:translateY="1.1304348">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFF"
|
||||||
|
android:pathData="M13 11h2v2h-2m0 2h2a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2h-2V7h4V5h-4a2 2 0 0 0-2 2v6c0 1.1 0.9 2 2 2m8 2H7V3h14m0-2H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2M3 5H1v16a2 2 0 0 0 2 2h16v-2H3V5z" />
|
||||||
|
</group>
|
||||||
|
</vector>
|
13
app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml
Normal file
13
app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="26.086956"
|
||||||
|
android:viewportHeight="26.086956">
|
||||||
|
<group
|
||||||
|
android:translateX="1.0434783"
|
||||||
|
android:translateY="1.0434783">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFF"
|
||||||
|
android:pathData="M12,11.18C15.3,8.18 17,6.64 17,4.69C17,3.19 15.75,2 14.25,2C13.39,2 12.57,2.36 12,3C11.43,2.36 10.61,2 9.69,2C8.19,2 7,3.25 7,4.75C7,6.64 8.7,8.18 12,11.18M11.18,12C8.18,8.7 6.64,7 4.69,7C3.19,7 2,8.25 2, 9.75C2,10.61 2.36,11.43 3,12C2.36,12.57 2,13.39 2,14.31C2,15.81 3.25,17 4.75,17C6.64,17 8.18,15.3 11.18,12M12.83, 12C15.82,15.3 17.36,17 19.31,17C20.81,17 22,15.75 22,14.25C22,13.39 21.64,12.57 21,12C21.64,11.43 22,10.61 22,9.69C22, 8.19 20.75,7 19.25,7C17.36,7 15.82,8.7 12.83,12M12,12.82C8.7,15.82 7,17.36 7,19.31C7,20.81 8.25,22 9.75,22C10.61,22 11.43,21.64 12,21C12.57,21.64 13.39,22 14.31,22C15.81,22 17,20.75 17,19.25C17,17.36 15.3,15.82 12,12.82Z" />
|
||||||
|
</group>
|
||||||
|
</vector>
|
13
app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml
Normal file
13
app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="26.086956"
|
||||||
|
android:viewportHeight="26.086956">
|
||||||
|
<group
|
||||||
|
android:translateX="1.0434783"
|
||||||
|
android:translateY="1.0434783">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFF"
|
||||||
|
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z" />
|
||||||
|
</group>
|
||||||
|
</vector>
|
13
app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml
Normal file
13
app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="26.086956"
|
||||||
|
android:viewportHeight="26.086956">
|
||||||
|
<group
|
||||||
|
android:translateX="1.0434783"
|
||||||
|
android:translateY="1.0434783">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFF"
|
||||||
|
android:pathData="M20.2,2H19.5H18C17.1,2 16,3 16,4H8C8,3 6.9,2 6,2H4.5H3.8H2V11C2,12 3,13 4,13H6.2C6.6,15 7.9,16.7 11,17V19.1C8.8,19.3 8,20.4 8,21.7V22H16V21.7C16,20.4 15.2,19.3 13,19.1V17C16.1,16.7 17.4,15 17.8,13H20C21,13 22,12 22,11V2H20.2M4,11V4H6V6V11C5.1,11 4.3,11 4,11M20,11C19.7,11 18.9,11 18,11V6V4H20V11Z" />
|
||||||
|
</group>
|
||||||
|
</vector>
|
@ -1,14 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="26.086956"
|
|
||||||
android:viewportHeight="26.086956"
|
|
||||||
android:tint="#FFFFFF">
|
|
||||||
<group
|
|
||||||
android:translateX="1.0434783"
|
|
||||||
android:translateY="1.0434783">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:pathData="M12,11.18C15.3,8.18 17,6.64 17,4.69C17,3.19 15.75,2 14.25,2C13.39,2 12.57,2.36 12,3C11.43,2.36 10.61,2 9.69,2C8.19,2 7,3.25 7,4.75C7,6.64 8.7,8.18 12,11.18M11.18,12C8.18,8.7 6.64,7 4.69,7C3.19,7 2,8.25 2,9.75C2,10.61 2.36,11.43 3,12C2.36,12.57 2,13.39 2,14.31C2,15.81 3.25,17 4.75,17C6.64,17 8.18,15.3 11.18,12M12.83,12C15.82,15.3 17.36,17 19.31,17C20.81,17 22,15.75 22,14.25C22,13.39 21.64,12.57 21,12C21.64,11.43 22,10.61 22,9.69C22,8.19 20.75,7 19.25,7C17.36,7 15.82,8.7 12.83,12M12,12.82C8.7,15.82 7,17.36 7,19.31C7,20.81 8.25,22 9.75,22C10.61,22 11.43,21.64 12,21C12.57,21.64 13.39,22 14.31,22C15.81,22 17,20.75 17,19.25C17,17.36 15.3,15.82 12,12.82Z" />
|
|
||||||
</group>
|
|
||||||
</vector>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user