@@ -4,8 +4,6 @@ import android.content.Context
44import android.graphics.Bitmap
55import android.graphics.BitmapFactory
66import androidx.compose.runtime.Composable
7- import androidx.compose.runtime.collectAsState
8- import androidx.compose.runtime.getValue
97import androidx.compose.ui.unit.DpSize
108import androidx.compose.ui.unit.dp
119import androidx.datastore.preferences.core.Preferences
@@ -47,16 +45,20 @@ class SpotlightWidget : GlanceAppWidget() {
4745 private val viewModel by lazy { SpotlightViewModel () }
4846
4947 override suspend fun provideGlance (context : Context , id : GlanceId ) {
50- if (viewModel.isLoggedIn) {
51- cacheImages(context)
48+ val entries = if (viewModel.isLoggedIn) {
49+ val articles = viewModel.fetchArticles()
50+ cacheImages(context, articles)
51+ articles.map { it.toSpotlightEntry() }
52+ } else {
53+ emptyList()
5254 }
5355
5456 provideContent {
5557 GlanceTheme {
5658 if (! viewModel.isLoggedIn) {
5759 LoggedOutContent ()
5860 } else {
59- Content ()
61+ Content (entries )
6062 }
6163 }
6264 }
@@ -84,16 +86,14 @@ class SpotlightWidget : GlanceAppWidget() {
8486 }
8587
8688 @Composable
87- private fun Content () {
89+ private fun Content (entries : List < SpotlightEntry > ) {
8890 val context = LocalContext .current
8991 val prefs = currentState<Preferences >()
90- val articles by viewModel.articles.collectAsState(emptyList())
91- val entries = articles.map { it.toSpotlightEntry() }
9292 val manualOffset = prefs[CURRENT_INDEX_KEY ] ? : 0
9393 val currentIndex =
9494 if (entries.isEmpty()) 0 else (lcgIndex(entries.size) + manualOffset).mod(entries.size)
9595 val entry = entries.getOrNull(currentIndex)
96- val imageBitmap = entry?.let { readCachedImage(context, currentIndex ) }
96+ val imageBitmap = entry?.let { readCachedImage(context, it.id ) }
9797
9898 SpotlightLayout (
9999 entry = entry,
@@ -122,10 +122,6 @@ class SpotlightWidget : GlanceAppWidget() {
122122 val CURRENT_INDEX_KEY = intPreferencesKey(" spotlight_current_index" )
123123
124124 suspend fun refresh (context : Context , glanceId : GlanceId ) {
125- try {
126- cacheImages(context)
127- } catch (_: Exception ) {
128- }
129125 SpotlightWidget ().update(context, glanceId)
130126 }
131127
@@ -137,26 +133,26 @@ class SpotlightWidget : GlanceAppWidget() {
137133 SpotlightWidget ().update(context, glanceId)
138134 }
139135
140- private suspend fun cacheImages (context : Context ) {
141- val viewModel = SpotlightViewModel ()
142- val articles = viewModel.fetchArticles()
143-
136+ private suspend fun cacheImages (context : Context , articles : List <Article >) {
144137 clearImageCache(context)
145138
146- articles.forEachIndexed { index, article ->
139+ articles.forEach { article ->
147140 article.imageURL?.let { url ->
148- cacheImage(context, url, index )
141+ cacheImage(context, url, article.id )
149142 }
150143 }
151144 }
152145
153146 private fun imageDir (context : Context ): File =
154147 File (context.cacheDir, " spotlight_images" ).apply { mkdirs() }
155148
156- private fun imageFile (context : Context , index : Int ): File =
157- File (imageDir(context), " spotlight_$index .jpg" )
149+ private fun imageFile (context : Context , id : String ): File =
150+ File (imageDir(context), " spotlight_${safeFileName(id)} .jpg" )
158151
159- private suspend fun cacheImage (context : Context , url : String , index : Int ) {
152+ private fun safeFileName (id : String ): String =
153+ id.hashCode().toUInt().toString(16 )
154+
155+ private suspend fun cacheImage (context : Context , url : String , id : String ) {
160156 try {
161157 val request = ImageRequest .Builder (context)
162158 .data(url)
@@ -166,15 +162,15 @@ class SpotlightWidget : GlanceAppWidget() {
166162 val result = context.imageLoader.execute(request)
167163 val image = result.image ? : return
168164 val bitmap = image.toBitmap()
169- imageFile(context, index ).outputStream().use { out ->
165+ imageFile(context, id ).outputStream().use { out ->
170166 bitmap.compress(Bitmap .CompressFormat .JPEG , 80 , out )
171167 }
172168 } catch (_: Exception ) {
173169 }
174170 }
175171
176- fun readCachedImage (context : Context , index : Int ): Bitmap ? {
177- val file = imageFile(context, index )
172+ fun readCachedImage (context : Context , id : String ): Bitmap ? {
173+ val file = imageFile(context, id )
178174 if (! file.exists()) return null
179175 return BitmapFactory .decodeFile(file.absolutePath)
180176 }
@@ -192,9 +188,6 @@ private class SpotlightViewModel : KoinComponent {
192188 val isLoggedIn
193189 get() = appPreferences.isLoggedIn
194190
195- val articles
196- get() = account.latestArticles(limit = 10 )
197-
198191 suspend fun fetchArticles () =
199192 account.latestArticles(limit = 10 ).first()
200193}
0 commit comments