Skip to content

Commit

Permalink
Refactored DeckPickerWidget to handle empty state visibility, allow…
Browse files Browse the repository at this point in the history
…ing users to reconfigure the widget by clicking the empty state message.
  • Loading branch information
xenonnn4w committed Sep 14, 2024
1 parent 6d3d0ca commit 195965a
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.view.View
import android.widget.RemoteViews
import com.ichi2.anki.AnkiDroidApp
import com.ichi2.anki.CollectionManager.withCol
import com.ichi2.anki.CrashReportService
import com.ichi2.anki.R
import com.ichi2.anki.Reviewer
import com.ichi2.anki.analytics.UsageAnalytics
import com.ichi2.anki.isCollectionEmpty
import com.ichi2.anki.pages.DeckOptions
import com.ichi2.libanki.DeckId
import com.ichi2.widget.ACTION_UPDATE_WIDGET
Expand Down Expand Up @@ -92,52 +94,113 @@ class DeckPickerWidget : AnalyticsWidgetProvider() {
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: AppWidgetId,
deckIds: LongArray
deckIds: LongArray?
) {
val remoteViews = RemoteViews(context.packageName, R.layout.widget_deck_picker_large)

if (deckIds == null || deckIds.isEmpty()) {
showEmptyWidget(context, appWidgetManager, appWidgetId, remoteViews)
return
}
AnkiDroidApp.applicationScope.launch {
val isCollectionEmpty = isCollectionEmpty()
if (isCollectionEmpty) {
showEmptyCollection(context, appWidgetManager, appWidgetId, remoteViews)
return@launch
}

val deckData = getDeckNamesAndStats(deckIds.toList())

remoteViews.removeAllViews(R.id.deckCollection)
if (deckData.isEmpty()) {
showEmptyWidget(context, appWidgetManager, appWidgetId, remoteViews)
return@launch
}

showDeck(context, appWidgetManager, appWidgetId, remoteViews, deckIds)
}
}

private suspend fun showDeck(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: AppWidgetId,
remoteViews: RemoteViews,
deckIds: LongArray?
) {
remoteViews.removeAllViews(R.id.deckCollection)

val deckData = deckIds?.let { getDeckNamesAndStats(it.toList()) }
if (deckData != null) {
for (deck in deckData) {
val deckView = RemoteViews(context.packageName, R.layout.widget_item_deck_main)

remoteViews.setViewVisibility(R.id.empty_widget, View.GONE)
remoteViews.setViewVisibility(R.id.deckCollection, View.VISIBLE)
deckView.setTextViewText(R.id.deckName, deck.name)
deckView.setTextViewText(R.id.deckNew, deck.newCount.toString())
deckView.setTextViewText(R.id.deckDue, deck.reviewCount.toString())
deckView.setTextViewText(R.id.deckLearn, deck.learnCount.toString())

val isEmptyDeck = deck.newCount == 0 && deck.reviewCount == 0 && deck.learnCount == 0

if (!isEmptyDeck) {
val intent = Intent(context, Reviewer::class.java).apply {
val intent = if (!isEmptyDeck) {
Intent(context, Reviewer::class.java).apply {
action = Intent.ACTION_VIEW
putExtra("deckId", deck.deckId)
}
val pendingIntent = PendingIntent.getActivity(
context,
deck.deckId.toInt(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
deckView.setOnClickPendingIntent(R.id.deckName, pendingIntent)
} else {
val intent = DeckOptions.getIntent(context, deck.deckId)
val pendingIntent = PendingIntent.getActivity(
context,
deck.deckId.toInt(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
deckView.setOnClickPendingIntent(R.id.deckName, pendingIntent)
DeckOptions.getIntent(context, deck.deckId)
}

val pendingIntent = PendingIntent.getActivity(
context,
deck.deckId.toInt(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

deckView.setOnClickPendingIntent(R.id.deckName, pendingIntent)
remoteViews.addView(R.id.deckCollection, deckView)
}
appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
}

appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
}

private fun showEmptyCollection(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: AppWidgetId,
remoteViews: RemoteViews
) {
remoteViews.setTextViewText(R.id.empty_widget, context.getString(R.string.app_not_initialized_new))
remoteViews.setViewVisibility(R.id.empty_widget, View.VISIBLE)
remoteViews.setViewVisibility(R.id.deckCollection, View.GONE)

appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
}

private fun showEmptyWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: AppWidgetId,
remoteViews: RemoteViews
) {
remoteViews.setViewVisibility(R.id.empty_widget, View.VISIBLE)
remoteViews.setViewVisibility(R.id.deckCollection, View.GONE)

val configIntent = Intent(context, DeckPickerWidgetConfig::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val configPendingIntent = PendingIntent.getActivity(
context,
appWidgetId,
configIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
remoteViews.setOnClickPendingIntent(R.id.empty_widget, configPendingIntent)

appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
}

/**
Expand Down
11 changes: 11 additions & 0 deletions AnkiDroid/src/main/res/layout/widget_deck_picker_large.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@
android:focusable="false"
android:theme="@style/Theme.Material3.DynamicColors.DayNight">

<TextView
android:id="@+id/empty_widget"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="7dp"
android:gravity="center"
android:padding="20dp"
android:text="@string/empty_widget"
android:visibility="gone" />

<LinearLayout
android:id="@+id/deckCollection"
android:layout_width="match_parent"
Expand Down

0 comments on commit 195965a

Please sign in to comment.