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",
"openToJoin": "Open to join",
"results": "Results",
"activityDone": "Activity Done!"
"activityDone": "Activity Done!",
"moreLabel": "more"
}

@ -69,37 +69,43 @@ class ActivitySummary extends StatelessWidget {
spacing: 4.0,
mainAxisSize: MainAxisSize.min,
children: [
Stack(
alignment: Alignment.bottomRight,
children: [
Text(
activity.description,
style: const TextStyle(
fontSize: 12.0,
InlineEllipsisText(
text: activity.description,
maxLines: showInstructions ? null : 2,
trailingWidth: 50.0,
style: DefaultTextStyle.of(context)
.style
.copyWith(fontSize: 12.0),
trailing: WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
),
),
TextButton(
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,
padding: const EdgeInsets.symmetric(
horizontal: 4.0,
),
child: Text(
showInstructions
? L10n.of(context).less
: L10n.of(context).more,
style: TextStyle(
fontSize: 12.0,
color: theme.colorScheme.primary,
child: TextButton(
onPressed: toggleInstructions,
style: TextButton.styleFrom(
minimumSize: Size.zero,
padding: EdgeInsets.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
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) ...[
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_plans/course_plan_builder.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/events/constants/pangea_event_types.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
@ -221,13 +222,15 @@ class SpaceDetailsContent extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
if (isColumnMode) ...[
Avatar(
mxContent: room.avatar,
name: displayname,
userId: room.directChatMatrixID,
size: 80.0,
borderRadius:
room.isSpace ? BorderRadius.circular(24.0) : null,
ClipPath(
clipper: MapClipper(),
child: Avatar(
mxContent: room.avatar,
name: displayname,
userId: room.directChatMatrixID,
size: 80.0,
borderRadius: BorderRadius.circular(0.0),
),
),
const SizedBox(width: 16.0),
],

Loading…
Cancel
Save