Skip to content
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion PainTracker/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
android:theme="@style/Theme.PainTracker"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".ui.MainActivity"
android:exported="true"
android:theme="@style/Theme.PainTracker">
<intent-filter>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package com.example.paintracker
import android.content.Context
import com.example.paintracker.interfaces.IBitmapLoaderService
import com.example.paintracker.interfaces.IConfigService
import com.example.paintracker.interfaces.IPainContext
import com.example.paintracker.interfaces.IPathService
import com.example.paintracker.interfaces.IVisualiserLayerIoService
import com.example.paintracker.services.BitmapLoaderService
import com.example.paintracker.services.ConfigService
import com.example.paintracker.data.PainContext
import com.example.paintracker.interfaces.INotesIoService
import com.example.paintracker.services.NotesIoService
import com.example.paintracker.services.PathService
import com.example.paintracker.services.VisualiserLayerIoService
import dagger.Module
Expand Down Expand Up @@ -47,4 +51,16 @@ object ServiceModule {
fun provideBitmapLoaderService(): IBitmapLoaderService {
return BitmapLoaderService()
}

@Provides
@Singleton
fun providePainContext(): IPainContext {
return PainContext()
}

@Provides
@Singleton
fun provideNotesIoService(pathService: IPathService): INotesIoService {
return NotesIoService(pathService)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.paintracker.base

open class Observable {
private val listeners = mutableListOf<(String, Any?, Any?) -> Unit>()

fun addChangeListener(listener: (propertyName: String, oldValue: Any?, newValue: Any?) -> Unit) {
listeners.add(listener)
}

fun removeChangeListener(listener: (propertyName: String, oldValue: Any?, newValue: Any?) -> Unit) {
listeners.remove(listener)
}

protected fun notifyListeners(propertyName: String, oldValue: Any?, newValue: Any?) {
listeners.forEach { it(propertyName, oldValue, newValue) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.paintracker.data

import com.example.paintracker.base.Observable
import com.example.paintracker.interfaces.IPainContext
import java.time.LocalDate
import kotlin.properties.Delegates

class PainContext : Observable(), IPainContext {
override var selectedDate: LocalDate by Delegates.observable(LocalDate.now()) { _, oldValue, newValue ->
notifyListeners("selectedDate", oldValue, newValue)
}

override var showAllLayers: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
notifyListeners("showAllLayers", oldValue, newValue)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.paintracker.interfaces

import java.time.LocalDate

interface INotesIoService {
fun loadNotes(date: LocalDate): String?
fun saveNotes(date: LocalDate, notes: String)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.paintracker.interfaces

import java.time.LocalDate

interface IPainContext {
var selectedDate: LocalDate
var showAllLayers: Boolean
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.example.paintracker.interfaces

import android.content.Context
import com.example.paintracker.data.VisualiserLayer
import java.nio.file.Path
import java.time.LocalDate

enum class Path {
enum class SpecialPath {
APPDATAROOT
}

interface IPathService {
fun initialize(context: Context)
fun getPath(path: Path): String
fun getPath(path: SpecialPath): String
fun getVisualLayerPath(date: LocalDate, layer: VisualiserLayer) : Path
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ interface IVisualiserLayerIoService {
fun loadAll(localDate: LocalDate, layers: MutableList<VisualiserLayer>, width: Int, height: Int)
fun saveLayer(localDate: LocalDate, layer: VisualiserLayer, side: Side)
fun deleteLayer(localDate: LocalDate, layer: VisualiserLayer, side: Side)
fun deleteLayers(localDate: LocalDate, layers: MutableList<VisualiserLayer>)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.example.paintracker.services

import com.example.paintracker.interfaces.INotesIoService
import com.example.paintracker.interfaces.IPathService
import com.example.paintracker.interfaces.SpecialPath
import java.io.File
import java.nio.file.Paths
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import javax.inject.Inject

class NotesIoService @Inject constructor(
private val pathService: IPathService
) : INotesIoService {

override fun loadNotes(date: LocalDate): String? {
val dataRoot = pathService.getPath(SpecialPath.APPDATAROOT)
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val datePart = date.format(formatter)
val datePath = Paths.get(dataRoot).resolve(datePart)
val notesPath = datePath.resolve("notes.txt")
val notes = File(notesPath.toString())
if (notes.exists()) {
val fileContents = notes.readText()
return fileContents
}
else {
return null
}
}

override fun saveNotes(date: LocalDate, notes: String) {
val dataRoot = pathService.getPath(SpecialPath.APPDATAROOT)
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val datePart = date.format(formatter)
val datePath = Paths.get(dataRoot).resolve(datePart)
val notesPath = datePath.resolve("notes.txt")
val notesDirectory = datePath.toFile()
if (!notesDirectory.exists()) {
notesDirectory.mkdirs()
}

File(notesPath.toString()).writeText(notes)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.example.paintracker.services

import android.content.Context
import com.example.paintracker.data.VisualiserLayer
import com.example.paintracker.interfaces.IPathService
import com.example.paintracker.interfaces.Path
import com.example.paintracker.interfaces.SpecialPath
import java.nio.file.Path
import java.nio.file.Paths
import java.time.LocalDate
import java.time.format.DateTimeFormatter

class PathService : IPathService {
private lateinit var _context: Context
Expand All @@ -12,9 +16,18 @@ class PathService : IPathService {
_context = context
}

override fun getPath(path: Path): String {
override fun getPath(path: SpecialPath): String {
return when (path) {
Path.APPDATAROOT -> Paths.get(_context.filesDir.absolutePath, "data").toString()
SpecialPath.APPDATAROOT -> Paths.get(_context.filesDir.absolutePath, "data").toString()
}
}

override fun getVisualLayerPath(date: LocalDate, layer: VisualiserLayer) : Path {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val datePart = date.format(formatter)
val dataRoot = getPath(SpecialPath.APPDATAROOT)
val datePath = Paths.get(dataRoot).resolve(datePart)
val layerPath = datePath.resolve(layer.painCategory?.id)
return layerPath
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ import com.example.paintracker.data.VisualiserLayer
import com.example.paintracker.interfaces.IBitmapLoaderService
import com.example.paintracker.interfaces.IPathService
import com.example.paintracker.interfaces.IVisualiserLayerIoService
import com.example.paintracker.interfaces.Path
import com.example.paintracker.interfaces.Side
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Paths
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import javax.inject.Inject
Expand All @@ -24,16 +22,13 @@ class VisualiserLayerIoService @Inject constructor(
private val bitmapLoaderService: IBitmapLoaderService
) : IVisualiserLayerIoService {

private val dataRoot: String by lazy { pathService.getPath(Path.APPDATAROOT) }

override fun loadAll(localDate: LocalDate, layers: MutableList<VisualiserLayer>, width: Int, height: Int) {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val datePart = localDate.format(formatter)
Log.i("VisualiserLayerIoService", "Loading all images for '${datePart}', width = ${width}, height = ${height}.")

val datePath = Paths.get(dataRoot).resolve(datePart)
for (visualLayer in layers) {
val layerPath = datePath.resolve(visualLayer.painCategory?.id)
val layerPath = pathService.getVisualLayerPath(localDate, visualLayer)
val frontPath = layerPath.resolve("front.png")
val backPath = layerPath.resolve("back.png")

Expand All @@ -44,21 +39,18 @@ class VisualiserLayerIoService @Inject constructor(

if(frontPath.exists()) {
Log.i("VisualiserLayerIoService","Loading front image '${frontPath.parent}'")
visualLayer.frontDrawing = BitmapFactory.decodeFile(frontPath.toString())
visualLayer.frontDrawing = BitmapFactory.decodeFile(frontPath.toString()) // bitmapLoaderService.loadBitmap(frontPath.toString(), width, height)
}

if(backPath.exists()) {
Log.i("VisualiserLayerIoService","Loading back image '${backPath.parent}'")
visualLayer.backDrawing = BitmapFactory.decodeFile(backPath.toString())
visualLayer.backDrawing = BitmapFactory.decodeFile(backPath.toString()) // bitmapLoaderService.loadBitmap(backPath.toString(), width, height)
}
}
}

override fun saveLayer(localDate: LocalDate, layer: VisualiserLayer, side: Side) {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val datePart = localDate.format(formatter)
val datePath = Paths.get(dataRoot).resolve(datePart)
val layerPath = datePath.resolve(layer.painCategory?.id)
val layerPath = pathService.getVisualLayerPath(localDate, layer)
val frontPath = layerPath.resolve("front.png")
val backPath = layerPath.resolve("back.png")
val path = if (side == Side.FRONT) frontPath else backPath
Expand All @@ -74,10 +66,7 @@ class VisualiserLayerIoService @Inject constructor(
}

override fun deleteLayer(localDate: LocalDate, layer: VisualiserLayer, side: Side) {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
val datePart = localDate.format(formatter)
val datePath = Paths.get(dataRoot).resolve(datePart)
val layerPath = datePath.resolve(layer.painCategory?.id)
val layerPath = pathService.getVisualLayerPath(localDate, layer)
val frontPath = layerPath.resolve("front.png")
val backPath = layerPath.resolve("back.png")
val path = if (side == Side.FRONT) frontPath else backPath
Expand All @@ -94,6 +83,18 @@ class VisualiserLayerIoService @Inject constructor(
}
}

override fun deleteLayers(localDate: LocalDate, layers: MutableList<VisualiserLayer>) {
for (visualLayer in layers) {
val layerPath = pathService.getVisualLayerPath(localDate, visualLayer)
val frontPath = layerPath.resolve("front.png")
val backPath = layerPath.resolve("back.png")
Files.deleteIfExists(frontPath)
Files.deleteIfExists(backPath)
visualLayer.frontDrawing = null
visualLayer.backDrawing = null
}
}

private fun saveBitmapToFile(bitmap: Bitmap, path: String) {
val file = File(path)
try {
Expand Down
Loading
Loading