From 9a93430305d1bfd92fd6efd907c0da88012277b3 Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:13:18 +0200 Subject: [PATCH 01/15] Taxi app | Change TripDto, LocationDto and Change entities and the mapper between them --- .../kotlin/data/BpLocationDataSource.kt | 5 ++-- .../remote/fakegateway/LocationFakeGateway.kt | 5 ++-- .../remote/fakegateway/OrderFakeGateway.kt | 29 ++++++++++--------- .../kotlin/data/remote/mapper/MapMapper.kt | 24 +++++++++------ .../kotlin/data/remote/model/LocationDto.kt | 9 ++++-- .../kotlin/data/remote/model/OrderDto.kt | 9 ------ .../kotlin/data/remote/model/TripDto.kt | 24 +++++++++++++++ .../kotlin/domain/entity/Location.kt | 5 ++-- .../commonMain/kotlin/domain/entity/Order.kt | 8 ----- .../commonMain/kotlin/domain/entity/Trip.kt | 16 ++++++++++ .../kotlin/domain/gateway/IOrderGateway.kt | 4 +-- 11 files changed, 84 insertions(+), 54 deletions(-) delete mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/OrderDto.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt delete mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Order.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Trip.kt diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/BpLocationDataSource.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/BpLocationDataSource.kt index e22b3dea1..145b32a68 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/BpLocationDataSource.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/BpLocationDataSource.kt @@ -17,9 +17,8 @@ class BpLocationDataSource(private val locationTracker: LocationTracker) : IBpLo locationTracker.startTracking() return locationTracker.getLocationsFlow().map { Location( - lat = it.latitude, - lng = it.longitude, - addressName = "" + latitude = it.latitude, + longitude = it.longitude, ) } } catch (deniedAlways: DeniedAlwaysException) { diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt index 87d8cb45d..f386a0c93 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt @@ -13,9 +13,8 @@ class LocationFakeGateway : ILocationGateway { lattiude += 0.00004 emit( Location( - lat = lattiude, - lng = 31.235712, - addressName = "Cairo, Egypt", + latitude = lattiude, + longitude = 31.235712, ) ) delay(2000) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt index c781901e8..fae568652 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt @@ -2,28 +2,29 @@ package data.remote.fakegateway import data.remote.mapper.toEntity import data.remote.model.LocationDto -import data.remote.model.OrderDto -import domain.entity.Order +import data.remote.model.TripDto +import domain.entity.Trip import domain.gateway.IOrderGateway import kotlinx.coroutines.delay class OrderFakeGateway : IOrderGateway { - override suspend fun findingNewOrder(): Order { + override suspend fun findingNewOrder(): Trip { delay(4000) - return OrderDto( + return TripDto( id = "djsahdjadhjadjas45dsadas", - passengerId = "sjdadjsadsa-dsa4d8sa4dsa", - passengerName = "Cristiano Ronaldo", - pickUpAddress = LocationDto( - lat = 40.6790229, - lng = -73.8740306, - addressName = "45, Faisal St., Riyadh, KSA", + clientName = "Cristiano Ronaldo", + startPoint = LocationDto( + latitude = 40.6790229, + longitude = -73.8740306, ), - dropOffAddress = LocationDto( - lat = 30.8859508, - lng = 31.4453136, - addressName = "Nirmala,girsls HSS", + destination = LocationDto( + latitude = 30.8859508, + longitude = 31.4453136, ), + startPointAddress = "ooveofe", + destinationAddress = "h9viife", + price = 100.0, + tripStatus = 1 ).toEntity() } } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt index c5cc04820..ab25b07ab 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt @@ -1,19 +1,25 @@ package data.remote.mapper import data.remote.model.LocationDto -import data.remote.model.OrderDto +import data.remote.model.TripDto import domain.entity.Location -import domain.entity.Order +import domain.entity.Trip -fun OrderDto.toEntity(): Order = Order( +fun TripDto.toEntity(): Trip = Trip( id = id ?: "", - passengerName = passengerName ?: "", - dropOffAddress = dropOffAddress.toEntity(), - pickUpAddress = pickUpAddress.toEntity(), + passengerName = this.clientName ?: "", + dropOffLocation = this.destination.toEntity(), + pickUpLocation = this.startPoint.toEntity(), + pickUpAddress = this.startPointAddress, + dropOffAddress = this.destinationAddress ) fun LocationDto.toEntity(): Location = Location( - lat = lat ?: 0.0, - lng = lng ?: 0.0, - addressName = addressName ?: "", + latitude = this.latitude ?: 0.0, + longitude = this.longitude ?: 0.0, +) + +fun Location.toDto(): LocationDto = LocationDto( + latitude = this.latitude, + longitude = this.longitude, ) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/LocationDto.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/LocationDto.kt index 92aa4720b..3969d0417 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/LocationDto.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/LocationDto.kt @@ -1,7 +1,10 @@ package data.remote.model +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable data class LocationDto( - val lat: Double?, - val lng: Double?, - val addressName: String?, + @SerialName("latitude") val latitude: Double? = null, + @SerialName("longitude") val longitude: Double? = null ) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/OrderDto.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/OrderDto.kt deleted file mode 100644 index b0fc21003..000000000 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/OrderDto.kt +++ /dev/null @@ -1,9 +0,0 @@ -package data.remote.model - -data class OrderDto( - val id: String?, - val passengerName: String?, - val passengerId: String?, - val pickUpAddress: LocationDto, - val dropOffAddress: LocationDto, -) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt new file mode 100644 index 000000000..387f163ee --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt @@ -0,0 +1,24 @@ +package data.remote.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TripDto( + @SerialName("id") + val id: String, + @SerialName("clientName") + val clientName: String, + @SerialName("startPoint") + val startPoint: LocationDto, + @SerialName("destination") + val destination: LocationDto, + @SerialName("startPointAddress") + val startPointAddress: String, + @SerialName("destinationAddress") + val destinationAddress: String, + @SerialName("price") + val price: Double, + @SerialName("tripStatus") + val tripStatus: Int +) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Location.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Location.kt index 3ff4b717b..21dc56ea9 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Location.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Location.kt @@ -1,7 +1,6 @@ package domain.entity data class Location( - val lat: Double, - val lng: Double, - val addressName: String, + val latitude: Double, + val longitude: Double, ) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Order.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Order.kt deleted file mode 100644 index dc0e80eff..000000000 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Order.kt +++ /dev/null @@ -1,8 +0,0 @@ -package domain.entity - -data class Order( - val id: String, - val passengerName: String, - val pickUpAddress: Location, - val dropOffAddress: Location, -) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Trip.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Trip.kt new file mode 100644 index 000000000..33e3b4a7d --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Trip.kt @@ -0,0 +1,16 @@ +package domain.entity + +data class Trip( + val id: String, + val passengerName: String, + val pickUpLocation: Location, + val pickUpAddress: String, + val dropOffLocation: Location, + val dropOffAddress: String, +){ + enum class Status(val statusCode: Int){ + APPROVED(1), + RECEIVED(2), + FINISHED(3); + } +} \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/IOrderGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/IOrderGateway.kt index c272be265..e7e940e14 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/IOrderGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/IOrderGateway.kt @@ -1,7 +1,7 @@ package domain.gateway -import domain.entity.Order +import domain.entity.Trip interface IOrderGateway { - suspend fun findingNewOrder(): Order + suspend fun findingNewOrder(): Trip } \ No newline at end of file From 78a7551653dd7c6d41e89375f6dea17dbacabb0c Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:16:50 +0200 Subject: [PATCH 02/15] Taxi app | Change MapUiState and the mapper between the entities and the uiState --- .../kotlin/presentation/map/MapMapper.kt | 29 +++++++------------ .../presentation/map/MapScreenUiState.kt | 16 +++++----- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt index e8b855d84..69f660df5 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt @@ -1,30 +1,23 @@ package presentation.map import domain.entity.Location -import domain.entity.Order +import domain.entity.Trip -fun Order.toUiState() = OrderInfoUiState( +fun Trip.toUiState() = TripInfoUiState( + id = this.id, passengerName = passengerName, - dropOffAddress = LocationInfoUiState( - addressName = dropOffAddress.addressName, - lat = dropOffAddress.lat, - lng = dropOffAddress.lng, - ), - pickUpAddress = LocationInfoUiState( - addressName = pickUpAddress.addressName, - lat = pickUpAddress.lat, - lng = pickUpAddress.lng, - ), + dropOffLocation = this.dropOffLocation.toUiState(), + pickUpLocation = this.pickUpLocation.toUiState(), + dropOffAddress = this.dropOffAddress, + pickUpAddress = this.pickUpAddress ) fun Location.toUiState() = LocationInfoUiState( - lat = lat, - lng = lng, - addressName = addressName, + lat = latitude, + lng = longitude, ) fun LocationInfoUiState.toEntity(): Location = Location( - lat = lat, - lng = lng, - addressName = addressName, + latitude = lat, + longitude = lng, ) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenUiState.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenUiState.kt index 3a37777f4..76dc3084c 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenUiState.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenUiState.kt @@ -3,24 +3,26 @@ package presentation.map import presentation.base.ErrorState data class MapScreenUiState( - val isLoading: Boolean = false, + val isLoading: Boolean = true, val error: ErrorState? = null, - val userName: String = "", + val driverName: String = "", val currentLocation: LocationInfoUiState = LocationInfoUiState(), val isNewOrderFound: Boolean = false, val isAcceptedOrder: Boolean = false, - val orderInfoUiState: OrderInfoUiState = OrderInfoUiState(), + val tripInfoUiState: TripInfoUiState = TripInfoUiState(), ) -data class OrderInfoUiState( +data class TripInfoUiState( + val id: String = "", val passengerName: String = "", - val pickUpAddress: LocationInfoUiState? = null, - val dropOffAddress: LocationInfoUiState? = null, + val pickUpLocation: LocationInfoUiState? = null, + val dropOffLocation: LocationInfoUiState? = null, + val pickUpAddress: String = "", + val dropOffAddress: String = "", val isArrived: Boolean = false, ) data class LocationInfoUiState( val lat: Double = 0.0, val lng: Double = 0.0, - val addressName: String = "", ) \ No newline at end of file From 37c22761db4a07daa2cc93c4b32351e3d2041948 Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:18:09 +0200 Subject: [PATCH 03/15] Taxi app | add socket exception --- .../shared/src/commonMain/kotlin/domain/ErrorType.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt index d2b6168d9..dc0dfc2e7 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt @@ -33,4 +33,5 @@ class InvalidDriverNameException(private val errorMessage: String) : BpException class InvalidDriverEmailException(private val errorMessage: String) : BpException(errorMessage) -class InvalidDescriptionException(private val errorMessage: String) : BpException(errorMessage) \ No newline at end of file +class InvalidDescriptionException(private val errorMessage: String) : BpException(errorMessage) +class SocketException(private val errorMessage: String) : BpException(errorMessage) \ No newline at end of file From d1a210839a106eb9c0828bdd6c9222ac69803f89 Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:19:47 +0200 Subject: [PATCH 04/15] Taxi app | add functions to handle webSocket the receiving and sending Data --- .../data/remote/gateway/BaseRemoteGateway.kt | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/BaseRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/BaseRemoteGateway.kt index e4259b154..d6c4e48ed 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/BaseRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/BaseRemoteGateway.kt @@ -1,15 +1,24 @@ package data.remote.gateway import data.remote.model.BaseResponse -import domain.InternetException import domain.InvalidPasswordException import domain.InvalidUserNameException import domain.NoInternetException +import domain.SocketException import domain.UnknownErrorException import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.plugins.ClientRequestException +import io.ktor.client.plugins.websocket.receiveDeserialized +import io.ktor.client.plugins.websocket.sendSerialized +import io.ktor.client.plugins.websocket.wss import io.ktor.client.statement.HttpResponse +import io.ktor.util.network.UnresolvedAddressException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn abstract class BaseRemoteGateway(val client: HttpClient) { @@ -23,12 +32,37 @@ abstract class BaseRemoteGateway(val client: HttpClient) { val errorMessages = e.response.body>().status?.errorMessages errorMessages?.let { throwMatchingException(it) } throw UnknownErrorException(e.message) - } catch (e: InternetException) { + } catch (e: UnresolvedAddressException) { throw NoInternetException() } catch (e: Exception) { throw UnknownErrorException(e.message.toString()) } } + suspend inline fun HttpClient.tryToExecuteWebSocket(path: String): Flow { + return flow { + wss(path = path) { + while (true) { + try { + emit(receiveDeserialized()) + } catch (e: Exception) { + throw SocketException(e.message.orEmpty()) + } + } + } + }.flowOn(Dispatchers.IO) + } + suspend inline fun HttpClient.tryToSendWebSocketData( + data: T, + path: String, + ) { + wss(path) { + try { + sendSerialized(data) + } catch (e: Exception) { + throw SocketException(e.message.orEmpty()) + } + } + } fun throwMatchingException(errorMessages: Map) { when { From 6f26a362f6e455add9643a3a3b6c1c0d5902bbfc Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:21:22 +0200 Subject: [PATCH 05/15] Taxi app | make the requests of trips endpoints --- .../data/remote/gateway/TripRemoteGateway.kt | 46 +++++++++++++++++++ .../src/commonMain/kotlin/di/GatewayModule.kt | 3 ++ .../gateway/remote/ITripRemoteGateway.kt | 12 +++++ 3 files changed, 61 insertions(+) create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt new file mode 100644 index 000000000..6cb4abe94 --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt @@ -0,0 +1,46 @@ +package data.remote.gateway + +import data.remote.mapper.toDto +import data.remote.mapper.toEntity +import data.remote.model.BaseResponse +import data.remote.model.LocationDto +import data.remote.model.TripDto +import domain.NotFoundedException +import domain.entity.Location +import domain.entity.Trip +import domain.gateway.remote.ITripRemoteGateway +import io.ktor.client.HttpClient +import io.ktor.client.request.forms.submitForm +import io.ktor.http.HttpMethod +import io.ktor.http.Parameters +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class TripRemoteGateway(client: HttpClient) : ITripRemoteGateway, + BaseRemoteGateway(client = client) { + override suspend fun getTrips(): Flow { + return client.tryToExecuteWebSocket("/trip/incoming-taxi-rides") + .map { it.toEntity() } + } + + override suspend fun sendLocation(location: Location, tripId: String) { + client.tryToSendWebSocketData( + path = "/location/sender/$tripId", + data = location.toDto() + ) + } + + override suspend fun updateTrip(taxiId: String, tripId: String) { + val result = tryToExecute> { + submitForm( + url = ("/trip/update/taxi-ride"), + formParameters = Parameters.build { + append("tripId", tripId) + append("taxiId", taxiId) + }, + block = { method = HttpMethod.Put } + ) + }.value ?: throw NotFoundedException() + } + +} \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt b/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt index cafe2d030..6d04835a5 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt @@ -4,10 +4,12 @@ import data.local.gateway.LocalConfigurationGateway import data.remote.fakegateway.OrderFakeGateway import data.remote.gateway.IdentityRemoteGateway import data.remote.gateway.LocationRemoteGateway +import data.remote.gateway.TripRemoteGateway import domain.gateway.ILocationGateway import domain.gateway.IOrderGateway import domain.gateway.local.ILocalConfigurationGateway import domain.gateway.remote.IIdentityRemoteGateway +import domain.gateway.remote.ITripRemoteGateway import org.koin.core.module.dsl.bind import org.koin.core.module.dsl.singleOf import org.koin.dsl.module @@ -19,4 +21,5 @@ val GatewayModule = module { singleOf(::LocalConfigurationGateway) { bind() } singleOf(::OrderFakeGateway) { bind() } singleOf(::LocationRemoteGateway) { bind() } + singleOf(::TripRemoteGateway) {bind()} } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt new file mode 100644 index 000000000..c6ced17cc --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt @@ -0,0 +1,12 @@ +package domain.gateway.remote + +import domain.entity.Location +import domain.entity.Trip +import kotlinx.coroutines.flow.Flow + + +interface ITripRemoteGateway { + suspend fun getTrips(): Flow + suspend fun sendLocation(location: Location, tripId: String) + suspend fun updateTrip(taxiId: String, tripId: String) +} \ No newline at end of file From 7e68998ce8ae45c92be0ceecd37914099aabc43e Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:23:23 +0200 Subject: [PATCH 06/15] Taxi app | add TripUseCase to handle the requests to gateway --- .../src/commonMain/kotlin/di/UseCaseModule.kt | 6 ++-- .../domain/usecase/ManageOrderUseCase.kt | 15 ---------- .../domain/usecase/ManageTripUseCase.kt | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+), 18 deletions(-) delete mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageOrderUseCase.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/di/UseCaseModule.kt b/client_taxi_driver/shared/src/commonMain/kotlin/di/UseCaseModule.kt index bfdacd957..0e19ddc90 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/di/UseCaseModule.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/di/UseCaseModule.kt @@ -2,16 +2,16 @@ package di import domain.usecase.ILoginUserUseCase import domain.usecase.IManageLocationUseCase -import domain.usecase.IManageOrderUseCase +import domain.usecase.IManageTripUseCase import domain.usecase.LoginUserUseCase import domain.usecase.ManageLocationUseCase -import domain.usecase.ManageOrderUseCase +import domain.usecase.ManageTripUseCase import org.koin.core.module.dsl.bind import org.koin.core.module.dsl.singleOf import org.koin.dsl.module val UseCaseModule = module { singleOf(::LoginUserUseCase) { bind() } - singleOf(::ManageOrderUseCase) { bind() } + singleOf(::ManageTripUseCase) { bind() } singleOf(::ManageLocationUseCase) { bind() } } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageOrderUseCase.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageOrderUseCase.kt deleted file mode 100644 index 4e58ae32e..000000000 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageOrderUseCase.kt +++ /dev/null @@ -1,15 +0,0 @@ -package domain.usecase - -import data.remote.fakegateway.OrderFakeGateway -import domain.entity.Order - - -interface IManageOrderUseCase { - suspend fun foundNewOrder(): Order -} - -class ManageOrderUseCase( - private val mapGateway: OrderFakeGateway, -) : IManageOrderUseCase { - override suspend fun foundNewOrder() = mapGateway.findingNewOrder() -} \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt new file mode 100644 index 000000000..dbdf4bdf0 --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt @@ -0,0 +1,28 @@ +package domain.usecase + +import domain.entity.Location +import domain.entity.Trip +import domain.gateway.remote.ITripRemoteGateway +import kotlinx.coroutines.flow.last + + +interface IManageTripUseCase { + suspend fun findNewTrip(): Trip + suspend fun updateTripLocation(location: Location, tripId: String) + suspend fun updateTripStatus(tripId: String) +} + +class ManageTripUseCase( + private val tripGateway: ITripRemoteGateway, +) : IManageTripUseCase { + override suspend fun findNewTrip(): Trip { + return tripGateway.getTrips().last() + } + override suspend fun updateTripLocation(location: Location, tripId: String) { + tripGateway.sendLocation(location = location, tripId = tripId) + } + + override suspend fun updateTripStatus(tripId: String) { + tripGateway.updateTrip("0" ,tripId) + } +} \ No newline at end of file From 72bf883386eec6f70f0495adb9df635e34d28a78 Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:24:07 +0200 Subject: [PATCH 07/15] Taxi app | add requests to the useCase --- .../kotlin/presentation/map/MapScreenModel.kt | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt index 97c5921ed..a45d98702 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt @@ -2,30 +2,32 @@ package presentation.map import cafe.adriel.voyager.core.model.coroutineScope import domain.entity.Location -import domain.entity.Order +import domain.entity.Trip import domain.usecase.IManageLocationUseCase -import domain.usecase.IManageOrderUseCase +import domain.usecase.IManageTripUseCase import domain.usecase.LoginUserUseCase +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.launch import presentation.base.BaseScreenModel import presentation.base.ErrorState class MapScreenModel( private val loginUserUseCase: LoginUserUseCase, - private val order: IManageOrderUseCase, + private val manageTrip: IManageTripUseCase, private val location: IManageLocationUseCase, ) : BaseScreenModel(MapScreenUiState()), MapScreenInteractionListener { init { - getLiveLocation() findingNewOrder() + getLiveLocation() getUserName() } private fun findingNewOrder() { tryToExecute( - function = order::foundNewOrder, + function = manageTrip::findNewTrip, onSuccess = ::onFoundNewOrderSuccess, onError = ::onError ) @@ -36,19 +38,19 @@ class MapScreenModel( val username = loginUserUseCase.getUsername() updateState { it.copy( - userName = username, + driverName = username, ) } } } - private fun onFoundNewOrderSuccess(order: Order) { + private fun onFoundNewOrderSuccess(order: Trip) { updateState { it.copy( isLoading = false, isNewOrderFound = true, error = null, - orderInfoUiState = order.toUiState() + tripInfoUiState = order.toUiState() ) } } @@ -72,23 +74,42 @@ class MapScreenModel( } private fun onGetLiveLocationSuccess(location: Location) { - updateState { - it.copy( + updateState { mapScreenUiState -> + mapScreenUiState.copy( isLoading = true, error = null, currentLocation = location.toUiState() - ) + ).also { + if (it.isAcceptedOrder) { + sendLocationIfTripAccepted( + it.currentLocation.toEntity(), + it.tripInfoUiState.id + ) + } + } } } + private fun sendLocationIfTripAccepted(location: Location, tripId: String) { + tryToExecute( + function = { manageTrip.updateTripLocation(location, tripId) }, + onSuccess = {}, + onError = ::onError, + ) + } + override fun onClickAccept() { - updateState { - it.copy( + updateState { mapScreenUiState -> + mapScreenUiState.copy( isLoading = false, error = null, isNewOrderFound = false, isAcceptedOrder = true, - ) + ).also { + coroutineScope.launch(Dispatchers.IO) { + manageTrip.updateTripStatus(it.tripInfoUiState.id) + } + } } } @@ -99,7 +120,7 @@ class MapScreenModel( isNewOrderFound = false, isAcceptedOrder = false, error = null, - orderInfoUiState = OrderInfoUiState() + tripInfoUiState = TripInfoUiState() ) } findingNewOrder() @@ -110,10 +131,14 @@ class MapScreenModel( it.copy( isLoading = false, error = null, - orderInfoUiState = it.orderInfoUiState.copy( + tripInfoUiState = it.tripInfoUiState.copy( isArrived = true ) - ) + ).also { + coroutineScope.launch(Dispatchers.IO) { + manageTrip.updateTripStatus(it.tripInfoUiState.id) + } + } } } @@ -123,10 +148,14 @@ class MapScreenModel( isLoading = true, isAcceptedOrder = false, error = null, - orderInfoUiState = OrderInfoUiState() - ) + tripInfoUiState = TripInfoUiState() + ).also { + coroutineScope.launch(Dispatchers.IO) { + manageTrip.updateTripStatus(it.tripInfoUiState.id) + } + findingNewOrder() + } } - findingNewOrder() } override fun onClickCloseIcon() { From 64e96646ccdec55d90e846a21982671fbef7332d Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Tue, 14 Nov 2023 20:26:30 +0200 Subject: [PATCH 08/15] Taxi app | solve the changed name errors and the loading card animation --- .../kotlin/presentation/map/CalfMap.kt | 4 ++-- .../kotlin/presentation/map/MapScreen.kt | 21 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/CalfMap.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/CalfMap.kt index bb40ad822..6c5826d98 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/CalfMap.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/CalfMap.kt @@ -26,14 +26,14 @@ fun CalfMapWebView( AnimatedVisibility(destination == null) { state.evaluateJavascript( - "createInfiniteLoopFunction(${currentLocation.lat},${currentLocation.lng})()", + "createInfiniteLoopFunction(${currentLocation.latitude},${currentLocation.longitude})()", null ) } LaunchedEffect(key1 = currentLocation) { destination?.let { location -> state.evaluateJavascript( - "getDirections(${currentLocation.lat},${currentLocation.lng},${location.lat},${location.lng})", + "getDirections(${currentLocation.latitude},${currentLocation.longitude},${location.latitude},${location.longitude})", null ) } diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt index 90ecfe951..a4157aa90 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt @@ -49,6 +49,7 @@ class MapScreen : @Composable override fun onRender(state: MapScreenUiState, listener: MapScreenInteractionListener) { + Box( modifier = Modifier.fillMaxSize() ) { @@ -56,11 +57,11 @@ class MapScreen : modifier = Modifier, url = MAP_URL, currentLocation = state.currentLocation.toEntity(), - destination = state.orderInfoUiState.dropOffAddress?.toEntity(), + destination = state.tripInfoUiState.dropOffLocation?.toEntity(), ) BpAppBar( isBackIconVisible = false, - title = "${Resources.strings.mapScreenAppBarTitle}${state.userName}!" + title = "${Resources.strings.mapScreenAppBarTitle}${state.driverName}!" ) { Box( modifier = Modifier @@ -82,7 +83,7 @@ class MapScreen : } MapCardAnimation( modifier = Modifier.align(Alignment.BottomCenter), - visible = state.isLoading, + visible = !state.isLoading, ) { FindingRideCard() } @@ -95,7 +96,7 @@ class MapScreen : modifier = Modifier.align( Alignment.BottomCenter, ), - state = state.orderInfoUiState, + state = state.tripInfoUiState, listener = listener, ) } @@ -108,7 +109,7 @@ class MapScreen : modifier = Modifier.align( Alignment.BottomCenter, ), - state = state.orderInfoUiState, + state = state.tripInfoUiState, listener = listener, ) } @@ -203,7 +204,7 @@ class MapScreen : @Composable private fun NewOrderCard( modifier: Modifier = Modifier, - state: OrderInfoUiState, + state: TripInfoUiState, listener: MapScreenInteractionListener, ) { MapCard( @@ -230,7 +231,7 @@ class MapScreen : Text( modifier = Modifier.padding(start = 4.dp), - text = state.pickUpAddress?.addressName ?: "", + text = state.pickUpAddress, color = Theme.colors.contentSecondary, style = Theme.typography.body, ) @@ -256,7 +257,7 @@ class MapScreen : @Composable private fun OrderCard( modifier: Modifier = Modifier, - state: OrderInfoUiState, + state: TripInfoUiState, listener: MapScreenInteractionListener, ) { MapCard( @@ -281,7 +282,7 @@ class MapScreen : style = Theme.typography.caption, ) Text( - text = state.pickUpAddress?.addressName ?: "", + text = state.pickUpAddress, color = Theme.colors.contentPrimary, style = Theme.typography.body, ) @@ -301,7 +302,7 @@ class MapScreen : style = Theme.typography.caption, ) Text( - text = state.dropOffAddress?.addressName ?: "", + text = state.dropOffAddress, color = Theme.colors.contentPrimary, style = Theme.typography.body, ) From dabb77b1ee1eed8dae2996ec8c163f79189cb57e Mon Sep 17 00:00:00 2001 From: HassanAyman Date: Thu, 16 Nov 2023 20:05:34 +0200 Subject: [PATCH 09/15] Taxi app | add fixed taxi id --- .../kotlin/data/remote/gateway/TripRemoteGateway.kt | 9 +++++++-- .../kotlin/domain/gateway/remote/ITripRemoteGateway.kt | 2 +- .../kotlin/domain/usecase/ManageTripUseCase.kt | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt index 6cb4abe94..aafd40a49 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.map class TripRemoteGateway(client: HttpClient) : ITripRemoteGateway, BaseRemoteGateway(client = client) { + override suspend fun getTrips(): Flow { return client.tryToExecuteWebSocket("/trip/incoming-taxi-rides") .map { it.toEntity() } @@ -30,17 +31,21 @@ class TripRemoteGateway(client: HttpClient) : ITripRemoteGateway, ) } - override suspend fun updateTrip(taxiId: String, tripId: String) { + override suspend fun updateTrip(tripId: String) { val result = tryToExecute> { submitForm( url = ("/trip/update/taxi-ride"), formParameters = Parameters.build { append("tripId", tripId) - append("taxiId", taxiId) + append("taxiId", TAXI_ID) }, block = { method = HttpMethod.Put } ) }.value ?: throw NotFoundedException() } + private companion object{ + const val TAXI_ID = "653d6d4f5a253b12181fa2de" + } + } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt index c6ced17cc..1668cd1c2 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt @@ -8,5 +8,5 @@ import kotlinx.coroutines.flow.Flow interface ITripRemoteGateway { suspend fun getTrips(): Flow suspend fun sendLocation(location: Location, tripId: String) - suspend fun updateTrip(taxiId: String, tripId: String) + suspend fun updateTrip(tripId: String) } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt index dbdf4bdf0..b49687d18 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt @@ -23,6 +23,6 @@ class ManageTripUseCase( } override suspend fun updateTripStatus(tripId: String) { - tripGateway.updateTrip("0" ,tripId) + tripGateway.updateTrip(tripId) } } \ No newline at end of file From a15ae09552e333a2099aae52a0ab92d242765d7d Mon Sep 17 00:00:00 2001 From: Asia sama Date: Tue, 5 Dec 2023 09:11:38 +0300 Subject: [PATCH 10/15] taxi app | get taxi id and save it locally --- .../module/UserConfigurationCollection.kt | 1 + .../remote/fakegateway/IdentityFakeGateway.kt | 14 +++++--- .../gateway/{ => remote}/TripRemoteGateway.kt | 15 ++++---- .../kotlin/data/remote/mapper/TaxiMapper.kt | 35 +++++++++++++++++++ .../kotlin/data/remote/model/TaxiDto.kt | 19 ++++++++++ .../commonMain/kotlin/domain/entity/Taxi.kt | 15 ++++++++ .../local/ILocalConfigurationGateway.kt | 2 ++ 7 files changed, 87 insertions(+), 14 deletions(-) rename client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/{ => remote}/TripRemoteGateway.kt (81%) create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/TaxiMapper.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiDto.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Taxi.kt diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/local/module/UserConfigurationCollection.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/local/module/UserConfigurationCollection.kt index ffea97821..045c99798 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/local/module/UserConfigurationCollection.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/local/module/UserConfigurationCollection.kt @@ -8,4 +8,5 @@ class UserConfigurationCollection : RealmObject { var refreshToken: String = "" var username: String = "" var isKeepMeLoggedInMeChecked: Boolean = false + var taxiId: String = "" } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/IdentityFakeGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/IdentityFakeGateway.kt index f570cae57..cfe7ae945 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/IdentityFakeGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/IdentityFakeGateway.kt @@ -4,6 +4,8 @@ import domain.InvalidPasswordException import domain.InvalidUserNameException import domain.PermissionDenied import domain.entity.Session +import domain.entity.Taxi +import domain.entity.TaxiRequestPermission import domain.gateway.remote.IIdentityRemoteGateway class IdentityFakeGateway : IIdentityRemoteGateway { @@ -27,11 +29,13 @@ class IdentityFakeGateway : IIdentityRemoteGateway { return Pair("wertqyhgt", "qazswxza") } - override suspend fun createRequestPermission( - driverFullName: String, - driverEmail: String, - description: String - ) { + override suspend fun createRequestPermission(taxiRequestPermission: TaxiRequestPermission): Boolean { + TODO("Not yet implemented") } + override suspend fun getAllVehicles(): List { + TODO("Not yet implemented") + } + + } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/TripRemoteGateway.kt similarity index 81% rename from client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt rename to client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/TripRemoteGateway.kt index aafd40a49..1c071c615 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/TripRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/TripRemoteGateway.kt @@ -1,9 +1,10 @@ -package data.remote.gateway +package data.remote.gateway.remote import data.remote.mapper.toDto import data.remote.mapper.toEntity import data.remote.model.BaseResponse import data.remote.model.LocationDto +import data.remote.model.TaxiTripDto import data.remote.model.TripDto import domain.NotFoundedException import domain.entity.Location @@ -20,8 +21,9 @@ class TripRemoteGateway(client: HttpClient) : ITripRemoteGateway, BaseRemoteGateway(client = client) { override suspend fun getTrips(): Flow { - return client.tryToExecuteWebSocket("/trip/incoming-taxi-rides") + val result= client.tryToExecuteWebSocket("/trip/incoming-taxi-rides") .map { it.toEntity() } + return result } override suspend fun sendLocation(location: Location, tripId: String) { @@ -31,21 +33,16 @@ class TripRemoteGateway(client: HttpClient) : ITripRemoteGateway, ) } - override suspend fun updateTrip(tripId: String) { + override suspend fun updateTrip(tripId: String, taxiId: String) { val result = tryToExecute> { submitForm( url = ("/trip/update/taxi-ride"), formParameters = Parameters.build { append("tripId", tripId) - append("taxiId", TAXI_ID) + append("taxiId", taxiId) }, block = { method = HttpMethod.Put } ) }.value ?: throw NotFoundedException() } - - private companion object{ - const val TAXI_ID = "653d6d4f5a253b12181fa2de" - } - } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/TaxiMapper.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/TaxiMapper.kt new file mode 100644 index 000000000..e944c64b2 --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/TaxiMapper.kt @@ -0,0 +1,35 @@ +package data.remote.mapper + +import data.remote.model.TaxiDto +import domain.entity.Taxi + +fun TaxiDto.toEntity(): Taxi { + return Taxi( + id = id?:"", + plateNumber = plateNumber, + color = color, + type = type, + driverId = driverId?:"", + driverUsername = driverUsername, + driverImage = driverImage?:"", + rate = rate?:0.0, + isAvailable = isAvailable?:false, + seats = seats?:0, + tripsCount = tripsCount?:0, + ) +} +fun Taxi.toDto(): TaxiDto { + return TaxiDto( + id = id, + plateNumber = plateNumber, + color = color, + type = type, + driverId = driverId, + driverUsername = driverUsername, + driverImage = driverImage, + rate = rate, + isAvailable = isAvailable, + seats = seats, + tripsCount = tripsCount, + ) +} \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiDto.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiDto.kt new file mode 100644 index 000000000..b596ad66d --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiDto.kt @@ -0,0 +1,19 @@ +package data.remote.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TaxiDto( + @SerialName("id") val id: String? = null, + @SerialName("plateNumber") val plateNumber: String, + @SerialName("color") val color: Long, + @SerialName("type") val type: String, + @SerialName("driverId") val driverId: String? = null, + @SerialName("driverUsername") val driverUsername: String, + @SerialName("driverImage") val driverImage: String? = null, + @SerialName("rate") val rate: Double? = null, + @SerialName("isAvailable") val isAvailable: Boolean = true, + @SerialName("seats") val seats: Int = 4, + @SerialName("tripsCount") val tripsCount: Int? = 0, +) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Taxi.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Taxi.kt new file mode 100644 index 000000000..480d0631a --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/Taxi.kt @@ -0,0 +1,15 @@ +package domain.entity + +data class Taxi( + val id: String, + val plateNumber: String, + val color: Long, + val type: String, + val driverId: String, + val driverUsername: String, + val driverImage: String, + val rate: Double, + val isAvailable: Boolean, + val seats: Int, + val tripsCount: Int, +) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/local/ILocalConfigurationGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/local/ILocalConfigurationGateway.kt index 127256951..5dc363c38 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/local/ILocalConfigurationGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/local/ILocalConfigurationGateway.kt @@ -10,6 +10,8 @@ interface ILocalConfigurationGateway { suspend fun saveKeepMeLoggedInFlag(isChecked: Boolean) suspend fun getKeepMeLoggedInFlag(): Boolean suspend fun clearTokens() + suspend fun saveTaxiId(taxiId: String) + suspend fun getTaxiId(): String suspend fun saveUserName(username: String) suspend fun getUsername(): String From bbcba994dea3f8bede8b94c74663a9d915d38697 Mon Sep 17 00:00:00 2001 From: Asia sama Date: Tue, 5 Dec 2023 09:16:37 +0300 Subject: [PATCH 11/15] taxi app | fix create taxi request permeation --- .../{ => remote}/IdentityRemoteGateway.kt | 28 +++++++++++++++---- .../remote/mapper/RequestPermissionMapper.kt | 17 +++++++++++ .../remote/model/TaxiRequestPermissionDto.kt | 12 ++++++++ .../domain/entity/TaxiRequestPermission.kt | 7 +++++ .../gateway/remote/IIdentityRemoteGateway.kt | 9 +++--- .../kotlin/domain/usecase/LoginUserUseCase.kt | 27 +++++++++--------- .../presentation/login/LoginScreenModel.kt | 10 ++----- .../presentation/resources/StringResources.kt | 3 +- 8 files changed, 80 insertions(+), 33 deletions(-) rename client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/{ => remote}/IdentityRemoteGateway.kt (65%) create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/RequestPermissionMapper.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiRequestPermissionDto.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/TaxiRequestPermission.kt diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/IdentityRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/IdentityRemoteGateway.kt similarity index 65% rename from client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/IdentityRemoteGateway.kt rename to client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/IdentityRemoteGateway.kt index 1929dafaa..09169d5f5 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/IdentityRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/IdentityRemoteGateway.kt @@ -1,14 +1,21 @@ -package data.remote.gateway +package data.remote.gateway.remote +import data.remote.mapper.toDto import data.remote.mapper.toEntity import data.remote.model.BaseResponse import data.remote.model.SessionDto +import data.remote.model.TaxiDto +import domain.entity.TaxiRequestPermission import data.remote.model.UserTokensDto import domain.InvalidCredentialsException import domain.entity.Session +import domain.entity.Taxi import domain.gateway.remote.IIdentityRemoteGateway import io.ktor.client.HttpClient import io.ktor.client.request.forms.submitForm +import io.ktor.client.request.get +import io.ktor.client.request.post +import io.ktor.client.request.setBody import io.ktor.client.request.url import io.ktor.http.Parameters @@ -44,10 +51,19 @@ class IdentityRemoteGateway(client: HttpClient) : IIdentityRemoteGateway, } override suspend fun createRequestPermission( - driverFullName: String, - driverEmail: String, - description: String, - ) { - // TODO: add create request permission end point when backend is done + taxiRequestPermission: TaxiRequestPermission + ): Boolean { + val result = tryToExecute> { + post("/restaurant-permission-request") { + setBody(taxiRequestPermission.toDto()) + } + }.value ?: throw Exception() + + return result + } + override suspend fun getAllVehicles(): List { + return tryToExecute>> { + get("taxis/belongs-to-delivery-driver") + }.value?.map { it.toEntity() } ?: throw Exception() } } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/RequestPermissionMapper.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/RequestPermissionMapper.kt new file mode 100644 index 000000000..7858f8e8a --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/RequestPermissionMapper.kt @@ -0,0 +1,17 @@ +package data.remote.mapper + +import data.remote.model.TaxiRequestPermissionDto +import domain.entity.TaxiRequestPermission + + +fun TaxiRequestPermission.toDto() = TaxiRequestPermissionDto( + driverFullName = driverFullName, + driverEmail = driverEmail, + description = description, +) + +fun TaxiRequestPermissionDto.toEntity() = TaxiRequestPermission( + driverFullName = driverFullName, + driverEmail = driverEmail, + description = description, +) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiRequestPermissionDto.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiRequestPermissionDto.kt new file mode 100644 index 000000000..f42e1e214 --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiRequestPermissionDto.kt @@ -0,0 +1,12 @@ +package data.remote.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +@Serializable +data class TaxiRequestPermissionDto( + @SerialName("restaurantName") val driverFullName: String, + @SerialName("ownerEmail") val driverEmail: String, + @SerialName("cause") val description: String +) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/TaxiRequestPermission.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/TaxiRequestPermission.kt new file mode 100644 index 000000000..95139dc85 --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/entity/TaxiRequestPermission.kt @@ -0,0 +1,7 @@ +package domain.entity + +data class TaxiRequestPermission( + val driverFullName: String, + val driverEmail: String, + val description: String, +) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/IIdentityRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/IIdentityRemoteGateway.kt index d1e7d9970..c67b488d4 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/IIdentityRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/IIdentityRemoteGateway.kt @@ -1,6 +1,8 @@ package domain.gateway.remote +import domain.entity.TaxiRequestPermission import domain.entity.Session +import domain.entity.Taxi interface IIdentityRemoteGateway { @@ -10,10 +12,7 @@ interface IIdentityRemoteGateway { // the pair this fun return is suspend fun refreshAccessToken(refreshToken: String): Pair - suspend fun createRequestPermission( - driverFullName: String, - driverEmail: String, - description: String, - ) + suspend fun createRequestPermission(taxiRequestPermission: TaxiRequestPermission): Boolean + suspend fun getAllVehicles(): List } diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/LoginUserUseCase.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/LoginUserUseCase.kt index d07c33123..daddab6df 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/LoginUserUseCase.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/LoginUserUseCase.kt @@ -4,6 +4,7 @@ import domain.InvalidDriverEmailException import domain.InvalidDriverNameException import domain.InvalidPasswordException import domain.InvalidUserNameException +import domain.entity.TaxiRequestPermission import domain.gateway.local.ILocalConfigurationGateway import domain.gateway.remote.IIdentityRemoteGateway @@ -17,13 +18,10 @@ interface ILoginUserUseCase { suspend fun saveUsername(username: String) suspend fun getUsername(): String + suspend fun getKeepMeLoggedInFlag(): Boolean - suspend fun requestPermission( - driverFullName: String, - driverEmail: String, - description: String, - ) + suspend fun requestPermission(taxiRequestPermission: TaxiRequestPermission): Boolean } class LoginUserUseCase( @@ -41,6 +39,7 @@ class LoginUserUseCase( localGateWay.saveAccessToken(userTokens.accessToken) localGateWay.saveRefreshToken(userTokens.refreshToken) localGateWay.saveKeepMeLoggedInFlag(isKeepMeLoggedInChecked) + localGateWay.saveTaxiId(getTaxiId()) } override suspend fun saveUsername(username: String) { @@ -51,20 +50,20 @@ class LoginUserUseCase( return localGateWay.getUsername() } + override suspend fun getKeepMeLoggedInFlag(): Boolean { return localGateWay.getKeepMeLoggedInFlag() } - override suspend fun requestPermission( - driverFullName: String, driverEmail: String, description: String, - ) { - checkValidationPermissionFields(driverFullName, driverEmail) - - remoteGateway.createRequestPermission( - driverFullName, - driverEmail, - description + override suspend fun requestPermission(taxiRequestPermission: TaxiRequestPermission): Boolean { + checkValidationPermissionFields( + taxiRequestPermission.driverFullName, + taxiRequestPermission.driverEmail ) + return remoteGateway.createRequestPermission(taxiRequestPermission) + } + private suspend fun getTaxiId(): String { + return remoteGateway.getAllVehicles().first().id } diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/login/LoginScreenModel.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/login/LoginScreenModel.kt index 236476c78..da936551a 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/login/LoginScreenModel.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/login/LoginScreenModel.kt @@ -1,6 +1,7 @@ package presentation.login import cafe.adriel.voyager.core.model.coroutineScope +import domain.entity.TaxiRequestPermission import domain.usecase.ILoginUserUseCase import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -157,14 +158,9 @@ class LoginScreenModel(private val loginUserUseCase: ILoginUserUseCase) : driverEmail: String, description: String ) { + val requestPermission = TaxiRequestPermission(driverFullName, driverEmail, description) tryToExecute( - { - loginUserUseCase.requestPermission( - driverFullName, - driverEmail, - description - ) - }, + { loginUserUseCase.requestPermission(requestPermission) }, { onAskForPermissionSuccess() }, ::onLoginFailed ) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/resources/StringResources.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/resources/StringResources.kt index bfe7c192c..57b2216ef 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/resources/StringResources.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/resources/StringResources.kt @@ -31,4 +31,5 @@ data class StringResources( val pickUp: String = "Pick up", val dropOff: String = "Drop off", val close: String = "Close", -) + val accessDeniedMessage: String = "To continue, Please access location permission", + ) From dc934a26bd81429ff1c4f1c8802aedb115831368 Mon Sep 17 00:00:00 2001 From: Asia sama Date: Tue, 5 Dec 2023 09:17:58 +0300 Subject: [PATCH 12/15] taxi app | save taxi id locally --- .../data/local/gateway/LocalConfigurationGateway.kt | 11 +++++++++++ .../domain/gateway/remote/ITripRemoteGateway.kt | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/local/gateway/LocalConfigurationGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/local/gateway/LocalConfigurationGateway.kt index 8ddd3f5da..35f0bcd74 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/local/gateway/LocalConfigurationGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/local/gateway/LocalConfigurationGateway.kt @@ -51,6 +51,17 @@ class LocalConfigurationGateway(private val realm: Realm) : ILocalConfigurationG override suspend fun clearTokens() { realm.write { delete(query()) } } + override suspend fun saveTaxiId(taxiId: String) { + realm.write { + query("$ID == $CONFIGURATION_ID").first() + .find()?.taxiId = taxiId + } + } + + override suspend fun getTaxiId(): String { + return realm.query("$ID == $CONFIGURATION_ID").first() + .find()?.taxiId ?: "" + } override suspend fun saveKeepMeLoggedInFlag(isChecked: Boolean) { realm.write { diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt index 1668cd1c2..bc848f620 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/remote/ITripRemoteGateway.kt @@ -8,5 +8,5 @@ import kotlinx.coroutines.flow.Flow interface ITripRemoteGateway { suspend fun getTrips(): Flow suspend fun sendLocation(location: Location, tripId: String) - suspend fun updateTrip(tripId: String) + suspend fun updateTrip(tripId: String,taxiId: String) } \ No newline at end of file From c9b4c00e7cba0b39b8e372550eb1e42679d659ee Mon Sep 17 00:00:00 2001 From: Asia sama Date: Tue, 5 Dec 2023 09:22:51 +0300 Subject: [PATCH 13/15] taxi app | fix socket implementation --- .../remote/fakegateway/OrderFakeGateway.kt | 6 +-- .../{ => remote}/AuthorizationInterceptor.kt | 2 +- .../gateway/{ => remote}/BaseRemoteGateway.kt | 17 +++++++-- .../kotlin/data/remote/mapper/MapMapper.kt | 12 +++--- .../kotlin/data/remote/model/TaxiTripDto.kt | 15 ++++++++ .../kotlin/data/remote/model/TripDto.kt | 38 ++++++++++--------- .../src/commonMain/kotlin/di/NetworkModule.kt | 27 +++++++++++-- .../src/commonMain/kotlin/domain/ErrorType.kt | 3 +- .../domain/usecase/ManageTripUseCase.kt | 18 ++++++--- .../presentation/base/BaseScreenModel.kt | 28 +++----------- .../kotlin/presentation/base/ErrorState.kt | 1 + .../kotlin/presentation/map/MapMapper.kt | 8 ++-- .../kotlin/presentation/map/MapScreen.kt | 11 ++---- .../kotlin/presentation/map/MapScreenModel.kt | 18 ++++++--- 14 files changed, 124 insertions(+), 80 deletions(-) rename client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/{ => remote}/AuthorizationInterceptor.kt (97%) rename client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/{ => remote}/BaseRemoteGateway.kt (80%) create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiTripDto.kt diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt index fae568652..b052259bf 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/OrderFakeGateway.kt @@ -2,7 +2,7 @@ package data.remote.fakegateway import data.remote.mapper.toEntity import data.remote.model.LocationDto -import data.remote.model.TripDto +import data.remote.model.TaxiTripDto import domain.entity.Trip import domain.gateway.IOrderGateway import kotlinx.coroutines.delay @@ -10,7 +10,7 @@ import kotlinx.coroutines.delay class OrderFakeGateway : IOrderGateway { override suspend fun findingNewOrder(): Trip { delay(4000) - return TripDto( + return TaxiTripDto( id = "djsahdjadhjadjas45dsadas", clientName = "Cristiano Ronaldo", startPoint = LocationDto( @@ -24,7 +24,7 @@ class OrderFakeGateway : IOrderGateway { startPointAddress = "ooveofe", destinationAddress = "h9viife", price = 100.0, - tripStatus = 1 + tripStatus = 1, ).toEntity() } } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/AuthorizationInterceptor.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/AuthorizationInterceptor.kt similarity index 97% rename from client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/AuthorizationInterceptor.kt rename to client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/AuthorizationInterceptor.kt index 1fbc64cae..b70a45b00 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/AuthorizationInterceptor.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/AuthorizationInterceptor.kt @@ -1,4 +1,4 @@ -package data.remote.gateway +package data.remote.gateway.remote import data.local.gateway.LocalConfigurationGateway import io.ktor.client.HttpClient diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/BaseRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/BaseRemoteGateway.kt similarity index 80% rename from client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/BaseRemoteGateway.kt rename to client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/BaseRemoteGateway.kt index d6c4e48ed..52cb4ffe0 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/BaseRemoteGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/remote/BaseRemoteGateway.kt @@ -1,10 +1,12 @@ -package data.remote.gateway +package data.remote.gateway.remote import data.remote.model.BaseResponse +import domain.AlreadyExistException import domain.InvalidPasswordException import domain.InvalidUserNameException import domain.NoInternetException import domain.SocketException +import domain.UnAuthorizedException import domain.UnknownErrorException import io.ktor.client.HttpClient import io.ktor.client.call.body @@ -24,17 +26,18 @@ import kotlinx.coroutines.flow.flowOn abstract class BaseRemoteGateway(val client: HttpClient) { protected suspend inline fun tryToExecute( - method: HttpClient.() -> HttpResponse + method: HttpClient.() -> HttpResponse, ): T { try { return client.method().body() } catch (e: ClientRequestException) { - val errorMessages = e.response.body>().status?.errorMessages + val errorMessages = e.response.body>().status?.errorMessages errorMessages?.let { throwMatchingException(it) } throw UnknownErrorException(e.message) } catch (e: UnresolvedAddressException) { throw NoInternetException() } catch (e: Exception) { + println("exception: $e") throw UnknownErrorException(e.message.toString()) } } @@ -71,11 +74,15 @@ abstract class BaseRemoteGateway(val client: HttpClient) { errorMessages.containsErrors(USER_NOT_EXIST) -> throw InvalidUserNameException(errorMessages.getOrEmpty(USER_NOT_EXIST)) + errorMessages.containsErrors(ALREADY_EXIST) -> + throw AlreadyExistException(errorMessages.getOrEmpty(ALREADY_EXIST)) - else -> throw UnknownErrorException("UnKnow Error") + errorMessages.containsErrors(INVALID_PERMISSION) -> + throw UnAuthorizedException(errorMessages.getOrEmpty(INVALID_PERMISSION)) } } + private fun Map.containsErrors(vararg errorCodes: String): Boolean = keys.containsAll(errorCodes.toList()) @@ -84,5 +91,7 @@ abstract class BaseRemoteGateway(val client: HttpClient) { companion object { const val WRONG_PASSWORD = "1013" const val USER_NOT_EXIST = "1043" + const val INVALID_PERMISSION = "1014" + const val ALREADY_EXIST = "3010" } } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt index ab25b07ab..4c773c21b 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/mapper/MapMapper.kt @@ -1,17 +1,17 @@ package data.remote.mapper import data.remote.model.LocationDto -import data.remote.model.TripDto +import data.remote.model.TaxiTripDto import domain.entity.Location import domain.entity.Trip -fun TripDto.toEntity(): Trip = Trip( +fun TaxiTripDto.toEntity(): Trip = Trip( id = id ?: "", passengerName = this.clientName ?: "", - dropOffLocation = this.destination.toEntity(), - pickUpLocation = this.startPoint.toEntity(), - pickUpAddress = this.startPointAddress, - dropOffAddress = this.destinationAddress + dropOffLocation = this.destination?.toEntity()?: Location(0.0, 0.0), + pickUpLocation = this.startPoint?.toEntity()?: Location(0.0, 0.0), + pickUpAddress = this.startPointAddress?:"", + dropOffAddress = this.destinationAddress?:"", ) fun LocationDto.toEntity(): Location = Location( diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiTripDto.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiTripDto.kt new file mode 100644 index 000000000..8d015534a --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TaxiTripDto.kt @@ -0,0 +1,15 @@ +package data.remote.model + +import kotlinx.serialization.Serializable + +@Serializable +data class TaxiTripDto( + val id: String, + val clientName: String, + val startPoint: LocationDto, + val destination: LocationDto, + val startPointAddress: String, + val destinationAddress: String, + val price: Double, + val tripStatus: Int +) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt index 387f163ee..28080da77 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/model/TripDto.kt @@ -1,24 +1,26 @@ package data.remote.model -import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class TripDto( - @SerialName("id") - val id: String, - @SerialName("clientName") - val clientName: String, - @SerialName("startPoint") - val startPoint: LocationDto, - @SerialName("destination") - val destination: LocationDto, - @SerialName("startPointAddress") - val startPointAddress: String, - @SerialName("destinationAddress") - val destinationAddress: String, - @SerialName("price") - val price: Double, - @SerialName("tripStatus") - val tripStatus: Int -) + val id: String? = null, + val taxiId: String? = null, + val driverId: String? = null, + val clientId: String? = null, + val orderId: String? = null, + val restaurantId: String? = null, + val taxiPlateNumber: String? = null, + val taxiDriverName: String? = null, + val taxiColor: Long? = null, + val startPoint: LocationDto? = null, + val destination: LocationDto? = null, + val startPointAddress: String? = null, + val destinationAddress: String? = null, + val rate: Double? = null, + val price: Double? = null, + val startDate: String? = null, + val endDate: String? = null, + val isATaxiTrip: Boolean? = null, + val tripStatus: Int = 0 +) \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/di/NetworkModule.kt b/client_taxi_driver/shared/src/commonMain/kotlin/di/NetworkModule.kt index cd8d98eef..0b381c3a2 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/di/NetworkModule.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/di/NetworkModule.kt @@ -1,15 +1,19 @@ package di -import data.remote.gateway.intercept +import data.remote.gateway.remote.intercept import io.ktor.client.HttpClient -import io.ktor.client.engine.cio.CIO import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.defaultRequest import io.ktor.client.plugins.logging.DEFAULT import io.ktor.client.plugins.logging.LogLevel import io.ktor.client.plugins.logging.Logger import io.ktor.client.plugins.logging.Logging +import io.ktor.client.plugins.websocket.WebSockets import io.ktor.client.request.header +import io.ktor.http.URLBuilder +import io.ktor.http.URLProtocol +import io.ktor.http.Url +import io.ktor.serialization.kotlinx.KotlinxWebsocketSerializationConverter import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json import org.koin.dsl.module @@ -23,6 +27,11 @@ val NetworkModule = module { install(Logging) { logger = Logger.DEFAULT level = LogLevel.ALL + logger = object : Logger { + override fun log(message: String) { + println("HTTP Client: $message") + } + } } defaultRequest { @@ -30,7 +39,17 @@ val NetworkModule = module { header("Accept-Language", "en") url(BASEURL) } - + install(WebSockets) { + contentConverter = KotlinxWebsocketSerializationConverter(Json) + val urlBuilder = URLBuilder( + protocol = URLProtocol.WSS, + host = "beep-beep-api-gateway-nap2u.ondigitalocean.app/", +// Local host = "192.168.1.100", +// Local port = 8080 + ) + Url(urlBuilder) + pingInterval = 10000 + } install(ContentNegotiation) { json( Json { @@ -45,4 +64,4 @@ val NetworkModule = module { client } } -private const val BASEURL = "https://beep-beep-api-gateway-nap2u.ondigitalocean.app" +private const val BASEURL = "https://beep-beep-api-gateway-nap2u.ondigitalocean.app/" diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt index dc0dfc2e7..365a430f5 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/ErrorType.kt @@ -9,7 +9,7 @@ class NoInternetException : InternetException("No internet connection") //region authorization open class AuthorizationException(message: String) : BpException(message) -class UnAuthorizedException : AuthorizationException("You have to login") +class UnAuthorizedException(message: String) : AuthorizationException(message) class PermissionDenied : AuthorizationException("You have to allow permission") //endregion @@ -26,6 +26,7 @@ class UnknownErrorException(message: String) : BpException(message) class InvalidCredentialsException(message: String) : BpException(message) class InvalidUserNameException(private val errorMessage: String) : BpException(errorMessage) +class AlreadyExistException(private val errorMessage: String) : BpException(errorMessage) class InvalidPasswordException(private val errorMessage: String) : BpException(errorMessage) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt index b49687d18..3bb46b15f 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageTripUseCase.kt @@ -2,27 +2,35 @@ package domain.usecase import domain.entity.Location import domain.entity.Trip +import domain.gateway.local.ILocalConfigurationGateway import domain.gateway.remote.ITripRemoteGateway -import kotlinx.coroutines.flow.last +import kotlinx.coroutines.flow.Flow interface IManageTripUseCase { - suspend fun findNewTrip(): Trip + suspend fun findNewTrip(): Flow suspend fun updateTripLocation(location: Location, tripId: String) suspend fun updateTripStatus(tripId: String) + suspend fun getTaxiId(): String } class ManageTripUseCase( private val tripGateway: ITripRemoteGateway, + private val localGateWay: ILocalConfigurationGateway ) : IManageTripUseCase { - override suspend fun findNewTrip(): Trip { - return tripGateway.getTrips().last() + override suspend fun findNewTrip(): Flow { + return tripGateway.getTrips() } override suspend fun updateTripLocation(location: Location, tripId: String) { tripGateway.sendLocation(location = location, tripId = tripId) } override suspend fun updateTripStatus(tripId: String) { - tripGateway.updateTrip(tripId) + val taxiId = localGateWay.getTaxiId() + tripGateway.updateTrip(tripId,taxiId) + } + + override suspend fun getTaxiId(): String { + TODO("Not yet implemented") } } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/BaseScreenModel.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/BaseScreenModel.kt index bd555ca3d..e174627f1 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/BaseScreenModel.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/BaseScreenModel.kt @@ -2,6 +2,7 @@ package presentation.base import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.coroutineScope +import domain.AlreadyExistException import domain.InvalidCredentialsException import domain.InvalidDriverEmailException import domain.InvalidDriverNameException @@ -93,31 +94,14 @@ abstract class BaseScreenModel(initialState: S) : ScreenModel, KoinCompone is ServerSideException -> onError(ErrorState.ServerError) is UnAuthorizedException -> onError(ErrorState.UnAuthorized) is NotFoundedException -> onError(ErrorState.NotFound(exception.message.toString())) - is UnknownErrorException -> onError( - ErrorState.UnknownError( - exception.message.toString() - ) - ) - - is InvalidCredentialsException -> onError( - ErrorState.InvalidCredentials( - exception.message.toString() - ) - ) - + is UnknownErrorException -> onError(ErrorState.UnknownError(exception.message.toString())) + is InvalidCredentialsException -> onError(ErrorState.InvalidCredentials(exception.message.toString())) is InvalidUserNameException -> onError(ErrorState.InvalidUserName(exception.message.toString())) is InvalidPasswordException -> onError(ErrorState.InvalidPassword(exception.message.toString())) is InvalidDriverNameException -> onError(ErrorState.InvalidDriverName(exception.message.toString())) - is InvalidDriverEmailException -> onError( - ErrorState.InvalidDriverEmail( - exception.message.toString() - ) - ) - - is LocationPermissionDeniedAlwaysException -> onError( - ErrorState.LocationPermissionDenied(message = exception.message.toString()) - ) - + is InvalidDriverEmailException -> onError(ErrorState.InvalidDriverEmail(exception.message.toString())) + is LocationPermissionDeniedAlwaysException -> onError(ErrorState.LocationPermissionDenied(message = exception.message.toString())) + is AlreadyExistException -> onError(ErrorState.AlreadyExist(message = exception.message.toString())) is LocationPermissionDeniedException -> onError( ErrorState.LocationPermissionDenied(message = exception.message.toString()) ) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/ErrorState.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/ErrorState.kt index a6781ed30..2a71517d4 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/ErrorState.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/base/ErrorState.kt @@ -9,6 +9,7 @@ sealed interface ErrorState { data class UnknownError(val errorMessage: String) : ErrorState data class NotFound(val errorMessage: String) : ErrorState data class LocationPermissionDenied(val message: String) : ErrorState + data class AlreadyExist(val message: String) : ErrorState data class InvalidUserName(val errorMessage: String) : ErrorState data class InvalidPassword(val errorMessage: String) : ErrorState data class InvalidDriverName(val errorMessage: String) : ErrorState diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt index 69f660df5..f85dd7dcc 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapMapper.kt @@ -6,10 +6,10 @@ import domain.entity.Trip fun Trip.toUiState() = TripInfoUiState( id = this.id, passengerName = passengerName, - dropOffLocation = this.dropOffLocation.toUiState(), - pickUpLocation = this.pickUpLocation.toUiState(), - dropOffAddress = this.dropOffAddress, - pickUpAddress = this.pickUpAddress + dropOffLocation = dropOffLocation.toUiState(), + pickUpLocation = pickUpLocation.toUiState(), + dropOffAddress = dropOffAddress, + pickUpAddress = pickUpAddress ) fun Location.toUiState() = LocationInfoUiState( diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt index a4157aa90..1818ea742 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreen.kt @@ -83,19 +83,16 @@ class MapScreen : } MapCardAnimation( modifier = Modifier.align(Alignment.BottomCenter), - visible = !state.isLoading, - ) { - FindingRideCard() - } + visible = !state.isNewOrderFound && !state.isAcceptedOrder, + content = { FindingRideCard() } + ) MapCardAnimation( modifier = Modifier.align(Alignment.BottomCenter), visible = state.isNewOrderFound, ) { NewOrderCard( - modifier = Modifier.align( - Alignment.BottomCenter, - ), + modifier = Modifier.align(Alignment.BottomCenter,), state = state.tripInfoUiState, listener = listener, ) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt index a45d98702..7cfc999bc 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt @@ -26,9 +26,10 @@ class MapScreenModel( } private fun findingNewOrder() { - tryToExecute( + println("findingNewOrder") + tryToCollect( function = manageTrip::findNewTrip, - onSuccess = ::onFoundNewOrderSuccess, + onNewValue= ::onFoundNewOrderSuccess, onError = ::onError ) } @@ -42,6 +43,7 @@ class MapScreenModel( ) } } + println("getUserName: ${state.value.driverName}") } private fun onFoundNewOrderSuccess(order: Trip) { @@ -56,6 +58,7 @@ class MapScreenModel( } private fun onError(errorState: ErrorState) { + println("onError: $errorState") updateState { it.copy( isLoading = false, @@ -150,10 +153,15 @@ class MapScreenModel( error = null, tripInfoUiState = TripInfoUiState() ).also { - coroutineScope.launch(Dispatchers.IO) { - manageTrip.updateTripStatus(it.tripInfoUiState.id) + try { + coroutineScope.launch(Dispatchers.IO) { + manageTrip.updateTripStatus(it.tripInfoUiState.id) + } + // findingNewOrder() + }catch (e: Exception) { + onError(ErrorState.UnknownError(e.message ?: "Unknown Error")) } - findingNewOrder() + } } } From dabc33ba730fdc64669ce8bd109787d0fd20aca9 Mon Sep 17 00:00:00 2001 From: Asia sama Date: Tue, 5 Dec 2023 09:24:43 +0300 Subject: [PATCH 14/15] taxi app | fix get location and tracking on it --- .../remote/fakegateway/LocationFakeGateway.kt | 8 ++++ .../remote/gateway/LocationRemoteGateway.kt | 12 ------ .../gateway/local/LocationRemoteGateway.kt | 37 ++++++++++++++++++ .../src/commonMain/kotlin/di/GatewayModule.kt | 6 +-- .../kotlin/domain/gateway/ILocationGateway.kt | 2 + .../domain/usecase/ManageLocationUseCase.kt | 12 +++++- .../kotlin/presentation/main/MainScreen.kt | 19 ++++++++- .../main/MainScreenInteractionListener.kt | 2 +- .../presentation/main/MainScreenModel.kt | 39 +++++++++++++++++-- .../presentation/main/MainScreenUiState.kt | 4 +- .../kotlin/presentation/main/MainUiEffect.kt | 2 +- 11 files changed, 118 insertions(+), 25 deletions(-) delete mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/LocationRemoteGateway.kt create mode 100644 client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/local/LocationRemoteGateway.kt diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt index f386a0c93..c3d60ae57 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/fakegateway/LocationFakeGateway.kt @@ -7,6 +7,10 @@ import kotlinx.coroutines.flow.flow class LocationFakeGateway : ILocationGateway { + override suspend fun startTracking() { + TODO("Not yet implemented") + } + override suspend fun trackCurrentLocation() = flow { var lattiude = 30.044420 while (true) { @@ -20,4 +24,8 @@ class LocationFakeGateway : ILocationGateway { delay(2000) } } + + override suspend fun stopTracking() { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/LocationRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/LocationRemoteGateway.kt deleted file mode 100644 index d314084f6..000000000 --- a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/LocationRemoteGateway.kt +++ /dev/null @@ -1,12 +0,0 @@ -package data.remote.gateway - -import domain.dataSource.IBpLocationDataSource -import domain.gateway.ILocationGateway -import kotlinx.coroutines.flow.distinctUntilChanged - -class LocationRemoteGateway( - private val bpLocation: IBpLocationDataSource, -) : ILocationGateway { - override suspend fun trackCurrentLocation() = - bpLocation.getCurrentLocation().distinctUntilChanged() -} \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/local/LocationRemoteGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/local/LocationRemoteGateway.kt new file mode 100644 index 000000000..f9ca94315 --- /dev/null +++ b/client_taxi_driver/shared/src/commonMain/kotlin/data/remote/gateway/local/LocationRemoteGateway.kt @@ -0,0 +1,37 @@ +package data.remote.gateway.local + +import data.service.ILocationService +import dev.icerock.moko.geo.LocationTracker +import dev.icerock.moko.permissions.DeniedAlwaysException +import domain.LocationPermissionDeniedException +import domain.entity.Location +import domain.gateway.ILocationGateway +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class LocationRemoteGateway( + private val locationService: ILocationService, + private val locationTracker: LocationTracker +) : ILocationGateway { + +override suspend fun startTracking() { + try { + locationTracker.startTracking() + if (!locationService.isGPSEnabled()) { + locationService.openLocationSettings() + } + } catch (e: DeniedAlwaysException) { + throw LocationPermissionDeniedException(e.message) + } +} + + override suspend fun trackCurrentLocation(): Flow { + return locationTracker.getLocationsFlow().map { + Location(it.latitude, it.longitude) + } + } + + override suspend fun stopTracking() { + locationTracker.stopTracking() + } +} \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt b/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt index 6d04835a5..581735525 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/di/GatewayModule.kt @@ -2,9 +2,9 @@ package di import data.local.gateway.LocalConfigurationGateway import data.remote.fakegateway.OrderFakeGateway -import data.remote.gateway.IdentityRemoteGateway -import data.remote.gateway.LocationRemoteGateway -import data.remote.gateway.TripRemoteGateway +import data.remote.gateway.remote.IdentityRemoteGateway +import data.remote.gateway.local.LocationRemoteGateway +import data.remote.gateway.remote.TripRemoteGateway import domain.gateway.ILocationGateway import domain.gateway.IOrderGateway import domain.gateway.local.ILocalConfigurationGateway diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/ILocationGateway.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/ILocationGateway.kt index 58742e648..9133ee39f 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/ILocationGateway.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/gateway/ILocationGateway.kt @@ -4,5 +4,7 @@ import domain.entity.Location import kotlinx.coroutines.flow.Flow interface ILocationGateway { + suspend fun startTracking() suspend fun trackCurrentLocation(): Flow + suspend fun stopTracking() } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageLocationUseCase.kt b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageLocationUseCase.kt index 8a67dbee1..8ab64c3e2 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageLocationUseCase.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/domain/usecase/ManageLocationUseCase.kt @@ -1,18 +1,28 @@ package domain.usecase -import data.remote.gateway.LocationRemoteGateway +import data.remote.gateway.local.LocationRemoteGateway import domain.entity.Location import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged interface IManageLocationUseCase { + suspend fun startTracking() suspend fun trackCurrentLocation(): Flow + suspend fun stopTracking() } class ManageLocationUseCase( private val locationGateway: LocationRemoteGateway, ) : IManageLocationUseCase { + + override suspend fun startTracking() { + locationGateway.startTracking() + } + + override suspend fun stopTracking() { + locationGateway.stopTracking() + } override suspend fun trackCurrentLocation() = locationGateway.trackCurrentLocation().distinctUntilChanged() } \ No newline at end of file diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreen.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreen.kt index 7f985d8a3..a1c9019fc 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreen.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreen.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import cafe.adriel.voyager.navigator.Navigator +import com.beepbeep.designSystem.ui.composable.BPSnackBar import com.beepbeep.designSystem.ui.composable.BpButton import com.beepbeep.designSystem.ui.theme.Theme import org.jetbrains.compose.resources.ExperimentalResourceApi @@ -23,6 +24,7 @@ import org.jetbrains.compose.resources.painterResource import presentation.base.BaseScreen import presentation.map.MapScreen import presentation.resources.Resources +import util.getNavigationBarPadding class MainScreen : BaseScreen() { @@ -73,17 +75,30 @@ class MainScreen : BpButton( title = Resources.strings.start, - onClick = listener::onCLickStart, + onClick = listener::onClickStart, modifier = Modifier.fillMaxWidth().padding(top = 24.dp, bottom = 22.dp) ) } } + BPSnackBar( + icon = painterResource(Resources.images.errorIcon), + iconBackgroundColor = Theme.colors.warningContainer, + iconTint = Theme.colors.warning, + isVisible = state.showSnackBar, + modifier = Modifier.padding(bottom = getNavigationBarPadding().calculateBottomPadding()) + .align(Alignment.BottomCenter) + ) { + Text( + text = Resources.strings.accessDeniedMessage, + style = Theme.typography.body.copy(color = Theme.colors.contentPrimary), + ) + } } } override fun onEffect(effect: MainUiEffect, navigator: Navigator) { when(effect){ - MainUiEffect.MainEffect -> navigator.push(MapScreen()) + MainUiEffect.Start -> navigator.push(MapScreen()) } } diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenInteractionListener.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenInteractionListener.kt index 1a6c2104c..4bda143cf 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenInteractionListener.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenInteractionListener.kt @@ -3,5 +3,5 @@ package presentation.main import presentation.base.BaseInteractionListener interface MainScreenInteractionListener : BaseInteractionListener { - fun onCLickStart() + fun onClickStart() } diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenModel.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenModel.kt index a63cb97b2..efa54278c 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenModel.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenModel.kt @@ -1,11 +1,42 @@ package presentation.main +import cafe.adriel.voyager.core.model.coroutineScope +import domain.usecase.IManageLocationUseCase +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import presentation.base.BaseScreenModel +import presentation.base.ErrorState -class MainScreenModel: - BaseScreenModel(MainScreenUiState()), +class MainScreenModel( + private val location: IManageLocationUseCase, +): BaseScreenModel(MainScreenUiState()), MainScreenInteractionListener { - override fun onCLickStart() { - sendNewEffect(MainUiEffect.MainEffect) + + override fun onClickStart() { + tryToExecute( + function = location::startTracking, + onSuccess = { onSuccess() }, + onError = ::onError + ) + } + + private fun onSuccess() { + sendNewEffect(MainUiEffect.Start) + } + + private fun onError(error: ErrorState) { + when (error) { + ErrorState.LocationPermissionDenied("LocationPermissionDenied") -> showSnackBar() + else -> {} + } + } + private fun showSnackBar() { + coroutineScope.launch { + updateState { it.copy(showSnackBar = true) } + delay(4000) + updateState { it.copy(showSnackBar = false) } + } + } + } diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenUiState.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenUiState.kt index 16a3ae67d..bdebbab7f 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenUiState.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainScreenUiState.kt @@ -1,5 +1,7 @@ package presentation.main data class MainScreenUiState( - val test: String = "" + val test: String = "", + val showSnackBar: Boolean = false, + val snackBarMessage: String = "" ) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainUiEffect.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainUiEffect.kt index 0b21e6af3..2b05abd29 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainUiEffect.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/main/MainUiEffect.kt @@ -1,5 +1,5 @@ package presentation.main sealed interface MainUiEffect { - data object MainEffect : MainUiEffect + data object Start : MainUiEffect } From 28f586f44b139766e9fd20727fc2e8800404488f Mon Sep 17 00:00:00 2001 From: Asia sama Date: Tue, 5 Dec 2023 11:03:27 +0300 Subject: [PATCH 15/15] taxi app | fix update taxi trip --- .../kotlin/presentation/map/MapScreenModel.kt | 70 ++++++++----------- 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt index 7cfc999bc..35923dac7 100644 --- a/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt +++ b/client_taxi_driver/shared/src/commonMain/kotlin/presentation/map/MapScreenModel.kt @@ -6,8 +6,6 @@ import domain.entity.Trip import domain.usecase.IManageLocationUseCase import domain.usecase.IManageTripUseCase import domain.usecase.LoginUserUseCase -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO import kotlinx.coroutines.launch import presentation.base.BaseScreenModel import presentation.base.ErrorState @@ -29,7 +27,7 @@ class MapScreenModel( println("findingNewOrder") tryToCollect( function = manageTrip::findNewTrip, - onNewValue= ::onFoundNewOrderSuccess, + onNewValue = ::onFoundNewOrderSuccess, onError = ::onError ) } @@ -47,6 +45,8 @@ class MapScreenModel( } private fun onFoundNewOrderSuccess(order: Trip) { + println("onFoundNewOrderSuccess: $order") + println("state.value.tripInfoUiState:${state.value.tripInfoUiState}") updateState { it.copy( isLoading = false, @@ -58,7 +58,7 @@ class MapScreenModel( } private fun onError(errorState: ErrorState) { - println("onError: $errorState") + println("onEeeeeeeeeeeerror: $errorState") updateState { it.copy( isLoading = false, @@ -96,7 +96,7 @@ class MapScreenModel( private fun sendLocationIfTripAccepted(location: Location, tripId: String) { tryToExecute( function = { manageTrip.updateTripLocation(location, tripId) }, - onSuccess = {}, + onSuccess = { println("update trip location success") }, onError = ::onError, ) } @@ -104,25 +104,20 @@ class MapScreenModel( override fun onClickAccept() { updateState { mapScreenUiState -> mapScreenUiState.copy( - isLoading = false, - error = null, - isNewOrderFound = false, - isAcceptedOrder = true, - ).also { - coroutineScope.launch(Dispatchers.IO) { - manageTrip.updateTripStatus(it.tripInfoUiState.id) - } - } + isLoading = false, error = null, + isNewOrderFound = false, isAcceptedOrder = true, + ) } + updateTrip() } override fun onClickCancel() { updateState { it.copy( isLoading = true, + error = null, isNewOrderFound = false, isAcceptedOrder = false, - error = null, tripInfoUiState = TripInfoUiState() ) } @@ -130,40 +125,31 @@ class MapScreenModel( } override fun onClickArrived() { - updateState { - it.copy( - isLoading = false, - error = null, - tripInfoUiState = it.tripInfoUiState.copy( - isArrived = true - ) - ).also { - coroutineScope.launch(Dispatchers.IO) { - manageTrip.updateTripStatus(it.tripInfoUiState.id) - } - } + updateState { it.copy(isLoading = false, error = null, + tripInfoUiState = it.tripInfoUiState.copy(isArrived = true) + ) } + updateTrip() + } + + private fun updateTrip() { + println("///////////////////////trip ID:${state.value.tripInfoUiState.id}///////////////////////") + tryToExecute( + function = { manageTrip.updateTripStatus(state.value.tripInfoUiState.id) }, + onSuccess = { println("update trip success") }, + onError = ::onError + ) } override fun onClickDropOff() { updateState { it.copy( - isLoading = true, - isAcceptedOrder = false, - error = null, - tripInfoUiState = TripInfoUiState() - ).also { - try { - coroutineScope.launch(Dispatchers.IO) { - manageTrip.updateTripStatus(it.tripInfoUiState.id) - } - // findingNewOrder() - }catch (e: Exception) { - onError(ErrorState.UnknownError(e.message ?: "Unknown Error")) - } - - } + isLoading = true, error = null, + isAcceptedOrder = false, tripInfoUiState = TripInfoUiState() + ) } + updateTrip() + findingNewOrder() } override fun onClickCloseIcon() {