From 1676c9f6dae21e60b7cd77b92300fca83cbbeaf4 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Thu, 23 Mar 2023 19:01:06 +0100 Subject: [PATCH 1/5] Replace Controllers with Activities for location+geocoding Signed-off-by: Marcel Hibbe --- app/src/main/AndroidManifest.xml | 10 + .../talk/controllers/ChatController.kt | 11 +- .../GeocodingActivity.kt} | 169 ++++++---- .../talk/location/GeocodingResult.kt | 31 ++ .../LocationPickerActivity.kt} | 310 ++++++++++-------- .../nextcloud/talk/utils/bundle/BundleKeys.kt | 1 + ...r_geocoding.xml => activity_geocoding.xml} | 19 ++ ...ler_location.xml => activity_location.xml} | 25 ++ 8 files changed, 358 insertions(+), 218 deletions(-) rename app/src/main/java/com/nextcloud/talk/{controllers/GeocodingController.kt => location/GeocodingActivity.kt} (52%) create mode 100644 app/src/main/java/com/nextcloud/talk/location/GeocodingResult.kt rename app/src/main/java/com/nextcloud/talk/{controllers/LocationPickerController.kt => location/LocationPickerActivity.kt} (68%) rename app/src/main/res/layout/{controller_geocoding.xml => activity_geocoding.xml} (56%) rename app/src/main/res/layout/{controller_location.xml => activity_location.xml} (81%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9cbe6f53..da49e3702 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -194,6 +194,16 @@ android:name=".messagesearch.MessageSearchActivity" android:theme="@style/AppTheme" /> + + + + diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index 48a693b6b..c42dbbaa1 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -134,6 +134,7 @@ import com.nextcloud.talk.extensions.loadAvatarOrImagePreview import com.nextcloud.talk.jobs.DownloadFileToCacheWorker import com.nextcloud.talk.jobs.ShareOperationWorker import com.nextcloud.talk.jobs.UploadAndShareFilesWorker +import com.nextcloud.talk.location.LocationPickerActivity import com.nextcloud.talk.messagesearch.MessageSearchActivity import com.nextcloud.talk.models.domain.ReactionAddedModel import com.nextcloud.talk.models.domain.ReactionDeletedModel @@ -1767,13 +1768,9 @@ class ChatController(args: Bundle) : fun showShareLocationScreen() { Log.d(TAG, "showShareLocationScreen") - val bundle = Bundle() - bundle.putString(KEY_ROOM_TOKEN, roomToken) - router.pushController( - RouterTransaction.with(LocationPickerController(bundle)) - .pushChangeHandler(HorizontalChangeHandler()) - .popChangeHandler(HorizontalChangeHandler()) - ) + val intent = Intent(activity, LocationPickerActivity::class.java) + intent.putExtra(KEY_ROOM_TOKEN, roomToken) + activity!!.startActivity(intent) } private fun showConversationInfoScreen() { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/GeocodingController.kt b/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt similarity index 52% rename from app/src/main/java/com/nextcloud/talk/controllers/GeocodingController.kt rename to app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt index 9b09095f5..e22562978 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/GeocodingController.kt +++ b/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt @@ -18,32 +18,33 @@ * along with this program. If not, see . */ -package com.nextcloud.talk.controllers +package com.nextcloud.talk.location import android.app.SearchManager import android.content.Context +import android.content.Intent +import android.graphics.drawable.ColorDrawable import android.os.Build import android.os.Bundle import android.text.InputType import android.util.Log import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem -import android.view.View import android.view.inputmethod.EditorInfo import android.widget.AdapterView import android.widget.Toast import androidx.appcompat.widget.SearchView +import androidx.core.content.res.ResourcesCompat import androidx.core.view.MenuItemCompat import androidx.preference.PreferenceManager import autodagger.AutoInjector import com.nextcloud.talk.R +import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.adapters.GeocodingAdapter import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication -import com.nextcloud.talk.controllers.base.BaseController -import com.nextcloud.talk.controllers.util.viewBinding -import com.nextcloud.talk.databinding.ControllerGeocodingBinding +import com.nextcloud.talk.databinding.ActivityGeocodingBinding +import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.bundle.BundleKeys import fr.dudie.nominatim.client.TalkJsonNominatimClient import fr.dudie.nominatim.model.Address @@ -57,13 +58,11 @@ import org.osmdroid.config.Configuration import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) -class GeocodingController(args: Bundle) : - BaseController( - R.layout.controller_geocoding, - args - ), +class GeocodingActivity : + BaseActivity(), SearchView.OnQueryTextListener { - private val binding: ControllerGeocodingBinding? by viewBinding(ControllerGeocodingBinding::bind) + + private lateinit var binding: ActivityGeocodingBinding @Inject lateinit var ncApi: NcApi @@ -71,7 +70,7 @@ class GeocodingController(args: Bundle) : @Inject lateinit var okHttpClient: OkHttpClient - var roomToken: String? + lateinit var roomToken: String var nominatimClient: TalkJsonNominatimClient? = null var searchItem: MenuItem? = null @@ -81,52 +80,88 @@ class GeocodingController(args: Bundle) : lateinit var adapter: GeocodingAdapter private var geocodingResults: List
= ArrayList() - constructor(args: Bundle, listener: LocationPickerController) : this(args) { - targetController = listener - } - - init { - setHasOptionsMenu(true) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) + + binding = ActivityGeocodingBinding.inflate(layoutInflater) + setupActionBar() + setupSystemColors() + setContentView(binding.root) + Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context)) - query = args.getString(BundleKeys.KEY_GEOCODING_QUERY) - roomToken = args.getString(BundleKeys.KEY_ROOM_TOKEN) + + roomToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!! + query = intent.getStringExtra(BundleKeys.KEY_GEOCODING_QUERY) } - private fun initAdapter(addresses: List
) { - adapter = GeocodingAdapter(binding?.geocodingResults?.context!!, addresses) - binding?.geocodingResults?.adapter = adapter - } - - override fun onAttach(view: View) { - super.onAttach(view) - + override fun onStart() { + super.onStart() initAdapter(geocodingResults) - initGeocoder() + } + + override fun onResume() { + super.onResume() + if (!query.isNullOrEmpty()) { searchLocation() } else { Log.e(TAG, "search string that was passed to GeocodingController was null or empty") } - binding?.geocodingResults?.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> + binding.geocodingResults.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> val address: Address = adapter.getItem(position) as Address - val listener: GeocodingResultListener? = targetController as GeocodingResultListener? - listener?.receiveChosenGeocodingResult(address.latitude, address.longitude, address.displayName) - router.popCurrentController() + val geocodingResult = GeocodingResult(address.latitude, address.longitude, address.displayName) + + val intent = Intent(this, LocationPickerActivity::class.java) + intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken) + intent.putExtra(BundleKeys.KEY_GEOCODING_RESULT, geocodingResult) + startActivity(intent) } } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.menu_geocoding, menu) + private fun setupActionBar() { + setSupportActionBar(binding.geocodingToolbar) + binding.geocodingToolbar.setNavigationOnClickListener { + onBackPressed() + } + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent))) + supportActionBar?.title = "" + } + + private fun setupSystemColors() { + DisplayUtils.applyColorToStatusBar( + this, + ResourcesCompat.getColor( + resources, + R.color.appbar, + null + ) + ) + DisplayUtils.applyColorToNavigationBar( + this.window, + ResourcesCompat.getColor(resources, R.color.bg_default, null) + ) + } + + private fun initAdapter(addresses: List
) { + adapter = GeocodingAdapter(binding.geocodingResults.context!!, addresses) + binding.geocodingResults.adapter = adapter + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + super.onCreateOptionsMenu(menu) + menuInflater.inflate(R.menu.menu_geocoding, menu) searchItem = menu.findItem(R.id.geocoding_action_search) initSearchView() searchItem?.expandActionView() searchView?.setQuery(query, false) searchView?.clearFocus() + return true } override fun onQueryTextSubmit(query: String?): Boolean { @@ -141,38 +176,38 @@ class GeocodingController(args: Bundle) : } private fun initSearchView() { - if (activity != null) { - val searchManager = activity!!.getSystemService(Context.SEARCH_SERVICE) as SearchManager - if (searchItem != null) { - searchView = MenuItemCompat.getActionView(searchItem) as SearchView - searchView?.maxWidth = Int.MAX_VALUE - searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER - var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) { - imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING - } - searchView?.imeOptions = imeOptions - searchView?.queryHint = resources!!.getString(R.string.nc_search) - searchView?.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName)) - searchView?.setOnQueryTextListener(this) - - searchItem?.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { - override fun onMenuItemActionExpand(menuItem: MenuItem): Boolean { - return true - } - - override fun onMenuItemActionCollapse(menuItem: MenuItem): Boolean { - router.popCurrentController() - return true - } - }) + val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager + if (searchItem != null) { + searchView = MenuItemCompat.getActionView(searchItem) as SearchView + searchView?.maxWidth = Int.MAX_VALUE + searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER + var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) { + imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING } + searchView?.imeOptions = imeOptions + searchView?.queryHint = resources!!.getString(R.string.nc_search) + searchView?.setSearchableInfo(searchManager.getSearchableInfo(componentName)) + searchView?.setOnQueryTextListener(this) + + searchItem?.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { + override fun onMenuItemActionExpand(menuItem: MenuItem): Boolean { + return true + } + + override fun onMenuItemActionCollapse(menuItem: MenuItem): Boolean { + val intent = Intent(context, LocationPickerActivity::class.java) + intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken) + startActivity(intent) + return true + } + }) } } private fun initGeocoder() { - val baseUrl = context!!.getString(R.string.osm_geocoder_url) - val email = context!!.getString(R.string.osm_geocoder_contact) + val baseUrl = getString(R.string.osm_geocoder_url) + val email = context.getString(R.string.osm_geocoder_contact) nominatimClient = TalkJsonNominatimClient(baseUrl, okHttpClient, email) } @@ -206,11 +241,7 @@ class GeocodingController(args: Bundle) : } } - interface GeocodingResultListener { - fun receiveChosenGeocodingResult(lat: Double, lon: Double, name: String) - } - companion object { - private const val TAG = "GeocodingController" + private val TAG = GeocodingActivity::class.java.simpleName } } diff --git a/app/src/main/java/com/nextcloud/talk/location/GeocodingResult.kt b/app/src/main/java/com/nextcloud/talk/location/GeocodingResult.kt new file mode 100644 index 000000000..544e2ad16 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/location/GeocodingResult.kt @@ -0,0 +1,31 @@ +/* + * Nextcloud Talk application + * + * @author Marcel Hibbe + * Copyright (C) 2023 Marcel Hibbe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.location + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class GeocodingResult( + val lat: Double, + val lon: Double, + var displayName: String +) : Parcelable diff --git a/app/src/main/java/com/nextcloud/talk/controllers/LocationPickerController.kt b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt similarity index 68% rename from app/src/main/java/com/nextcloud/talk/controllers/LocationPickerController.kt rename to app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt index ee21e3d48..a413a1b50 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/LocationPickerController.kt +++ b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt @@ -18,11 +18,13 @@ * along with this program. If not, see . */ -package com.nextcloud.talk.controllers +package com.nextcloud.talk.location import android.Manifest +import android.app.Activity import android.app.SearchManager import android.content.Context +import android.content.Intent import android.content.pm.PackageManager import android.graphics.drawable.ColorDrawable import android.location.Location @@ -33,7 +35,6 @@ import android.os.Bundle import android.text.InputType import android.util.Log import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.inputmethod.EditorInfo @@ -44,19 +45,17 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.view.MenuItemCompat import androidx.preference.PreferenceManager import autodagger.AutoInjector -import com.bluelinelabs.conductor.RouterTransaction -import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler import com.nextcloud.talk.R +import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication -import com.nextcloud.talk.controllers.base.BaseController -import com.nextcloud.talk.controllers.util.viewBinding -import com.nextcloud.talk.databinding.ControllerLocationBinding +import com.nextcloud.talk.databinding.ActivityLocationBinding import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.bundle.BundleKeys +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_GEOCODING_RESULT import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN import fr.dudie.nominatim.client.TalkJsonNominatimClient import fr.dudie.nominatim.model.Address @@ -82,15 +81,12 @@ import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) -class LocationPickerController(args: Bundle) : - BaseController( - R.layout.controller_location, - args - ), +class LocationPickerActivity : + BaseActivity(), SearchView.OnQueryTextListener, - LocationListener, - GeocodingController.GeocodingResultListener { - private val binding: ControllerLocationBinding? by viewBinding(ControllerLocationBinding::bind) + LocationListener { + + private lateinit var binding: ActivityLocationBinding @Inject lateinit var ncApi: NcApi @@ -103,38 +99,102 @@ class LocationPickerController(args: Bundle) : var nominatimClient: TalkJsonNominatimClient? = null - var roomToken: String? + lateinit var roomToken: String + var geocodingResult: GeocodingResult? = null var myLocation: GeoPoint = GeoPoint(COORDINATE_ZERO, COORDINATE_ZERO) private var locationManager: LocationManager? = null private lateinit var locationOverlay: MyLocationNewOverlay - var moveToCurrentLocationWasClicked: Boolean = true + var moveToCurrentLocation: Boolean = true var readyToShareLocation: Boolean = false var searchItem: MenuItem? = null var searchView: SearchView? = null - var receivedChosenGeocodingResult: Boolean = false - var geocodedLat: Double = 0.0 - var geocodedLon: Double = 0.0 - var geocodedName: String = "" - - init { - setHasOptionsMenu(true) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) + + binding = ActivityLocationBinding.inflate(layoutInflater) + setupActionBar() + setupSystemColors() + setContentView(binding.root) + getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context)) - roomToken = args.getString(KEY_ROOM_TOKEN) + roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!! + geocodingResult = intent.getParcelableExtra(KEY_GEOCODING_RESULT) } - override fun onAttach(view: View) { - super.onAttach(view) + override fun onStart() { + super.onStart() initMap() } + override fun onResume() { + super.onResume() + + if (geocodingResult != null) { + moveToCurrentLocation = false + } + + setLocationDescription(false, geocodingResult != null) + binding.shareLocation.isClickable = false + binding.shareLocation.setOnClickListener { + if (readyToShareLocation) { + shareLocation( + binding.map.mapCenter?.latitude, + binding.map.mapCenter?.longitude, + binding.placeName.text.toString() + ) + } else { + Log.w(TAG, "readyToShareLocation was false while user tried to share location.") + } + } + } + + private fun setupActionBar() { + setSupportActionBar(binding.locationPickerToolbar) + binding.locationPickerToolbar.setNavigationOnClickListener { + onBackPressed() + } + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent))) + supportActionBar?.title = context.getString(R.string.nc_share_location) + } + + private fun setupSystemColors() { + DisplayUtils.applyColorToStatusBar( + this, + ResourcesCompat.getColor( + resources, + R.color.appbar, + null + ) + ) + DisplayUtils.applyColorToNavigationBar( + this.window, + ResourcesCompat.getColor(resources, R.color.bg_default, null) + ) + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + super.onCreateOptionsMenu(menu) + menuInflater.inflate(R.menu.menu_locationpicker, menu) + return true + } + + override fun onPrepareOptionsMenu(menu: Menu): Boolean { + super.onPrepareOptionsMenu(menu) + searchItem = menu.findItem(R.id.location_action_search) + initSearchView() + return true + } + @Suppress("Detekt.TooGenericExceptionCaught") - override fun onDetach(view: View) { - super.onDetach(view) + override fun onStop() { + super.onStop() try { locationManager!!.removeUpdates(this) @@ -145,68 +205,29 @@ class LocationPickerController(args: Bundle) : locationOverlay.disableMyLocation() } - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - super.onCreateOptionsMenu(menu, inflater) - inflater.inflate(R.menu.menu_locationpicker, menu) - searchItem = menu.findItem(R.id.location_action_search) - initSearchView() - } - - override fun onPrepareOptionsMenu(menu: Menu) { - super.onPrepareOptionsMenu(menu) - actionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent))) - actionBar?.title = context!!.getString(R.string.nc_share_location) - } - - override val title: String - get() = - resources!!.getString(R.string.nc_share_location) - - override fun onViewBound(view: View) { - setLocationDescription(false, receivedChosenGeocodingResult) - binding?.shareLocation?.isClickable = false - binding?.shareLocation?.setOnClickListener { - if (readyToShareLocation) { - shareLocation( - binding?.map?.mapCenter?.latitude, - binding?.map?.mapCenter?.longitude, - binding?.placeName?.text.toString() - ) - } else { - Log.w(TAG, "readyToShareLocation was false while user tried to share location.") - } - } - } - private fun initSearchView() { - if (activity != null) { - val searchManager = activity!!.getSystemService(Context.SEARCH_SERVICE) as SearchManager - if (searchItem != null) { - searchView = MenuItemCompat.getActionView(searchItem) as SearchView - searchView?.maxWidth = Int.MAX_VALUE - searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER - var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) { - imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING - } - searchView?.imeOptions = imeOptions - searchView?.queryHint = resources!!.getString(R.string.nc_search) - searchView?.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName)) - searchView?.setOnQueryTextListener(this) + val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager + if (searchItem != null) { + searchView = MenuItemCompat.getActionView(searchItem) as SearchView + searchView?.maxWidth = Int.MAX_VALUE + searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER + var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) { + imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING } + searchView?.imeOptions = imeOptions + searchView?.queryHint = resources!!.getString(R.string.nc_search) + searchView?.setSearchableInfo(searchManager.getSearchableInfo(componentName)) + searchView?.setOnQueryTextListener(this) } } override fun onQueryTextSubmit(query: String?): Boolean { if (!query.isNullOrEmpty()) { - val bundle = Bundle() - bundle.putString(BundleKeys.KEY_GEOCODING_QUERY, query) - bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken) - router.pushController( - RouterTransaction.with(GeocodingController(bundle, this)) - .pushChangeHandler(HorizontalChangeHandler()) - .popChangeHandler(HorizontalChangeHandler()) - ) + val intent = Intent(this, GeocodingActivity::class.java) + intent.putExtra(BundleKeys.KEY_GEOCODING_QUERY, query) + intent.putExtra(KEY_ROOM_TOKEN, roomToken) + startActivity(intent) } return true } @@ -217,10 +238,10 @@ class LocationPickerController(args: Bundle) : @Suppress("Detekt.TooGenericExceptionCaught", "Detekt.ComplexMethod") private fun initMap() { - binding?.map?.setTileSource(TileSourceFactory.MAPNIK) - binding?.map?.onResume() + binding.map.setTileSource(TileSourceFactory.MAPNIK) + binding.map.onResume() - locationManager = activity!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager + locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager if (!isLocationPermissionsGranted()) { requestLocationPermissions() @@ -229,12 +250,12 @@ class LocationPickerController(args: Bundle) : } val copyrightOverlay = CopyrightOverlay(context) - binding?.map?.overlays?.add(copyrightOverlay) + binding.map.overlays.add(copyrightOverlay) - binding?.map?.setMultiTouchControls(true) - binding?.map?.isTilesScaledToDpi = true + binding.map.setMultiTouchControls(true) + binding.map.isTilesScaledToDpi = true - locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(context), binding?.map) + locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(context), binding.map) locationOverlay.enableMyLocation() locationOverlay.setPersonHotspot(PERSON_HOT_SPOT_X, PERSON_HOT_SPOT_Y) locationOverlay.setPersonIcon( @@ -242,24 +263,24 @@ class LocationPickerController(args: Bundle) : ResourcesCompat.getDrawable(resources!!, R.drawable.current_location_circle, null) ) ) - binding?.map?.overlays?.add(locationOverlay) + binding.map.overlays.add(locationOverlay) - val mapController = binding?.map?.controller + val mapController = binding.map.controller - if (receivedChosenGeocodingResult) { - mapController?.setZoom(ZOOM_LEVEL_RECEIVED_RESULT) + if (geocodingResult != null) { + mapController.setZoom(ZOOM_LEVEL_RECEIVED_RESULT) } else { - mapController?.setZoom(ZOOM_LEVEL_DEFAULT) + mapController.setZoom(ZOOM_LEVEL_DEFAULT) } - val zoomToCurrentPositionOnFirstFix = !receivedChosenGeocodingResult + val zoomToCurrentPositionOnFirstFix = geocodingResult == null locationOverlay.runOnFirstFix { if (locationOverlay.myLocation != null) { myLocation = locationOverlay.myLocation if (zoomToCurrentPositionOnFirstFix) { - activity!!.runOnUiThread { - mapController?.setZoom(ZOOM_LEVEL_DEFAULT) - mapController?.setCenter(myLocation) + runOnUiThread { + mapController.setZoom(ZOOM_LEVEL_DEFAULT) + mapController.setCenter(myLocation) } } } else { @@ -269,20 +290,22 @@ class LocationPickerController(args: Bundle) : } } - if (receivedChosenGeocodingResult && geocodedLat != COORDINATE_ZERO && geocodedLon != COORDINATE_ZERO) { - mapController?.setCenter(GeoPoint(geocodedLat, geocodedLon)) - } - - binding?.centerMapButton?.setOnClickListener { - if (myLocation.latitude == COORDINATE_ZERO && myLocation.longitude == COORDINATE_ZERO) { - Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show() - } else { - mapController?.animateTo(myLocation) - moveToCurrentLocationWasClicked = true + geocodingResult?.let { + if (it.lat != COORDINATE_ZERO && it.lon != COORDINATE_ZERO) { + mapController.setCenter(GeoPoint(it.lat, it.lon)) } } - binding?.map?.addMapListener( + binding.centerMapButton.setOnClickListener { + if (myLocation.latitude == COORDINATE_ZERO && myLocation.longitude == COORDINATE_ZERO) { + Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show() + } else { + mapController.animateTo(myLocation) + moveToCurrentLocation = true + } + } + + binding.map.addMapListener( delayedMapListener() ) } @@ -293,17 +316,17 @@ class LocationPickerController(args: Bundle) : override fun onScroll(paramScrollEvent: ScrollEvent): Boolean { try { when { - moveToCurrentLocationWasClicked -> { + moveToCurrentLocation -> { setLocationDescription(isGpsLocation = true, isGeocodedResult = false) - moveToCurrentLocationWasClicked = false + moveToCurrentLocation = false } - receivedChosenGeocodingResult -> { - binding?.shareLocation?.isClickable = true + geocodingResult != null -> { + binding.shareLocation.isClickable = true setLocationDescription(isGpsLocation = false, isGeocodedResult = true) - receivedChosenGeocodingResult = false + geocodingResult = null } else -> { - binding?.shareLocation?.isClickable = true + binding.shareLocation.isClickable = true setLocationDescription(isGpsLocation = false, isGeocodedResult = false) } } @@ -349,35 +372,35 @@ class LocationPickerController(args: Bundle) : " and there is no alternative like UnifiedNlp installed. Furthermore no GPS is " + "supported." ) - Toast.makeText(context, context?.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG) + Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG) .show() } } } catch (e: SecurityException) { Log.e(TAG, "Error when requesting location updates. Permissions may be missing.", e) - Toast.makeText(context, context?.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show() + Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show() } catch (e: Exception) { Log.e(TAG, "Error when requesting location updates.", e) - Toast.makeText(context, context?.getString(R.string.nc_common_error_sorry), Toast.LENGTH_LONG).show() + Toast.makeText(context, context.getString(R.string.nc_common_error_sorry), Toast.LENGTH_LONG).show() } } private fun setLocationDescription(isGpsLocation: Boolean, isGeocodedResult: Boolean) { when { isGpsLocation -> { - binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_current_location) - binding?.placeName?.visibility = View.GONE - binding?.placeName?.text = "" + binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_current_location) + binding.placeName.visibility = View.GONE + binding.placeName.text = "" } isGeocodedResult -> { - binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_this_location) - binding?.placeName?.visibility = View.VISIBLE - binding?.placeName?.text = geocodedName + binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location) + binding.placeName.visibility = View.VISIBLE + binding.placeName.text = geocodingResult?.displayName } else -> { - binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_this_location) - binding?.placeName?.visibility = View.GONE - binding?.placeName?.text = "" + binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location) + binding.placeName.visibility = View.GONE + binding.placeName.text = "" } } } @@ -395,11 +418,14 @@ class LocationPickerController(args: Bundle) : } private fun executeShareLocation(selectedLat: Double?, selectedLon: Double?, locationName: String?) { + binding.roundedImageView.visibility = View.GONE + binding.sendingLocationProgressbar.visibility = View.VISIBLE + val objectId = "geo:$selectedLat,$selectedLon" var locationNameToShare = locationName if (locationNameToShare.isNullOrBlank()) { - locationNameToShare = resources?.getString(R.string.nc_shared_location) + locationNameToShare = resources.getString(R.string.nc_shared_location) } val metaData: String = @@ -410,8 +436,8 @@ class LocationPickerController(args: Bundle) : val apiVersion = ApiUtils.getChatApiVersion(currentUser, intArrayOf(1)) ncApi.sendLocation( - ApiUtils.getCredentials(currentUser?.username, currentUser?.token), - ApiUtils.getUrlToSendLocation(apiVersion, currentUser?.baseUrl, roomToken), + ApiUtils.getCredentials(currentUser.username, currentUser.token), + ApiUtils.getUrlToSendLocation(apiVersion, currentUser.baseUrl, roomToken), "geo-location", objectId, metaData @@ -424,13 +450,13 @@ class LocationPickerController(args: Bundle) : } override fun onNext(t: GenericOverall) { - router.popCurrentController() + finish() } override fun onError(e: Throwable) { Log.e(TAG, "error when trying to share location", e) Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show() - router.popCurrentController() + finish() } override fun onComplete() { @@ -472,6 +498,8 @@ class LocationPickerController(args: Bundle) : permissions: Array, grantResults: IntArray ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + fun areAllGranted(grantResults: IntArray): Boolean { grantResults.forEach { if (it == PackageManager.PERMISSION_DENIED) return false @@ -487,13 +515,6 @@ class LocationPickerController(args: Bundle) : } } - override fun receiveChosenGeocodingResult(lat: Double, lon: Double, name: String) { - receivedChosenGeocodingResult = true - geocodedLat = lat - geocodedLon = lon - geocodedName = name - } - private fun initGeocoder() { val baseUrl = context!!.getString(R.string.osm_geocoder_url) val email = context!!.getString(R.string.osm_geocoder_contact) @@ -542,8 +563,13 @@ class LocationPickerController(args: Bundle) : // empty } + override fun onBackPressed() { + setResult(Activity.RESULT_CANCELED) + finish() + } + companion object { - private const val TAG = "LocPicker" + private val TAG = LocationPickerActivity::class.java.simpleName private const val REQUEST_PERMISSIONS_REQUEST_CODE = 1 private const val PERSON_HOT_SPOT_X: Float = 20.0F private const val PERSON_HOT_SPOT_Y: Float = 20.0F diff --git a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt index efd7ee0df..4b643b1ed 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt @@ -85,4 +85,5 @@ object BundleKeys { const val KEY_NOTIFICATION_RESTRICT_DELETION = "KEY_NOTIFICATION_RESTRICT_DELETION" const val KEY_DISMISS_RECORDING_URL = "KEY_DISMISS_RECORDING_URL" const val KEY_SHARE_RECORDING_TO_CHAT_URL = "KEY_SHARE_RECORDING_TO_CHAT_URL" + const val KEY_GEOCODING_RESULT = "KEY_GEOCODING_RESULT" } diff --git a/app/src/main/res/layout/controller_geocoding.xml b/app/src/main/res/layout/activity_geocoding.xml similarity index 56% rename from app/src/main/res/layout/controller_geocoding.xml rename to app/src/main/res/layout/activity_geocoding.xml index 5630edd04..545467887 100644 --- a/app/src/main/res/layout/controller_geocoding.xml +++ b/app/src/main/res/layout/activity_geocoding.xml @@ -20,11 +20,30 @@ --> + + + + + + + + + + + Date: Wed, 29 Mar 2023 10:45:11 +0200 Subject: [PATCH 2/5] Remove geocoding activity from history by FLAG_ACTIVITY_CLEAR_TOP With this, it's not opened again with onBackPressed in location view. But it still opens again when app was interrupted and being shown again. Signed-off-by: Marcel Hibbe --- app/src/main/AndroidManifest.xml | 6 ++---- .../java/com/nextcloud/talk/location/GeocodingActivity.kt | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index da49e3702..5a1956fa0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -196,13 +196,11 @@ + android:theme="@style/AppTheme" /> + android:theme="@style/AppTheme" /> diff --git a/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt b/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt index e22562978..cf36d04d2 100644 --- a/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/location/GeocodingActivity.kt @@ -115,6 +115,7 @@ class GeocodingActivity : val geocodingResult = GeocodingResult(address.latitude, address.longitude, address.displayName) val intent = Intent(this, LocationPickerActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken) intent.putExtra(BundleKeys.KEY_GEOCODING_RESULT, geocodingResult) startActivity(intent) @@ -197,6 +198,7 @@ class GeocodingActivity : override fun onMenuItemActionCollapse(menuItem: MenuItem): Boolean { val intent = Intent(context, LocationPickerActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken) startActivity(intent) return true From f3230498155903ad3804c7ce1282ff7c9224ca36 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 29 Mar 2023 11:50:49 +0200 Subject: [PATCH 3/5] Fix to keep map position when app was in background Signed-off-by: Marcel Hibbe --- .../java/com/nextcloud/talk/location/LocationPickerActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt index a413a1b50..8418f51ed 100644 --- a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt @@ -273,7 +273,7 @@ class LocationPickerActivity : mapController.setZoom(ZOOM_LEVEL_DEFAULT) } - val zoomToCurrentPositionOnFirstFix = geocodingResult == null + val zoomToCurrentPositionOnFirstFix = geocodingResult == null && moveToCurrentLocation locationOverlay.runOnFirstFix { if (locationOverlay.myLocation != null) { myLocation = locationOverlay.myLocation From 4ab3d78458618a2d07d0c1fe25c6d87ebd7eb2b3 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 29 Mar 2023 12:25:11 +0200 Subject: [PATCH 4/5] Keep position on screen rotation Signed-off-by: Marcel Hibbe --- .../talk/location/LocationPickerActivity.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt index 8418f51ed..c6fcc8891 100644 --- a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt @@ -108,6 +108,10 @@ class LocationPickerActivity : var moveToCurrentLocation: Boolean = true var readyToShareLocation: Boolean = false + + private var mapCenterLat: Double = 0.0 + private var mapCenterLon: Double = 0.0 + var searchItem: MenuItem? = null var searchView: SearchView? = null @@ -115,6 +119,12 @@ class LocationPickerActivity : super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) + if (savedInstanceState != null) { + moveToCurrentLocation = savedInstanceState.getBoolean("moveToCurrentLocation") == true + mapCenterLat = savedInstanceState.getDouble("mapCenterLat") + mapCenterLon = savedInstanceState.getDouble("mapCenterLon") + } + binding = ActivityLocationBinding.inflate(layoutInflater) setupActionBar() setupSystemColors() @@ -153,6 +163,13 @@ class LocationPickerActivity : } } + override fun onSaveInstanceState(bundle: Bundle) { + super.onSaveInstanceState(bundle) + bundle.putBoolean("moveToCurrentLocation", moveToCurrentLocation) + bundle.putDouble("mapCenterLat", binding.map.mapCenter.latitude) + bundle.putDouble("mapCenterLon", binding.map.mapCenter.longitude) + } + private fun setupActionBar() { setSupportActionBar(binding.locationPickerToolbar) binding.locationPickerToolbar.setNavigationOnClickListener { @@ -273,6 +290,10 @@ class LocationPickerActivity : mapController.setZoom(ZOOM_LEVEL_DEFAULT) } + if (mapCenterLat != 0.0 && mapCenterLon != 0.0) { + mapController.setCenter(GeoPoint(mapCenterLat, mapCenterLon)) + } + val zoomToCurrentPositionOnFirstFix = geocodingResult == null && moveToCurrentLocation locationOverlay.runOnFirstFix { if (locationOverlay.myLocation != null) { From bc96ffcd2065a62cf3fa136ed77a89942d17112b Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 29 Mar 2023 12:38:13 +0200 Subject: [PATCH 5/5] Fix to forget geocoding result when scrolled and then rotated device Signed-off-by: Marcel Hibbe --- .../com/nextcloud/talk/location/LocationPickerActivity.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt index c6fcc8891..84cb840c5 100644 --- a/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/location/LocationPickerActivity.kt @@ -119,10 +119,14 @@ class LocationPickerActivity : super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) + roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!! + geocodingResult = intent.getParcelableExtra(KEY_GEOCODING_RESULT) + if (savedInstanceState != null) { moveToCurrentLocation = savedInstanceState.getBoolean("moveToCurrentLocation") == true mapCenterLat = savedInstanceState.getDouble("mapCenterLat") mapCenterLon = savedInstanceState.getDouble("mapCenterLon") + geocodingResult = savedInstanceState.getParcelable("geocodingResult") } binding = ActivityLocationBinding.inflate(layoutInflater) @@ -131,9 +135,6 @@ class LocationPickerActivity : setContentView(binding.root) getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context)) - - roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!! - geocodingResult = intent.getParcelableExtra(KEY_GEOCODING_RESULT) } override fun onStart() { @@ -168,6 +169,7 @@ class LocationPickerActivity : bundle.putBoolean("moveToCurrentLocation", moveToCurrentLocation) bundle.putDouble("mapCenterLat", binding.map.mapCenter.latitude) bundle.putDouble("mapCenterLon", binding.map.mapCenter.longitude) + bundle.putParcelable("geocodingResult", geocodingResult) } private fun setupActionBar() {