Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F13341442
D222.1779344075.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Authored By
Unknown
Size
57 KB
Referenced Files
None
Subscribers
None
D222.1779344075.diff
View Options
diff --git a/app/build.gradle b/app/build.gradle
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -116,6 +116,8 @@
// Guava implementation for DBUpdateWorker
implementation 'com.google.guava:guava:33.5.0-android'
+
+ implementation 'com.google.android.flexbox:flexbox:3.0.0'
implementation "androidx.fragment:fragment-ktx:$fragment_version"
implementation "androidx.activity:activity-ktx:$activity_version"
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java b/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java
--- a/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/PalinaAdapter.java
@@ -25,11 +25,13 @@
import androidx.preference.PreferenceManager;
import android.content.SharedPreferences;
+import android.view.Gravity;
import android.os.Build;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.PopupMenu;
import android.widget.TextView;
import java.util.*;
@@ -87,7 +89,13 @@
final Resources res = con.getResources();
vh.routeIDTextView.setText(route.getDisplayCode());
- vh.routeCard.setOnClickListener(view -> mRouteListener.requestShowingRoute(route));
+ //vh.routeCard.setOnClickListener(view -> mRouteListener.requestShowingRoute(route));
+
+ // Clicking anywhere on the row shows a popup menu
+ vh.itemView.setOnClickListener(view ->
+ openPopupMenuDetails(con,view, route)
+ ); //vh.rowRouteDestination.getVisibility() == View.VISIBLE ? vh.rowRouteDestination : vh.itemView
+
if(route.destinazione==null || route.destinazione.length() == 0) {
vh.rowRouteDestination.setVisibility(View.GONE);
// move around the route timetable
@@ -114,11 +122,6 @@
}
vh.rowRouteDestination.setText(dest);
-
- //set click listener
- vh.itemView.setOnClickListener(view -> {
- mRouteListener.showRouteFullDirection(route);
- });
}
switch (route.type) {
@@ -208,6 +211,26 @@
return Capitalize.DO_NOTHING;
}
+ private void openPopupMenuDetails(Context con, View view, Route route){
+ PopupMenu popup = new PopupMenu(con, view, Gravity.END);
+ popup.inflate(R.menu.menu_arrivals_line_item);
+ if (route.destinazione == null || route.destinazione.isEmpty()) {
+ popup.getMenu().findItem(R.id.action_show_direction).setVisible(false);
+ }
+ popup.setOnMenuItemClickListener(item -> {
+ int id = item.getItemId();
+ if (id == R.id.action_open_line) {
+ mRouteListener.requestShowingRoute(route);
+ return true;
+ } else if (id == R.id.action_show_direction) {
+ mRouteListener.showRouteFullDirection(route);
+ return true;
+ }
+ return false;
+ });
+ popup.show();
+ }
+
public PalinaAdapter(Context context, Palina p, PalinaClickListener listener, boolean hideEmptyRoutes) {
Comparator<Passaggio> sorter = null;
if (p.getPassaggiSourceIfAny()== Passaggio.Source.GTTJSON){
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt b/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt
--- a/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/RouteAdapter.kt
@@ -12,7 +12,7 @@
class RouteAdapter(val routes: List<GtfsRoute>,
click: ItemClicker,
- private val layoutId: Int = R.layout.entry_line_num_descr) :
+ private val layoutId: Int = R.layout.entry_line_name_description) :
RecyclerView.Adapter<RouteAdapter.ViewHolder>()
{
val clickreference: WeakReference<ItemClicker>
@@ -45,7 +45,7 @@
// Get element from your dataset at this position and replace the
// contents of the view with that element
val route = routes[position]
- holder.nameTextView.text = route.shortName
+ holder.nameTextView.text = route.getShortNameDisplay()
holder.descrptionTextView.text = route.longName
holder.itemView.setOnClickListener{
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt b/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
--- a/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/RouteOnlyLineAdapter.kt
@@ -6,6 +6,7 @@
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import it.reyboz.bustorino.R
+import it.reyboz.bustorino.backend.FiveTNormalizer
import it.reyboz.bustorino.backend.Palina
import java.lang.ref.WeakReference
@@ -47,7 +48,8 @@
// Get element from your dataset at this position and replace the
// contents of the view with that element
- viewHolder.textView.text = routeNames[position]
+ // SHOW "STAR" as "ST"
+ viewHolder.textView.text = FiveTNormalizer.filterFullStarName(routeNames[position])
viewHolder.itemView.setOnClickListener{
clickreference?.get()?.onItemClick(position, routeNames[position])
}
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/FiveTNormalizer.java b/app/src/main/java/it/reyboz/bustorino/backend/FiveTNormalizer.java
--- a/app/src/main/java/it/reyboz/bustorino/backend/FiveTNormalizer.java
+++ b/app/src/main/java/it/reyboz/bustorino/backend/FiveTNormalizer.java
@@ -182,6 +182,7 @@
if(routeID.length() == 3 && routeID.charAt(2) == 'B') {
return routeID.substring(0,2).concat("/");
}
+ //TODO: Decide what to do about the "+" lines (68+, 13+)
switch(routeID) {
case "1C":
@@ -380,4 +381,13 @@
return sb.toString();
}
+
+ public static String filterFullStarName(String name){
+ String outName = name;
+ if(name.contains("STAR ")){
+ //FIX FOR THE MaTO data
+ outName = outName.replace("STAR ","ST");
+ }
+ return outName;
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/Route.java b/app/src/main/java/it/reyboz/bustorino/backend/Route.java
--- a/app/src/main/java/it/reyboz/bustorino/backend/Route.java
+++ b/app/src/main/java/it/reyboz/bustorino/backend/Route.java
@@ -432,6 +432,15 @@
return adjusted;
}
+ public String getRouteLongDisplayName() {
+
+ String routeName = FiveTNormalizer.routeInternalToDisplay(this.name);
+ if (routeName == null) {
+ routeName = this.displayCode;
+ }
+ return routeName;
+ }
+
// ---- Parcelable implem ---
protected Route(Parcel in) {
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/Stop.java b/app/src/main/java/it/reyboz/bustorino/backend/Stop.java
--- a/app/src/main/java/it/reyboz/bustorino/backend/Stop.java
+++ b/app/src/main/java/it/reyboz/bustorino/backend/Stop.java
@@ -282,6 +282,13 @@
return String.format(Locale.US, "geo:%f,%f", this.lat, this.lon);
}
+ /**
+ * Check if the stop contains the coordinates
+ * @return true if both the latitude and the longitude are not null
+ */
+ public final boolean hasCoords(){
+ return (this.lat!=null)&&(this.lon!=null);
+ }
public final @Nullable String getGeoURLWithAddress() {
String url = getGeoURL();
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/gtfs/GtfsUtils.java b/app/src/main/java/it/reyboz/bustorino/backend/gtfs/GtfsUtils.java
--- a/app/src/main/java/it/reyboz/bustorino/backend/gtfs/GtfsUtils.java
+++ b/app/src/main/java/it/reyboz/bustorino/backend/gtfs/GtfsUtils.java
@@ -18,6 +18,7 @@
package it.reyboz.bustorino.backend.gtfs;
import androidx.core.util.Pair;
+import it.reyboz.bustorino.backend.FiveTNormalizer;
import it.reyboz.bustorino.backend.ServiceType;
abstract public class GtfsUtils {
@@ -69,4 +70,13 @@
public static String getLineNameFromGtfsID(String routeID){
return getRouteInfoFromGTFS(routeID).second;
}
+
+ public static String lineNameDisplayFromGtfsID(String routeID){
+ String name = getRouteInfoFromGTFS(routeID).second;
+
+ String altName = FiveTNormalizer.routeInternalToDisplay(name);
+ if (altName==null) //WTF WHY DOES IT HAVE TO BE NULL
+ return name;
+ else return altName;
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt
--- a/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt
+++ b/app/src/main/java/it/reyboz/bustorino/backend/mato/MatoAPIFetcher.kt
@@ -199,7 +199,7 @@
for (i in 0 until routesStoppingJSON.length()){
val routeBaseInfo = routesStoppingJSON.getJSONObject(i)
val r = Route(routeBaseInfo.getString("shortName"), Route.Type.UNKNOWN,"")
- r.setGtfsId(routeBaseInfo.getString("gtfsId").trim())
+ r.gtfsId = routeBaseInfo.getString("gtfsId").trim()
baseRoutes.add(r)
}
@@ -233,7 +233,7 @@
//val gtfsRoutes = mutableListOf<>()
return palina
}
- fun parseRouteStoptimesJSON(jsonPatternWithStops: JSONObject): Route{
+ private fun parseRouteStoptimesJSON(jsonPatternWithStops: JSONObject): Route{
val patternJSON = jsonPatternWithStops.getJSONObject("pattern")
val routeJSON = patternJSON.getJSONObject("route")
@@ -258,7 +258,7 @@
"TRAM" -> routeType = Route.Type.TRAM
}
val route = Route(
- routeJSON.getString("shortName"),
+ FiveTNormalizer.filterFullStarName(routeJSON.getString("shortName")),
patternJSON.getString("headsign"),
routeType,
passages,
diff --git a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsRoute.kt b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsRoute.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsRoute.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/gtfs/GtfsRoute.kt
@@ -20,6 +20,7 @@
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
+import it.reyboz.bustorino.backend.FiveTNormalizer
@Entity(tableName=GtfsRoute.DB_TABLE)
data class GtfsRoute(
@@ -80,4 +81,8 @@
override fun getColumns(): Array<String> {
return COLUMNS
}
+
+ fun getShortNameDisplay(): String {
+ return FiveTNormalizer.filterFullStarName(shortName)
+ }
}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ArrivalsFragment.kt
@@ -65,6 +65,7 @@
//Views
protected lateinit var addToFavorites: ImageButton
+ protected lateinit var openInMapButton: ImageButton
protected lateinit var timesSourceTextView: TextView
protected lateinit var messageTextView: TextView
protected lateinit var arrivalsRecyclerView: RecyclerView
@@ -95,14 +96,8 @@
private val palinaClickListener: PalinaClickListener = object : PalinaClickListener {
override fun showRouteFullDirection(route: Route) {
- var routeName: String?
+ var routeName = route.routeLongDisplayName
Log.d(DEBUG_TAG, "Make toast for line " + route.name)
-
-
- routeName = FiveTNormalizer.routeInternalToDisplay(route.name)
- if (routeName == null) {
- routeName = route.displayCode
- }
if (context == null) Log.e(DEBUG_TAG, "Touched on a route but Context is null")
else if (route.destinazione == null || route.destinazione.length == 0) {
Toast.makeText(
@@ -169,6 +164,7 @@
val root = inflater.inflate(R.layout.fragment_arrivals, container, false)
messageTextView = root.findViewById(R.id.messageTextView)
addToFavorites = root.findViewById(R.id.addToFavorites)
+ openInMapButton = root.findViewById(R.id.openInMapButton)
// "How does it work part"
howDoesItWorkTextView = root.findViewById(R.id.howDoesItWorkTextView)
hideHintButton = root.findViewById(R.id.hideHintButton)
@@ -219,7 +215,7 @@
val displayName = requireArguments().getString(STOP_TITLE)
if (displayName != null) setTextViewMessage(
String.format(
- getString(R.string.passages), displayName
+ getString(R.string.passages_fill), displayName
)
)
@@ -459,18 +455,25 @@
val adapter = PalinaAdapter(context, lastUpdatedPalina, palinaClickListener, true)
showArrivalsSources(lastUpdatedPalina!!)
resetListAdapter(adapter)
+ lastUpdatedPalina?.let{ pal ->
+ openInMapButton.setOnClickListener {
+ if (pal.hasCoords())
+ mListener.showMapCenteredOnStop(pal)
+ }
+ }
+
val routesWithNoPassages = lastUpdatedPalina!!.routesNamesWithNoPassages
if (routesWithNoPassages.isEmpty()) {
//hide the views if there are no empty routes
- noArrivalsRecyclerView!!.visibility = View.GONE
+ noArrivalsRecyclerView.visibility = View.GONE
noArrivalsTitleView!!.visibility = View.GONE
} else {
Collections.sort(routesWithNoPassages, LinesNameSorter())
noArrivalsAdapter = RouteOnlyLineAdapter(routesWithNoPassages, null)
- noArrivalsRecyclerView!!.adapter = noArrivalsAdapter
+ noArrivalsRecyclerView.adapter = noArrivalsAdapter
- noArrivalsRecyclerView!!.visibility = View.VISIBLE
+ noArrivalsRecyclerView.visibility = View.VISIBLE
noArrivalsTitleView!!.visibility = View.VISIBLE
}
@@ -539,7 +542,8 @@
Log.e("ArrivalsFragm$tag", "NO ID FOR THIS FRAGMENT - something went horribly wrong")
}
if (message.isNotEmpty()) {
- setTextViewMessage(getString(R.string.passages, message))
+ setTextViewMessage(getString(R.string.passages_fill, message))
+ //setTextViewMessage(message)
}
// whatever is the case, update the star icon
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/GeneralMapLibreFragment.kt
@@ -45,6 +45,7 @@
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.maplibre.android.MapLibre
+import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.location.LocationComponent
import org.maplibre.android.location.LocationComponentOptions
@@ -326,7 +327,7 @@
}
// Hide the bottom sheet and remove extra symbol
- protected fun hideStopOrBusBottomSheet(){
+ protected open fun hideStopOrBusBottomSheet(){
if (stopActiveSymbol!=null){
symbolManager?.delete(stopActiveSymbol)
stopActiveSymbol = null
@@ -534,7 +535,7 @@
*/
protected fun showVehicleTripInBottomSheet(
veh: String,
- onDirectionsClick: (patternCode: String) -> Unit
+ onDirectionsClick: (patternCode: String, veh: String) -> Unit
) {
val data = updatesByVehDict[veh] ?: run {
Log.w(DEBUG_TAG, "Asked to show vehicle $veh, but it's not present in the updates")
@@ -542,7 +543,7 @@
}
bottomLayout?.let {
val lineName = FiveTNormalizer.fixShortNameForDisplay(
- GtfsUtils.getLineNameFromGtfsID(data.posUpdate.routeID), true
+ GtfsUtils.getLineNameFromGtfsID(data.posUpdate.routeID), false
)
val pat = data.pattern
if (pat != null) {
@@ -554,7 +555,7 @@
stopNumberTextView.text = getString(R.string.line_fill, lineName)
}
directionsCard.setOnClickListener {
- onDirectionsClick(pat?.code ?: "")
+ onDirectionsClick(pat?.code ?: "", veh)
}
directionsCard.visibility = View.VISIBLE
bottomrightImage.setImageDrawable(
@@ -700,6 +701,7 @@
val string_show = if (stop.numRoutesStopping==0) ""
else requireContext().getString(R.string.lines_fill, stop.routesThatStopHereToString())
linesPassingTextView.text = string_show
+ linesPassingTextView.visibility = View.VISIBLE
//SET ON CLICK LISTENER
arrivalsCard.setOnClickListener{
@@ -911,6 +913,13 @@
updatePositionsIcons(forced = false)
}
+ protected fun setCameraPosition(latitude: Double, longitude: Double, zoom: Double) {
+ map?.cameraPosition = CameraPosition.Builder()
+ .target(LatLng(latitude, longitude))
+ .zoom(zoom)
+ .build()
+ }
+
companion object{
private const val DEBUG_TAG="GeneralMapLibreFragment"
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
@@ -23,7 +23,6 @@
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
-import android.content.res.ColorStateList
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@@ -35,18 +34,15 @@
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
-import androidx.core.view.ViewCompat
import androidx.fragment.app.viewModels
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.gson.JsonObject
import it.reyboz.bustorino.R
import it.reyboz.bustorino.adapters.NameCapitalize
import it.reyboz.bustorino.adapters.StopAdapterListener
import it.reyboz.bustorino.adapters.StopRecyclerAdapter
-import it.reyboz.bustorino.backend.FiveTNormalizer
import it.reyboz.bustorino.backend.Stop
import it.reyboz.bustorino.backend.gtfs.GtfsUtils
import it.reyboz.bustorino.backend.gtfs.PolylineParser
@@ -101,7 +97,7 @@
private var patternShown: MatoPatternWithStops? = null
private val viewModel: LinesViewModel by viewModels()
- private var firstInit = true
+ //private var firstInit = true
private var pausedFragment = false
private lateinit var switchButton: ImageButton
@@ -263,8 +259,7 @@
}
val titleTextView = rootView.findViewById<TextView>(R.id.titleTextView)
- titleTextView.text = getString(R.string.line)+" "+FiveTNormalizer.fixShortNameForDisplay(
- GtfsUtils.getLineNameFromGtfsID(lineID), true)
+ titleTextView.text = getString(R.string.line)+" "+ GtfsUtils.lineNameDisplayFromGtfsID(lineID)
favoritesButton?.isClickable = true
favoritesButton?.setOnClickListener {
@@ -342,24 +337,27 @@
usingMQTTPositions = PreferenceManager.getDefaultSharedPreferences(requireContext())
.getString(keySourcePositions, "mqtt").contentEquals("mqtt")
- viewModel.patternsWithStopsByRouteLiveData.observe(viewLifecycleOwner){
- patterns -> savePatternsToShow(patterns)
- }
+ viewModel.patternsWithStopsByRouteLiveData.observe(viewLifecycleOwner, this::savePatternsToShow)
/*
*/
viewModel.stopsForPatternLiveData.observe(viewLifecycleOwner) { stops ->
- if(mapView.visibility ==View.VISIBLE)
- patternShown?.let{
- // We have the pattern and the stops here, time to display them
- //TODO: Decide if we should follow the camera view given by the previous screen (probably the map fragment)
- // use !restoredCameraInMap to do so
- displayPatternWithStopsOnMap(it,stops, true)
- } ?:{
- Log.w(DEBUG_TAG, "The viewingPattern is null!")
- }
- else{
- if(stopsRecyclerView.visibility==View.VISIBLE)
+ val pattern = viewModel.selectedPatternLiveData.value
+ if (pattern == null) {
+ Log.w(DEBUG_TAG, "The selectedPattern is null!")
+ return@observe
+ }
+ if(mapView.visibility ==View.VISIBLE) {
+ // We have the pattern and the stops here, time to display them
+ //TODO: Decide if we should follow the camera view given by the previous screen (probably the map fragment)
+ // use !restoredCameraInMap to do so
+
+ // val shouldZoom = (shownStopInBottomSheet == null) //use this if we want to avoid zoom when we're keeping the stop open
+ displayPatternWithStopsOnMap(pattern, stops, true)
+ } else {
+ if(stopsRecyclerView.visibility==View.VISIBLE) {
+ patternShown = pattern
showStopsInRecyclerView(stops)
+ }
}
}
viewModel.gtfsRoute.observe(viewLifecycleOwner){route->
@@ -395,6 +393,20 @@
updatePositionsIcons(true)
livePositionsViewModel.retriggerPositionUpdate()
}
+ if (shownStopInBottomSheet!=null){
+ //check if the stop is inside the new pattern
+ /*val s = shownStopInBottomSheet!!
+ val newPatternStops = patternWithStops.stopsIndices
+ val filterPStops = newPatternStops.filter { ps -> ps.stopGtfsId == "gtt:${s.ID}" }
+ if (filterPStops.isEmpty()){
+ hideStopOrBusBottomSheet()
+ }
+ */
+ // do another thing, just close the stop when the pattern is changed
+ if (patt.code != patternWithStops.pattern.code){
+ hideStopOrBusBottomSheet()
+ }
+ }
}
}
livePositionsViewModel.setGtfsLineToFilterPos(lineID, patternWithStops.pattern)
@@ -576,16 +588,16 @@
mapReady.addOnMapClickListener { point ->
val screenPoint = mapReady.projection.toScreenLocation(point)
- val features = mapReady.queryRenderedFeatures(screenPoint, STOPS_LAYER_ID)
+ val stopsNearby = mapReady.queryRenderedFeatures(screenPoint, STOPS_LAYER_ID)
val busNearby = mapReady.queryRenderedFeatures(screenPoint, BUSES_LAYER_ID)
- if (features.isNotEmpty()) {
- val feature = features[0]
+ //Log.d(DEBUG_TAG, "onMapClick, stopsNearby: $stopsNearby \nstopShown: $shownStopInBottomSheet \nbusNearby: $busNearby,")
+
+ if (stopsNearby.isNotEmpty()) {
+ val feature = stopsNearby[0]
val id = feature.getStringProperty("id")
- val name = feature.getStringProperty("name")
- //Toast.makeText(requireContext(), "Clicked on $name ($id)", Toast.LENGTH_SHORT).show()
val stop = viewModel.getStopByID(id)
stop?.let {
- if (isBottomSheetShowing() || vehShowing.isNotEmpty()){
+ if (isBottomSheetShowing() || vehShowing.isNotEmpty()) {
hideStopOrBusBottomSheet()
}
openStopInBottomSheet(it)
@@ -597,21 +609,7 @@
return@addOnMapClickListener true
} else if (busNearby.isNotEmpty()){
val feature = busNearby[0]
- val vehid = feature.getStringProperty("veh")
- val route = feature.getStringProperty("line")
- if(isBottomSheetShowing())
- hideStopOrBusBottomSheet()
- //if(context!=null){
- // Toast.makeText(context, "Veh $vehid on route ${route.slice(0..route.length-2)}", Toast.LENGTH_SHORT).show()
- //}
- showVehicleTripInBottomSheet(vehid)
- updatesByVehDict[vehid]?.let {
- //if (it.posUpdate.latitude != null && it.longitude != null)
- mapReady.animateCamera(
- CameraUpdateFactory.newLatLng(LatLng(it.posUpdate.latitude, it.posUpdate.longitude)),
- 750
- )
- }
+ openBusFromMapClick(feature)
return@addOnMapClickListener true
}
@@ -626,7 +624,7 @@
val zoom = 12.0
val latlngTarget = LatLng(MapLibreFragment.DEFAULT_CENTER_LAT, MapLibreFragment.DEFAULT_CENTER_LON)
if(!setViewAlready)
- mapReady.cameraPosition = savedCameraPosition ?:CameraPosition.Builder().target(latlngTarget).zoom(zoom).build()
+ mapReady.cameraPosition = savedCameraPosition ?:CameraPosition.Builder().target(latlngTarget).zoom(zoom).build()
savedCameraPosition = null
@@ -637,9 +635,23 @@
return true
}
- private fun observeBusPositionUpdates(){
-
+ /**
+ * Separate function to find the vehicle associated with a feature and display it
+ */
+ private fun openBusFromMapClick(feature: Feature){
+ val vehid = feature.getStringProperty("veh")
+ if(isBottomSheetShowing())
+ hideStopOrBusBottomSheet()
+ showVehicleTripInBottomSheet(vehid)
+ updatesByVehDict[vehid]?.let {
+ map?.animateCamera(
+ CameraUpdateFactory.newLatLng(LatLng(it.posUpdate.latitude, it.posUpdate.longitude)),
+ 750
+ )
+ }
+ }
+ private fun observeBusPositionUpdates(){
//live bus positions
livePositionsViewModel.filteredLocationUpdates.observe(viewLifecycleOwner){ pair ->
//Log.d(DEBUG_TAG, "Received ${updates.size} updates for the positions")
@@ -672,12 +684,27 @@
}
private fun showVehicleTripInBottomSheet(veh: String) {
- super.showVehicleTripInBottomSheet(veh) { patternCode ->
+ super.showVehicleTripInBottomSheet(veh) { patternCode, veh ->
//this is checked in @GeneralMapLibreFragment
//val data = updatesByVehDict[veh] ?: return@showVehicleTripInBottomSheet
if (patternCode.isEmpty()) return@showVehicleTripInBottomSheet
if (patternShown?.pattern?.code == patternCode) {
- Toast.makeText(context, R.string.showing_same_direction, Toast.LENGTH_SHORT).show()
+ //center view on vehicle
+ updatesByVehDict[veh]?.let { up->
+ map?.let{
+ /*
+ val c = it.cameraPosition
+ it.moveCamera(CameraUpdateFactory.CameraPositionUpdate(c.bearing,
+ LatLng(up.posUpdate.latitude, up.posUpdate.longitude),
+ c.tilt,c.zoom, c.padding)
+ )
+ */
+ it.animateCamera(CameraUpdateFactory.newLatLng(LatLng(up.posUpdate.latitude, up.posUpdate.longitude)))
+ }
+ } ?: {
+ Toast.makeText(context, R.string.showing_same_direction, Toast.LENGTH_SHORT).show()
+ }
+
} else {
showPatternWithCode(patternCode)
}
@@ -749,7 +776,7 @@
var p: MatoPatternWithStops? = null
if (patternIdToShow.isNotEmpty()){
- for (patt in currentPatterns) {
+ for (patt in patterns) {
if (patt.pattern.code == patternIdToShow){
p = patt
}
@@ -763,7 +790,7 @@
else if(stopIDFromToShow.isNotEmpty()) {
val stopGtfsID = "gtt:$stopIDFromToShow"
var pLength = 0
- for (patt in currentPatterns) {
+ for (patt in patterns) {
for (pstop in patt.stopsIndices) {
if (pstop.stopGtfsId == stopGtfsID) {
//found
@@ -781,9 +808,9 @@
else
Log.d(DEBUG_TAG, "Requesting to show pattern from stop $stopIDFromToShow, found pattern ${p.pattern.code}")
}
-
- stopIDFromToShow = ""
+ // the flag of showing pattern is not necessary anymore, we have set the pattern
patternIdToShow = ""
+ // the flag of selecting from stop needs to be used again when displaying the pattern
return p
}
/**
@@ -798,7 +825,7 @@
it.addAll(currentPatterns.map { p->"${p.pattern.directionId} - ${p.pattern.headsign}" })
it.notifyDataSetChanged()
}
- val patternToShow = filterPatternFromArgs(patterns)
+ val patternToShow = filterPatternFromArgs(currentPatterns)
if(patternToShow!=null) {
//showPattern(patternToShow)
patternShown = patternToShow
@@ -816,7 +843,6 @@
Log.d(DEBUG_TAG, "Requesting stops for pattern ${patternWithStops.pattern.code}")
viewModel.selectedPatternLiveData.value = patternWithStops
viewModel.currentPatternStops.value = patternWithStops.stopsIndices.sortedBy { i-> i.order }
- patternShown = patternWithStops
viewModel.requestStopsForPatternWithStops(patternWithStops)
}
@@ -831,12 +857,11 @@
}
}
Log.d(DEBUG_TAG, "Requesting stops fro pattern $code in position: $pos")
+ // this triggers the showing on the map / recyclerview
if (pos !=-2)
patternsSpinner.setSelection(pos)
else
Log.e(DEBUG_TAG, "Pattern with code $code not found!!")
- //request pattern stops from DB
- //setPatternAndReqStops(patternWs)
}
/**
@@ -957,12 +982,28 @@
Log.e(DEBUG_TAG, "Stops layer is not started!!")
}
+ var reallyZoomToPattern = zoomToPattern
+ if(stopIDFromToShow.isNotEmpty()){
+ //open the stop
+ val stopfilt = stopsSorted.filter { s -> s.ID == stopIDFromToShow }
+ if (stopfilt.isEmpty()){
+ Log.e(DEBUG_TAG, "Tried to show stop but it's not in the selected pattern")
+ } else{
+ val stop = stopfilt[0]
+ openStopInBottomSheet(stop)
+
+ if(stop.hasCoords()) {
+ reallyZoomToPattern = false
+ setCameraPosition(stop.latitude!!, stop.longitude!!, 13.5)
+ }
+
+ }
+ // Reset this to avoid checking again when showing
+ stopIDFromToShow = ""
+ //camera set
+ }
+ if(reallyZoomToPattern) zoomToCurrentPattern()
- //POINTS LIST IS NOT IN ORDER ANY MORE
- //if(!map.overlayManager.contains(stopsOverlay)){
- // map.overlayManager.add(stopsOverlay)
- //}
- if(zoomToPattern) zoomToCurrentPattern()
}
private fun initializeRecyclerView(){
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesGridShowingFragment.kt
@@ -17,6 +17,9 @@
import androidx.recyclerview.widget.RecyclerView
import androidx.work.WorkInfo
import androidx.work.WorkManager
+import com.google.android.flexbox.FlexDirection
+import com.google.android.flexbox.FlexboxLayoutManager
+import com.google.android.flexbox.JustifyContent
import it.reyboz.bustorino.R
import it.reyboz.bustorino.adapters.RouteAdapter
import it.reyboz.bustorino.adapters.RouteOnlyLineAdapter
@@ -30,7 +33,6 @@
import it.reyboz.bustorino.util.ViewUtils
import it.reyboz.bustorino.viewmodels.LinesGridShowingViewModel
-
class LinesGridShowingFragment : ScreenBaseFragment() {
@@ -63,6 +65,13 @@
private val linesComparator = Comparator<GtfsRoute> { a,b ->
return@Comparator linesNameSorter.compare(a.shortName, b.shortName)
}
+ private val linesPriorityComparator = Comparator<Pair<GtfsRoute,Int>> { pa, pb ->
+ if (pa.second != pb.second){
+ return@Comparator pa.second - pb.second
+ } else{
+ return@Comparator linesNameSorter.compare(pa.first.shortName, pb.first.shortName)
+ }
+ }
private val routeClickListener = RouteAdapter.ItemClicker {
fragmentListener.openLineFromStop(it.gtfsId, null)
@@ -73,6 +82,13 @@
private val lastQueryEmptyForAgency = HashMap<String, Boolean>(3)
private var openRecyclerView = "AG_URBAN"
+ private fun getFlexLayoutManager(context: Context): FlexboxLayoutManager{
+ val layoutManager = FlexboxLayoutManager(context)
+ layoutManager.flexDirection = FlexDirection.ROW
+ layoutManager.justifyContent = JustifyContent.FLEX_START
+
+ return layoutManager
+ }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@@ -105,37 +121,36 @@
recyView.layoutManager = gridLayoutManager
}
//init favorites recyclerview
- val gridLayoutManager = AutoFitGridLayoutManager(
- requireContext().applicationContext,
- (utils.convertDipToPixels(context, 70f)).toInt()
- )
- favoritesRecyclerView.layoutManager = gridLayoutManager
+ favoritesRecyclerView.layoutManager = getFlexLayoutManager(requireContext())
+
+ viewModel.getLinesLiveData().observe(viewLifecycleOwner){ rL ->
- viewModel.getLinesLiveData().observe(viewLifecycleOwner){
- //routesList = ArrayList(it)
- //routesList.sortWith(linesComparator)
routesByAgency.clear()
for (k in AGENCIES){
routesByAgency[k] = ArrayList()
}
-
- for(route in it){
+ val routesPrioByAg = HashMap<String, ArrayList<Pair<GtfsRoute,Int>>>()
+ for (ag in AGENCIES){
+ routesPrioByAg[ag] = ArrayList()
+ }
+ for(p in rL){
+ val route = p.first
val agency = route.agencyID
if(agency !in routesByAgency.keys){
Log.e(DEBUG_TAG, "The agency $agency is not present in the predefined agencies (${routesByAgency.keys})")
}
routesByAgency[agency]?.add(route)
+ routesPrioByAg[agency]!!.add(p)
}
//zip agencies and recyclerviews
- Companion.AGENCIES.zip(recViews) { ag, recView ->
- routesByAgency[ag]?.let { routeList ->
- if (routeList.size > 0) {
- routeList.sortWith(linesComparator)
- //val adapter = RouteOnlyLineAdapter(it.map { rt -> rt.shortName })
- val adapter = RouteAdapter(routeList, routeClickListener)
+ AGENCIES.zip(recViews) { ag, recView ->
+ routesPrioByAg[ag]?.let { routePrioList ->
+ if (routePrioList.isNotEmpty()) {
+ routePrioList.sortWith(linesPriorityComparator)
+ val adapter = RouteAdapter(routePrioList.map { it.first }, routeClickListener)
val lastQueryEmpty = if(ag in lastQueryEmptyForAgency.keys) lastQueryEmptyForAgency[ag]!! else true
if (lastQueryEmpty)
recView.adapter = adapter
@@ -148,7 +163,7 @@
lastQueryEmptyForAgency[ag] = true
}
- durations[ag] = if(routeList.size < 20) ViewUtils.DEF_DURATION else 1000
+ durations[ag] = if(routePrioList.size < 20) ViewUtils.DEF_DURATION else 1000
}
}
@@ -390,7 +405,7 @@
companion object {
- private const val COLUMN_WIDTH_DP=200
+ private const val COLUMN_WIDTH_DP=250
private const val AG_FAV = "fav"
private const val AG_URBAN = "gtt:U"
private const val AG_EXTRAURB ="gtt:E"
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/MapLibreFragment.kt
@@ -161,6 +161,12 @@
super.onCreate(savedInstanceState)
arguments?.let {
initialStopToShow = Stop.fromBundle(arguments)
+ if (initialStopToShow==null){
+
+ } else if(!initialStopToShow!!.hasCoords()){
+ //null the stop if it doesn't have coordinates, we cannot find it
+ initialStopToShow = null
+ }
}
}
@@ -352,9 +358,11 @@
if (initialStopToShow!=null){
val s = initialStopToShow!!
- mapReady.cameraPosition = CameraPosition.Builder().target(
- LatLng(s.latitude!!, s.longitude!!)
- ).zoom(DEFAULT_ZOOM).build()
+ if(s.hasCoords()){
+ mapReady.cameraPosition = CameraPosition.Builder().target(
+ LatLng(s.latitude!!, s.longitude!!)
+ ).zoom(DEFAULT_ZOOM).build()
+ }
restoredMapCamera.set(true)
} else{
var boundsRestored = false
@@ -437,6 +445,12 @@
override fun showOpenStopWithSymbolLayer(): Boolean {
return false
}
+ override fun hideStopOrBusBottomSheet(){
+ if (shownStopInBottomSheet?.ID == initialStopToShow?.ID){
+ initialStopToShow = null
+ }
+ super.hideStopOrBusBottomSheet()
+ }
override fun onAttach(context: Context) {
super.onAttach(context)
@@ -536,7 +550,7 @@
private fun showVehicleTripInBottomSheet(veh: String) {
val data = updatesByVehDict[veh] ?: return
- super.showVehicleTripInBottomSheet(veh) { patternCode ->
+ super.showVehicleTripInBottomSheet(veh) { patternCode, _ ->
map?.let { mapStateViewModel.saveMapState(it) }
fragmentListener?.openLineFromVehicle(
data.posUpdate.getLineGTFSFormat(),
@@ -553,7 +567,8 @@
initialStopToShow?.let{ s->
//show the stop in the bottom sheet
if(!initialStopShown && (s.ID in stopsShowing.map { it.ID })) {
- openStopInBottomSheet(s)
+ val stopToShow = stopsShowing.first { it.ID == s.ID }
+ openStopInBottomSheet(stopToShow)
initialStopShown = true
}
}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ResultListFragment.java
@@ -34,7 +34,6 @@
import android.view.ViewGroup;
import android.widget.*;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
import it.reyboz.bustorino.R;
import it.reyboz.bustorino.backend.FiveTNormalizer;
@@ -167,7 +166,7 @@
});
String displayName = getArguments().getString(ArrivalsFragment.STOP_TITLE);
setTextViewMessage(String.format(
- getString(R.string.passages), displayName));
+ getString(R.string.passages_fill), displayName));
break;
default:
throw new IllegalStateException("Argument passed was not of a supported type");
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
@@ -3,8 +3,6 @@
import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.view.Gravity;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
diff --git a/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt b/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt
--- a/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt
+++ b/app/src/main/java/it/reyboz/bustorino/viewmodels/LinesGridShowingViewModel.kt
@@ -39,15 +39,24 @@
fun getLineQueryValue():String{
return queryLiveData.value ?: ""
}
- private val filteredLinesLiveData = MediatorLiveData<List<GtfsRoute>>()
- fun getLinesLiveData(): LiveData<List<GtfsRoute>> {
- return filteredLinesLiveData
- }
+ private val filteredLinesLiveData = MediatorLiveData<List<Pair<GtfsRoute,Int >>>()
+ fun getLinesLiveData() = filteredLinesLiveData
- private fun filterLinesForQuery(lines: List<GtfsRoute>, query: String): List<GtfsRoute>{
+ private fun filterLinesForQuery(lines: List<GtfsRoute>, query: String): ArrayList<Pair<GtfsRoute,Int>>{
val result= lines.filter { r-> query.lowercase() in r.shortName.lowercase() }
-
- return result
+ //val filterDescr = lines.filter { r -> query.lowercase() in r.description.lowercase() }
+ val out = ArrayList<Pair<GtfsRoute,Int>>()
+ for (r in result){
+ out.add(Pair(r,1))
+ }
+ for (r: GtfsRoute in lines) {
+ if (query.lowercase() in r.description.lowercase()) {
+ if (r !in result){
+ out.add(Pair(r,2))
+ }
+ }
+ }
+ return out
}
init {
diff --git a/app/src/main/res/drawable/ic_star_filled.xml b/app/src/main/res/drawable/ic_star_filled.xml
--- a/app/src/main/res/drawable/ic_star_filled.xml
+++ b/app/src/main/res/drawable/ic_star_filled.xml
@@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
+ android:width="30dp"
+ android:height="30dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
diff --git a/app/src/main/res/drawable/ic_star_outline.xml b/app/src/main/res/drawable/ic_star_outline.xml
--- a/app/src/main/res/drawable/ic_star_outline.xml
+++ b/app/src/main/res/drawable/ic_star_outline.xml
@@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
+ android:width="30dp"
+ android:height="30dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
diff --git a/app/src/main/res/layout/entry_bus_line_passage.xml b/app/src/main/res/layout/entry_bus_line_passage.xml
--- a/app/src/main/res/layout/entry_bus_line_passage.xml
+++ b/app/src/main/res/layout/entry_bus_line_passage.xml
@@ -7,6 +7,9 @@
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="16dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:clickable="true"
+ android:focusable="true"
>
diff --git a/app/src/main/res/layout/entry_line_num_descr.xml b/app/src/main/res/layout/entry_line_name_description.xml
rename from app/src/main/res/layout/entry_line_num_descr.xml
rename to app/src/main/res/layout/entry_line_name_description.xml
--- a/app/src/main/res/layout/entry_line_num_descr.xml
+++ b/app/src/main/res/layout/entry_line_name_description.xml
@@ -4,7 +4,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="5dp"
- android:layout_margin="4dp"
+ android:layout_margin="8dp"
>
<RelativeLayout
android:layout_width="match_parent"
@@ -19,7 +19,7 @@
app:cardElevation="0sp"
android:layout_gravity="center_vertical"
android:layout_margin="5dp"
- android:padding="3dp"
+ android:padding="6dp"
app:cardBackgroundColor="@color/orange_500"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
@@ -48,18 +48,23 @@
</TextView>
</RelativeLayout>
</androidx.cardview.widget.CardView>
- <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:id="@+id/lineDirectionTextView"
- android:layout_weight="8"
android:textSize="20sp"
- android:text="@string/route_towards_destination"
+ android:text="@string/hello_blank_fragment"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
- android:layout_marginEnd="10dp"
- android:layout_alignParentTop="true"
+ android:layout_marginEnd="2dp"
android:layout_toEndOf="@id/innerCardView"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="5dp"
+ android:layout_marginStart="13dp"
+ android:layout_marginBottom="10dp"
+ android:minHeight="52sp"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_arrivals.xml b/app/src/main/res/layout/fragment_arrivals.xml
--- a/app/src/main/res/layout/fragment_arrivals.xml
+++ b/app/src/main/res/layout/fragment_arrivals.xml
@@ -13,37 +13,79 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="5dp"
- app:cardElevation="4dp"
+ app:cardElevation="6dp"
android:layout_alignParentTop="true"
android:layout_marginStart="8sp"
android:layout_marginEnd="8sp"
android:layout_marginTop="5sp"
- android:padding="5sp"
+ android:padding="8sp"
>
-
- <TextView
- android:id="@+id/messageTextView"
+ <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dp"
- android:layout_marginLeft="8dp"
- android:layout_toStartOf="@+id/addToFavorites"
- android:layout_toLeftOf="@+id/addToFavorites"
-
- android:foreground="?attr/selectableItemBackground"
- android:gravity="center_vertical"
- android:minHeight="40dp"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
-
- <ImageButton
- android:id="@+id/addToFavorites"
- android:layout_width="45dp"
- android:layout_height="match_parent"
- android:layout_gravity="end"
- android:background="@android:color/transparent"
- android:foreground="?attr/selectableItemBackground"
- app:srcCompat="@drawable/ic_star_outline"
- tools:ignore="OnClick"/>
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/arrivalsTextView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:foreground="?attr/selectableItemBackground"
+ android:gravity="center_vertical"
+ android:text="@string/passages"
+ android:minHeight="35dp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/messageTextView"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ app:layout_constraintHorizontal_bias="0.0"
+ android:visibility="gone"/>
+ <TextView
+ android:id="@+id/messageTextView"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:layout_marginStart="12dp"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/addToFavorites"
+ app:layout_constraintStart_toEndOf="@id/arrivalsTextView"
+ android:foreground="?attr/selectableItemBackground"
+
+ android:gravity="center_vertical"
+ android:minHeight="35dp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="19sp"/>
+ <ImageButton
+ android:id="@+id/addToFavorites"
+ android:layout_width="35dp"
+ android:layout_height="35dp"
+ android:layout_gravity="end"
+ android:layout_margin="5dp"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/openInMapButton"
+ app:layout_constraintStart_toEndOf="@id/messageTextView"
+ android:background="@android:color/transparent"
+ android:foreground="?attr/selectableItemBackground"
+ app:srcCompat="@drawable/ic_star_outline"
+ tools:ignore="OnClick"
+ />
+ <ImageButton
+ android:id="@+id/openInMapButton"
+ android:layout_width="35dp"
+ android:layout_height="35dp"
+ android:layout_gravity="end"
+ android:layout_margin="5dp"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/addToFavorites"
+ android:background="@android:color/transparent"
+ android:foreground="?attr/selectableItemBackground"
+ app:srcCompat="@drawable/ic_map_white_30"
+ android:tint="@color/orange_500"
+ tools:ignore="OnClick"
+ android:layout_marginEnd="12dp"
+ />
+ </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
diff --git a/app/src/main/res/menu/menu_arrivals_line_item.xml b/app/src/main/res/menu/menu_arrivals_line_item.xml
new file mode 100644
--- /dev/null
+++ b/app/src/main/res/menu/menu_arrivals_line_item.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/action_open_line"
+ android:title="@string/action_open_line"/>
+ <item
+ android:id="@+id/action_show_direction"
+ android:title="@string/action_show_direction"/>
+</menu>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -41,7 +41,7 @@
<string name="message_check_at_least_one">Vérifiez cocher au moins un élément à importer !</string>
<string name="load_file_favorites">Importer les favoris depuis une sauvegarde</string>
<string name="load_preferences">Importer les préférences depuis une sauvegarde</string>
- <string name="passages">Arrivées à: %1$s</string>
+ <string name="passages_fill">Arrivées à: %1$s</string>
<string name="action_about_more">En savoir plus</string>
<string name="action_author">Rencontrer l\'auteur</string>
<string name="action_help">Aide</string>
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -18,7 +18,8 @@
<string name="no_arrivals_stop">Nessun passaggio trovato alla fermata</string>
<string name="searching_arrivals_fmt">Ricerca arrivi da %1$s</string>
<string name="parsing_error">Errore di lettura del sito 5T/GTT (dannato sito!)</string>
- <string name="passages">Fermata: %1$s</string>
+ <string name="passages_fill">Fermata: %1$s</string>
+ <string name="passages">Fermata:</string>
<string name="line">Linea</string>
<string name="lines">Linee</string>
<string name="urban_lines">Linee urbane</string>
@@ -45,6 +46,8 @@
<string name="action_source">Codice sorgente</string>
<string name="action_licence">Licenza</string>
<string name="action_author">Incontra l\'autore</string>
+ <string name="action_open_line">Mostra linea</string>
+ <string name="action_show_direction">Vedi direzione</string>
<string name="added_in_favorites">Fermata aggiunta ai preferiti</string>
<string name="cant_add_to_favorites">Impossibile aggiungere ai preferiti (memoria piena o database corrotto?)!</string>
<string name="title_activity_favorites">Preferiti</string>
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -140,7 +140,7 @@
<string name="insert_bus_stop_number_error">Voer bushalte nummer in</string>
<string name="network_error">Check je internetverbinding!</string>
<string name="query_too_short">Te korte naam, typ meer karakters en probeer opnieuw</string>
- <string name="passages">Aankomsten om: %1$s</string>
+ <string name="passages_fill">Aankomsten om: %1$s</string>
<string name="lines_fill">Lijnen: %1$s</string>
<string name="action_about_more">Meer over</string>
<string name="title_activity_favorites">Favorieten</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -31,7 +31,8 @@
<string name="parsing_error">Error parsing the 5T/GTT website (damn site!)</string>
<string name="query_too_short">Name too short, type more characters and retry
</string> <!-- TODO: carry out experiments to determine the best wording for this message and publish a paper with the findings -->
- <string name="passages">Arrivals at: %1$s</string>
+ <string name="passages_fill">Arrivals at: %1$s</string>
+ <string name="passages">Arrivals at:</string>
<string name="results">Choose the bus stop…</string>
<string name="line">Line</string>
<string name="lines">Lines</string>
@@ -142,6 +143,8 @@
<string name="cant_add_to_favorites">Cannot add to favorites (storage full or corrupted database?)!</string>
<string name="action_view_on_map">View on a map</string>
+ <string name="action_open_line">Open line</string>
+ <string name="action_show_direction">Show full direction</string>
<string name="cannot_show_on_map_no_activity">Cannot find any application to show it in</string>
<string name="cannot_show_on_map_no_position">Cannot find the position of the stop</string>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, May 21, 08:14 (22 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1911176
Default Alt Text
D222.1779344075.diff (57 KB)
Attached To
Mode
D222: Show stop from arrivals and many other improvements
Attached
Detach File
Event Timeline