Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
5add95ece1 | |||
575e244b3a | |||
8db73e9459 | |||
040857ba20 |
@ -14,6 +14,7 @@ cache:
|
||||
#branches:
|
||||
# only:
|
||||
# - master
|
||||
# - 0.7.x
|
||||
|
||||
android:
|
||||
licenses:
|
||||
|
@ -16,8 +16,8 @@ android {
|
||||
testApplicationId "io.github.tests.wulkanowy"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 28
|
||||
versionCode 26
|
||||
versionName "0.7.0"
|
||||
versionCode 27
|
||||
versionName "0.7.1"
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
@ -77,7 +77,7 @@ play {
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation('io.github.wulkanowy:api:0.7.0') { exclude module: "threetenbp" }
|
||||
implementation('io.github.wulkanowy:api:0.7.1') { exclude module: "threetenbp" }
|
||||
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
||||
|
@ -34,9 +34,9 @@ class GradeLocalTest {
|
||||
@Test
|
||||
fun saveAndReadTest() {
|
||||
gradeLocal.saveGrades(listOf(
|
||||
createGradeLocal(5, 3, LocalDate.of(2018, 9, 10), "", 1),
|
||||
createGradeLocal(4, 4, LocalDate.of(2019, 2, 27), "", 2),
|
||||
createGradeLocal(3, 5, LocalDate.of(2019, 2, 28), "", 2)
|
||||
createGradeLocal(5, 3.0, LocalDate.of(2018, 9, 10), "", 1),
|
||||
createGradeLocal(4, 4.0, LocalDate.of(2019, 2, 27), "", 2),
|
||||
createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2)
|
||||
))
|
||||
|
||||
val grades = gradeLocal
|
||||
|
@ -71,10 +71,10 @@ class GradeRepositoryTest {
|
||||
@Test
|
||||
fun markOlderThanRegisterDateAsRead() {
|
||||
every { mockApi.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 4, of(2019, 2, 25), "Ocena pojawiła się"),
|
||||
createGradeApi(5, 4, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
|
||||
createGradeApi(5, 4, of(2019, 2, 27), "Ocena z dnia logowania"),
|
||||
createGradeApi(5, 4, of(2019, 2, 28), "Ocena jeszcze nowsza")
|
||||
createGradeApi(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
|
||||
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
|
||||
))
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
@ -89,16 +89,16 @@ class GradeRepositoryTest {
|
||||
@Test
|
||||
fun mitigateOldGradesNotifications() {
|
||||
gradeLocal.saveGrades(listOf(
|
||||
createGradeLocal(5, 3, of(2019, 2, 25), "Jedna ocena"),
|
||||
createGradeLocal(4, 4, of(2019, 2, 26), "Druga"),
|
||||
createGradeLocal(3, 5, of(2019, 2, 27), "Trzecia")
|
||||
createGradeLocal(5, 3.0, of(2019, 2, 25), "Jedna ocena"),
|
||||
createGradeLocal(4, 4.0, of(2019, 2, 26), "Druga"),
|
||||
createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia")
|
||||
))
|
||||
|
||||
every { mockApi.getGrades(1) } returns Single.just(listOf(
|
||||
createGradeApi(5, 2, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"),
|
||||
createGradeApi(4, 3, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
|
||||
createGradeApi(3, 4, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
|
||||
createGradeApi(2, 5, of(2019, 2, 28), "Ta jest już w ogóle nowa")
|
||||
createGradeApi(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"),
|
||||
createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
|
||||
createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
|
||||
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
|
||||
))
|
||||
|
||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||
|
@ -5,7 +5,7 @@ import org.threeten.bp.LocalDate
|
||||
import io.github.wulkanowy.api.grades.Grade as GradeRemote
|
||||
import io.github.wulkanowy.data.db.entities.Grade as GradeLocal
|
||||
|
||||
fun createGradeLocal(value: Int, weight: Int, date: LocalDate, desc: String, semesterId: Int = 1): GradeLocal {
|
||||
fun createGradeLocal(value: Int, weight: Double, date: LocalDate, desc: String, semesterId: Int = 1): GradeLocal {
|
||||
return GradeLocal(
|
||||
semesterId = semesterId,
|
||||
studentId = 1,
|
||||
@ -24,7 +24,7 @@ fun createGradeLocal(value: Int, weight: Int, date: LocalDate, desc: String, sem
|
||||
)
|
||||
}
|
||||
|
||||
fun createGradeApi(value: Int, weight: Int, date: LocalDate, desc: String): GradeRemote {
|
||||
fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String): GradeRemote {
|
||||
return GradeRemote().apply {
|
||||
this.value = value
|
||||
this.weightValue = weight
|
||||
|
@ -39,18 +39,12 @@
|
||||
android:name=".ui.modules.main.MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/main_title"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
||||
<activity
|
||||
android:name=".ui.modules.message.send.SendMessageActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/send_message_title"
|
||||
android:parentActivityName=".ui.modules.main.MainActivity"
|
||||
android:theme="@style/WulkanowyTheme.NoActionBar">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".ui.modules.main.MainActivity" />
|
||||
</activity>
|
||||
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
||||
|
||||
<service
|
||||
android:name=".services.widgets.TimetableWidgetService"
|
||||
|
@ -41,6 +41,7 @@ import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.Subject
|
||||
import io.github.wulkanowy.data.db.entities.Timetable
|
||||
import io.github.wulkanowy.data.db.migrations.Migration10
|
||||
import io.github.wulkanowy.data.db.migrations.Migration11
|
||||
import io.github.wulkanowy.data.db.migrations.Migration2
|
||||
import io.github.wulkanowy.data.db.migrations.Migration3
|
||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||
@ -79,7 +80,7 @@ import javax.inject.Singleton
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
const val VERSION_SCHEMA = 10
|
||||
const val VERSION_SCHEMA = 11
|
||||
|
||||
fun newInstance(context: Context): AppDatabase {
|
||||
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
|
||||
@ -95,7 +96,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
Migration7(),
|
||||
Migration8(),
|
||||
Migration9(),
|
||||
Migration10()
|
||||
Migration10(),
|
||||
Migration11()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ data class Grade(
|
||||
|
||||
val weight: String,
|
||||
|
||||
val weightValue: Int,
|
||||
val weightValue: Double,
|
||||
|
||||
val date: LocalDate,
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
package io.github.wulkanowy.data.db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration11 : Migration(10, 11) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS Grades_temp (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
is_read INTEGER NOT NULL,
|
||||
is_notified INTEGER NOT NULL,
|
||||
semester_id INTEGER NOT NULL,
|
||||
student_id INTEGER NOT NULL,
|
||||
subject TEXT NOT NULL,
|
||||
entry TEXT NOT NULL,
|
||||
value INTEGER NOT NULL,
|
||||
modifier REAL NOT NULL,
|
||||
comment TEXT NOT NULL,
|
||||
color TEXT NOT NULL,
|
||||
grade_symbol TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
weight TEXT NOT NULL,
|
||||
weightValue REAL NOT NULL,
|
||||
date INTEGER NOT NULL,
|
||||
teacher TEXT NOT NULL
|
||||
)
|
||||
""")
|
||||
database.execSQL("INSERT INTO Grades_temp SELECT * FROM Grades")
|
||||
database.execSQL("DROP TABLE Grades")
|
||||
database.execSQL("ALTER TABLE Grades_temp RENAME TO Grades")
|
||||
}
|
||||
}
|
@ -29,6 +29,8 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
|
||||
@Inject
|
||||
lateinit var pagerAdapter: BaseFragmentPagerAdapter
|
||||
|
||||
private var semesterSwitchMenu: MenuItem? = null
|
||||
|
||||
companion object {
|
||||
private const val SAVED_SEMESTER_KEY = "CURRENT_SEMESTER"
|
||||
|
||||
@ -57,6 +59,8 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
inflater?.inflate(R.menu.action_menu_grade, menu)
|
||||
semesterSwitchMenu = menu?.findItem(R.id.gradeMenuSemester)
|
||||
presenter.onCreateMenu()
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
@ -75,6 +79,7 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
|
||||
setOnSelectPageListener { presenter.onPageSelected(it) }
|
||||
}
|
||||
gradeTabLayout.setupWithViewPager(gradeViewPager)
|
||||
gradeSwipe.setOnRefreshListener { presenter.onSwipeRefresh() }
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
@ -95,8 +100,20 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
|
||||
gradeProgress.visibility = if (show) VISIBLE else INVISIBLE
|
||||
}
|
||||
|
||||
override fun showEmpty() {
|
||||
gradeEmpty.visibility = VISIBLE
|
||||
override fun showEmpty(show: Boolean) {
|
||||
gradeEmpty.visibility = if (show) VISIBLE else INVISIBLE
|
||||
}
|
||||
|
||||
override fun showRefresh(show: Boolean) {
|
||||
gradeSwipe.isRefreshing = show
|
||||
}
|
||||
|
||||
override fun showSemesterSwitch(show: Boolean) {
|
||||
semesterSwitchMenu?.isVisible = show
|
||||
}
|
||||
|
||||
override fun enableSwipe(enable: Boolean) {
|
||||
gradeSwipe.isEnabled = enable
|
||||
}
|
||||
|
||||
override fun showSemesterDialog(selectedIndex: Int) {
|
||||
|
@ -33,11 +33,18 @@ class GradePresenter @Inject constructor(
|
||||
disposable.add(Completable.timer(150, MILLISECONDS, schedulers.mainThread)
|
||||
.subscribe {
|
||||
selectedIndex = savedIndex ?: 0
|
||||
view.initView()
|
||||
view.run {
|
||||
initView()
|
||||
enableSwipe(false)
|
||||
}
|
||||
loadData()
|
||||
})
|
||||
}
|
||||
|
||||
fun onCreateMenu() {
|
||||
if (semesters.isEmpty()) view?.showSemesterSwitch(false)
|
||||
}
|
||||
|
||||
fun onViewReselected() {
|
||||
Timber.i("Grade view is reselected")
|
||||
view?.run { notifyChildParentReselected(currentPageIndex) }
|
||||
@ -69,6 +76,7 @@ class GradePresenter @Inject constructor(
|
||||
view?.apply {
|
||||
showContent(true)
|
||||
showProgress(false)
|
||||
showEmpty(false)
|
||||
loadedSemesterId[currentPageIndex] = semesterId
|
||||
}
|
||||
}
|
||||
@ -77,6 +85,10 @@ class GradePresenter @Inject constructor(
|
||||
loadChild(index)
|
||||
}
|
||||
|
||||
fun onSwipeRefresh() {
|
||||
loadData()
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
Timber.i("Loading grade data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
@ -89,17 +101,21 @@ class GradePresenter @Inject constructor(
|
||||
}
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally { view?.showRefresh(false) }
|
||||
.subscribe({
|
||||
view?.run {
|
||||
Timber.i("Loading grade result: Attempt load index $currentPageIndex")
|
||||
loadChild(currentPageIndex)
|
||||
enableSwipe(false)
|
||||
showSemesterSwitch(true)
|
||||
}
|
||||
}) {
|
||||
Timber.i("Loading grade result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
view?.run {
|
||||
showProgress(false)
|
||||
showEmpty()
|
||||
showEmpty(true)
|
||||
enableSwipe(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -12,10 +12,16 @@ interface GradeView : BaseSessionView {
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
fun showEmpty()
|
||||
fun showEmpty(show: Boolean)
|
||||
|
||||
fun showRefresh(show: Boolean)
|
||||
|
||||
fun showSemesterSwitch(show: Boolean)
|
||||
|
||||
fun showSemesterDialog(selectedIndex: Int)
|
||||
|
||||
fun enableSwipe(enable: Boolean)
|
||||
|
||||
fun notifyChildLoadData(index: Int, semesterId: Int, forceRefresh: Boolean)
|
||||
|
||||
fun notifyChildParentReselected(index: Int)
|
||||
|
@ -72,6 +72,10 @@ class SendMessageActivity : BaseActivity(), SendMessageView {
|
||||
else false
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return presenter.onUpNavigate()
|
||||
}
|
||||
|
||||
override fun setReportingUnit(unit: ReportingUnit) {
|
||||
sendMessageFromTextView.setText(unit.senderName)
|
||||
}
|
||||
|
@ -47,6 +47,11 @@ class SendMessagePresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun onUpNavigate(): Boolean {
|
||||
view?.popView()
|
||||
return true
|
||||
}
|
||||
|
||||
private fun loadData(message: Message?) {
|
||||
var reportingUnit: ReportingUnit? = null
|
||||
var recipients: List<Recipient> = emptyList()
|
||||
|
@ -1,5 +1,3 @@
|
||||
Wersja 0.7.0
|
||||
|
||||
Dodaliśmy:
|
||||
- szczęśliwy numerek
|
||||
- lekcje zrealizowane
|
||||
|
@ -17,13 +17,19 @@
|
||||
app:tabTextColor="@android:color/white"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/gradeViewPager"
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/gradeSwipe"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="48dp"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="visible" />
|
||||
android:layout_marginTop="48dp">
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/gradeViewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="visible" />
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/gradeProgress"
|
||||
|
@ -22,11 +22,11 @@ class GradeExtensionTest {
|
||||
@Test
|
||||
fun calcWeightedAverage() {
|
||||
assertEquals(3.47, listOf(
|
||||
createGrade(5, 6, 0.33),
|
||||
createGrade(5, 5, -0.33),
|
||||
createGrade(4, 1, 0.0),
|
||||
createGrade(1, 9, 0.5),
|
||||
createGrade(0, 0, 0.0)
|
||||
createGrade(5, 6.0, 0.33),
|
||||
createGrade(5, 5.0, -0.33),
|
||||
createGrade(4, 1.0, 0.0),
|
||||
createGrade(1, 9.0, 0.5),
|
||||
createGrade(0, .0, 0.0)
|
||||
).calcAverage(), 0.005)
|
||||
}
|
||||
|
||||
@ -42,23 +42,23 @@ class GradeExtensionTest {
|
||||
|
||||
@Test
|
||||
fun changeModifier_default() {
|
||||
assertEquals(.33, createGrade(5, 0, .33).changeModifier(.0, .0).modifier, .0)
|
||||
assertEquals(-.33, createGrade(5, 0, -.33).changeModifier(.0, .0).modifier, .0)
|
||||
assertEquals(.33, createGrade(5, .0, .33).changeModifier(.0, .0).modifier, .0)
|
||||
assertEquals(-.33, createGrade(5, .0, -.33).changeModifier(.0, .0).modifier, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeModifier_plus() {
|
||||
assertEquals(.33, createGrade(5, 0, .25).changeModifier(.33, .50).modifier, .0)
|
||||
assertEquals(.25, createGrade(5, 0, .33).changeModifier(.25, .0).modifier, .0)
|
||||
assertEquals(.33, createGrade(5, .0, .25).changeModifier(.33, .50).modifier, .0)
|
||||
assertEquals(.25, createGrade(5, .0, .33).changeModifier(.25, .0).modifier, .0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeModifier_minus() {
|
||||
assertEquals(-.33, createGrade(5, 0, -.25).changeModifier(.25, .33).modifier, .0)
|
||||
assertEquals(-.25, createGrade(5, 0, -.33).changeModifier(.0, .25).modifier, .0)
|
||||
assertEquals(-.33, createGrade(5, .0, -.25).changeModifier(.25, .33).modifier, .0)
|
||||
assertEquals(-.25, createGrade(5, .0, -.33).changeModifier(.0, .25).modifier, .0)
|
||||
}
|
||||
|
||||
private fun createGrade(value: Int, weightValue: Int = 0, modifier: Double = 0.25): Grade {
|
||||
private fun createGrade(value: Int, weightValue: Double = .0, modifier: Double = 0.25): Grade {
|
||||
return Grade(
|
||||
semesterId = 1,
|
||||
studentId = 1,
|
||||
|
Reference in New Issue
Block a user