Skip to content

Commit

Permalink
Merge pull request #206 from alexandr7035/develop
Browse files Browse the repository at this point in the history
Release v5.4

- Improve UI performance
- Fix crash on contributions grid update
- Fix UI bugs
- Refactoring
  • Loading branch information
alexandr7035 authored Dec 13, 2021
2 parents d126f8f + 876d5b2 commit d9a9747
Show file tree
Hide file tree
Showing 39 changed files with 757 additions and 680 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ android {
applicationId 'by.alexandr7035.gitstat'
minSdkVersion 21
targetSdkVersion 31
versionCode 2100
versionName "5.3"
versionCode 2200
versionName "5.4"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/by/alexandr7035/gitstat/core/TimeHelper.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package by.alexandr7035.gitstat.core

import by.alexandr7035.gitstat.extensions.getStringDateFromLong
import by.alexandr7035.gitstat.extensions.getUnixDateFromStringFormat
import by.alexandr7035.gitstat.core.extensions.getStringDateFromLong
import by.alexandr7035.gitstat.core.extensions.getUnixDateFromStringFormat
import java.text.SimpleDateFormat
import java.util.*

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import by.alexandr7035.gitstat.core.AppError
import by.alexandr7035.gitstat.core.ErrorType
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import by.alexandr7035.gitstat.view.contributions.plots.LinePlotFill
import com.github.mikephil.charting.charts.LineChart
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package by.alexandr7035.gitstat.core.extensions

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData

// Sometimes we may receive nulls in livedata observers
// For example, when room cache tables are cleared before saving updated data
// So we just skip null updates to avoid null checks
//
// See https://proandroiddev.com/nonnull-livedata-with-kotlin-extension-26963ffd0333
fun <T> LiveData<T>.observeNullSafe(owner: LifecycleOwner, observer: (t: T) -> Unit) {
this.observe(owner, {
it?.let(observer)
})
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import java.text.SimpleDateFormat
import java.util.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import androidx.navigation.NavController
import androidx.navigation.NavDirections
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import android.graphics.Color
import android.graphics.Typeface
import by.alexandr7035.gitstat.view.repositories.plots.languages_plot.PieDataValueFormatter
import com.github.mikephil.charting.charts.PieChart
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.data.PieData
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import android.graphics.Typeface
import android.text.SpannableString
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import timber.log.Timber

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.alexandr7035.gitstat.extensions
package by.alexandr7035.gitstat.core.extensions

import com.github.mikephil.charting.components.YAxis
import kotlin.math.floor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package by.alexandr7035.gitstat.core.view

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.widget.AppCompatTextView

class CollapsingTextView(context: Context, attrs: AttributeSet): AppCompatTextView(context, attrs), View.OnClickListener {
private var predefinedMaxLines = 0

init {
predefinedMaxLines = maxLines

// If want to collapse on clicks directly on the view
// Otherwise use toggle() method
if (isClickable) {
super.setOnClickListener(this)
}
}

override fun onClick(p0: View?) {
toggle()
}

fun toggle() {
maxLines = if (maxLines == predefinedMaxLines) {
Int.MAX_VALUE
} else {
predefinedMaxLines
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import by.alexandr7035.gitstat.R
import by.alexandr7035.gitstat.extensions.debug
import by.alexandr7035.gitstat.core.extensions.debug
import timber.log.Timber


Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package by.alexandr7035.gitstat.data

import androidx.lifecycle.LiveData
import by.alexandr7035.gitstat.core.KeyValueStorage
import by.alexandr7035.gitstat.core.TimeHelper
import by.alexandr7035.gitstat.data.helpers.YearlyMetricsHelper
import by.alexandr7035.gitstat.data.local.dao.ContributionsDao
import by.alexandr7035.gitstat.data.local.model.*
import javax.inject.Inject
import kotlin.math.round


class ContributionsRepository @Inject constructor(
private val dao: ContributionsDao,
private val timeHelper: TimeHelper,
private val keyValueStorage: KeyValueStorage
private val yearlyMetricsHelper: YearlyMetricsHelper
) {

fun getAllContributionsLiveData(): LiveData<List<ContributionDayEntity>> {
Expand All @@ -39,32 +36,11 @@ class ContributionsRepository @Inject constructor(
// Simply calculate for previous years
// For the current year need to detect last contribution year
fun getLastTotalContributionRateForYear(yearData: ContributionsYearWithRates): Float {
return if (yearData.year.id == timeHelper.getCurrentYearForUnixDate(System.currentTimeMillis())) {
val lastCacheSyncDate = keyValueStorage.getLastCacheSyncDate()
yearData.contributionRates.findLast { it.date == timeHelper.getBeginningOfDayForUnixDate(lastCacheSyncDate) }?.rate ?: 0F
} else {
yearData.contributionRates[yearData.contributionRates.size - 1].rate
}
return yearlyMetricsHelper.getAnnualContributionRate(yearData)
}

fun getContributionRateForYear(yearData: ContributionsYearWithDays): Float {

val contributionsCount = yearData.contributionDays.sumOf { it.count }

return if (yearData.year.id == timeHelper.getCurrentYearForUnixDate(System.currentTimeMillis())) {
// Get last contribution day
val lastCacheSyncDate = keyValueStorage.getLastCacheSyncDate()
val lastContributedDay = yearData.contributionDays.findLast {
it.date == timeHelper.getBeginningOfDayForUnixDate(lastCacheSyncDate)
}
val lastContributedDayPosition = yearData.contributionDays.lastIndexOf(lastContributedDay)
// Slice of days from the beginning of the year to last contribution date
val contributionDays = yearData.contributionDays.slice(0..lastContributedDayPosition)

round(contributionsCount.toFloat() / contributionDays.size.toFloat() * 100) / 100F
} else {
round(contributionsCount.toFloat() / yearData.contributionDays.size.toFloat() * 100) / 100F
}
return yearlyMetricsHelper.getEndingTotalContributionRate(yearData)
}

fun getMaxContributionRateForYear(yearData: ContributionsYearWithRates): Float {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import by.alexandr7035.gitstat.core.*
import by.alexandr7035.gitstat.data.local.CacheDB
import by.alexandr7035.gitstat.data.local.model.*
import by.alexandr7035.gitstat.data.remote.mappers.*
import by.alexandr7035.gitstat.extensions.performRequestWithDataResult
import by.alexandr7035.gitstat.core.extensions.performRequestWithDataResult
import com.apollographql.apollo3.ApolloClient
import timber.log.Timber
import java.util.*
Expand Down Expand Up @@ -67,13 +67,13 @@ class DataSyncRepository @Inject constructor(
// NOTE! DO NOT CHANGE ORDER
// LIVEDATA TRIGGERED IMMEDIATELY AFTER SAVING CACHE
// AS ONE DATA MAY DEPEND ON THE OTHER, WRONG ORDER MAY CAUSE CRASH
// Years and months must be at the end
// Order must be: days -> months -> years
db.getContributionsDao().apply {
insertContributionRatesCache(contributionRates)
insertContributionDays(contributionDays)
insertContributionTypes(contributionTypes)
insertContributionYearsCache(contributionYears)
insertContributionMonthsCache(contributionMonths)
insertContributionYearsCache(contributionYears)
}

syncStatusLiveData?.postValue(DataSyncStatus.SUCCESS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import androidx.lifecycle.LifecycleService
import androidx.lifecycle.MutableLiveData
import by.alexandr7035.gitstat.R
import by.alexandr7035.gitstat.core.DataSyncStatus
import by.alexandr7035.gitstat.extensions.debug
import by.alexandr7035.gitstat.core.extensions.debug
import by.alexandr7035.gitstat.core.extensions.observeNullSafe
import by.alexandr7035.gitstat.view.MainActivity
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.*
Expand Down Expand Up @@ -48,7 +49,7 @@ class SyncForegroundService: LifecycleService() {
stopSelf()
}

statusLiveData?.observe(this, {
statusLiveData?.observeNullSafe(this, {
Timber.debug("Service: sync status changed $it")

val notificationText = when (it) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package by.alexandr7035.gitstat.data.helpers

import by.alexandr7035.gitstat.core.KeyValueStorage
import by.alexandr7035.gitstat.core.TimeHelper
import by.alexandr7035.gitstat.data.local.model.ContributionsYearWithDays
import by.alexandr7035.gitstat.data.local.model.ContributionsYearWithRates
import javax.inject.Inject
import kotlin.math.round

interface YearlyMetricsHelper {
// Contribution rate for certain year
fun getAnnualContributionRate(yearData: ContributionsYearWithRates): Float

// Value of total (not annual) contribution rate by the end of specified year
fun getEndingTotalContributionRate(yearData: ContributionsYearWithDays): Float


class Impl @Inject constructor(private val timeHelper: TimeHelper, private val keyValueStorage: KeyValueStorage): YearlyMetricsHelper {
override fun getAnnualContributionRate(yearData: ContributionsYearWithRates): Float {
return if (yearData.year.id == timeHelper.getCurrentYearForUnixDate(System.currentTimeMillis())) {
val lastCacheSyncDate = keyValueStorage.getLastCacheSyncDate()
yearData.contributionRates.findLast { it.date == timeHelper.getBeginningOfDayForUnixDate(lastCacheSyncDate) }?.rate ?: 0F
} else {
yearData.contributionRates[yearData.contributionRates.size - 1].rate
}
}

override fun getEndingTotalContributionRate(yearData: ContributionsYearWithDays): Float {
val contributionsCount = yearData.contributionDays.sumOf { it.count }

return if (yearData.year.id == timeHelper.getCurrentYearForUnixDate(System.currentTimeMillis())) {
// Get last contribution day
val lastCacheSyncDate = keyValueStorage.getLastCacheSyncDate()
val lastContributedDay = yearData.contributionDays.findLast {
it.date == timeHelper.getBeginningOfDayForUnixDate(lastCacheSyncDate)
}
val lastContributedDayPosition = yearData.contributionDays.lastIndexOf(lastContributedDay)
// Slice of days from the beginning of the year to last contribution date
val contributionDays = yearData.contributionDays.slice(0..lastContributedDayPosition)

round(contributionsCount.toFloat() / contributionDays.size.toFloat() * 100) / 100F
} else {
round(contributionsCount.toFloat() / yearData.contributionDays.size.toFloat() * 100) / 100F
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import by.alexandr7035.gitstat.core.Mapper
import by.alexandr7035.gitstat.core.TimeHelper
import by.alexandr7035.gitstat.data.local.model.RepoLanguage
import by.alexandr7035.gitstat.data.local.model.RepositoryEntity
import by.alexandr7035.gitstat.extensions.debug
import by.alexandr7035.gitstat.core.extensions.debug
import timber.log.Timber
import javax.inject.Inject

Expand Down
12 changes: 9 additions & 3 deletions app/src/main/java/by/alexandr7035/gitstat/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.room.Room
import by.alexandr7035.gitstat.core.KeyValueStorage
import by.alexandr7035.gitstat.core.TimeHelper
import by.alexandr7035.gitstat.data.*
import by.alexandr7035.gitstat.data.helpers.YearlyMetricsHelper
import by.alexandr7035.gitstat.data.local.CacheDB
import by.alexandr7035.gitstat.data.local.RoomTypeConverters
import by.alexandr7035.gitstat.data.local.dao.ContributionsDao
Expand Down Expand Up @@ -65,10 +66,9 @@ object AppModule {
@Singleton
fun provideContributionsRepository(
dao: ContributionsDao,
timeHelper: TimeHelper,
keyValueStorage: KeyValueStorage
yearlyMetricsHelper: YearlyMetricsHelper
): ContributionsRepository{
return ContributionsRepository(dao, timeHelper, keyValueStorage)
return ContributionsRepository(dao, yearlyMetricsHelper)
}


Expand Down Expand Up @@ -175,4 +175,10 @@ object AppModule {
fun provideTimeHelper(): TimeHelper {
return TimeHelper()
}

@Provides
@Singleton
fun provideYearlyMetricsHelper(keyValueStorage: KeyValueStorage, timeHelper: TimeHelper): YearlyMetricsHelper {
return YearlyMetricsHelper.Impl(timeHelper, keyValueStorage)
}
}
Loading

0 comments on commit d9a9747

Please sign in to comment.