Skip to content
Open

Ios #19

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
Binary file added SharedCode/src/androidMain/.DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions SharedCode/src/commonMain/kotlin/ApplicationContract.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import kotlinx.coroutines.CoroutineScope
interface ApplicationContract {
interface View {
fun setLabel(text: String)
fun updateSearchResults(results: List<String>)
}

abstract class Presenter: CoroutineScope {
abstract fun onViewTaken(view: View)
abstract fun getTrainTimes(departureStation: String, arrivalStation: String)
}
}
65 changes: 60 additions & 5 deletions SharedCode/src/commonMain/kotlin/ApplicationPresenter.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,74 @@
package com.jetbrains.handson.mpp.mobile

import io.ktor.client.*
import io.ktor.client.features.json.*
import io.ktor.client.features.json.serializer.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.coroutines.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlin.coroutines.CoroutineContext

@Serializable
data class OutboundJourney(val departureTime: String, val arrivalTime: String) {}

@Serializable
data class SerializableResponse(val numberOfAdults: Int, val numberOfChildren: Int, val outboundJourneys: List<OutboundJourney>) {}

class ApplicationPresenter: ApplicationContract.Presenter() {

private val dispatchers = AppDispatchersImpl()
private var view: ApplicationContract.View? = null
private lateinit var view: ApplicationContract.View
private val job: Job = SupervisorJob()

override val coroutineContext: CoroutineContext
get() = dispatchers.main + job

override fun onViewTaken(view: ApplicationContract.View) {
this.view = view
view.setLabel(createApplicationScreenMessage())
// view.setLabel(createApplicationScreenMessage())
}

private fun serializableResponseToStringArray(serializableResponse: SerializableResponse): List<String> {
var result: MutableList<String> = mutableListOf<String>()
for (journey in serializableResponse.outboundJourneys) {
result.add("${journey.departureTime} - ${journey.arrivalTime}")
}
return result
}

val client = HttpClient() {
install(JsonFeature) {
serializer = KotlinxSerializer(kotlinx.serialization.json.Json { this.ignoreUnknownKeys = true; this.isLenient = true})
}
}


fun updateSearchResults(results: List<String>) {
this.view?.setLabel("a")
this.view?.updateSearchResults(results)
}

public override fun getTrainTimes(departureStation: String, arrivalStation: String) {
this.view.updateSearchResults(listOf("Loading..."))
launch {
val response: SerializableResponse = client.request("https://mobile-api-softwire2.lner.co.uk/v1/fares?originStation=$departureStation&destinationStation=$arrivalStation&noChanges=false&numberOfAdults=2&numberOfChildren=0&journeyType=single&outboundDateTime=2021-07-24T14%3A30%3A00.000%2B01%3A00&outboundIsArriveBy=false")
/*val response: SerializableResponse = client.request("https://mobile-api-softwire2.lner.co.uk/v1/fares/") {
method = HttpMethod.Get
parameter("originStation", departureStation)
parameter("destinationStation", arrivalStation)
parameter("noChanges", "false")
parameter("numberOfAdults", "1")
parameter("numberOfChildren", "0")
parameter("journeyType", "single")
parameter("outboundDateTime", "2021-07-24T14%3A30%3A00.000%2B01%3A00")
parameter("outboundIsArriveBy", "false")
}*/
updateSearchResults(
serializableResponseToStringArray(response))
}
}

override val coroutineContext: CoroutineContext
get() = dispatchers.main + job

}
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jetbrains.handson.mpp.mobile">

<uses-permission android:name="android.permission.INTERNET"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/jetbrains/handson/mpp/mobile/Extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.jetbrains.handson.mpp.mobile

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes

fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): View {
return LayoutInflater.from(context).inflate(layoutRes, this, attachToRoot)
}
62 changes: 60 additions & 2 deletions app/src/main/java/com/jetbrains/handson/mpp/mobile/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,78 @@
package com.jetbrains.handson.mpp.mobile

import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Spinner
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.runBlocking
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity(), ApplicationContract.View {

lateinit var departureStationSpinner: Spinner
lateinit var arrivalStationSpinner: Spinner
private lateinit var linearLayoutManager: LinearLayoutManager
lateinit var adapter: RecyclerAdapter

// private lateinit var linearLayoutManager: RecyclerView.LinearLayoutManager

private val presenter: ApplicationPresenter = ApplicationPresenter()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val presenter = ApplicationPresenter()
linearLayoutManager = LinearLayoutManager(this)
var recyclerView: RecyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = linearLayoutManager


adapter = RecyclerAdapter(this, listOf(OutboundJourney(arrivalTime = "Test", departureTime = "Test"), OutboundJourney(arrivalTime = "Test", departureTime = "Test"),OutboundJourney(arrivalTime = "Test", departureTime = "Test"),OutboundJourney(arrivalTime = "Test", departureTime = "Test")))
recyclerView.adapter = adapter


presenter.onViewTaken(this)

departureStationSpinner = findViewById<Spinner>(R.id.stations_spinner1) as Spinner
arrivalStationSpinner = findViewById<Spinner>(R.id.stations_spinner2) as Spinner
departureStationSpinner.setSelection(0)
arrivalStationSpinner.setSelection(0)

// linearLayoutManager = LinearLayoutManager(this)
// recyclerView.layoutManager = linearLayoutManager
}

override fun setLabel(text: String) {
findViewById<TextView>(R.id.main_text).text = text
//findViewById<TextView>(R.id.main_text).text = text
}

fun onSubmitClicked(view: View) {

var departureCode = departureStationSpinner.selectedItem.toString()
val ld = departureCode.length
departureCode = departureCode.substring(ld - 4, ld - 1)

var arrivalCode = arrivalStationSpinner.selectedItem.toString()
val ad = arrivalCode.length
arrivalCode = arrivalCode.substring(ad - 4, ad - 1)
val url =
"https://www.lner.co.uk/travel-information/travelling-now/live-train-times/depart/$departureCode/$arrivalCode/#LiveDepResults"

presenter.getTrainTimes(departureCode, arrivalCode)

// println("printed msg")

// val intent = Intent(Intent.ACTION_VIEW)
// intent.data = Uri.parse(url)
// startActivity(intent)
}

override fun updateSearchResults(results: List<String>) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
package com.jetbrains.handson.mpp.mobile

import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.recyclerview.widget.RecyclerView

class RecyclerAdapter(private val times: ArrayList<OutboundJourney>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {



override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflatedView = parent.inflate(R.layout.recyclerview_item_row, false)
return ViewHolder(inflatedView)
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
TODO("Not yet implemented")
}

override fun getItemCount(): Int {
return times.size
}

inner class ViewHolder(v: View): RecyclerView.ViewHolder(v) {
var departureTime: TextView
var arrivalTime: TextView

init {
departureTime = itemView.findViewById(R.id.departure_time)
arrivalTime = itemView.findViewById(R.id.arrival_time)
}
}
}*/

package com.jetbrains.handson.mpp.mobile

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class RecyclerAdapter(context: Context, journeys: List<OutboundJourney>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private var mData: List<OutboundJourney> = journeys
private var mInflater: LayoutInflater = LayoutInflater.from(context)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view: View = mInflater.inflate(R.layout.recyclerview_item_row, parent, false)
return ViewHolder(view)
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val outboundJourney: OutboundJourney = mData[position]
if (holder is ViewHolder) {
holder.departureTime.text = outboundJourney.departureTime
holder.arrivalTime.text = outboundJourney.arrivalTime
}
}

override fun getItemCount(): Int {
return this.mData.size
}

class ViewHolder(view: View): RecyclerView.ViewHolder(view) {
var departureTime: TextView = view.findViewById(R.id.departure_time)
var arrivalTime: TextView = view.findViewById(R.id.arrival_time)
}


}
73 changes: 61 additions & 12 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
Expand All @@ -7,17 +8,65 @@
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/main_text"
android:textSize="42sp"
android:layout_margin="5sp"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Spinner
android:id="@+id/stations_spinner1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="100dp"
android:layout_marginTop="176dp"
android:layout_marginEnd="100dp"
android:entries="@array/stations_array"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.507"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Spinner
android:id="@+id/stations_spinner2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="50dp"
android:layout_marginStart="100dp"
android:layout_marginEnd="100dp"
android:entries="@array/stations_array"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stations_spinner1"/>

<Button
android:id="@+id/buton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="100dp"
android:onClick="onSubmitClicked"
android:text="Get Times"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stations_spinner2" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="411dp"
android:layout_height="335dp"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buton1" />

<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/buton1"-->
<!-- android:layout_marginTop="60dp">-->
<!-- <androidx.recyclerview.widget.RecyclerView-->
<!-- android:id="@+id/recyclerView"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:scrollbars="vertical"/>-->
<!-- </LinearLayout>-->

</androidx.constraintlayout.widget.ConstraintLayout>
Loading