Compare commits
	
		
			4 Commits
		
	
	
		
			4daff41b3e
			...
			2eb1f4b52b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2eb1f4b52b | |||
| 00678c0ac8 | |||
| abc21f858b | |||
| d67e33a41d | 
| @@ -9,14 +9,31 @@ plugins { | ||||
|     id "dev.flutter.flutter-gradle-plugin" | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
|     implementation "androidx.glance:glance:1.1.1" | ||||
|     implementation "androidx.glance:glance-appwidget:1.1.1" | ||||
|     implementation 'androidx.compose.foundation:foundation-layout-android:1.7.6' | ||||
|     implementation 'com.google.code.gson:gson:2.10.1' | ||||
|     implementation 'io.coil-kt.coil3:coil-compose:3.0.4' | ||||
|     implementation 'io.coil-kt.coil3:coil-network-okhttp:3.0.4' | ||||
| } | ||||
|  | ||||
| android { | ||||
|     buildFeatures { | ||||
|         compose true | ||||
|     } | ||||
|  | ||||
|     namespace = "dev.solsynth.solian" | ||||
|     compileSdk = flutter.compileSdkVersion | ||||
|     ndkVersion = "27.0.12077973" | ||||
|  | ||||
|     compileOptions { | ||||
|       sourceCompatibility JavaVersion.VERSION_17 | ||||
|       targetCompatibility JavaVersion.VERSION_17 | ||||
|         sourceCompatibility JavaVersion.VERSION_17 | ||||
|         targetCompatibility JavaVersion.VERSION_17 | ||||
|     } | ||||
|  | ||||
|     composeOptions { | ||||
|         kotlinCompilerExtensionVersion = "1.4.8" | ||||
|     } | ||||
|  | ||||
|     kotlinOptions { | ||||
| @@ -24,11 +41,8 @@ android { | ||||
|     } | ||||
|  | ||||
|     defaultConfig { | ||||
|         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). | ||||
|         applicationId = "dev.solsynth.solian" | ||||
|         // You can update the following values to match your application needs. | ||||
|         // For more information, see: https://flutter.dev/to/review-gradle-config. | ||||
|         minSdk = flutter.minSdkVersion | ||||
|         minSdk = 26 | ||||
|         targetSdk = flutter.targetSdkVersion | ||||
|         versionCode = flutter.versionCode | ||||
|         versionName = flutter.versionName | ||||
|   | ||||
| @@ -52,12 +52,22 @@ | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.SEND" /> | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
|                 <data android:mimeType="*/*" /> | ||||
|                 <data android:mimeType="image/*" /> | ||||
|             </intent-filter> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.SEND_MULTIPLE" /> | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
|                 <data android:mimeType="*/*" /> | ||||
|                 <data android:mimeType="image/*" /> | ||||
|             </intent-filter> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.SEND" /> | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
|                 <data android:mimeType="video/*" /> | ||||
|             </intent-filter> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.SEND_MULTIPLE" /> | ||||
|                 <category android:name="android.intent.category.DEFAULT" /> | ||||
|                 <data android:mimeType="video/*" /> | ||||
|             </intent-filter> | ||||
|  | ||||
|             <!-- Specifies an Android theme to apply to this Activity as soon as | ||||
| @@ -78,7 +88,30 @@ | ||||
|         <meta-data | ||||
|             android:name="flutterEmbedding" | ||||
|             android:value="2" /> | ||||
|  | ||||
|         <!-- Widgets --> | ||||
|         <receiver android:name=".widgets.CheckInWidgetReceiver" | ||||
|             android:label="Check In" | ||||
|             android:exported="true"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> | ||||
|             </intent-filter> | ||||
|             <meta-data | ||||
|                 android:name="android.appwidget.provider" | ||||
|                 android:resource="@xml/check_in_widget" /> | ||||
|         </receiver> | ||||
|         <receiver android:name=".widgets.FeaturedPostWidgetReceiver" | ||||
|             android:label="Featured Post" | ||||
|             android:exported="true"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> | ||||
|             </intent-filter> | ||||
|             <meta-data | ||||
|                 android:name="android.appwidget.provider" | ||||
|                 android:resource="@xml/featured_post_widget" /> | ||||
|         </receiver> | ||||
|     </application> | ||||
|  | ||||
|     <!-- Required to query activities that can process text, see: | ||||
|          https://developer.android.com/training/package-visibility and | ||||
|          https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT. | ||||
|   | ||||
| @@ -0,0 +1,32 @@ | ||||
| package dev.solsynth.solian.data | ||||
|  | ||||
| import java.time.Instant | ||||
|  | ||||
| data class SolarPost( | ||||
|     val id: Int, | ||||
|     val body: SolarPostBody, | ||||
|     val publisher: SolarPublisher, | ||||
|     val publisherId: Int, | ||||
|     val createdAt: Instant, | ||||
|     val updatedAt: Instant, | ||||
|     val editedAt: Instant?, | ||||
|     val publishedAt: Instant? | ||||
| ) | ||||
|  | ||||
| data class SolarPostBody( | ||||
|     val content: String?, | ||||
|     val title: String?, | ||||
|     val description: String?, | ||||
|     val attachments: List<String>? | ||||
| ) | ||||
|  | ||||
| data class SolarPublisher( | ||||
|     val id: Int, | ||||
|     val name: String, | ||||
|     val nick: String, | ||||
|     val description: String?, | ||||
|     val avatar: String?, | ||||
|     val banner: String?, | ||||
|     val createdAt: Instant, | ||||
|     val updatedAt: Instant | ||||
| ) | ||||
| @@ -0,0 +1,37 @@ | ||||
| package dev.solsynth.solian.data | ||||
|  | ||||
| import com.google.gson.JsonDeserializationContext | ||||
| import com.google.gson.JsonDeserializer | ||||
| import com.google.gson.JsonElement | ||||
| import com.google.gson.JsonParseException | ||||
| import com.google.gson.JsonPrimitive | ||||
| import com.google.gson.JsonSerializationContext | ||||
| import com.google.gson.JsonSerializer | ||||
| import java.lang.reflect.Type | ||||
| import java.time.Instant | ||||
| import java.time.format.DateTimeFormatter | ||||
|  | ||||
|  | ||||
| class InstantAdapter : JsonSerializer<Instant?>, | ||||
|     JsonDeserializer<Instant?> { | ||||
|     override fun serialize( | ||||
|         src: Instant?, | ||||
|         typeOfSrc: Type?, | ||||
|         context: JsonSerializationContext? | ||||
|     ): JsonElement { | ||||
|         return JsonPrimitive(formatter.format(src)) | ||||
|     } | ||||
|  | ||||
|     @Throws(JsonParseException::class) | ||||
|     override fun deserialize( | ||||
|         json: JsonElement, | ||||
|         typeOfT: Type?, | ||||
|         context: JsonDeserializationContext? | ||||
|     ): Instant { | ||||
|         return Instant.parse(json.asString) | ||||
|     } | ||||
|  | ||||
|     companion object { | ||||
|         private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_INSTANT | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,16 @@ | ||||
| package dev.solsynth.solian.data | ||||
|  | ||||
| import java.time.Instant | ||||
|  | ||||
| data class SolarUser( | ||||
|     val id: Int, | ||||
|     val name: String, | ||||
|     val nick: String | ||||
| ) | ||||
|  | ||||
| data class SolarCheckInRecord( | ||||
|     val id: Int, | ||||
|     val resultTier: Int, | ||||
|     val resultExperience: Int, | ||||
|     val createdAt: Instant | ||||
| ) | ||||
| @@ -0,0 +1,97 @@ | ||||
| import android.content.Context | ||||
| 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.Button | ||||
| import androidx.glance.GlanceId | ||||
| import androidx.glance.GlanceModifier | ||||
| import androidx.glance.appwidget.GlanceAppWidget | ||||
| 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.Row | ||||
| import androidx.glance.layout.Spacer | ||||
| import androidx.glance.layout.fillMaxWidth | ||||
| import androidx.glance.layout.height | ||||
| import androidx.glance.layout.padding | ||||
| import androidx.glance.state.GlanceStateDefinition | ||||
| import androidx.glance.text.FontFamily | ||||
| import androidx.glance.text.FontWeight | ||||
| import androidx.glance.text.Text | ||||
| import androidx.glance.text.TextStyle | ||||
| import com.google.gson.FieldNamingPolicy | ||||
| import com.google.gson.GsonBuilder | ||||
| import dev.solsynth.solian.data.InstantAdapter | ||||
| import dev.solsynth.solian.data.SolarCheckInRecord | ||||
| import java.time.Instant | ||||
| import java.time.OffsetDateTime | ||||
| import java.time.ZoneId | ||||
| import java.time.format.DateTimeFormatter | ||||
|  | ||||
| class CheckInWidget : GlanceAppWidget() { | ||||
|     override val stateDefinition: GlanceStateDefinition<*>? | ||||
|         get() = HomeWidgetGlanceStateDefinition() | ||||
|  | ||||
|     override suspend fun provideGlance(context: Context, id: GlanceId) { | ||||
|         provideContent { | ||||
|             GlanceContent(context, currentState()) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     private fun GlanceContent(context: Context, currentState: HomeWidgetGlanceState) { | ||||
|         val gson = | ||||
|             GsonBuilder() | ||||
|                 .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) | ||||
|                 .registerTypeAdapter(Instant::class.java, InstantAdapter()) | ||||
|                 .create() | ||||
|         val resultTierSymbols = listOf("大凶", "凶", "中平", "吉", "大吉") | ||||
|  | ||||
|         val prefs = currentState.preferences | ||||
|         val checkInRaw = prefs.getString("today_check_in", null) | ||||
|  | ||||
|         Column( | ||||
|             modifier = GlanceModifier | ||||
|                 .fillMaxWidth() | ||||
|                 .background(Color.White) | ||||
|                 .padding(16.dp) | ||||
|         ) { | ||||
|             if (checkInRaw != null) { | ||||
|                 val checkIn = 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) | ||||
|                     ) | ||||
|                 } | ||||
|                 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) | ||||
|                 ) | ||||
|                 Spacer(modifier = GlanceModifier.height(8.dp)) | ||||
|                 Button( | ||||
|                     text = "Check In", | ||||
|                     onClick = {} | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,8 @@ | ||||
| package dev.solsynth.solian.widgets | ||||
|  | ||||
| import CheckInWidget | ||||
| import HomeWidgetGlanceWidgetReceiver | ||||
|  | ||||
| class CheckInWidgetReceiver : HomeWidgetGlanceWidgetReceiver<CheckInWidget>() { | ||||
|     override val glanceAppWidget = CheckInWidget() | ||||
| } | ||||
| @@ -0,0 +1,160 @@ | ||||
| import android.content.Context | ||||
| import androidx.compose.runtime.Composable | ||||
| import androidx.compose.ui.graphics.Color | ||||
| import androidx.compose.ui.text.style.TextOverflow | ||||
| import androidx.compose.ui.unit.dp | ||||
| import androidx.compose.ui.unit.sp | ||||
| import androidx.glance.GlanceId | ||||
| import androidx.glance.GlanceModifier | ||||
| import androidx.glance.appwidget.GlanceAppWidget | ||||
| 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.Row | ||||
| import androidx.glance.layout.Spacer | ||||
| import androidx.glance.layout.fillMaxSize | ||||
| import androidx.glance.layout.fillMaxWidth | ||||
| import androidx.glance.layout.height | ||||
| import androidx.glance.layout.padding | ||||
| import androidx.glance.layout.width | ||||
| import androidx.glance.state.GlanceStateDefinition | ||||
| import androidx.glance.text.FontFamily | ||||
| import androidx.glance.text.FontWeight | ||||
| import androidx.glance.text.Text | ||||
| import androidx.glance.text.TextStyle | ||||
| import coil3.ImageLoader | ||||
| import coil3.compose.AsyncImage | ||||
| import coil3.compose.setSingletonImageLoaderFactory | ||||
| import coil3.request.crossfade | ||||
| import com.google.gson.FieldNamingPolicy | ||||
| import com.google.gson.GsonBuilder | ||||
| import dev.solsynth.solian.data.InstantAdapter | ||||
| import dev.solsynth.solian.data.SolarPost | ||||
| import java.time.Instant | ||||
| import java.time.LocalDateTime | ||||
| import java.time.ZoneId | ||||
| import java.time.format.DateTimeFormatter | ||||
|  | ||||
|  | ||||
| class FeaturedPostWidget : GlanceAppWidget() { | ||||
|     override val stateDefinition: GlanceStateDefinition<*>? | ||||
|         get() = HomeWidgetGlanceStateDefinition() | ||||
|  | ||||
|     override suspend fun provideGlance(context: Context, id: GlanceId) { | ||||
|         provideContent { | ||||
|             GlanceContent(context, currentState()) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private val serverUrl = "https://api.sn.solsynth.dev" | ||||
|  | ||||
|     private fun getAttachmentUrl(identifier: String): String { | ||||
|         return if (identifier.startsWith("http")) { | ||||
|             identifier | ||||
|         } else { | ||||
|             "$serverUrl/cgi/uc/attachments/$identifier" | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Composable | ||||
|     private fun GlanceContent(context: Context, currentState: HomeWidgetGlanceState) { | ||||
|         setSingletonImageLoaderFactory { context -> | ||||
|             ImageLoader.Builder(context) | ||||
|                 .crossfade(true) | ||||
|                 .build() | ||||
|         } | ||||
|  | ||||
|         val gson = | ||||
|             GsonBuilder() | ||||
|                 .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) | ||||
|                 .registerTypeAdapter(Instant::class.java, InstantAdapter()) | ||||
|                 .create() | ||||
|  | ||||
|         val prefs = currentState.preferences | ||||
|         val postFeaturedRaw = prefs.getString("post_featured", null) | ||||
|  | ||||
|         Column( | ||||
|             modifier = GlanceModifier | ||||
|                 .fillMaxWidth() | ||||
|                 .background(Color.White) | ||||
|                 .padding(16.dp) | ||||
|         ) { | ||||
|             if (postFeaturedRaw != null) { | ||||
|                 val postFeaturedList: Array<SolarPost> = | ||||
|                     gson.fromJson(postFeaturedRaw, Array<SolarPost>::class.java) | ||||
|                 val postFeatured = postFeaturedList.firstOrNull(); | ||||
|  | ||||
|                 Row { | ||||
|                     Text( | ||||
|                         text = postFeatured?.publisher?.nick ?: "Unknown", | ||||
|                         style = TextStyle(fontSize = 15.sp) | ||||
|                     ) | ||||
|                     Spacer(modifier = GlanceModifier.width(8.dp)) | ||||
|                     Text( | ||||
|                         text = "@${postFeatured?.publisher?.name}", | ||||
|                         style = TextStyle(fontSize = 13.sp, fontFamily = FontFamily.Monospace) | ||||
|                     ) | ||||
|                 } | ||||
|  | ||||
|                 Spacer(modifier = GlanceModifier.height(8.dp)) | ||||
|  | ||||
|                 if (postFeatured?.body?.title != null) { | ||||
|                     Text( | ||||
|                         text = postFeatured.body.title, | ||||
|                         style = TextStyle(fontSize = 25.sp, fontFamily = FontFamily.Serif) | ||||
|                     ) | ||||
|                 } | ||||
|                 if (postFeatured?.body?.description != null) { | ||||
|                     Text( | ||||
|                         text = postFeatured.body.description, | ||||
|                         style = TextStyle(fontSize = 19.sp, fontFamily = FontFamily.Serif) | ||||
|                     ) | ||||
|                 } | ||||
|  | ||||
|                 if (postFeatured?.body?.title != null || postFeatured?.body?.description != null) { | ||||
|                     Spacer(modifier = GlanceModifier.height(8.dp)) | ||||
|                 } | ||||
|  | ||||
|                 Text( | ||||
|                     text = postFeatured?.body?.content ?: "No content", | ||||
|                     style = TextStyle(fontSize = 15.sp), | ||||
|                 ) | ||||
|  | ||||
|                 Spacer(modifier = GlanceModifier.height(8.dp)) | ||||
|  | ||||
|  | ||||
|                 if (postFeatured?.createdAt != null) { | ||||
|                     Text( | ||||
|                         LocalDateTime.ofInstant(postFeatured.createdAt, ZoneId.systemDefault()) | ||||
|                             .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")), | ||||
|                         style = TextStyle(fontSize = 13.sp), | ||||
|                     ) | ||||
|                 } | ||||
|  | ||||
|                 Text( | ||||
|                     "Solar Network Featured Post", | ||||
|                     style = TextStyle(fontSize = 11.sp, fontWeight = FontWeight.Bold), | ||||
|                 ) | ||||
|  | ||||
|                 return@Column; | ||||
|             } | ||||
|  | ||||
|             Column( | ||||
|                 modifier = GlanceModifier.fillMaxSize(), | ||||
|                 verticalAlignment = Alignment.Vertical.CenterVertically, | ||||
|                 horizontalAlignment = Alignment.Horizontal.CenterHorizontally | ||||
|             ) { | ||||
|                 Text( | ||||
|                     text = "No featured posts", | ||||
|                     style = TextStyle(fontSize = 17.sp, fontWeight = FontWeight.Bold) | ||||
|                 ) | ||||
|                 Text( | ||||
|                     text = "Open the app to load recommendations", | ||||
|                     style = TextStyle(fontSize = 15.sp) | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,8 @@ | ||||
| package dev.solsynth.solian.widgets | ||||
|  | ||||
| import FeaturedPostWidget | ||||
| import HomeWidgetGlanceWidgetReceiver | ||||
|  | ||||
| class FeaturedPostWidgetReceiver : HomeWidgetGlanceWidgetReceiver<FeaturedPostWidget>() { | ||||
|     override val glanceAppWidget = FeaturedPostWidget() | ||||
| } | ||||
							
								
								
									
										7
									
								
								android/app/src/main/res/xml/check_in_widget.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								android/app/src/main/res/xml/check_in_widget.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:initialLayout="@layout/glance_default_loading_layout" | ||||
|     android:minWidth="80dp" | ||||
|     android:minHeight="40dp" | ||||
|     android:resizeMode="horizontal|vertical" | ||||
|     android:updatePeriodMillis="10000"> | ||||
| </appwidget-provider> | ||||
							
								
								
									
										7
									
								
								android/app/src/main/res/xml/featured_post_widget.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								android/app/src/main/res/xml/featured_post_widget.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:initialLayout="@layout/glance_default_loading_layout" | ||||
|     android:minWidth="320dp" | ||||
|     android:minHeight="40dp" | ||||
|     android:resizeMode="horizontal|vertical" | ||||
|     android:updatePeriodMillis="10000"> | ||||
| </appwidget-provider> | ||||
| @@ -1,3 +1,4 @@ | ||||
| org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError | ||||
| android.useAndroidX=true | ||||
| android.enableJetifier=true | ||||
| kotlin.suppressKotlinVersionCompatibilityCheck=true | ||||
|   | ||||
| @@ -18,7 +18,7 @@ pluginManagement { | ||||
|  | ||||
| plugins { | ||||
|     id "dev.flutter.flutter-plugin-loader" version "1.0.0" | ||||
|     id "com.android.application" version '8.7.2' apply false | ||||
|     id "com.android.application" version '8.7.3' apply false | ||||
|     // START: FlutterFire Configuration | ||||
|     id "com.google.gms.google-services" version "4.3.15" apply false | ||||
|     id "com.google.firebase.crashlytics" version "2.8.1" apply false | ||||
|   | ||||
| @@ -60,7 +60,7 @@ struct CheckInEntry: TimelineEntry { | ||||
| struct CheckInWidgetEntryView : View { | ||||
|     var entry: CheckInProvider.Entry | ||||
|      | ||||
|     private let resultTierSymbols: [String] = ["大凶", "凶", "中平", "大吉", "吉"] | ||||
|     private let resultTierSymbols: [String] = ["大凶", "凶", "中平", "吉", "大吉"] | ||||
|      | ||||
|     func checkIn() -> Void {} | ||||
|      | ||||
|   | ||||
| @@ -15,7 +15,8 @@ class HomeWidgetProvider { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Future<void> saveWidgetData(String id, dynamic data, {bool update = true}) async { | ||||
|   Future<void> saveWidgetData(String id, dynamic data, | ||||
|       {bool update = true}) async { | ||||
|     if (kIsWeb || !(Platform.isAndroid || Platform.isIOS)) return; | ||||
|     await HomeWidget.saveWidgetData(id, jsonEncode(data)); | ||||
|     if (update) await updateWidget(); | ||||
| @@ -29,8 +30,14 @@ class HomeWidgetProvider { | ||||
|         await HomeWidget.updateWidget( | ||||
|           name: widget, | ||||
|           iOSName: widget, | ||||
|           androidName: "com.solsynth.solian.$widget", | ||||
|           qualifiedAndroidName: "group.solsynth.solian.$widget", | ||||
|         ); | ||||
|       } | ||||
|     } else if (Platform.isAndroid) { | ||||
|       const widgets = ["FeaturedPostWidget", "CheckInWidget"]; | ||||
|       for (final widget in widgets) { | ||||
|         await HomeWidget.updateWidget( | ||||
|           androidName: "${widget}Receiver", | ||||
|           qualifiedAndroidName: "dev.solsynth.solian.widgets.${widget}Receiver", | ||||
|         ); | ||||
|       } | ||||
|     } | ||||
|   | ||||
| @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev | ||||
| # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | ||||
| # In Windows, build-name is used as the major, minor, and patch parts | ||||
| # of the product and file versions while build-number is used as the build suffix. | ||||
| version: 2.0.1+29 | ||||
| version: 2.0.1+30 | ||||
|  | ||||
| environment: | ||||
|   sdk: ^3.5.4 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user