feat: 添加logo,修复部分ui

This commit is contained in:
phoenix--zhang 2026-07-07 17:56:52 +08:00
parent a3426831ed
commit a3f489abe2
18 changed files with 263 additions and 124 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -40,7 +40,7 @@ class UserRequest {
}); });
} }
static Future eventCreateHis({ static Future eventCreateHistory({
required String shortPlayId, required String shortPlayId,
required String videoId required String videoId
}) { }) {

View File

@ -149,7 +149,7 @@ class VideoRequest {
queryParameters: params, queryParameters: params,
).then((value) { ).then((value) {
if (value.isSuccess) { if (value.isSuccess) {
HelpLog.print('getVideoDetail: ${value.data['data']}'); HelpLog.print('getVideoDetail: ${value.data}');
return NyDetailModel.fromJson(value.data['data']); return NyDetailModel.fromJson(value.data['data']);
} }
return null; return null;

View File

@ -1,8 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:novyronst/common/api/video_request.dart'; import 'package:novyronst/common/api/video_request.dart';
import 'package:novyronst/common/help/app_nav.dart';
import 'package:novyronst/common/model/ny_drama_model.dart'; import 'package:novyronst/common/model/ny_drama_model.dart';
import 'package:novyronst/pages/collect/pages/collect_page_helpers.dart'; import 'package:novyronst/pages/collect/pages/collect_page_helpers.dart';
import 'package:novyronst/pages/first/player_detail/video_detail_page.dart';
import 'package:novyronst/pages/widgets/ny_empty_view.dart'; import 'package:novyronst/pages/widgets/ny_empty_view.dart';
import 'package:novyronst/pages/widgets/ny_loading_widget.dart';
import 'package:novyronst/tools/widgets/extend_widget.dart';
class FavoritePage extends StatefulWidget { class FavoritePage extends StatefulWidget {
const FavoritePage({ const FavoritePage({
@ -66,9 +70,7 @@ class _FavoritePageState extends State<FavoritePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_isLoading && _items.isEmpty) { if (_isLoading && _items.isEmpty) {
return const Center( return const NyLoadingWidget();
child: CircularProgressIndicator(color: Colors.white),
);
} }
if (_items.isEmpty) { if (_items.isEmpty) {
@ -164,6 +166,10 @@ class _FavoriteCard extends StatelessWidget {
), ),
), ),
], ],
).addInkWell(
onTap: () {
AppNav.to(VideoDetailPage(drama: item));
},
); );
}, },
); );

View File

@ -1,7 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:novyronst/common/api/video_request.dart'; import 'package:novyronst/common/api/video_request.dart';
import 'package:novyronst/common/help/app_nav.dart';
import 'package:novyronst/common/model/ny_drama_model.dart'; import 'package:novyronst/common/model/ny_drama_model.dart';
import 'package:novyronst/pages/collect/pages/collect_page_helpers.dart'; import 'package:novyronst/pages/collect/pages/collect_page_helpers.dart';
import 'package:novyronst/pages/first/player_detail/video_detail_page.dart';
import 'package:novyronst/pages/widgets/ny_loading_widget.dart';
import 'package:novyronst/tools/widgets/extend_widget.dart';
class HistoryPage extends StatefulWidget { class HistoryPage extends StatefulWidget {
const HistoryPage({super.key, required this.isEditing, this.fetchHistory}); const HistoryPage({super.key, required this.isEditing, this.fetchHistory});
@ -51,9 +55,7 @@ class _HistoryPageState extends State<HistoryPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_isLoading && _items.isEmpty) { if (_isLoading && _items.isEmpty) {
return const Center( return const NyLoadingWidget();
child: CircularProgressIndicator(color: Colors.white),
);
} }
if (_items.isEmpty) { if (_items.isEmpty) {
@ -102,7 +104,11 @@ class _HistoryLeadingButton extends StatelessWidget {
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
constraints: const BoxConstraints.tightFor(width: 30, height: 40), constraints: const BoxConstraints.tightFor(width: 30, height: 40),
onPressed: onDelete, onPressed: onDelete,
icon: const Icon(Icons.delete_outline, color: Colors.redAccent, size: 28), icon: const Icon(
Icons.delete_outline,
color: Colors.redAccent,
size: 28,
),
); );
} }
@ -174,6 +180,10 @@ class _HistoryItem extends StatelessWidget {
), ),
], ],
), ),
).addInkWell(
onTap: () {
AppNav.to(VideoDetailPage(drama: item));
},
); );
} }
} }

View File

@ -1,5 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:novyronst/common/api/video_request.dart'; import 'package:novyronst/common/api/video_request.dart';
import 'package:novyronst/common/help/app_nav.dart'; import 'package:novyronst/common/help/app_nav.dart';
@ -12,6 +13,8 @@ import 'package:novyronst/pages/first/widgets/home_first_view.dart';
import 'package:novyronst/pages/first/widgets/home_rank_widget.dart'; import 'package:novyronst/pages/first/widgets/home_rank_widget.dart';
import 'package:novyronst/pages/first/widgets/home_remaining_sections.dart'; import 'package:novyronst/pages/first/widgets/home_remaining_sections.dart';
import 'package:novyronst/pages/first/widgets/search_view.dart'; import 'package:novyronst/pages/first/widgets/search_view.dart';
import 'package:novyronst/pages/widgets/ny_loading_widget.dart';
import 'package:novyronst/pages/widgets/ny_refresh_header.dart';
import 'package:novyronst/root/lib_export.dart'; import 'package:novyronst/root/lib_export.dart';
import '../../../tools/widgets/app_bg_page.dart'; import '../../../tools/widgets/app_bg_page.dart';
@ -44,44 +47,34 @@ class _RootPageState extends State<FirstPage> {
NyDramaModel? _dramaModel; NyDramaModel? _dramaModel;
bool _useGlassHeader = false; bool _useGlassHeader = false;
bool _isLoading = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_getCategoryData(); _refreshHomeData();
_getAllData();
} }
void _getAllData() { Future<void> _refreshHomeData() async {
VideoRequest.getHomeData().then((value) {
setState(() { setState(() {
_homeDatas = value; _isLoading = true;
}); });
List<NyDramaModel> temp = []; final results = await Future.wait([
temp = _homeDatas VideoRequest.getCategoriesList(),
.firstWhere((element) => element.moduleKey == 'week_ranking') VideoRequest.getHomeData(),
.dataList; ]);
if (temp.isEmpty) { if (!mounted) return;
temp = _homeDatas
.firstWhere((element) => element.moduleKey == 'home_v3_recommand') final categories = results[0] as List<NyCategoryModel>;
.dataList; final homeDatas = results[1] as List<NyHomeModel>;
}
if (temp.isNotEmpty) {
_dramaModel = temp.first;
}
});
}
void _getCategoryData() {
VideoRequest.getCategoriesList().then((value) {
setState(() { setState(() {
_categories = value; _categories = categories;
}); _homeDatas = homeDatas;
// for (NyCategoryModel element in value) { _dramaModel = firstHomeDrama(homeDatas);
// print('NyCategoryModel===: ${element.name}'); _isLoading = false;
// }
}); });
} }
@ -92,7 +85,7 @@ class _RootPageState extends State<FirstPage> {
children: [ children: [
Positioned.fill( Positioned.fill(
child: _homeDatas.isEmpty child: _homeDatas.isEmpty
? const SizedBox() ? (_isLoading ? NyLoadingWidget() : const SizedBox())
: NotificationListener<ScrollNotification>( : NotificationListener<ScrollNotification>(
onNotification: _handleScrollNotification, onNotification: _handleScrollNotification,
child: CustomScrollView( child: CustomScrollView(
@ -107,7 +100,6 @@ class _RootPageState extends State<FirstPage> {
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 16, left: 16,
right: 10, right: 10,
top: 16,
bottom: 8, bottom: 8,
), ),
sliver: SliverToBoxAdapter( sliver: SliverToBoxAdapter(
@ -129,13 +121,18 @@ class _RootPageState extends State<FirstPage> {
), ),
), ),
), ),
if (_dramaModel != null)
SliverToBoxAdapter( SliverToBoxAdapter(
child: HomeRemainingSections(dramaOne: _dramaModel!), child: HomeRemainingSections(
dramaOne: _dramaModel!,
),
), ),
..._buildSliversFromData(), ..._buildSliversFromData(),
const SliverToBoxAdapter(child: SizedBox(height: 110)), const SliverToBoxAdapter(
child: SizedBox(height: 110),
),
], ],
), ),
), ),
@ -234,3 +231,21 @@ class _HomeGlassHeader extends StatelessWidget {
bool shouldUseHomeGlassHeader(double scrollOffset) { bool shouldUseHomeGlassHeader(double scrollOffset) {
return scrollOffset > 8; return scrollOffset > 8;
} }
NyDramaModel? firstHomeDrama(List<NyHomeModel> homeDatas) {
List<NyDramaModel> moduleItems(String key) {
return homeDatas
.where((element) => element.moduleKey == key)
.map((element) => element.dataList)
.firstOrNull ??
<NyDramaModel>[];
}
final rankingItems = moduleItems('week_ranking');
if (rankingItems.isNotEmpty) return rankingItems.first;
final recommendedItems = moduleItems('home_v3_recommand');
if (recommendedItems.isNotEmpty) return recommendedItems.first;
return null;
}

View File

@ -5,6 +5,7 @@ import 'package:novyronst/common/model/ny_drama_model.dart';
import 'package:novyronst/common/model/ny_episode_model.dart'; import 'package:novyronst/common/model/ny_episode_model.dart';
import 'package:novyronst/pages/first/player_detail/video_esp_page.dart'; import 'package:novyronst/pages/first/player_detail/video_esp_page.dart';
import 'package:novyronst/pages/play/widgets/player_view.dart'; import 'package:novyronst/pages/play/widgets/player_view.dart';
import 'package:novyronst/pages/widgets/ny_loading_widget.dart';
class VideoDetailPage extends StatefulWidget { class VideoDetailPage extends StatefulWidget {
const VideoDetailPage({super.key, required this.drama}); const VideoDetailPage({super.key, required this.drama});
@ -32,12 +33,10 @@ class _VideoDetailPageState extends State<VideoDetailPage> {
_isLoading = true; _isLoading = true;
}); });
// id: 3150, short_id: 1913 short_play_video_id: 207599 short_play_id: 3150
final detail = await VideoRequest.getVideoDetail( final detail = await VideoRequest.getVideoDetail(
shortPlayId: widget.drama.shortPlayId ?? widget.drama.shortId, shortPlayId: widget.drama.shortPlayId ?? 0,
shortPlayVideoId: shortPlayVideoId: widget.drama.shortPlayVideoId ?? 0
widget.drama.shortPlayVideoId ??
widget.drama.id ??
widget.drama.shortId,
); );
if (!mounted) return; if (!mounted) return;
@ -153,9 +152,7 @@ class _VideoDetailPageState extends State<VideoDetailPage> {
Widget _buildBody() { Widget _buildBody() {
if (_isLoading && _videos.isEmpty) { if (_isLoading && _videos.isEmpty) {
return const Center( return const NyLoadingWidget();
child: CircularProgressIndicator(color: Colors.white),
);
} }
if (_videos.isEmpty) { if (_videos.isEmpty) {

View File

@ -30,16 +30,16 @@ class HomeCardWidget extends StatelessWidget {
cutCorner: CutCorner.topRight, cutCorner: CutCorner.topRight,
cutSize: 30, cutSize: 30,
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_threeLine(), _threeLine(),
const SizedBox(height: 10), SizedBox(height: 10.h),
OutlinedTitle(title, fontSize: 17), OutlinedTitle(title, fontSize: 17.w),
const SizedBox(height: 10), SizedBox(height: 10.h),
Expanded(child: _listView()), Expanded(child: _listView()),
const SizedBox(height: 6), SizedBox(height: 6.h),
NovyButtonBg(text: 'Click to watch', width: 327.w), NovyButtonBg(text: 'Click to watch', width: 327.w),
], ],
), ),
@ -67,14 +67,14 @@ class HomeCardWidget extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
HelpImage.network(drama.imageUrl, width: 104.w, height: 157.h), HelpImage.network(drama.imageUrl, width: 104.w, height: 157.h),
const SizedBox(height: 5), SizedBox(height: 4.h),
NovyText( NovyText(
drama.name, drama.name,
fontSize: 12.sp, fontSize: 12.sp,
color: Colors.black, color: Colors.black,
maxLines: 2, maxLines: 2,
), ),
const SizedBox(height: 2), SizedBox(height: 1.5.h),
if (tag != '') Row(children: [NyTagWidget(text: tag)]), if (tag != '') Row(children: [NyTagWidget(text: tag)]),
], ],
), ),

View File

@ -1,8 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:novyronst/common/help/app_nav.dart'; import 'package:novyronst/common/help/app_nav.dart';
import 'package:novyronst/common/help/help_time.dart';
import 'package:novyronst/common/model/ny_category_model.dart'; import 'package:novyronst/common/model/ny_category_model.dart';
import 'package:novyronst/common/model/ny_drama_model.dart';
import 'package:novyronst/pages/first/pages/category_list_page.dart'; import 'package:novyronst/pages/first/pages/category_list_page.dart';
import 'package:novyronst/pages/first/player_detail/video_detail_page.dart';
import 'package:novyronst/pages/widgets/cut_corner_clipper.dart'; import 'package:novyronst/pages/widgets/cut_corner_clipper.dart';
import 'package:novyronst/pages/widgets/ny_progress_widget.dart'; import 'package:novyronst/pages/widgets/ny_progress_widget.dart';
import 'package:novyronst/pages/widgets/ny_tag_widget.dart'; import 'package:novyronst/pages/widgets/ny_tag_widget.dart';
@ -12,6 +15,8 @@ import 'package:novyronst/tools/widgets/novy_button_bg.dart';
import 'package:novyronst/tools/widgets/novy_com_widget.dart'; import 'package:novyronst/tools/widgets/novy_com_widget.dart';
import 'package:novyronst/tools/widgets/novy_img_bg.dart'; import 'package:novyronst/tools/widgets/novy_img_bg.dart';
import '../../../common/api/video_request.dart';
class HomeFirstView extends StatefulWidget { class HomeFirstView extends StatefulWidget {
const HomeFirstView({super.key, required this.categories}); const HomeFirstView({super.key, required this.categories});
@ -23,32 +28,79 @@ class HomeFirstView extends StatefulWidget {
} }
} }
NyDramaModel? firstHistoryItem(List<NyDramaModel> items) {
if (items.isEmpty) return null;
return items.first;
}
double historyProgress(NyDramaModel item) {
final process = item.currentEpisode;
if (process == null) return 0;
return (process / item.episodeTotal).clamp(0, 1).toDouble();
}
String homeHistoryTag(NyDramaModel item) {
final category = item.category;
if (category != null && category.isNotEmpty) return category.first;
final categoryList = item.categoryList;
if (categoryList != null && categoryList.isNotEmpty) {
return categoryList.first.name;
}
return item.tagType;
}
class _HomeFirstViewState extends State<HomeFirstView> { class _HomeFirstViewState extends State<HomeFirstView> {
NyDramaModel? _historyItem;
@override
void initState() {
super.initState();
_getHistoryList();
}
void _getHistoryList() {
VideoRequest.getCollections().then((value) {
if (!mounted) return;
setState(() {
_historyItem = firstHistoryItem(value);
});
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const double space = 25; const double space = 25;
final historyItem = _historyItem;
final hasHistory = historyItem != null;
final top = 151 - space;
final height = top + (hasHistory ? 204 + 16 : 0) + 45;
return Stack( return Stack(
children: [ children: [
// 151 // 151
SizedBox(height: 151 - space + 200 + 52 + 20), SizedBox(height: height),
HelpImage.asset( HelpImage.asset(
ConstImage.homeFirst, ConstImage.homeFirst,
width: AppScreen.screenWidth, width: AppScreen.screenWidth,
fit: BoxFit.fill, fit: BoxFit.fill,
), ),
Positioned( Positioned(
top: 151 - space, top: top - 20,
left: 16, left: 16.w,
right: 16, right: 16.w,
child: Column( child: Column(
children: [ children: [
if (hasHistory) ...[
CutCornerClipper( CutCornerClipper(
width: AppScreen.screenWidth - 32, width: AppScreen.screenWidth - 32.w,
height: 204, height: 204,
cutSize: 80, cutSize: 80.w,
child: _buildVideoItem(), child: _buildVideoItem(historyItem),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
],
SingleChildScrollView( SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: Row( child: Row(
@ -97,7 +149,9 @@ class _HomeFirstViewState extends State<HomeFirstView> {
); );
} }
Widget _buildVideoItem() { Widget _buildVideoItem(NyDramaModel item) {
final tag = homeHistoryTag(item);
return Padding( return Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: Column( child: Column(
@ -107,58 +161,71 @@ class _HomeFirstViewState extends State<HomeFirstView> {
NovyText( NovyText(
'Current Viewing Progress', 'Current Viewing Progress',
color: Colors.black, color: Colors.black,
fontSize: 16, fontSize: 15.w,
fontFamily: ConstFont.montBlack, fontFamily: ConstFont.montBold,
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
HelpImage.asset(ConstImage.homeCurrentTag, height: 10), HelpImage.asset(ConstImage.homeCurrentTag, height: 10.h),
], ],
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Row( Row(
children: [ children: [
Container( HelpImage.networkRadius(
color: Colors.grey.withAlpha(200), item.imageUrl,
width: 60, width: 60,
height: 90, height: 90,
fit: BoxFit.cover,
borderRadius: BorderRadius.circular(2),
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
SizedBox( Expanded(
child: SizedBox(
height: 90, height: 90,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
NovyText( NovyText(
'Jdksyjs dsaoy', item.name,
color: Colors.black, color: Colors.black,
fontSize: 14, fontSize: 13.w,
fontFamily: ConstFont.montMedium, fontFamily: ConstFont.montMedium,
maxLines: 1,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
NovyText( NovyText(
'Jdksyjs dsaoy dasku dsaldsa dljas', item.description,
color: Colors.grey, color: Colors.grey,
fontSize: 10, fontSize: 10.w,
fontFamily: ConstFont.montRegular, fontFamily: ConstFont.montRegular,
maxLines: 2, maxLines: 2,
), ),
Spacer(), const Spacer(),
Row( Row(
children: [ children: [
NyTagWidget(text: 'Safiray'), if (tag.isNotEmpty) ...[
NyTagWidget(text: tag),
const SizedBox(width: 8), const SizedBox(width: 8),
NyHotWidget(text: '12.4k'), ],
NyHotWidget(
text: HelpTime.formatNum(item.watchTotal),
),
], ],
), ),
], ],
), ),
), ),
),
], ],
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
NyProgressWidget(), NyProgressWidget(progress: historyProgress(item)),
const SizedBox(height: 6), const SizedBox(height: 6),
NovyButtonBg(text: 'Keep Watching', type: 2, width: 327.w), NovyButtonBg(text: 'Keep Watching', type: 2, width: 327.w).addInkWell(
onTap: () {
AppNav.to(VideoDetailPage(drama: item));
},
),
], ],
), ),
); );

View File

@ -21,11 +21,11 @@ class HomeRankWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CutCornerClipper( return CutCornerClipper(
width: AppScreen.screenWidth - 32, width: AppScreen.screenWidth - 32.w,
cutCorner: CutCorner.bottomLeft, cutCorner: CutCorner.bottomLeft,
cutSize: 40, cutSize: 40,
child: Padding( child: Padding(
padding: const EdgeInsets.all(8), padding: EdgeInsets.all(8.w),
child: dramaRanks.isEmpty child: dramaRanks.isEmpty
? const SizedBox(height: 20) ? const SizedBox(height: 20)
: Column( : Column(
@ -35,7 +35,7 @@ class HomeRankWidget extends StatelessWidget {
Row( Row(
children: [ children: [
SizedBox(width: 20.w), SizedBox(width: 20.w),
NovyButtonBg(text: 'Keep Watching', width: 308.w), NovyButtonBg(text: 'Keep Watching', width: 302.w),
], ],
), ),
], ],
@ -48,7 +48,7 @@ class HomeRankWidget extends StatelessWidget {
return Row( return Row(
children: [ children: [
_firstVideoView(), _firstVideoView(),
const SizedBox(width: 8), SizedBox(width: 8.w),
_otherVideoView(), _otherVideoView(),
], ],
); );
@ -111,19 +111,19 @@ class HomeRankWidget extends StatelessWidget {
onTap: () => AppNav.to(VideoDetailPage(drama: item)), onTap: () => AppNav.to(VideoDetailPage(drama: item)),
child: Container( child: Container(
margin: const EdgeInsets.only(bottom: 8), margin: const EdgeInsets.only(bottom: 8),
width: 160.w, width: 157.w,
height: 93.w, height: 93.w,
child: Row( child: Row(
children: [ children: [
HelpImage.network(item.imageUrl, width: 62.w, height: 93.w), HelpImage.network(item.imageUrl, width: 61.w, height: 93.w),
const SizedBox(width: 8), SizedBox(width: 7.w),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_colorsText(index + 2), _colorsText(index + 2),
const SizedBox(height: 8), const SizedBox(height: 8),
NovyText(item.name, fontSize: 13, color: Colors.black), NovyText(item.name, fontSize: 13.w, color: Colors.black),
const SizedBox(height: 5), const SizedBox(height: 5),
tag.isNotEmpty tag.isNotEmpty
? NyTagWidget(text: tag) ? NyTagWidget(text: tag)
@ -144,10 +144,10 @@ class HomeRankWidget extends StatelessWidget {
return Text( return Text(
'$index', '$index',
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 19.w,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.grey.withAlpha(127), color: Colors.grey.withAlpha(127),
fontStyle: FontStyle.italic, // fontStyle: FontStyle.italic,
), ),
); );
} }
@ -165,10 +165,10 @@ class HomeRankWidget extends StatelessWidget {
child: Text( child: Text(
'$index', '$index',
style: TextStyle( style: TextStyle(
fontSize: index == 1 ? 40 : 20, fontSize: index == 1 ? 40.w : 19.w,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
fontStyle: FontStyle.italic, // fontStyle: FontStyle.italic,
), ),
), ),
); );

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:novyronst/common/api/video_request.dart'; import 'package:novyronst/common/api/video_request.dart';
import 'package:novyronst/common/const/const_color.dart'; import 'package:novyronst/common/const/const_color.dart';
import 'package:novyronst/common/const/const_string.dart'; import 'package:novyronst/common/const/const_string.dart';
@ -8,6 +9,7 @@ import 'package:novyronst/common/model/ny_drama_model.dart';
import 'package:novyronst/common/model/ny_episode_model.dart'; import 'package:novyronst/common/model/ny_episode_model.dart';
import 'package:novyronst/pages/first/player_detail/video_detail_page.dart'; import 'package:novyronst/pages/first/player_detail/video_detail_page.dart';
import 'package:novyronst/pages/widgets/cut_corner_clipper.dart'; import 'package:novyronst/pages/widgets/cut_corner_clipper.dart';
import 'package:novyronst/root/lib_export.dart';
import 'package:novyronst/tools/widgets/novy_com_widget.dart'; import 'package:novyronst/tools/widgets/novy_com_widget.dart';
import '../../../common/model/ny_detail_model.dart'; import '../../../common/model/ny_detail_model.dart';
@ -99,7 +101,7 @@ class _ActorSection extends StatelessWidget {
alignment: Alignment.topRight, alignment: Alignment.topRight,
child: OutlinedTitle( child: OutlinedTitle(
'Read This Series Of Short Plays', 'Read This Series Of Short Plays',
fontSize: 17, fontSize: AppScreen.isIos ? 17.w : 16.w,
), ),
), ),
const SizedBox(height: 26), const SizedBox(height: 26),

View File

@ -3,6 +3,7 @@ import 'package:novyronst/common/api/user_request.dart';
import 'package:novyronst/common/help/app_nav.dart'; import 'package:novyronst/common/help/app_nav.dart';
import 'package:novyronst/common/help/help_image.dart'; import 'package:novyronst/common/help/help_image.dart';
import 'package:novyronst/common/help/help_token.dart'; import 'package:novyronst/common/help/help_token.dart';
import 'package:novyronst/root/lib_export.dart';
import 'package:novyronst/root/root_page.dart'; import 'package:novyronst/root/root_page.dart';
class LauncherPage extends StatefulWidget { class LauncherPage extends StatefulWidget {
@ -27,7 +28,7 @@ class _LauncherPageState extends State<LauncherPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: HelpImage.asset(ConstImage.launcher, fit: BoxFit.cover), body: HelpImage.asset(ConstImage.launcher, height: AppScreen.screenHeight, fit: BoxFit.cover),
); );
} }

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:novyronst/common/api/user_request.dart';
import 'package:novyronst/common/const/const_color.dart'; import 'package:novyronst/common/const/const_color.dart';
import 'package:novyronst/common/model/ny_drama_model.dart'; import 'package:novyronst/common/model/ny_drama_model.dart';
import 'package:novyronst/tools/widgets/novy_com_widget.dart'; import 'package:novyronst/tools/widgets/novy_com_widget.dart';
@ -35,6 +36,7 @@ class _PlayerViewState extends State<PlayerView> {
late final PageController _pageController; late final PageController _pageController;
final Map<int, VideoPlayerController> _controllers = {}; final Map<int, VideoPlayerController> _controllers = {};
final Map<int, Future<VideoPlayerController?>> _initializingControllers = {}; final Map<int, Future<VideoPlayerController?>> _initializingControllers = {};
final Set<String> _reportedHistoryKeys = {};
int _currentIndex = 0; int _currentIndex = 0;
@override @override
@ -142,6 +144,7 @@ class _PlayerViewState extends State<PlayerView> {
isPageActive: widget.isActive, isPageActive: widget.isActive,
)) { )) {
await controller.play(); await controller.play();
_reportHistory(index);
} }
} catch (_) { } catch (_) {
if (_controllers[index] == controller) { if (_controllers[index] == controller) {
@ -181,6 +184,7 @@ class _PlayerViewState extends State<PlayerView> {
isPageActive: widget.isActive, isPageActive: widget.isActive,
)) { )) {
await controller.play(); await controller.play();
_reportHistory(_currentIndex);
} }
} }
@ -224,7 +228,25 @@ class _PlayerViewState extends State<PlayerView> {
!controller.value.isInitialized) { !controller.value.isInitialized) {
return; return;
} }
controller.value.isPlaying ? controller.pause() : controller.play(); if (controller.value.isPlaying) {
controller.pause();
} else {
controller.play();
_reportHistory(_currentIndex);
}
}
void _reportHistory(int index) {
if (index < 0 || index >= widget.videos.length) return;
final ids = resolvePlayerHistoryIds(widget.videos[index]);
if (ids == null || _reportedHistoryKeys.contains(ids.key)) return;
_reportedHistoryKeys.add(ids.key);
UserRequest.eventCreateHistory(
shortPlayId: ids.shortPlayId,
videoId: ids.videoId,
).catchError((_) {});
} }
@override @override
@ -523,3 +545,23 @@ double resolvePlayerMetaBottom({
}) { }) {
return safeAreaBottom + bottomSpacing; return safeAreaBottom + bottomSpacing;
} }
class PlayerHistoryIds {
const PlayerHistoryIds({required this.shortPlayId, required this.videoId});
final String shortPlayId;
final String videoId;
String get key => '$shortPlayId:$videoId';
}
PlayerHistoryIds? resolvePlayerHistoryIds(NyDramaModel drama) {
final shortPlayId = drama.shortPlayId ?? drama.shortId;
final videoId = drama.shortPlayVideoId ?? drama.id;
if (videoId == null) return null;
return PlayerHistoryIds(
shortPlayId: shortPlayId.toString(),
videoId: videoId.toString(),
);
}

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:novyronst/common/const/const_color.dart';
import 'package:novyronst/root/lib_export.dart'; import 'package:novyronst/root/lib_export.dart';
class NyLoadingWidget extends StatefulWidget { class NyLoadingWidget extends StatefulWidget {