Legg til haptisk tilbakemelding på knappetrykk og listeval (#11)
Android: HapticFeedbackConstants.VIRTUAL_KEY på alle knappar og listeelement. PWA: navigator.vibrate(10ms) på same interaksjonar. Closes #11 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c35ccb91bf
commit
3c1da8adec
5 changed files with 17 additions and 1 deletions
|
|
@ -3,6 +3,7 @@ package no.naiv.tilfluktsrom
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.view.HapticFeedbackConstants
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.hardware.Sensor
|
import android.hardware.Sensor
|
||||||
import android.hardware.SensorEvent
|
import android.hardware.SensorEvent
|
||||||
|
|
@ -202,6 +203,7 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
|
||||||
|
|
||||||
private fun setupButtons() {
|
private fun setupButtons() {
|
||||||
binding.toggleViewFab.setOnClickListener {
|
binding.toggleViewFab.setOnClickListener {
|
||||||
|
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||||
isCompassMode = !isCompassMode
|
isCompassMode = !isCompassMode
|
||||||
if (isCompassMode) {
|
if (isCompassMode) {
|
||||||
binding.mapView.visibility = View.GONE
|
binding.mapView.visibility = View.GONE
|
||||||
|
|
@ -216,24 +218,29 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
|
||||||
|
|
||||||
// Reset to navigation: re-fit map to show user + selected shelter
|
// Reset to navigation: re-fit map to show user + selected shelter
|
||||||
binding.resetNavigationFab.setOnClickListener {
|
binding.resetNavigationFab.setOnClickListener {
|
||||||
|
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||||
userHasInteractedWithMap = false
|
userHasInteractedWithMap = false
|
||||||
binding.resetNavigationFab.visibility = View.GONE
|
binding.resetNavigationFab.visibility = View.GONE
|
||||||
selectedShelter?.let { highlightShelterOnMap(it) }
|
selectedShelter?.let { highlightShelterOnMap(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.infoButton.setOnClickListener {
|
binding.infoButton.setOnClickListener {
|
||||||
|
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||||
CivilDefenseInfoDialog().show(supportFragmentManager, CivilDefenseInfoDialog.TAG)
|
CivilDefenseInfoDialog().show(supportFragmentManager, CivilDefenseInfoDialog.TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.refreshButton.setOnClickListener {
|
binding.refreshButton.setOnClickListener {
|
||||||
|
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||||
forceRefresh()
|
forceRefresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.shareButton.setOnClickListener {
|
binding.shareButton.setOnClickListener {
|
||||||
|
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||||
shareShelter()
|
shareShelter()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.cacheRetryButton.setOnClickListener {
|
binding.cacheRetryButton.setOnClickListener {
|
||||||
|
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||||
val loc = currentLocation
|
val loc = currentLocation
|
||||||
if (loc == null) {
|
if (loc == null) {
|
||||||
Toast.makeText(this, R.string.status_no_location, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.status_no_location, Toast.LENGTH_SHORT).show()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package no.naiv.tilfluktsrom.ui
|
package no.naiv.tilfluktsrom.ui
|
||||||
|
|
||||||
|
import android.view.HapticFeedbackConstants
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
|
@ -63,6 +64,7 @@ class ShelterListAdapter(
|
||||||
binding.root.alpha = if (isSelected) 1.0f else 0.7f
|
binding.root.alpha = if (isSelected) 1.0f else 0.7f
|
||||||
|
|
||||||
binding.root.setOnClickListener {
|
binding.root.setOnClickListener {
|
||||||
|
it.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||||
val pos = adapterPosition
|
val pos = adapterPosition
|
||||||
if (pos != RecyclerView.NO_POSITION) {
|
if (pos != RecyclerView.NO_POSITION) {
|
||||||
selectPosition(pos)
|
selectPosition(pos)
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ function setupButtons(): void {
|
||||||
// Toggle map/compass
|
// Toggle map/compass
|
||||||
const toggleFab = document.getElementById('toggle-fab')!;
|
const toggleFab = document.getElementById('toggle-fab')!;
|
||||||
toggleFab.addEventListener('click', async () => {
|
toggleFab.addEventListener('click', async () => {
|
||||||
|
navigator.vibrate?.(10);
|
||||||
isCompassMode = !isCompassMode;
|
isCompassMode = !isCompassMode;
|
||||||
|
|
||||||
const mapContainer = document.getElementById('map-container')!;
|
const mapContainer = document.getElementById('map-container')!;
|
||||||
|
|
@ -112,6 +113,7 @@ function setupButtons(): void {
|
||||||
const cacheRetryBtn = document.getElementById('cache-retry-btn')!;
|
const cacheRetryBtn = document.getElementById('cache-retry-btn')!;
|
||||||
cacheRetryBtn.textContent = t('action_cache_now');
|
cacheRetryBtn.textContent = t('action_cache_now');
|
||||||
cacheRetryBtn.addEventListener('click', () => {
|
cacheRetryBtn.addEventListener('click', () => {
|
||||||
|
navigator.vibrate?.(10);
|
||||||
if (currentLocation && navigator.onLine) {
|
if (currentLocation && navigator.onLine) {
|
||||||
startCaching(currentLocation.latitude, currentLocation.longitude);
|
startCaching(currentLocation.latitude, currentLocation.longitude);
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +122,7 @@ function setupButtons(): void {
|
||||||
// Reset view button
|
// Reset view button
|
||||||
const resetBtn = document.getElementById('reset-view-btn')!;
|
const resetBtn = document.getElementById('reset-view-btn')!;
|
||||||
resetBtn.addEventListener('click', () => {
|
resetBtn.addEventListener('click', () => {
|
||||||
|
navigator.vibrate?.(10);
|
||||||
const selected = nearestShelters[selectedShelterIndex] ?? null;
|
const selected = nearestShelters[selectedShelterIndex] ?? null;
|
||||||
mapView.resetView(selected, currentLocation);
|
mapView.resetView(selected, currentLocation);
|
||||||
resetBtn.classList.remove('visible');
|
resetBtn.classList.remove('visible');
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ export function updateList(
|
||||||
item.appendChild(addressSpan);
|
item.appendChild(addressSpan);
|
||||||
item.appendChild(detailsSpan);
|
item.appendChild(detailsSpan);
|
||||||
item.addEventListener('click', () => {
|
item.addEventListener('click', () => {
|
||||||
|
navigator.vibrate?.(10);
|
||||||
onSelect?.(i);
|
onSelect?.(i);
|
||||||
});
|
});
|
||||||
container!.appendChild(item);
|
container!.appendChild(item);
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,8 @@ export function setStatus(text: string): void {
|
||||||
/** Set the refresh button click handler. */
|
/** Set the refresh button click handler. */
|
||||||
export function onRefreshClick(handler: () => void): void {
|
export function onRefreshClick(handler: () => void): void {
|
||||||
const btn = document.getElementById('refresh-btn');
|
const btn = document.getElementById('refresh-btn');
|
||||||
if (btn) btn.addEventListener('click', handler);
|
if (btn) btn.addEventListener('click', () => {
|
||||||
|
navigator.vibrate?.(10);
|
||||||
|
handler();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue