Skip to content

Commit 62b1d1c

Browse files
refactor: extract widget storage behind WidgetRepository interface
1 parent e963530 commit 62b1d1c

6 files changed

Lines changed: 67 additions & 6 deletions

File tree

AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ open class AnkiDroidApp :
132132
// Get preferences
133133
val preferences = this.sharedPrefs()
134134

135+
initializeWidgetRepository()
136+
135137
// Ensures any change is propagated to widgets
136138
ChangeManager.subscribe(this)
137139

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-FileCopyrightText: 2026 Sumit Singh <sumitsinghkoranga7@gmail.com>
2+
// SPDX-License-Identifier: GPL-3.0-or-later
3+
package com.ichi2.anki
4+
5+
import android.app.Application
6+
import android.content.Context
7+
import com.ichi2.widget.SmallWidgetStatus
8+
import com.ichi2.widget.WidgetRepository
9+
import com.ichi2.widget.WidgetStorage
10+
11+
/**
12+
* Delegates [WidgetRepository] to [MetaDB]. Replace this class to migrate
13+
* widget storage to MMKV/DataStore without touching callers.
14+
*
15+
* TODO: replace MetaDB backing with MMKV or DataStore (#20737)
16+
*/
17+
internal class MetaDbWidgetRepository(
18+
private val context: Context,
19+
) : WidgetRepository {
20+
override fun storeSmallWidgetStatus(status: SmallWidgetStatus) = MetaDB.storeSmallWidgetStatus(context, status)
21+
22+
override fun getWidgetSmallStatus(): SmallWidgetStatus = MetaDB.getWidgetSmallStatus(context)
23+
24+
override fun dueCardsCount(): Int = MetaDB.getNotificationStatus(context)
25+
}
26+
27+
context(application: Application)
28+
fun initializeWidgetRepository() {
29+
WidgetStorage.setRepository(MetaDbWidgetRepository(application))
30+
}

AnkiDroid/src/main/java/com/ichi2/anki/services/NotificationService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ class NotificationService : AnkiBroadcastReceiver() {
332332
PENDING_NOTIFICATIONS_ONLY.toString(),
333333
)!!
334334
.toInt()
335-
val dueCardsCount = WidgetStatus.fetchDue(context)
335+
val dueCardsCount = WidgetStatus.fetchDue()
336336
if (dueCardsCount >= minCardsDue) {
337337
// Build basic notification
338338
val cardsDueText =

AnkiDroid/src/main/java/com/ichi2/widget/AnkiDroidWidgetSmall.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class AnkiDroidWidgetSmall : AnalyticsWidgetProvider() {
148148
}
149149
} else {
150150
// Compute the total number of cards due.
151-
val (dueCardsCount, eta) = WidgetStatus.fetchSmall(context)
151+
val (dueCardsCount, eta) = WidgetStatus.fetchSmall()
152152
if (dueCardsCount == 0) {
153153
updateViews.setViewVisibility(R.id.ankidroid_widget_small_finish_layout, View.VISIBLE)
154154
updateViews.setViewVisibility(R.id.widget_eta, View.INVISIBLE)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-FileCopyrightText: 2026 Sumit Singh <sumitsinghkoranga7@gmail.com>
2+
// SPDX-License-Identifier: GPL-3.0-or-later
3+
package com.ichi2.widget
4+
5+
/**
6+
* Storage abstraction for widget status, decoupling widget code from [com.ichi2.anki.MetaDB].
7+
* When `:widgets` becomes a separate module, this interface moves with it.
8+
*/
9+
interface WidgetRepository {
10+
fun storeSmallWidgetStatus(status: SmallWidgetStatus)
11+
12+
fun getWidgetSmallStatus(): SmallWidgetStatus
13+
14+
fun dueCardsCount(): Int
15+
}
16+
17+
object WidgetStorage {
18+
lateinit var instance: WidgetRepository
19+
private set
20+
21+
fun setRepository(repository: WidgetRepository) {
22+
instance = repository
23+
}
24+
25+
fun storeSmallWidgetStatus(status: SmallWidgetStatus) = instance.storeSmallWidgetStatus(status)
26+
27+
fun getWidgetSmallStatus(): SmallWidgetStatus = instance.getWidgetSmallStatus()
28+
29+
fun dueCardsCount(): Int = instance.dueCardsCount()
30+
}

AnkiDroid/src/main/java/com/ichi2/widget/WidgetStatus.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package com.ichi2.widget
1717
import android.content.Context
1818
import com.ichi2.anki.AnkiDroidApp
1919
import com.ichi2.anki.CollectionManager.withCol
20-
import com.ichi2.anki.MetaDB
2120
import com.ichi2.anki.R
2221
import com.ichi2.anki.common.utils.android.SdCard
2322
import com.ichi2.anki.preferences.sharedPrefs
@@ -94,7 +93,7 @@ object WidgetStatus {
9493
return
9594
}
9695
val status = querySmallWidgetStatus()
97-
MetaDB.storeSmallWidgetStatus(context, status)
96+
WidgetStorage.storeSmallWidgetStatus(status)
9897
if (smallWidgetEnabled) {
9998
Timber.i("triggering small widget UI update")
10099
AnkiDroidWidgetSmall.UpdateService().doUpdate(context)
@@ -105,9 +104,9 @@ object WidgetStatus {
105104
}
106105

107106
/** Returns the status of each of the decks. */
108-
fun fetchSmall(context: Context): SmallWidgetStatus = MetaDB.getWidgetSmallStatus(context)
107+
fun fetchSmall(): SmallWidgetStatus = WidgetStorage.getWidgetSmallStatus()
109108

110-
fun fetchDue(context: Context): Int = MetaDB.getNotificationStatus(context)
109+
fun fetchDue(): Int = WidgetStorage.dueCardsCount()
111110

112111
private suspend fun querySmallWidgetStatus(): SmallWidgetStatus =
113112
withCol {

0 commit comments

Comments
 (0)