1
0

Compare commits

...

4 Commits
0.7.0 ... 0.7.1

17 changed files with 136 additions and 53 deletions

View File

@ -14,6 +14,7 @@ cache:
#branches:
# only:
# - master
# - 0.7.x
android:
licenses:

View File

@ -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"

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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()
}

View File

@ -34,7 +34,7 @@ data class Grade(
val weight: String,
val weightValue: Int,
val weightValue: Double,
val date: LocalDate,

View File

@ -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")
}
}

View File

@ -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) {

View File

@ -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)
}
})
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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()

View File

@ -1,5 +1,3 @@
Wersja 0.7.0
Dodaliśmy:
- szczęśliwy numerek
- lekcje zrealizowane

View File

@ -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"

View File

@ -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,