-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: notice card UI * feat: show notice content with NoticeSummary entity * feat: add DDay widget * feat: add behavior property in ZigglePressable * feat: add press events in NoticeCard
- Loading branch information
1 parent
57297f3
commit 3f8910a
Showing
9 changed files
with
321 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
lib/app/modules/notice/domain/entities/notice_summary.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
class NoticeSummary { | ||
final int id; | ||
final String title; | ||
final String authorName; | ||
final DateTime? deadline; | ||
final String content; | ||
final List<String> images; | ||
final int likes; | ||
final bool authorIsCertificated; | ||
|
||
const NoticeSummary({ | ||
required this.id, | ||
required this.title, | ||
required this.authorName, | ||
required this.deadline, | ||
required this.content, | ||
required this.images, | ||
required this.likes, | ||
required this.authorIsCertificated, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:flutter/material.dart'; | ||
import 'package:ziggle/app/values/palette.dart'; | ||
import 'package:ziggle/gen/strings.g.dart'; | ||
|
||
class DDay extends StatefulWidget { | ||
const DDay({super.key, required this.deadline}); | ||
|
||
final DateTime deadline; | ||
|
||
@override | ||
State<DDay> createState() => _DDayState(); | ||
} | ||
|
||
class _DDayState extends State<DDay> { | ||
late final Timer _timer; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
_timer = Timer.periodic(const Duration(seconds: 1), (_) => setState(() {})); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
_timer.cancel(); | ||
super.dispose(); | ||
} | ||
|
||
( | ||
int?, | ||
TextSpan Function( | ||
{required num n, required InlineSpan Function(num p1) nBuilder})? | ||
) _getN() { | ||
final now = DateTime.now(); | ||
final diff = widget.deadline.difference(now); | ||
if (diff.isNegative) { | ||
return (null, null); | ||
} | ||
final daysLeft = diff.inDays; | ||
if (daysLeft > 0) { | ||
return (daysLeft, t.notice.dDay.daysLeft); | ||
} | ||
final hoursLeft = diff.inHours; | ||
if (hoursLeft > 0) { | ||
return (hoursLeft, t.notice.dDay.hoursLeft); | ||
} | ||
final minutesLeft = diff.inMinutes; | ||
if (minutesLeft > 0) { | ||
return (minutesLeft, t.notice.dDay.minutesLeft); | ||
} | ||
final secondsLeft = diff.inSeconds; | ||
return (secondsLeft, t.notice.dDay.secondsLeft); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final (n, builder) = _getN(); | ||
|
||
return Container( | ||
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 10), | ||
decoration: BoxDecoration( | ||
borderRadius: BorderRadius.circular(5), | ||
color: n != null ? Palette.primary : Palette.grayText, | ||
), | ||
child: n != null | ||
? Text.rich( | ||
builder!( | ||
n: n, | ||
nBuilder: (n) => TextSpan( | ||
text: n.toString(), | ||
style: const TextStyle(fontWeight: FontWeight.w700), | ||
), | ||
), | ||
style: const TextStyle( | ||
fontSize: 12, | ||
fontWeight: FontWeight.w400, | ||
color: Palette.white, | ||
), | ||
) | ||
: Text( | ||
t.notice.dDay.overdue, | ||
style: const TextStyle( | ||
fontSize: 12, | ||
fontWeight: FontWeight.w400, | ||
color: Palette.white, | ||
), | ||
), | ||
); | ||
} | ||
} |
134 changes: 134 additions & 0 deletions
134
lib/app/modules/notice/presentation/widgets/notice_card.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:ziggle/app/modules/common/presentation/widgets/ziggle_pressable.dart'; | ||
import 'package:ziggle/app/modules/notice/domain/entities/notice_summary.dart'; | ||
import 'package:ziggle/app/modules/notice/presentation/widgets/d_day.dart'; | ||
import 'package:ziggle/app/values/palette.dart'; | ||
import 'package:ziggle/gen/assets.gen.dart'; | ||
|
||
class NoticeCard extends StatelessWidget { | ||
const NoticeCard({ | ||
super.key, | ||
required this.notice, | ||
required this.onPressed, | ||
required this.onLike, | ||
required this.onShare, | ||
}); | ||
|
||
final NoticeSummary notice; | ||
final VoidCallback onPressed; | ||
final VoidCallback onLike; | ||
final VoidCallback onShare; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return ZigglePressable( | ||
onPressed: onPressed, | ||
decoration: const BoxDecoration( | ||
color: Palette.white, | ||
borderRadius: BorderRadius.all(Radius.circular(15)), | ||
), | ||
child: Padding( | ||
padding: const EdgeInsets.all(14), | ||
child: Column( | ||
crossAxisAlignment: CrossAxisAlignment.stretch, | ||
children: [ | ||
Row( | ||
children: [ | ||
Assets.images.defaultProfile.image(width: 40), | ||
const SizedBox(width: 10), | ||
Expanded( | ||
child: Column( | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
children: [ | ||
Row( | ||
children: [ | ||
Text( | ||
notice.authorName, | ||
style: const TextStyle( | ||
fontSize: 16, | ||
fontWeight: FontWeight.w500, | ||
color: Palette.black, | ||
height: 1, | ||
leadingDistribution: TextLeadingDistribution.even, | ||
), | ||
), | ||
const SizedBox(width: 5), | ||
if (notice.authorIsCertificated) | ||
Assets.icons.certificatedBadge.svg(width: 20), | ||
], | ||
), | ||
const SizedBox(height: 2), | ||
const Text( | ||
'10분 전', | ||
style: TextStyle( | ||
fontSize: 12, | ||
color: Palette.gray, | ||
), | ||
), | ||
], | ||
), | ||
), | ||
if (notice.deadline != null) DDay(deadline: notice.deadline!), | ||
], | ||
), | ||
const SizedBox(height: 8), | ||
Text( | ||
notice.title, | ||
style: const TextStyle( | ||
color: Palette.black, | ||
fontSize: 16, | ||
fontWeight: FontWeight.w600, | ||
), | ||
), | ||
const SizedBox(height: 8), | ||
if (notice.images.isNotEmpty) | ||
Image.network( | ||
notice.images.first, | ||
height: 250, | ||
width: double.infinity, | ||
fit: BoxFit.cover, | ||
) | ||
else | ||
Text( | ||
notice.content, | ||
style: const TextStyle( | ||
fontSize: 14, | ||
fontWeight: FontWeight.w400, | ||
color: Palette.black, | ||
), | ||
), | ||
const SizedBox(height: 8), | ||
Row( | ||
children: [ | ||
ZigglePressable( | ||
behavior: HitTestBehavior.translucent, | ||
onPressed: onLike, | ||
child: Row( | ||
children: [ | ||
Assets.icons.fire.svg(width: 30), | ||
const SizedBox(width: 5), | ||
Text( | ||
'${notice.likes}', | ||
style: const TextStyle( | ||
fontSize: 16, | ||
fontWeight: FontWeight.w600, | ||
color: Palette.black, | ||
), | ||
), | ||
], | ||
), | ||
), | ||
const Spacer(), | ||
ZigglePressable( | ||
behavior: HitTestBehavior.translucent, | ||
onPressed: onShare, | ||
child: Assets.icons.share.svg(width: 30), | ||
), | ||
], | ||
) | ||
], | ||
), | ||
), | ||
); | ||
} | ||
} |