Bimba.git

commit fd440c27e34bf8fd70fa1cd50c289279ca494537

Author: Adam <git@apiote.xyz>

reformat

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


diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d2478c7b8a3b0a9eff5234a919762e5ff954ce86..3dda5bd2202ae415c42e7a46cbf35e869f85359d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,8 +36,7 @@ 			android:exported="false" />
 		<activity
 			android:name=".search.ResultsActivity"
 			android:exported="false"
-			android:label="@string/title_activity_results"
-			android:theme="@style/Theme.Bimba.Style" />
+			android:label="@string/title_activity_results" />
 		<activity
 			android:name=".dashboard.MainActivity"
 			android:exported="false"




diff --git a/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt b/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt
index db337e6501eacb2db359c1a0d07169c80cdf2ce2..6786b6a8fe2f3ee6a38d00b7b623fdddda9aee8d 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt
@@ -27,7 +27,7 @@ suspend fun locateItems(server: Server, plusCode: String): InputStream? {
 	return request(server, "items", mapOf("near" to plusCode))
 }
 
-suspend fun getDepartures(server: Server, stop: String, line: String?): InputStream? {
+suspend fun getDepartures(server: Server, stop: String, line: String? = null): InputStream? {
 	val params = mutableMapOf("code" to stop)
 	if (line != null) {
 		params["line"] = line




diff --git a/app/src/main/java/ml/adamsprogs/bimba/api/Responses.kt b/app/src/main/java/ml/adamsprogs/bimba/api/Responses.kt
index c909c287b157221e2c2104426ca740a7aca8657f..527f9975d70cd1b6a4dc629b3dd6ee8718eda5d0 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/api/Responses.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/api/Responses.kt
@@ -5,15 +5,6 @@ import java.io.InputStream
 
 interface DeparturesResponse {
 	companion object {
-		fun printable(it: String) = it.map {
-			when (Character.getType(it).toByte()) {
-				Character.CONTROL, Character.FORMAT, Character.PRIVATE_USE,
-				Character.SURROGATE, Character.UNASSIGNED, Character.OTHER_SYMBOL
-				-> "\\u%04x".format(it.code)
-				else -> it.toString()
-			}
-		}.joinToString("")
-
 		fun unmarshall(stream: InputStream): DeparturesResponse {
 			val reader = Reader(stream)
 			when (reader.readUInt()) {
@@ -142,6 +133,6 @@ 		}
 	}
 }
 
-data class Error(val message: String) : ItemsResponse, DeparturesResponse {
+data class Error(val message: String) : ItemsResponse, DeparturesResponse, FeedsResponse {
 
 }
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/api/Structs.kt b/app/src/main/java/ml/adamsprogs/bimba/api/Structs.kt
index 72b68952db24dc2ba3c1b54e4cbf5d616991a5a4..0fb37650fd4fddbaf31805944da035af90c8c68f 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/api/Structs.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/api/Structs.kt
@@ -297,6 +297,7 @@ 				dpToPixel(1.6f),
 				dpToPixel(1.6f),
 				dpToPixelI(10.4f)
 			), Paint().apply { color = colour.toInt() })
+
 		val iconID = when (type) {
 			LineType.BUS -> R.drawable.ic_bus_black_24dp
 			LineType.TRAM -> R.drawable.ic_tram_black_24dp




diff --git a/app/src/main/java/ml/adamsprogs/bimba/dashboard/MainActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/dashboard/MainActivity.kt
index 5034bc457a778d3284aa02db0798a7257a070b92..b7050351283bcb2b9de8b36629e81e9bb8fa4f2e 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/dashboard/MainActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/dashboard/MainActivity.kt
@@ -30,13 +30,11 @@ import ml.adamsprogs.bimba.departures.DeparturesActivity
 
 
 class MainActivity : AppCompatActivity() {
-
 	private lateinit var binding: ActivityMainBinding
 	private lateinit var locationPermissionRequest: ActivityResultLauncher<Array<String>>
 
 	override fun onCreate(savedInstanceState: Bundle?) {
 		super.onCreate(savedInstanceState)
-
 		binding = ActivityMainBinding.inflate(layoutInflater)
 		setContentView(binding.root)
 
@@ -122,7 +120,6 @@ 			is Stop -> {
 				val intent = Intent(this, DeparturesActivity::class.java).apply {
 					putExtra("code", item.code)
 					putExtra("name", item.name)
-					// todo line, date, etc
 				}
 				startActivity(intent)
 			}




diff --git a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeFragment.kt b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeFragment.kt
index 2f3a65df25748b68bc7294bc1af3b82cfac9d41a..049677ff850b90b70b9f64f5af0b5d9dac9dc8be 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeFragment.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeFragment.kt
@@ -15,9 +15,7 @@ import ml.adamsprogs.bimba.api.Item
 import ml.adamsprogs.bimba.databinding.FragmentHomeBinding
 
 class HomeFragment : Fragment() {
-
 	private var _binding: FragmentHomeBinding? = null
-
 	private val binding get() = _binding!!
 
 	private var lastSuggestions = listOf<Item>()
@@ -27,15 +25,10 @@ 		inflater: LayoutInflater,
 		container: ViewGroup?,
 		savedInstanceState: Bundle?
 	): View {
+		_binding = FragmentHomeBinding.inflate(inflater, container, false)
+
 		val homeViewModel =
 			ViewModelProvider(this)[HomeViewModel::class.java]
-
-		_binding = FragmentHomeBinding.inflate(inflater, container, false)
-		val root: View = binding.root
-
-		val shp = requireContext().getSharedPreferences("shp", AppCompatActivity.MODE_PRIVATE)
-
-		binding.searchBar.lastSuggestions = listOf<Item>()
 		homeViewModel.items.observe(viewLifecycleOwner) {
 			binding.searchBar.updateLastSuggestions(it)
 		}
@@ -81,7 +74,7 @@ 				binding.searchBar.lastSuggestions = lastSuggestions
 			}
 		}*/
 
-		return root
+		return binding.root
 	}
 
 	override fun onDestroyView() {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt
index 287426107c8a599cba17349d16ab17c50bb03fdc..4327e3af558a8306a823fbdd0cc554ccc881865b 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt
@@ -16,7 +16,6 @@ import ml.adamsprogs.bimba.api.*
 import java.io.InputStream
 
 class HomeViewModel : ViewModel() {
-
 	private val mutableItems = MutableLiveData<List<Item>>()
 	val items: LiveData<List<Item>> = mutableItems
 
@@ -36,7 +35,7 @@ 				is ItemsSuccess -> {
 					return@withContext response.items
 				}
 				else -> {
-					 TODO("Error response")
+					TODO("Error response")
 				}
 			}
 		}




diff --git a/app/src/main/java/ml/adamsprogs/bimba/departures/Departures.kt b/app/src/main/java/ml/adamsprogs/bimba/departures/Departures.kt
index 596b5f1baf1f850d332b2fb4ed6e16f617959895..30abca2865d228a9cda756829cfce9a5efb1da31 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/departures/Departures.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/departures/Departures.kt
@@ -1,5 +1,6 @@
 package ml.adamsprogs.bimba.departures
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.util.Log
 import android.view.LayoutInflater
@@ -21,6 +22,7 @@ 	val headsign: TextView = itemView.findViewById(R.id.departure_headsign)
 
 
 	companion object {
+		@SuppressLint("SetTextI18n")
 		fun bind(
 			departure: Departure,
 			holder: BimbaDepartureViewHolder?,
@@ -31,7 +33,8 @@ 			holder?.root?.setOnClickListener {
 				onClickListener(departure)
 			}
 			holder?.lineIcon?.setImageBitmap(departure.line.icon(context!!))
-			holder?.headsign?.text = "${departure.line.name} » ${departure.headsign}"
+			holder?.headsign?.text =
+				"${departure.line.name} » ${departure.headsign}"  // check if >> is a11y
 			val now = Calendar.getInstance()
 			val departureTime = Calendar.getInstance().apply {
 				set(Calendar.HOUR_OF_DAY, departure.time.Hour.toInt())
@@ -41,14 +44,11 @@ 				// todo zone
 				roll(Calendar.DAY_OF_MONTH, departure.time.DayOffset.toInt())
 			}
 			var duration = departureTime.timeInMillis - now.timeInMillis
-			val days = duration / (24 * 60 * 60 * 1000)
-			duration %= (24 * 60 * 60 * 1000)
 			val hours = duration / (60 * 60 * 1000)
 			duration %= (60 * 60 * 1000)
 			val minutes = duration / (60 * 1000)
 			duration %= (60 * 1000)
-			val seconds = duration / 1000
-			holder?.departureTime?.text = when (departure.status.toInt()) {
+			holder?.departureTime?.text = when (departure.status.toInt()) { // todo(i18n) plurals
 				0 -> {
 					"in " +
 									if (hours > 0) {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/departures/DeparturesActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/departures/DeparturesActivity.kt
index ca814dc1cebfd445554539279afac988f8e8458d..5896a7bc1f2a91b21377e2cd31053206292ef947 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/departures/DeparturesActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/departures/DeparturesActivity.kt
@@ -1,6 +1,7 @@
 package ml.adamsprogs.bimba.departures
 
 import android.content.Context
+import android.content.SharedPreferences
 import androidx.appcompat.app.AppCompatActivity
 import android.os.Bundle
 import android.util.Log
@@ -18,9 +19,10 @@ import java.io.InputStream
 
 class DeparturesActivity : AppCompatActivity() {
 	private var _binding: ActivityDeparturesBinding? = null
-
 	private val binding get() = _binding!!
 
+	private lateinit var preferences: SharedPreferences
+
 	private lateinit var adapter: BimbaDeparturesAdapter
 
 	override fun onCreate(savedInstanceState: Bundle?) {
@@ -39,8 +41,7 @@ 		}
 		binding.departuresRecycler.adapter = adapter
 		WindowCompat.setDecorFitsSystemWindows(window, false)
 
-		val shp = getSharedPreferences("shp", MODE_PRIVATE)
-		val host = shp.getString("host", "bimba.apiote.xyz")!!
+		preferences = getSharedPreferences("shp", MODE_PRIVATE)
 
 		// todo check every 30s
 
@@ -48,8 +49,8 @@ 		MainScope().launch {
 			intent?.extras?.getString("code")?.let {
 				val departuresStream = getDepartures(
 					Server(
-						host, shp.getString("token", "")!!,
-						shp.getString("${host}_feeds", "")!!
+						host, preferences.getString("token", "")!!,
+						preferences.getString("${host}_feeds", "")!!
 					), it, null
 				)
 				if (departuresStream == null) {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/search/Results.kt b/app/src/main/java/ml/adamsprogs/bimba/search/Results.kt
index 576997efda9bb9db7bc74b89daa12ba069d3541d..bcc2e5cbc4286454282862dcacfd1655da85d70c 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/search/Results.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/search/Results.kt
@@ -1,20 +1,18 @@
 package ml.adamsprogs.bimba.search
 
+import android.annotation.SuppressLint
 import android.content.Context
-import android.graphics.PorterDuff
 import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
 import android.widget.TextView
-import androidx.appcompat.content.res.AppCompatResources
 import androidx.recyclerview.widget.RecyclerView
 import com.mancj.materialsearchbar.adapter.SuggestionsAdapter
 import ml.adamsprogs.bimba.R
 import ml.adamsprogs.bimba.api.Item
 import ml.adamsprogs.bimba.api.Line
-import ml.adamsprogs.bimba.api.LineType
 import ml.adamsprogs.bimba.api.Stop
 
 class BimbaViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@@ -31,38 +29,40 @@ 			context: Context?,
 			onClickListener: (Item) -> Unit
 		) {
 			when (item) {
-				is Stop -> {
-					holder?.icon?.setImageResource(R.drawable.ic_stop_black_24dp) // todo stop icon // todo dark theme colour
-					holder?.title?.text = "${item.name} [${item.code}]"
-					holder?.description?.text =
-						item.changeOptions.groupBy { it.line }.map{ Pair(it.key, it.value.joinToString { co-> co.headsign })}.joinToString { "${it.first} » ${it.second}" }
-				}
-				is Line -> {
-					val icon = item.icon(context!!)
-					holder?.icon?.apply {
-						setImageBitmap(icon)
-						colorFilter = null
-						Log.v("Colour", "${item.name}: ${item.colour}, ${item.colour.toInt().toString(16)}")
-						Log.v("Colour", "${item.name}: ${item.textColour()}, ${item.textColour().toString(16)}")
-					}
-					holder?.title?.text = item.name
-					holder?.description?.text =
-						"${item.headsignsThere.joinToString { it }} «» ${item.headsignsBack.joinToString { it }}"
-				}
-				else -> TODO("Shouldn't happen")
+				is Stop -> bindStop(item, holder)
+				is Line -> bindLine(item, holder, context)
+				else -> throw NotImplementedError("Shouldn't happen")
 			}
 			holder?.root?.setOnClickListener {
 				onClickListener(item)
 			}
-			/*holder!!.root.setOnClickListener {
-				onSuggestionClickListener.onSuggestionClickListener(suggestion)
-			}
-			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-				holder.text.text = Html.fromHtml(suggestion.getBody(context), Html.FROM_HTML_MODE_LEGACY)
-			} else {
-				@Suppress("DEPRECATION")
-				holder.text.text = Html.fromHtml(suggestion.getBody(context))
+		}
+
+		@SuppressLint("SetTextI18n")
+		fun bindStop(stop: Stop, holder: BimbaViewHolder?) {
+			holder?.icon?.setImageResource(R.drawable.ic_stop_black_24dp) // todo(ui,dark) stop icon // todo dark theme colour
+			holder?.title?.text = "${stop.name} [${stop.code}]"
+			holder?.description?.text =
+				stop.changeOptions.groupBy { it.line }
+					.map { Pair(it.key, it.value.joinToString { co -> co.headsign }) }
+					.joinToString { "${it.first} » ${it.second}" }
+		}
+
+		@SuppressLint("SetTextI18n")
+		fun bindLine(line: Line, holder: BimbaViewHolder?, context: Context?) {
+			val icon = line.icon(context!!)
+			holder?.icon?.apply {
+				setImageBitmap(icon)
+				colorFilter = null
+				Log.v("Colour", "${line.name}: ${line.colour}, ${line.colour.toInt().toString(16)}")
+				Log.v("Colour", "${line.name}: ${line.textColour()}, ${line.textColour().toString(16)}")
 			}
+			holder?.title?.text = line.name
+			holder?.description?.text =
+				"${line.headsignsThere.joinToString { it }} «» ${line.headsignsBack.joinToString { it }}"
+		}
+	}
+}
 
 interface Adapter {
 	fun createViewHolder(




diff --git a/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt
index 9ef7fa066249335b95328fc21c70eaeb5c86abc7..6ce9b705b3da1c076159a5bce9bb6962343f23b2 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt
@@ -27,19 +27,17 @@ 		MODE_LOCATION, MODE_SEARCH
 	}
 
 	private var _binding: ActivityResultsBinding? = null
-
 	private val binding get() = _binding!!
 
 	private lateinit var adapter: BimbaResultsAdapter
-
-	private lateinit var shp: SharedPreferences
+	private lateinit var preferences: SharedPreferences
 
 	override fun onCreate(savedInstanceState: Bundle?) {
 		super.onCreate(savedInstanceState)
 		_binding = ActivityResultsBinding.inflate(layoutInflater)
 		setContentView(binding.root)
 
-		shp = getSharedPreferences("shp", MODE_PRIVATE)
+		preferences = getSharedPreferences("shp", MODE_PRIVATE)
 
 		binding.resultsRecycler.layoutManager = LinearLayoutManager(this)
 		adapter = BimbaResultsAdapter(layoutInflater, this, listOf()) {
@@ -48,12 +46,11 @@ 				is Stop -> {
 					val intent = Intent(this, DeparturesActivity::class.java).apply {
 						putExtra("code", it.code)
 						putExtra("name", it.name)
-						// todo line, date, etc
 					}
 					startActivity(intent)
 				}
 				is Line -> {
-					TODO("start line graph actvity")
+					TODO("start line graph activity")
 				}
 			}
 		}
@@ -71,11 +68,11 @@ 			}
 			Mode.MODE_SEARCH -> {
 				val query = intent.extras?.getString("query")!!
 				supportActionBar?.title = "Results for ‘$query’"
-				val host = shp.getString("host", "bimba.apiote.xyz")!!
+				val host = preferences.getString("host", "bimba.apiote.xyz")!!
 				getItemsByQuery(
 					Server(
-						host, shp.getString("token", "")!!,
-						shp.getString("${host}_feeds", "")!!
+						host, preferences.getString("token", "")!!,
+						preferences.getString("${host}_feeds", "")!!
 					), query
 				)
 			}
@@ -96,11 +93,11 @@ 		Log.v("Location", "found $location")
 		val code = OpenLocationCode.encode(location.latitude, location.longitude)
 		val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
 		locationManager.removeUpdates(this)
-		val host = shp.getString("host", "bimba.apiote.xyz")!!
+		val host = preferences.getString("host", "bimba.apiote.xyz")!!
 		getItemsByLocation(
 			Server(
-				host, shp.getString("token", "")!!,
-				shp.getString("${host}_feeds", "")!!
+				host, preferences.getString("token", "")!!,
+				preferences.getString("${host}_feeds", "")!!
 			), code
 		)
 	}




diff --git a/app/src/main/res/layout/activity_departures.xml b/app/src/main/res/layout/activity_departures.xml
index 81649a0c4b35fff32622ac71c348438035fd5da1..783da782471292a2ce18f33c274c2ed6dbb6c215 100644
--- a/app/src/main/res/layout/activity_departures.xml
+++ b/app/src/main/res/layout/activity_departures.xml
@@ -3,6 +3,7 @@  	xmlns:app="http://schemas.android.com/apk/res-auto"
 	android:layout_width="match_parent"
 	android:layout_height="match_parent">
+
 	<androidx.constraintlayout.widget.ConstraintLayout
 		android:id="@+id/departures_progress"
 		android:layout_width="match_parent"
@@ -26,18 +27,18 @@
 		<!-- todo toolbar font family -->
 		<com.google.android.material.appbar.CollapsingToolbarLayout
 			android:id="@+id/collapsing_layout"
-			app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
 			style="?attr/collapsingToolbarLayoutMediumStyle"
 			android:layout_width="match_parent"
-			app:maxLines="2"
-			android:layout_height="?attr/collapsingToolbarLayoutMediumSize">
+			android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
+			app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
+			app:maxLines="2">
 
 			<com.google.android.material.appbar.MaterialToolbar
 				android:id="@+id/departures_app_bar"
 				android:layout_width="match_parent"
-				app:layout_collapseMode="pin"
 				android:layout_height="?attr/actionBarSize"
-				android:elevation="0dp" />
+				android:elevation="0dp"
+				app:layout_collapseMode="pin" />
 
 		</com.google.android.material.appbar.CollapsingToolbarLayout>
 




diff --git a/app/src/main/res/layout/departure.xml b/app/src/main/res/layout/departure.xml
index 906911d4c1f911da7ed8d86df5989c7956ce993d..cf20ee4ca1b84bf6c447bed2d9117b49abb78f96 100644
--- a/app/src/main/res/layout/departure.xml
+++ b/app/src/main/res/layout/departure.xml
@@ -10,7 +10,6 @@ 	 		android:id="@+id/line_icon"
 		android:layout_width="24dp"
 		android:layout_height="24dp"
-
 		android:layout_marginStart="8dp"
 		app:layout_constraintBottom_toTopOf="@+id/departure_headsign"
 		app:layout_constraintStart_toStartOf="parent"