feat(app): 일정 상세 화면 새 API 대응 및 YouTube 앱 내 재생

- ScheduleDetail 모델: 새 API 형식 (category 중첩 객체, YouTube/X 전용 필드)
- YouTube 섹션: omni_video_player로 앱 내 재생, 예정 플레이스홀더 추가
- X 섹션: username, content, imageUrls, postUrl 직접 사용
- 숏츠 영상 16:9 통일, 날짜 형식 웹과 동일하게 변경
- 콘서트 섹션을 기본 섹션으로 통합 (API 변경 반영)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
caadiq 2026-03-27 20:20:51 +09:00
parent 6284d216bd
commit c37d7e14af
4 changed files with 488 additions and 628 deletions

View file

@ -39,68 +39,70 @@ class ScheduleDetail {
final String title;
final String date;
final String? time;
final String? description;
final int categoryId;
final int? categoryId;
final String? categoryName;
final String? categoryColor;
final String? sourceUrl;
final String? sourceName;
final String? imageUrl;
final List<String> images;
final String? locationName;
final String? locationAddress;
final String? locationLat;
final String? locationLng;
final List<ScheduleMember> members;
final List<RelatedDate> relatedDates;
// YouTube
final String? channelName;
final String? videoId;
final String? videoType;
final String? videoUrl;
final String? bannerUrl;
// X
final String? postId;
final String? username;
final String? content;
final List<String> imageUrls;
final String? postUrl;
ScheduleDetail({
required this.id,
required this.title,
required this.date,
this.time,
this.description,
required this.categoryId,
this.categoryId,
this.categoryName,
this.categoryColor,
this.sourceUrl,
this.sourceName,
this.imageUrl,
this.images = const [],
this.locationName,
this.locationAddress,
this.locationLat,
this.locationLng,
this.members = const [],
this.relatedDates = const [],
this.channelName,
this.videoId,
this.videoType,
this.videoUrl,
this.bannerUrl,
this.postId,
this.username,
this.content,
this.imageUrls = const [],
this.postUrl,
});
factory ScheduleDetail.fromJson(Map<String, dynamic> json) {
// category
final category = json['category'] as Map<String, dynamic>?;
return ScheduleDetail(
id: json['id'] as int,
title: json['title'] as String,
date: json['date'] as String,
time: json['time'] as String?,
description: json['description'] as String?,
categoryId: json['category_id'] as int,
categoryName: json['category_name'] as String?,
categoryColor: json['category_color'] as String?,
sourceUrl: json['source_url'] as String?,
sourceName: json['source_name'] as String?,
imageUrl: json['image_url'] as String?,
images: (json['images'] as List<dynamic>?)?.cast<String>() ?? [],
locationName: json['location_name'] as String?,
locationAddress: json['location_address'] as String?,
locationLat: json['location_lat'] as String?,
locationLng: json['location_lng'] as String?,
categoryId: category?['id'] as int?,
categoryName: category?['name'] as String?,
categoryColor: category?['color'] as String?,
members: (json['members'] as List<dynamic>?)
?.map((m) => ScheduleMember.fromJson(m))
.toList() ??
[],
relatedDates: (json['related_dates'] as List<dynamic>?)
?.map((r) => RelatedDate.fromJson(r))
.toList() ??
[],
channelName: json['channelName'] as String?,
videoId: json['videoId'] as String?,
videoType: json['videoType'] as String?,
videoUrl: json['videoUrl'] as String?,
bannerUrl: json['bannerUrl'] as String?,
postId: json['postId'] as String?,
username: json['username'] as String?,
content: json['content'] as String?,
imageUrls: (json['imageUrls'] as List<dynamic>?)?.cast<String>() ?? [],
postUrl: json['postUrl'] as String?,
);
}

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.4.1"
archive:
dependency: transitive
description:
name: archive
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
url: "https://pub.dev"
source: hosted
version: "4.0.9"
args:
dependency: transitive
description:
@ -230,6 +238,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.12.0"
flutter_inappwebview:
dependency: transitive
description:
name: flutter_inappwebview
sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
url: "https://pub.dev"
source: hosted
version: "6.1.5"
flutter_inappwebview_android:
dependency: transitive
description:
name: flutter_inappwebview_android
sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
flutter_inappwebview_internal_annotations:
dependency: transitive
description:
name: flutter_inappwebview_internal_annotations
sha256: e30fba942e3debea7b7e6cdd4f0f59ce89dd403a9865193e3221293b6d1544c6
url: "https://pub.dev"
source: hosted
version: "1.3.0"
flutter_inappwebview_ios:
dependency: transitive
description:
name: flutter_inappwebview_ios
sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_inappwebview_macos:
dependency: transitive
description:
name: flutter_inappwebview_macos
sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_inappwebview_platform_interface:
dependency: transitive
description:
name: flutter_inappwebview_platform_interface
sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
url: "https://pub.dev"
source: hosted
version: "1.3.0+1"
flutter_inappwebview_web:
dependency: transitive
description:
name: flutter_inappwebview_web
sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_inappwebview_windows:
dependency: transitive
description:
name: flutter_inappwebview_windows
sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
flutter_lints:
dependency: "direct dev"
description:
@ -264,6 +336,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
freezed_annotation:
dependency: transitive
description:
name: freezed_annotation
sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
frontend_server_client:
dependency: transitive
description:
@ -344,6 +424,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.2"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8
url: "https://pub.dev"
source: hosted
version: "4.11.0"
leak_tracker:
dependency: transitive
description:
@ -456,6 +544,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
omni_video_player:
dependency: "direct main"
description:
name: omni_video_player
sha256: e01ce74413c2eb1cfe042c81507ef2573af66e7ee2984b9ee45808d35a3ea9da
url: "https://pub.dev"
source: hosted
version: "3.7.2"
package_config:
dependency: transitive
description:
@ -632,6 +728,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.5.2"
posix:
dependency: transitive
description:
name: posix
sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07"
url: "https://pub.dev"
source: hosted
version: "6.5.0"
provider:
dependency: transitive
description:
@ -752,6 +856,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
simple_sparse_list:
dependency: transitive
description:
name: simple_sparse_list
sha256: aa648fd240fa39b49dcd11c19c266990006006de6699a412de485695910fbc1f
url: "https://pub.dev"
source: hosted
version: "0.1.4"
sky_engine:
dependency: transitive
description: flutter
@ -901,6 +1013,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
unicode:
dependency: transitive
description:
name: unicode
sha256: a6f7bcfc8ea1d5ce1f6c0b1c39117a9919f4953edd9fd7a64090a9796c499b57
url: "https://pub.dev"
source: hosted
version: "1.1.9"
url_launcher:
dependency: "direct main"
description:
@ -1045,6 +1165,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.4.0"
visibility_detector:
dependency: transitive
description:
name: visibility_detector
sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
url: "https://pub.dev"
source: hosted
version: "0.4.0+2"
vm_service:
dependency: transitive
description:
@ -1053,6 +1181,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "15.0.2"
volume_controller:
dependency: transitive
description:
name: volume_controller
sha256: "109c31a8d4f8cb0e18a1a231b1db97cdbc7084cb4f43928051e9fad59916dd09"
url: "https://pub.dev"
source: hosted
version: "3.4.3"
wakelock_plus:
dependency: transitive
description:
@ -1141,6 +1277,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.3"
youtube_explode_dart:
dependency: transitive
description:
name: youtube_explode_dart
sha256: "3d731d71df9901b1915bae806781df519cff32517e36db279f844ae619669e45"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
sdks:
dart: ">=3.10.7 <4.0.0"
flutter: ">=3.35.0"

View file

@ -50,6 +50,7 @@ dependencies:
video_player: ^2.9.2
chewie: ^1.8.5
expandable_page_view: ^1.0.17
omni_video_player: ^3.1.6
shared_preferences: ^2.3.5
dev_dependencies: