Author: Adam Evyčędo <git@apiote.xyz>
suggest searching
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/DashboardViewModel.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/DashboardViewModel.kt index c29eae885cd246c368dc35001cd26eebb9562ff6..0905bcc2f6e39ba980ac16e495806cb697ed32ac 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/DashboardViewModel.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/DashboardViewModel.kt @@ -8,6 +8,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.google.android.material.chip.Chip +import com.google.android.material.chip.ChipGroup import com.google.android.material.textfield.TextInputEditText import xyz.apiote.bimba.czwek.repo.Place import xyz.apiote.bimba.czwek.repo.TimeReference @@ -49,14 +50,12 @@ ORIGIN_KEY to "", DEST_KEY to "" ) - val positionChips = mutableMapOf<String, Chip?>( + val positionQueries = mutableMapOf<String, Query?>( ORIGIN_KEY to null, DEST_KEY to null ) - val positionQueries = mutableMapOf<String, Query?>( - ORIGIN_KEY to null, - DEST_KEY to null + val suggestions = mutableMapOf<String, ChipGroup>( ) val textInputs = mutableMapOf<String, TextInputEditText>() diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt index 7a37f67c483df9e94995581c8268ce11782c26dc..d70dc1c6f78dde7051b5797e069dd7b5dc29c6e0 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/journey/JourneyFragment.kt @@ -36,7 +36,6 @@ import androidx.lifecycle.ViewModelProvider import androidx.swiperefreshlayout.widget.CircularProgressDrawable import com.google.android.material.chip.Chip import com.google.android.material.chip.ChipDrawable -import com.google.android.material.chip.ChipGroup import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.timepicker.MaterialTimePicker import com.google.android.material.timepicker.TimeFormat @@ -100,6 +99,9 @@ dashboard.viewModel.textInputs[DashboardViewModel.ORIGIN_KEY] = binding.origin dashboard.viewModel.textInputs[DashboardViewModel.DEST_KEY] = binding.destination + dashboard.viewModel.suggestions[DashboardViewModel.ORIGIN_KEY] = binding.originSuggestions + dashboard.viewModel.suggestions[DashboardViewModel.DEST_KEY] = binding.destinationSuggestions + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) binding.originInput.updatePadding(left = insets.left, right = insets.right) @@ -146,15 +148,8 @@ dashboard.hideBadge() chipifyOrigin(dashboard.viewModel.data[DashboardViewModel.ORIGIN_KEY]!!.value) chipifyDestination(dashboard.viewModel.data[DashboardViewModel.DEST_KEY]!!.value) - binding.originChipHere.setOnClickListener { - setChipProgress(binding.originChipHere) - setHere(DashboardViewModel.ORIGIN_KEY) - } - - binding.destinationChipHere.setOnClickListener { - setChipProgress(binding.destinationChipHere) - setHere(DashboardViewModel.DEST_KEY) - } + initSuggestions(DashboardViewModel.ORIGIN_KEY) + initSuggestions(DashboardViewModel.DEST_KEY) binding.goButton.isEnabled = dashboard.viewModel.data[DashboardViewModel.ORIGIN_KEY]!!.value != null && dashboard.viewModel.data[DashboardViewModel.DEST_KEY]!!.value != null @@ -220,7 +215,7 @@ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { - afterTextChanged(DashboardViewModel.ORIGIN_KEY, binding.originSuggestions, s, inflater) + afterTextChanged(DashboardViewModel.ORIGIN_KEY, s) } }) @@ -230,7 +225,7 @@ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { - afterTextChanged(DashboardViewModel.DEST_KEY, binding.destinationSuggestions, s, inflater) + afterTextChanged(DashboardViewModel.DEST_KEY, s) } }) @@ -361,10 +356,9 @@ } private fun afterTextChanged( source: String, - suggestions: ChipGroup, s: Editable?, - inflater: LayoutInflater ) { + val suggestions = dashboard.viewModel.suggestions[source]!! if (s.isNullOrBlank()) { dashboard.viewModel.spans[source] = "" binding.goButton.isEnabled = false @@ -382,7 +376,7 @@ .replace(dashboard.viewModel.spans[source]!!, "") ) q.parse(requireContext()) if (q.mode in arrayOf(Mode.POSITION, Mode.LOCATION_PLUS_CODE)) { - val chip = inflater.inflate(R.layout.chip_suggestion, suggestions, false) as Chip + val chip = layoutInflater.inflate(R.layout.chip_suggestion, suggestions, false) as Chip chip.text = q.toString() chip.isCheckable = false chip.isChipIconVisible = true @@ -393,7 +387,7 @@ dashboard.viewModel.set( source, Place(q.position!!.latitude, q.position!!.longitude) ) - suggestions.removeView(dashboard.viewModel.positionChips[source]) + initSuggestions(source) } else { setChipProgress(chip) dashboard.viewModel.positionQueries[source] = q @@ -401,14 +395,39 @@ viewModel.hereChipRequester = source setHere(source) } } - suggestions.removeView(dashboard.viewModel.positionChips[source]) - dashboard.viewModel.positionChips[source] = chip - suggestions.addView(chip, 1) + initSuggestions(source) + suggestions.addView(chip) + } else if (q.mode == Mode.NAME) { + val chip = layoutInflater.inflate(R.layout.chip_suggestion, suggestions, false) as Chip + chip.text = q.toString() + chip.isCheckable = false + chip.isChipIconVisible = true + chip.setChipIconResource(R.drawable.search) + chip.setOnClickListener { + searchText(source) + } + initSuggestions(source) + suggestions.addView(chip) } else { - suggestions.removeView(dashboard.viewModel.positionChips[source]) + initSuggestions(source) } } + fun initSuggestions(source: String) { + val suggestions = dashboard.viewModel.suggestions[source]!! + suggestions.removeAllViews() + val chip = layoutInflater.inflate(R.layout.chip_suggestion, suggestions, false) as Chip + chip.setText(R.string.here) + chip.isCheckable = false + chip.isChipIconVisible = true + chip.setChipIconResource(R.drawable.gps) + chip.setOnClickListener { + setChipProgress(chip) + setHere(source) + } + suggestions.addView(chip) + } + private fun getSearchText(source: String): String = dashboard.viewModel.textInputs[source]!!.text.toString() .replace(dashboard.viewModel.spans[source]!!, "") @@ -480,10 +499,9 @@ var chip: ChipDrawable? = ChipDrawable.createFromResource(requireContext(), R.xml.journey_chip) chip!!.text = text val ld = LayerDrawable(arrayOf(chip)).apply { setLayerInset(0, dpToPixelI(4f), 0, dpToPixelI(4f), 0) - setBounds(0, 0, chip.intrinsicWidth, chip.intrinsicHeight) + setBounds(0, 0, chip.intrinsicWidth + 24, chip.intrinsicHeight) } val span = ImageSpan(ld) - // FIXME size is one char to small textView.text?.setSpan(span, 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) @SuppressLint("ClickableViewAccessibility") textView.setOnTouchListener { v, e -> @@ -516,6 +534,8 @@ } else { false } } + + initSuggestions(source) } private fun setHere(source: String) { @@ -579,9 +599,7 @@ it, Place(position.latitude, position.longitude) ) dashboard.viewModel.positionQueries[it] = null - val suggestions = - if (it == DashboardViewModel.ORIGIN_KEY) binding.originSuggestions else binding.destinationSuggestions - suggestions.removeView(dashboard.viewModel.positionChips[it]) + initSuggestions(it) } viewModel.hereChipRequester = null } diff --git a/app/src/main/res/drawable/gps.xml b/app/src/main/res/drawable/gps.xml new file mode 100644 index 0000000000000000000000000000000000000000..6408c48bc2c87c88bc82a86c889136fad96678a1 --- /dev/null +++ b/app/src/main/res/drawable/gps.xml @@ -0,0 +1,16 @@ +<!-- +SPDX-FileCopyrightText: Google + +SPDX-License-Identifier: Apache-2.0 +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorOnSurface" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94L23,13v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z" /> +</vector> diff --git a/app/src/main/res/drawable/inexact.xml b/app/src/main/res/drawable/inexact.xml deleted file mode 100644 index d1ba0403097cbc7a980bc9d5ddfd921596069d04..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/inexact.xml +++ /dev/null @@ -1,17 +0,0 @@ -<!-- -SPDX-FileCopyrightText: Michael Irigoyen - -SPDX-License-Identifier: Apache-2.0 - -source: https://pictogrammers.com/library/mdi/icon/tilde/ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:tint="?attr/colorOnSurface" - android:viewportWidth="24" - android:viewportHeight="24"> - <path - android:fillColor="#000000" - android:pathData="M2,15C2,15 2,9 8,9C12,9 12.5,12.5 15.5,12.5C19.5,12.5 19.5,9 19.5,9H22C22,9 22,15 16,15C12,15 10.5,11.5 8.5,11.5C4.5,11.5 4.5,15 4.5,15H2" /> -</vector> \ No newline at end of file diff --git a/app/src/main/res/drawable/search.xml b/app/src/main/res/drawable/search.xml new file mode 100644 index 0000000000000000000000000000000000000000..c22960ef9611bcfcfd5164564e088af45080949a --- /dev/null +++ b/app/src/main/res/drawable/search.xml @@ -0,0 +1,16 @@ +<!-- +SPDX-FileCopyrightText: Google + +SPDX-License-Identifier: Apache-2.0 +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorOnSurface" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" /> +</vector> diff --git a/app/src/main/res/layout/fragment_journey.xml b/app/src/main/res/layout/fragment_journey.xml index 2f1948ee67e81fee870fb3f12d410e27cfd31a1e..8c00176c1876bddbcc75762fea831c91efc934fc 100644 --- a/app/src/main/res/layout/fragment_journey.xml +++ b/app/src/main/res/layout/fragment_journey.xml @@ -43,20 +43,7 @@ android:layout_marginTop="4dp" android:layout_marginRight="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/origin_input"> - - <com.google.android.material.chip.Chip - android:id="@+id/origin_chip_here" - style="@style/Widget.Material3.Chip.Suggestion" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:checkable="false" - android:text="@string/here" - app:chipIcon="@drawable/gps_black" - app:chipIconTint="?attr/colorOnSurface" - app:chipIconVisible="true" /> - - </com.google.android.material.chip.ChipGroup> + app:layout_constraintTop_toBottomOf="@id/origin_input" /> <!-- via required: false @@ -107,20 +94,8 @@ android:layout_marginTop="4dp" android:layout_marginRight="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/destination_input"> - - <com.google.android.material.chip.Chip - android:id="@+id/destination_chip_here" - style="@style/Widget.Material3.Chip.Suggestion" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:checkable="false" - android:text="@string/here" - app:chipIcon="@drawable/gps_black" - app:chipIconTint="?attr/colorOnSurface" - app:chipIconVisible="true" /> + app:layout_constraintTop_toBottomOf="@id/destination_input" /> - </com.google.android.material.chip.ChipGroup> <com.google.android.material.divider.MaterialDivider android:id="@+id/materialDivider"