generated from ttipo/project-base
refactor(flutter): 공공데이터 사진 위젯과 출처 모델을 공용으로 분리
장소 화면도 공공누리 사진과 출처 표기를 써야 해서, 행사 쪽에 있던 것을 shared 로 옮겼다. Type3 사진을 자르지 않는 규칙이 한 위젯(PublicImage)에만 있게 한다. event_models 는 출처 모델을 다시 내보내 기존 import 는 그대로 동작한다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
/// 축제·공연·행사·전시 — 백엔드 EventListItemDto / EventDetailDto 와 1:1 대응한다.
|
||||
library;
|
||||
|
||||
import 'package:wandergo/shared/models/source_models.dart';
|
||||
|
||||
// 기존 import 를 깨지 않도록 출처 모델을 함께 내보낸다
|
||||
export 'package:wandergo/shared/models/source_models.dart';
|
||||
|
||||
/// 행사 분류 (백엔드 EVENT_KINDS)
|
||||
enum EventKind {
|
||||
festival,
|
||||
@@ -17,23 +22,6 @@ enum EventKind {
|
||||
}
|
||||
}
|
||||
|
||||
/// 사진 공공누리 유형 — Type3 은 변경 금지(자르지 않고 그대로 보인다)
|
||||
enum ImageLicense {
|
||||
type1('Type1'),
|
||||
type3('Type3');
|
||||
|
||||
const ImageLicense(this.code);
|
||||
|
||||
final String code;
|
||||
|
||||
static ImageLicense? parse(Object? value) {
|
||||
for (final license in values) {
|
||||
if (license.code == value) return license;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 목록의 한 건
|
||||
class EventItem {
|
||||
const EventItem({
|
||||
@@ -97,23 +85,6 @@ class EventItem {
|
||||
}
|
||||
}
|
||||
|
||||
/// 정보 출처 표기 — 화면에 반드시 보인다
|
||||
class Attribution {
|
||||
const Attribution({required this.provider, this.asOf});
|
||||
|
||||
final String provider;
|
||||
|
||||
/// 원본 기준 시점
|
||||
final String? asOf;
|
||||
|
||||
factory Attribution.fromJson(Map<String, dynamic> json) {
|
||||
return Attribution(
|
||||
provider: json['provider'] as String,
|
||||
asOf: json['asOf'] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 상세 — 목록 필드에 소개·시간·링크·출처를 더한다
|
||||
class EventDetail {
|
||||
const EventDetail({
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:wandergo/core/l10n/l10n.dart';
|
||||
import 'package:wandergo/core/theme/app_colors.dart';
|
||||
import 'package:wandergo/core/theme/app_theme.dart';
|
||||
import 'package:wandergo/core/utils/format.dart';
|
||||
import 'package:wandergo/features/event/data/models/event_models.dart';
|
||||
import 'package:wandergo/shared/widgets/public_image.dart';
|
||||
|
||||
extension EventKindLabel on EventKind {
|
||||
String label(AppLocalizations l10n) => switch (this) {
|
||||
@@ -17,9 +16,7 @@ extension EventKindLabel on EventKind {
|
||||
}
|
||||
|
||||
/// 사진이 없을 때 분류별 자리 표시 색·아이콘 (디자인 캔버스의 자리 표시 톤)
|
||||
({Color background, Color foreground, IconData icon}) _placeholderOf(
|
||||
EventKind? kind,
|
||||
) => switch (kind) {
|
||||
ImagePlaceholder _placeholderOf(EventKind? kind) => switch (kind) {
|
||||
EventKind.festival => (
|
||||
background: const Color(0xFFFFE7B8),
|
||||
foreground: const Color(0xFF6E4A00),
|
||||
@@ -51,8 +48,7 @@ String eventMeta(EventItem item) {
|
||||
return parts.join(' · ');
|
||||
}
|
||||
|
||||
/// 행사 사진 — 공공누리 Type3 은 자르지 않고(변경 금지) 통째로 보인다.
|
||||
/// [fit] 을 주지 않으면 Type3 은 contain, 나머지는 cover.
|
||||
/// 행사 사진 — 사진이 없으면 행사 종류별 자리 표시를 보인다([PublicImage]).
|
||||
class EventImage extends StatelessWidget {
|
||||
const EventImage({
|
||||
super.key,
|
||||
@@ -75,34 +71,14 @@ class EventImage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final placeholder = _placeholderOf(kind);
|
||||
final fallback = ColoredBox(
|
||||
color: placeholder.background,
|
||||
child: Center(
|
||||
child: Icon(placeholder.icon, size: 28, color: placeholder.foreground),
|
||||
),
|
||||
);
|
||||
final imageUrl = url;
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(radius),
|
||||
child: SizedBox(
|
||||
width: width,
|
||||
height: height,
|
||||
child: imageUrl == null
|
||||
? fallback
|
||||
: ColoredBox(
|
||||
color: AppColors.placeholder,
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: imageUrl,
|
||||
fit:
|
||||
fit ??
|
||||
(license == ImageLicense.type3
|
||||
? BoxFit.contain
|
||||
: BoxFit.cover),
|
||||
errorWidget: (_, _, _) => fallback,
|
||||
),
|
||||
),
|
||||
),
|
||||
return PublicImage(
|
||||
url: url,
|
||||
license: license,
|
||||
placeholder: _placeholderOf(kind),
|
||||
width: width,
|
||||
height: height,
|
||||
radius: radius,
|
||||
fit: fit,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user