diff --git a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportCommemorativePhotosTest.kt b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportCommemorativePhotosTest.kt index 525395a..2932332 100644 --- a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportCommemorativePhotosTest.kt +++ b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportCommemorativePhotosTest.kt @@ -37,7 +37,7 @@ internal class ReportCommemorativePhotosTest : ReportAbstractTest() { treasuresProgress.commemorativePhotosByTreasuresDescriptionIds.put(2, tempPhoto(600, 600)) StorageHelper(context).save(Route(treasuresProgress.routeName)) - model.initialize(treasuresProgress, context) + model.initialize(context, null, treasuresProgress) val reportPhotos = ReportCommemorativePhotos(model, font, seed) //when @@ -59,7 +59,7 @@ internal class ReportCommemorativePhotosTest : ReportAbstractTest() { treasuresProgress.commemorativePhotosByTreasuresDescriptionIds.put(2, tempPhoto(600, 600)) treasuresProgress.commemorativePhotosByTreasuresDescriptionIds.put(3, tempPhoto(400, 800)) treasuresProgress.commemorativePhotosByTreasuresDescriptionIds.put(4, tempPhoto(600, 500)) - model.initialize(treasuresProgress, context) + model.initialize(context, null, treasuresProgress) val reportPhotos = ReportCommemorativePhotos(model, font, seed) //when diff --git a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportGeneratorTest.kt b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportGeneratorTest.kt index 5203b61..36a8e55 100644 --- a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportGeneratorTest.kt +++ b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportGeneratorTest.kt @@ -9,6 +9,7 @@ import androidx.test.platform.app.InstrumentationRegistry import org.junit.Test import org.junit.runner.RunWith import pl.marianjureczko.poszukiwacz.activity.treasureselector.Coordinates +import pl.marianjureczko.poszukiwacz.model.HunterPath import pl.marianjureczko.poszukiwacz.model.Route import pl.marianjureczko.poszukiwacz.model.Treasure import pl.marianjureczko.poszukiwacz.model.TreasureType @@ -33,14 +34,15 @@ class ReportGeneratorTest { treasuresProgress.commemorativePhotosByTreasuresDescriptionIds.put(3, photos[2]) treasuresProgress.commemorativePhotosByTreasuresDescriptionIds.put(13, photos[4]) treasuresProgress.commemorativePhotosByTreasuresDescriptionIds.put(0, photos[5]) - treasuresProgress.hunterPath.addLocation(Coordinates(10.0, 10.0), Date(1)) - treasuresProgress.hunterPath.addLocation(Coordinates(10.0, 11.0), Date(1_000_000)) - treasuresProgress.hunterPath.addLocation(Coordinates(10.0, 11.0), Date(2_000_000)) + val hunterPath = HunterPath() + hunterPath.addLocation(Coordinates(10.0, 10.0), Date(1)) + hunterPath.addLocation(Coordinates(10.0, 11.0), Date(1_000_000)) + hunterPath.addLocation(Coordinates(10.0, 11.0), Date(2_000_000)) StorageHelper(context).save(Route(treasuresProgress.routeName)) //when val model = FacebookViewModel(SavedStateHandle(mapOf())) - model.initialize(treasuresProgress, context) + model.initialize(context, hunterPath, treasuresProgress) //MapBox doesn't work in tests model.getMap()?.isSelected = false val actual = report.create(context, model) { diff --git a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapHeaderTest.kt b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapHeaderTest.kt index 2f5169a..edfd008 100644 --- a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapHeaderTest.kt +++ b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapHeaderTest.kt @@ -19,7 +19,7 @@ class ReportMapHeaderTest : ReportAbstractTest() { val bitmap = Bitmap.createBitmap(ReportCommons.REPORT_WIDTH, 200, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) canvas.drawColor(Color.WHITE) - model.initialize(treasuresProgress, context) + model.initialize(context, null, treasuresProgress) //when reportMapHeader.draw(context, canvas, 0f) diff --git a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummaryTest.kt b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummaryTest.kt index 40abf42..6ba52e2 100644 --- a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummaryTest.kt +++ b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummaryTest.kt @@ -8,6 +8,7 @@ import junit.framework.TestCase import org.junit.Test import org.junit.runner.RunWith import pl.marianjureczko.poszukiwacz.activity.treasureselector.Coordinates +import pl.marianjureczko.poszukiwacz.model.HunterPath import java.io.File import java.util.Date @@ -22,10 +23,11 @@ class ReportMapSummaryTest : ReportAbstractTest() { val bitmap = Bitmap.createBitmap(ReportCommons.REPORT_WIDTH, 200, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) canvas.drawColor(Color.WHITE) - treasuresProgress.hunterPath.addLocation(Coordinates(10.0, 10.0), Date(1)) - treasuresProgress.hunterPath.addLocation(Coordinates(10.0, 11.0), Date(1_000_000)) - treasuresProgress.hunterPath.addLocation(Coordinates(10.0, 11.0), Date(2_000_000)) - model.initialize(treasuresProgress, context) + val hunterPath = HunterPath() + hunterPath.addLocation(Coordinates(10.0, 10.0), Date(1)) + hunterPath.addLocation(Coordinates(10.0, 11.0), Date(1_000_000)) + hunterPath.addLocation(Coordinates(10.0, 11.0), Date(2_000_000)) + model.initialize(context, hunterPath, treasuresProgress) //when reportMapHeader.draw(context, canvas, 0f) diff --git a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportSummaryTest.kt b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportSummaryTest.kt index bcf8653..42d174e 100644 --- a/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportSummaryTest.kt +++ b/app/src/androidTest/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportSummaryTest.kt @@ -25,7 +25,7 @@ internal class ReportSummaryTest : ReportAbstractTest() { val treasure = Treasure("1", 17, TreasureType.GOLD) treasuresProgress.collect(treasure) - model.initialize(treasuresProgress, context) + model.initialize(context, null, treasuresProgress) //when reportSummary.draw(context, canvas, 0f) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 545f375..9431e03 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,7 +56,9 @@ + android:exported="false" + android:theme="@style/FullscreenTheme" + /> + android:label="@string/photo_tip" + android:theme="@style/FullscreenTheme" + /> + android:theme="@style/AppTheme" /> = registerForActivityResult(ActivityResultContracts.TakePicture()) { result -> + private val doPhotoLauncher: ActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.TakePicture()) { result -> if (result) { photoHelper.moveCommemorativePhotoToPermanentLocation(target = model.commemorativePhotoAbsolutePath) reloadImage(model.commemorativePhotoUri()) @@ -58,7 +60,7 @@ class CommemorativeActivity : ActivityWithAdsAndBackButton() { setUpAds(binding.adView) } - override fun getCurrentTreasuresProgress(): TreasuresProgress? = model.progress + override fun getTreasureProgress(): TreasuresProgress? = model.progress private fun rotatePhoto(photoFullPath: String, uri: Uri) { lifecycleScope.launch { diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookActivity.kt index 6b7c414..3aec35f 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookActivity.kt @@ -12,7 +12,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.facebook.CallbackManager import com.facebook.FacebookCallback import com.facebook.FacebookException -import com.facebook.FacebookSdk import com.facebook.share.Sharer import com.facebook.share.model.SharePhoto import com.facebook.share.model.SharePhotoContent @@ -36,7 +35,7 @@ class FacebookActivity : PermissionActivity() { private val model: FacebookViewModel by viewModels() companion object { - const val TREASURE_PROGRESS = "pl.marianjureczko.poszukiwacz.activity.facebook_treasure_progress" + const val INPUT = "pl.marianjureczko.poszukiwacz.activity.input" const val STORAGE_DO_NOT_REQUIRE_PERMISSONS = Build.VERSION_CODES.Q private val xmlHelper = XmlHelper() } @@ -48,11 +47,8 @@ class FacebookActivity : PermissionActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT - - model.initialize( - progress = xmlHelper.loadFromString(intent.getStringExtra(TREASURE_PROGRESS)!!), - this - ) + val input = intent.getSerializableExtra(INPUT) as FacebookInputData + model.initialize(this, hunterPath = input.hunterPath, progress = input.progress) callbackManager = CallbackManager.Factory.create() shareDialog = ShareDialog(this) @@ -120,5 +116,5 @@ class FacebookActivity : PermissionActivity() { } } - override fun getCurrentTreasuresProgress(): TreasuresProgress? = null + override fun getTreasureProgress(): TreasuresProgress? = null } \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookContract.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookContract.kt index cf4d9a2..d782dc4 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookContract.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookContract.kt @@ -4,11 +4,13 @@ import android.app.Activity import android.content.Context import android.content.Intent import androidx.activity.result.contract.ActivityResultContract +import pl.marianjureczko.poszukiwacz.model.HunterPath import pl.marianjureczko.poszukiwacz.model.TreasuresProgress import pl.marianjureczko.poszukiwacz.shared.XmlHelper import java.io.Serializable data class FacebookInputData( + val hunterPath: HunterPath?, val progress: TreasuresProgress ) : Serializable @@ -18,13 +20,9 @@ data class FacebookOutputData( class FacebookContract : ActivityResultContract() { - companion object { - private val xmlHelper = XmlHelper() - } - override fun createIntent(context: Context, input: FacebookInputData): Intent { return Intent(context, FacebookActivity::class.java).apply { - putExtra(FacebookActivity.TREASURE_PROGRESS, xmlHelper.writeToString(input.progress)) + putExtra(FacebookActivity.INPUT, input) } } diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookViewModel.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookViewModel.kt index 684d647..386068e 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookViewModel.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/FacebookViewModel.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import pl.marianjureczko.poszukiwacz.R +import pl.marianjureczko.poszukiwacz.model.HunterPath import pl.marianjureczko.poszukiwacz.model.Route import pl.marianjureczko.poszukiwacz.model.TreasuresProgress import pl.marianjureczko.poszukiwacz.shared.StorageHelper @@ -12,13 +13,16 @@ class FacebookViewModel(private val state: SavedStateHandle) : ViewModel() { private val TAG = javaClass.simpleName lateinit var progress: TreasuresProgress private set + var hunterPath: HunterPath? = null + private set lateinit var elements: List private set lateinit var route: Route - fun initialize(progress: TreasuresProgress, context: Context) { + fun initialize(context: Context, hunterPath: HunterPath?, progress: TreasuresProgress) { this.progress = progress + this.hunterPath = hunterPath val elements = mutableListOf() elements.add(ElementDescription(Type.TREASURES_SUMMARY, true, context.getString(R.string.collected_treasures))) val treasure = context.getString(R.string.treasure) diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMap.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMap.kt index 43c2816..1810a1a 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMap.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMap.kt @@ -62,19 +62,22 @@ class ReportMap( } private fun drawRoute(snapshot: MapSnapshotInterface, mapCanvas: Canvas) { - val locations = model.progress.hunterPath.pathAsCoordinates().toList() - if (locations.size > 1) { - var previousXY = snapshot.screenCoordinate(Point.fromLngLat(locations[0].longitude, locations[0].latitude)) - locations.asSequence() - .drop(1) - .forEach { - val xy = snapshot.screenCoordinate(Point.fromLngLat(it.longitude, it.latitude)) - mapCanvas.drawLine( - previousXY.x.toFloat(), previousXY.y.toFloat(), xy.x.toFloat(), xy.y.toFloat(), - Paint().apply { color = Color.RED } - ) - previousXY = xy - } + model.hunterPath?.let { + val locations = it.pathAsCoordinates().toList() + if (locations.size > 1) { + var previousXY = + snapshot.screenCoordinate(Point.fromLngLat(locations[0].longitude, locations[0].latitude)) + locations.asSequence() + .drop(1) + .forEach { + val xy = snapshot.screenCoordinate(Point.fromLngLat(it.longitude, it.latitude)) + mapCanvas.drawLine( + previousXY.x.toFloat(), previousXY.y.toFloat(), xy.x.toFloat(), xy.y.toFloat(), + Paint().apply { color = Color.RED } + ) + previousXY = xy + } + } } } diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummary.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummary.kt index 4eb7da5..ebb080b 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummary.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/facebook/ReportMapSummary.kt @@ -29,9 +29,9 @@ class ReportMapSummary( val textPaint = ReportCommons.getTextPaint(font, Paint.Align.LEFT) var textY = currentTop + 50 var x = ReportCommons.REPORT_MARGIN - canvas.drawText(distanceText(context, model.progress.hunterPath), x, textY, textPaint) + canvas.drawText(distanceText(context, model.hunterPath), x, textY, textPaint) textY += 40 - canvas.drawText(timeText(context, model.progress.hunterPath), x, textY, textPaint) + canvas.drawText(timeText(context, model.hunterPath), x, textY, textPaint) } } @@ -42,17 +42,18 @@ class ReportMapSummary( context.getResources().getConfiguration().locale } - private fun distanceText(context: Context, hunterPath: HunterPath): String { - val formattedDistance = "%.2f".format(hunterPath.pathLengthInKm()) + private fun distanceText(context: Context, hunterPath: HunterPath?): String { + val distance = hunterPath?.pathLengthInKm() ?: 0.0 + val formattedDistance = "%.2f".format(distance) return "${context.getString(R.string.walked_route)} $formattedDistance km." } - private fun timeText(context: Context, hunterPath: HunterPath): String { + private fun timeText(context: Context, hunterPath: HunterPath?): String { val loc = Locale("en", "US") val timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT, loc) val dateFormat: DateFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, loc) - hunterPath.getStartTime()?.let { start -> + hunterPath?.getStartTime()?.let { start -> val startDate = dateFormat.format(start) val startTime = timeFormat.format(start) hunterPath.getEndTime()?.let { end -> diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/main/MainActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/main/MainActivity.kt index 1c6e000..aaac273 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/main/MainActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/main/MainActivity.kt @@ -23,7 +23,7 @@ import pl.marianjureczko.poszukiwacz.shared.StorageHelper class MainActivity : PermissionActivity() { private val TAG = javaClass.simpleName - override fun getCurrentTreasuresProgress(): TreasuresProgress? { + override fun getTreasureProgress(): TreasuresProgress? { return null } diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/map/MapActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/map/MapActivity.kt index 81ae7a3..b8263f8 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/map/MapActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/map/MapActivity.kt @@ -41,7 +41,7 @@ class MapActivity : ActivityWithAdsAndBackButton() { setUpAds(binding.adView) } - override fun getCurrentTreasuresProgress(): TreasuresProgress? = model.progress + override fun getTreasureProgress(): TreasuresProgress? = model.progress override fun onResume() { super.onResume() diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/photo/PhotoActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/photo/PhotoActivity.kt index ff617ff..c299ed9 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/photo/PhotoActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/photo/PhotoActivity.kt @@ -33,7 +33,7 @@ class PhotoActivity : ActivityWithAdsAndBackButton() { setUpAds(binding.adView) } - override fun getCurrentTreasuresProgress(): TreasuresProgress = + override fun getTreasureProgress(): TreasuresProgress = model.progress } \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivity.kt index 2b1f02c..7920108 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivity.kt @@ -2,20 +2,48 @@ package pl.marianjureczko.poszukiwacz.activity.result import android.app.Activity import android.content.pm.ActivityInfo +import android.net.Uri import android.os.Bundle import android.view.View +import android.widget.Toast +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.activity.viewModels +import androidx.core.view.isVisible import pl.marianjureczko.poszukiwacz.R +import pl.marianjureczko.poszukiwacz.activity.commemorative.CommemorativeContract +import pl.marianjureczko.poszukiwacz.activity.commemorative.CommemorativeInputData import pl.marianjureczko.poszukiwacz.databinding.ActivityResultBinding import pl.marianjureczko.poszukiwacz.model.TreasuresProgress import pl.marianjureczko.poszukiwacz.shared.ActivityWithAdsAndBackButton +import pl.marianjureczko.poszukiwacz.shared.PhotoHelper +import pl.marianjureczko.poszukiwacz.shared.StorageHelper class ResultActivity : ActivityWithAdsAndBackButton() { companion object { - const val RESULT = "pl.marianjureczko.poszukiwacz.activity.result"; + const val RESULT_IN = "pl.marianjureczko.poszukiwacz.activity.result_in" + const val RESULT_OUT = "pl.marianjureczko.poszukiwacz.activity.result_out" } + private val model: ResultActivityViewModel by viewModels() private lateinit var binding: ActivityResultBinding + private val storageHelper = StorageHelper(this) + private val photoHelper = PhotoHelper(this, storageHelper) + + private val showCommemorativeLauncher: ActivityResultLauncher = + registerForActivityResult(CommemorativeContract()) {} + + private val doPhotoLauncher: ActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.TakePicture()) { result -> + if (result) { + model.addCommemorativePhoto(storageHelper, photoHelper.moveCommemorativePhotoToPermanentLocation()) + configureDoPhotoButton() + Toast.makeText(this, R.string.photo_saved, Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(this, R.string.photo_not_replaced, Toast.LENGTH_SHORT).show() + } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -24,24 +52,51 @@ class ResultActivity : ActivityWithAdsAndBackButton() { binding = ActivityResultBinding.inflate(layoutInflater) requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT - val input = intent.getSerializableExtra(RESULT) as ResultActivityData - if (input.isError()) { - binding.resultDescription.text = input.error + val input = intent.getSerializableExtra(RESULT_IN) as ResultActivityInput + model.initialize(this, storageHelper, input.treasure, input.progress, input.treasureDescription) + + configureView() + setContentView(binding.root) + setUpAds(binding.adView) + } + + private fun configureView() { + if (model.isError()) { + binding.resultDescription.text = model.errorMsg binding.resultImg.visibility = View.GONE } else { - binding.resultDescription.text = input.treasure!!.quantity.toString() - binding.resultImg.setImageResource(input.treasure.type.image()) + binding.resultDescription.text = model.treasure!!.quantity.toString() + binding.resultImg.setImageResource(model.treasure!!.type.image()) + } + + if (model.canMakeCommemorativePhoto()) { + configureDoPhotoButton() + } else { + binding.buttonsLayout.isVisible = false + } + } + + private fun configureDoPhotoButton() { + binding.buttonsLayout.isVisible = true + if (model.currentTreasureHasCommemorativePhoto()) { + binding.doPhoto.setImageResource(R.drawable.camera_show_photo) + binding.doPhoto.setOnClickListener { + model.commemorativeInputData()?.let { showCommemorativeLauncher.launch(it) } + } + } else { + binding.doPhoto.setImageResource(R.drawable.camera_do_photo) + binding.doPhoto.setOnClickListener { + doPhotoLauncher.launch(photoHelper.createCommemorativePhotoTempUri()) + } } - setContentView(binding.root) - setUpAds(binding.adView) } - override fun getCurrentTreasuresProgress(): TreasuresProgress? { + override fun getTreasureProgress(): TreasuresProgress? { return null } override fun onBackPressed() { - setResult(Activity.RESULT_OK, intent) + setResult(Activity.RESULT_OK, model.activityResult()) super.onBackPressed() } } \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityContract.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityContract.kt index eba5630..6390380 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityContract.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityContract.kt @@ -4,14 +4,14 @@ import android.content.Context import android.content.Intent import androidx.activity.result.contract.ActivityResultContract -class ResultActivityContract : ActivityResultContract() { - override fun createIntent(context: Context, input: ResultActivityData?): Intent { +class ResultActivityContract : ActivityResultContract() { + override fun createIntent(context: Context, input: ResultActivityInput?): Intent { return Intent(context, ResultActivity::class.java).apply { - putExtra(ResultActivity.RESULT, input) + putExtra(ResultActivity.RESULT_IN, input) } } - override fun parseResult(resultCode: Int, intent: Intent?): ResultActivityData? { - return intent?.getSerializableExtra(ResultActivity.RESULT) as ResultActivityData? + override fun parseResult(resultCode: Int, intent: Intent?): ResultActivityOutput { + return intent?.getSerializableExtra(ResultActivity.RESULT_OUT) as ResultActivityOutput } } \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityData.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityData.kt deleted file mode 100644 index d8b1da7..0000000 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityData.kt +++ /dev/null @@ -1,11 +0,0 @@ -package pl.marianjureczko.poszukiwacz.activity.result - -import pl.marianjureczko.poszukiwacz.model.Treasure -import java.io.Serializable - -data class ResultActivityData(val treasure: Treasure?, val error: String?) : Serializable { - constructor(treasure: Treasure?) : this(treasure, null) - constructor(error: String?) : this(null, error) - - fun isError(): Boolean = error != null -} \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityInput.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityInput.kt new file mode 100644 index 0000000..0e12c5c --- /dev/null +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityInput.kt @@ -0,0 +1,18 @@ +package pl.marianjureczko.poszukiwacz.activity.result + +import pl.marianjureczko.poszukiwacz.model.Treasure +import pl.marianjureczko.poszukiwacz.model.TreasureDescription +import pl.marianjureczko.poszukiwacz.model.TreasuresProgress +import java.io.Serializable + +data class ResultActivityInput( + val treasure: Treasure?, + val treasureDescription: TreasureDescription?, + val progress: TreasuresProgress? +) : Serializable + +data class ResultActivityOutput( + val progress: TreasuresProgress?, + val justFoundTreasureDescription: TreasureDescription?, + val newTreasureCollected: Boolean +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityViewModel.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityViewModel.kt new file mode 100644 index 0000000..529be65 --- /dev/null +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/result/ResultActivityViewModel.kt @@ -0,0 +1,109 @@ +package pl.marianjureczko.poszukiwacz.activity.result + +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import pl.marianjureczko.poszukiwacz.R +import pl.marianjureczko.poszukiwacz.activity.commemorative.CommemorativeInputData +import pl.marianjureczko.poszukiwacz.model.Treasure +import pl.marianjureczko.poszukiwacz.model.TreasureDescription +import pl.marianjureczko.poszukiwacz.model.TreasuresProgress +import pl.marianjureczko.poszukiwacz.shared.StorageHelper + +class ResultActivityViewModel(private val state: SavedStateHandle) : ViewModel() { + + companion object { + const val ERROR_MSG = "errorMsg" + const val PROGRESS = "progress" + } + + var treasure: Treasure? = null + private set + var progress: TreasuresProgress? + get() = state.get(PROGRESS) + private set(value) = state.set(PROGRESS, value) + private var currentTreasureDescription: TreasureDescription? = null + var errorMsg: String? + get() = state.get(ERROR_MSG) + private set(value) = state.set(ERROR_MSG, value) + + /** + * Checks what kind of treasure was found and adds it to the progress if it's a mew one. + * If there nothing to add, sets an appropriate error message in errMsg. + */ + fun initialize( + app: AppCompatActivity, + storageHelper: StorageHelper, + treasure: Treasure?, + progress: TreasuresProgress?, + currentTreasureDescription: TreasureDescription? + ) { + this.treasure = treasure + this.progress = progress + this.currentTreasureDescription = currentTreasureDescription + + if (treasure == null) { + errorMsg = app.resources.getString(R.string.not_a_treasure_msg) + } else { + val p = this.progress + p?.let { + if (it.contains(treasure)) { + errorMsg = app.resources.getString(R.string.treasure_already_taken_msg) + } else { + it.collect(treasure) + if (currentTreasureDescription != null) { + it.collect(currentTreasureDescription) + } + // to save the updated progress in the quasi persistent state + this.progress = it + storageHelper.save(it) + } + } + } + } + + fun addCommemorativePhoto(storageHelper: StorageHelper, commemorativePhotoAbsolutePath: String) { + currentTreasureDescription?.let { + progress?.let { + it.addCommemorativePhoto(currentTreasureDescription!!, commemorativePhotoAbsolutePath) + storageHelper.save(it) + // to save the updated progress in the quasi persistent state + progress = it + } + } + } + + fun isError(): Boolean = this.errorMsg != null + + fun canMakeCommemorativePhoto(): Boolean = !isError() && currentTreasureDescription != null + + fun currentTreasureHasCommemorativePhoto(): Boolean = + if (progress != null && currentTreasureDescription != null) { + progress!!.getCommemorativePhoto(currentTreasureDescription!!) != null + } else { + false + } + + fun commemorativeInputData(): CommemorativeInputData? { + if (!currentTreasureHasCommemorativePhoto()) { + return null + } + return CommemorativeInputData( + progress!!.getCommemorativePhoto(currentTreasureDescription!!)!!, + progress!! + ) + + } + + fun activityResult(): Intent { + val data = Intent() + progress?.let { + data.putExtra( + ResultActivity.RESULT_OUT, + ResultActivityOutput(progress, currentTreasureDescription, !isError()) + ) + } + return data + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/ChangeTreasureButtonListener.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/ChangeTreasureButtonListener.kt index 4ae778f..e8564b8 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/ChangeTreasureButtonListener.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/ChangeTreasureButtonListener.kt @@ -4,9 +4,10 @@ import android.view.View import androidx.activity.result.ActivityResultLauncher import pl.marianjureczko.poszukiwacz.activity.treasureselector.SelectTreasureInputData import pl.marianjureczko.poszukiwacz.model.Treasure +import pl.marianjureczko.poszukiwacz.model.TreasureDescription interface TreasuresStorage { - fun getTreasureSelectorActivityInputData(justFoundTreasure: Treasure?): SelectTreasureInputData + fun getTreasureSelectorActivityInputData(justFoundTreasureDesc: TreasureDescription?): SelectTreasureInputData } class ChangeTreasureButtonListener ( diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/JustFoundFinder.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/JustFoundFinder.kt new file mode 100644 index 0000000..378fde0 --- /dev/null +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/JustFoundFinder.kt @@ -0,0 +1,34 @@ +package pl.marianjureczko.poszukiwacz.activity.searching + +import android.util.Log +import pl.marianjureczko.poszukiwacz.activity.treasureselector.Coordinates +import pl.marianjureczko.poszukiwacz.model.Treasure +import pl.marianjureczko.poszukiwacz.model.TreasureDescription + +/** + * To find data about the "just found" by user treasure + */ +class JustFoundFinder( + /**justFoundTreasure shall be used for app version with fixed treasures locations*/ + val justFoundTreasure: Treasure?, + val selectedTreasureDescription: TreasureDescription?, + val userLocation: Coordinates?, + val locationCalculator: LocationCalculator = LocationCalculator() +) { + private val TAG = javaClass.simpleName + + fun findTreasureDescription(): TreasureDescription? { + return if (justFoundTreasure != null && selectedTreasureDescription != null && userLocation != null) { + val distance = locationCalculator.distanceInSteps(selectedTreasureDescription, userLocation) + Log.i(TAG, "Distance is $distance") + if (distance < 60) { + selectedTreasureDescription + } else { + null + } + } else { + null + } + } +} + diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivity.kt index 2d97a54..02416ab 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivity.kt @@ -14,7 +14,8 @@ import pl.marianjureczko.poszukiwacz.R import pl.marianjureczko.poszukiwacz.activity.map.MapActivityContract import pl.marianjureczko.poszukiwacz.activity.map.MapInputData import pl.marianjureczko.poszukiwacz.activity.result.ResultActivityContract -import pl.marianjureczko.poszukiwacz.activity.result.ResultActivityData +import pl.marianjureczko.poszukiwacz.activity.result.ResultActivityInput +import pl.marianjureczko.poszukiwacz.activity.result.ResultActivityOutput import pl.marianjureczko.poszukiwacz.activity.treasureselector.SelectTreasureContract import pl.marianjureczko.poszukiwacz.activity.treasureselector.SelectTreasureInputData import pl.marianjureczko.poszukiwacz.activity.treasureselector.SelectTreasureOutputData @@ -46,7 +47,7 @@ class SearchingActivity : ActivityWithAdsAndBackButton() { private val model: SearchingActivityViewModel by viewModels() private lateinit var binding: ActivitySearchingBinding private lateinit var treasureSelectorLauncher: ActivityResultLauncher - private lateinit var showResultLauncher: ActivityResultLauncher + private lateinit var showResultLauncher: ActivityResultLauncher private lateinit var showMapLauncher: ActivityResultLauncher @SuppressLint("SourceLockedOrientationActivity") @@ -57,7 +58,12 @@ class SearchingActivity : ActivityWithAdsAndBackButton() { setContentView(R.layout.activity_searching) restoreState() - binding.scanBtn.setOnClickListener(ScanButtonListener(createScanTreasureLauncher(), resources.getString(R.string.qr_scanner_msg))) + binding.scanBtn.setOnClickListener( + ScanButtonListener( + createScanTreasureLauncher(), + resources.getString(R.string.qr_scanner_msg) + ) + ) treasureSelectorLauncher = createSelectTreasureLauncher() showResultLauncher = createShowResultLauncher() showMapLauncher = createShowMapLauncher() @@ -72,15 +78,16 @@ class SearchingActivity : ActivityWithAdsAndBackButton() { storageHelper ) val handler = Handler() - val locationRequester = LocationRequester(this, locationListener, handler, getSystemService(LOCATION_SERVICE) as LocationManager) + val locationRequester = + LocationRequester(this, locationListener, handler, getSystemService(LOCATION_SERVICE) as LocationManager) handler.post(locationRequester) setContentView(binding.root) setUpAds(binding.adView) } - override fun getCurrentTreasuresProgress(): TreasuresProgress? { - return model.getTreasureBag() + override fun getTreasureProgress(): TreasuresProgress? { + return model.getProgress() } override fun onPostResume() { @@ -100,25 +107,15 @@ class SearchingActivity : ActivityWithAdsAndBackButton() { showCollectedTreasures() } - private fun processSearchingResult(result: String): ResultActivityData { - try { + private fun processSearchingResult(result: String): ResultActivityInput { + return try { val treasure: Treasure = treasureParser.parse(result) - return if (model.treasureIsAlreadyCollected(treasure)) { - ResultActivityData(resources.getString(R.string.treasure_already_taken_msg)) - } else { - add(treasure) - ResultActivityData(treasure) - } + ResultActivityInput(treasure, model.tryToFindTreasureDescription(treasure), model.getTreasuresProgress()) } catch (ex: IllegalArgumentException) { - return ResultActivityData(resources.getString(R.string.not_a_treasure_msg)) + ResultActivityInput(null, null, model.getTreasuresProgress()) } } - private fun add(treasure: Treasure) { - model.collectTreasure(treasure, storageHelper) - showCollectedTreasures() - } - private fun showCollectedTreasures() { binding.goldTxt.text = model.getGolds() binding.rubyTxt.text = model.getRubies() @@ -135,15 +132,19 @@ class SearchingActivity : ActivityWithAdsAndBackButton() { private fun createSelectTreasureLauncher(): ActivityResultLauncher = registerForActivityResult(SelectTreasureContract()) { result: SelectTreasureOutputData? -> if (result != null) { - model.replaceTreasureBag(result.progress, storageHelper) + model.replaceProgress(result.progress, storageHelper) } } - private fun createShowResultLauncher(): ActivityResultLauncher = - registerForActivityResult(ResultActivityContract()) { result: ResultActivityData? -> - result?.let { - if (!it.isError()) { - treasureSelectorLauncher.launch(model.getTreasureSelectorActivityInputData(it.treasure)) + private fun createShowResultLauncher(): ActivityResultLauncher = + registerForActivityResult(ResultActivityContract()) { result: ResultActivityOutput? -> + result?.let { resultActivityOutput -> + resultActivityOutput.progress?.let { progress -> + model.replaceProgress(progress, storageHelper) + showCollectedTreasures() + if (resultActivityOutput.newTreasureCollected) { + treasureSelectorLauncher.launch(model.getTreasureSelectorActivityInputData(resultActivityOutput.justFoundTreasureDescription)) + } } } } diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModel.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModel.kt index 1b57699..4b6d5b9 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModel.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModel.kt @@ -25,6 +25,7 @@ class SearchingActivityViewModel(private val state: SavedStateHandle) : ViewMode private val TAG = javaClass.simpleName private val xmlHelper = XmlHelper() private lateinit var route: Route + //TODO: state should be employed as property is mutable private lateinit var treasuresProgress: TreasuresProgress private var currentLocation: Location? = null private var currentCoordinates: Coordinates? = state.get(CURRENT_COORDINATES) @@ -33,46 +34,50 @@ class SearchingActivityViewModel(private val state: SavedStateHandle) : ViewMode field = value state[TREASURE_SELECTION_INITIALIZED] = value } + private var hunterPath: HunterPath? = deserializeHunterPath(state.get(PATH)) private set(value) { if (value != null) { field = value state[PATH] = xmlHelper.writeToString(value) - treasuresProgress.hunterPath = value } } private var mediaPlayer: MediaPlayer? = null + fun initialize(routeXml: String, storageHelper: StorageHelper) { + route = xmlHelper.loadFromString(routeXml) + loadProgressFromStorage(storageHelper) + } + override fun getSelectedForHuntTreasure(): TreasureDescription? { return treasuresProgress.selectedTreasure } - override fun getTreasureSelectorActivityInputData(justFoundTreasure: Treasure?): SelectTreasureInputData { + override fun getTreasureSelectorActivityInputData(justFoundTreasureDesc: TreasureDescription?): SelectTreasureInputData { treasureSelectionInitialized = true - return SelectTreasureInputData(route, treasuresProgress, currentCoordinates, justFoundTreasure) + return SelectTreasureInputData(route, treasuresProgress, currentCoordinates, justFoundTreasureDesc) } + fun tryToFindTreasureDescription(justFoundTreasure: Treasure?) = + JustFoundFinder(justFoundTreasure, getSelectedForHuntTreasure(), currentCoordinates) + .findTreasureDescription() + override fun setCurrentLocation(location: Location?, storageHelper: StorageHelper) { currentLocation = location location?.let { currentCoordinates = Coordinates(it.latitude, it.longitude) state[CURRENT_COORDINATES] = currentCoordinates - if (treasuresProgress.hunterPath!!.addLocation(currentCoordinates!!)) { - storageHelper.save(this.treasuresProgress) + val hp = hunterPath!! + if (hp.addLocation(currentCoordinates!!)) { + storageHelper.save(hp) } //to call setter - hunterPath = treasuresProgress.hunterPath + hunterPath = hp } } override fun getTreasuresProgress(): TreasuresProgress = treasuresProgress - fun initialize(routeXml: String, storageHelper: StorageHelper) { - route = xmlHelper.loadFromString(routeXml) - treasuresProgress = storageHelper.loadProgress(route.name) ?: TreasuresProgress(route.name) - hunterPath = treasuresProgress.hunterPath - } - override fun tipName(): String? = treasuresProgress.selectedTreasure?.tipFileName @@ -91,9 +96,6 @@ class SearchingActivityViewModel(private val state: SavedStateHandle) : ViewMode fun treasureSelectionInitialized() = treasureSelectionInitialized || treasuresProgress.selectedTreasure != null - fun treasureIsAlreadyCollected(treasure: Treasure): Boolean = - treasuresProgress.contains(treasure) - fun collectTreasure(treasure: Treasure, storageHelper: StorageHelper) { treasuresProgress.collect(treasure) storageHelper.save(this.treasuresProgress) @@ -108,14 +110,28 @@ class SearchingActivityViewModel(private val state: SavedStateHandle) : ViewMode fun getDiamonds(): String = treasuresProgress.diamonds.toString() - fun replaceTreasureBag(treasuresProgress: TreasuresProgress, storageHelper: StorageHelper) { + fun replaceProgress(treasuresProgress: TreasuresProgress, storageHelper: StorageHelper) { this.treasuresProgress = treasuresProgress storageHelper.save(this.treasuresProgress) } + fun loadProgressFromStorage(storageHelper: StorageHelper) { + var loadedProgress = storageHelper.loadProgress(route.name) + if (loadedProgress == null) { + loadedProgress = TreasuresProgress(route.name) + storageHelper.save(loadedProgress) + } + treasuresProgress = loadedProgress + hunterPath = storageHelper.loadHunterPath(route.name) + if(hunterPath == null) { + hunterPath = HunterPath(route.name) + storageHelper.save(hunterPath!!) + } + } + //visibility for tests internal fun getRoute() = route - internal fun getTreasureBag() = treasuresProgress + internal fun getProgress() = treasuresProgress private fun handleMediaPlayerError(what: Int, extra: Int): Boolean { when (what) { diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureseditor/TreasuresEditorActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureseditor/TreasuresEditorActivity.kt index e15ed10..b2cc446 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureseditor/TreasuresEditorActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureseditor/TreasuresEditorActivity.kt @@ -45,7 +45,7 @@ class TreasuresEditorActivity : PermissionActivity(), RouteNameDialog.Callback, } private val TAG = javaClass.simpleName - override fun getCurrentTreasuresProgress(): TreasuresProgress? { + override fun getTreasureProgress(): TreasuresProgress? { return null } diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectTreasureContract.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectTreasureContract.kt index 35ef664..0da28d2 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectTreasureContract.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectTreasureContract.kt @@ -6,6 +6,7 @@ import android.content.Intent import androidx.activity.result.contract.ActivityResultContract import pl.marianjureczko.poszukiwacz.model.Route import pl.marianjureczko.poszukiwacz.model.Treasure +import pl.marianjureczko.poszukiwacz.model.TreasureDescription import pl.marianjureczko.poszukiwacz.model.TreasuresProgress import pl.marianjureczko.poszukiwacz.shared.XmlHelper import java.io.Serializable @@ -14,7 +15,7 @@ data class SelectTreasureInputData( val route: Route, val progress: TreasuresProgress, val currentCoordinates: Coordinates?, - val justFoundTreasure: Treasure? + val justFoundTreasureDescription: TreasureDescription? ) : Serializable data class SelectTreasureOutputData( @@ -28,8 +29,8 @@ class SelectTreasureContract : ActivityResultContract>(IDS_OF_COLLECTED)?.let { this.progress.collectedTreasuresDescriptionId.clear() this.progress.collectedTreasuresDescriptionId.addAll(it) @@ -110,18 +113,6 @@ class SelectorViewModel(private val state: SavedStateHandle) : ViewModel() { } } - fun getUserLocation(): Coordinates? = - userLocation?.copy() - - fun getJustFound(): Treasure? = - justFoundTreasure + fun treasureDescriptionHasBeenIdentified(): Boolean = this.justFoundTreasureDescription != null - fun treasureIsNotFarAwayFromUser(): Boolean = - if (getSelectedTreasure() != null && getUserLocation() != null) { - val distance = LocationCalculator().distanceInSteps(getSelectedTreasure()!!, getUserLocation()!!) - Log.i(TAG, "Distance is $distance") - distance < 60; - } else { - false - } } \ No newline at end of file diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureProgressHolder.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureProgressHolder.kt index 75d0c9e..34d58a3 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureProgressHolder.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureProgressHolder.kt @@ -35,7 +35,7 @@ class TreasureProgressHolder( private val photoHelper = PhotoHelper(context, storageHelper) fun setup(treasure: TreasureDescription, commemorativePhoto: String?) { - if (model.isCollected(treasure)) { + if (model.isCollected(treasure) && treasure != model.justFoundTreasureDescription) { showCollected() } else { showNotCollected() @@ -66,7 +66,6 @@ class TreasureProgressHolder( doPhotoLauncher.launch(photoHelper.createCommemorativePhotoTempUri()) } else { showCommemorativeLauncher.launch(CommemorativeInputData(commemorativePhoto, model.progress)) -// context.startActivity(CommemorativeActivity.intent(context, commemorativePhoto)) } } } diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureSelectorActivity.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureSelectorActivity.kt index 5544850..b5ccdc4 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureSelectorActivity.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/TreasureSelectorActivity.kt @@ -18,7 +18,7 @@ import pl.marianjureczko.poszukiwacz.activity.commemorative.CommemorativeContrac import pl.marianjureczko.poszukiwacz.activity.commemorative.CommemorativeInputData import pl.marianjureczko.poszukiwacz.databinding.ActivityTreasureSelectorBinding import pl.marianjureczko.poszukiwacz.model.Route -import pl.marianjureczko.poszukiwacz.model.Treasure +import pl.marianjureczko.poszukiwacz.model.TreasureDescription import pl.marianjureczko.poszukiwacz.model.TreasuresProgress import pl.marianjureczko.poszukiwacz.permissions.ActivityRequirements import pl.marianjureczko.poszukiwacz.permissions.PermissionActivity @@ -34,33 +34,35 @@ import pl.marianjureczko.poszukiwacz.shared.XmlHelper class TreasureSelectorActivity : PermissionActivity(), ActivityTerminator { private val TAG = javaClass.simpleName - override fun getCurrentTreasuresProgress(): TreasuresProgress? { + override fun getTreasureProgress(): TreasuresProgress? { return model.progress } private lateinit var binding: ActivityTreasureSelectorBinding private val model: SelectorViewModel by viewModels() private lateinit var adapter: TreasureProgressAdapter - private val storageHelper = StorageHelper(this) - private val photoHelper = PhotoHelper(this, storageHelper) - private val doPhotoLauncher: ActivityResultLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { result -> - if (result) { - val newPhotoLocation = photoHelper.moveCommemorativePhotoToPermanentLocation() - model.setCommemorativePhotoOnSelectedTreasureDescription(newPhotoLocation) - adapter.notifyDataSetChanged() - Toast.makeText(this, R.string.photo_saved, Toast.LENGTH_SHORT).show() - } else { - Toast.makeText(this, R.string.photo_not_saved, Toast.LENGTH_SHORT).show() + private val photoHelper = PhotoHelper(this, StorageHelper(this)) + private val doPhotoLauncher: ActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.TakePicture()) { result -> + if (result) { + val newPhotoLocation = photoHelper.moveCommemorativePhotoToPermanentLocation() + model.setCommemorativePhotoOnSelectedTreasureDescription(newPhotoLocation) + adapter.notifyDataSetChanged() + Toast.makeText(this, R.string.photo_saved, Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(this, R.string.photo_not_saved, Toast.LENGTH_SHORT).show() + } } - } - private val commemorativeLauncher: ActivityResultLauncher = registerForActivityResult(CommemorativeContract()) {} + private val commemorativeLauncher: ActivityResultLauncher = + registerForActivityResult(CommemorativeContract()) {} companion object { const val RESULT_PROGRESS = "pl.marianjureczko.poszukiwacz.activity.treasure_selector_result_progress" internal const val ROUTE = "pl.marianjureczko.poszukiwacz.activity.route_to_select_from" internal const val PROGRESS = "pl.marianjureczko.poszukiwacz.activity.route_progress" internal const val LOCATION = "pl.marianjureczko.poszukiwacz.activity.user_coordinates" - internal const val TREASURE = "pl.marianjureczko.poszukiwacz.activity.treasure_selector_treasure" + internal const val TREASURE_DESCRIPTION = + "pl.marianjureczko.poszukiwacz.activity.treasure_selector_treasure_description" private val xmlHelper = XmlHelper() } @@ -79,7 +81,7 @@ class TreasureSelectorActivity : PermissionActivity(), ActivityTerminator { route = xmlHelper.loadFromString(intent.getStringExtra(ROUTE)!!), progress = xmlHelper.loadFromString(intent.getStringExtra(PROGRESS)!!), userLocation = intent.getSerializableExtra(LOCATION) as Coordinates?, - justFound = intent.getSerializableExtra(TREASURE) as Treasure? + justFoundTreasureDescription = intent.getSerializableExtra(TREASURE_DESCRIPTION) as TreasureDescription? ) adapter = TreasureProgressAdapter(this, model, this, doPhotoLauncher, commemorativeLauncher) binding.treasuresToSelect.adapter = adapter @@ -106,16 +108,14 @@ class TreasureSelectorActivity : PermissionActivity(), ActivityTerminator { } private fun markTreasureIfFound() = - model.getJustFound()?.let { - if (model.treasureIsNotFarAwayFromUser()) { - model.collect(model.getSelectedTreasure()!!) - adapter.notifyDataSetChanged() - val id = model.getSelectedTreasure()!!.id.toString() - Toast.makeText(this, this.getString(R.string.treasure_marked_as_collected, id), Toast.LENGTH_LONG).show() - } else { - //TODO: in case the toast is too quick - https://www.geeksforgeeks.org/display-toast-for-a-specific-time-in-android/ - Toast.makeText(this, R.string.treasure_nor_marked, Toast.LENGTH_LONG).show() - } + if (model.treasureDescriptionHasBeenIdentified()) { + val id = model.justFoundTreasureDescription!!.id.toString() + Toast.makeText(this, this.getString(R.string.treasure_marked_as_collected, id), Toast.LENGTH_LONG).show() + model.justFoundTreasureDescription = null + adapter.notifyDataSetChanged() + } else { + //TODO: in case the toast is too quick - https://www.geeksforgeeks.org/display-toast-for-a-specific-time-in-android/ + Toast.makeText(this, R.string.treasure_nor_marked, Toast.LENGTH_LONG).show() } private fun intentResultWithProgress(): Intent { diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/model/HunterPath.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/model/HunterPath.kt index bcd84be..b9f9bed 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/model/HunterPath.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/model/HunterPath.kt @@ -3,12 +3,21 @@ package pl.marianjureczko.poszukiwacz.model import org.apache.commons.math3.stat.StatUtils import org.simpleframework.xml.Element import org.simpleframework.xml.ElementList +import org.simpleframework.xml.Root import pl.marianjureczko.poszukiwacz.activity.searching.LocationCalculator import pl.marianjureczko.poszukiwacz.activity.treasureselector.Coordinates import java.io.Serializable import java.util.Date -class HunterPath : Serializable { +@Root +class HunterPath() : Serializable { + + constructor(routeName: String) : this() { + this.routeName = routeName + } + + @field:Element + lateinit var routeName: String /** * Measurements for the next chunk. When te chunk creation criteria are met, the measurements are used to produce the chunk and are remove. diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgress.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgress.kt index dbed2fa..a3494a2 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgress.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgress.kt @@ -44,10 +44,6 @@ class TreasuresProgress() : Serializable { @field:Element(required = false) var selectedTreasure: TreasureDescription? = null - /** set is required for restoring state */ - @field:Element - var hunterPath = HunterPath() - fun contains(treasure: Treasure): Boolean = collectedQrCodes.contains(treasure.id) diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/ActivityWithAdsAndBackButton.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/ActivityWithAdsAndBackButton.kt index cb31243..d1fce12 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/ActivityWithAdsAndBackButton.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/ActivityWithAdsAndBackButton.kt @@ -58,8 +58,8 @@ abstract class ActivityWithAdsAndBackButton : AppCompatActivity(), SelectTreasur val url = this.getString(R.string.help_path) startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) } else if (id == R.id.facebook) { - if (getCurrentTreasuresProgress() != null) { - facebookLauncher.launch(FacebookInputData(getCurrentTreasuresProgress()!!)) + if (getTreasureProgress() != null) { + facebookLauncher.launch(createFacebookInputData(getTreasureProgress()!!)) } else { val progresses = storageHelper.loadAll() .mapNotNull { route -> storageHelper.loadProgress(route.name) } @@ -68,7 +68,7 @@ abstract class ActivityWithAdsAndBackButton : AppCompatActivity(), SelectTreasur Toast.makeText(this, R.string.facebook_nothing_to_share, Toast.LENGTH_SHORT).show() } else { if (progresses.size == 1) { - facebookLauncher.launch(FacebookInputData(progresses[0])) + facebookLauncher.launch(createFacebookInputData(progresses[0])) } else { SelectTreasureProgressDialog.newInstance(progresses).apply { show(supportFragmentManager, "SelectTreasureProgressDialog") @@ -80,16 +80,20 @@ abstract class ActivityWithAdsAndBackButton : AppCompatActivity(), SelectTreasur return super.onOptionsItemSelected(item) } + private fun createFacebookInputData(treasureProgress: TreasuresProgress): FacebookInputData { + return FacebookInputData(storageHelper.loadHunterPath(treasureProgress.routeName), treasureProgress) + } + override fun onTreasureProgressSelected(routeName: String) { val progresses = storageHelper.loadProgress(routeName) if (progresses == null) { Toast.makeText(this, R.string.facebook_invalid_roote, Toast.LENGTH_SHORT).show() } else { - facebookLauncher.launch(FacebookInputData(progresses)) + facebookLauncher.launch(createFacebookInputData(progresses)) } } - protected abstract fun getCurrentTreasuresProgress(): TreasuresProgress? + protected abstract fun getTreasureProgress(): TreasuresProgress? private fun createShareOnFacebookLauncher(): ActivityResultLauncher = registerForActivityResult(FacebookContract()) { result: FacebookOutputData? -> diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/StorageHelper.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/StorageHelper.kt index adba42d..516523d 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/StorageHelper.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/StorageHelper.kt @@ -3,6 +3,7 @@ package pl.marianjureczko.poszukiwacz.shared import android.content.Context import android.util.Log import org.apache.commons.io.IOUtils +import pl.marianjureczko.poszukiwacz.model.HunterPath import pl.marianjureczko.poszukiwacz.model.Route import pl.marianjureczko.poszukiwacz.model.TreasureDescription import pl.marianjureczko.poszukiwacz.model.TreasuresProgress @@ -26,6 +27,7 @@ open class StorageHelper(val context: Context) { companion object { const val routesDirectory = "/treasures_lists" const val progressDirectory = "/progress" + const val hunterPathsDirectory = "/huner_paths" } fun newSoundFile(): String = newFile("sound_", ".3gp") @@ -34,9 +36,16 @@ open class StorageHelper(val context: Context) { fun newCommemorativePhotoFile(): String = newFile("commemorativephoto_", ".jpg") - fun save(bag: TreasuresProgress) { - val file = getProgressFile(bag.routeName) - xmlHelper.writeToFile(bag, file) + fun save(route: Route) { + xmlHelper.writeToFile(route, getRouteFile(route.fileName())) + } + + fun save(progress: TreasuresProgress) { + xmlHelper.writeToFile(progress, getProgressFile(progress.routeName)) + } + + fun save(hunterPath: HunterPath) { + xmlHelper.writeToFile(hunterPath, getHunterPathFile(hunterPath.routeName)) } fun loadProgress(routeName: String): TreasuresProgress? { @@ -53,9 +62,18 @@ open class StorageHelper(val context: Context) { } } - fun save(route: Route) { - val xmlFile = getRouteFile(route.fileName()) - xmlHelper.writeToFile(route, xmlFile) + fun loadHunterPath(routeName: String): HunterPath? { + val file = getHunterPathFile(routeName) + return if (file.exists()) { + try { + xmlHelper.loadHunterPathFromFile(file) + } catch (e: Exception) { + Log.e(TAG, e.message, e) + null + } + } else { + null + } } /** The route should be already saved */ @@ -179,20 +197,19 @@ open class StorageHelper(val context: Context) { private fun newFile(prefix: String, extension: String) = getRoutesDir().absolutePath + File.separator + prefix + UUID.randomUUID().toString() + extension - private fun getRouteFile(routeName: String): File { - //TODO: what about invalid characters in name? - val dir = getRoutesDir() - return File("${dir.absolutePath}/$routeName.xml") - } + //TODO: what about invalid characters in name? + private fun getRouteFile(routeName: String): File = getFile(getRoutesDir(), routeName) - private fun getRoutesDir(): File = getDir(routesDirectory) + private fun getProgressFile(routeName: String): File = getFile(getProgressDir(), routeName) - private fun getProgressFile(routeName: String): File { - val dir = getProgressDir() - return File("${dir.absolutePath}/$routeName.xml") - } + private fun getHunterPathFile(routeName: String): File = getFile(getHunterPathsDir(), routeName) + + private fun getFile(dir: File, routeName: String) = File("${dir.absolutePath}/$routeName.xml") + + private fun getRoutesDir(): File = getDir(routesDirectory) private fun getProgressDir(): File = getDir(progressDirectory) + private fun getHunterPathsDir(): File = getDir(hunterPathsDirectory) private fun getDir(dirName: String): File { val dir = File(context.filesDir.absolutePath + dirName) @@ -204,7 +221,12 @@ open class StorageHelper(val context: Context) { private fun pathsToRelative(route: Route): Route { val relativeTreasures = route.treasures - .map { it.copy(tipFileName = toRelativePath(it.tipFileName), photoFileName = toRelativePath(it.photoFileName)) } + .map { + it.copy( + tipFileName = toRelativePath(it.tipFileName), + photoFileName = toRelativePath(it.photoFileName) + ) + } .toMutableList() return route.copy(treasures = relativeTreasures) } diff --git a/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/XmlHelper.kt b/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/XmlHelper.kt index 14cbcc3..c7d91be 100644 --- a/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/XmlHelper.kt +++ b/app/src/main/java/pl/marianjureczko/poszukiwacz/shared/XmlHelper.kt @@ -2,6 +2,7 @@ package pl.marianjureczko.poszukiwacz.shared import org.simpleframework.xml.Serializer import org.simpleframework.xml.core.Persister +import pl.marianjureczko.poszukiwacz.model.HunterPath import pl.marianjureczko.poszukiwacz.model.Route import pl.marianjureczko.poszukiwacz.model.TreasuresProgress import java.io.File @@ -14,6 +15,12 @@ class XmlHelper { serializer.write(route, outputFile) } + fun writeToFile(progress: TreasuresProgress, outputFile: File) = + serializer.write(progress, outputFile) + + fun writeToFile(hunterPath: HunterPath, outputFile: File) = + serializer.write(hunterPath, outputFile) + fun writeToString(o: Any): String { val stringWriter = StringWriter() serializer.write(o, stringWriter) @@ -29,11 +36,12 @@ class XmlHelper { return serializer.read(T::class.java, xml) } - fun writeToFile(bag: TreasuresProgress, outputFile: File) = - serializer.write(bag, outputFile) - fun loadProgressFromFile(xmlFile: File): TreasuresProgress { val xml = xmlFile.readText() return serializer.read(TreasuresProgress::class.java, xml) } + fun loadHunterPathFromFile(xmlFile: File): HunterPath { + val xml = xmlFile.readText() + return serializer.read(HunterPath::class.java, xml) + } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_result.xml b/app/src/main/res/layout/activity_result.xml index 1949f5c..c723d98 100644 --- a/app/src/main/res/layout/activity_result.xml +++ b/app/src/main/res/layout/activity_result.xml @@ -1,9 +1,10 @@ @@ -11,62 +12,41 @@ android:id="@+id/resultImg" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1.0" + android:layout_weight="10.0" android:gravity="top" - android:padding="4dp" /> + android:layout_marginTop="50dp" /> - - - + android:autoSizeTextType="uniform" + android:gravity="center" + android:textSize="60dp" + android:fontFamily="@font/akaya_telivigala" /> + android:orientation="horizontal"> - - - - { + val someDescription = some() + val someTreasure = some() + return listOf( + Arguments.of( + "SHOULD return null WHEN treasure is null", + null, + someDescription, + some(), + 0, + null + ), + Arguments.of( + "SHOULD return null WHEN description and coordinates are null", + someTreasure, + null, + null, + 0, + null + ), + Arguments.of( + "SHOULD return null WHEN only description is null", + someTreasure, + someDescription, + null, + 0, + null + ), + Arguments.of( + "SHOULD return null WHEN only coordinates is null", + someTreasure, + null, + some(), + 0, + null + ), + Arguments.of( + "SHOULD return null WHEN description is far away from coordinates", + someTreasure, + someDescription, + some(), + 60, + null + ), + Arguments.of( + "SHOULD return description WHEN description is close to coordinates", + someTreasure, + someDescription, + some(), + 59, + someDescription + ), + ) + } + } + + @Mock + lateinit var locationCalculator: LocationCalculator + + @ParameterizedTest(name = "{0}") + @MethodSource("data") + fun findTreasureDescription( + comment: String, + justFoundTreasure: Treasure?, + description: TreasureDescription?, + userCoordinates: Coordinates?, + coordinatesDistance: Int, + expected: TreasureDescription? + ) { + //given + justFoundTreasure?.let { + description?.let { + userCoordinates?.let { + BDDMockito.given(locationCalculator.distanceInSteps(description, userCoordinates)) + .willReturn(coordinatesDistance) + } + } + } + val finder = JustFoundFinder(justFoundTreasure, description, userCoordinates, locationCalculator) + + //when + val actual = finder.findTreasureDescription() + + //then + assertThat(actual).isEqualTo(expected) + } +} \ No newline at end of file diff --git a/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModelTest.kt b/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModelTest.kt index fa6b8a4..fb86a7c 100644 --- a/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModelTest.kt +++ b/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/searching/SearchingActivityViewModelTest.kt @@ -6,9 +6,14 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.BDDMockito.given +import org.mockito.BDDMockito.mockingDetails +import org.mockito.BDDMockito.reset import org.mockito.BDDMockito.then import org.mockito.Mock +import org.mockito.Mockito import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.verification.VerificationMode +import pl.marianjureczko.poszukiwacz.model.HunterPath import pl.marianjureczko.poszukiwacz.model.Route import pl.marianjureczko.poszukiwacz.model.Treasure import pl.marianjureczko.poszukiwacz.model.TreasureType @@ -35,7 +40,7 @@ class SearchingActivityViewModelTest { //then assertThat(fixture.model.getRoute()).isEqualTo(fixture.route) - assertThat(fixture.model.getTreasureBag()).usingRecursiveComparison().isEqualTo(TreasuresProgress(fixture.route.name)) + assertThat(fixture.model.getProgress()).usingRecursiveComparison().isEqualTo(TreasuresProgress(fixture.route.name)) } @Test @@ -43,13 +48,13 @@ class SearchingActivityViewModelTest { //given val treasuresProgress = some() val fixture = SearchingActivityViewModelFixture(state) - fixture.setupMockForGivenTreasureBag(storageHelper, treasuresProgress) + fixture.setupMockForGivenTreasureProgress(storageHelper, treasuresProgress) //when initialize model (in fixture) //then assertThat(fixture.model.getRoute()).isEqualTo(fixture.route) - assertThat(fixture.model.getTreasureBag()).usingRecursiveComparison().isEqualTo(treasuresProgress) + assertThat(fixture.model.getProgress()).usingRecursiveComparison().isEqualTo(treasuresProgress) } @Test @@ -59,25 +64,26 @@ class SearchingActivityViewModelTest { val treasuresProgress = some() //when - model.replaceTreasureBag(treasuresProgress, storageHelper) + model.replaceProgress(treasuresProgress, storageHelper) //then then(storageHelper).should().save(treasuresProgress) - assertThat(model.getTreasureBag()).usingRecursiveComparison().isEqualTo(treasuresProgress) + assertThat(model.getProgress()).usingRecursiveComparison().isEqualTo(treasuresProgress) } @Test - fun `SHOULD save new treasure bag WHEN collecting next treasure`() { + fun `SHOULD save new treasure progress WHEN collecting next treasure`() { //given val fixture = SearchingActivityViewModelFixture(state) fixture.setupMockForEmptyTreasureBag(storageHelper) val treasure = some().copy(type = TreasureType.DIAMOND) + reset(storageHelper) //when fixture.model.collectTreasure(treasure, storageHelper) //then - then(storageHelper).should().save(fixture.model.getTreasureBag()) + then(storageHelper).should().save(fixture.model.getProgress()) assertThat(fixture.model.getDiamonds()).isEqualTo(treasure.quantity.toString()) } @@ -112,7 +118,7 @@ class SearchingActivityViewModelTest { fun `SHOULD say initialized WHEN the flag is not set ie getTreasureSelectorActivityInputData was never called but selected is set`() { //given val fixture = SearchingActivityViewModelFixture(state) - fixture.setupMockForGivenTreasureBag(storageHelper, some()) + fixture.setupMockForGivenTreasureProgress(storageHelper, some()) assertThat(fixture.model.getSelectedForHuntTreasure()).isNotNull() //when @@ -135,7 +141,7 @@ class SearchingActivityViewModelTest { fun `SHOULD persist state WHEN getting data from treasure selector launcher TO not reexecute the selection second time`() { //given val fixture = SearchingActivityViewModelFixture(state) - fixture.setupMockForGivenTreasureBag(storageHelper, some()) + fixture.setupMockForGivenTreasureProgress(storageHelper, some()) assertThat(fixture.model.getSelectedForHuntTreasure()).isNotNull() //when @@ -160,7 +166,7 @@ data class SearchingActivityViewModelFixture( model.initialize(xml, storageHelper) } - fun setupMockForGivenTreasureBag(storageHelper: StorageHelper, treasuresProgress: TreasuresProgress) { + fun setupMockForGivenTreasureProgress(storageHelper: StorageHelper, treasuresProgress: TreasuresProgress) { given(storageHelper.loadProgress(route.name)) .willReturn(treasuresProgress) model.initialize(xml, storageHelper) @@ -169,4 +175,6 @@ data class SearchingActivityViewModelFixture( private fun initializeModel(storageHelper: StorageHelper) { model.initialize(xml, storageHelper) } -} \ No newline at end of file +} + +private fun any(type: Class): T = Mockito.any(type) \ No newline at end of file diff --git a/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectorViewModelTest.kt b/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectorViewModelTest.kt index 1d063b5..6341df8 100644 --- a/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectorViewModelTest.kt +++ b/app/src/test/java/pl/marianjureczko/poszukiwacz/activity/treasureselector/SelectorViewModelTest.kt @@ -144,7 +144,7 @@ internal class SelectorViewModelTest { //given val model = some() model.initialize(some(), some(), null, null) - assertThat(model.getUserLocation()).isNull() + assertThat(model.userLocation).isNull() val treasureDescription = some() //when @@ -170,7 +170,7 @@ internal class SelectorViewModelTest { //then assertThat(treasureId).isEqualTo(treasureDescription.id) - assertThat(distanceInSteps).isEqualTo(calculator.distanceInSteps(treasureDescription, model.getUserLocation()!!)) + assertThat(distanceInSteps).isEqualTo(calculator.distanceInSteps(treasureDescription, model.userLocation!!)) return expected } }) diff --git a/app/src/test/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgressArranger.kt b/app/src/test/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgressArranger.kt index 9ada357..867d7f0 100644 --- a/app/src/test/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgressArranger.kt +++ b/app/src/test/java/pl/marianjureczko/poszukiwacz/model/TreasuresProgressArranger.kt @@ -12,7 +12,7 @@ class TreasuresProgressArranger : CustomArranger() { instance.collect(treasureDescription) instance.collect(some()) instance.addCommemorativePhoto(treasureDescription, someString()) - instance.hunterPath.addLocation(Coordinates(some() % 180, some() % 90)) +// instance.hunterPath.addLocation(Coordinates(some() % 180, some() % 90)) return instance } } \ No newline at end of file diff --git a/docs/development.md b/docs/development.md index ced74ba..4765008 100644 --- a/docs/development.md +++ b/docs/development.md @@ -35,6 +35,14 @@ When using gradle directly the token can be delivered as a parameter: `-PMAPBOX_ CapturePhotoIntent --> TreasuresEditorActivity SearchingActivity --> MapActivity : show map MapActivity --> SearchingActivity + ResultActivity --> CapturePhotoIntent : make commemorative photo + CapturePhotoIntent --> ResultActivity + ResultActivity --> CommemorativeActivity : show commemorative photo + CommemorativeActivity --> ResultActivity + TreasureSelectorActivity --> CommemorativeActivity : show commemorative photo + CommemorativeActivity --> CapturePhotoIntent : replace\n commemorative photo + CapturePhotoIntent --> CommemorativeActivity + CommemorativeActivity --> TreasureSelectorActivity MainActivity --> FacebookActivity FacebookActivity --> MainActivity @@ -55,6 +63,7 @@ When using gradle directly the token can be delivered as a parameter: `-PMAPBOX_ MapActivity --> FacebookActivity FacebookActivity --> MapActivity + note right of QrScanIntent: INTENT note right of CapturePhotoIntent: INTENT ``` @@ -64,8 +73,7 @@ When using gradle directly the token can be delivered as a parameter: `-PMAPBOX_ There are three levels of state persistence. 1. **View Model level.** There is the ViewModel class that allows data to survive configuration changes such as screen rotations. Each stateful activity has a view model class (a - class - extending the `ViewModel`). + class extending the `ViewModel`). 2. **Saved instance state.** Data saved this way survives system initiated process death (e.g. removing the process due to lack of memory). Saving instance state should be done through view model. The view model class aggregates an instance of the `SavedStateHandle`. When the data is changed, the view model should