Skip to content
This repository was archived by the owner on Dec 21, 2025. It is now read-only.

Conversation

@xanderlmk
Copy link
Owner

@xanderlmk xanderlmk commented Jun 20, 2025

Summary by Sourcery

Refactor the card creation and editing workflows to use structured UI state objects, SavedStateHandle and StateFlow, and introduce centralized preference management and dynamic theming. Migrate from ad-hoc Fields states to CDetails and MyTextRange models, streamline Compose components for add/edit cards (including notation cards with KaTeX keyboard support), and consolidate keyboard selection into a dedicated repository.

New Features:

  • Support persistent notation card editing with dynamic steps and KaTeX menus backed by SavedStateHandle
  • Add PreferencesManager and PreferenceValues to expose app settings (themes, review/card counts, KaTeX dimensions) as StateFlows
  • Enhanced BuildKeyboardHtml to include new symbol categories (binary operators, logic/set theory, relations)

Enhancements:

  • Refactor AddCardViewModel and EditCardViewModel to manage CDetails state via StateFlow, replacing legacy Fields
  • Unify UI state classes under model.ui.states (CDetails, MyTextRange, SelectedKeyboard, Decision, Dialogs)
  • Simplify Compose card views by removing manual focus code and introducing collect*AsStates helpers
  • Update navigation routes to include deckId/card_id arguments and handle keyboard state on back navigation
  • Streamline theme options UI with composable BoxedOptions and KatexMenuOptions components
  • Consolidate icon rendering into a ContentIcons helper

Build:

  • Bump AGP to 8.10.1 in libs.versions.toml

Documentation:

  • Update user-facing dialogs and settings screens to reflect new theming controls

@sourcery-ai
Copy link

sourcery-ai bot commented Jun 20, 2025

Reviewer's Guide

This PR overhauls state management and UI options across card creation/editing flows, introducing SavedStateHandle persistence in ViewModels, migrating away from the old Fields model to a structured CDetails/flow-based state, centralizing keyboard selection logic, and consolidating preference handling and UI components for consistency and extensibility.

Class diagram for new and updated ViewModels and state types

classDiagram
    class AddCardViewModel {
        -flashCardRepository: FlashCardRepository
        -isOwnerOrCoOwnerRepo: IsOwnerOrCoOwnerRepo
        -kbRepository: KeyboardSelectionRepository
        -savedStateHandle: SavedStateHandle
        -deckUUID: String
        +fields: StateFlow<CDetails>
        +selection: StateFlow<MyTextRange>
        +composition: StateFlow<MyTextRange?>
        +showKatexKeyboard: StateFlow<Boolean>
        +selectedKB: StateFlow<SelectedKeyboard?>
        +resetOffset: StateFlow<Boolean>
        +updateQ(q: String)
        +updateA(a: String)
        +updateM(m: String)
        +updateCh(c: String, idx: Int)
        +updateCor(c: Char)
        +addStep()
        +removeStep()
        +updateStep(s: String, idx: Int)
        +updateQA(qa: PartOfQorA)
        +resetDone()
        +updateSelectedKB(selectedKeyboard: SelectedKeyboard)
        +onCreate()
        +toggleKeyboard()
        +resetSelectedKB()
    }
    class EditCardViewModel {
        -cardTypeRepository: CardTypeRepository
        -sSRepository: ScienceSpecificRepository
        -kbRepository: KeyboardSelectionRepository
        -savedStateHandle: SavedStateHandle
        -cardId: Int
        +fields: StateFlow<CDetails>
        +selection: StateFlow<MyTextRange>
        +composition: StateFlow<MyTextRange?>
        +showKatexKeyboard: StateFlow<Boolean>
        +selectedKB: StateFlow<SelectedKeyboard?>
        +resetOffset: StateFlow<Boolean>
        +selectedSLSymbols: StateFlow<List<KaTeXMenu>>
        +updateQ(q: String)
        +updateA(a: String)
        +updateM(m: String)
        +updateCh(c: String, idx: Int)
        +updateCor(c: Char)
        +addStep()
        +removeStep()
        +updateStep(s: String, idx: Int)
        +updateQA(qa: PartOfQorA)
        +resetDone()
        +updateSelectedKB(selectedKeyboard: SelectedKeyboard)
        +onCreate()
        +toggleKeyboard()
        +resetSelectedKB()
    }
    class CDetails {
        <<sealed class>>
        +question: String
        +answer: String
        +middle: String
        +choices: List<String>
        +correct: Char
        +steps: List<String>
        +isQOrA: PartOfQorA
        +updateQuestion(q: String): CDetails
        +updateAnswer(a: String): CDetails
        +updateMiddle(m: String): CDetails
        +updateChoices(c: String, idx: Int): CDetails
        +updateCorrect(c: Char): CDetails
        +addStep(): CDetails
        +removeStep(): CDetails
        +updateStep(s: String, idx: Int): CDetails
        +updateQOrA(qa: PartOfQorA): CDetails
    }
    class SelectedKeyboard
    class MyTextRange
    class KaTeXMenu
    class ListOfKatexMenu {
        +km: List<KaTeXMenu>
    }
    AddCardViewModel --> CDetails
    EditCardViewModel --> CDetails
    EditCardViewModel --> ListOfKatexMenu
    ListOfKatexMenu --> KaTeXMenu
    AddCardViewModel --> SelectedKeyboard
    EditCardViewModel --> SelectedKeyboard
    AddCardViewModel --> MyTextRange
    EditCardViewModel --> MyTextRange
    EditCardViewModel --> KaTeXMenu
Loading

Class diagram for CDetails sealed class structure

classDiagram
    class CDetails {
        <<sealed class>>
    }
    class BasicCD {
        +question: String
        +answer: String
    }
    class HintCD {
        +question: String
        +hint: String
        +answer: String
    }
    class ThreeCD {
        +question: String
        +middle: String
        +answer: String
        +isQOrA: PartOfQorA
    }
    class MultiCD {
        +question: String
        +choiceA: String
        +choiceB: String
        +choiceC: String
        +choiceD: String
        +correct: Char
    }
    class NotationCD {
        +question: String
        +steps: List<String>
        +answer: String
    }
    CDetails <|-- BasicCD
    CDetails <|-- HintCD
    CDetails <|-- ThreeCD
    CDetails <|-- MultiCD
    CDetails <|-- NotationCD
Loading

File-Level Changes

Change Details Files
Migrate card view models to use SavedStateHandle and CDetails for persistent, structured UI state
  • Injected SavedStateHandle into AddCardViewModel and EditCardViewModel
  • Replaced mutable Fields with CDetails and MyTextRange, encoded/decoded via Json
  • Exposed fields, selection, composition as MutableStateFlow/StateFlow
  • Refactored update methods (updateQ, updateA, addStep, removeStep, etc.) to update flows and SavedStateHandle
EditCardViewModel.kt
AddCardViewModel.kt
Screen-Related.kt
CTConversionHandler.kt
CardTypesDao.kt
OfflineCardTypeRepository.kt
Replace direct Fields usage in composables with flow-based state collectors
  • Removed Fields constructor parameters from card views
  • Introduced collectNotationFieldsAsStates and collectTextRangesAsStates helpers
  • Updated Add/Edit card composables to call vm.fields.collectAsStateWithLifecycle
  • Unified onFocusChanged and replace focusRequester chains
AddNotationCard.kt
AddMultiChoiceCard.kt
AddBasicCard.kt
AddThreeCard.kt
AddHintCard.kt
EditNotationCard.kt
EditBasicCard.kt
EditThreeCard.kt
EditChoiceCard.kt
EditHintCard.kt
miscFunctions/Functions.kt
Centralize KaTeX keyboard selection into KeyboardSelectionRepository
  • Extracted showKatexKeyboard, selectedKB, resetOffset flows into repository interface and impl
  • Persisted keyboard state in SavedStateHandle via viewModels onCreate/init
  • Removed ad-hoc keyboard state from NavViewModel
  • Updated ToggleKeyBoard and KaTeXMenu calls to use repository methods
KeyboardSelectionRepository.kt
NavViewModel.kt
AddCardViewModel.kt
EditCardViewModel.kt
miscFunctions/Functions.kt
AddNotationCard.kt
EditNotationCard.kt
Introduce PreferencesManager and flows for dynamic theme and menu settings
  • Added PreferencesManager storing shared prefs with MutableStateFlow
  • Created PreferenceValues parcelable and setPreferenceValues helper
  • Replaced direct preferences access in activities and nav hosts with PreferenceValues flows
  • Exposed review/card/menu dimension settings and bound UI options accordingly
PreferencesManager.kt
AddCardView.kt
MainActivity.kt
DeckNavHost.kt
AppNavHost.kt
SupabaseNavHost.kt
ResetPasswordActivity.kt
DeepLinkerActivity.kt
Refactor UI utilities and options for consistency
  • Extracted ContentIcons helper to unify icon rendering
  • Added BoxedOptions and KatexMenuOptions composables for integer settings
  • Updated SystemThemeOptions, Buttons, CustomText, TextProps to support new theming and styling
  • Removed redundant modifiers, consolidated focus and styling logic
ContentIcons.kt
BoxedOptions.kt
KatexMenuOptions.kt
SystemThemeOptions.kt
Buttons.kt
CustomText.kt
TextProps.kt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@xanderlmk xanderlmk merged commit 47e7c2d into main Jun 20, 2025
1 check passed
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @xanderlmk - I've reviewed your changes - here's some feedback:

  • There’s a lot of duplicated serialization and SavedStateHandle logic in AddCardViewModel and EditCardViewModel—consider extracting the CDetails state‐saving and restoration into a shared helper or base class to DRY up the code.
  • The new PreferencesManager manually syncs SharedPreferences with MutableStateFlows—migrating to Jetpack DataStore would give you a first­class reactive preferences API and eliminate boilerplate.
  • This PR touches UI, ViewModels, navigation, and preferences all at once—splitting it into focused changes (e.g. keyboard handling, ViewModel state persistence, preferences migration) would make review and maintenance much easier.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- There’s a lot of duplicated serialization and SavedStateHandle logic in AddCardViewModel and EditCardViewModel—consider extracting the CDetails state‐saving and restoration into a shared helper or base class to DRY up the code.
- The new PreferencesManager manually syncs SharedPreferences with MutableStateFlows—migrating to Jetpack DataStore would give you a first­class reactive preferences API and eliminate boilerplate.
- This PR touches UI, ViewModels, navigation, and preferences all at once—splitting it into focused changes (e.g. keyboard handling, ViewModel state persistence, preferences migration) would make review and maintenance much easier.

## Individual Comments

### Comment 1
<location> `app/src/main/java/com/belmontCrest/cardCrafter/views/mainViews/DefaultDeckOptions.kt:46` </location>
<code_context>
-    clicked: Boolean,
     getUIStyle: GetUIStyle
 ) {
-    var expanded by remember { mutableStateOf(false) }
-    if (clicked) {
-        expanded = false
-    }
</code_context>

<issue_to_address>
The 'clicked' parameter and related logic are now unused and can be removed.

Remove the 'clicked' parameter from the function signature and delete all related code to simplify the component.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
@Composable
fun DefaultDeckOptions(
    cardAmount: MutableState<String>,
    reviewSuccess: Boolean,
    cardSuccess: Boolean,
    getUIStyle: GetUIStyle
) {
=======
@Composable
fun DefaultDeckOptions(
    cardAmount: MutableState<String>,
    reviewSuccess: Boolean,
    cardSuccess: Boolean,
    getUIStyle: GetUIStyle
) {
>>>>>>> REPLACE

</suggested_fix>

### Comment 2
<location> `app/src/main/java/com/belmontCrest/cardCrafter/controller/cardHandlers/CardTypeHandler.kt:35` </location>
<code_context>
+        vm: EditCardViewModel, getUIStyle: GetUIStyle, onUpdate: () -> KaTeXMenu
     ) {
-
-        if (ct is CT.Basic) {
-            if (!changed) {
-                val cardDetails by remember { mutableStateOf(ct.toCardDetails()) }
-                fields.question = rememberSaveable { mutableStateOf(cardDetails.question.value) }
-                fields.answer = rememberSaveable { mutableStateOf(cardDetails.answer.value) }
-            }
-            EditBasicCard(fields)
-        } else {
-            EditBasicCard(fields)
</code_context>

<issue_to_address>
The CardTypeHandler implementations no longer use the CT argument for field initialization.

If CT is no longer required, please remove it from the interface and all related code to prevent confusion.

Suggested implementation:

```
interface CardTypeHandler {
    @Composable
    fun HandleCardEdit(
        vm: EditCardViewModel, getUIStyle: GetUIStyle, onUpdate: () -> KaTeXMenu
    )
}

```

```
class BasicCardTypeHandler : CardTypeHandler {
    @Composable
    override fun HandleCardEdit(
        vm: EditCardViewModel, getUIStyle: GetUIStyle, onUpdate: () -> KaTeXMenu
    ) {
        EditBasicCard(vm)
    }
}

```

```
class ThreeCardTypeHandler : CardTypeHandler {
    @Composable
    override fun HandleCardEdit(

```

You will also need to:
1. Remove the `CT` parameter from all other `CardTypeHandler` implementations.
2. Update all calls to `HandleCardEdit` throughout the codebase to no longer pass a `CT` argument.
3. Remove any logic that depends on the `CT` parameter within those implementations.
</issue_to_address>

### Comment 3
<location> `app/src/main/java/com/belmontCrest/cardCrafter/localDatabase/dbInterface/daoInterfaces/deckAndCardDao/CardTypesDao.kt:104` </location>
<code_context>
                 insertBasicCard(
                     BasicCard(
                         cardId = cardId,
-                        question = fields.question.value,
-                        answer = fields.answer.value
+                        question = fields.question,
+                        answer = fields.answer
</code_context>

<issue_to_address>
All usages of fields.question.value, fields.answer.value, etc. are replaced with fields.question, fields.answer, etc.

Ensure all fields are properly initialized and non-null, since the previous MutableState may have provided defaults.

Suggested implementation:

```
                // Ensure fields.question and fields.answer are non-null, provide defaults if necessary
                val question = fields.question ?: ""
                val answer = fields.answer ?: ""
                insertBasicCard(
                    BasicCard(
                        cardId = cardId,
                        question = question,
                        answer = answer
                    )
                )

```

- If there are other usages of `fields.*` (e.g., `fields.extra`, `fields.hint`, etc.) in this or related functions, apply the same null-check/default-value pattern.
- If `CDetails` is a data class you control, consider enforcing non-null types or providing default values at the data class level for even safer code.
</issue_to_address>

### Comment 4
<location> `app/src/main/java/com/belmontCrest/cardCrafter/model/application/PreferencesManager.kt:122` </location>
<code_context>
+        get() = sharedPreferences.getInt("menu_height", 200)
+        set(value) = sharedPreferences.edit { putInt("menu_height", value) }
+
+    private var katexMenuWidth: Int
+        get() = sharedPreferences.getInt("menu_width", Int.MIN_VALUE)
+        set(value) = sharedPreferences.edit { putInt("menu_width", value) }
+}
</code_context>

<issue_to_address>
Default value for katexMenuWidth may be problematic.

Int.MIN_VALUE as a default for menu_width may cause UI issues if unset. Recommend using a sensible default like 200 to prevent negative values in the UI.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    private var katexMenuWidth: Int
        get() = sharedPreferences.getInt("menu_width", Int.MIN_VALUE)
        set(value) = sharedPreferences.edit { putInt("menu_width", value) }
=======
    private var katexMenuWidth: Int
        get() = sharedPreferences.getInt("menu_width", 200)
        set(value) = sharedPreferences.edit { putInt("menu_width", value) }
>>>>>>> REPLACE

</suggested_fix>

### Comment 5
<location> `app/src/main/java/com/belmontCrest/cardCrafter/model/application/PreferencesManager.kt:43` </location>
<code_context>
+        _width.update { katexMenuWidth }
+    }
+
+    fun saveDynamicTheme() {
+        _dynamicTheme.update { !it }; isDynamicThemeEnabled = _dynamicTheme.value
+    }
+
</code_context>

<issue_to_address>
saveDynamicTheme toggles the value rather than setting it explicitly.

Consider updating saveDynamicTheme to accept a Boolean parameter, aligning its behavior with saveCuteTheme and reducing potential confusion from unintended toggling.

Suggested implementation:

```
    fun saveDynamicTheme(enabled: Boolean) {
        _dynamicTheme.update { enabled }
        isDynamicThemeEnabled = enabled
    }

```

You will also need to update all usages of `saveDynamicTheme()` elsewhere in your codebase to pass a Boolean argument, e.g. `saveDynamicTheme(true)` or `saveDynamicTheme(false)`, to match the new function signature.
</issue_to_address>

### Comment 6
<location> `app/src/main/java/com/belmontCrest/cardCrafter/localDatabase/tables/ParcelableConstuctors.kt:58` </location>
<code_context>
+        correct = parcel.readString()!![0]
+    )
+
+fun toParcelableNotationCard(parcel: Parcel): NotationCard? =
+    NotationCard(
+        cardId = parcel.readInt(),
+        question = parcel.readString()!!,
+        steps = listOf(parcel.readString()!!),
+        answer = parcel.readString()!!
+    )
</code_context>

<issue_to_address>
steps field in toParcelableNotationCard only reads a single string.

Currently, only one step is read from the parcel. To support multiple steps, read the list size first and then read each step in a loop.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 21 to 36
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.belmontCrest.cardCrafter.R
import com.belmontCrest.cardCrafter.ui.theme.GetUIStyle
import com.belmontCrest.cardCrafter.ui.theme.generalSettingsOptionsModifier
import com.belmontCrest.cardCrafter.uiFunctions.EditIntField

@Composable
fun DefaultDeckOptions(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The 'clicked' parameter and related logic are now unused and can be removed.

Remove the 'clicked' parameter from the function signature and delete all related code to simplify the component.

Suggested change
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.belmontCrest.cardCrafter.R
import com.belmontCrest.cardCrafter.ui.theme.GetUIStyle
import com.belmontCrest.cardCrafter.ui.theme.generalSettingsOptionsModifier
import com.belmontCrest.cardCrafter.uiFunctions.EditIntField
@Composable
fun DefaultDeckOptions(
@Composable
fun DefaultDeckOptions(
cardAmount: MutableState<String>,
reviewSuccess: Boolean,
cardSuccess: Boolean,
getUIStyle: GetUIStyle
) {

Comment on lines -35 to -41
if (ct is CT.Basic) {
if (!changed) {
val cardDetails by remember { mutableStateOf(ct.toCardDetails()) }
fields.question = rememberSaveable { mutableStateOf(cardDetails.question.value) }
fields.answer = rememberSaveable { mutableStateOf(cardDetails.answer.value) }
}
EditBasicCard(fields)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The CardTypeHandler implementations no longer use the CT argument for field initialization.

If CT is no longer required, please remove it from the interface and all related code to prevent confusion.

Suggested implementation:

interface CardTypeHandler {
    @Composable
    fun HandleCardEdit(
        vm: EditCardViewModel, getUIStyle: GetUIStyle, onUpdate: () -> KaTeXMenu
    )
}

class BasicCardTypeHandler : CardTypeHandler {
    @Composable
    override fun HandleCardEdit(
        vm: EditCardViewModel, getUIStyle: GetUIStyle, onUpdate: () -> KaTeXMenu
    ) {
        EditBasicCard(vm)
    }
}

class ThreeCardTypeHandler : CardTypeHandler {
    @Composable
    override fun HandleCardEdit(

You will also need to:

  1. Remove the CT parameter from all other CardTypeHandler implementations.
  2. Update all calls to HandleCardEdit throughout the codebase to no longer pass a CT argument.
  3. Remove any logic that depends on the CT parameter within those implementations.

Comment on lines -104 to -105
question = fields.question.value,
answer = fields.answer.value
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): All usages of fields.question.value, fields.answer.value, etc. are replaced with fields.question, fields.answer, etc.

Ensure all fields are properly initialized and non-null, since the previous MutableState may have provided defaults.

Suggested implementation:

                // Ensure fields.question and fields.answer are non-null, provide defaults if necessary
                val question = fields.question ?: ""
                val answer = fields.answer ?: ""
                insertBasicCard(
                    BasicCard(
                        cardId = cardId,
                        question = question,
                        answer = answer
                    )
                )

  • If there are other usages of fields.* (e.g., fields.extra, fields.hint, etc.) in this or related functions, apply the same null-check/default-value pattern.
  • If CDetails is a data class you control, consider enforcing non-null types or providing default values at the data class level for even safer code.

Comment on lines +122 to +124
private var katexMenuWidth: Int
get() = sharedPreferences.getInt("menu_width", Int.MIN_VALUE)
set(value) = sharedPreferences.edit { putInt("menu_width", value) }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Default value for katexMenuWidth may be problematic.

Int.MIN_VALUE as a default for menu_width may cause UI issues if unset. Recommend using a sensible default like 200 to prevent negative values in the UI.

Suggested change
private var katexMenuWidth: Int
get() = sharedPreferences.getInt("menu_width", Int.MIN_VALUE)
set(value) = sharedPreferences.edit { putInt("menu_width", value) }
private var katexMenuWidth: Int
get() = sharedPreferences.getInt("menu_width", 200)
set(value) = sharedPreferences.edit { putInt("menu_width", value) }

Comment on lines +43 to +44
fun saveDynamicTheme() {
_dynamicTheme.update { !it }; isDynamicThemeEnabled = _dynamicTheme.value
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: saveDynamicTheme toggles the value rather than setting it explicitly.

Consider updating saveDynamicTheme to accept a Boolean parameter, aligning its behavior with saveCuteTheme and reducing potential confusion from unintended toggling.

Suggested implementation:

    fun saveDynamicTheme(enabled: Boolean) {
        _dynamicTheme.update { enabled }
        isDynamicThemeEnabled = enabled
    }

You will also need to update all usages of saveDynamicTheme() elsewhere in your codebase to pass a Boolean argument, e.g. saveDynamicTheme(true) or saveDynamicTheme(false), to match the new function signature.

Comment on lines +58 to +62
fun toParcelableNotationCard(parcel: Parcel): NotationCard? =
NotationCard(
cardId = parcel.readInt(),
question = parcel.readString()!!,
steps = listOf(parcel.readString()!!),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): steps field in toParcelableNotationCard only reads a single string.

Currently, only one step is read from the parcel. To support multiple steps, read the list size first and then read each step in a loop.

@xanderlmk xanderlmk deleted the more-card-options branch July 28, 2025 21:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants