chore: update how activity summary description expansion button layout works (#3930)

pull/2245/head
ggurdin 2 months ago committed by GitHub
parent 8fdeb2d48a
commit d057cee222
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5230,5 +5230,6 @@
"myActivities": "My activities", "myActivities": "My activities",
"openToJoin": "Open to join", "openToJoin": "Open to join",
"results": "Results", "results": "Results",
"activityDone": "Activity Done!" "activityDone": "Activity Done!",
"moreLabel": "more"
} }

@ -69,37 +69,43 @@ class ActivitySummary extends StatelessWidget {
spacing: 4.0, spacing: 4.0,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Stack( InlineEllipsisText(
alignment: Alignment.bottomRight, text: activity.description,
children: [ maxLines: showInstructions ? null : 2,
Text( trailingWidth: 50.0,
activity.description, style: DefaultTextStyle.of(context)
style: const TextStyle( .style
fontSize: 12.0, .copyWith(fontSize: 12.0),
trailing: WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
), ),
), padding: const EdgeInsets.symmetric(
TextButton( horizontal: 4.0,
onPressed: toggleInstructions,
style: TextButton.styleFrom(
minimumSize: Size.zero,
padding: EdgeInsets.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
),
backgroundColor: theme.colorScheme.surface,
), ),
child: Text( child: TextButton(
showInstructions onPressed: toggleInstructions,
? L10n.of(context).less style: TextButton.styleFrom(
: L10n.of(context).more, minimumSize: Size.zero,
style: TextStyle( padding: EdgeInsets.zero,
fontSize: 12.0, tapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: theme.colorScheme.primary, backgroundColor:
Theme.of(context).colorScheme.surface,
),
child: Text(
showInstructions
? L10n.of(context).less
: L10n.of(context).moreLabel,
style: TextStyle(
fontSize: 12.0,
color: Theme.of(context).colorScheme.primary,
),
), ),
), ),
), ),
], ),
), ),
if (showInstructions) ...[ if (showInstructions) ...[
Row( Row(
@ -179,3 +185,62 @@ class ActivitySummary extends StatelessWidget {
); );
} }
} }
class InlineEllipsisText extends StatelessWidget {
final String text;
final int? maxLines;
final TextStyle? style;
final WidgetSpan trailing;
final double trailingWidth;
const InlineEllipsisText({
super.key,
required this.text,
required this.trailing,
required this.trailingWidth,
this.maxLines,
this.style,
});
@override
Widget build(BuildContext context) {
final effectiveStyle = style ?? DefaultTextStyle.of(context).style;
final span = TextSpan(text: text, style: effectiveStyle);
return LayoutBuilder(
builder: (context, constraints) {
final tp = TextPainter(
text: span,
maxLines: maxLines,
textDirection: TextDirection.ltr,
ellipsis: '',
);
tp.layout(maxWidth: constraints.maxWidth);
String truncated = text;
if (tp.didExceedMaxLines && maxLines != null) {
// Find cutoff point where text fits
final pos = tp.getPositionForOffset(
Offset(
constraints.maxWidth - trailingWidth,
tp.preferredLineHeight * maxLines!,
),
);
final endIndex = tp.getOffsetBefore(pos.offset) ?? text.length;
truncated = '${text.substring(0, endIndex).trimRight()}';
}
tp.dispose();
return RichText(
text: TextSpan(
children: [
TextSpan(text: truncated, style: effectiveStyle),
trailing, // always visible
],
),
maxLines: maxLines,
overflow: TextOverflow.clip, // prevent extra wrapping
);
},
);
}
}

@ -17,6 +17,7 @@ import 'package:fluffychat/pangea/course_chats/course_chats_page.dart';
import 'package:fluffychat/pangea/course_creation/course_info_chip_widget.dart'; import 'package:fluffychat/pangea/course_creation/course_info_chip_widget.dart';
import 'package:fluffychat/pangea/course_plans/course_plan_builder.dart'; import 'package:fluffychat/pangea/course_plans/course_plan_builder.dart';
import 'package:fluffychat/pangea/course_plans/course_plan_room_extension.dart'; import 'package:fluffychat/pangea/course_plans/course_plan_room_extension.dart';
import 'package:fluffychat/pangea/course_plans/map_clipper.dart';
import 'package:fluffychat/pangea/course_settings/course_settings.dart'; import 'package:fluffychat/pangea/course_settings/course_settings.dart';
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
@ -221,13 +222,15 @@ class SpaceDetailsContent extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (isColumnMode) ...[ if (isColumnMode) ...[
Avatar( ClipPath(
mxContent: room.avatar, clipper: MapClipper(),
name: displayname, child: Avatar(
userId: room.directChatMatrixID, mxContent: room.avatar,
size: 80.0, name: displayname,
borderRadius: userId: room.directChatMatrixID,
room.isSpace ? BorderRadius.circular(24.0) : null, size: 80.0,
borderRadius: BorderRadius.circular(0.0),
),
), ),
const SizedBox(width: 16.0), const SizedBox(width: 16.0),
], ],

Loading…
Cancel
Save