Skip to content

Feat/performance ux improvements#12

Merged
sitholevunene373-lab merged 8 commits into
mainfrom
feat/performance-ux-improvements
Jun 19, 2026
Merged

Feat/performance ux improvements#12
sitholevunene373-lab merged 8 commits into
mainfrom
feat/performance-ux-improvements

Conversation

@sitholevunene373-lab

@sitholevunene373-lab sitholevunene373-lab commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Enhanced premium UI/UX with updated typography, semantic color palette, and smoother animations
    • Added dark mode with persisted theme toggle, improved focus-visible accessibility, and touch-friendly responsive layouts
    • Improved message row interactions (selection, starring, unread styling, and clearer thread metadata)
    • Improved user feedback with optimistic starring (rollback on failure), skeleton loading, and toast notifications
    • Enhanced empty-state search suggestions and added keyboard shortcuts for faster navigation
  • Chores

    • Added reusable async/debounce helpers and performance measurement utilities

@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flow Error Error Jun 19, 2026 5:51pm

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a MessageRow React component, a useAsync lifecycle hook, a useDebounce hook, and performance.ts measurement utilities. Also adds UX_IMPROVEMENTS.md, a comprehensive spec document covering design tokens, interaction patterns with code examples, accessibility guidance, responsive/dark-mode CSS patterns, and a phased implementation checklist.

Changes

Implementation: hooks, utilities, and MessageRow

Layer / File(s) Summary
useAsync and useDebounce hooks
src/hooks/useAsync.ts, src/hooks/useDebounce.ts
useAsync manages idle/pending/success/error state for an async function with an unmount guard via mountedRef; useDebounce delays value propagation using setTimeout/cleanup inside an effect.
Performance monitoring utilities
src/lib/performance.ts
PerformanceMetrics interface, an internal zeroed metrics object, measurePerformance/measureAsyncPerformance wrappers using performance.now() with dev-mode console logging, and reportMetrics().
MessageRow component
src/components/MessageRow.tsx
Memoized client component rendering a mail thread row: select checkbox, star button, ContactHoverCard sender display, subject/preview text, outbound tracking badge, thread count indicator, and formatted date.

UX Improvements Specification

Layer / File(s) Summary
Design tokens
UX_IMPROVEMENTS.md (lines 1–178)
CSS variable definitions for typography, semantic color palette with prefers-color-scheme: dark override and migration strategy, spacing scale, elevation shadows and radius scale, and transition variables with fadeInMessage keyframe animation.
Interaction pattern examples
UX_IMPROVEMENTS.md (lines 181–353)
Code snippets for keyboard shortcut handlers with input-focus guard, optimistic star-toggle with server POST and revert-on-failure, SkeletonLoader conditional rendering, Toast interface with UUID IDs and auto-dismiss, and empty-state search suggestions UI with preset queries.
Accessibility, responsive/dark mode, and roadmap
UX_IMPROVEMENTS.md (lines 357–564)
:focus-visible and ARIA labeling guidance with explicit WCAG AA/AAA contrast claims, responsive grid and larger touch-target CSS at media breakpoints, automatic and manual dark-mode overrides with useThemeToggle hook, performance visual feedback guidelines, Gmail/Outlook feature comparison table, and phased implementation priority checklist.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hooks and helpers hop on by,
Async guards and debounce's sigh.
MessageRow threads in UI glow,
Performance metrics stealth and slow.
Dark mode themes and toasts take flight—
UX spec shines bold and bright! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and generic, using broad marketing-style language ('Feat/performance ux improvements') that lacks specificity about the actual implementation details. Use a more descriptive title that highlights the primary change, such as 'Add performance monitoring and UX documentation with hooks' or 'Introduce async/debounce hooks and design system documentation'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/performance-ux-improvements

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.0)
src/components/MessageRow.tsx

File contains syntax errors that prevent linting: Line 18: ';' expected'; Line 18: Expected a semicolon or an implicit semicolon after a statement, but found none; Line 38: Expected a statement but instead found '}'.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/components/MessageRow.tsx

Parsing error: Property or signature expected.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (2)
UX_IMPROVEMENTS.md (2)

235-245: ⚡ Quick win

Improve optimistic update rollback to handle undefined message state safely.

In the rollback logic (line 240), the code uses message?.starred to restore the previous value. If message is undefined, the rollback will set starred: undefined instead of a boolean, potentially breaking downstream code that expects a boolean.

Recommend storing the original starred state before the optimistic update:

const toggleStarred = (messageId: string) => {
+  const originalStarred = messages.find(m => m.id === messageId)?.starred;
+
  setMessages(current =>
    current.map(item =>
      item.id === messageId ? { ...item, starred: !item.starred } : item
    )
  );

  fetch(...)
    .catch(() => {
      setMessages(current =>
        current.map(item =>
          item.id === messageId 
-            ? { ...item, starred: message?.starred }
+            ? { ...item, starred: originalStarred }
            : item
        )
      );
    });
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@UX_IMPROVEMENTS.md` around lines 235 - 245, The rollback logic in the catch
block uses message?.starred to restore the previous state, but if message is
undefined, this will set starred to undefined instead of a boolean, causing
issues in downstream code. Before the optimistic setMessages call, capture and
store the original starred value from the message object (e.g., const
originalStarred = message?.starred), then use this stored originalStarred
variable in the rollback logic instead of message?.starred to ensure the state
is always restored to a valid boolean value.

168-168: 💤 Low value

Specify exact file locations and integration points for code examples.

The spec provides code snippets with directives like "Add to FlowConsole.tsx" (line 168) and "Create SkeletonLoader component" (line 254), but does not specify:

  • Which file should host the SkeletonLoader component (e.g., src/components/SkeletonLoader.tsx)?
  • Whether keyboard shortcuts should go into a dedicated hook (e.g., src/hooks/useKeyboardShortcuts.ts) or inline in FlowConsole?
  • Whether Toast notifications should use the component added in this PR or a new Toast system?

Clarity on these integration points will help developers implement the spec consistently and avoid duplication.

Also applies to: 254-254

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@UX_IMPROVEMENTS.md` at line 168, The UX_IMPROVEMENTS.md specification lacks
clarity on where certain components and functionality should be implemented.
Update the specification to explicitly define file locations and integration
points: specify the exact file path where the SkeletonLoader component should be
created (e.g., src/components/SkeletonLoader.tsx), clarify whether keyboard
shortcuts should be implemented in a dedicated hook file (e.g.,
src/hooks/useKeyboardShortcuts.ts) or inline within FlowConsole.tsx, and specify
whether the Toast notification system should reuse an existing Toast component
from the codebase or introduce a new Toast system. This will provide developers
with unambiguous guidance and prevent implementation inconsistencies and code
duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/MessageRow.tsx`:
- Around line 18-20: In the MessageRow.tsx file, replace the `any` type with
`ContactPreview` type for the contact parameters in the callback function
signatures. Specifically, update the `onOpenCompose` callback on line 18 and the
`onShowStatus` callback on line 19 to use `contact: ContactPreview` instead of
`contact: any`. Ensure that `ContactPreview` is imported from
`@/lib/flow-console/types` at the top of the file to resolve the TypeScript
linting violation.

In `@src/hooks/useAsync.ts`:
- Around line 39-47: The cleanup function in the useEffect hook sets
mountedRef.current to false, which runs before the effect re-executes when
dependencies change. This prevents the state updates in the execute function
(the setStatus calls that check mountedRef.current at lines 25 and 29) from
succeeding on subsequent effect runs. To fix this, set mountedRef.current to
true at the beginning of the effect body (after the immediate check), before any
execute() calls, so that state updates can proceed when dependencies change.
Keep the cleanup function that sets it to false to handle actual unmount
scenarios.

In `@src/lib/performance.ts`:
- Around line 11-15: The metrics object is initialized but its properties are
never updated when durations are computed in the wrapper functions. For each
wrapper function (referenced in lines 17-28 and 30-48 that compute duration
values), add assignments to update the corresponding metric property in the
metrics object (such as metrics.renderTime, metrics.searchTime,
metrics.apiTime). Additionally, the reportMetrics() function at line 47 returns
the mutable singleton by reference, which allows callers to modify the internal
state. Change reportMetrics() to return a copy or immutable version of the
metrics object to prevent external modifications.

In `@UX_IMPROVEMENTS.md`:
- Around line 38-82: The new CSS color tokens defined in the UX_IMPROVEMENTS.md
file (--color-primary, --color-gray-*, --color-bg, --color-text-*) conflict with
existing semantic variables already defined in src/app/styles/base.css
(--flow-muted, --blue, --red, etc.). Decide on a merge strategy: either fully
migrate to the new naming scheme by deprecating old tokens and updating all
component usage (like MessageRow), or establish the new tokens as aliases
mapping to existing variables (e.g., --color-primary: var(--blue);). Document
the chosen approach clearly in the UX_IMPROVEMENTS.md spec and verify that
component implementations throughout the codebase are updated consistently to
use the appropriate token set.
- Around line 73-81: The dark mode variable definitions in the `@media`
(prefers-color-scheme: dark) block (lines 73-81) and the html[data-theme='dark']
block (lines 428-431) have unclear precedence rules, making it ambiguous whether
the manual toggle or system preference takes priority. Add explicit
documentation stating which approach takes precedence (e.g., "manual toggle wins
if both are set"), provide a complete example demonstrating how both dark mode
approaches interact correctly using CSS specificity techniques like :where() or
explicit selector ordering, and document the JavaScript logic required to set
the data-theme attribute when users manually toggle dark mode so the
implementation is clear and maintainable.
- Around line 113-116: The new border-radius token scale (--radius-sm,
--radius-md, --radius-lg, --radius-full) conflicts with the existing --radius
token defined in src/app/styles/base.css set to 0.625rem (~10px). Decide whether
to: (1) completely replace the old --radius definition with the new scale and
update all references throughout the codebase to use the appropriate new token,
or (2) keep both but clarify their relationship by mapping the existing --radius
to one of the new scale values (such as --radius-md). Once decided, update the
token definitions in both UX_IMPROVEMENTS.md and src/app/styles/base.css to be
consistent, and ensure all component styles that reference --radius are updated
accordingly to prevent visual regressions.
- Around line 365-368: The Color Contrast section in the UX_IMPROVEMENTS.md file
claims WCAG AA compliance but lacks actual measured contrast ratio data for the
specific color pairs defined in the palette. Verify the actual contrast ratios
for each color combination (--color-text-secondary on --color-bg,
--color-text-disabled on --color-bg, and dark mode variants) using a WCAG
contrast checker tool like WebAIM Contrast Checker. Document the measured
contrast ratios for each pair in the Color Contrast section, and if any
combination fails to meet the stated 4.5:1 (normal text) or 3:1 (large text)
standards, either adjust the color values in the palette to meet the standards
or remove the specific compliance claim from the documentation.
- Around line 182-208: The handleKeyDown function inside the useEffect hook
needs to call e.preventDefault() after each keyboard shortcut action is
executed. For each case in the switch statement (cases 'j', 'k', 'c', 'r', and
'e'), add e.preventDefault() after the corresponding action call to prevent the
default browser behavior and avoid conflicts with accessibility tools.
Additionally, consider implementing a help dialog accessible via the question
mark key to document available shortcuts and provide users with a way to
understand or disable them.
- Around line 296-310: The className attribute on the toast div uses a
non-existent Tailwind class animate-fade-in. Replace animate-fade-in with the
correct animation classes animate-in fade-in, which are provided by the
tw-animate-css library that the project uses for enter/exit animations. This
should be done in the className template string where the conditional styling is
applied to the toast container div that maps over the toasts array.

---

Nitpick comments:
In `@UX_IMPROVEMENTS.md`:
- Around line 235-245: The rollback logic in the catch block uses
message?.starred to restore the previous state, but if message is undefined,
this will set starred to undefined instead of a boolean, causing issues in
downstream code. Before the optimistic setMessages call, capture and store the
original starred value from the message object (e.g., const originalStarred =
message?.starred), then use this stored originalStarred variable in the rollback
logic instead of message?.starred to ensure the state is always restored to a
valid boolean value.
- Line 168: The UX_IMPROVEMENTS.md specification lacks clarity on where certain
components and functionality should be implemented. Update the specification to
explicitly define file locations and integration points: specify the exact file
path where the SkeletonLoader component should be created (e.g.,
src/components/SkeletonLoader.tsx), clarify whether keyboard shortcuts should be
implemented in a dedicated hook file (e.g., src/hooks/useKeyboardShortcuts.ts)
or inline within FlowConsole.tsx, and specify whether the Toast notification
system should reuse an existing Toast component from the codebase or introduce a
new Toast system. This will provide developers with unambiguous guidance and
prevent implementation inconsistencies and code duplication.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8e33c32d-4ff8-4d0a-b8f6-e377c82f9c8b

📥 Commits

Reviewing files that changed from the base of the PR and between d730969 and 35ec23e.

📒 Files selected for processing (5)
  • UX_IMPROVEMENTS.md
  • src/components/MessageRow.tsx
  • src/hooks/useAsync.ts
  • src/hooks/useDebounce.ts
  • src/lib/performance.ts

Comment thread src/components/MessageRow.tsx Outdated
Comment thread src/hooks/useAsync.ts
Comment thread src/lib/performance.ts
Comment thread UX_IMPROVEMENTS.md
Comment thread UX_IMPROVEMENTS.md
Comment thread UX_IMPROVEMENTS.md
Comment thread UX_IMPROVEMENTS.md
Comment thread UX_IMPROVEMENTS.md
Comment thread UX_IMPROVEMENTS.md Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

⚠️ Branch updated during autofix.

The branch was updated while autofix was in progress. Please try again.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 3 file(s) based on 7 unresolved review comments.

Files modified:

  • UX_IMPROVEMENTS.md
  • src/hooks/useAsync.ts
  • src/lib/performance.ts

Commit: b3ae90dabcf1a48c204423286ac1ab8b80c4bcf1

The changes have been pushed to the feat/performance-ux-improvements branch.

Time taken: 7m 16s

Fixed 3 file(s) based on 7 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/hooks/useAsync.ts (1)

21-37: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Callers must memoize asyncFunction to avoid infinite re-renders.

If asyncFunction is an inline arrow (not wrapped in useCallback), its identity changes each render → execute changes → useEffect re-triggers → setState → re-render → loop.

Consider either:

  1. Documenting this requirement clearly, or
  2. Using a ref to capture the latest function while keeping execute stable
Option 2: Stable execute via ref
+  const asyncFunctionRef = useRef(asyncFunction);
+  asyncFunctionRef.current = asyncFunction;

-  const execute = useCallback(async () => {
+  const execute = useCallback(async () => {
     setState({ status: 'pending', data: null, error: null });
     try {
-      const response = await asyncFunction();
+      const response = await asyncFunctionRef.current();
       if (mountedRef.current) {
         setState({ status: 'success', data: response, error: null });
       }
     } catch (error) {
       if (mountedRef.current) {
         setState({
           status: 'error',
           data: null,
           error: error instanceof Error ? error : new Error(String(error)),
         });
       }
     }
-  }, [asyncFunction]);
+  }, []);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/useAsync.ts` around lines 21 - 37, The execute function in useAsync
has asyncFunction in its dependency array, causing execute to change whenever
asyncFunction changes (especially with inline arrow functions), which can
trigger infinite re-renders. To fix this, create a useRef to store the
asyncFunction and update it on each render, then remove asyncFunction from the
useCallback dependency array and have execute call the ref.current instead. This
keeps execute stable while always using the latest asyncFunction, preventing
unnecessary re-triggers.
src/components/MessageRow.tsx (1)

12-38: ⚠️ Potential issue | 🔴 Critical

Critical: File has malformed syntax that prevents compilation.

The code structure is corrupted:

  1. Lines 18-26: Duplicate import statements appear inside the MessageRowProps interface definition
  2. Lines 21-25: Import paths contain invalid backticks (e.g., '@/components/...'')
  3. Lines 28-37: Duplicate MessageRowProps interface declaration
  4. Line 38: Orphan closing brace }

The file will not compile. Move the duplicate imports (lines 18-26) and the second interface declaration (lines 28-37) to the top of the file before the first interface definition, and remove the orphan closing brace at line 38. The correct structure should have all imports at the top, followed by a single interface definition.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/MessageRow.tsx` around lines 12 - 38, The MessageRowProps
interface has malformed syntax with duplicate import statements mixed within it
and invalid backticks in import paths. Fix this by first moving all import
statements (including Star, memo, ContactHoverCard, ContactPreview,
formatListDate, getMessageFolderLabel, sentTrackingKind, sentTrackingLabel,
contactFromMessage, MailThread, and the styles import) to the very top of the
file before any interface definitions. Remove the invalid backticks from these
import paths so they are properly formatted without the extra quote characters.
Then ensure there is only a single MessageRowProps interface definition with all
its properties (thread, isSelected, onSelect, onToggleSelect, onToggleStarred,
onOpenCompose, onShowStatus, onKeyDown), and remove the duplicate interface
declaration that appears later. Finally, remove the orphan closing brace at the
end of the file.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/MessageRow.tsx`:
- Around line 12-38: The MessageRowProps interface has malformed syntax with
duplicate import statements mixed within it and invalid backticks in import
paths. Fix this by first moving all import statements (including Star, memo,
ContactHoverCard, ContactPreview, formatListDate, getMessageFolderLabel,
sentTrackingKind, sentTrackingLabel, contactFromMessage, MailThread, and the
styles import) to the very top of the file before any interface definitions.
Remove the invalid backticks from these import paths so they are properly
formatted without the extra quote characters. Then ensure there is only a single
MessageRowProps interface definition with all its properties (thread,
isSelected, onSelect, onToggleSelect, onToggleStarred, onOpenCompose,
onShowStatus, onKeyDown), and remove the duplicate interface declaration that
appears later. Finally, remove the orphan closing brace at the end of the file.

In `@src/hooks/useAsync.ts`:
- Around line 21-37: The execute function in useAsync has asyncFunction in its
dependency array, causing execute to change whenever asyncFunction changes
(especially with inline arrow functions), which can trigger infinite re-renders.
To fix this, create a useRef to store the asyncFunction and update it on each
render, then remove asyncFunction from the useCallback dependency array and have
execute call the ref.current instead. This keeps execute stable while always
using the latest asyncFunction, preventing unnecessary re-triggers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c167719a-aeb2-43d6-9ad7-d614966c6fc6

📥 Commits

Reviewing files that changed from the base of the PR and between 35ec23e and b3ae90d.

📒 Files selected for processing (4)
  • UX_IMPROVEMENTS.md
  • src/components/MessageRow.tsx
  • src/hooks/useAsync.ts
  • src/lib/performance.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/performance.ts
  • UX_IMPROVEMENTS.md

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

@sitholevunene373-lab
sitholevunene373-lab merged commit 82f1163 into main Jun 19, 2026
5 of 7 checks passed
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.

1 participant