Skip to content

Commit 31996c1

Browse files
committed
Layout the project cards horizontally on compact screens
1 parent d2bcda1 commit 31996c1

1 file changed

Lines changed: 129 additions & 62 deletions

File tree

lib/frontpage/projects_section.dart

Lines changed: 129 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -229,78 +229,141 @@ class ProjectsSection extends StatelessWidget {
229229
}
230230

231231
Widget _buildProjectCard(BuildContext context, Project project) {
232-
return Card(
233-
clipBehavior: Clip.antiAlias,
234-
child: InkWell(
235-
onTap: project.links.isEmpty
236-
? null
237-
: () {
238-
launchUrl(project.links.first.uri);
239-
},
240-
child: Padding(
241-
padding: EdgeInsets.all(16),
242-
child: Column(
243-
mainAxisSize: MainAxisSize.min,
244-
mainAxisAlignment: MainAxisAlignment.start,
245-
crossAxisAlignment: CrossAxisAlignment.stretch,
246-
children: [
247-
Flexible(
248-
child: Card.filled(
249-
clipBehavior: Clip.antiAlias,
250-
elevation: 0,
251-
child: AspectRatio(
252-
aspectRatio: 1.618,
253-
child: Image(
254-
image: project.image,
255-
fit: BoxFit.cover,
256-
),
257-
),
258-
),
259-
),
260-
const SizedBox(height: 12),
261-
Padding(
262-
padding: EdgeInsets.symmetric(horizontal: 6),
263-
child: _buildProjectText(context, project),
264-
),
265-
const SizedBox(height: 4),
266-
for (ProjectLink link in project.links)
267-
Align(
268-
alignment: Alignment.centerLeft,
269-
child: Link(
270-
uri: link.uri,
271-
builder: (context, followLink) {
272-
return TextButton.icon(
273-
onPressed: followLink,
274-
icon: Image(
275-
image: link.image,
276-
color: descriptionTextStyle(context)?.color,
277-
width: 20,
278-
height: 20,
232+
switch (WindowSize.of(context)) {
233+
case WindowSize.compact:
234+
return Card(
235+
clipBehavior: Clip.antiAlias,
236+
child: InkWell(
237+
onTap: () {
238+
launchUrl(project.links.first.uri);
239+
},
240+
child: Padding(
241+
padding: EdgeInsets.all(8),
242+
child: SizedBox(
243+
height: 164,
244+
child: Row(
245+
crossAxisAlignment: CrossAxisAlignment.stretch,
246+
spacing: 8,
247+
children: [
248+
Flexible(
249+
fit: FlexFit.tight,
250+
flex: 1,
251+
child: Card.filled(
252+
clipBehavior: Clip.antiAlias,
253+
elevation: 0,
254+
child: Image(
255+
image: project.image,
256+
fit: BoxFit.cover,
279257
),
280-
label: Row(
281-
spacing: 8,
282-
mainAxisSize: MainAxisSize.min,
258+
),
259+
),
260+
Flexible(
261+
flex: 2,
262+
child: Padding(
263+
padding: EdgeInsets.symmetric(vertical: 4),
264+
child: Column(
265+
mainAxisAlignment: MainAxisAlignment.center,
283266
children: [
284-
Text(
285-
link.title,
286-
style: TextStyle(
287-
color: descriptionTextStyle(context)?.color,
288-
),
267+
Padding(
268+
padding: EdgeInsets.symmetric(horizontal: 6),
269+
child: _buildProjectText(context, project),
289270
),
290-
Icon(
291-
Icons.open_in_new,
292-
color: descriptionTextStyle(context)?.color,
271+
const SizedBox(height: 4),
272+
Row(
273+
children: [
274+
for (ProjectLink link in project.links)
275+
_buildProjectLink(context, link),
276+
],
293277
),
294278
],
295279
),
296-
);
297-
},
280+
),
281+
),
282+
],
283+
),
284+
),
285+
),
286+
),
287+
);
288+
289+
default:
290+
return Card(
291+
clipBehavior: Clip.antiAlias,
292+
child: InkWell(
293+
onTap: project.links.isEmpty
294+
? null
295+
: () {
296+
launchUrl(project.links.first.uri);
297+
},
298+
child: Padding(
299+
padding: EdgeInsets.all(16),
300+
child: Column(
301+
mainAxisSize: MainAxisSize.min,
302+
mainAxisAlignment: MainAxisAlignment.start,
303+
crossAxisAlignment: CrossAxisAlignment.stretch,
304+
children: [
305+
Flexible(
306+
child: Card.filled(
307+
clipBehavior: Clip.antiAlias,
308+
elevation: 0,
309+
child: AspectRatio(
310+
aspectRatio: 1.618,
311+
child: Image(
312+
image: project.image,
313+
fit: BoxFit.cover,
314+
),
315+
),
316+
),
317+
),
318+
const SizedBox(height: 12),
319+
Padding(
320+
padding: EdgeInsets.symmetric(horizontal: 6),
321+
child: _buildProjectText(context, project),
298322
),
323+
const SizedBox(height: 4),
324+
for (ProjectLink link in project.links)
325+
Align(
326+
alignment: Alignment.centerLeft,
327+
child: _buildProjectLink(context, link),
328+
),
329+
],
330+
),
331+
),
332+
),
333+
);
334+
}
335+
}
336+
337+
Widget _buildProjectLink(BuildContext context, ProjectLink link) {
338+
return Link(
339+
uri: link.uri,
340+
builder: (context, followLink) {
341+
return TextButton.icon(
342+
onPressed: followLink,
343+
icon: Image(
344+
image: link.image,
345+
color: descriptionTextStyle(context)?.color,
346+
width: 20,
347+
height: 20,
348+
),
349+
label: Row(
350+
spacing: 8,
351+
mainAxisSize: MainAxisSize.min,
352+
children: [
353+
Text(
354+
link.title,
355+
style: TextStyle(
356+
color: descriptionTextStyle(context)?.color,
299357
),
358+
),
359+
Icon(
360+
Icons.open_in_new,
361+
color: descriptionTextStyle(context)?.color,
362+
),
300363
],
301364
),
302-
),
303-
),
365+
);
366+
},
304367
);
305368
}
306369

@@ -313,10 +376,14 @@ class ProjectsSection extends StatelessWidget {
313376
project.title,
314377
style: Theme.of(context).textTheme.titleMedium,
315378
textAlign: TextAlign.start,
379+
maxLines: 1,
380+
overflow: TextOverflow.ellipsis,
316381
),
317382
Text(
318383
project.description,
319384
style: descriptionTextStyle(context),
385+
maxLines: 3,
386+
overflow: TextOverflow.ellipsis,
320387
),
321388
if (project.startDate != null)
322389
Padding(

0 commit comments

Comments
 (0)