feat: 添加logo,修复部分ui
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 58 KiB |
@ -40,7 +40,7 @@ class UserRequest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future eventCreateHis({
|
static Future eventCreateHistory({
|
||||||
required String shortPlayId,
|
required String shortPlayId,
|
||||||
required String videoId
|
required String videoId
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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));
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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));
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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)]),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -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));
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
@ -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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||