From 435b730f3b6f9ea10c370e3105c506e8166d0887 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 21 Dec 2024 13:03:07 +0800 Subject: [PATCH] :recycle: Android use background info too --- android/app/src/main/AndroidManifest.xml | 11 ++- .../solsynth/solian/widgets/CheckInWidget.kt | 62 ++++++++------ .../widgets/FeaturedPostWidgetReceiver.kt | 8 -- ...turedPostWidget.kt => RandomPostWidget.kt} | 85 +++++++------------ .../widgets/RandomPostWidgetReceiver.kt | 8 ++ ...post_widget.xml => random_post_widget.xml} | 2 +- android/build.gradle | 9 ++ lib/providers/widget.dart | 6 +- 8 files changed, 95 insertions(+), 96 deletions(-) delete mode 100644 android/app/src/main/kotlin/dev/solsynth/solian/widgets/FeaturedPostWidgetReceiver.kt rename android/app/src/main/kotlin/dev/solsynth/solian/widgets/{FeaturedPostWidget.kt => RandomPostWidget.kt} (73%) create mode 100644 android/app/src/main/kotlin/dev/solsynth/solian/widgets/RandomPostWidgetReceiver.kt rename android/app/src/main/res/xml/{featured_post_widget.xml => random_post_widget.xml} (90%) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 2d2ec07..f218860 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,6 +27,11 @@ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> + + + + + @@ -100,15 +105,15 @@ android:name="android.appwidget.provider" android:resource="@xml/check_in_widget" /> - + android:resource="@xml/random_post_widget" /> diff --git a/android/app/src/main/kotlin/dev/solsynth/solian/widgets/CheckInWidget.kt b/android/app/src/main/kotlin/dev/solsynth/solian/widgets/CheckInWidget.kt index 80254d6..132cde4 100644 --- a/android/app/src/main/kotlin/dev/solsynth/solian/widgets/CheckInWidget.kt +++ b/android/app/src/main/kotlin/dev/solsynth/solian/widgets/CheckInWidget.kt @@ -1,10 +1,12 @@ import android.content.Context +import android.net.Uri import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.glance.GlanceId import androidx.glance.GlanceModifier +import androidx.glance.action.clickable import androidx.glance.appwidget.GlanceAppWidget import androidx.glance.appwidget.provideContent import androidx.glance.background @@ -26,11 +28,11 @@ import com.google.gson.GsonBuilder import dev.solsynth.solian.data.InstantAdapter import dev.solsynth.solian.data.SolarCheckInRecord import java.time.Instant +import java.time.LocalDate import java.time.OffsetDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter - class CheckInWidget : GlanceAppWidget() { override val stateDefinition: GlanceStateDefinition<*>? get() = HomeWidgetGlanceStateDefinition() @@ -51,7 +53,7 @@ class CheckInWidget : GlanceAppWidget() { val resultTierSymbols = listOf("大凶", "凶", "中平", "吉", "大吉") val prefs = currentState.preferences - val checkInRaw = prefs.getString("today_check_in", null) + val checkInRaw = prefs.getString("pas_check_in_record", null) Column( modifier = GlanceModifier @@ -61,33 +63,43 @@ class CheckInWidget : GlanceAppWidget() { .padding(16.dp) ) { if (checkInRaw != null) { - val checkIn = gson.fromJson(checkInRaw, SolarCheckInRecord::class.java) + val checkIn: SolarCheckInRecord = + gson.fromJson(checkInRaw, SolarCheckInRecord::class.java) val dateFormatter = DateTimeFormatter.ofPattern("EEE, MM/dd") - Column { - Text( - text = resultTierSymbols[checkIn.resultTier], - style = TextStyle(fontSize = 25.sp, fontFamily = FontFamily.Serif) - ) - Text( - text = "+${checkIn.resultExperience} EXP", - style = TextStyle(fontSize = 15.sp, fontFamily = FontFamily.Monospace) - ) + val checkDate = checkIn.createdAt.atZone(ZoneId.of("UTC")).toLocalDate() + val currentDate = LocalDate.now() + if (checkDate.isEqual(currentDate)) { + Column { + Text( + text = resultTierSymbols[checkIn.resultTier], + style = TextStyle(fontSize = 25.sp, fontFamily = FontFamily.Serif) + ) + Text( + text = "+${checkIn.resultExperience} EXP", + style = TextStyle(fontSize = 15.sp, fontFamily = FontFamily.Monospace) + ) + } + Spacer(modifier = GlanceModifier.height(8.dp)) + Row(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = OffsetDateTime.ofInstant( + checkIn.createdAt, + ZoneId.systemDefault() + ) + .format(dateFormatter), + style = TextStyle(fontSize = 13.sp) + ) + } + + return@Column; } - Spacer(modifier = GlanceModifier.height(8.dp)) - Row(horizontalAlignment = Alignment.CenterHorizontally) { - Text( - text = OffsetDateTime.ofInstant(checkIn.createdAt, ZoneId.systemDefault()) - .format(dateFormatter), - style = TextStyle(fontSize = 13.sp) - ) - } - } else { - Text( - text = "You haven't checked in today", - style = TextStyle(fontSize = 15.sp) - ) } } + + Text( + text = "You haven't checked in today", + style = TextStyle(fontSize = 15.sp) + ) } } diff --git a/android/app/src/main/kotlin/dev/solsynth/solian/widgets/FeaturedPostWidgetReceiver.kt b/android/app/src/main/kotlin/dev/solsynth/solian/widgets/FeaturedPostWidgetReceiver.kt deleted file mode 100644 index 03dab9d..0000000 --- a/android/app/src/main/kotlin/dev/solsynth/solian/widgets/FeaturedPostWidgetReceiver.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.solsynth.solian.widgets - -import FeaturedPostWidget -import HomeWidgetGlanceWidgetReceiver - -class FeaturedPostWidgetReceiver : HomeWidgetGlanceWidgetReceiver() { - override val glanceAppWidget = FeaturedPostWidget() -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/dev/solsynth/solian/widgets/FeaturedPostWidget.kt b/android/app/src/main/kotlin/dev/solsynth/solian/widgets/RandomPostWidget.kt similarity index 73% rename from android/app/src/main/kotlin/dev/solsynth/solian/widgets/FeaturedPostWidget.kt rename to android/app/src/main/kotlin/dev/solsynth/solian/widgets/RandomPostWidget.kt index 78805d5..b83aab9 100644 --- a/android/app/src/main/kotlin/dev/solsynth/solian/widgets/FeaturedPostWidget.kt +++ b/android/app/src/main/kotlin/dev/solsynth/solian/widgets/RandomPostWidget.kt @@ -1,6 +1,7 @@ import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory +import android.net.Uri import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @@ -10,10 +11,12 @@ import androidx.glance.GlanceModifier import androidx.glance.GlanceTheme import androidx.glance.Image import androidx.glance.ImageProvider +import androidx.glance.action.clickable import androidx.glance.appwidget.GlanceAppWidget import androidx.glance.appwidget.cornerRadius import androidx.glance.appwidget.provideContent import androidx.glance.background +import androidx.glance.currentState import androidx.glance.layout.Alignment import androidx.glance.layout.Column import androidx.glance.layout.ContentScale @@ -30,23 +33,12 @@ import androidx.glance.text.FontFamily import androidx.glance.text.FontWeight import androidx.glance.text.Text import androidx.glance.text.TextStyle -import coil3.Image -import coil3.compose.AsyncImagePainter -import coil3.compose.rememberAsyncImagePainter -import coil3.imageLoader -import coil3.request.ErrorResult -import coil3.request.ImageRequest -import coil3.request.SuccessResult -import coil3.request.crossfade -import coil3.toBitmap import com.google.gson.FieldNamingPolicy import com.google.gson.GsonBuilder -import com.google.gson.reflect.TypeToken +import dev.solsynth.solian.MainActivity import dev.solsynth.solian.data.InstantAdapter -import dev.solsynth.solian.data.SolarPagination import dev.solsynth.solian.data.SolarPost -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import es.antonborri.home_widget.actionStartActivity import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response @@ -56,31 +48,16 @@ import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter -class FeaturedPostWidget : GlanceAppWidget() { +class RandomPostWidget : GlanceAppWidget() { override val stateDefinition: GlanceStateDefinition<*>? get() = HomeWidgetGlanceStateDefinition() private val defaultUrl = "https://api.sn.solsynth.dev" override suspend fun provideGlance(context: Context, id: GlanceId) { - // TODO: Fix this -// val state = currentState() -// val prefs = state.preferences -// var baseUrl = prefs.getString("nex_server_url", null) ?: defaultUrl -// if (baseUrl.startsWith("\"") && baseUrl.endsWith("\"")) { -// baseUrl = baseUrl.substring(1, baseUrl.length - 1) -// } - - val postData = withContext(Dispatchers.IO) { fetchPostRandomly(defaultUrl) } - val avatarImage = withContext(Dispatchers.IO) { - postData?.publisher?.avatar?.let { - loadImageFromUrl(it) - } - } - provideContent { GlanceTheme { - GlanceContent(context, postData, avatarImage) + GlanceContent(context, currentState(), null) } } } @@ -109,40 +86,37 @@ class FeaturedPostWidget : GlanceAppWidget() { } } - private fun fetchPostRandomly(baseUrl: String): SolarPost? { + @Composable + private fun GlanceContent( + context: Context, + currentState: HomeWidgetGlanceState, + avatar: Bitmap? + ) { + val prefs = currentState.preferences + val postRaw = prefs.getString("int_random_post", null) + val gson = GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .registerTypeAdapter(Instant::class.java, InstantAdapter()) .create() - val type = object : TypeToken>() {}.type - val request = Request.Builder() - .url("$baseUrl/cgi/co/recommendations/shuffle?take=1") - .build() + val data: SolarPost? = postRaw?.let { postRaw -> + gson.fromJson(postRaw, SolarPost::class.java) + } ?: null; - return try { - val response: Response = client.newCall(request).execute() - if (response.isSuccessful) { - val body = response.body?.string() - val resp = gson.fromJson>(body, type) - resp.data.firstOrNull() - } else { - null - } - } catch (e: IOException) { - null - } - } - - @Composable - private fun GlanceContent(context: Context, data: SolarPost?, avatar: Bitmap?) { Column( modifier = GlanceModifier .fillMaxWidth() .fillMaxHeight() .background(Color.White) .padding(16.dp) + .clickable( + onClick = actionStartActivity( + context, + Uri.parse("https://sn.solsynth.dev/posts/${data!!.id}") + ) + ) ) { if (data != null) { Row(verticalAlignment = Alignment.CenterVertically) { @@ -154,10 +128,9 @@ class FeaturedPostWidget : GlanceAppWidget() { .cornerRadius(18.dp), contentScale = ContentScale.Crop ) + Spacer(modifier = GlanceModifier.width(8.dp)) } - Spacer(modifier = GlanceModifier.width(8.dp)) - Text( text = data.publisher.nick, style = TextStyle(fontSize = 15.sp) @@ -174,13 +147,13 @@ class FeaturedPostWidget : GlanceAppWidget() { if (data.body.title != null) { Text( text = data.body.title, - style = TextStyle(fontSize = 25.sp, fontFamily = FontFamily.Serif) + style = TextStyle(fontSize = 25.sp) ) } if (data.body.description != null) { Text( text = data.body.description, - style = TextStyle(fontSize = 19.sp, fontFamily = FontFamily.Serif) + style = TextStyle(fontSize = 19.sp) ) } @@ -203,7 +176,7 @@ class FeaturedPostWidget : GlanceAppWidget() { ) Text( - "Solar Network Featured Post", + "#${data.id}", style = TextStyle(fontSize = 11.sp, fontWeight = FontWeight.Bold), ) diff --git a/android/app/src/main/kotlin/dev/solsynth/solian/widgets/RandomPostWidgetReceiver.kt b/android/app/src/main/kotlin/dev/solsynth/solian/widgets/RandomPostWidgetReceiver.kt new file mode 100644 index 0000000..9966fc7 --- /dev/null +++ b/android/app/src/main/kotlin/dev/solsynth/solian/widgets/RandomPostWidgetReceiver.kt @@ -0,0 +1,8 @@ +package dev.solsynth.solian.widgets + +import RandomPostWidget +import HomeWidgetGlanceWidgetReceiver + +class RandomPostWidgetReceiver : HomeWidgetGlanceWidgetReceiver() { + override val glanceAppWidget = RandomPostWidget() +} \ No newline at end of file diff --git a/android/app/src/main/res/xml/featured_post_widget.xml b/android/app/src/main/res/xml/random_post_widget.xml similarity index 90% rename from android/app/src/main/res/xml/featured_post_widget.xml rename to android/app/src/main/res/xml/random_post_widget.xml index 5043a84..9ef00c6 100644 --- a/android/app/src/main/res/xml/featured_post_widget.xml +++ b/android/app/src/main/res/xml/random_post_widget.xml @@ -1,6 +1,6 @@ diff --git a/android/build.gradle b/android/build.gradle index d2ffbff..9390a40 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -3,6 +3,15 @@ allprojects { google() mavenCentral() } + configurations.all { + resolutionStrategy { + eachDependency { + if ((requested.group == "androidx.work") && (requested.name.startsWith("work-runtime"))) { + useVersion("2.9.1") + } + } + } + } } rootProject.buildDir = "../build" diff --git a/lib/providers/widget.dart b/lib/providers/widget.dart index 53492e3..56e47dd 100644 --- a/lib/providers/widget.dart +++ b/lib/providers/widget.dart @@ -34,7 +34,7 @@ class HomeWidgetProvider { ); } } else if (Platform.isAndroid) { - const widgets = ["FeaturedPostWidget", "CheckInWidget"]; + const widgets = ["RandomPostWidget", "CheckInWidget"]; for (final widget in widgets) { await HomeWidget.updateWidget( androidName: "${widget}Receiver", @@ -53,7 +53,7 @@ Future widgetUpdateRandomPost() async { await HomeWidget.updateWidget( name: "SolarRandomPostWidget", iOSName: "SolarRandomPostWidget", - androidName: "FeaturedPostWidgetReceiver", - qualifiedAndroidName: "dev.solsynth.solian.widgets.FeaturedPostWidgetReceiver", + androidName: "RandomPostWidgetReceiver", + qualifiedAndroidName: "dev.solsynth.solian.widgets.RandomPostWidgetReceiver", ); }