diff options
| author | Claude <noreply@anthropic.com> | 2026-04-11 08:31:11 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-04-11 08:31:11 +0000 |
| commit | 45f56beef36a9888aef3773ac10f089c3d2c3b00 (patch) | |
| tree | 3b79f6165ab80125292544a4f327ddee1dafea8f /android-app/app/src/main | |
| parent | d5e819e869f3b15da0f28ba2d8525e825afeb5a0 (diff) | |
Remove bad ASA external links; fix conditions not loading on startup
- Strip all three unverified external link cards (ASA courses, ASA online,
Quizlet flashcards) from the Learn tab — asa.com is a Brazilian financial
site, not the American Sailing Association
- Remove dead openUrl() click handlers and unused Intent/Uri imports from LearnFragment
- Parallelize the two sequential API calls in fetchCurrentConditions so the HUD
populates in ~half the time (weather + marine fetched concurrently via async/await)
- Add onFailure logging in loadConditions so errors are visible in logcat instead
of silently swallowed
- Eagerly call loadConditions in the setStyle callback as a startup backstop: the
camera-idle listener fires before GPS fixes and the initial position may be (0,0),
so this guarantees a real fetch once the style is ready with a valid camera position
https://claude.ai/code/session_01HXPjBsogsJVRwCiekDGkJX
Diffstat (limited to 'android-app/app/src/main')
5 files changed, 17 insertions, 171 deletions
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt index e6355bd..01971a6 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt @@ -429,6 +429,13 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { val windArrowBitmap = rasterizeDrawable(R.drawable.ic_wind_arrow) mapHandler?.setupLayers(style, anchorBitmap, arrowBitmap, userBitmap) mapHandler?.setupWindLayer(style, windArrowBitmap) + // Eagerly load conditions at style-ready time so the HUD is never blank + // on startup — the camera-idle may fire before GPS fixes, this is the backstop. + maplibreMap.cameraPosition.target?.let { center -> + if (center.latitude != 0.0 || center.longitude != 0.0) { + viewModel.loadConditions(center.latitude, center.longitude) + } + } } maplibreMap.addOnCameraIdleListener { diff --git a/android-app/app/src/main/kotlin/org/terst/nav/data/repository/WeatherRepository.kt b/android-app/app/src/main/kotlin/org/terst/nav/data/repository/WeatherRepository.kt index dc47a20..26c5da7 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/data/repository/WeatherRepository.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/data/repository/WeatherRepository.kt @@ -1,5 +1,7 @@ package org.terst.nav.data.repository +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope import org.terst.nav.data.api.MarineApiService import org.terst.nav.data.api.WeatherApiService import org.terst.nav.data.model.ForecastItem @@ -52,8 +54,11 @@ class WeatherRepository( */ suspend fun fetchCurrentConditions(lat: Double, lon: Double): Result<MarineConditions> = runCatching { - val weather = weatherApi.getWeatherForecast(lat, lon, forecastDays = 1) - val marine = marineApi.getMarineForecast(lat, lon) + coroutineScope { + val weatherDeferred = async { weatherApi.getWeatherForecast(lat, lon, forecastDays = 1) } + val marineDeferred = async { marineApi.getMarineForecast(lat, lon) } + val weather = weatherDeferred.await() + val marine = marineDeferred.await() val w = weather.hourly val m = marine.hourly MarineConditions( @@ -68,6 +73,7 @@ class WeatherRepository( currentSpeedKt = m.oceanCurrentVelocity.firstOrNull()?.let { it * 1.94384 }, currentDirDeg = m.oceanCurrentDirection.firstOrNull() ) + } } /** diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt index 9bd660b..df31949 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt @@ -127,6 +127,7 @@ class MainViewModel( viewModelScope.launch { repository.fetchCurrentConditions(lat, lon) .onSuccess { _marineConditions.value = it } + .onFailure { android.util.Log.e("Nav", "fetchCurrentConditions failed", it) } } } diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt index da3f020..418246c 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt @@ -1,7 +1,5 @@ package org.terst.nav.ui.learn -import android.content.Intent -import android.net.Uri import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -36,16 +34,6 @@ class LearnFragment : Fragment() { openDoc("docs/sailing_reference.md") } - // ASA / external links — open in browser - view.findViewById<MaterialCardView>(R.id.card_asa_courses).setOnClickListener { - openUrl("https://www.asa.com/courses/") - } - view.findViewById<MaterialCardView>(R.id.card_asa_online).setOnClickListener { - openUrl("https://www.asa.com/online-courses/") - } - view.findViewById<MaterialCardView>(R.id.card_flashcards).setOnClickListener { - openUrl("https://quizlet.com/subject/sailing/") - } } private fun openDoc(path: String) { @@ -54,8 +42,4 @@ class LearnFragment : Fragment() { .addToBackStack(null) .commit() } - - private fun openUrl(url: String) { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) - } } diff --git a/android-app/app/src/main/res/layout/fragment_learn.xml b/android-app/app/src/main/res/layout/fragment_learn.xml index 8813ba2..fa18c5d 100644 --- a/android-app/app/src/main/res/layout/fragment_learn.xml +++ b/android-app/app/src/main/res/layout/fragment_learn.xml @@ -158,7 +158,7 @@ android:id="@+id/card_sailing_reference" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="24dp" + android:layout_marginBottom="8dp" app:cardCornerRadius="12dp" app:cardElevation="2dp"> @@ -201,157 +201,5 @@ </LinearLayout> </com.google.android.material.card.MaterialCardView> - <!-- ── ASA Training & Practice (external links) ──────────── --> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="ASA TRAINING & PRACTICE" - android:textSize="11sp" - android:textAllCaps="true" - android:letterSpacing="0.12" - android:textColor="?attr/colorOnSurfaceVariant" - android:layout_marginBottom="8dp" /> - - <com.google.android.material.card.MaterialCardView - android:id="@+id/card_asa_courses" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="8dp" - app:cardCornerRadius="12dp" - app:cardElevation="2dp"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:padding="16dp" - android:gravity="center_vertical"> - - <LinearLayout - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:orientation="vertical"> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="ASA Course Catalog" - android:textAppearance="?attr/textAppearanceTitleSmall" /> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="ASA 101–114: keelboat through offshore passagemaking" - android:textSize="12sp" - android:textColor="?attr/colorOnSurfaceVariant" - android:layout_marginTop="2dp" /> - - </LinearLayout> - - <ImageView - android:layout_width="18dp" - android:layout_height="18dp" - android:src="@drawable/ic_open_in_new" - android:tint="?attr/colorOnSurfaceVariant" - android:contentDescription="Opens in browser" /> - - </LinearLayout> - </com.google.android.material.card.MaterialCardView> - - <com.google.android.material.card.MaterialCardView - android:id="@+id/card_asa_online" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="8dp" - app:cardCornerRadius="12dp" - app:cardElevation="2dp"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:padding="16dp" - android:gravity="center_vertical"> - - <LinearLayout - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:orientation="vertical"> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="ASA Online Learning" - android:textAppearance="?attr/textAppearanceTitleSmall" /> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Self-paced online courses and study guides" - android:textSize="12sp" - android:textColor="?attr/colorOnSurfaceVariant" - android:layout_marginTop="2dp" /> - - </LinearLayout> - - <ImageView - android:layout_width="18dp" - android:layout_height="18dp" - android:src="@drawable/ic_open_in_new" - android:tint="?attr/colorOnSurfaceVariant" - android:contentDescription="Opens in browser" /> - - </LinearLayout> - </com.google.android.material.card.MaterialCardView> - - <com.google.android.material.card.MaterialCardView - android:id="@+id/card_flashcards" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="8dp" - app:cardCornerRadius="12dp" - app:cardElevation="2dp"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:padding="16dp" - android:gravity="center_vertical"> - - <LinearLayout - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:orientation="vertical"> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Sailing Flashcards" - android:textAppearance="?attr/textAppearanceTitleSmall" /> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Quizlet decks for knots, rules, lights & signals" - android:textSize="12sp" - android:textColor="?attr/colorOnSurfaceVariant" - android:layout_marginTop="2dp" /> - - </LinearLayout> - - <ImageView - android:layout_width="18dp" - android:layout_height="18dp" - android:src="@drawable/ic_open_in_new" - android:tint="?attr/colorOnSurfaceVariant" - android:contentDescription="Opens in browser" /> - - </LinearLayout> - </com.google.android.material.card.MaterialCardView> - </LinearLayout> </ScrollView> |
