Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import java.io.FileInputStream
plugins {
id("com.android.application")
id("kotlin-android")
id("org.jetbrains.kotlin.plugin.compose")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
id("com.google.gms.google-services")
Expand All @@ -21,6 +22,10 @@ android {
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

buildFeatures {
compose = true
}

compileOptions {
// Flag required by flutter_local_notifications package
isCoreLibraryDesugaringEnabled = true
Expand Down Expand Up @@ -88,4 +93,5 @@ dependencies {
// Dependency required by flutter_local_notifications package
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.glance:glance-appwidget:1.1.1")
}
10 changes: 10 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@
</activity>
<receiver android:exported="false"
android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver"/>
<receiver
android:name=".DailyPuzzleWidgetReceiver"
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/daily_puzzle_widget_info" />
</receiver>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
Expand Down
127 changes: 127 additions & 0 deletions android/app/src/main/kotlin/org/lichess/mobileV2/DailyPuzzleWidget.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.lichess.mobileV2

import android.content.Context
import android.graphics.BitmapFactory
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.GlanceTheme
import androidx.glance.Image
import androidx.glance.ImageProvider
import androidx.glance.action.actionStartActivity
import androidx.glance.action.clickable
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.SizeMode
import androidx.glance.appwidget.provideContent
import androidx.glance.currentState
import androidx.glance.background
import androidx.glance.layout.Alignment
import androidx.glance.layout.Box
import androidx.glance.layout.Column
import androidx.glance.layout.ContentScale
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.size
import androidx.glance.layout.width
import androidx.glance.text.FontWeight
import androidx.glance.text.Text
import androidx.glance.text.TextStyle
import es.antonborri.home_widget.HomeWidgetGlanceState
import es.antonborri.home_widget.HomeWidgetGlanceStateDefinition

class DailyPuzzleWidget : GlanceAppWidget() {

override val stateDefinition = HomeWidgetGlanceStateDefinition()

override val sizeMode = SizeMode.Single

override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
GlanceTheme {
DailyPuzzleContent(context)
}
}
}

@Composable
private fun DailyPuzzleContent(context: Context) {
val state = currentState<HomeWidgetGlanceState>()
val prefs = state.preferences
val puzzleId = prefs.getString("puzzle_id", null)
val sideToMove = prefs.getString("puzzle_side_to_move", null)
val plays = prefs.getInt("puzzle_plays", 0)
val imagePath = prefs.getString("puzzle_board_image", null)

val intent = android.content.Intent(
android.content.Intent.ACTION_VIEW,
android.net.Uri.parse(
if (puzzleId != null) "https://lichess.org/training/$puzzleId"
else "https://lichess.org/training/daily"
)
)

Box(
modifier = GlanceModifier
.fillMaxSize()
.padding(8.dp)
.clickable(actionStartActivity<MainActivity>()),
contentAlignment = Alignment.Center,
) {
if (puzzleId != null) {
Column(
modifier = GlanceModifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "Daily Puzzle",
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 12.sp),
)
Spacer(modifier = GlanceModifier.height(4.dp))

if (imagePath != null) {
val file = java.io.File(imagePath)
if (file.exists()) {
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
if (bitmap != null) {
Image(
provider = ImageProvider(bitmap),
contentDescription = "Chess board",
contentScale = ContentScale.Fit,
)
}
}
}

Spacer(modifier = GlanceModifier.height(4.dp))

if (sideToMove != null) {
Text(
text = if (sideToMove == "white") "White to play" else "Black to play",
style = TextStyle(fontSize = 10.sp),
)
}
}
} else {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = "Daily Puzzle",
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 14.sp),
)
Spacer(modifier = GlanceModifier.height(8.dp))
Text(
text = "Open Lichess to load",
style = TextStyle(fontSize = 12.sp),
)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.lichess.mobileV2

import es.antonborri.home_widget.HomeWidgetGlanceWidgetReceiver

class DailyPuzzleWidgetReceiver : HomeWidgetGlanceWidgetReceiver<DailyPuzzleWidget>() {
override val glanceAppWidget = DailyPuzzleWidget()
}
9 changes: 9 additions & 0 deletions android/app/src/main/res/xml/daily_puzzle_widget_info.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/glance_default_loading_layout"
android:minWidth="180dp"
android:minHeight="110dp"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen">
</appwidget-provider>
1 change: 1 addition & 0 deletions android/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.11.1" apply false
id("org.jetbrains.kotlin.android") version "2.2.21" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.2.21" apply false
id("com.google.gms.google-services") version "4.4.4" apply false
id("com.google.firebase.crashlytics") version "3.0.6" apply false
}
Expand Down
Loading