[READ ONLY MIRROR] Open Source TikTok alternative built on AT Protocol github.com/sprksocial/client
flutter atproto video dart
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798import 'package:flutter/gestures.dart';import 'package:material_ui/material_ui.dart';import 'package:spark/src/core/design_system/tokens/colors.dart';import 'package:spark/src/core/utils/text_formatter.dart';
/// A widget that displays text with clickable @mentionsclass MentionedText extends StatelessWidget { /// Creates a text widget with clickable @mentions const MentionedText({ required this.text, required this.onUsernameTap, super.key, this.expandText = false, this.maxLines = 2, this.overflow = TextOverflow.ellipsis, this.textStyle, this.mentionStyle, });
/// The text to display, which may contain @mentions final String text;
/// Called when a username is tapped final ValueChanged<String> onUsernameTap;
/// Whether to show the full text or truncate it final bool expandText;
/// Maximum number of lines when not expanded final int? maxLines;
/// How to handle overflow when not expanded final TextOverflow overflow;
/// Text style to apply to the regular text final TextStyle? textStyle;
/// Text style to apply to the @mentions, merged with textStyle final TextStyle? mentionStyle;
@override Widget build(BuildContext context) { final usernameMatches = TextFormatter.findUsernameMatches(text); final theme = Theme.of(context);
final defaultTextStyle = TextStyle( color: theme.colorScheme.onSurface, fontSize: 14, );
final baseStyle = textStyle ?? defaultTextStyle; final effectiveMentionStyle = mentionStyle ?? const TextStyle(color: AppColors.primary, fontWeight: FontWeight.bold);
// Build text spans for mentions final spans = <InlineSpan>[]; var lastEnd = 0;
usernameMatches.sort((a, b) => a.start.compareTo(b.start));
for (final match in usernameMatches) { if (match.start > lastEnd) { spans.add( TextSpan( text: text.substring(lastEnd, match.start), style: baseStyle, ), ); }
final username = match.group(0)!; spans.add( TextSpan( text: username, style: effectiveMentionStyle, recognizer: TapGestureRecognizer() ..onTap = () => onUsernameTap(username), ), );
lastEnd = match.end; }
if (lastEnd < text.length) { spans.add(TextSpan(text: text.substring(lastEnd), style: baseStyle)); }
final textSpan = TextSpan(children: spans, style: baseStyle);
return RichText( text: textSpan, maxLines: expandText ? null : maxLines, overflow: expandText ? TextOverflow.visible : overflow, ); }}