386 lines
11 KiB
Dart
386 lines
11 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:skywood/main/lib_file.dart';
|
|
import 'package:skywood/pages/like/pages/collection_page.dart';
|
|
import 'package:skywood/pages/like/pages/play_log_page.dart';
|
|
import 'package:skywood/pages/like/widget/like_header.dart';
|
|
import 'package:skywood/pages/widgets/common_bg_page.dart';
|
|
import 'package:skywood/pages/widgets/pixel_widgets.dart';
|
|
import 'package:skywood/utils/extend/app_keep_alive.dart';
|
|
|
|
class LikePage extends StatefulWidget {
|
|
const LikePage({super.key});
|
|
|
|
@override
|
|
State<StatefulWidget> createState() {
|
|
return _MainRootState();
|
|
}
|
|
}
|
|
|
|
class _MainRootState extends State<LikePage> {
|
|
int _tabIndex = 0;
|
|
final _pageController = PageController(initialPage: 0);
|
|
|
|
final List<String> _collectionTitles = const [
|
|
'Undercover Play',
|
|
"Don't Cross Me",
|
|
'Two Worlds Apart',
|
|
'Rekindled Scorn',
|
|
'My Revenge is You',
|
|
"Mr. Gu's Sweet Weakness",
|
|
];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return CommonBgPage(
|
|
child: SafeArea(
|
|
bottom: false,
|
|
child: Padding(
|
|
padding: EdgeInsets.only(left: 15.w, right: 15.w, top: 20.h, bottom: 10.h+50.h),
|
|
child: Stack(
|
|
children: [
|
|
HelpImg.asset(ConstImg.likeBg, width: AppScreen.screenWidth - 30.w, height: 700.h,
|
|
fit: BoxFit.fill,
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
|
child: Column(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 10, top: 10),
|
|
child: LikeHeader(
|
|
onSelectedIndex: (index) {
|
|
_pageController.jumpToPage(index);
|
|
},
|
|
),
|
|
),
|
|
// 主页面
|
|
Expanded(
|
|
child: PageView(
|
|
controller: _pageController,
|
|
children: [
|
|
AppKeepAlive(child: CollectionPage()),
|
|
AppKeepAlive(child: PlayLogPage())
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
)),
|
|
);
|
|
}
|
|
|
|
Widget _buildTabs() {
|
|
return Row(
|
|
children: [
|
|
Expanded(
|
|
child: _LibraryTab(
|
|
title: 'My Collection',
|
|
selected: _tabIndex == 0,
|
|
onTap: () => setState(() => _tabIndex = 0),
|
|
),
|
|
),
|
|
SizedBox(width: 8.w),
|
|
Expanded(
|
|
child: _LibraryTab(
|
|
title: 'Play Log',
|
|
selected: _tabIndex == 1,
|
|
onTap: () => setState(() => _tabIndex = 1),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildCollection() {
|
|
return GridView.builder(
|
|
key: const ValueKey('collection'),
|
|
padding: EdgeInsets.only(top: 2.h, bottom: 120.h),
|
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: 3,
|
|
mainAxisSpacing: 10.h,
|
|
crossAxisSpacing: 7.w,
|
|
childAspectRatio: 100 / 174,
|
|
),
|
|
itemCount: _collectionTitles.length,
|
|
itemBuilder: (context, index) {
|
|
return _CollectionCard(title: _collectionTitles[index]);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget _buildPlayLog() {
|
|
return ListView(
|
|
key: const ValueKey('play-log'),
|
|
padding: EdgeInsets.only(bottom: 120.h),
|
|
children: [
|
|
_ContinueCard(),
|
|
SizedBox(height: 18.h),
|
|
Text(
|
|
'Watch History',
|
|
style: TextStyle(
|
|
color: const Color(0xFF1C1E1F),
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w700,
|
|
height: 1,
|
|
),
|
|
),
|
|
SizedBox(height: 10.h),
|
|
_HistoryItem(title: 'As A Mafia Boss, I Refuse To Be An Extra'),
|
|
SizedBox(height: 10.h),
|
|
_HistoryItem(title: 'Fatal Vengeance'),
|
|
SizedBox(height: 10.h),
|
|
_HistoryItem(title: "Don't Cross Me"),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class _LibraryTab extends StatelessWidget {
|
|
const _LibraryTab({
|
|
required this.title,
|
|
required this.selected,
|
|
required this.onTap,
|
|
});
|
|
|
|
final String title;
|
|
final bool selected;
|
|
final VoidCallback onTap;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return GestureDetector(
|
|
onTap: onTap,
|
|
child: Container(
|
|
height: 45.h,
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: selected ? const Color(0xFF16ED1E) : const Color(0xFFF6F6F6),
|
|
border: Border.all(
|
|
color: selected ? CommonColor.black : const Color(0xFFD6D6D6),
|
|
width: 1.5.w,
|
|
),
|
|
boxShadow: selected
|
|
? const [
|
|
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)),
|
|
]
|
|
: null,
|
|
),
|
|
child: Text(
|
|
title,
|
|
style: TextStyle(
|
|
color: selected ? Colors.white : const Color(0xFFB2B2B2),
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w900,
|
|
height: 1,
|
|
shadows: selected
|
|
? const [Shadow(color: Color(0xFF1C1E1F), offset: Offset(1, 1))]
|
|
: null,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _CollectionCard extends StatelessWidget {
|
|
const _CollectionCard({required this.title});
|
|
|
|
final String title;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
padding: EdgeInsets.fromLTRB(4.w, 8.h, 4.w, 6.h),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFF4FFB6),
|
|
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
|
boxShadow: const [
|
|
BoxShadow(color: Color(0xFF653CFA), offset: Offset(3, 3)),
|
|
],
|
|
),
|
|
child: Column(
|
|
children: [
|
|
Row(
|
|
children: List.generate(4, (index) {
|
|
return Container(
|
|
width: 11.w,
|
|
height: 6.h,
|
|
margin: EdgeInsets.only(right: 5.w),
|
|
decoration: BoxDecoration(
|
|
color: index == 3
|
|
? const Color(0xFFEAEAEA)
|
|
: const Color(0xFF96FE9B),
|
|
border: Border.all(
|
|
color: const Color(0xFF1C1E1F),
|
|
width: 0.8.w,
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
SizedBox(height: 8.h),
|
|
const Expanded(child: PosterImage()),
|
|
SizedBox(height: 8.h),
|
|
Text(
|
|
title,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: TextStyle(
|
|
color: const Color(0xFF1C1E1F),
|
|
fontSize: 13.sp,
|
|
fontWeight: FontWeight.w500,
|
|
height: 1,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ContinueCard extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
height: 140.h,
|
|
padding: EdgeInsets.all(10.w),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFEAE6FF),
|
|
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
const PosterImage(width: 90, height: 120, borderRadius: 2),
|
|
SizedBox(width: 10.w),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Mogul And His Runaway Bride',
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: TextStyle(
|
|
color: const Color(0xFF1B1926),
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w600,
|
|
height: 1.25,
|
|
),
|
|
),
|
|
SizedBox(height: 18.h),
|
|
Text(
|
|
'Chapter 10 / 28',
|
|
style: TextStyle(
|
|
color: CommonColor.primacyColor,
|
|
fontSize: 11.sp,
|
|
height: 1,
|
|
),
|
|
),
|
|
SizedBox(height: 6.h),
|
|
_ProgressLine(value: 0.46),
|
|
const Spacer(),
|
|
const PixelButton(
|
|
label: 'Continue Watch',
|
|
width: 145,
|
|
height: 29,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _HistoryItem extends StatelessWidget {
|
|
const _HistoryItem({required this.title});
|
|
|
|
final String title;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
height: 100.h,
|
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFEAE6FF),
|
|
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
const PosterImage(width: 66, height: 88, borderRadius: 2),
|
|
SizedBox(width: 10.w),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
title,
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: TextStyle(
|
|
color: CommonColor.black,
|
|
fontSize: 13.sp,
|
|
fontWeight: FontWeight.w600,
|
|
height: 1.2,
|
|
),
|
|
),
|
|
Text(
|
|
'EP.40/85',
|
|
style: TextStyle(
|
|
color: CommonColor.primacyColor,
|
|
fontSize: 11.sp,
|
|
height: 1,
|
|
),
|
|
),
|
|
_ProgressLine(value: 0.46),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ProgressLine extends StatelessWidget {
|
|
const _ProgressLine({required this.value});
|
|
|
|
final double value;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Row(
|
|
children: [
|
|
Expanded(
|
|
child: Container(
|
|
height: 6.h,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white.withValues(alpha: 0.7),
|
|
border: Border.all(color: const Color(0xFF1C1E1F), width: 0.5.w),
|
|
borderRadius: BorderRadius.circular(10.r),
|
|
),
|
|
alignment: Alignment.centerLeft,
|
|
child: FractionallySizedBox(
|
|
widthFactor: value,
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF00EE02),
|
|
borderRadius: BorderRadius.circular(10.r),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 4.w),
|
|
Text('46%', style: TextStyle(fontSize: 10.sp, height: 1)),
|
|
],
|
|
);
|
|
}
|
|
}
|