Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import com.skedgo.tripkit.booking.quickbooking.Rider
import org.joda.time.format.ISODateTimeFormat
import java.text.SimpleDateFormat
import java.util.Locale
import android.content.Context
import java.util.Date
import com.skedgo.tripkit.ui.utils.SystemTimeFormatManager

data class GenericListItem(
val label: String,
Expand Down Expand Up @@ -70,5 +73,26 @@ data class GenericListItem(

return emptyList()
}

private fun formatTime(context: Context, timeInMillis: Long): String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some identical logics can be extracted.

val fromSdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.UK)
val toSdfDate = SimpleDateFormat("MMM dd, yyyy", Locale.UK)
// Use SystemTimeFormatManager singleton instead of requiring Context parameter
val timePattern = SystemTimeFormatManager.getTimeFormatPatternWithAmPm()
val toSdfTime = SimpleDateFormat(timePattern, Locale.UK)
val fromDate = Date(timeInMillis)
return "${toSdfDate.format(fromDate)} ${toSdfTime.format(fromDate)}"
}

private fun formatTimeRange(context: Context, startTimeInMillis: Long, endTimeInMillis: Long): String {
val fromSdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.UK)
val toSdfDate = SimpleDateFormat("MMM dd, yyyy", Locale.UK)
// Use SystemTimeFormatManager singleton instead of requiring Context parameter
val timePattern = SystemTimeFormatManager.getTimeFormatPatternWithAmPm()
val toSdfTime = SimpleDateFormat(timePattern, Locale.UK)
val startDate = Date(startTimeInMillis)
val endDate = Date(endTimeInMillis)
return "${toSdfDate.format(startDate)} ${toSdfTime.format(startDate)} - ${toSdfDate.format(endDate)} ${toSdfTime.format(endDate)}"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import java.util.Calendar
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.TimeUnit.MILLISECONDS
import android.text.format.DateFormat
import com.skedgo.tripkit.ui.utils.SystemTimeFormatManager

class TKUIDateTimePickerDialogFragment : BaseDialog<FragmentTkuiDateTimePickerDialogBinding>() {

Expand Down Expand Up @@ -82,8 +84,8 @@ class TKUIDateTimePickerDialogFragment : BaseDialog<FragmentTkuiDateTimePickerDi
calendar.set(Calendar.HOUR_OF_DAY, selectedHour)
calendar.set(Calendar.MINUTE, selectedMinute)

// Format the time as hh:mm a (12-hour format with AM/PM)
val sdf = SimpleDateFormat("hh:mm a", Locale.getDefault())
val timePattern = SystemTimeFormatManager.getTimeFormatPattern()
val sdf = SimpleDateFormat(timePattern, Locale.getDefault())
val formattedTime = sdf.format(calendar.time)

viewModel.setTime(formattedTime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.google.android.gms.maps.model.MarkerOptions
import com.skedgo.tripkit.common.model.location.Location
import com.skedgo.tripkit.parkingspots.models.Parking
import com.skedgo.tripkit.ui.map.adapter.StopInfoWindowAdapter
import com.skedgo.tripkit.ui.map.adapter.ViewableInfoWindowAdapter
import com.skedgo.tripkit.ui.map.adapter.NonClickableInfoWindowAdapter
import com.skedgo.tripkit.ui.model.PodLocation
import com.skedgo.tripkit.ui.tracking.EventTracker
import com.squareup.otto.Bus
Expand All @@ -22,7 +22,7 @@ class CarParkPOILocation(val parking: Parking) : IMapPoiLocation {
CreateMarkerForParking.execute(resources, parking)

override fun getInfoWindowAdapter(context: Context): StopInfoWindowAdapter {
return ViewableInfoWindowAdapter(LayoutInflater.from(context))
return NonClickableInfoWindowAdapter(LayoutInflater.from(context))

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.google.android.gms.maps.model.MarkerOptions
import com.skedgo.tripkit.common.model.location.Location
import com.skedgo.tripkit.data.database.locations.facility.FacilityLocationEntity
import com.skedgo.tripkit.ui.map.adapter.StopInfoWindowAdapter
import com.skedgo.tripkit.ui.map.adapter.ViewableInfoWindowAdapter
import com.skedgo.tripkit.ui.map.adapter.NonClickableInfoWindowAdapter
import com.skedgo.tripkit.ui.model.PodLocation
import com.skedgo.tripkit.ui.tracking.EventTracker
import com.squareup.otto.Bus
Expand All @@ -24,7 +24,7 @@ class FacilityPOILocation(
CreateMarkerFoFacility.execute(resources, facilityLocationEntity)

override fun getInfoWindowAdapter(context: Context): StopInfoWindowAdapter {
return ViewableInfoWindowAdapter(LayoutInflater.from(context))
return NonClickableInfoWindowAdapter(LayoutInflater.from(context))

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.skedgo.tripkit.ui.map

import android.content.Context
import android.content.res.Resources
import android.view.LayoutInflater
import com.google.android.gms.maps.model.MarkerOptions
import com.skedgo.tripkit.common.model.location.Location
import com.skedgo.tripkit.common.model.stop.ScheduledStop
import com.skedgo.tripkit.data.locations.StopsFetcher
import com.skedgo.tripkit.ui.map.adapter.NonClickableInfoWindowAdapter
import com.skedgo.tripkit.ui.map.adapter.StopInfoWindowAdapter
import com.skedgo.tripkit.ui.tracking.EventTracker
import com.squareup.otto.Bus
Expand All @@ -25,7 +27,7 @@ class StopPOILocation(
}

override fun getInfoWindowAdapter(context: Context): StopInfoWindowAdapter? {
return stopInfoWindowAdapter
return NonClickableInfoWindowAdapter(LayoutInflater.from(context))
}

override fun toLocation(): Location {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.skedgo.tripkit.ui.map.adapter

import android.view.LayoutInflater
import android.view.View
import com.google.android.gms.maps.model.Marker
import com.skedgo.tripkit.ui.map.SimpleCalloutView
import javax.inject.Inject

class NonClickableInfoWindowAdapter @Inject constructor(private val inflater: LayoutInflater) :
StopInfoWindowAdapter {
private var view: SimpleCalloutView? = null

override fun getInfoContents(marker: Marker): View {
if (view == null) {
view = SimpleCalloutView.create(inflater)
}
assert(view != null)
view!!.setTitle(marker.title)
view!!.setSnippet(marker.snippet)
// Explicitly hide the right image (arrow icon) for non-clickable POIs
view!!.setRightImage(0) // This will hide the image via ViewUtils.setImage
return view!!
}

override fun windowInfoHeightInPixel(marker: Marker): Int {
return if (view != null) {
view!!.height
} else {
0
}
}

override fun onInfoWindowClosed(marker: Marker) {
}

override fun getInfoWindow(marker: Marker): View? {
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ import com.skedgo.tripkit.ui.TripKitUI
import com.skedgo.tripkit.ui.core.addTo
import com.skedgo.tripkit.ui.core.module.HomeMapFragmentModule
import com.skedgo.tripkit.ui.data.toLocation
import com.skedgo.tripkit.ui.map.CarParkPOILocation
import com.skedgo.tripkit.ui.map.FacilityPOILocation
import com.skedgo.tripkit.ui.map.GenericIMapPoiLocation
import com.skedgo.tripkit.ui.map.IMapPoiLocation
import com.skedgo.tripkit.ui.map.StopPOILocation
import com.skedgo.tripkit.ui.map.LocationEnhancedMapFragment
import com.skedgo.tripkit.ui.map.MapCameraController
import com.skedgo.tripkit.ui.map.MapMarkerUtils
Expand Down Expand Up @@ -888,7 +891,7 @@ class TripKitMapFragment : LocationEnhancedMapFragment(), OnInfoWindowClickListe
poiMarkers.setOnInfoWindowClickListener { marker: Marker ->
if (onInfoWindowClickListener != null) {
val poiLocation = marker.tag as IMapPoiLocation?
if (poiLocation != null) {
if (poiLocation != null && isPoiWindowAdapterClickable(poiLocation)) {
onInfoWindowClickListener!!.onInfoWindowClick(poiLocation.toLocation())
}
}
Expand Down Expand Up @@ -932,10 +935,14 @@ class TripKitMapFragment : LocationEnhancedMapFragment(), OnInfoWindowClickListe
transportModes = it
}

poiMarkers?.clear()
viewModel.showMarkers.set(show)
if (show) {
tripLocationMarkers?.showAll()
poiMarkers?.showAll()
loadMarkers()
} else {
tripLocationMarkers?.hideAll()
poiMarkers?.hideAll()
}
}

Expand All @@ -947,6 +954,18 @@ class TripKitMapFragment : LocationEnhancedMapFragment(), OnInfoWindowClickListe
map?.let { cameraController.moveToPolygonBounds(it, polygon) }
}

/**
* Check if a POI location should be clickable based on its type
*/
private fun isPoiWindowAdapterClickable(poiLocation: IMapPoiLocation): Boolean {
return when (poiLocation) {
is StopPOILocation -> false
is CarParkPOILocation -> false
is FacilityPOILocation -> false
else -> true
}
}

companion object {
private fun asMarkerIcon(mode: SelectionType): BitmapDescriptor {
return if (mode === SelectionType.DEPARTURE) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.skedgo.tripkit.ui.timetables

import android.content.Context
import android.text.format.DateFormat
import com.skedgo.tripkit.common.model.realtimealert.RealTimeStatus
import com.skedgo.tripkit.common.util.TimeUtils
import com.skedgo.tripkit.datetime.PrintTime
Expand All @@ -27,7 +28,9 @@ open class GetRealtimeText @Inject constructor(

val isRightToLeft = context.resources.getBoolean(R.bool.is_right_to_left)

val dateTimeFormatter = DateTimeFormat.forPattern("HH:mm")
// Use system-aware time format instead of hardcoded "HH:mm"
val timePattern = if (DateFormat.is24HourFormat(context)) "H:mm" else "h:mm a"
val dateTimeFormatter = DateTimeFormat.forPattern(timePattern)
val startTime = realTimeDeparture(service, service.realtimeVehicle)
val endTime = realTimeArrival(service, service.realtimeVehicle)
val startDateTime = DateTime(TimeUnit.SECONDS.toMillis(startTime))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.gms.maps.model.Polyline
import com.google.android.gms.maps.model.PolylineOptions
import com.skedgo.rxtry.printThrowableStackTrace
import com.skedgo.rxtry.subscribeWithErrorHandling
import com.skedgo.tripkit.common.model.stop.ScheduledStop
import com.skedgo.tripkit.common.model.stop.ServiceStop
Expand Down Expand Up @@ -155,12 +156,15 @@ class TimetableMapContributor(val fragment: Fragment) : TripKitMapContributor {
val marker = map.addMarker(first)
stopCodesToMarkerMap[second!!] = marker
}
fitAllMapElementsToBounds()
}
)


autoDisposable.add(viewModel.viewPort
.subscribeWithErrorHandling { coordinates: List<LatLng>? -> this.centerMapOver(map, coordinates) })
// autoDisposable.add(viewModel.viewPort
// .subscribeWithErrorHandling { coordinates: List<LatLng>? ->
// this.centerMapOver(map, coordinates) }
// )

autoDisposable.add(viewModel.drawServiceLine
.subscribeWithErrorHandling { polylineOptions: List<PolylineOptions?> ->
Expand All @@ -179,10 +183,7 @@ class TimetableMapContributor(val fragment: Fragment) : TripKitMapContributor {
}
}

val bounds = builder.build()
val padding = 50 // Optional padding around the bounds
val cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, padding)
map.animateCamera(cameraUpdate)
fitAllMapElementsToBounds()
})

autoDisposable.add(viewModel.realtimeVehicle
Expand All @@ -192,6 +193,7 @@ class TimetableMapContributor(val fragment: Fragment) : TripKitMapContributor {
} else {
setRealTimeVehicle(null) // Handle empty OptionalCompat
}
fitAllMapElementsToBounds()
})
}

Expand Down Expand Up @@ -419,4 +421,65 @@ class TimetableMapContributor(val fragment: Fragment) : TripKitMapContributor {
fun getMapPreviousPosition(): CameraPosition? {
return previousCameraPosition
}

private fun fitAllMapElementsToBounds(
paddingPx: Int = 160,
includeRealtimeVehicle: Boolean = true,
singlePointZoom: Float = 16f
) {
val map = googleMap ?: return

val builder = LatLngBounds.Builder()
var count = 0
var firstPoint: LatLng? = null

// 1) All stop markers
for (marker in stopCodesToMarkerMap.values) {
val p = marker.position
builder.include(p)
if (count == 0) firstPoint = p
count++
}

// 2) All polyline points
for (poly in serviceLines) {
for (p in poly.points) {
builder.include(p)
if (count == 0) firstPoint = p
count++
}
}

// 3) Realtime vehicle marker
if (includeRealtimeVehicle) {
realTimeVehicleMarker?.position?.let { p ->
builder.include(p)
if (count == 0) firstPoint = p
count++
}
}

if (count == 0) return // nothing to show

try {
if (count == 1) {
// Only one point -> just zoom to it
map.animateCamera(CameraUpdateFactory.newLatLngZoom(firstPoint!!, singlePointZoom))
} else {
// Multiple points -> fit bounds
val bounds = builder.build()
try {
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, paddingPx))
} catch (_: IllegalStateException) {
// Fallback if called before map has size; post to the view to retry
fragment.view?.post {
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, paddingPx))
}
}
}
} catch (e: Exception) {
e.printThrowableStackTrace()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be replaced by Timber or Log

}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import com.skedgo.tripkit.ui.trip.ArriveBy
import com.skedgo.tripkit.ui.trip.LeaveAfter
import com.skedgo.tripkit.ui.trip.Now
import com.skedgo.tripkit.ui.trip.RoutingTime
import com.skedgo.tripkit.ui.utils.SystemTimeFormatManager
import io.reactivex.Single
import org.joda.time.DateTime
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import javax.inject.Inject

private const val ROUTING_TIME_PATTERN = "MMM dd, h:mm a"

open class RoutingTimeViewModelMapper @Inject internal constructor(
private val resources: Resources
) {
Expand All @@ -27,7 +26,9 @@ open class RoutingTimeViewModelMapper @Inject internal constructor(
}

private fun DateTime.format(): String {
val simpleDateFormat = SimpleDateFormat(ROUTING_TIME_PATTERN, Locale.US)
val timePattern = SystemTimeFormatManager.getTimeFormatPattern()
val datePattern = "MMM dd, $timePattern"
val simpleDateFormat = SimpleDateFormat(datePattern, Locale.US)
simpleDateFormat.timeZone = zone.toTimeZone()
return simpleDateFormat.format(Date(millis))
}
Expand Down
Loading