Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/ui-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ Android 端保存这些设置,在应用关闭后刷新时读取当前系统颜
其他日期为 1px 淡色实线,直接位于卡片上方。当天课程的圆角作为蒙版,线在卡片内按
同色系强调色叠加:浅色模式加深、深色模式提亮,与已上时段的填充保持清楚对比,
保留文字明暗;圆角外自然露出原色。
课程块空间不足时优先保留完整地点;课程名只使用剩余空间,并在必要时省略。
进度填充与时间线共享同一中心坐标;卡片的 2px 内缩只限制填充范围。
时间线始终按节次位置移动,课间停在节次边界,不在课程开始或结束时切换绘制方式。
课程结束后恢复普通底色;课表时段外,独立时间线仍停在下一次早课起点。
Expand Down
67 changes: 33 additions & 34 deletions lib/schedule/ui/course_tile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,15 @@ class CourseTile extends StatelessWidget {
final narrow = constraints.maxWidth < 100;
final fontSize = narrow ? 12.0 : 14.0;
final media = MediaQuery.of(context);
final compact = constraints.maxHeight <
final compact =
constraints.maxHeight <
40 * media.textScaler.scale(1);
final horizontalPadding = compact ? 1.0 : (narrow ? 3.0 : 10.0);
final verticalPadding = compact ? 0.0 : (narrow ? 4.0 : 6.0);
final horizontalPadding = compact
? 1.0
: (narrow ? 3.0 : 10.0);
final verticalPadding = compact
? 0.0
: (narrow ? 4.0 : 6.0);
final spacing = narrow ? 3.0 : 4.0;
final width =
constraints.maxWidth - horizontalPadding * 2;
Expand Down Expand Up @@ -135,29 +140,22 @@ class CourseTile extends StatelessWidget {
if (title.height +
(roomLines > 0 ? room.height + spacing : 0) >
available) {
title.maxLines = 1;
title.layout(maxWidth: width);
room.maxLines = 1;
room.layout(maxWidth: width);
final reserveRoom =
roomLines > 0 &&
title.height + room.height + spacing <= available;
titleLines = _fittingLines(
title,
width,
available - (reserveRoom ? room.height + spacing : 0),
);
roomLines = reserveRoom
? _fittingLines(
room,
width,
available - title.height - spacing,
)
: 0;
// Keep the location intact; the title uses leftover space.
if (roomLines > 0) {
roomLines = _fittingLines(room, width, available);
final titleSpace = available - room.height - spacing;
titleLines = titleSpace > 0
? _fittingLines(title, width, titleSpace)
: 0;
} else {
titleLines = _fittingLines(title, width, available);
}
}
title.dispose();
room.dispose();
if (titleLines <= 0) return const SizedBox.shrink();
if (titleLines <= 0 && roomLines <= 0) {
return const SizedBox.shrink();
}
return Padding(
padding: EdgeInsets.symmetric(
horizontal: horizontalPadding,
Expand All @@ -166,18 +164,20 @@ class CourseTile extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
child: Text(
course.name,
textAlign: TextAlign.start,
softWrap: true,
maxLines: titleLines,
overflow: TextOverflow.ellipsis,
style: titleStyle,
if (titleLines > 0)
Flexible(
child: Text(
course.name,
textAlign: TextAlign.start,
softWrap: true,
maxLines: titleLines,
overflow: TextOverflow.ellipsis,
style: titleStyle,
),
),
),
if (roomLines > 0) ...[
if (titleLines > 0 && roomLines > 0)
SizedBox(height: spacing),
if (roomLines > 0)
Text(
course.room,
textAlign: TextAlign.start,
Expand All @@ -186,7 +186,6 @@ class CourseTile extends StatelessWidget {
overflow: TextOverflow.ellipsis,
style: roomStyle,
),
],
],
),
);
Expand Down
11 changes: 7 additions & 4 deletions test/course_tile_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,18 @@ void main() {
expect(tester.takeException(), isNull);
});

testWidgets('Short cards ellipsize without overflowing', (tester) async {
testWidgets('Short cards keep the full room before the course name', (
tester,
) async {
await showCard(tester, width: 52, height: 48);
final title = tester.renderObject<RenderParagraph>(find.text(course.name));
expect(title.didExceedMaxLines, isTrue);
final room = tester.renderObject<RenderParagraph>(find.text(course.room));
expect(room.didExceedMaxLines, isFalse);
final card = tester.getRect(find.byType(CourseTile));
expect(
tester.getRect(find.text(course.room)).bottom,
lessThanOrEqualTo(card.bottom - 6),
lessThanOrEqualTo(card.bottom),
);
expect(find.text(course.name), findsNothing);
expect(tester.takeException(), isNull);
});

Expand Down
Loading