Bimba.git

commit ab6f3b2734e4c4980326a5aca12cb88785e61df0

Author: Adam Evyčędo <git@apiote.xyz>

show feed name in search results

%!v(PANIC=String method: strings: negative Repeat count)


diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeFragment.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeFragment.kt
index fb91f012e086d05335c724054932e4adeb84d1bc..937651e34f7d64ab76dc0caeecf9ae19f23374ce 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeFragment.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeFragment.kt
@@ -4,8 +4,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later
 
 package xyz.apiote.bimba.czwek.dashboard.ui.home
 
-import android.content.Context
-import android.net.ConnectivityManager
 import android.os.Bundle
 import android.view.KeyEvent
 import android.view.LayoutInflater
@@ -40,6 +38,8 @@
 		val homeViewModel =
 			ViewModelProvider(this)[HomeViewModel::class.java]
 		homeViewModel.queryables.observe(viewLifecycleOwner) {
+			adapter.feedsSettings = homeViewModel.feedsSettings
+			adapter.feeds = homeViewModel.feeds
 			adapter.update(it)
 		}
 
@@ -74,12 +74,8 @@ 		binding.suggestionsRecycler.layoutManager = LinearLayoutManager(activity)
 		adapter = BimbaResultsAdapter(layoutInflater, activity, listOf())
 		binding.suggestionsRecycler.adapter = adapter
 
-		val cm = requireContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
 		binding.searchView.editText.addTextChangedListener(
-			homeViewModel.SearchBarWatcher(
-				requireContext(),
-				cm
-			)
+			homeViewModel.SearchBarWatcher(requireContext())
 		)
 		binding.searchView.editText.setOnKeyListener { v, keyCode, event ->
 			when (keyCode) {
@@ -107,4 +103,4 @@ 	override fun onDestroyView() {
 		super.onDestroyView()
 		_binding = null
 	}
-}
\ No newline at end of file
+}




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeViewModel.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeViewModel.kt
index bfe94f905401ecfea122365da7f6c07f5c47d910..38afc1078fe260f2e80a6553869cc720b446b48e 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeViewModel.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeViewModel.kt
@@ -16,19 +16,24 @@ import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import kotlinx.coroutines.launch
+import xyz.apiote.bimba.czwek.repo.FeedInfo
+import xyz.apiote.bimba.czwek.repo.OfflineRepository
 import xyz.apiote.bimba.czwek.repo.OnlineRepository
 import xyz.apiote.bimba.czwek.repo.Queryable
 import xyz.apiote.bimba.czwek.repo.TrafficResponseException
+import xyz.apiote.bimba.czwek.settings.feeds.FeedsSettings
 
 class HomeViewModel : ViewModel() {
 	private val mutableQueryables = MutableLiveData<List<Queryable>>()
 	val queryables: LiveData<List<Queryable>> = mutableQueryables
+	var feeds: Map<String, FeedInfo>? = null
+	var feedsSettings: FeedsSettings? = null
 
-	fun getQueryables(cm: ConnectivityManager, query: String, context: Context) {
+	fun getQueryables(query: String, context: Context) {
 		viewModelScope.launch {
 			try {
-				val repository = OnlineRepository()
-				mutableQueryables.value = repository.queryQueryables(cm, query, context) ?: emptyList()
+				getFeeds(context)
+				mutableQueryables.value = OnlineRepository().queryQueryables(query, context) ?: emptyList()
 			} catch (e: TrafficResponseException) {
 				// xxx intentionally no error showing in suggestions
 				Log.e("Suggestion", "$e")
@@ -36,9 +41,13 @@ 			}
 		}
 	}
 
-	inner class SearchBarWatcher(
-		private val context: Context, private val cm: ConnectivityManager
-	) : TextWatcher {
+	private suspend fun getFeeds(context: Context) {
+		feeds = OfflineRepository().getFeeds(context)
+		feedsSettings = FeedsSettings.load(context)
+	}
+
+
+	inner class SearchBarWatcher(private val context: Context) : TextWatcher {
 		private val handler = Handler(Looper.getMainLooper())
 		private var workRunnable = Runnable {}
 
@@ -52,9 +61,9 @@ 		override fun afterTextChanged(s: Editable?) {
 			handler.removeCallbacks(workRunnable)
 			workRunnable = Runnable {
 				val text = s.toString()
-				getQueryables(cm, text, context)
+				getQueryables(text, context)
 			}
 			handler.postDelayed(workRunnable, 750)
 		}
 	}
-}
\ No newline at end of file
+}




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt
index 4905c0f55b5ce6589d62fbaefd313b170a9fc639..dc8bdba932bf7327316bd331ae92791002adce35 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt
@@ -18,8 +18,8 @@ }
 
 interface Repository {
 	suspend fun getFeeds(
-		server: Server,
-		context: Context
+		context: Context,
+		server: Server = Server.get(context)
 	): Map<String, FeedInfo>?
 
 	suspend fun getDepartures(
@@ -45,13 +45,11 @@ 		context: Context
 	): Line?
 
 	suspend fun queryQueryables(
-		cm: ConnectivityManager,
 		query: String,
 		context: Context
 	): List<Queryable>?
 
 	suspend fun locateQueryables(
-		cm: ConnectivityManager,
 		position: Position,
 		context: Context
 	): List<Queryable>?




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt
index 9943189f8702bf06fd84fd25a1d919b8f3f181db..0a92c37cd563b5560cd44f559b7ff8ce787d82bb 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt
@@ -19,11 +19,11 @@ import java.net.URLEncoder
 
 class OfflineRepository : Repository {
 	override suspend fun getFeeds(
-		server: Server,
-		context: Context
+		context: Context,
+		server: Server
 	): Map<String, FeedInfo>? {
 		val file = File(
-			context.cacheDir, URLEncoder.encode(server.apiPath, "utf-8")
+			context.filesDir, URLEncoder.encode(server.apiPath, "utf-8")
 		)
 		if (!file.exists()) {
 			return emptyMap()
@@ -84,7 +84,6 @@ 		TODO("Not yet implemented")
 	}
 
 	override suspend fun queryQueryables(
-		cm: ConnectivityManager,
 		query: String,
 		context: Context
 	): List<Queryable>? {
@@ -92,7 +91,6 @@ 		TODO("Not yet implemented")
 	}
 
 	override suspend fun locateQueryables(
-		cm: ConnectivityManager,
 		position: Position,
 		context: Context
 	): List<Queryable>? {




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt
index a84e433fe5cb2fc1ca004ebc8b5852c1a9216fd2..e25943d37a5bb1d941a759ad6cd56a29f23b20ba 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt
@@ -50,14 +50,14 @@
 class OnlineRepository : Repository {
 	private fun saveFeedCache(server: Server, context: Context, rawResponse: ByteArray) {
 		val file = File(
-			context.cacheDir, URLEncoder.encode(server.apiPath, "utf-8")
+			context.filesDir, URLEncoder.encode(server.apiPath, "utf-8")
 		)
 		file.writeBytes(rawResponse)
 	}
 
 	override suspend fun getFeeds(
-		server: Server,
-		context: Context
+		context: Context,
+		server: Server
 	): Map<String, FeedInfo>? {
 		val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
 		val result =
@@ -210,20 +210,21 @@ 		}
 	}
 
 	override suspend fun queryQueryables(
-		cm: ConnectivityManager, query: String, context: Context
+		query: String, context: Context
 	): List<Queryable>? {
-		return getQueryables(cm, query, null, context, "query")
+		return getQueryables(query, null, context, "query")
 	}
 
 	override suspend fun locateQueryables(
-		cm: ConnectivityManager, position: Position, context: Context
+		position: Position, context: Context
 	): List<Queryable>? {
-		return getQueryables(cm, null, position, context, "locate")
+		return getQueryables(null, position, context, "locate")
 	}
 
 	private suspend fun getQueryables(
-		cm: ConnectivityManager, query: String?, position: Position?, context: Context, type: String
+		query: String?, position: Position?, context: Context, type: String
 	): List<Queryable>? {
+		val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
 		val result = when (type) {
 			"query" -> {
 				xyz.apiote.bimba.czwek.api.queryQueryables(cm, Server.get(context), query!!, limit = 12)




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt b/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt
index c59ee9c8f563016082f1d8fa69b1f379cd2e8e30..ef4757d062459420ae3714d74bce0c0592bcb441 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt
@@ -15,27 +15,32 @@ import androidx.recyclerview.widget.DiffUtil
 import androidx.recyclerview.widget.RecyclerView
 import xyz.apiote.bimba.czwek.R
 import xyz.apiote.bimba.czwek.departures.DeparturesActivity
+import xyz.apiote.bimba.czwek.repo.FeedInfo
 import xyz.apiote.bimba.czwek.repo.Line
 import xyz.apiote.bimba.czwek.repo.Queryable
 import xyz.apiote.bimba.czwek.repo.Stop
 import xyz.apiote.bimba.czwek.repo.StopStub
+import xyz.apiote.bimba.czwek.settings.feeds.FeedsSettings
 
 class BimbaViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
 	val root: View = itemView.findViewById(R.id.suggestion)
 	val icon: ImageView = itemView.findViewById(R.id.suggestion_image)
 	val title: TextView = itemView.findViewById(R.id.suggestion_title)
 	val description: TextView = itemView.findViewById(R.id.suggestion_description)
+	val feedName: TextView = itemView.findViewById(R.id.feed_name)
 
 	companion object {
 		fun bind(
 			queryable: Queryable,
 			holder: BimbaViewHolder?,
 			context: Context?,
+			feeds: Map<String, FeedInfo>?,
+			feedsSettings: FeedsSettings?,
 			onClickListener: (Queryable) -> Unit
 		) {
 			when (queryable) {
-				is Stop -> bindStop(queryable, holder, context)
-				is Line -> bindLine(queryable, holder, context)
+				is Stop -> bindStop(queryable, holder, context, feeds, feedsSettings)
+				is Line -> bindLine(queryable, holder, context, feeds, feedsSettings)
 			}
 			holder?.root?.setOnClickListener {
 				onClickListener(queryable)
@@ -72,12 +77,22 @@ 				onClickListener(stopStub)
 			}
 		}
 
-		private fun bindStop(stop: Stop, holder: BimbaViewHolder?, context: Context?) {
+		private fun bindStop(
+			stop: Stop,
+			holder: BimbaViewHolder?,
+			context: Context?,
+			feeds: Map<String, FeedInfo>?,
+			feedsSettings: FeedsSettings?
+		) {
 			holder?.icon?.apply {
 				setImageDrawable(stop.icon(context!!))
 				contentDescription = context.getString(R.string.stop_content_description)
 			}
 			holder?.title?.text = stop.name
+			if ((feedsSettings?.activeFeeds() ?: 0) > 1) {
+				holder?.feedName?.visibility = View.VISIBLE
+				holder?.feedName?.text = feeds?.get(stop.feedID)?.name ?: ""
+			}
 			context?.let {
 				stop.changeOptions(it).let { changeOptions ->
 					holder?.description?.apply {
@@ -88,11 +103,21 @@ 				}
 			}
 		}
 
-		private fun bindLine(line: Line, holder: BimbaViewHolder?, context: Context?) {
+		private fun bindLine(
+			line: Line,
+			holder: BimbaViewHolder?,
+			context: Context?,
+			feeds: Map<String, FeedInfo>?,
+			feedsSettings: FeedsSettings?
+		) {
 			holder?.icon?.apply {
 				setImageDrawable(line.icon(context!!))
 				contentDescription = line.type.name
 				colorFilter = null
+			}
+			if ((feedsSettings?.activeFeeds() ?: 0) > 1) {
+				holder?.feedName?.visibility = View.VISIBLE
+				holder?.feedName?.text = feeds?.get(line.feedID)?.name ?: ""
 			}
 			holder?.title?.text = line.name
 			holder?.description?.text = if (line.headsigns.size == 1) {
@@ -186,6 +211,8 @@ 		}
 
 	}
 
+	var feeds: Map<String, FeedInfo>? = null
+	var feedsSettings: FeedsSettings? = null
 	private val onClickListener: ((Queryable) -> Unit) = {
 		when (it) {
 			is Stop -> {
@@ -213,7 +240,14 @@ 		return BimbaViewHolder(rowView)
 	}
 
 	override fun onBindViewHolder(holder: BimbaViewHolder, position: Int) {
-		BimbaViewHolder.bind(queryables[position], holder, context, onClickListener)
+		BimbaViewHolder.bind(
+			queryables[position],
+			holder,
+			context,
+			feeds,
+			feedsSettings,
+			onClickListener
+		)
 	}
 
 	override fun getItemCount(): Int = queryables.size




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/search/ResultsActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/search/ResultsActivity.kt
index 2aded60740f242cfb8b7ac4283a21791bf8abc9e..6243e61e18928bc6551514c3f3195c511222738c 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/search/ResultsActivity.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/search/ResultsActivity.kt
@@ -25,10 +25,12 @@ import kotlinx.coroutines.launch
 import xyz.apiote.bimba.czwek.R
 import xyz.apiote.bimba.czwek.api.Error
 import xyz.apiote.bimba.czwek.databinding.ActivityResultsBinding
+import xyz.apiote.bimba.czwek.repo.OfflineRepository
 import xyz.apiote.bimba.czwek.repo.OnlineRepository
 import xyz.apiote.bimba.czwek.repo.Position
 import xyz.apiote.bimba.czwek.repo.Queryable
 import xyz.apiote.bimba.czwek.repo.TrafficResponseException
+import xyz.apiote.bimba.czwek.settings.feeds.FeedsSettings
 
 class ResultsActivity : AppCompatActivity(), LocationListener {
 	enum class Mode {
@@ -79,7 +81,7 @@ 			}
 		}
 	}
 
-	private fun getMode():Mode {
+	private fun getMode(): Mode {
 		return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
 			intent.extras!!.getSerializable("mode", Mode::class.java)!!
 		} else {
@@ -132,12 +134,21 @@ 		locationManager.removeUpdates(this)
 		handler.removeCallbacks(runnable)
 	}
 
+	private suspend fun getFeeds() {
+		if (adapter.feeds.isNullOrEmpty()) {
+			adapter.feeds = OfflineRepository().getFeeds(this)
+		}
+		if (adapter.feedsSettings == null) {
+			adapter.feedsSettings = FeedsSettings.load(this)
+		}
+	}
+
 	private fun getQueryablesByQuery(query: String, context: Context) {
-		val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
 		MainScope().launch {
 			try {
 				val repository = OnlineRepository()
-				val result = repository.queryQueryables(cm, query, context)
+				val result = repository.queryQueryables(query, context)
+				getFeeds()
 				updateItems(result)
 			} catch (e: TrafficResponseException) {
 				Log.w("Suggestion", "$e")
@@ -147,11 +158,11 @@ 		}
 	}
 
 	private fun getQueryablesByLocation(position: Position, context: Context) {
-		val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
 		MainScope().launch {
 			try {
 				val repository = OnlineRepository()
-				val result = repository.locateQueryables(cm, position, context)
+				val result = repository.locateQueryables(position, context)
+				getFeeds()
 				updateItems(result)
 			} catch (e: TrafficResponseException) {
 				Log.w("Suggestion", "$e")
@@ -195,4 +206,4 @@ 			binding.errorText.visibility = View.GONE
 			binding.resultsRecycler.visibility = View.VISIBLE
 		}
 	}
-}
\ No newline at end of file
+}




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt
index aaabcdc6a63e0a4d6da769274b660fd5db0611b0..13fd5163f5b2f5f7313d89cea0289946670e810c 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt
@@ -93,7 +93,7 @@
 		MainScope().launch {
 			val offlineRepository = OfflineRepository()
 			val offlineFeeds =
-				offlineRepository.getFeeds(Server.get(this@FeedChooserActivity), this@FeedChooserActivity)
+				offlineRepository.getFeeds(this@FeedChooserActivity)
 			if (!offlineFeeds.isNullOrEmpty()) {
 				feeds.putAll(offlineFeeds)
 				updateItems(offlineFeeds.map { it.value }, null)
@@ -101,7 +101,7 @@ 			}
 			try {
 				val repository = OnlineRepository()
 				val onlineFeeds =
-					repository.getFeeds(Server.get(this@FeedChooserActivity), this@FeedChooserActivity)
+					repository.getFeeds(this@FeedChooserActivity)
 				feeds.clear()
 				joinFeeds(offlineFeeds, onlineFeeds).let { joinedFeeds ->
 					feeds.putAll(joinedFeeds)




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt
index 9412dd8b17cd21c2ad90fd6448ec7acbbe4dbec9..91921e1025e74c19ad73d9d75cd4e39d5668bfec 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt
@@ -15,7 +15,8 @@
 @Serializable
 @OptIn(ExperimentalStdlibApi::class)
 data class FeedsSettings(val settings: MutableMap<String, FeedSettings>) {
-	fun getIDs() = settings.filter { it.value.enabled }.keys.joinToString(",")
+	fun activeFeeds() = settings.count { it.value.enabled && it.value.useOnline }
+	fun getIDs() = settings.filter { it.value.enabled && it.value.useOnline }.keys.joinToString(",")
 
 	fun save(context: Context, server: Server) {
 		val doc = KBson().dump(serializer(), this).toHexString()
@@ -28,7 +29,7 @@ 		}
 	}
 
 	companion object {
-		fun load(context: Context, apiPath: String): FeedsSettings {
+		fun load(context: Context, apiPath: String = Server.get(context).apiPath): FeedsSettings {
 			val doc = context.getSharedPreferences(
 				"feeds_settings",
 				Context.MODE_PRIVATE




diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedsViewModel.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedsViewModel.kt
index 22faaa10edbd16162766777f7d60ae45c7713ed5..edcd9f0503d5f81973bab770d443f5717dbe6255 100644
--- a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedsViewModel.kt
+++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedsViewModel.kt
@@ -5,14 +5,13 @@ import android.util.Log
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
-import xyz.apiote.bimba.czwek.api.Server
 
 class FeedsViewModel : ViewModel() {
 	private val _settings = MutableLiveData<FeedsSettings>()
 	val settings: LiveData<FeedsSettings> = _settings
 
 	fun loadSettings(context: Context) {
-		_settings.value = FeedsSettings.load(context, Server.get(context).apiPath)
+		_settings.value = FeedsSettings.load(context)
 	}
 
 	fun setSettings(feedID: String, feedSettings: FeedSettings) {




diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index a34a6f00d8c1c13f15c1498c63de29195cd4c75a..eb621f767365a76f5fa26f83738325eaefa828dc 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -25,14 +25,12 @@ 			android:layout_height="wrap_content"
 			android:layout_marginStart="8dp"
 			android:layout_marginTop="8dp"
 			android:layout_marginEnd="8dp"
-			android:contentDescription="@string/search_placeholder"
 			android:hint="@string/search_placeholder"
 			app:layout_constraintEnd_toEndOf="parent"
 			app:layout_constraintStart_toStartOf="parent"
 			app:layout_constraintTop_toTopOf="parent"
 			app:navigationIcon="@drawable/menu"
-			app:useDrawerArrowDrawable="true"
-			tool:ignore="ContentDescription" />
+			app:useDrawerArrowDrawable="true" />
 	</com.google.android.material.appbar.AppBarLayout>
 
 	<com.google.android.material.search.SearchView
@@ -67,7 +65,7 @@ 			app:layout_constraintBottom_toBottomOf="parent"
 			app:layout_constraintEnd_toEndOf="parent"
 			app:layout_constraintStart_toStartOf="parent"
 			app:layout_constraintTop_toTopOf="parent"
-			tool:ignore="ContentDescription" />
+			tool:ignore="ContentDescription,ImageContrastCheck" />
 
 	</androidx.constraintlayout.widget.ConstraintLayout>
 
@@ -80,5 +78,6 @@ 		android:layout_margin="16dp"
 		android:contentDescription="@string/home_fab_description"
 		android:src="@drawable/gps_black"
 		app:layout_constraintBottom_toBottomOf="parent"
-		app:layout_constraintEnd_toEndOf="parent" />
+		app:layout_constraintEnd_toEndOf="parent"
+		tool:ignore="ImageContrastCheck" />
 </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file




diff --git a/app/src/main/res/layout/result.xml b/app/src/main/res/layout/result.xml
index 75e4256123ce4cfe818cf5cd9be5558a3ab0ccff..ca09e81118eadcdf7ab34fed534d7e84c4169680 100644
--- a/app/src/main/res/layout/result.xml
+++ b/app/src/main/res/layout/result.xml
@@ -18,13 +18,11 @@ 		android:id="@+id/suggestion_image"
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
 		android:layout_marginStart="8dp"
-		android:layout_marginTop="8dp"
-		android:layout_marginBottom="8dp"
-		app:layout_constraintBottom_toBottomOf="parent"
+		app:layout_constraintBottom_toBottomOf="@+id/suggestion_title"
 		app:layout_constraintStart_toStartOf="parent"
-		app:layout_constraintTop_toTopOf="parent"
-		tool:src="@drawable/vehicle_black"
-		tool:ignore="ContentDescription" />
+		app:layout_constraintTop_toTopOf="@+id/suggestion_title"
+		tool:ignore="ContentDescription"
+		tool:src="@drawable/vehicle_black" />
 
 	<!-- todo maxWidth or separate layout for graphView -->
 	<com.google.android.material.textview.MaterialTextView
@@ -40,14 +38,25 @@ 		app:layout_constraintTop_toTopOf="parent"
 		tool:text="Tower Hill" />
 
 	<com.google.android.material.textview.MaterialTextView
+		android:id="@+id/feed_name"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:visibility="gone"
+		android:textAppearance="@style/TextAppearance.Material3.LabelSmall"
+		app:layout_constraintStart_toStartOf="@+id/suggestion_title"
+		app:layout_constraintTop_toBottomOf="@+id/suggestion_title"
+		tool:text="TfL London" />
+
+	<com.google.android.material.textview.MaterialTextView
 		android:id="@+id/suggestion_description"
 		style="@style/Theme.Bimba.SearchResult.Description"
 		android:layout_width="wrap_content"
-		android:maxWidth="360dp"
 		android:layout_height="wrap_content"
+		android:maxWidth="360dp"
+		android:layout_marginTop="4dp"
 		app:layout_constraintBottom_toBottomOf="parent"
 		app:layout_constraintStart_toStartOf="@+id/suggestion_title"
-		app:layout_constraintTop_toBottomOf="@+id/suggestion_title"
+		app:layout_constraintTop_toBottomOf="@+id/feed_name"
 		tool:text="Metropolitan » Baker Street, Tower Hill The Monument, Westminster, Piccadilly Circus, Oxford Street" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file