Skip to content

Conversation

@VelikovPetar
Copy link
Contributor

@VelikovPetar VelikovPetar commented Dec 18, 2025

🎯 Goal

We currently have the following scenario: When opening the ChannelList offline, and there are no matching channels in the DB, we still show a loading screen for up to 5 seconds. This is caused by two seemingly unrelated things:

  1. Postponing the QueryChannels call for up to 5 seconds, if there is no current connectionId (no WS connection)
  2. Hiding the loading state ONLY if we have channels in the DB matching the query
// MoshiChatApi.kt

override fun queryChannels(query: QueryChannelsRequest): Call<List<Channel>> {
        val request = io.getstream.chat.android.client.api2.model.requests.QueryChannelsRequest(
            // ...
        )

        val lazyQueryChannelsCall = {
            channelApi.queryChannels(
                // ...
            )
        }

        val isConnectionRequired = query.watch || query.presence
        return if (connectionId.isBlank() && isConnectionRequired) {
            logger.i { "[queryChannels] postponing because an active connection is required" }
            postponeCall(lazyQueryChannelsCall)
        } else {
            lazyQueryChannelsCall()
        }
    }
// QueryChannelsLogic.kt

internal suspend fun queryOffline(pagination: AnyChannelPaginationRequest) {
        // ...

        queryChannelsDatabaseLogic.let { dbLogic ->
            fetchChannelsFromCache(pagination, dbLogic)
                .also { channels ->
                    if (channels.isNotEmpty()) {
                        addChannels(channels)
                        loadingPerPage(false, hasOffset)
                    }
                }
        }
    }

Because the DB query doesn't return channels we don't reset the loading state. Additionally, since the QueryChannels call is postponed for 5 seconds, the loading state is reset only after 5 seconds.

In this PR we now separate the logic for updating the loading state in QueryChannelsState covering two separate scenarios:

  1. No data in DB for the current query (first time querying) - we keep the current logic. We don't reset the loading state, and rely fully on the online result.
  2. Data for the current query exists in the DB (could be zero or more channels) - we optimistically set the data and reset the loading state (because we have already written data for that query in the DB)

Note: This has the drawback that if the first load of a specific query is done offline, the same 'bug' will appear again. But we currently cannot reliably know from the QueryChannelsLogic how the actual query will behave (will it be postponed, will it fail or succeed), so we cannot pre-emptively hide the loading state.

🛠 Implementation details

Implement different handling when we don't have any data in the DB for the current query (first run on the query), and different handling when we have data for the query (zero or more channels)

🎨 UI Changes

Before After (empty - first load) After (empty - second load) After (non-empty)
before.mp4
after-firstload.mp4
after-secondload.mp4
after-nonempty.mp4

🧪 Testing

  1. Apply the given patch (adds a query filter which doesn't match any channels)
  2. Login with "Petar Velikov"
  3. Kill app
  4. Turn of internet / Enter airplane mode
  5. Open the app
  6. The No channels screen should be immediately visible without bigger delay
Provide the patch summary here
Index: stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt
--- a/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt	(revision 08e7c73ec4c3a3022f2035aaf5b1cce2fd18e3e1)
+++ b/stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt	(date 1766059245424)
@@ -60,7 +60,6 @@
 import io.getstream.chat.android.compose.sample.ChatApp
 import io.getstream.chat.android.compose.sample.ChatHelper
 import io.getstream.chat.android.compose.sample.R
-import io.getstream.chat.android.compose.sample.feature.channel.ChannelConstants.CHANNEL_ARG_DRAFT
 import io.getstream.chat.android.compose.sample.feature.channel.add.AddChannelActivity
 import io.getstream.chat.android.compose.sample.feature.channel.add.group.AddGroupChannelActivity
 import io.getstream.chat.android.compose.sample.feature.channel.isGroupChannel
@@ -121,7 +120,7 @@
             filters = Filters.and(
                 Filters.eq("type", "messaging"),
                 Filters.`in`("members", listOf(currentUserId)),
-                Filters.or(Filters.notExists(CHANNEL_ARG_DRAFT), Filters.eq(CHANNEL_ARG_DRAFT, false)),
+                Filters.eq("name", "unknown"), // just a filter that yields no results
             ),
             chatEventHandlerFactory = CustomChatEventHandlerFactory(),
             isDraftMessageEnabled = true,

Summary by CodeRabbit

  • Bug Fixes

    • Fixed loading-state display when querying channels offline — UI no longer shows a persistent loading indicator when no matching channels exist in local storage; offline-to-online transitions behave more predictably.
  • Tests

    • Added comprehensive tests for offline query caching, loading-state transitions, empty-cache scenarios, and cache-delegation behaviors to improve reliability of offline channel queries.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Walkthrough

fetchChannelsFromCache now returns null when the query spec is not present in the DB instead of an empty list. QueryOffline and callers were updated to treat "spec not found" (null) separately from "spec found but no channels", and tests were added covering these behaviors.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Added entry documenting the fix for showing channel loading state when querying offline with no matching channels in DB.
Database Logic
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogic.kt
Changed fetchChannelsFromCache return type from List<Channel> to List<Channel>?; returns null when the query spec is absent and only fetches channels when spec exists.
Query Channels Logic
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogic.kt
Updated call site to handle nullable cache result; removed pre-update of cids before persisting; removed parseChatEventResult; added clearer logging distinguishing null vs. non-null cache results.
Database Logic Tests
stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
New tests covering null input spec, missing spec (returns null), found spec with channels, found spec with no channels (empty list), and delegation to repository/facade methods.
Query Channels Logic Tests
stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt
New tests for queryOffline: loading-state gating, first/more flags, cache fetch parameters, handling missing spec (null), adding cached channels and resetting loading, empty-cache handling, and insertion of query spec.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Client
    participant Logic as QueryChannelsLogic
    participant DBLogic as QueryChannelsDatabaseLogic
    participant Repo as RepositoryFacade
    participant State as QueryChannelsStateLogic

    Caller->>Logic: queryOffline(pagination, spec)
    alt query already loading
        Logic->>Caller: return / skip
    else not loading
        Logic->>State: set loading (first/more)
        Logic->>DBLogic: fetchChannelsFromCache(pagination, spec)
        DBLogic->>Repo: findQuerySpec(spec)
        alt spec not found
            Repo-->>DBLogic: spec missing
            DBLogic-->>Logic: null
            Logic->>State: leave loading state (no cache update)
            Note right of Logic: proceed to online fetch
        else spec found
            Repo-->>DBLogic: spec found
            DBLogic->>Repo: selectChannels(cids, pagination)
            Repo-->>DBLogic: channels[]
            DBLogic-->>Logic: channels[]
            Logic->>State: addChannels(channels)
            Logic->>State: clear loading
            Logic->>Repo: insertQueryChannels(spec)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • gpunto
  • aleksandar-apostolov

Poem

🐰 A hop, a fix, a cached null plea —
Now specs that vanish set the state free.
Empty lists no longer trick the light,
Tests stand guard through day and night,
I nibble code and cheer the harmony!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.54% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main fix: addressing the loading state display issue when channels are loaded offline. It directly reflects the primary objective of the PR.
Description check ✅ Passed The description comprehensively covers all required sections: Goal clearly explains the issue and root causes, Implementation details describe the solution approach, UI Changes include before/after videos, and Testing provides reproduction steps with a patch. It exceeds template requirements.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bug/AND-963_fix_showing_loading_when_channels_are_loaded_offline

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 29cc52f and 68e5e75.

📒 Files selected for processing (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Build / compose apks
  • GitHub Check: compare-sdk-sizes / Compare SDK sizes
  • GitHub Check: Debug build
  • GitHub Check: Unit tests
  • GitHub Check: API check

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • UTF-8: Entity not found: Issue - Could not find referenced Issue.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 18, 2025

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.25 MB 0.00 MB 🟢
stream-chat-android-offline 5.48 MB 5.48 MB 0.00 MB 🟢
stream-chat-android-ui-components 10.60 MB 10.60 MB 0.00 MB 🟢
stream-chat-android-compose 12.81 MB 12.81 MB 0.00 MB 🟢

@VelikovPetar VelikovPetar marked this pull request as ready for review December 18, 2025 12:21
@VelikovPetar VelikovPetar requested a review from a team as a code owner December 18, 2025 12:21
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
CHANGELOG.md (1)

35-37: Polish wording of the changelog entry for clarity

The current phrasing is understandable but a bit awkward. Consider tightening it to better describe the actual behavior change:

Suggested diff
- - Fix showing channels loading state when querying offline and no matching channels are found in the DB. [#6051](https://github.com/GetStream/stream-chat-android/pull/6051)
+ - Fix channel list remaining in loading state when querying offline and no matching channels are found in the DB. [#6051](https://github.com/GetStream/stream-chat-android/pull/6051)
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 59ae0b6 and 08e7c73.

📒 Files selected for processing (5)
  • CHANGELOG.md (1 hunks)
  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogic.kt (1 hunks)
  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogic.kt (2 hunks)
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt (1 hunks)
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,kts}

📄 CodeRabbit inference engine (AGENTS.md)

Format and apply Kotlin style with Spotless (4 spaces, no wildcard imports, licence headers)

Files:

  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogic.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogic.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt
**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/*.kt: Use @OptIn annotations explicitly; avoid suppressions unless documented
Document public APIs with KDoc, including thread expectations and state notes

Files:

  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogic.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogic.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt
**/src/test/**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/src/test/**/*.kt: Use backtick test names (for example: fun message list filters muted channels()) for readability
Use deterministic tests with runTest + virtual time for concurrency-sensitive logic (uploads, sync, message state)
Keep helper extensions private/internal in test files

Files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt
🧠 Learnings (4)
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/src/test/**/*.kt : Use deterministic tests with `runTest` + virtual time for concurrency-sensitive logic (uploads, sync, message state)

Applied to files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*Test.kt : Add Paparazzi snapshots for Compose UI regressions and run `verifyPaparazziDebug`

Applied to files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-ui-components/**/*Test.kt : Record Shot baselines when behaviour changes in XML kit UI tests

Applied to files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/src/test/**/*.kt : Use backtick test names (for example: `fun `message list filters muted channels`()`) for readability

Applied to files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt
🧬 Code graph analysis (2)
stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt (2)
stream-chat-android-client-test/src/main/java/io/getstream/chat/android/client/test/Mother.kt (1)
  • randomQueryChannelsSpec (654-658)
stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt (2)
  • randomChannelConfig (584-585)
  • randomString (94-98)
stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt (1)
stream-chat-android-core/src/main/java/io/getstream/chat/android/models/Filters.kt (1)
  • eq (57-58)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Test compose (2)
  • GitHub Check: Test compose (1)
  • GitHub Check: Test compose (0)
🔇 Additional comments (19)
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogic.kt (1)

41-63: LGTM! Clear null semantics for cache miss.

The updated signature and KDoc clearly distinguish between "spec not found in DB" (null) and "spec found with zero channels" (empty list). The implementation correctly uses safe navigation to return null when no cached spec exists.

stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsDatabaseLogicTest.kt (8)

41-54: LGTM! Clean test setup with appropriate mocks.

The test class correctly initializes all required dependencies as mocks and creates the system under test with proper dependency injection.


55-69: LGTM! Test follows guidelines and verifies delegation correctly.

Uses backtick naming convention and runTest as per coding guidelines.


71-82: LGTM! Correctly tests null spec scenario.

The test validates the new behavior where a null queryChannelsSpec input returns null, indicating no cached data to fetch.


84-100: LGTM! Validates cache miss behavior.

The test correctly verifies that when the repository returns null for a spec lookup, fetchChannelsFromCache returns null.


102-138: LGTM! Comprehensive happy path test.

The test thoroughly validates the successful fetch scenario, including pagination parameters, cid matching, and repository interactions.


140-164: LGTM! Critical test for the PR's core fix.

This test is essential as it validates the distinction between "spec not found" (null) and "spec found with zero channels" (empty list), which is the key to fixing the offline loading state issue described in the PR.


166-204: LGTM! Delegation tests are complete and correct.

Both selectChannel and selectChannels tests properly verify delegation to the channel repository.


206-235: LGTM! Insert operations properly tested.

Both insertQueryChannels and insertChannelConfigs tests correctly verify delegation to their respective repositories.

stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogic.kt (2)

51-71: LGTM! Correctly implements the split offline query logic.

The implementation properly distinguishes between two scenarios as intended:

  • Null result: No cached spec found → maintains loading state and waits for online data
  • Non-null result: Spec found with 0+ channels → optimistically updates state and clears loading indicator

This directly addresses the PR's objective of preventing prolonged loading screens when querying offline with no matching channels in the database.


91-107: LGTM! Proper handling of nullable result with helpful logging.

The method correctly handles the nullable return type from the database logic and provides clear diagnostic logging to distinguish between "no cached spec" (null) and "spec found with N channels" (non-null).

stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/logic/querychannels/internal/QueryChannelsLogicTest.kt (8)

42-77: LGTM! Well-structured test setup.

The test class properly initializes all dependencies with mocks and uses @BeforeEach to ensure a clean state for each test. The use of TestCoroutineRule aligns with the coding guideline for deterministic coroutine tests.


79-93: LGTM! Correctly verifies early return guard.

The test ensures that when a query is already in progress, queryOffline returns early without performing any operations, preventing duplicate queries.


95-110: LGTM! Validates first page loading state.

The test correctly verifies that when offset is 0, the first page loading indicator is set, not the "loading more" indicator.


112-127: LGTM! Validates pagination loading state.

The test correctly verifies that when offset > 0, the "loading more" indicator is set, not the first page loading indicator.


129-147: LGTM! Verifies correct parameter passing.

The test ensures that fetchChannelsFromCache receives the correct pagination request and query spec.


149-165: LGTM! Critical test for the PR's core fix.

This test validates the essential behavior where, when no cached spec is found (null return), the loading state remains active to await online data. This prevents immediately showing an empty state when offline with no cached data, which was the PR's objective.


167-189: LGTM! Validates optimistic cache update flow.

The test correctly verifies that when cached channels are found, they are added to the state and the loading indicator is cleared, providing immediate feedback to the user.


191-228: LGTM! Completes the test coverage for offline query scenarios.

The first test validates the crucial case where a cached spec exists but has no channels (empty list), ensuring the loading state is properly cleared even with zero results. The second test verifies that the query spec is persisted after adding channels, maintaining consistency between in-memory state and database.

Copy link
Contributor

@gpunto gpunto left a comment

Choose a reason for hiding this comment

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

Forgot to approve: just left a comment to understand a similar scenario (which is not changed by this PR)

@VelikovPetar
Copy link
Contributor Author

Forgot to approve: just left a comment to understand a similar scenario (which is not changed by this PR)
@gpunto I think it is a valid concern: Before this change, the user would see a loading screen (not the empty one) before showing the new results. But after the change, they will see empty state -> results state.

@gpunto
Copy link
Contributor

gpunto commented Dec 18, 2025

Forgot to approve: just left a comment to understand a similar scenario (which is not changed by this PR)

@gpunto I think it is a valid concern: Before this change, the user would see a loading screen (not the empty one) before showing the new results. But after the change, they will see empty state -> results state.

Right! We were checking for emptiness 👍

@sonarqubecloud
Copy link

@VelikovPetar VelikovPetar merged commit e8f0426 into develop Dec 23, 2025
17 of 18 checks passed
@VelikovPetar VelikovPetar deleted the bug/AND-963_fix_showing_loading_when_channels_are_loaded_offline branch December 23, 2025 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants