Skip to content

Commit c4f052e

Browse files
committed
fix: polish widget foundation
1 parent 395e16f commit c4f052e

34 files changed

Lines changed: 239 additions & 126 deletions

app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class HeadlinesPreviewContentTest {
5858
// Verify settings and preview section
5959
composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
6060
composeTestRule.onNodeWithTag("headlines_preview_carousel").assertExists()
61-
composeTestRule.onNodeWithTag("headline_card_small").assertExists()
61+
composeTestRule.onNodeWithTag("headline_card_wide").assertExists()
6262

6363
// Verify buttons
6464
composeTestRule.onNodeWithTag("buttons_row").assertExists()
@@ -164,7 +164,7 @@ class HeadlinesPreviewContentTest {
164164
composeTestRule.onNodeWithTag("divider").assertExists()
165165
composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
166166
composeTestRule.onNodeWithTag("headlines_preview_carousel").assertExists()
167-
composeTestRule.onNodeWithTag("headline_card_small").assertExists()
167+
composeTestRule.onNodeWithTag("headline_card_wide").assertExists()
168168
composeTestRule.onNodeWithTag("buttons_row").assertExists()
169169
composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
170170
composeTestRule.onNodeWithTag("WidgetSave").assertExists()

app/src/main/java/to/bitkit/appwidget/AppWidgetPreferencesStore.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import to.bitkit.data.dto.WeatherDTO
1919
import to.bitkit.data.dto.price.GraphPeriod
2020
import to.bitkit.data.dto.price.PriceDTO
2121
import to.bitkit.data.serializers.AppWidgetDataSerializer
22+
import to.bitkit.repositories.CurrencyRepo
2223
import javax.inject.Inject
2324
import javax.inject.Singleton
2425

@@ -32,6 +33,7 @@ private val Context.appWidgetDataStore: DataStore<AppWidgetData> by dataStore(
3233
interface AppWidgetEntryPoint {
3334
fun appWidgetPreferencesStore(): AppWidgetPreferencesStore
3435
fun appWidgetDataRepository(): AppWidgetDataRepository
36+
fun currencyRepo(): CurrencyRepo
3537
}
3638

3739
@Singleton

app/src/main/java/to/bitkit/appwidget/config/AppWidgetConfigActivity.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package to.bitkit.appwidget.config
22

3-
import android.app.Activity
43
import android.appwidget.AppWidgetManager
54
import android.content.Intent
65
import android.os.Bundle
@@ -20,6 +19,7 @@ import to.bitkit.appwidget.ui.price.PriceGlanceWidget
2019
import to.bitkit.appwidget.ui.weather.WeatherGlanceReceiver
2120
import to.bitkit.appwidget.ui.weather.WeatherGlanceWidget
2221
import to.bitkit.ui.theme.AppThemeSurface
22+
import to.bitkit.ui.utils.enableAppEdgeToEdge
2323
import to.bitkit.utils.Logger
2424

2525
@AndroidEntryPoint
@@ -34,6 +34,7 @@ class AppWidgetConfigActivity : ComponentActivity() {
3434

3535
override fun onCreate(savedInstanceState: Bundle?) {
3636
super.onCreate(savedInstanceState)
37+
enableAppEdgeToEdge()
3738

3839
val appWidgetId = intent?.extras?.getInt(
3940
AppWidgetManager.EXTRA_APPWIDGET_ID,
@@ -58,7 +59,9 @@ class AppWidgetConfigActivity : ComponentActivity() {
5859
onConfirm = {
5960
when (viewModel.uiState.value.type) {
6061
AppWidgetType.PRICE -> PriceGlanceWidget().updateAll(this@AppWidgetConfigActivity)
61-
AppWidgetType.HEADLINES -> HeadlinesGlanceWidget().updateAll(this@AppWidgetConfigActivity)
62+
AppWidgetType.HEADLINES -> HeadlinesGlanceWidget().updateAll(
63+
this@AppWidgetConfigActivity,
64+
)
6265
AppWidgetType.BLOCKS -> BlocksGlanceWidget().updateAll(this@AppWidgetConfigActivity)
6366
AppWidgetType.FACTS -> Unit
6467
AppWidgetType.WEATHER -> WeatherGlanceWidget().updateAll(this@AppWidgetConfigActivity)
@@ -68,7 +71,7 @@ class AppWidgetConfigActivity : ComponentActivity() {
6871
AppWidgetManager.EXTRA_APPWIDGET_ID,
6972
appWidgetId,
7073
)
71-
setResult(Activity.RESULT_OK, result)
74+
setResult(RESULT_OK, result)
7275
finish()
7376
},
7477
onCancel = { finish() },

app/src/main/java/to/bitkit/appwidget/config/AppWidgetConfigViewModel.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import to.bitkit.appwidget.model.HomeHeadlinePreferences
2020
import to.bitkit.appwidget.model.HomePricePreferences
2121
import to.bitkit.appwidget.model.HomeWeatherPreferences
2222
import to.bitkit.data.dto.FeeCondition
23+
import to.bitkit.data.dto.WeatherDTO
2324
import to.bitkit.data.dto.price.GraphPeriod
2425
import to.bitkit.data.dto.price.TradingPair
2526
import to.bitkit.models.widget.ArticleModel
@@ -29,6 +30,7 @@ import to.bitkit.models.widget.PricePreferences
2930
import to.bitkit.models.widget.WeatherDataOption
3031
import to.bitkit.models.widget.WeatherPreferences
3132
import to.bitkit.models.widget.toArticleModel
33+
import to.bitkit.repositories.CurrencyRepo
3234
import to.bitkit.ui.screens.widgets.blocks.WeatherModel
3335
import to.bitkit.ui.screens.widgets.blocks.toWeatherModel
3436
import to.bitkit.utils.Logger
@@ -39,6 +41,7 @@ import javax.inject.Inject
3941
class AppWidgetConfigViewModel @Inject constructor(
4042
private val preferencesStore: AppWidgetPreferencesStore,
4143
private val dataRepository: AppWidgetDataRepository,
44+
private val currencyRepo: CurrencyRepo,
4245
) : ViewModel() {
4346

4447
companion object {
@@ -53,7 +56,7 @@ class AppWidgetConfigViewModel @Inject constructor(
5356
val entry = preferencesStore.getEntry(appWidgetId)
5457
val data = preferencesStore.data.first()
5558
val previewArticle = data.cachedArticles.randomOrNull()?.toArticleModel() ?: DEFAULT_PREVIEW_ARTICLE
56-
val previewWeather = data.cachedWeather?.toWeatherModel() ?: DEFAULT_PREVIEW_WEATHER
59+
val previewWeather = data.cachedWeather?.toPreviewWeather() ?: DEFAULT_PREVIEW_WEATHER
5760

5861
_uiState.update {
5962
it.copy(
@@ -72,7 +75,7 @@ class AppWidgetConfigViewModel @Inject constructor(
7275
dataRepository.fetchWeather()
7376
.onSuccess { fetched ->
7477
preferencesStore.cacheWeather(fetched)
75-
_uiState.update { it.copy(previewWeather = fetched.toWeatherModel()) }
78+
_uiState.update { it.copy(previewWeather = fetched.toPreviewWeather()) }
7679
}
7780
.onFailure { Logger.warn("Failed to fetch weather for config preview", it, context = TAG) }
7881
}
@@ -239,6 +242,10 @@ class AppWidgetConfigViewModel @Inject constructor(
239242
.onSuccess { preferencesStore.cacheWeather(it) }
240243
.onFailure { Logger.warn("Failed to fetch initial weather", it, context = TAG) }
241244
}
245+
246+
private fun WeatherDTO.toPreviewWeather() = toWeatherModel(
247+
currentFee = currencyRepo.formatSatsAsFiatWithSymbol(avgFeeSats, withSpace = true) ?: currentFee,
248+
)
242249
}
243250

244251
private val DEFAULT_PREVIEW_ARTICLE = ArticleModel(

app/src/main/java/to/bitkit/appwidget/config/BlocksConfigContent.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package to.bitkit.appwidget.config
22

33
import androidx.annotation.DrawableRes
4-
import androidx.compose.foundation.background
54
import androidx.compose.foundation.layout.Arrangement
65
import androidx.compose.foundation.layout.Column
76
import androidx.compose.foundation.layout.Row
@@ -61,10 +60,7 @@ internal fun BlocksConfigContent(
6160
)
6261
}
6362

64-
ScreenColumn(
65-
noBackground = true,
66-
modifier = Modifier.background(Colors.Gray7)
67-
) {
63+
ScreenColumn {
6864
AppTopBar(
6965
titleText = stringResource(R.string.widgets__blocks__name),
7066
onBackClick = onCancel,

app/src/main/java/to/bitkit/appwidget/config/HeadlinesConfigContent.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package to.bitkit.appwidget.config
22

3-
import androidx.compose.foundation.background
43
import androidx.compose.foundation.layout.Arrangement
54
import androidx.compose.foundation.layout.Column
65
import androidx.compose.foundation.layout.Row
@@ -43,10 +42,7 @@ internal fun HeadlinesConfigContent(
4342
val prefs = state.headlinePreferences
4443
val previewArticle = state.previewArticle
4544

46-
ScreenColumn(
47-
noBackground = true,
48-
modifier = Modifier.background(Colors.Gray7)
49-
) {
45+
ScreenColumn {
5046
AppTopBar(
5147
titleText = stringResource(R.string.widgets__news__name),
5248
onBackClick = onCancel,

app/src/main/java/to/bitkit/appwidget/config/PriceConfigContent.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package to.bitkit.appwidget.config
22

3-
import androidx.compose.foundation.background
43
import androidx.compose.foundation.clickable
54
import androidx.compose.foundation.layout.Arrangement
65
import androidx.compose.foundation.layout.Column
@@ -44,10 +43,7 @@ internal fun PriceConfigContent(
4443
val prefs = state.pricePreferences
4544
val selectedPair = prefs.enabledPairs.firstOrNull() ?: TradingPair.BTC_USD
4645

47-
ScreenColumn(
48-
noBackground = true,
49-
modifier = Modifier.background(Colors.Gray7)
50-
) {
46+
ScreenColumn {
5147
AppTopBar(
5248
titleText = stringResource(R.string.widgets__price__name),
5349
onBackClick = onCancel,

app/src/main/java/to/bitkit/appwidget/config/WeatherConfigContent.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package to.bitkit.appwidget.config
22

3-
import androidx.compose.foundation.background
43
import androidx.compose.foundation.layout.Arrangement
54
import androidx.compose.foundation.layout.Column
65
import androidx.compose.foundation.layout.Row
@@ -37,15 +36,11 @@ internal fun WeatherConfigContent(
3736
onReset: () -> Unit,
3837
onSave: () -> Unit,
3938
onCancel: () -> Unit,
40-
modifier: Modifier = Modifier,
4139
) {
4240
val prefs = state.weatherPreferences
4341
val weather = state.previewWeather
4442

45-
ScreenColumn(
46-
noBackground = true,
47-
modifier = modifier.background(Colors.Gray7)
48-
) {
43+
ScreenColumn {
4944
AppTopBar(
5045
titleText = stringResource(R.string.widgets__weather__name),
5146
onBackClick = onCancel,

app/src/main/java/to/bitkit/appwidget/ui/facts/FactsGlanceContent.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package to.bitkit.appwidget.ui.facts
22

3+
import android.content.Intent
34
import androidx.compose.runtime.Composable
45
import androidx.compose.ui.unit.dp
56
import androidx.glance.GlanceModifier
67
import androidx.glance.Image
78
import androidx.glance.ImageProvider
89
import androidx.glance.LocalContext
910
import androidx.glance.LocalSize
11+
import androidx.glance.appwidget.action.actionStartActivity
1012
import androidx.glance.layout.Alignment
1113
import androidx.glance.layout.Box
1214
import androidx.glance.layout.fillMaxSize
@@ -18,6 +20,7 @@ import to.bitkit.appwidget.ui.components.CaptionB
1820
import to.bitkit.appwidget.ui.components.GlanceLayoutDimens
1921
import to.bitkit.appwidget.ui.components.GlanceWidgetScaffold
2022
import to.bitkit.appwidget.ui.theme.GlanceTextStyles
23+
import to.bitkit.ui.MainActivity
2124

2225
private val BADGE_SIZE = 32.dp
2326
private val BADGE_RESERVED_END = 40.dp
@@ -28,8 +31,11 @@ fun FactsGlanceContent(
2831
fact: String?,
2932
) {
3033
val context = LocalContext.current
34+
val openAppIntent = Intent(context, MainActivity::class.java).apply {
35+
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
36+
}
3137

32-
GlanceWidgetScaffold {
38+
GlanceWidgetScaffold(onClick = actionStartActivity(openAppIntent)) {
3339
if (fact == null) {
3440
CaptionB(text = context.getString(R.string.appwidget__loading))
3541
return@GlanceWidgetScaffold

app/src/main/java/to/bitkit/appwidget/ui/weather/WeatherGlanceWidget.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package to.bitkit.appwidget.ui.weather
33
import android.content.Context
44
import androidx.compose.runtime.collectAsState
55
import androidx.compose.runtime.getValue
6+
import androidx.compose.runtime.remember
67
import androidx.glance.GlanceId
78
import androidx.glance.appwidget.GlanceAppWidget
89
import androidx.glance.appwidget.GlanceAppWidgetManager
@@ -14,6 +15,8 @@ import to.bitkit.appwidget.model.AppWidgetData
1415
import to.bitkit.appwidget.model.AppWidgetEntry
1516
import to.bitkit.appwidget.model.AppWidgetType
1617
import to.bitkit.appwidget.ui.components.GlanceLayoutDimens
18+
import to.bitkit.data.dto.WeatherDTO
19+
import to.bitkit.repositories.CurrencyRepo
1720
import to.bitkit.ui.screens.widgets.blocks.toWeatherModel
1821

1922
class WeatherGlanceWidget : GlanceAppWidget() {
@@ -23,16 +26,20 @@ class WeatherGlanceWidget : GlanceAppWidget() {
2326
)
2427

2528
override suspend fun provideGlance(context: Context, id: GlanceId) {
26-
val store = EntryPointAccessors
29+
val accessor = EntryPointAccessors
2730
.fromApplication(context, AppWidgetEntryPoint::class.java)
28-
.appWidgetPreferencesStore()
31+
val store = accessor.appWidgetPreferencesStore()
32+
val currencyRepo = accessor.currencyRepo()
2933
val appWidgetId = GlanceAppWidgetManager(context).getAppWidgetId(id)
3034

3135
provideContent {
3236
val data by store.data.collectAsState(initial = AppWidgetData())
37+
val currencyState by currencyRepo.currencyState.collectAsState()
3338
val entry = data.entries.find { it.appWidgetId == appWidgetId }
3439
?: AppWidgetEntry(appWidgetId = appWidgetId, type = AppWidgetType.WEATHER)
35-
val weather = data.cachedWeather?.toWeatherModel()
40+
val weather = remember(data.cachedWeather, currencyState) {
41+
data.cachedWeather?.toGlanceWeather(currencyRepo)
42+
}
3643

3744
WeatherGlanceContent(
3845
entry = entry,
@@ -48,4 +55,8 @@ class WeatherGlanceWidget : GlanceAppWidget() {
4855
.appWidgetPreferencesStore()
4956
.unregisterWidget(appWidgetId)
5057
}
58+
59+
private fun WeatherDTO.toGlanceWeather(currencyRepo: CurrencyRepo) = toWeatherModel(
60+
currentFee = currencyRepo.formatSatsAsFiatWithSymbol(avgFeeSats, withSpace = true) ?: currentFee,
61+
)
5162
}

0 commit comments

Comments
 (0)