Finished app state persistence and improved user interaction
This commit is contained in:
parent
1786c5c12a
commit
44cf06c9a6
|
@ -24,13 +24,7 @@ class MessageListActivity : AppCompatActivity() {
|
|||
|
||||
private lateinit var model: MessageListViewModel
|
||||
|
||||
private val spinnerOptions: ArrayList<CharSequence> = ArrayList()
|
||||
private val solutions: ArrayList<CharSequence> = ArrayList()
|
||||
private var nextSolutionIndex: Int = 0
|
||||
private var currentSolutionState: State = State.HAVE_YOU_TRIED
|
||||
private lateinit var adapter: ArrayAdapter<CharSequence>
|
||||
private lateinit var component: Component
|
||||
private lateinit var problem: Problem
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -43,11 +37,11 @@ class MessageListActivity : AppCompatActivity() {
|
|||
|
||||
model = ViewModelProviders.of(this).get(MessageListViewModel::class.java)
|
||||
|
||||
initFirstChoice()
|
||||
|
||||
horizontalLayout = findViewById(R.id.layout_chatbox)
|
||||
typingIndicator = findViewById(R.id.indicator)
|
||||
typingIndicator.visibility = View.GONE
|
||||
horizontalLayout.visibility = View.GONE
|
||||
spinner = findViewById(R.id.spinner)
|
||||
|
||||
recyclerView = findViewById<RecyclerView>(R.id.messageList).apply {
|
||||
// use this setting to improve performance if you know that changes
|
||||
|
@ -59,14 +53,25 @@ class MessageListActivity : AppCompatActivity() {
|
|||
|
||||
// specify an viewAdapter (see also next example)
|
||||
adapter = viewAdapter
|
||||
|
||||
}
|
||||
|
||||
val spinnerOptions: ArrayList<CharSequence>? = model.spinnerOptions.value
|
||||
if (spinnerOptions != null) {
|
||||
adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, spinnerOptions)
|
||||
}
|
||||
// Specify the layout to use when the list of choices appears
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
adapter.setNotifyOnChange(true)
|
||||
// Apply the adapter to the spinner
|
||||
spinner.adapter = adapter
|
||||
|
||||
val messageObserver = Observer<ArrayList<Message>> { messages ->
|
||||
viewAdapter.replaceMessages(messages)
|
||||
}
|
||||
|
||||
model.getMessages().observe(this, messageObserver)
|
||||
|
||||
initFirstChoice()
|
||||
}
|
||||
|
||||
fun sendMessage(view: View) {
|
||||
|
@ -74,16 +79,17 @@ class MessageListActivity : AppCompatActivity() {
|
|||
val message = Message(text, true, System.currentTimeMillis())
|
||||
model.add(message)
|
||||
recyclerView.scrollToPosition(model.size() - 1)
|
||||
viewAdapter.notifyItemInserted(model.size() - 1)
|
||||
horizontalLayout.visibility = View.GONE
|
||||
model.spinnerVisible.value = false
|
||||
|
||||
nextStage(text)
|
||||
}
|
||||
|
||||
private fun receiveMessage(message: Message) {
|
||||
receiveMessages(listOf(message))
|
||||
private fun receiveMessage(message: Message, showSpinner: Boolean = true) {
|
||||
receiveMessages(listOf(message), showSpinner)
|
||||
}
|
||||
|
||||
private fun receiveMessages(messages: List<Message>) {
|
||||
private fun receiveMessages(messages: List<Message>, showSpinner: Boolean = true) {
|
||||
model.uiScope.launch {
|
||||
for (message in messages) {
|
||||
typingIndicator.visibility = View.VISIBLE
|
||||
|
@ -92,6 +98,10 @@ class MessageListActivity : AppCompatActivity() {
|
|||
model.add(message)
|
||||
recyclerView.scrollToPosition(model.size() - 1)
|
||||
}
|
||||
if (showSpinner) {
|
||||
horizontalLayout.visibility = View.VISIBLE
|
||||
model.spinnerVisible.value = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -100,7 +110,7 @@ class MessageListActivity : AppCompatActivity() {
|
|||
when (selection) {
|
||||
in resources.getStringArray(R.array.components) -> {
|
||||
// first selection
|
||||
component = Component.valueOf(selection.toUpperCase())
|
||||
model.component.value = Component.valueOf(selection.toUpperCase())
|
||||
secondChoice()
|
||||
}
|
||||
in resources.getStringArray(R.array.monitor_problems),
|
||||
|
@ -109,12 +119,11 @@ class MessageListActivity : AppCompatActivity() {
|
|||
in resources.getStringArray(R.array.tv_problems),
|
||||
in resources.getStringArray(R.array.router_problems) -> {
|
||||
// second selection
|
||||
problem = Problem.valueOf(selection.toUpperCase().replace(' ', '_'))
|
||||
receiveMessage(Message(getString(R.string.okay), false, System.currentTimeMillis()))
|
||||
model.problem.value = Problem.valueOf(selection.toUpperCase().replace(' ', '_'))
|
||||
solutionQuestion()
|
||||
}
|
||||
in resources.getStringArray(R.array.binary) -> {
|
||||
when (currentSolutionState) {
|
||||
when (model.currentSolutionState.value) {
|
||||
State.HAVE_YOU_TRIED -> triedAnswer(selection)
|
||||
State.DID_IT_WORK -> doesItWorkAnswer(selection)
|
||||
}
|
||||
|
@ -124,61 +133,66 @@ class MessageListActivity : AppCompatActivity() {
|
|||
getString(R.string.gardner_second),
|
||||
false,
|
||||
System.currentTimeMillis()
|
||||
))
|
||||
horizontalLayout.visibility = View.GONE
|
||||
), false)
|
||||
}
|
||||
getString(R.string.can_you_say_sth_different) -> {
|
||||
receiveMessages(listOf(
|
||||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.im_gardner), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.okay_saves_time), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.its_funny), false, System.currentTimeMillis())))
|
||||
horizontalLayout.visibility = View.GONE
|
||||
Message(getString(R.string.its_funny), false, System.currentTimeMillis())),
|
||||
false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initFirstChoice() {
|
||||
spinner = findViewById(R.id.spinner)
|
||||
receiveMessage(Message(getString(R.string.greeting), false, System.currentTimeMillis()))
|
||||
// Create an ArrayAdapter using the string array and a default spinner layout
|
||||
spinnerOptions.addAll(resources.getStringArray(R.array.components))
|
||||
adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, spinnerOptions)
|
||||
// Specify the layout to use when the list of choices appears
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
adapter.setNotifyOnChange(true)
|
||||
// Apply the adapter to the spinner
|
||||
spinner.adapter = adapter
|
||||
val isInitialized = model.initialized.value
|
||||
if (isInitialized != null && !isInitialized) {
|
||||
model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.components))
|
||||
adapter.notifyDataSetChanged()
|
||||
model.initialized.value = true
|
||||
receiveMessage(Message(getString(R.string.greeting), false, System.currentTimeMillis()))
|
||||
}
|
||||
else {
|
||||
val spinnerVisible = model.spinnerVisible.value
|
||||
if (spinnerVisible != null && spinnerVisible) horizontalLayout.visibility = View.VISIBLE
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun secondChoice() {
|
||||
model.spinnerOptions.value?.clear()
|
||||
when (model.component.value) {
|
||||
Component.PRINTER -> model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.printer_problems))
|
||||
Component.PC -> model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.pc_problems))
|
||||
Component.MONITOR -> model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.monitor_problems))
|
||||
Component.TV -> model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.tv_problems))
|
||||
Component.ROUTER -> model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.router_problems))
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
receiveMessages(listOf(
|
||||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.select_problem), false, System.currentTimeMillis())
|
||||
))
|
||||
spinnerOptions.clear()
|
||||
when (component) {
|
||||
Component.PRINTER -> spinnerOptions.addAll(resources.getStringArray(R.array.printer_problems))
|
||||
Component.PC -> spinnerOptions.addAll(resources.getStringArray(R.array.pc_problems))
|
||||
Component.MONITOR -> spinnerOptions.addAll(resources.getStringArray(R.array.monitor_problems))
|
||||
Component.TV -> spinnerOptions.addAll(resources.getStringArray(R.array.tv_problems))
|
||||
Component.ROUTER -> spinnerOptions.addAll(resources.getStringArray(R.array.router_problems))
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun solutionQuestion() {
|
||||
val format = "component_problem"
|
||||
val stringName = format.replace("component", component.toString().toLowerCase()).
|
||||
replace("problem", problem.toString().toLowerCase())
|
||||
solutions.addAll(getSolutionArray(stringName))
|
||||
val stringName = format.replace("component", model.component.value.toString().toLowerCase()).
|
||||
replace("problem", model.problem.value.toString().toLowerCase())
|
||||
model.solutions.value?.addAll(getSolutionArray(stringName))
|
||||
|
||||
val firstSolutionQuestion = getString(R.string.have_you_tried, solutions[0])
|
||||
nextSolutionIndex++
|
||||
receiveMessage(Message(firstSolutionQuestion, false, System.currentTimeMillis()))
|
||||
spinnerOptions.clear()
|
||||
spinnerOptions.addAll(resources.getStringArray(R.array.binary))
|
||||
val firstSolutionQuestion = getString(R.string.have_you_tried, model.solutions.value?. let { it[0] })
|
||||
model.nextSolutionIndex.value = (model.nextSolutionIndex.value ?: 0) + 1
|
||||
model.spinnerOptions.value?.clear()
|
||||
model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.binary))
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
receiveMessages(listOf(
|
||||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(firstSolutionQuestion, false, System.currentTimeMillis())
|
||||
))
|
||||
}
|
||||
|
||||
private fun triedAnswer(selection: String) {
|
||||
|
@ -200,7 +214,7 @@ class MessageListActivity : AppCompatActivity() {
|
|||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.did_it_work), false, System.currentTimeMillis())
|
||||
))
|
||||
currentSolutionState = State.DID_IT_WORK
|
||||
model.currentSolutionState.value = State.DID_IT_WORK
|
||||
}
|
||||
|
||||
private fun pleaseTry() {
|
||||
|
@ -208,53 +222,60 @@ class MessageListActivity : AppCompatActivity() {
|
|||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.please_try), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.i_wait), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.have_you_tried, solutions[nextSolutionIndex - 1]), false, System.currentTimeMillis())
|
||||
Message(getString(R.string.have_you_tried, model.solutions.value?.let { it[(model.nextSolutionIndex.value ?: 1) - 1]}), false, System.currentTimeMillis())
|
||||
))
|
||||
}
|
||||
|
||||
private fun problemSolved() {
|
||||
receiveMessage(Message(getString(R.string.okay), false, System.currentTimeMillis()))
|
||||
spinnerOptions.clear()
|
||||
spinnerOptions.add(getString(R.string.can_you_say_sth_different))
|
||||
model.spinnerOptions.value?.clear()
|
||||
model.spinnerOptions.value?.add(getString(R.string.can_you_say_sth_different))
|
||||
adapter.notifyDataSetChanged()
|
||||
receiveMessage(Message(getString(R.string.okay), false, System.currentTimeMillis()))
|
||||
}
|
||||
|
||||
private fun nextSolutionQuestion() {
|
||||
receiveMessages(listOf(
|
||||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.sorry), false, System.currentTimeMillis())
|
||||
))
|
||||
if (nextSolutionIndex == solutions.size) {
|
||||
if (model.nextSolutionIndex.value == model.solutions.value?.size) {
|
||||
// we exhausted all options
|
||||
var summary = """
|
||||
Component: ${component.toString().toLowerCase().capitalize()}
|
||||
Problem: ${problem.toString().replace('_', ' ').toLowerCase().capitalizeWords()}
|
||||
Component: ${model.component.value.toString().toLowerCase().capitalize()}
|
||||
Problem: ${model.problem.value.toString().replace('_', ' ').toLowerCase().capitalizeWords()}
|
||||
Tried Solutions:
|
||||
""".trimIndent()
|
||||
for (solution in solutions) {
|
||||
val item = "\n - $solution"
|
||||
summary = summary.plus(item)
|
||||
val solutions: ArrayList<CharSequence>? = model.solutions.value
|
||||
if (solutions != null) {
|
||||
for (solution in solutions) {
|
||||
val item = "\n - $solution"
|
||||
summary = summary.plus(item)
|
||||
}
|
||||
}
|
||||
|
||||
model.spinnerOptions.value?.clear()
|
||||
model.spinnerOptions.value?.add(getString(R.string.who_are_you))
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
receiveMessages(listOf(
|
||||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.sorry), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.cant_help), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.should_contact_support), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.okay_wait), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.tell_support), false, System.currentTimeMillis()),
|
||||
Message(summary, false, System.currentTimeMillis())
|
||||
))
|
||||
|
||||
spinnerOptions.clear()
|
||||
spinnerOptions.add(getString(R.string.who_are_you))
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
else {
|
||||
val solutionQuestion = getString(R.string.have_you_tried, solutions[nextSolutionIndex])
|
||||
nextSolutionIndex++
|
||||
currentSolutionState = State.HAVE_YOU_TRIED
|
||||
receiveMessage(Message(solutionQuestion, false, System.currentTimeMillis()))
|
||||
spinnerOptions.clear()
|
||||
spinnerOptions.addAll(resources.getStringArray(R.array.binary))
|
||||
val solutionQuestion = getString(R.string.have_you_tried, model.solutions.value?.let {it[model.nextSolutionIndex.value ?: 0]})
|
||||
model.nextSolutionIndex.value = (model.nextSolutionIndex.value ?: 0) + 1
|
||||
model.currentSolutionState.value = State.HAVE_YOU_TRIED
|
||||
model.spinnerOptions.value?.clear()
|
||||
model.spinnerOptions.value?.addAll(resources.getStringArray(R.array.binary))
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
receiveMessages(listOf(
|
||||
Message(getString(R.string.okay), false, System.currentTimeMillis()),
|
||||
Message(getString(R.string.sorry), false, System.currentTimeMillis()),
|
||||
Message(solutionQuestion, false, System.currentTimeMillis())
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,26 @@ class MessageListViewModel : ViewModel() {
|
|||
private val messages: MutableLiveData<ArrayList<Message>> by lazy {
|
||||
MutableLiveData<ArrayList<Message>>(ArrayList<Message>())
|
||||
}
|
||||
val spinnerOptions: MutableLiveData<ArrayList<CharSequence>> by lazy {
|
||||
MutableLiveData<ArrayList<CharSequence>>(ArrayList<CharSequence>())
|
||||
}
|
||||
val solutions: MutableLiveData<ArrayList<CharSequence>> by lazy {
|
||||
MutableLiveData<ArrayList<CharSequence>>(ArrayList<CharSequence>())
|
||||
}
|
||||
val nextSolutionIndex: MutableLiveData<Int> by lazy {
|
||||
MutableLiveData<Int>(0)
|
||||
}
|
||||
val currentSolutionState: MutableLiveData<State> by lazy {
|
||||
MutableLiveData<State>(State.HAVE_YOU_TRIED)
|
||||
}
|
||||
val component: MutableLiveData<Component> by lazy {
|
||||
MutableLiveData<Component>()
|
||||
}
|
||||
val problem: MutableLiveData<Problem> by lazy {
|
||||
MutableLiveData<Problem>()
|
||||
}
|
||||
val initialized: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>(false) }
|
||||
val spinnerVisible: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>(false) }
|
||||
|
||||
private val viewModelJob = SupervisorJob()
|
||||
val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
|
||||
|
|
Loading…
Reference in New Issue