refactored internal documentation and simplified comments across chat BLoCs, file viewer, and navigation components

This commit is contained in:
2026-05-10 17:01:50 +02:00
parent a0bc46f522
commit 1a11b9ac60
8 changed files with 68 additions and 185 deletions
@@ -30,9 +30,6 @@ RichObjectString? _attachedFile(GetChatResponseObject bubbleData) {
return file;
}
/// Long-press / double-tap options dialog for a single chat message bubble.
/// The hosting [ChatBubble] keeps responsibility for rendering the bubble;
/// this file owns the modal interactions (react, reply, copy, delete, ...).
void showChatMessageOptionsDialog(
BuildContext context, {
required GetRoomResponseObject chatData,
@@ -183,11 +180,9 @@ void _openOrCreateDirectChat(
}
void switchToChat(GetRoomResponseObject room) {
// Pop the current ChatView before swapping the global ChatBloc token —
// otherwise the previous group chat stays mounted in the back-stack and
// would render empty after a back-swipe (currentToken no longer matches).
// Stops at any open popup so a confirmation dialog still in flight does
// not get silently dismissed.
// Pop the previous ChatView first — otherwise it stays in the
// back-stack with a now-mismatched currentToken and renders empty
// on back-swipe. Stop at popups so an open dialog stays alive.
Navigator.of(
context,
).popUntil((route) => route.isFirst || route is PopupRoute);
@@ -78,9 +78,8 @@ class HighlightedLinkify extends StatefulWidget {
}
class _HighlightedLinkifyState extends State<HighlightedLinkify> {
// Cached per link text so character-by-character search rebuilds don't
// churn through allocate/dispose on every keystroke. Stale entries are
// pruned at the end of each build via [_seenLinkKeys].
// Cached per link text — search rebuilds keystroke-by-keystroke
// would otherwise churn allocate/dispose. Pruned via [_seenLinkKeys].
final Map<String, TapGestureRecognizer> _recognizers = {};
final Set<String> _seenLinkKeys = {};
@@ -97,8 +96,7 @@ class _HighlightedLinkifyState extends State<HighlightedLinkify> {
final key = el.text;
final existing = _recognizers[key];
if (existing != null) {
// Refresh onTap so a new widget.onOpen callback (from a parent
// rebuild) picks up the latest closure.
// Refresh onTap so a parent rebuild's new closure is picked up.
existing.onTap = () => widget.onOpen?.call(el);
return existing;
}
@@ -124,14 +122,9 @@ class _HighlightedLinkifyState extends State<HighlightedLinkify> {
final defaultStyle = widget.style ??
Theme.of(context).textTheme.bodyMedium ??
DefaultTextStyle.of(context).style;
// Start from the surrounding text style so links inherit font family,
// size, weight, etc., then layer the link-specific color and underline
// on top. (Going the other way around — link style as base — used to
// work because TextStyle.copyWith treats `null` as "leave unchanged",
// so the explicit `color: null, decoration: null` were silently
// ignored and the merge pulled defaultStyle's color/decoration over
// the blue + underline. Result: links rendered in body-text color
// with no underline.)
// Default first, link style on top — reversing the merge silently
// drops link color/underline because TextStyle.merge treats explicit
// nulls in the overlay as "leave unchanged".
final linkStyle = defaultStyle.merge(
widget.linkStyle ??
const TextStyle(