Skip to content

refactor: migrate preferences to DataStore and decouple core:domain for KMP#4731

Merged
jamesarich merged 5 commits intomainfrom
feat/prefs-datastore
Mar 6, 2026
Merged

refactor: migrate preferences to DataStore and decouple core:domain for KMP#4731
jamesarich merged 5 commits intomainfrom
feat/prefs-datastore

Conversation

@jamesarich
Copy link
Copy Markdown
Collaborator

Key Changes

  • DataStore Migration: Replaced SharedPreferences with DataStore across all modules, utilizing SharedPreferencesMigration to ensure zero data loss for existing users.
  • Reactive Architecture: Refactored all preference interfaces (UI, Radio, Map, etc.) from synchronous var properties to reactive StateFlows, improving UI consistency and thread safety.
  • Architectural Decoupling: Relocated preference interfaces to the KMP-compatible :core:repository module, allowing :core:domain to consume settings without depending on the Android-bound :core:prefs.
  • KMP Readiness: Converted :core:datastore to a full KMP module using OkioSerializer and OkioStorage.

- Convert the `core:datastore` module to a Kotlin Multiplatform (KMP) configuration.
- Relocate data sources, models, and serializers in `core:datastore` to `commonMain` and update serializers to implement `OkioSerializer`.
- Extract `MeshLogRepository` into a platform-agnostic interface in `core:repository` and move the concrete implementation to `MeshLogRepositoryImpl` in `core:data`.
- Move the `DatabaseManager` interface from `core:repository` to `core:common:database`.
- Update the `core:domain` module configuration to remove the direct dependency on `core:data`, favoring repository interfaces.
- Update package imports and dependency injections across multiple features (node, map, settings) and internal managers to reflect the new repository and database manager locations.

Signed-off-by: James Rich <[email protected]>
…itory

- Move preference interfaces from `core:prefs` to `core:repository` to decouple storage implementation from domain logic.
- Transition preference properties to reactive `StateFlow` and explicit setter methods (e.g., `setLoggingEnabled`) to support better observability.
- Introduce `PreferenceFlows.kt` to provide a utility for converting `SharedPreferences` listeners into Kotlin Flows.
- Update ViewModels, UseCases, and Repository implementations across the project to use the new reactive preference APIs.
- Consolidate common preference interfaces into an `AppPreferences` contract.
- Standardize preference implementations with Dagger/Hilt and `CoroutineDispatchers`.

Signed-off-by: James Rich <[email protected]>
- Replace `SharedPreferences` with `DataStore<Preferences>` across all preference implementation classes, including `AnalyticsPrefs`, `MeshPrefs`, `UiPrefs`, `MapPrefs`, and `RadioPrefs`.
- Remove custom `SharedPreferences` property delegates (`PrefDelegate`, `DoublePrefDelegate`, etc.) and the `preferenceFlow` helper in favor of `DataStore`'s native Flow support.
- Update `PrefsModule` and `GoogleMapsModule` to provide `DataStore` instances using `SharedPreferencesMigration` to ensure data persistence for existing users.
- Refactor `GoogleMapsPrefs` to expose settings as `StateFlow` properties and use explicit setter methods for updates.
- Update `MapViewModel` to consume preference changes via `StateFlow` and use asynchronous setters.
- Relocate `DataStoreModule` from `core:datastore` to `core:data`.
- Update `FilterPrefsTest` to use `PreferenceDataStoreFactory` and `runTest` for verifying preference logic.
- Update module dependencies to include `androidx.datastore` and remove obsolete references to `core:prefs` where applicable.

Signed-off-by: James Rich <[email protected]>
- Standardize `DataStore` preference implementations by compacting `StateFlow` declarations and applying consistent formatting to `edit` blocks across all `PrefsImpl` classes.
- Update copyright headers to include 2026 in core datastore and model files.
- Improve unit test reliability in `MessageFilterImplTest` and `MapViewModelTest` by using `MutableStateFlow` to mock reactive preference properties.
- Perform general code style cleanup, including adding trailing commas, adjusting vertical whitespace in interfaces/modules, and removing redundant safe calls in `MetricsViewModel`.
- Add `@Suppress("TooManyFunctions")` to the `MeshLogRepository` interface.
- Ensure consistent use of `SharingStarted.Eagerly` for preference-backed `StateFlow`s.

Signed-off-by: James Rich <[email protected]>
@github-actions github-actions bot added the enhancement New feature or request label Mar 6, 2026
@jamesarich jamesarich requested a review from Copilot March 6, 2026 01:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the app’s settings infrastructure to support Kotlin Multiplatform by moving preference interfaces into :core:repository, migrating Android implementations from SharedPreferences to DataStore<Preferences> (with SharedPreferencesMigration), and converting many preference reads/writes to reactive StateFlow patterns across features and core modules.

Changes:

  • Migrates preference APIs from synchronous getters/setters to StateFlow + explicit setter methods and updates call sites.
  • Introduces/relocates KMP-friendly repository interfaces (e.g., AppPreferences, MeshLogRepository) and updates DI bindings.
  • Converts :core:datastore to KMP using Okio (OkioSerializer/OkioStorage) and adds new proto DataSources.

Reviewed changes

Copilot reviewed 109 out of 113 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
feature/settings/src/test/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModelTest.kt Updates preference interface imports to repository module.
feature/settings/src/test/kotlin/org/meshtastic/feature/settings/filter/FilterSettingsViewModelTest.kt Adjusts tests for StateFlow-based prefs and setter methods.
feature/settings/src/test/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModelTest.kt Updates mocks/verifications for flow-based MeshLog prefs.
feature/settings/src/test/kotlin/org/meshtastic/feature/settings/SettingsViewModelTest.kt Updates imports for moved DatabaseManager/prefs interfaces.
feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt Uses reactive consent preference via StateFlow.
feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt Switches analytics/homoglyph flows to repository prefs StateFlows.
feature/settings/src/main/kotlin/org/meshtastic/feature/settings/filter/FilterSettingsViewModel.kt Migrates filter prefs usage to flow + setter methods.
feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt Migrates MeshLog prefs usage to flow + setter methods.
feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsViewModel.kt Migrates MeshLog prefs reads to flow-based values.
feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt Updates repository dependency and telemetry time filtering logic.
feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt Updates MeshLogRepository import to new shared interface.
feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt Migrates UI/emoji/homoglyph prefs usage to flow-based prefs.
feature/map/src/testGoogle/kotlin/org/meshtastic/feature/map/MapViewModelTest.kt Updates map prefs mocks to provide StateFlow values.
feature/map/src/main/kotlin/org/meshtastic/feature/map/node/NodeMapViewModel.kt Updates MapPrefs access to StateFlow value.
feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt Migrates map prefs access to flow-based prefs + setter methods.
feature/map/src/google/kotlin/org/meshtastic/feature/map/MapViewModel.kt Updates Google map prefs to flow-based getters + setter methods.
feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewModel.kt Updates MapPrefs map style to StateFlow and setter method.
feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt Updates RadioPrefs to flow-based devAddr.
feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateManager.kt Updates RadioPrefs access to devAddr.value.
core/ui/src/main/kotlin/org/meshtastic/core/ui/emoji/EmojiPickerViewModel.kt Migrates emoji frequency preference to StateFlow + setter.
core/repository/src/commonMain/kotlin/org/meshtastic/core/repository/usecase/SendMessageUseCase.kt Reads homoglyph encoding enabled from StateFlow.
core/repository/src/commonMain/kotlin/org/meshtastic/core/repository/MeshLogRepository.kt Adds shared (KMP) MeshLogRepository interface.
core/repository/src/commonMain/kotlin/org/meshtastic/core/repository/HomoglyphPrefs.kt Removes obsolete non-reactive homoglyph prefs interface file.
core/repository/src/commonMain/kotlin/org/meshtastic/core/repository/AppPreferences.kt Adds consolidated reactive preference interfaces for KMP.
core/repository/build.gradle.kts Adds database dependency needed by repository module.
core/prefs/src/test/kotlin/org/meshtastic/core/prefs/filter/FilterPrefsTest.kt Migrates tests to DataStore-backed FilterPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/ui/UiPrefsImpl.kt Adds DataStore-backed UiPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/ui/UiPrefs.kt Removes SharedPreferences-based UiPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/radio/RadioPrefsImpl.kt Adds DataStore-backed RadioPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/radio/RadioPrefs.kt Removes SharedPreferences-based RadioPrefs API/impl and extensions.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/meshlog/MeshLogPrefsImpl.kt Adds DataStore-backed MeshLogPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/meshlog/MeshLogPrefs.kt Removes SharedPreferences-based MeshLogPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefsImpl.kt Adds DataStore-backed MeshPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt Removes SharedPreferences-based MeshPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapTileProviderPrefsImpl.kt Adds DataStore-backed tile provider prefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapTileProviderPrefs.kt Removes SharedPreferences-based tile provider prefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapPrefsImpl.kt Adds DataStore-backed MapPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapPrefs.kt Removes SharedPreferences-based MapPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapConsentPrefsImpl.kt Adds DataStore-backed MapConsentPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapConsentPrefs.kt Removes SharedPreferences-based MapConsentPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/homoglyph/HomoglyphPrefsImpl.kt Adds DataStore-backed HomoglyphPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/homoglyph/HomoglyphPrefs.kt Removes SharedPreferences-based HomoglyphPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/filter/FilterPrefsImpl.kt Adds DataStore-backed FilterPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/filter/FilterPrefs.kt Removes SharedPreferences-based FilterPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/emoji/CustomEmojiPrefsImpl.kt Adds DataStore-backed CustomEmojiPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/emoji/CustomEmojiPrefs.kt Removes SharedPreferences-based CustomEmojiPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/di/PrefsModule.kt Replaces SharedPreferences providers with DataStore providers + migrations.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/analytics/AnalyticsPrefsImpl.kt Adds DataStore-backed AnalyticsPrefs implementation.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/analytics/AnalyticsPrefs.kt Removes SharedPreferences-based AnalyticsPrefs API/impl.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/StringSetPrefDelegate.kt Removes SharedPreferences delegate helper.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/PrefDelegate.kt Removes SharedPreferences delegate helper.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/NullableStringPrefDelegate.kt Removes SharedPreferences delegate helper.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/FloatPrefDelegate.kt Removes SharedPreferences delegate helper.
core/prefs/src/main/kotlin/org/meshtastic/core/prefs/DoublePrefDelegate.kt Removes SharedPreferences delegate helper.
core/prefs/src/google/kotlin/org/meshtastic/core/prefs/map/GoogleMapsPrefs.kt Migrates GoogleMapsPrefs to DataStore + StateFlow API.
core/prefs/src/google/kotlin/org/meshtastic/core/prefs/di/GoogleMapsModule.kt Provides GoogleMaps DataStore + migration via Hilt.
core/prefs/build.gradle.kts Adds DataStore/coroutines deps for new pref implementations and tests.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/settings/ToggleHomoglyphEncodingUseCaseTest.kt Updates test to use flow-based HomoglyphPrefs API.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/settings/ToggleAnalyticsUseCaseTest.kt Updates test to use flow-based AnalyticsPrefs API.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/settings/SetProvideLocationUseCaseTest.kt Updates UiPrefs import to repository module.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/settings/SetMeshLogSettingsUseCaseTest.kt Updates MeshLog prefs/repo imports + flow access.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/settings/SetDatabaseCacheLimitUseCaseTest.kt Updates DatabaseManager import to new common location.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/settings/IsOtaCapableUseCaseTest.kt Updates RadioPrefs mocking to provide StateFlow.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/settings/ExportDataUseCaseTest.kt Updates MeshLogRepository import to shared interface.
core/domain/src/test/kotlin/org/meshtastic/core/domain/usecase/SendMessageUseCaseTest.kt Updates homoglyph enabled mocking to use StateFlow.
core/domain/src/main/kotlin/org/meshtastic/core/domain/usecase/settings/ToggleHomoglyphEncodingUseCase.kt Migrates toggle logic to StateFlow + setter.
core/domain/src/main/kotlin/org/meshtastic/core/domain/usecase/settings/ToggleAnalyticsUseCase.kt Migrates toggle logic to StateFlow + setter.
core/domain/src/main/kotlin/org/meshtastic/core/domain/usecase/settings/SetProvideLocationUseCase.kt Updates UiPrefs import to repository module.
core/domain/src/main/kotlin/org/meshtastic/core/domain/usecase/settings/SetMeshLogSettingsUseCase.kt Migrates MeshLog setting updates to new prefs API.
core/domain/src/main/kotlin/org/meshtastic/core/domain/usecase/settings/SetDatabaseCacheLimitUseCase.kt Updates DatabaseManager import to core.common.database.
core/domain/src/main/kotlin/org/meshtastic/core/domain/usecase/settings/IsOtaCapableUseCase.kt Updates RadioPrefs imports/extensions to repository module.
core/domain/src/main/kotlin/org/meshtastic/core/domain/usecase/settings/ExportDataUseCase.kt Updates MeshLogRepository import to shared interface.
core/domain/build.gradle.kts Removes core:prefs/core:data deps from domain to support decoupling.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/serializer/ModuleConfigSerializer.kt Converts proto serializer to OkioSerializer for KMP.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/serializer/LocalStatsSerializer.kt Converts proto serializer to OkioSerializer for KMP.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/serializer/LocalConfigSerializer.kt Converts proto serializer to OkioSerializer for KMP.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/serializer/ChannelSetSerializer.kt Converts proto serializer to OkioSerializer for KMP.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/model/RecentAddress.kt Updates header; minor formatting cleanup.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/UiPreferencesDataSource.kt Exposes keys as public constants (visibility change).
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/RecentAddressesDataSource.kt Updates header; minor formatting cleanup.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/ModuleConfigDataSource.kt Adds DataSource wrapper for LocalModuleConfig DataStore.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/LocalStatsDataSource.kt Adds DataSource wrapper for LocalStats DataStore.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/LocalConfigDataSource.kt Adds DataSource wrapper for LocalConfig DataStore.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/ChannelSetDataSource.kt Adds DataSource wrapper for ChannelSet DataStore.
core/datastore/src/commonMain/kotlin/org/meshtastic/core/datastore/BootloaderWarningDataSource.kt Updates header; minor formatting cleanup.
core/datastore/build.gradle.kts Converts module to KMP and adds Okio/Hilt-related wiring.
core/database/src/androidMain/kotlin/org/meshtastic/core/database/DatabaseManager.kt Updates shared DatabaseManager import alias to new package.
core/database/build.gradle.kts Removes repository dependency from database module to break coupling.
core/data/src/test/kotlin/org/meshtastic/core/data/repository/MeshLogRepositoryTest.kt Updates to use MeshLogRepositoryImpl name and new prefs import.
core/data/src/test/kotlin/org/meshtastic/core/data/manager/PacketHandlerImplTest.kt Updates MeshLogRepository import to shared interface.
core/data/src/test/kotlin/org/meshtastic/core/data/manager/MessageFilterImplTest.kt Updates filter prefs mocking for flow-based prefs.
core/data/src/test/kotlin/org/meshtastic/core/data/manager/MeshConnectionManagerImplTest.kt Updates UiPrefs import to repository module.
core/data/src/main/kotlin/org/meshtastic/core/data/repository/MeshLogRepositoryImpl.kt Implements new shared MeshLogRepository interface.
core/data/src/main/kotlin/org/meshtastic/core/data/manager/PacketHandlerImpl.kt Updates MeshLogRepository import to shared interface.
core/data/src/main/kotlin/org/meshtastic/core/data/manager/MessageFilterImpl.kt Updates FilterPrefs access to use StateFlow.value.
core/data/src/main/kotlin/org/meshtastic/core/data/manager/MeshMessageProcessorImpl.kt Updates MeshLogRepository import to shared interface.
core/data/src/main/kotlin/org/meshtastic/core/data/manager/MeshConnectionManagerImpl.kt Updates UiPrefs import to repository module.
core/data/src/main/kotlin/org/meshtastic/core/data/manager/MeshActionHandlerImpl.kt Updates MeshPrefs/DatabaseManager imports and flow-based reads.
core/data/src/main/kotlin/org/meshtastic/core/data/manager/HistoryManagerImpl.kt Updates MeshPrefs reads to use StateFlow.value.
core/data/src/main/kotlin/org/meshtastic/core/data/di/RepositoryModule.kt Binds MeshLogRepository interface to MeshLogRepositoryImpl.
core/data/src/main/kotlin/org/meshtastic/core/data/di/DatabaseModule.kt Rebinds DatabaseManager to new core.common.database interface.
core/data/src/main/kotlin/org/meshtastic/core/data/di/DataStoreModule.kt Moves DataStore module and switches proto stores to OkioStorage.
core/data/src/google/kotlin/org/meshtastic/core/data/repository/CustomTileProviderRepository.kt Updates MapTileProviderPrefs usage to flow + setter API.
core/data/build.gradle.kts Adds datastore deps needed by refactored DataStore module usage.
core/common/src/commonMain/kotlin/org/meshtastic/core/common/database/DatabaseManager.kt Moves DatabaseManager interface into core.common.database package.
core/analytics/src/google/kotlin/org/meshtastic/core/analytics/platform/GooglePlatformAnalytics.kt Updates analytics preference listening to StateFlow.
core/analytics/build.gradle.kts Adds repository dependency to match new prefs interface location.
app/src/main/java/com/geeksville/mesh/worker/MeshLogCleanupWorker.kt Migrates MeshLog prefs to flow-based reads and repository imports.
app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt Migrates UiPrefs usage to flow-based reads and setter methods.
app/src/main/java/com/geeksville/mesh/repository/radio/AndroidRadioInterfaceService.kt Migrates RadioPrefs usage to flow-based reads and setter method.
app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt Updates MeshLogRepository import to shared interface.
app/src/main/java/com/geeksville/mesh/MeshUtilApplication.kt Updates MeshPrefs/MeshLogPrefs imports and flow-based access.
app/src/androidTest/java/com/geeksville/mesh/filter/MessageFilterIntegrationTest.kt Updates filter prefs to setter methods and repository import.

You can also share your feedback on Copilot code review. Take the survey.

…checks

- Update `AppPreferences` interface and `AnalyticsPrefsImpl` to expose `installId` as a `StateFlow<String>`, facilitating reactive and non-blocking access.
- Remove `runBlocking` call in `AnalyticsPrefsImpl` and move UUID generation logic to an asynchronous `init` block.
- Simplify logic in `MetricsViewModel` by removing redundant null-coalescing operators (`?: 0`) on properties that are now non-nullable.

Signed-off-by: James Rich <[email protected]>
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (63984f0) to head (ee27be6).
⚠️ Report is 9 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@          Coverage Diff          @@
##            main   #4731   +/-   ##
=====================================
  Coverage   0.00%   0.00%           
=====================================
  Files          3       3           
  Lines        231     231           
  Branches      34      34           
=====================================
  Misses       231     231           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jamesarich jamesarich added this pull request to the merge queue Mar 6, 2026
@jamesarich jamesarich removed this pull request from the merge queue due to a manual request Mar 6, 2026
@jamesarich jamesarich merged commit b9b68d2 into main Mar 6, 2026
6 checks passed
@jamesarich jamesarich deleted the feat/prefs-datastore branch March 6, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants