Skip to content

Commit

Permalink
Layout adjustments for main view
Browse files Browse the repository at this point in the history
  • Loading branch information
Ixam97 committed Nov 14, 2023
1 parent 774531b commit b0c08cb
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 75 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog [DE]:

## 0.26.0
- Experimentelles Farbschema hinzugefügt.
- Vereinfachte Auswahl der Sekundärachse.
- Der Datenbankupload wurde in Abschnitte unterteilt, um falsche Fehlermedungen zu vermeiden und den Fortschritt anzeigen zu können.

## 0.25.2 ()
- Erweiterung der Webhook-API.
- Option für eine Handy-Erinnerung beim verlassen des Fahrzeugs hinzugefügt.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

Currently the app is not available in the public Play Store. This is due to strict requirements by Google what kind of apps are allowed to be installed on cars. As of now the App is only available via internal test tracks which are limited to 100 users each. Currently there are no free internal test slots in any of the existing forks.

There are currently ongoing talks with Polestar to bring the app to a broader audience. But this will take some time and Polestar will most likely require some changes to make the app comply with there safety and usability standards.
There are currently ongoing talks with Polestar to bring the app to a broader audience. But this will take some time and Polestar will most likely require some changes to make the app comply with their safety and usability standards.

## Using the webhook API

Expand Down
4 changes: 2 additions & 2 deletions automotive/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ android {
defaultConfig {
minSdkVersion 29
targetSdkVersion 33
versionCode 193
versionName "0.26.0.0002"
versionCode 196
versionName "0.26.0.0004"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,27 @@ class CarStatsViewer : Application() {

val layout = LayoutInflater.from(context).inflate(R.layout.dialog_changelog, null)

val changelog4Title = layout.findViewById<TextView>(R.id.changes_0_26_0_title)
val changelog4TextView = layout.findViewById<TextView>(R.id.changes_0_26_0)
val changelog3Title = layout.findViewById<TextView>(R.id.changes_0_25_2_title)
val changelog3TextView = layout.findViewById<TextView>(R.id.changes_0_25_2)
val changelog2Title = layout.findViewById<TextView>(R.id.changes_0_25_1_title)
val changelog2TextView = layout.findViewById<TextView>(R.id.changes_0_25_1)
val changelog1Title = layout.findViewById<TextView>(R.id.changes_0_25_0_title)
val changelog1TextView = layout.findViewById<TextView>(R.id.changes_0_25_0)

changelog4Title.text = context.getString(R.string.main_changelog_dialog_title, "0.26.0")
changelog3Title.text = context.getString(R.string.main_changelog_dialog_title, "0.25.2")
changelog2Title.text = context.getString(R.string.main_changelog_dialog_title, "0.25.1")
changelog1Title.text = context.getString(R.string.main_changelog_dialog_title, "0.25.0")

val changesArray4 = context.resources.getStringArray(R.array.changes_0_26_0)
var changelog4 = ""
changesArray4.forEachIndexed { index, change ->
changelog4 += "$change"
if (index < changesArray4.size - 1) changelog4 += "\n\n"
}

val changesArray3 = context.resources.getStringArray(R.array.changes_0_25_2)
var changelog3 = ""
changesArray3.forEachIndexed { index, change ->
Expand All @@ -150,6 +160,7 @@ class CarStatsViewer : Application() {
if (index < changesArray1.size - 1) changelog1 += "\n\n"
}

changelog4TextView.text = changelog4
changelog3TextView.text = changelog3
changelog2TextView.text = changelog2
changelog1TextView.text = changelog1
Expand Down Expand Up @@ -201,7 +212,7 @@ class CarStatsViewer : Application() {
InAppLogger.i("${appContext.getString(R.string.app_name)} v${BuildConfig.VERSION_NAME} started")

InAppLogger.d("Screen width: ${resources.configuration.screenWidthDp}dp")

/*
CoroutineScope(Dispatchers.IO).launch {
InAppLogger.i("Available OEM fonts:")
Expand Down Expand Up @@ -242,6 +253,10 @@ class CarStatsViewer : Application() {
fontsLoaded = true
}
*/
fontsLoaded = true
MultiButtonWidget.isPolestar = true

// while (!fontsLoaded) {
// // Wait for fonts to be loaded before initializing trip database
// }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import com.ixam97.carStatsViewer.utils.setContentViewAndTheme
import kotlinx.android.synthetic.main.activity_history.*
import kotlinx.coroutines.*
import java.util.*
import kotlin.math.ceil
import kotlin.math.min
import kotlin.math.roundToInt

class HistoryActivity : FragmentActivity() {

Expand Down Expand Up @@ -384,8 +387,9 @@ class HistoryActivity : FragmentActivity() {
}

private fun uploadDatabase() {
val chunkSize = 250
CoroutineScope(Dispatchers.IO).launch {
val waitSnack = SnackbarWidget.Builder(this@HistoryActivity, "Upload in progress...")
val waitSnack = SnackbarWidget.Builder(this@HistoryActivity, "Upload in progress, 0%")
.build()
runOnUiThread {
this@HistoryActivity.window.findViewById<FrameLayout>(android.R.id.content).addView(waitSnack)
Expand All @@ -395,12 +399,57 @@ class HistoryActivity : FragmentActivity() {
val chargingSessions = CarStatsViewer.tripDataSource.getAllChargingSessions()
InAppLogger.i("[HIST] Done loading ${chargingSessions.size} charging sessions")

val drivingPointsChunks = ceil(drivingPoints.size.toFloat() / chunkSize).roundToInt()
InAppLogger.i("Divided ${drivingPoints.size} driving points into to $drivingPointsChunks chunks")
val chargingSessionsSize = chargingSessions.size
val totalParts = drivingPointsChunks + chargingSessionsSize

var result: LiveDataApi.ConnectionStatus? = null

for (i in 0 until drivingPointsChunks) {
result = (CarStatsViewer.liveDataApis[1] as HttpLiveData).sendWithDrivingPoint(
CarStatsViewer.dataProcessor.realTimeData,
drivingPoints.slice(chunkSize * i..min(chunkSize * (i+1), drivingPoints.size - 1))
)
val percentage = (((i + 1).toFloat() / totalParts) * 100).roundToInt()
if (result == LiveDataApi.ConnectionStatus.CONNECTED) {
InAppLogger.v("Chunk $i transferred, $percentage%")
runOnUiThread {
waitSnack.updateMessage("Upload in progress, $percentage%")
waitSnack.setProgressBarPercent(percentage)
}
} else {
InAppLogger.e("Chunk $i failed..")
break
}
}

for (i in 0 until chargingSessionsSize) {
result = (CarStatsViewer.liveDataApis[1] as HttpLiveData).sendWithDrivingPoint(
CarStatsViewer.dataProcessor.realTimeData,
chargingSessions = chargingSessions.slice(setOf(i))
)
val percentage = (((i + 1 + drivingPointsChunks).toFloat() / totalParts) * 100).roundToInt()
if (result == LiveDataApi.ConnectionStatus.CONNECTED) {
InAppLogger.v("Charging session $i transferred, $percentage%")
runOnUiThread {
waitSnack.updateMessage("Upload in progress, $percentage%")
waitSnack.setProgressBarPercent(percentage)
}
} else {
InAppLogger.e("Charging session $i failed..")
break
}
}
/*
val result = (CarStatsViewer.liveDataApis[1] as HttpLiveData).sendWithDrivingPoint(
CarStatsViewer.dataProcessor.realTimeData,
drivingPoints,
chargingSessions
)
*/

runOnUiThread {
this@HistoryActivity.window.findViewById<FrameLayout>(android.R.id.content).removeView(waitSnack)
when (result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,26 +491,26 @@ class MainActivity : FragmentActivity() {
when (secondaryConsumptionDimension) {
1 -> {
main_button_secondary_dimension.text = getString(R.string.main_secondary_axis, getString(R.string.main_speed))
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.TOP, R.id.main_image_button_speed, ConstraintSet.TOP)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.BOTTOM, R.id.main_image_button_speed, ConstraintSet.BOTTOM)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.LEFT, R.id.main_image_button_speed, ConstraintSet.LEFT)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.RIGHT, R.id.main_image_button_speed, ConstraintSet.RIGHT)
main_secondary_dimension_indicator.isVisible = true
}
2 -> {
main_button_secondary_dimension.text = getString(R.string.main_secondary_axis, getString(R.string.main_SoC))
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.TOP, R.id.main_image_button_soc, ConstraintSet.TOP)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.BOTTOM, R.id.main_image_button_soc, ConstraintSet.BOTTOM)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.LEFT, R.id.main_image_button_soc, ConstraintSet.LEFT)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.RIGHT, R.id.main_image_button_soc, ConstraintSet.RIGHT)
main_secondary_dimension_indicator.isVisible = true
}
3 -> {
main_button_secondary_dimension.text = getString(R.string.main_secondary_axis, getString(R.string.plot_dimensionY_ALTITUDE))
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.TOP, R.id.main_image_button_alt, ConstraintSet.TOP)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.BOTTOM, R.id.main_image_button_alt, ConstraintSet.BOTTOM)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.LEFT, R.id.main_image_button_alt, ConstraintSet.LEFT)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.RIGHT, R.id.main_image_button_alt, ConstraintSet.RIGHT)
main_secondary_dimension_indicator.isVisible = true
}
else -> {
main_button_secondary_dimension.text = getString(R.string.main_secondary_axis, "-")
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.TOP, R.id.main_image_button_speed, ConstraintSet.BOTTOM)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.BOTTOM, R.id.main_image_button_speed, ConstraintSet.BOTTOM)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.LEFT, R.id.main_image_button_speed, ConstraintSet.RIGHT)
constraintSet.connect(R.id.main_secondary_dimension_indicator, ConstraintSet.RIGHT, R.id.main_image_button_speed, ConstraintSet.RIGHT)
main_secondary_dimension_indicator.visibility = View.GONE
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.ixam97.carStatsViewer.R
import com.ixam97.carStatsViewer.utils.InAppLogger
import com.ixam97.carStatsViewer.utils.applyTypeface
import kotlinx.android.synthetic.main.widget_snackbar.view.*
import kotlin.math.roundToInt


class SnackbarWidget private constructor(
Expand All @@ -33,7 +34,7 @@ class SnackbarWidget private constructor(
): LinearLayout(context, attrs, defStyleAttr) {

private data class SnackbarParameters(
val message: String,
var message: String,
val buttonText: String? = null,
val drawableId: Int? = null,
val startHidden: Boolean = false,
Expand Down Expand Up @@ -98,6 +99,21 @@ class SnackbarWidget private constructor(
private val startIcon: ImageView
private val progressBar: View

fun updateMessage(message: String) {
snackbarParameters.message = message
messageText.text = snackbarParameters.message
}

fun setProgressBarPercent(percent: Int) {
val maxWidth = this@SnackbarWidget.measuredWidth
val onePercent = maxWidth.toFloat() / 100
val newWidth = onePercent * percent

val layoutParams = progress_bar.layoutParams
layoutParams.width = newWidth.roundToInt()
progressBar.layoutParams = layoutParams
}

private fun removeSelf() {
val anim = AnimationUtils.loadAnimation(context, R.anim.snackbar_down)
anim.setAnimationListener(object: AnimationListener{
Expand Down Expand Up @@ -137,37 +153,43 @@ class SnackbarWidget private constructor(

if (snackbarParameters.isError) {
(progressBar.parent as ViewGroup).setBackgroundColor(context.getColor(R.color.bad_red_dark))
messageText.setTextColor(context.getColor(android.R.color.white))
progressBar.setBackgroundColor(context.getColor(R.color.bad_red))
startIcon.setImageResource(R.drawable.ic_error)
startIcon.setColorFilter(context.getColor(android.R.color.white))
}

snackbarParameters.drawableId?.let {
startIcon.setImageResource(snackbarParameters.drawableId)
}

val anim = AnimationUtils.loadAnimation(context, R.anim.snackbar_up)
anim.setAnimationListener(object: AnimationListener{
override fun onAnimationStart(animation: Animation?) {}
override fun onAnimationEnd(animation: Animation?) {
if (snackbarParameters.duration > 0) {
Handler(Looper.getMainLooper()).postDelayed({
removeSelf()
}, snackbarParameters.duration)
}
val widthAnimator = ValueAnimator.ofInt(1, this@SnackbarWidget.measuredWidth)
widthAnimator.duration = snackbarParameters.duration
widthAnimator.interpolator = LinearInterpolator()
widthAnimator.addUpdateListener { barAnimation ->
val layoutParams = progress_bar.layoutParams
layoutParams.width = barAnimation.animatedValue as Int
progressBar.layoutParams = layoutParams

if (snackbarParameters.duration > 0) {
anim.setAnimationListener(object : AnimationListener {
override fun onAnimationStart(animation: Animation?) {}
override fun onAnimationEnd(animation: Animation?) {
if (snackbarParameters.duration > 0) {
Handler(Looper.getMainLooper()).postDelayed({
removeSelf()
}, snackbarParameters.duration)
}
val widthAnimator = ValueAnimator.ofInt(1, this@SnackbarWidget.measuredWidth)
widthAnimator.duration = snackbarParameters.duration
widthAnimator.interpolator = LinearInterpolator()
widthAnimator.addUpdateListener { barAnimation ->
val layoutParams = progress_bar.layoutParams
layoutParams.width = barAnimation.animatedValue as Int
progressBar.layoutParams = layoutParams
}
widthAnimator.start()
}
widthAnimator.start()
}
override fun onAnimationRepeat(animation: Animation?) {}

})
this.startAnimation(anim)
override fun onAnimationRepeat(animation: Animation?) {}

})
this.startAnimation(anim)
}

applyTypeface(this)
}
Expand Down
Loading

0 comments on commit b0c08cb

Please sign in to comment.