Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing Things #14

Merged
merged 13 commits into from
Mar 25, 2022
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ android {
applicationId "com.katiearose.sobriety"
minSdk 30
targetSdk 30
versionCode 7
versionName "v3.0.0"
versionCode 8
versionName "v4.0.0"
setProperty("archivesBaseName", "Sobriety $versionName")
}

Expand Down
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
android:theme="@style/Theme.Sobriety">
<activity
android:name=".Create"
android:windowSoftInputMode="adjustResize"
android:exported="false" />
android:exported="false"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".Main"
android:exported="true"
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/katiearose/sobriety/Addiction.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.katiearose.sobriety

import java.io.Serializable
import java.time.Instant

class Addiction(val name: String, var lastRelapse: Instant) : Serializable {
var averageRelapseDuration = 0L
private var relapses = 0

fun relapse() {
relapses++
averageRelapseDuration = calculateAverageRelapseDuration(Main.timeSinceInstant(lastRelapse))
lastRelapse = Instant.now()
}

private fun calculateAverageRelapseDuration(new: Long): Long =
((averageRelapseDuration * (relapses - 1)) + new) / relapses
}
8 changes: 6 additions & 2 deletions app/src/main/java/com/katiearose/sobriety/CircularBuffer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package com.katiearose.sobriety

import java.io.Serializable


class CircularBuffer<T>(size: Int) : Serializable {
@Deprecated(
"For old caches before the implementation of the Addiction class.",
ReplaceWith("N/A"),
DeprecationLevel.WARNING
)
internal class CircularBuffer<T>(size: Int) : Serializable {
private val buffer: ArrayList<T?> = ArrayList(size)

init {
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/java/com/katiearose/sobriety/Create.kt
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,12 @@ class Create : AppCompatActivity() {

//Don't allow creating without a name, or with a duplicate name
if (name == "" || nameExists) {
if (nameExists){
Snackbar.make(findViewById(R.id.clCreate),"Can't create duplicate entries", Snackbar.LENGTH_SHORT).show()
if (nameExists) {
Snackbar.make(
findViewById(R.id.clCreate),
"Can't create duplicate entries",
Snackbar.LENGTH_SHORT
).show()
}
val animationShake =
AnimationUtils.loadAnimation(this, R.anim.shake)
Expand Down
107 changes: 46 additions & 61 deletions app/src/main/java/com/katiearose/sobriety/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,26 @@ class Main : AppCompatActivity() {

companion object {
const val EXTRA_NAMES = "com.katiearose.sobriety.EXTRA_NAMES"
fun secondsToString(given: Long): String {
var time = given
val s = time % 60
time -= s
val m = (time % 3600) / 60
time -= m * 60
val h = (time % 86400) / 3600
time -= h * 3600
val d = time / 86400
return "$d days, $h hours, $m minutes and $s seconds"
}

fun timeSinceInstant(given: Instant) = Instant.now().epochSecond - given.epochSecond
}

private lateinit var addCardButton: FloatingActionButton
private lateinit var cardHolder: LinearLayout
private lateinit var prompt: TextView

private val addictions = HashMap<String, Pair<Instant, CircularBuffer<Long>>>()
private val addictions = ArrayList<Addiction>()
private val createCardRequestCode = 1

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -70,16 +83,14 @@ class Main : AppCompatActivity() {
//Pass current addiction names to create activity, to prevent creation of elements with identical keys
val addictionNames = arrayListOf<String>()
addictions.forEach {
addictionNames.add(it.key)
addictionNames.add(it.name)
}
val intent = Intent(this, Create::class.java)
intent.putStringArrayListExtra(EXTRA_NAMES, addictionNames)
startActivityForResult(intent, createCardRequestCode)
}

private fun createNewCard(input: Triple<String, Instant, CircularBuffer<Long>>) {
val name = input.first
var date = input.second
private fun createNewCard(addiction: Addiction) {
val params = RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
Expand All @@ -95,50 +106,44 @@ class Main : AppCompatActivity() {
cardView.cardElevation = 30f
val title = TextView(this)
title.textSize = 24F
title.text = name
title.text = addiction.name
title.textAlignment = TextView.TEXT_ALIGNMENT_CENTER
val timeRunning = TextView(this)
timeRunning.textSize = 16F
timeRunning.text = secondsToString(timeSinceInstant(date))
val averageOfLastThree = TextView(this)
averageOfLastThree.textSize = 12F
val buffer = input.third

averageOfLastThree.text = "Recent Average: ${secondsToString(averageFromBuffer(buffer))}"
timeRunning.text = secondsToString(timeSinceInstant(addiction.lastRelapse))
val average = TextView(this)
average.textSize = 12F
average.text = "Average: ${secondsToString(addiction.averageRelapseDuration)}"
val buttons = LinearLayout(this)
buttons.orientation = LinearLayout.HORIZONTAL
val resetButton = Button(this)
resetButton.text = "Reset"
val deleteButton = Button(this)
deleteButton.text = "Delete"
var deleted = false

deleteButton.setOnClickListener {
val action: () -> Unit = {
cardHolder.removeView(cardView)
addictions.remove(name)
deleted = true
addictions.remove(addiction)
updatePromptVisibility()
}
dialogConfirm("Delete entry \"$name\" ?", action)
dialogConfirm("Delete entry \"${addiction.name}\" ?", action)
}

resetButton.setOnClickListener {
val action: () -> Unit = {
buffer.update(timeSinceInstant(date))
date = Instant.now()

averageOfLastThree.text =
"Recent Average: ${secondsToString(averageFromBuffer(buffer))}"
addiction.relapse()
average.text =
"Average: ${secondsToString(addiction.averageRelapseDuration)}"
}
dialogConfirm("Reset entry \"$name\" ?", action)
dialogConfirm("Reset entry \"${addiction.name}\" ?", action)
}

val cardLinearLayout = LinearLayout(this)
cardLinearLayout.orientation = LinearLayout.VERTICAL
cardLinearLayout.addView(title)
cardLinearLayout.addView(timeRunning)
cardLinearLayout.addView(averageOfLastThree)
cardLinearLayout.addView(average)
buttons.addView(resetButton)
buttons.addView(deleteButton)
cardLinearLayout.addView(buttons)
Expand All @@ -147,8 +152,11 @@ class Main : AppCompatActivity() {
val mainHandler = Handler(Looper.getMainLooper())
mainHandler.postDelayed(object : Runnable {
override fun run() {
timeRunning.text = secondsToString(timeSinceInstant(date))
if (!deleted) mainHandler.postDelayed(this, 1000L)
if (!addictions.contains(addiction)) {
return
}
timeRunning.text = secondsToString(timeSinceInstant(addiction.lastRelapse))
mainHandler.postDelayed(this, 1000L)
}
}, 1000L)
}
Expand All @@ -175,32 +183,34 @@ class Main : AppCompatActivity() {
try {
InflaterInputStream(cache.inputStream()).use { iis ->
ObjectInputStream(iis).use {
addictions.putAll(it.readObject() as HashMap<String, Pair<Instant, CircularBuffer<Long>>>)
addictions.addAll(it.readObject() as ArrayList<Addiction>)
}
}
for (addiction in addictions) {
createNewCard(Triple(addiction.key, addiction.value.first, addiction.value.second))
createNewCard(addiction)
}
} catch (e: ClassCastException) {
readLegacyCache(cache.inputStream())
readCache(cache.inputStream())
}
}

@Deprecated(
"For old caches without buffers.",
"For old caches before the implementation of the Addiction class.",
ReplaceWith("readCache(FileInputStream)"),
DeprecationLevel.WARNING
)
private fun readLegacyCache(input: InputStream) {
val a = HashMap<String, Pair<Instant, CircularBuffer<Long>>>()
InflaterInputStream(input).use { iis ->
ObjectInputStream(iis).use {
for (i in it.readObject() as HashMap<String, Instant>) {
addictions[i.key] = Pair(i.value, CircularBuffer(3))
for (i in it.readObject() as HashMap<String, Pair<Instant, CircularBuffer<Long>>>) {
a[i.key] = i.value
}
}
}
for (addiction in addictions) {
createNewCard(Triple(addiction.key, addiction.value.first, addiction.value.second))
for (ad in a) {
val addiction = Addiction(ad.key, ad.value.first)
createNewCard(addiction)
}
}

Expand All @@ -214,19 +224,6 @@ class Main : AppCompatActivity() {
}
}

private fun secondsToString(given: Long): String {
var time = given
val s = time % 60
time -= s
val m = (time % 3600) / 60
time -= m * 60
val h = (time % 86400) / 3600
time -= h * 3600
val d = time / 86400
return "$d days, $h hours, $m minutes and $s seconds"
}

private fun timeSinceInstant(given: Instant) = Instant.now().epochSecond - given.epochSecond

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Expand All @@ -249,22 +246,10 @@ class Main : AppCompatActivity() {
if (resultCode == RESULT_OK) {
val name = data?.extras?.get("name") as String
val instant = data.extras?.get("instant") as Instant
val buffer = CircularBuffer<Long>(3)
addictions[name] = Pair(instant, buffer)
createNewCard(Triple(name, instant, buffer))
}
}
}

private fun averageFromBuffer(buffer: CircularBuffer<Long>): Long {
var num = 0
var total: Long = 0
for (i in 0..2) {
buffer.get(i)?.let {
total += it
num++
val addiction = Addiction(name, instant)
addictions.add(addiction)
createNewCard(addiction)
}
}
return if (num != 0) total / num else 0
}
}
2 changes: 1 addition & 1 deletion app/src/main/res/layout/activity_create.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/clCreate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/clCreate"
tools:context=".Create">


Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
android:clickable="true"
android:translationX="-30dp"
android:translationY="-30dp"
app:tint="@android:color/white"
app:layout_anchor="@+id/frameLayout"
app:layout_anchorGravity="end|bottom"
app:srcCompat="@android:drawable/ic_input_add" />
app:srcCompat="@android:drawable/ic_input_add"
app:tint="@android:color/white" />

<TextView
android:id="@+id/prompt"
Expand Down
3 changes: 3 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
New Class!
- A new class was added to better store data
- Average is now a running average and not just of the last three relapses
Binary file modified fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.