Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7527e94565 | |||
|
|
29708e23af | ||
|
|
191c7fa58d | ||
|
|
1cca41b1de | ||
|
|
74976ae83a | ||
|
|
bcdce80889 | ||
|
|
be0d7eae45 |
BIN
assets/home_bottom_video.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/home_coins_bg.png
Normal file
|
After Width: | Height: | Size: 395 KiB |
BIN
assets/home_coins_btn.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
assets/home_coins_close.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/home_coins_right.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
assets/home_coins_right_btn.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/refills_bottomSheet_bg.png
Normal file
|
After Width: | Height: | Size: 347 KiB |
BIN
assets/refills_bottomSheet_btn.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
assets/refills_bottomSheet_l.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/refills_bottomSheet_r.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
assets/refills_center_bg-s.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
assets/refills_center_bg.png
Normal file
|
After Width: | Height: | Size: 339 KiB |
BIN
assets/refills_center_line.png
Normal file
|
After Width: | Height: | Size: 313 B |
BIN
assets/refills_center_line2.png
Normal file
|
After Width: | Height: | Size: 158 B |
BIN
assets/refills_center_star.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/refills_top_bg.png
Normal file
|
After Width: | Height: | Size: 585 KiB |
BIN
assets/refills_top_bg_line.png
Normal file
|
After Width: | Height: | Size: 158 B |
BIN
assets/refills_top_btn.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
assets/refills_top_btn_all.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
assets/video_recommend_bg.png
Normal file
|
After Width: | Height: | Size: 274 KiB |
BIN
assets/video_recommend_btn.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
assets/video_recommend_play.png
Normal file
|
After Width: | Height: | Size: 617 B |
@ -51,7 +51,11 @@ class KtApis {
|
|||||||
static const String createGooglePay = "/googlePaid";
|
static const String createGooglePay = "/googlePaid";
|
||||||
static const String buyVideo = "/buy_video";
|
static const String buyVideo = "/buy_video";
|
||||||
static const String openNotify = "/openNotify";
|
static const String openNotify = "/openNotify";
|
||||||
|
static const String getReceiveDayCoin = "/getReceiveDayCoin";
|
||||||
|
static const String receiveDayCoin = "/receiveDayCoin";
|
||||||
|
static const String getReceiveDayCoinInfo = "/getReceiveDayCoinInfo";
|
||||||
|
static const String getRetainVipPaySetting = "/getRetainVipPaySetting";
|
||||||
|
|
||||||
///钱包
|
///钱包
|
||||||
static const String getCustomerOrder = "/getCustomerOrder";
|
static const String getCustomerOrder = "/getCustomerOrder";
|
||||||
static const String getCustomerBuyRecords = "/getCustomerBuyRecords";
|
static const String getCustomerBuyRecords = "/getCustomerBuyRecords";
|
||||||
|
|||||||
176
lib/kt_model/kt_receive_coin_info.dart
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
/// week_max_total : 10000
|
||||||
|
/// week_total : 1600
|
||||||
|
/// receive_coins : 500
|
||||||
|
/// receive_count : 2
|
||||||
|
/// receive_list : [{"id":1,"title":"test","week_max_total":2400,"week_total":600,"receive_coins":200,"day_text":"4/13"},{"id":5,"title":"Weekly Subscribe Coin Pack","week_max_total":7600,"week_total":1000,"receive_coins":300,"day_text":"3/23"}]
|
||||||
|
|
||||||
|
ReceiveCoinInfo ktReceiveCoinInfoFromJson(String str) => ReceiveCoinInfo.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String ktReceiveCoinInfoToJson(ReceiveCoinInfo data) => json.encode(data.toJson());
|
||||||
|
|
||||||
|
class ReceiveCoinInfo {
|
||||||
|
ReceiveCoinInfo({
|
||||||
|
int? weekMaxTotal,
|
||||||
|
int? weekTotal,
|
||||||
|
int? receiveCoins,
|
||||||
|
int? receiveCount,
|
||||||
|
List<ReceiveList>? receiveList,
|
||||||
|
}) {
|
||||||
|
_weekMaxTotal = weekMaxTotal;
|
||||||
|
_weekTotal = weekTotal;
|
||||||
|
_receiveCoins = receiveCoins;
|
||||||
|
_receiveCount = receiveCount;
|
||||||
|
_receiveList = receiveList;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiveCoinInfo.fromJson(dynamic json) {
|
||||||
|
_weekMaxTotal = json['week_max_total'];
|
||||||
|
_weekTotal = json['week_total'];
|
||||||
|
_receiveCoins = json['receive_coins'];
|
||||||
|
_receiveCount = json['receive_count'];
|
||||||
|
if (json['receive_list'] != null) {
|
||||||
|
_receiveList = [];
|
||||||
|
json['receive_list'].forEach((v) {
|
||||||
|
_receiveList?.add(ReceiveList.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int? _weekMaxTotal;
|
||||||
|
int? _weekTotal;
|
||||||
|
int? _receiveCoins;
|
||||||
|
int? _receiveCount;
|
||||||
|
List<ReceiveList>? _receiveList;
|
||||||
|
|
||||||
|
ReceiveCoinInfo copyWith({
|
||||||
|
int? weekMaxTotal,
|
||||||
|
int? weekTotal,
|
||||||
|
int? receiveCoins,
|
||||||
|
int? receiveCount,
|
||||||
|
List<ReceiveList>? receiveList,
|
||||||
|
}) => ReceiveCoinInfo(
|
||||||
|
weekMaxTotal: weekMaxTotal ?? _weekMaxTotal,
|
||||||
|
weekTotal: weekTotal ?? _weekTotal,
|
||||||
|
receiveCoins: receiveCoins ?? _receiveCoins,
|
||||||
|
receiveCount: receiveCount ?? _receiveCount,
|
||||||
|
receiveList: receiveList ?? _receiveList,
|
||||||
|
);
|
||||||
|
|
||||||
|
int? get weekMaxTotal => _weekMaxTotal;
|
||||||
|
|
||||||
|
int? get weekTotal => _weekTotal;
|
||||||
|
|
||||||
|
int? get receiveCoins => _receiveCoins;
|
||||||
|
|
||||||
|
int? get receiveCount => _receiveCount;
|
||||||
|
|
||||||
|
List<ReceiveList>? get receiveList => _receiveList;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final map = <String, dynamic>{};
|
||||||
|
map['week_max_total'] = _weekMaxTotal;
|
||||||
|
map['week_total'] = _weekTotal;
|
||||||
|
map['receive_coins'] = _receiveCoins;
|
||||||
|
map['receive_count'] = _receiveCount;
|
||||||
|
if (_receiveList != null) {
|
||||||
|
map['receive_list'] = _receiveList?.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// id : 1
|
||||||
|
/// title : "test"
|
||||||
|
/// week_max_total : 2400
|
||||||
|
/// week_total : 600
|
||||||
|
/// receive_coins : 200
|
||||||
|
/// week_remaining_total : 200
|
||||||
|
/// day_text : "4/13"
|
||||||
|
|
||||||
|
ReceiveList receiveListFromJson(String str) => ReceiveList.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String receiveListToJson(ReceiveList data) => json.encode(data.toJson());
|
||||||
|
|
||||||
|
class ReceiveList {
|
||||||
|
ReceiveList({
|
||||||
|
int? id,
|
||||||
|
String? title,
|
||||||
|
int? weekMaxTotal,
|
||||||
|
int? weekTotal,
|
||||||
|
int? receiveCoins,
|
||||||
|
int? weekRemainingTotal,
|
||||||
|
String? dayText,
|
||||||
|
}) {
|
||||||
|
_id = id;
|
||||||
|
_title = title;
|
||||||
|
_weekMaxTotal = weekMaxTotal;
|
||||||
|
_weekTotal = weekTotal;
|
||||||
|
_receiveCoins = receiveCoins;
|
||||||
|
_weekRemainingTotal = weekRemainingTotal;
|
||||||
|
_dayText = dayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiveList.fromJson(dynamic json) {
|
||||||
|
_id = json['id'];
|
||||||
|
_title = json['title'];
|
||||||
|
_weekMaxTotal = json['week_max_total'];
|
||||||
|
_weekTotal = json['week_total'];
|
||||||
|
_receiveCoins = json['receive_coins'];
|
||||||
|
_weekRemainingTotal = json['week_remaining_total'];
|
||||||
|
_dayText = json['day_text'];
|
||||||
|
}
|
||||||
|
|
||||||
|
int? _id;
|
||||||
|
String? _title;
|
||||||
|
int? _weekMaxTotal;
|
||||||
|
int? _weekTotal;
|
||||||
|
int? _receiveCoins;
|
||||||
|
int? _weekRemainingTotal;
|
||||||
|
String? _dayText;
|
||||||
|
|
||||||
|
ReceiveList copyWith({
|
||||||
|
int? id,
|
||||||
|
String? title,
|
||||||
|
int? weekMaxTotal,
|
||||||
|
int? weekTotal,
|
||||||
|
int? receiveCoins,
|
||||||
|
int? weekRemainingTotal,
|
||||||
|
String? dayText,
|
||||||
|
}) => ReceiveList(
|
||||||
|
id: id ?? _id,
|
||||||
|
title: title ?? _title,
|
||||||
|
weekMaxTotal: weekMaxTotal ?? _weekMaxTotal,
|
||||||
|
weekTotal: weekTotal ?? _weekTotal,
|
||||||
|
receiveCoins: receiveCoins ?? _receiveCoins,
|
||||||
|
weekRemainingTotal: weekRemainingTotal ?? _weekRemainingTotal,
|
||||||
|
dayText: dayText ?? _dayText,
|
||||||
|
);
|
||||||
|
|
||||||
|
int? get id => _id;
|
||||||
|
|
||||||
|
String? get title => _title;
|
||||||
|
|
||||||
|
int? get weekMaxTotal => _weekMaxTotal;
|
||||||
|
|
||||||
|
int? get weekTotal => _weekTotal;
|
||||||
|
|
||||||
|
int? get receiveCoins => _receiveCoins;
|
||||||
|
|
||||||
|
int? get weekRemainingTotal => _weekRemainingTotal;
|
||||||
|
|
||||||
|
String? get dayText => _dayText;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final map = <String, dynamic>{};
|
||||||
|
map['id'] = _id;
|
||||||
|
map['title'] = _title;
|
||||||
|
map['week_max_total'] = _weekMaxTotal;
|
||||||
|
map['week_total'] = _weekTotal;
|
||||||
|
map['receive_coins'] = _receiveCoins;
|
||||||
|
map['week_remaining_total'] = _weekRemainingTotal;
|
||||||
|
map['day_text'] = _dayText;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -359,6 +359,7 @@ class VideoInfo {
|
|||||||
num? isVip,
|
num? isVip,
|
||||||
Revolution? revolution,
|
Revolution? revolution,
|
||||||
String? imageUrl,
|
String? imageUrl,
|
||||||
|
String? playSeconds,
|
||||||
}) {
|
}) {
|
||||||
_id = id;
|
_id = id;
|
||||||
_shortPlayVideoId = shortPlayVideoId;
|
_shortPlayVideoId = shortPlayVideoId;
|
||||||
@ -372,6 +373,7 @@ class VideoInfo {
|
|||||||
_isVip = isVip;
|
_isVip = isVip;
|
||||||
_revolution = revolution;
|
_revolution = revolution;
|
||||||
_imageUrl = imageUrl;
|
_imageUrl = imageUrl;
|
||||||
|
_playSeconds = playSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoInfo.fromJson(dynamic json) {
|
VideoInfo.fromJson(dynamic json) {
|
||||||
@ -389,6 +391,7 @@ class VideoInfo {
|
|||||||
? Revolution.fromJson(json['revolution'])
|
? Revolution.fromJson(json['revolution'])
|
||||||
: null;
|
: null;
|
||||||
_imageUrl = json['image_url'];
|
_imageUrl = json['image_url'];
|
||||||
|
_playSeconds = json['play_seconds'];
|
||||||
}
|
}
|
||||||
|
|
||||||
num? _id;
|
num? _id;
|
||||||
@ -403,7 +406,7 @@ class VideoInfo {
|
|||||||
num? _isVip;
|
num? _isVip;
|
||||||
Revolution? _revolution;
|
Revolution? _revolution;
|
||||||
String? _imageUrl;
|
String? _imageUrl;
|
||||||
|
String? _playSeconds;
|
||||||
VideoInfo copyWith({
|
VideoInfo copyWith({
|
||||||
num? id,
|
num? id,
|
||||||
num? shortPlayVideoId,
|
num? shortPlayVideoId,
|
||||||
@ -417,6 +420,7 @@ class VideoInfo {
|
|||||||
num? isVip,
|
num? isVip,
|
||||||
Revolution? revolution,
|
Revolution? revolution,
|
||||||
String? imageUrl,
|
String? imageUrl,
|
||||||
|
String? playSeconds,
|
||||||
}) => VideoInfo(
|
}) => VideoInfo(
|
||||||
id: id ?? _id,
|
id: id ?? _id,
|
||||||
shortPlayVideoId: shortPlayVideoId ?? _shortPlayVideoId,
|
shortPlayVideoId: shortPlayVideoId ?? _shortPlayVideoId,
|
||||||
@ -430,6 +434,7 @@ class VideoInfo {
|
|||||||
isVip: isVip ?? _isVip,
|
isVip: isVip ?? _isVip,
|
||||||
revolution: revolution ?? _revolution,
|
revolution: revolution ?? _revolution,
|
||||||
imageUrl: imageUrl ?? _imageUrl,
|
imageUrl: imageUrl ?? _imageUrl,
|
||||||
|
playSeconds: playSeconds ?? _playSeconds,
|
||||||
);
|
);
|
||||||
|
|
||||||
num? get id => _id;
|
num? get id => _id;
|
||||||
@ -456,6 +461,8 @@ class VideoInfo {
|
|||||||
|
|
||||||
String? get imageUrl => _imageUrl;
|
String? get imageUrl => _imageUrl;
|
||||||
|
|
||||||
|
String? get playSeconds => _playSeconds;
|
||||||
|
|
||||||
set id(num? value) => _id = value;
|
set id(num? value) => _id = value;
|
||||||
|
|
||||||
set shortPlayVideoId(num? value) => _shortPlayVideoId = value;
|
set shortPlayVideoId(num? value) => _shortPlayVideoId = value;
|
||||||
@ -480,6 +487,8 @@ class VideoInfo {
|
|||||||
|
|
||||||
set imageUrl(String? value) => _imageUrl = value;
|
set imageUrl(String? value) => _imageUrl = value;
|
||||||
|
|
||||||
|
set playSeconds(String? value) => _playSeconds = value;
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final map = <String, dynamic>{};
|
final map = <String, dynamic>{};
|
||||||
map['id'] = _id;
|
map['id'] = _id;
|
||||||
@ -496,6 +505,7 @@ class VideoInfo {
|
|||||||
map['revolution'] = _revolution?.toJson();
|
map['revolution'] = _revolution?.toJson();
|
||||||
}
|
}
|
||||||
map['image_url'] = _imageUrl;
|
map['image_url'] = _imageUrl;
|
||||||
|
map['play_seconds'] = _playSeconds;
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import 'package:easy_refresh/easy_refresh.dart';
|
import 'package:easy_refresh/easy_refresh.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
|
||||||
import 'package:flutter_kinetra/kt_model/kt_home_category_bean.dart';
|
import 'package:flutter_kinetra/kt_model/kt_home_category_bean.dart';
|
||||||
import 'package:flutter_kinetra/kt_pages/kt_home/state.dart';
|
import 'package:flutter_kinetra/kt_pages/kt_home/state.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@ -8,6 +10,7 @@ import '../../dio_cilent/kt_apis.dart';
|
|||||||
import '../../dio_cilent/kt_request.dart';
|
import '../../dio_cilent/kt_request.dart';
|
||||||
import '../../kt_model/kt_short_video_bean.dart';
|
import '../../kt_model/kt_short_video_bean.dart';
|
||||||
import '../../kt_widgets/kt_status_widget.dart';
|
import '../../kt_widgets/kt_status_widget.dart';
|
||||||
|
import '../kt_routes.dart';
|
||||||
|
|
||||||
class KtHomeLogic extends GetxController {
|
class KtHomeLogic extends GetxController {
|
||||||
final state = KtHomeState();
|
final state = KtHomeState();
|
||||||
@ -21,6 +24,7 @@ class KtHomeLogic extends GetxController {
|
|||||||
void onReady() {
|
void onReady() {
|
||||||
super.onReady();
|
super.onReady();
|
||||||
refreshData();
|
refreshData();
|
||||||
|
getReceiveDayCoin();
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshData() {
|
refreshData() {
|
||||||
@ -178,4 +182,101 @@ class KtHomeLogic extends GetxController {
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getReceiveDayCoin() async {
|
||||||
|
ApiResponse res = await KtHttpClient().request(
|
||||||
|
KtApis.getReceiveDayCoin,
|
||||||
|
method: HttpMethod.get,
|
||||||
|
);
|
||||||
|
if (res.success) {
|
||||||
|
state.receiveCoin = res.data['coins'];
|
||||||
|
state.hasSubCoin = res.data['is_exist_sub'] == 1 && state.receiveCoin > 0;
|
||||||
|
if (state.hasSubCoin) {
|
||||||
|
Get.dialog(
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 301.w,
|
||||||
|
height: 260.w,
|
||||||
|
padding: EdgeInsets.only(top: 140.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('home_coins_bg.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Daily Reward',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFFFF4306),
|
||||||
|
fontSize: 22.sp,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'is waiting!',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 20.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset('ic_coin.png'.ktIcon, width: 28.w),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'+${state.receiveCoin}',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFFFF9500),
|
||||||
|
fontSize: 22.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
Get.toNamed(KtRoutes.refill);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 200.w,
|
||||||
|
height: 50.w,
|
||||||
|
margin: EdgeInsets.only(bottom: 12.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('home_coins_btn.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'Claim Now',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Get.back(),
|
||||||
|
child: Image.asset('home_coins_close.png'.ktIcon, width: 24.w),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,6 +66,125 @@ class _KtHomePageState extends State<KtHomePage>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 90.w,
|
||||||
|
right: 0,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => Get.toNamed(KtRoutes.refill),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'home_coins_right.png'.ktIcon,
|
||||||
|
width: 100.w,
|
||||||
|
height: 69.w,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 84.w,
|
||||||
|
height: 22.w,
|
||||||
|
margin: EdgeInsets.only(top: 54.w, left: 8.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('home_coins_right_btn.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'Daily Coins',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 悬浮小视频卡片
|
||||||
|
if (state.showVideo && state.curVideo != null)
|
||||||
|
Positioned(
|
||||||
|
bottom: 2.w,
|
||||||
|
right: 15.w,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => Get.toNamed(
|
||||||
|
KtRoutes.shortVideo,
|
||||||
|
arguments: {
|
||||||
|
'shortPlayId': state.curVideo?.shortPlayId,
|
||||||
|
'imageUrl': state.curVideo?.imageUrl ?? '',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
width: 345.w,
|
||||||
|
height: 40.w,
|
||||||
|
padding: EdgeInsets.only(right: 10.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20.w),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 40.w,
|
||||||
|
height: 40.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('home_bottom_video.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: KtNetworkImage(
|
||||||
|
imageUrl: state.curVideo?.imageUrl ?? '',
|
||||||
|
width: 30.w,
|
||||||
|
height: 30.w,
|
||||||
|
borderRadius: BorderRadius.circular(15.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8.w),
|
||||||
|
Container(
|
||||||
|
constraints: BoxConstraints(maxWidth: 160.w),
|
||||||
|
child: Text(
|
||||||
|
state.curVideo?.name ?? '',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Color(0xFF1E1E20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 20.w),
|
||||||
|
Text(
|
||||||
|
'Ep.${state.curVideo?.process}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Color(0xFF94949B),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Image.asset(
|
||||||
|
'ic_home_play.png'.ktIcon,
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.w,
|
||||||
|
),
|
||||||
|
SizedBox(width: 14.w),
|
||||||
|
Image.asset(
|
||||||
|
'ic_home_eposide.png'.ktIcon,
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.w,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -1098,8 +1217,7 @@ class _KtHomePageState extends State<KtHomePage>
|
|||||||
height: 127.w,
|
height: 127.w,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment:
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
video.name ?? '',
|
video.name ?? '',
|
||||||
|
|||||||
@ -95,6 +95,7 @@ class _KtMainPageState extends State<KtMainPage>
|
|||||||
itemCount: _tabsTitle.length,
|
itemCount: _tabsTitle.length,
|
||||||
),
|
),
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
selectedItemColor: Color(0xFF1E1E20),
|
selectedItemColor: Color(0xFF1E1E20),
|
||||||
selectedLabelStyle: TextStyle(
|
selectedLabelStyle: TextStyle(
|
||||||
fontSize: 10.sp,
|
fontSize: 10.sp,
|
||||||
@ -102,7 +103,7 @@ class _KtMainPageState extends State<KtMainPage>
|
|||||||
),
|
),
|
||||||
unselectedLabelStyle: TextStyle(
|
unselectedLabelStyle: TextStyle(
|
||||||
fontSize: 10.sp,
|
fontSize: 10.sp,
|
||||||
color: Color(0xFF95959C),
|
color: Color(0xFF94949B),
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
type: BottomNavigationBarType.fixed,
|
type: BottomNavigationBarType.fixed,
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||||
import 'package:flutter_kinetra/kt_pages/kt_mine/kt_store/state.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:in_app_purchase/in_app_purchase.dart';
|
import 'package:in_app_purchase/in_app_purchase.dart';
|
||||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import '../../../dio_cilent/kt_apis.dart';
|
import '../../../dio_cilent/kt_apis.dart';
|
||||||
import '../../../dio_cilent/kt_request.dart';
|
import '../../../dio_cilent/kt_request.dart';
|
||||||
@ -18,7 +19,10 @@ import '../../../kt_utils/kt_iap_util.dart';
|
|||||||
import '../../../kt_utils/kt_purchase_restore_utils.dart';
|
import '../../../kt_utils/kt_purchase_restore_utils.dart';
|
||||||
import '../../../kt_utils/kt_toast_utils.dart';
|
import '../../../kt_utils/kt_toast_utils.dart';
|
||||||
import '../../../kt_utils/kt_utils.dart';
|
import '../../../kt_utils/kt_utils.dart';
|
||||||
|
import '../../../kt_utils/kt_string_extend.dart';
|
||||||
|
// import '../../../kt_utils/logger_service.dart';
|
||||||
import '../logic.dart';
|
import '../logic.dart';
|
||||||
|
import 'state.dart';
|
||||||
|
|
||||||
class KtStoreLogic extends GetxController {
|
class KtStoreLogic extends GetxController {
|
||||||
final state = KtStoreState();
|
final state = KtStoreState();
|
||||||
@ -68,8 +72,9 @@ class KtStoreLogic extends GetxController {
|
|||||||
refreshController.refreshCompleted();
|
refreshController.refreshCompleted();
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
state.storeBean = KtStoreBean.fromJson(res.data);
|
state.storeBean = KtStoreBean.fromJson(res.data);
|
||||||
|
// appLogger.d(state.storeBean);
|
||||||
update();
|
update();
|
||||||
// initStore();
|
initStore();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
EasyLoading.dismiss();
|
EasyLoading.dismiss();
|
||||||
@ -305,12 +310,266 @@ class KtStoreLogic extends GetxController {
|
|||||||
|
|
||||||
buyGoods(KtGoodsBean payItem, {num? shortPlayId, num? videoId}) {
|
buyGoods(KtGoodsBean payItem, {num? shortPlayId, num? videoId}) {
|
||||||
if (payItem.buyType == 'sub_coins') {
|
if (payItem.buyType == 'sub_coins') {
|
||||||
// showSubCoinCheckDialog(payItem, shortPlayId: shortPlayId, videoId: videoId);
|
showSubCoinCheckDialog(
|
||||||
|
payItem,
|
||||||
|
shortPlayId: shortPlayId,
|
||||||
|
videoId: videoId,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
createOrder(payItem, shortPlayId: shortPlayId, videoId: videoId);
|
createOrder(payItem, shortPlayId: shortPlayId, videoId: videoId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 金币包详情确认弹窗
|
||||||
|
showSubCoinCheckDialog(
|
||||||
|
KtGoodsBean payItem, {
|
||||||
|
num? shortPlayId,
|
||||||
|
num? videoId,
|
||||||
|
}) {
|
||||||
|
Get.bottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
Container(
|
||||||
|
width: ScreenUtil().screenWidth,
|
||||||
|
height: 630.w,
|
||||||
|
padding: EdgeInsets.fromLTRB(15.w, 80.w, 15.w, 0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('refills_bottomSheet_bg.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Get.back(),
|
||||||
|
child: Image.asset(
|
||||||
|
'home_coins_close.png'.ktIcon,
|
||||||
|
width: 24.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'What You Get',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xFF79C900),
|
||||||
|
fontSize: 24.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24.w),
|
||||||
|
Container(
|
||||||
|
width: 345.w,
|
||||||
|
height: 147.w,
|
||||||
|
padding: EdgeInsets.all(16.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(14.w),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Bonus You Get',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xFF1E1E20) /* 黑 */,
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.33,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.w),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 150.w,
|
||||||
|
height: 83.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [Color(0xFFF5FFD1), Color(0xFFCFFF99)],
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.w),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 7.w),
|
||||||
|
Image.asset(
|
||||||
|
'refills_bottomSheet_l.png'.ktIcon,
|
||||||
|
width: 44.w,
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.w),
|
||||||
|
Text(
|
||||||
|
'Weekly Refill Package',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xFF1E1E20),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.33,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 150.w,
|
||||||
|
height: 83.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [Color(0xFFF5FFD1), Color(0xFFCFFF99)],
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.w),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 7.w),
|
||||||
|
Image.asset(
|
||||||
|
'refills_bottomSheet_r.png'.ktIcon,
|
||||||
|
width: 44.w,
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.w),
|
||||||
|
Text(
|
||||||
|
'Daily Bonuses',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xFF1E1E20),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.33,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 14.w),
|
||||||
|
Container(
|
||||||
|
width: 345.w,
|
||||||
|
padding: EdgeInsets.fromLTRB(16.w, 16.w, 16.w, 0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(14.w),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'How Do I Receive Coins?',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xFF1E1E20),
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.33,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 32.w),
|
||||||
|
ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) => Row(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'ic_coin.png'.ktIcon,
|
||||||
|
width: 16.w,
|
||||||
|
height: 16.w,
|
||||||
|
),
|
||||||
|
SizedBox(width: 8.w),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
payItem.extInfo?.subCoinsTxtList?[index] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xFF1E1E20),
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
height: 1.29,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
separatorBuilder: (_, __) => SizedBox(height: 16.w),
|
||||||
|
itemCount:
|
||||||
|
payItem.extInfo?.subCoinsTxtList?.length ?? 0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 14.w),
|
||||||
|
Text(
|
||||||
|
'${payItem.productDetails?.price ?? ''}/week',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color(0xFFFF9500),
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 9.w),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
createOrder(
|
||||||
|
payItem,
|
||||||
|
shortPlayId: shortPlayId,
|
||||||
|
videoId: videoId,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'refills_bottomSheet_btn.png'.ktIcon,
|
||||||
|
width: 345.w,
|
||||||
|
height: 68.w,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 46.w,
|
||||||
|
margin: EdgeInsets.only(top: 5.w),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Continue',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFF1E1E20),
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
height: 1.1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
createOrder(KtGoodsBean goods, {num? shortPlayId, num? videoId}) async {
|
createOrder(KtGoodsBean goods, {num? shortPlayId, num? videoId}) async {
|
||||||
EasyLoading.show(status: 'Paying...', maskType: EasyLoadingMaskType.black);
|
EasyLoading.show(status: 'Paying...', maskType: EasyLoadingMaskType.black);
|
||||||
// Map<String, dynamic> params = {"pay_setting_id": goods.id!};
|
// Map<String, dynamic> params = {"pay_setting_id": goods.id!};
|
||||||
|
|||||||
@ -38,8 +38,8 @@ class MyListLogic extends GetxController {
|
|||||||
state.loadStatus = KtLoadStatusType.loading;
|
state.loadStatus = KtLoadStatusType.loading;
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
state.curFavoriteIndex = 1;
|
state.curFavoriteIndex = 1;
|
||||||
state.favoriteList.clear();
|
// state.favoriteList.clear();
|
||||||
state.chestList.clear();
|
// state.chestList.clear();
|
||||||
}
|
}
|
||||||
if (loadMore) {
|
if (loadMore) {
|
||||||
state.curFavoriteIndex++;
|
state.curFavoriteIndex++;
|
||||||
@ -64,6 +64,10 @@ class MyListLogic extends GetxController {
|
|||||||
refreshCtrl.loadNoData();
|
refreshCtrl.loadNoData();
|
||||||
chestRefreshCtrl.loadNoData();
|
chestRefreshCtrl.loadNoData();
|
||||||
}
|
}
|
||||||
|
if (refresh) {
|
||||||
|
state.favoriteList.clear();
|
||||||
|
state.chestList.clear();
|
||||||
|
}
|
||||||
state.favoriteList.addAll(list);
|
state.favoriteList.addAll(list);
|
||||||
if (state.favoriteList.length > 3) {
|
if (state.favoriteList.length > 3) {
|
||||||
state.chestList = state.favoriteList.sublist(0, 3);
|
state.chestList = state.favoriteList.sublist(0, 3);
|
||||||
@ -86,7 +90,7 @@ class MyListLogic extends GetxController {
|
|||||||
getHistoryList({bool refresh = false, bool loadMore = false}) async {
|
getHistoryList({bool refresh = false, bool loadMore = false}) async {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
state.curHistoryIndex = 1;
|
state.curHistoryIndex = 1;
|
||||||
state.historyList.clear();
|
// state.historyList.clear();
|
||||||
}
|
}
|
||||||
if (loadMore) {
|
if (loadMore) {
|
||||||
state.curHistoryIndex++;
|
state.curHistoryIndex++;
|
||||||
@ -107,7 +111,9 @@ class MyListLogic extends GetxController {
|
|||||||
...res.data['list'].map((item) => KtHistoryVideoBean.fromJson(item)),
|
...res.data['list'].map((item) => KtHistoryVideoBean.fromJson(item)),
|
||||||
];
|
];
|
||||||
if (list.length < 20) refreshCtrl.loadNoData();
|
if (list.length < 20) refreshCtrl.loadNoData();
|
||||||
|
if (refresh) {
|
||||||
|
state.historyList.clear();
|
||||||
|
}
|
||||||
state.historyList.addAll(list);
|
state.historyList.addAll(list);
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -39,286 +39,288 @@ class _KtMyListPageState extends State<KtMyListPage> {
|
|||||||
),
|
),
|
||||||
child: state.chestList.isEmpty && state.historyList.isEmpty
|
child: state.chestList.isEmpty && state.historyList.isEmpty
|
||||||
? KtStatusWidget(
|
? KtStatusWidget(
|
||||||
type: KtErrorStatusType.nothingYet,
|
type: KtErrorStatusType.nothingYet,
|
||||||
onPressed: logic.initData,
|
onPressed: logic.initData,
|
||||||
)
|
)
|
||||||
: SmartRefresher(
|
: SmartRefresher(
|
||||||
controller: logic.refreshCtrl,
|
controller: logic.refreshCtrl,
|
||||||
enablePullUp: true,
|
enablePullUp: true,
|
||||||
enablePullDown: true,
|
enablePullDown: true,
|
||||||
onRefresh: () => logic.initData(),
|
onRefresh: () => logic.initData(),
|
||||||
onLoading: () => logic.getHistoryList(loadMore: true),
|
onLoading: () => logic.getHistoryList(loadMore: true),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
if (state.chestList.isNotEmpty)
|
if (state.chestList.isNotEmpty)
|
||||||
Container(
|
Container(
|
||||||
width: ScreenUtil().screenWidth - 30.w,
|
width: ScreenUtil().screenWidth - 30.w,
|
||||||
padding: EdgeInsets.fromLTRB(6.w, 53.w, 6.w, 6.w),
|
padding: EdgeInsets.fromLTRB(6.w, 46.w, 6.w, 6.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: AssetImage('collect_bg.png'.ktIcon),
|
image: AssetImage('collect_bg.png'.ktIcon),
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: 6.w),
|
|
||||||
Text(
|
|
||||||
'My Treasure Chest',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18.sp,
|
|
||||||
color: Colors.white,
|
|
||||||
fontWeight: FontWeight.w800,
|
|
||||||
fontStyle: FontStyle.italic,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const Spacer(),
|
),
|
||||||
GestureDetector(
|
child: Column(
|
||||||
onTap: () => Get.to(KtMyChestPage()),
|
children: [
|
||||||
child: Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
SizedBox(width: 6.w),
|
||||||
Text(
|
Text(
|
||||||
'View All',
|
'My Treasure Chest',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12.sp,
|
fontSize: 18.sp,
|
||||||
color: Color(0xFFD6D6D6),
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Image.asset(
|
const Spacer(),
|
||||||
'ic_right_white.png'.ktIcon,
|
GestureDetector(
|
||||||
width: 10.w,
|
onTap: () => Get.to(KtMyChestPage()),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(8.w),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'View All',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(0xFFD6D6D6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Image.asset(
|
||||||
|
'ic_right_white.png'.ktIcon,
|
||||||
|
width: 10.w,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 6.w),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
SizedBox(height: 8.w),
|
||||||
],
|
Container(
|
||||||
),
|
height: 145.w,
|
||||||
SizedBox(height: 15.w),
|
decoration: BoxDecoration(
|
||||||
Container(
|
color: Colors.white,
|
||||||
height: 145.w,
|
borderRadius: BorderRadius.circular(14.w),
|
||||||
decoration: BoxDecoration(
|
),
|
||||||
color: Colors.white,
|
child: Row(
|
||||||
borderRadius: BorderRadius.circular(14.w),
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
),
|
children: [
|
||||||
child: Row(
|
...state.chestList.map(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
(video) => Container(
|
||||||
children: [
|
margin: EdgeInsets.symmetric(
|
||||||
...state.chestList.map(
|
horizontal: 5.w,
|
||||||
(video) => Container(
|
|
||||||
margin: EdgeInsets.symmetric(
|
|
||||||
horizontal: 5.w,
|
|
||||||
),
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () => Get.toNamed(
|
|
||||||
KtRoutes.shortVideo,
|
|
||||||
arguments: {
|
|
||||||
'shortPlayId':
|
|
||||||
video.shortPlayId,
|
|
||||||
'imageUrl':
|
|
||||||
video.imageUrl ?? '',
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
child: KtNetworkImage(
|
child: Stack(
|
||||||
imageUrl: video.imageUrl ?? '',
|
children: [
|
||||||
width: 100.w,
|
GestureDetector(
|
||||||
height: 133.w,
|
onTap: () => Get.toNamed(
|
||||||
borderRadius:
|
KtRoutes.shortVideo,
|
||||||
BorderRadius.circular(6.w),
|
arguments: {
|
||||||
),
|
'shortPlayId':
|
||||||
),
|
video.shortPlayId,
|
||||||
Positioned(
|
'imageUrl':
|
||||||
right: 4.w,
|
video.imageUrl ?? '',
|
||||||
top: 4.w,
|
},
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () =>
|
|
||||||
logic.cancelCollect(
|
|
||||||
video.shortPlayId!,
|
|
||||||
),
|
),
|
||||||
child: Image.asset(
|
child: KtNetworkImage(
|
||||||
'ic_collect_sel.png'.ktIcon,
|
imageUrl: video.imageUrl ?? '',
|
||||||
width: 28.w,
|
width: 100.w,
|
||||||
),
|
height: 133.w,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(6.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
right: 4.w,
|
||||||
|
top: 4.w,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () =>
|
||||||
|
logic.cancelCollect(
|
||||||
|
video.shortPlayId!,
|
||||||
|
),
|
||||||
|
child: Image.asset(
|
||||||
|
'ic_collect_sel.png'.ktIcon,
|
||||||
|
width: 28.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
SizedBox(height: 15.w),
|
||||||
),
|
Expanded(
|
||||||
),
|
child: Container(
|
||||||
SizedBox(height: 15.w),
|
width: ScreenUtil().screenWidth,
|
||||||
Expanded(
|
padding: EdgeInsets.all(15.w),
|
||||||
child: Container(
|
decoration: BoxDecoration(
|
||||||
width: ScreenUtil().screenWidth,
|
color: Colors.white,
|
||||||
padding: EdgeInsets.all(15.w),
|
borderRadius: BorderRadius.vertical(
|
||||||
decoration: BoxDecoration(
|
top: Radius.circular(20.w),
|
||||||
color: Colors.white,
|
),
|
||||||
borderRadius: BorderRadius.vertical(
|
|
||||||
top: Radius.circular(20.w),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Continue Watching',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18.sp,
|
|
||||||
color: Color(0xFF1E1E20),
|
|
||||||
fontWeight: FontWeight.w800,
|
|
||||||
fontStyle: FontStyle.italic,
|
|
||||||
),
|
),
|
||||||
),
|
child: Column(
|
||||||
Expanded(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
child: ListView.separated(
|
children: [
|
||||||
padding: EdgeInsets.only(top: 10.w),
|
Text(
|
||||||
// shrinkWrap: true,
|
'Continue Watching',
|
||||||
// physics: NeverScrollableScrollPhysics(),
|
style: TextStyle(
|
||||||
itemBuilder: (context, index) {
|
fontSize: 18.sp,
|
||||||
KtHistoryVideoBean video =
|
color: Color(0xFF1E1E20),
|
||||||
state.historyList[index];
|
fontWeight: FontWeight.w800,
|
||||||
return GestureDetector(
|
fontStyle: FontStyle.italic,
|
||||||
onTap: () => Get.toNamed(
|
|
||||||
KtRoutes.shortVideo,
|
|
||||||
arguments: {
|
|
||||||
'shortPlayId': video.shortPlayId,
|
|
||||||
'imageUrl': video.imageUrl ?? '',
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
child: Container(
|
),
|
||||||
color: Colors.transparent,
|
Expanded(
|
||||||
child: Row(
|
child: ListView.separated(
|
||||||
children: [
|
padding: EdgeInsets.only(top: 10.w),
|
||||||
KtNetworkImage(
|
// shrinkWrap: true,
|
||||||
imageUrl: video.imageUrl ?? '',
|
// physics: NeverScrollableScrollPhysics(),
|
||||||
width: 74.w,
|
itemBuilder: (context, index) {
|
||||||
height: 98.w,
|
KtHistoryVideoBean video =
|
||||||
borderRadius:
|
state.historyList[index];
|
||||||
BorderRadius.circular(8.w),
|
return GestureDetector(
|
||||||
|
onTap: () => Get.toNamed(
|
||||||
|
KtRoutes.shortVideo,
|
||||||
|
arguments: {
|
||||||
|
'shortPlayId': video.shortPlayId,
|
||||||
|
'imageUrl': video.imageUrl ?? '',
|
||||||
|
},
|
||||||
),
|
),
|
||||||
SizedBox(width: 13.w),
|
child: Container(
|
||||||
SizedBox(
|
color: Colors.transparent,
|
||||||
width: 200.w,
|
child: Row(
|
||||||
height: 98.w,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
KtNetworkImage(
|
||||||
video.name ?? '',
|
imageUrl: video.imageUrl ?? '',
|
||||||
maxLines: 1,
|
width: 74.w,
|
||||||
overflow:
|
height: 98.w,
|
||||||
TextOverflow.ellipsis,
|
borderRadius:
|
||||||
style: TextStyle(
|
BorderRadius.circular(8.w),
|
||||||
fontSize: 13.sp,
|
|
||||||
color: Color(0xFF1E1E20),
|
|
||||||
fontWeight:
|
|
||||||
FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 6.w),
|
SizedBox(width: 13.w),
|
||||||
Text(
|
SizedBox(
|
||||||
video.category?.first ?? '',
|
width: 200.w,
|
||||||
maxLines: 1,
|
height: 98.w,
|
||||||
overflow:
|
child: Column(
|
||||||
TextOverflow.ellipsis,
|
crossAxisAlignment:
|
||||||
style: TextStyle(
|
CrossAxisAlignment.start,
|
||||||
fontSize: 10.sp,
|
mainAxisAlignment:
|
||||||
color: Color(0xFF79C900),
|
MainAxisAlignment.start,
|
||||||
fontWeight:
|
children: [
|
||||||
FontWeight.w400,
|
Text(
|
||||||
),
|
video.name ?? '',
|
||||||
),
|
maxLines: 1,
|
||||||
SizedBox(height: 20.w),
|
overflow:
|
||||||
Row(
|
TextOverflow.ellipsis,
|
||||||
children: [
|
style: TextStyle(
|
||||||
SizedBox(
|
fontSize: 13.sp,
|
||||||
width: 26.w,
|
color: Color(0xFF1E1E20),
|
||||||
height: 26.w,
|
fontWeight:
|
||||||
child: CircularProgressIndicator(
|
FontWeight.w500,
|
||||||
value:
|
),
|
||||||
(video.currentEpisode ??
|
),
|
||||||
0) /
|
SizedBox(height: 6.w),
|
||||||
(video.episodeTotal! >
|
Text(
|
||||||
0
|
video.category?.first ?? '',
|
||||||
? video
|
maxLines: 1,
|
||||||
.episodeTotal!
|
overflow:
|
||||||
: 1),
|
TextOverflow.ellipsis,
|
||||||
backgroundColor:
|
style: TextStyle(
|
||||||
Color(0xFFD9D9D9),
|
fontSize: 10.sp,
|
||||||
valueColor:
|
color: Color(0xFF79C900),
|
||||||
AlwaysStoppedAnimation<
|
fontWeight:
|
||||||
Color
|
FontWeight.w400,
|
||||||
>(
|
),
|
||||||
Color(
|
),
|
||||||
0xFFA7F62F,
|
SizedBox(height: 20.w),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 26.w,
|
||||||
|
height: 26.w,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
value:
|
||||||
|
(video.currentEpisode ??
|
||||||
|
0) /
|
||||||
|
(video.episodeTotal! >
|
||||||
|
0
|
||||||
|
? video
|
||||||
|
.episodeTotal!
|
||||||
|
: 1),
|
||||||
|
backgroundColor:
|
||||||
|
Color(0xFFD9D9D9),
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<
|
||||||
|
Color
|
||||||
|
>(
|
||||||
|
Color(
|
||||||
|
0xFFA7F62F,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
strokeWidth: 3.w,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 5.w),
|
||||||
strokeWidth: 3.w,
|
Text(
|
||||||
|
"${((video.currentEpisode ?? 0) / (video.episodeTotal! > 0 ? video.episodeTotal! : 1) * 100).toStringAsFixed(0)}%",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Color(
|
||||||
|
0xFF1E1E20,
|
||||||
|
),
|
||||||
|
fontWeight:
|
||||||
|
FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
SizedBox(width: 5.w),
|
),
|
||||||
Text(
|
),
|
||||||
"${((video.currentEpisode ?? 0) / (video.episodeTotal! > 0 ? video.episodeTotal! : 1) * 100).toStringAsFixed(0)}%",
|
const Spacer(),
|
||||||
style: TextStyle(
|
GestureDetector(
|
||||||
fontSize: 12.sp,
|
onTap: () =>
|
||||||
color: Color(
|
logic.likeVideo(video),
|
||||||
0xFF1E1E20,
|
child: Column(
|
||||||
),
|
children: [
|
||||||
fontWeight:
|
Image.asset(
|
||||||
FontWeight.w400,
|
video.isCollect == 1
|
||||||
|
? 'ic_collect_sel.png'
|
||||||
|
.ktIcon
|
||||||
|
: 'ic_collect_unsel.png'
|
||||||
|
.ktIcon,
|
||||||
|
width: 32.w,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
);
|
||||||
GestureDetector(
|
},
|
||||||
onTap: () =>
|
separatorBuilder: (_, __) =>
|
||||||
logic.likeVideo(video),
|
SizedBox(height: 12.w),
|
||||||
child: Column(
|
itemCount: state.historyList.length,
|
||||||
children: [
|
|
||||||
Image.asset(
|
|
||||||
video.isCollect == 1
|
|
||||||
? 'ic_collect_sel.png'
|
|
||||||
.ktIcon
|
|
||||||
: 'ic_collect_unsel.png'
|
|
||||||
.ktIcon,
|
|
||||||
width: 32.w,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
],
|
||||||
separatorBuilder: (_, __) =>
|
|
||||||
SizedBox(height: 12.w),
|
|
||||||
itemCount: state.historyList.length,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
259
lib/kt_pages/kt_refill/logic.dart
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:card_swiper/card_swiper.dart';
|
||||||
|
|
||||||
|
import '../../dio_cilent/kt_apis.dart';
|
||||||
|
import '../../dio_cilent/kt_request.dart';
|
||||||
|
import '../../kt_model/kt_receive_coin_info.dart';
|
||||||
|
import '../../kt_model/kt_short_video_bean.dart';
|
||||||
|
import '../../kt_utils/kt_toast_utils.dart';
|
||||||
|
import '../../kt_utils/kt_string_extend.dart';
|
||||||
|
import '../../kt_widgets/kt_network_image.dart';
|
||||||
|
import '../kt_mine/kt_store/logic.dart';
|
||||||
|
import '../kt_routes.dart';
|
||||||
|
import 'state.dart';
|
||||||
|
|
||||||
|
class KtRefillLogic extends GetxController {
|
||||||
|
final state = KtRefillState();
|
||||||
|
final RefreshController refreshController = RefreshController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
getReceiveDayCoin();
|
||||||
|
getRefillInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
super.onClose();
|
||||||
|
refreshController.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
getReceiveDayCoin() async {
|
||||||
|
ApiResponse res = await KtHttpClient().request(
|
||||||
|
KtApis.getReceiveDayCoin,
|
||||||
|
method: HttpMethod.get,
|
||||||
|
);
|
||||||
|
if (res.success) {
|
||||||
|
state.hasSubCoin = res.data['is_exist_sub'] == 1;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getRefillInfo() async {
|
||||||
|
try {
|
||||||
|
ApiResponse res = await KtHttpClient().request(
|
||||||
|
KtApis.getReceiveDayCoinInfo,
|
||||||
|
method: HttpMethod.get,
|
||||||
|
);
|
||||||
|
if (res.success) {
|
||||||
|
state.receiveCoinInfo = ReceiveCoinInfo.fromJson(res.data);
|
||||||
|
update();
|
||||||
|
refreshController.refreshCompleted();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
refreshController.refreshFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshInfo() {
|
||||||
|
getRefillInfo();
|
||||||
|
Get.put(KtStoreLogic()).getStoreInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
receiveDayCoin({int? id}) async {
|
||||||
|
Map<String, dynamic> params = {};
|
||||||
|
if (id != null) params['id'] = id;
|
||||||
|
ApiResponse res = await KtHttpClient().request(
|
||||||
|
KtApis.receiveDayCoin,
|
||||||
|
data: params,
|
||||||
|
);
|
||||||
|
if (res.success) {
|
||||||
|
KtToastUtils.showToast('Success');
|
||||||
|
getRefillInfo();
|
||||||
|
getReceiveDayCoin();
|
||||||
|
getRecommend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getRecommend() async {
|
||||||
|
ApiResponse res = await KtHttpClient().request(
|
||||||
|
KtApis.getDetailsRecommand,
|
||||||
|
method: HttpMethod.get,
|
||||||
|
);
|
||||||
|
if (res.success) {
|
||||||
|
state.recommendList = [
|
||||||
|
...res.data['list'].map((item) => KtShortVideoBean.fromJson(item)),
|
||||||
|
];
|
||||||
|
if (state.recommendList.isNotEmpty) {
|
||||||
|
showRecommendDialog();
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showRecommendDialog() {
|
||||||
|
EasyThrottle.throttle('show-recommend', Duration(seconds: 3), () async {
|
||||||
|
Get.bottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
isDismissible: true,
|
||||||
|
enableDrag: false,
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
child: Container(
|
||||||
|
height: 503.w,
|
||||||
|
width: ScreenUtil().screenWidth,
|
||||||
|
padding: EdgeInsets.fromLTRB(0.w, 75.w, 0.w, 20.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('video_recommend_bg.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(width: 15.w),
|
||||||
|
Image.asset('ip.png'.ktIcon, width: 38.w, height: 40.w),
|
||||||
|
SizedBox(width: 6.w),
|
||||||
|
Container(
|
||||||
|
height: 30.w,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 14.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFF1E1E20),
|
||||||
|
borderRadius: BorderRadius.circular(15.w),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'More Drama Gold Below!',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFFA7F62F),
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 290.w,
|
||||||
|
child: Swiper(
|
||||||
|
layout: SwiperLayout.CUSTOM,
|
||||||
|
customLayoutOption:
|
||||||
|
CustomLayoutOption(startIndex: -1, stateCount: 3)
|
||||||
|
..addRotate([-20.0 / 180, 0.0, 20.0 / 180])
|
||||||
|
..addTranslate([
|
||||||
|
Offset(-220.w, 0),
|
||||||
|
Offset(0, 0),
|
||||||
|
Offset(220.w, 0),
|
||||||
|
]),
|
||||||
|
itemWidth: 190.w,
|
||||||
|
itemHeight: 226.w,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final item =
|
||||||
|
state.recommendList[index %
|
||||||
|
state.recommendList.length];
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
Get.toNamed(
|
||||||
|
KtRoutes.shortVideo,
|
||||||
|
arguments: {
|
||||||
|
'shortPlayId':
|
||||||
|
state.recommendList[index].shortPlayId,
|
||||||
|
'imageUrl':
|
||||||
|
state.recommendList[index].imageUrl ?? '',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: KtNetworkImage(
|
||||||
|
imageUrl: item.imageUrl ?? '',
|
||||||
|
width: 190.w,
|
||||||
|
height: 226.w,
|
||||||
|
borderRadius: BorderRadius.circular(20.w),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: state.recommendList.length,
|
||||||
|
loop: true,
|
||||||
|
autoplay: true,
|
||||||
|
onIndexChanged: (index) => state.recommendIndex = index,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
Get.toNamed(
|
||||||
|
KtRoutes.shortVideo,
|
||||||
|
arguments: {
|
||||||
|
'shortPlayId': state
|
||||||
|
.recommendList[state.recommendIndex]
|
||||||
|
.shortPlayId,
|
||||||
|
'imageUrl':
|
||||||
|
state
|
||||||
|
.recommendList[state.recommendIndex]
|
||||||
|
.imageUrl ??
|
||||||
|
'',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 280.w,
|
||||||
|
height: 64.w,
|
||||||
|
padding: EdgeInsets.only(bottom: 16.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(
|
||||||
|
'video_recommend_btn.png'.ktIcon,
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
height: 48.w,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'video_recommend_play.png'.ktIcon,
|
||||||
|
width: 18.w,
|
||||||
|
height: 18.w,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'watch now',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
12
lib/kt_pages/kt_refill/state.dart
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import 'package:flutter_kinetra/kt_model/kt_receive_coin_info.dart';
|
||||||
|
|
||||||
|
import 'package:flutter_kinetra/kt_model/kt_short_video_bean.dart';
|
||||||
|
|
||||||
|
class KtRefillState {
|
||||||
|
KtRefillState();
|
||||||
|
|
||||||
|
ReceiveCoinInfo? receiveCoinInfo;
|
||||||
|
bool hasSubCoin = false;
|
||||||
|
List<KtShortVideoBean> recommendList = [];
|
||||||
|
int recommendIndex = 0;
|
||||||
|
}
|
||||||
772
lib/kt_pages/kt_refill/view.dart
Normal file
@ -0,0 +1,772 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
|
import '../../kt_model/kt_receive_coin_info.dart';
|
||||||
|
import '../../kt_model/kt_goods_bean.dart';
|
||||||
|
import '../../kt_utils/kt_string_extend.dart';
|
||||||
|
import '../kt_mine/kt_store/logic.dart';
|
||||||
|
import 'logic.dart';
|
||||||
|
|
||||||
|
class KtRefillPage extends StatefulWidget {
|
||||||
|
const KtRefillPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<KtRefillPage> createState() => _KtRefillPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _KtRefillPageState extends State<KtRefillPage> {
|
||||||
|
final logic = Get.put(KtRefillLogic());
|
||||||
|
final state = Get.find<KtRefillLogic>().state;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
extendBodyBehindAppBar: true,
|
||||||
|
body: Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(
|
||||||
|
15.w,
|
||||||
|
ScreenUtil().statusBarHeight,
|
||||||
|
15.w,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('bg1.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: Image.asset('ic_back.png'.ktIcon, width: 10.w),
|
||||||
|
onPressed: () => Navigator.of(context).maybePop(),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'My Refills',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 24.w),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: GetBuilder<KtRefillLogic>(
|
||||||
|
builder: (ctrl) {
|
||||||
|
return SmartRefresher(
|
||||||
|
controller: logic.refreshController,
|
||||||
|
physics: const ClampingScrollPhysics(),
|
||||||
|
enablePullUp: false,
|
||||||
|
enablePullDown: true,
|
||||||
|
onRefresh: logic.refreshInfo,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
cardView(),
|
||||||
|
if (state.hasSubCoin) activeRefillView(),
|
||||||
|
weeklyRefillView(),
|
||||||
|
ruleView(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget cardView() {
|
||||||
|
return Container(
|
||||||
|
width: 345.w,
|
||||||
|
height: 258.w,
|
||||||
|
padding: EdgeInsets.only(top: 59.w, left: 14.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('refills_top_bg.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Rewards Overview',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF1E1E20),
|
||||||
|
fontSize: 15.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 16.w),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Weekly Total',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF5E5E5E),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 4.w),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('ic_coin.png'.ktIcon, width: 17),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'${state.receiveCoinInfo?.weekMaxTotal ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFFF9500),
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 18.w),
|
||||||
|
width: 1.w,
|
||||||
|
height: 32.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('refills_top_bg_line.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Claimable Coins',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF5E5E5E),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 4.w),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('ic_coin.png'.ktIcon, width: 17),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'${state.receiveCoinInfo?.weekTotal ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFFF9500),
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Active Refills:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF777777),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${state.receiveCoinInfo?.receiveCount ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF79C900),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 6.w),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (!state.hasSubCoin) return;
|
||||||
|
logic.receiveDayCoin();
|
||||||
|
},
|
||||||
|
child: state.hasSubCoin
|
||||||
|
? Stack(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'refills_top_btn_all.png'.ktIcon,
|
||||||
|
width: 337.w,
|
||||||
|
height: 68.w,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 46.w,
|
||||||
|
margin: EdgeInsets.only(top: 5.w),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Claim All',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF1E1E20),
|
||||||
|
fontSize: 15.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 6.w),
|
||||||
|
Image.asset('ic_coin.png'.ktIcon, width: 13),
|
||||||
|
SizedBox(width: 2.w),
|
||||||
|
Text(
|
||||||
|
'${state.receiveCoinInfo?.receiveCoins ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF1E1E20),
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Stack(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'refills_top_btn.png'.ktIcon,
|
||||||
|
width: 337.w,
|
||||||
|
height: 68.w,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 46.w,
|
||||||
|
margin: EdgeInsets.only(top: 5.w),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Get a Refill to Claim',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFF7F7F7),
|
||||||
|
fontSize: 15.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget activeRefillView() {
|
||||||
|
return GetBuilder<KtRefillLogic>(
|
||||||
|
builder: (ctrl) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20.w),
|
||||||
|
Text(
|
||||||
|
'Active Refills',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15.sp,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF1C1C1C),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListView.builder(
|
||||||
|
padding: EdgeInsets.only(top: 0.w),
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: state.receiveCoinInfo?.receiveList?.length ?? 2,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
ReceiveList? item = state.receiveCoinInfo?.receiveList?[index];
|
||||||
|
return Container(
|
||||||
|
width: 345.w,
|
||||||
|
height: 122.w,
|
||||||
|
padding: EdgeInsets.only(top: 14.w, left: 12.w),
|
||||||
|
margin: EdgeInsets.only(top: 10.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('refills_center_bg-s.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
item?.title ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8.w),
|
||||||
|
Text(
|
||||||
|
'(Day ${item?.dayText ?? ''}/7)',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.white.withValues(alpha: 0.70),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(vertical: 12.w),
|
||||||
|
width: 320.w,
|
||||||
|
height: 1.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('refills_center_line.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Total Reward',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFCAB7A9),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.w),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('ic_coin.png'.ktIcon, width: 14),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'${item?.weekMaxTotal ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFFFF9E8),
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 12.w),
|
||||||
|
width: 1.w,
|
||||||
|
height: 32.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(
|
||||||
|
'refills_center_line2.png'.ktIcon,
|
||||||
|
),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Remaining',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFCAB7A9),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8.w),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('ic_coin.png'.ktIcon, width: 14),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'${item?.weekRemainingTotal ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFFFF9E8),
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (item?.receiveCoins == 0) return;
|
||||||
|
logic.receiveDayCoin(id: item!.id);
|
||||||
|
},
|
||||||
|
child: item?.receiveCoins == 0
|
||||||
|
? Container(
|
||||||
|
width: 100.w,
|
||||||
|
height: 48.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xE5B1B1B1),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(14.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'Claimed',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFFF7F7F7),
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 100.w,
|
||||||
|
height: 48.w,
|
||||||
|
padding: EdgeInsets.only(top: 5.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [
|
||||||
|
const Color(0xFF986100),
|
||||||
|
const Color(0xFF322000),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
border: Border.all(
|
||||||
|
width: 0.5.w,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(14.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Claim',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'ic_coin.png'.ktIcon,
|
||||||
|
width: 14,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'${item?.receiveCoins ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Colors.white
|
||||||
|
.withValues(
|
||||||
|
alpha: 0.70,
|
||||||
|
),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: -6.w,
|
||||||
|
top: -6.w,
|
||||||
|
child: Image.asset(
|
||||||
|
'refills_center_star.png'.ktIcon,
|
||||||
|
width: 20.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
right: -6.w,
|
||||||
|
bottom: -6.w,
|
||||||
|
child: Image.asset(
|
||||||
|
'refills_center_star.png'.ktIcon,
|
||||||
|
width: 20.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12.w),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget weeklyRefillView() {
|
||||||
|
Get.put(KtStoreLogic());
|
||||||
|
return GetBuilder<KtStoreLogic>(
|
||||||
|
builder: (ctrl) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20.w),
|
||||||
|
if (ctrl.state.refillCoinList.isNotEmpty)
|
||||||
|
Text(
|
||||||
|
'Weekly Refill',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontSize: 15.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF1C1C1C),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListView.builder(
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: ctrl.state.refillCoinList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
KtGoodsBean? item = ctrl.state.refillCoinList[index];
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => ctrl.buyGoods(item),
|
||||||
|
child: Container(
|
||||||
|
width: 345.w,
|
||||||
|
height: 80.w,
|
||||||
|
padding: EdgeInsets.only(left: 16.w, right: 13.w),
|
||||||
|
margin: EdgeInsets.only(top: 10.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('refills_center_bg.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Weekly Refill',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5.w),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('ic_coin.png'.ktIcon, width: 16),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'${item.extInfo?.maxTotalCoins ?? 0}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFFFFF9E8),
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Container(
|
||||||
|
height: 18.w,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 8.w,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.15),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(4.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
item.extInfo?.receiveCoinsRate ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
constraints: BoxConstraints(minWidth: 90.w),
|
||||||
|
height: 48.w,
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: 5.w,
|
||||||
|
left: 15.w,
|
||||||
|
right: 15.w,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [
|
||||||
|
const Color(0xFF986100),
|
||||||
|
const Color(0xFF322000),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
border: Border.all(
|
||||||
|
width: 0.5.w,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(14.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
item.productDetails?.price ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
height: 1,
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'/week',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Colors.white.withValues(
|
||||||
|
alpha: 0.50,
|
||||||
|
),
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: -6.w,
|
||||||
|
top: -6.w,
|
||||||
|
child: Image.asset(
|
||||||
|
'refills_center_star.png'.ktIcon,
|
||||||
|
width: 20.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
right: -6.w,
|
||||||
|
bottom: -6.w,
|
||||||
|
child: Image.asset(
|
||||||
|
'refills_center_star.png'.ktIcon,
|
||||||
|
width: 20.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget ruleView() {
|
||||||
|
return Container(
|
||||||
|
margin: EdgeInsets.only(top: 10.w, bottom: 43.w),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Subscription Rules',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF94949B),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 6.w),
|
||||||
|
...[
|
||||||
|
'1.Up to 2 subscriptions can be active at once.',
|
||||||
|
'2.Coins are delivered instantly upon purchase.',
|
||||||
|
'3.Daily bonus coins available from the next day.',
|
||||||
|
'4.All coins will be revoked when the subscription expires,',
|
||||||
|
'including both initial and daily coins.',
|
||||||
|
].map(
|
||||||
|
(text) => Container(
|
||||||
|
margin: EdgeInsets.only(bottom: 4.w),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Color(0xFF94949B),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,7 +11,7 @@ import 'kt_mine/kt_store/view.dart';
|
|||||||
import 'kt_short_video/view.dart';
|
import 'kt_short_video/view.dart';
|
||||||
import 'kt_splash_page.dart';
|
import 'kt_splash_page.dart';
|
||||||
import 'kt_webview_page.dart';
|
import 'kt_webview_page.dart';
|
||||||
|
import 'kt_refill/view.dart';
|
||||||
///路由文件
|
///路由文件
|
||||||
class KtRoutes {
|
class KtRoutes {
|
||||||
static const String splash = '/';
|
static const String splash = '/';
|
||||||
@ -52,5 +52,6 @@ class KtRoutes {
|
|||||||
name: webView,
|
name: webView,
|
||||||
page: () => const KtWebViewPage(url: 'url'),
|
page: () => const KtWebViewPage(url: 'url'),
|
||||||
),
|
),
|
||||||
|
GetPage(name: refill, page: () => const KtRefillPage()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:async';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:card_swiper/card_swiper.dart';
|
||||||
import 'package:flutter_kinetra/kt_pages/kt_mine/logic.dart';
|
import 'package:flutter_kinetra/kt_pages/kt_mine/logic.dart';
|
||||||
import 'package:flutter_kinetra/kt_pages/kt_short_video/state.dart';
|
import 'package:flutter_kinetra/kt_pages/kt_short_video/state.dart';
|
||||||
import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
|
import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
|
||||||
import 'package:flutter_kinetra/kt_utils/kt_toast_utils.dart';
|
import 'package:flutter_kinetra/kt_utils/kt_toast_utils.dart';
|
||||||
|
import 'package:flutter_kinetra/kt_pages/kt_home/logic.dart';
|
||||||
|
import 'package:flutter_kinetra/kt_pages/kt_my_list/logic.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:video_player/video_player.dart';
|
import 'package:video_player/video_player.dart';
|
||||||
@ -14,10 +17,13 @@ import 'package:video_player/video_player.dart';
|
|||||||
import '../../dio_cilent/kt_apis.dart';
|
import '../../dio_cilent/kt_apis.dart';
|
||||||
import '../../dio_cilent/kt_request.dart';
|
import '../../dio_cilent/kt_request.dart';
|
||||||
import '../../kt_model/kt_video_detail_bean.dart';
|
import '../../kt_model/kt_video_detail_bean.dart';
|
||||||
|
import '../../kt_model/kt_short_video_bean.dart';
|
||||||
import '../../kt_utils/kt_device_info_utils.dart';
|
import '../../kt_utils/kt_device_info_utils.dart';
|
||||||
import '../../kt_widgets/kt_status_widget.dart';
|
import '../../kt_widgets/kt_status_widget.dart';
|
||||||
import '../../kt_widgets/kt_store_widget.dart';
|
import '../../kt_widgets/kt_store_widget.dart';
|
||||||
|
import '../../kt_widgets/kt_dialog.dart';
|
||||||
import '../kt_mine/kt_store/logic.dart';
|
import '../kt_mine/kt_store/logic.dart';
|
||||||
|
import '../../kt_widgets/kt_network_image.dart';
|
||||||
|
|
||||||
class VideoPlayLogic extends GetxController {
|
class VideoPlayLogic extends GetxController {
|
||||||
final state = VideoPlayState();
|
final state = VideoPlayState();
|
||||||
@ -30,6 +36,9 @@ class VideoPlayLogic extends GetxController {
|
|||||||
bool _disposed = false;
|
bool _disposed = false;
|
||||||
final userLogic = Get.put(KtMineLogic());
|
final userLogic = Get.put(KtMineLogic());
|
||||||
|
|
||||||
|
final mylistLogic = Get.put(MyListLogic());
|
||||||
|
final mylistState = Get.find<MyListLogic>().state;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
@ -45,16 +54,44 @@ class VideoPlayLogic extends GetxController {
|
|||||||
state.imageUrl = Get.arguments['imageUrl'] ?? '';
|
state.imageUrl = Get.arguments['imageUrl'] ?? '';
|
||||||
state.activityId = Get.arguments['activityId'];
|
state.activityId = Get.arguments['activityId'];
|
||||||
state.isFromDiscover = Get.arguments['isFromDiscover'] ?? false;
|
state.isFromDiscover = Get.arguments['isFromDiscover'] ?? false;
|
||||||
|
startTimer();
|
||||||
fetchData();
|
fetchData();
|
||||||
|
getRecommend();
|
||||||
|
startVideoTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
clearCacheCtrl();
|
clearCacheCtrl();
|
||||||
|
state.timer?.cancel();
|
||||||
|
state.videotimer?.cancel();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 推荐点击
|
||||||
|
initData(shortPlayId, imageUrl) {
|
||||||
|
uploadHistorySeconds(
|
||||||
|
controllers[currentIndex]?.value.position.inMilliseconds ?? 0,
|
||||||
|
);
|
||||||
|
Get.back();
|
||||||
|
state.shortPlayId = shortPlayId;
|
||||||
|
state.videoId = 0;
|
||||||
|
state.imageUrl = imageUrl;
|
||||||
|
state.isRecommend = false;
|
||||||
|
|
||||||
|
// pageController.dispose();
|
||||||
|
currentIndex = 0;
|
||||||
|
pageController.jumpToPage(currentIndex);
|
||||||
|
// pageController = PageController(initialPage: currentIndex);
|
||||||
|
clearCacheCtrl();
|
||||||
|
fetchData();
|
||||||
|
state.recommendList.clear();
|
||||||
|
getRecommend();
|
||||||
|
startTimer();
|
||||||
|
startVideoTimer();
|
||||||
|
}
|
||||||
|
|
||||||
clearCacheCtrl() {
|
clearCacheCtrl() {
|
||||||
for (var controller in controllers) {
|
for (var controller in controllers) {
|
||||||
controller?.pause();
|
controller?.pause();
|
||||||
@ -88,6 +125,8 @@ class VideoPlayLogic extends GetxController {
|
|||||||
state.videoId = state.video?.videoInfo?.shortPlayVideoId ?? 0;
|
state.videoId = state.video?.videoInfo?.shortPlayVideoId ?? 0;
|
||||||
}
|
}
|
||||||
state.episodeList = state.video?.episodeList ?? [];
|
state.episodeList = state.video?.episodeList ?? [];
|
||||||
|
state.videoFirstTime =
|
||||||
|
int.tryParse(state.video?.videoInfo?.playSeconds ?? '0') ?? 0;
|
||||||
if (toPage) currentIndex = (state.video?.videoInfo?.episode ?? 1) - 1;
|
if (toPage) currentIndex = (state.video?.videoInfo?.episode ?? 1) - 1;
|
||||||
for (var video in state.episodeList) {
|
for (var video in state.episodeList) {
|
||||||
if (video.isLock == true) {
|
if (video.isLock == true) {
|
||||||
@ -105,6 +144,7 @@ class VideoPlayLogic extends GetxController {
|
|||||||
currentIndex,
|
currentIndex,
|
||||||
isToggle: true,
|
isToggle: true,
|
||||||
isUploadHistorySeconds: false,
|
isUploadHistorySeconds: false,
|
||||||
|
type: 1,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
_initializeController(currentIndex);
|
_initializeController(currentIndex);
|
||||||
@ -123,6 +163,37 @@ class VideoPlayLogic extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5s之后返回推荐
|
||||||
|
void startTimer() {
|
||||||
|
state.timer = Timer(const Duration(seconds: 5), () {
|
||||||
|
state.isRecommend = true;
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5s 之后隐藏控制器
|
||||||
|
void startVideoTimer() {
|
||||||
|
state.videotimer?.cancel();
|
||||||
|
state.videotimer = Timer(const Duration(seconds: 5), () {
|
||||||
|
state.isVideoctrHide = true;
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取推荐列表
|
||||||
|
getRecommend() async {
|
||||||
|
ApiResponse res = await KtHttpClient().request(
|
||||||
|
KtApis.getDetailsRecommand,
|
||||||
|
method: HttpMethod.get,
|
||||||
|
);
|
||||||
|
if (res.success) {
|
||||||
|
state.recommendList = [
|
||||||
|
...res.data['list'].map((item) => KtShortVideoBean.fromJson(item)),
|
||||||
|
];
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void reportHistory() {
|
void reportHistory() {
|
||||||
if (currentIndex < 0 || currentIndex >= state.episodeList.length) return;
|
if (currentIndex < 0 || currentIndex >= state.episodeList.length) return;
|
||||||
Map<String, dynamic> params = {
|
Map<String, dynamic> params = {
|
||||||
@ -141,6 +212,19 @@ class VideoPlayLogic extends GetxController {
|
|||||||
KtHttpClient().request(KtApis.activeAfterWatchingVideo, data: params);
|
KtHttpClient().request(KtApis.activeAfterWatchingVideo, data: params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateHomeVideo() {
|
||||||
|
final homeLogic = Get.put(KtHomeLogic());
|
||||||
|
final homeState = Get.find<KtHomeLogic>().state;
|
||||||
|
int playTime = controllers[currentIndex]?.value.position.inSeconds ?? 0;
|
||||||
|
homeState.curVideo = KtShortVideoBean()
|
||||||
|
..shortPlayId = state.shortPlayId
|
||||||
|
..imageUrl = state.video?.shortPlayInfo?.imageUrl
|
||||||
|
..name = state.video?.shortPlayInfo?.name
|
||||||
|
..playTime = playTime
|
||||||
|
..process = currentIndex + 1;
|
||||||
|
homeLogic.update();
|
||||||
|
}
|
||||||
|
|
||||||
// 切换剧集时处理视频状态
|
// 切换剧集时处理视频状态
|
||||||
Future<void> onPageChanged(
|
Future<void> onPageChanged(
|
||||||
int index, {
|
int index, {
|
||||||
@ -177,6 +261,9 @@ class VideoPlayLogic extends GetxController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
currentIndex = index;
|
currentIndex = index;
|
||||||
|
if (type == 1) {
|
||||||
|
controllers[index]?.seekTo(Duration(milliseconds: state.videoFirstTime));
|
||||||
|
}
|
||||||
if (state.episodeList[index].isLock == true) {
|
if (state.episodeList[index].isLock == true) {
|
||||||
controllers[index]?.seekTo(Duration(seconds: 0));
|
controllers[index]?.seekTo(Duration(seconds: 0));
|
||||||
controllers[index]?.pause();
|
controllers[index]?.pause();
|
||||||
@ -199,8 +286,9 @@ class VideoPlayLogic extends GetxController {
|
|||||||
controllers[index]?.play();
|
controllers[index]?.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
controllers[index]?.setPlaybackSpeed(state.currentSpeed);
|
controllers[index]?.setPlaybackSpeed(state.currentSpeed);
|
||||||
// updateHomeVideo();
|
updateHomeVideo();
|
||||||
// print('----curIndex:$currentIndex');
|
// print('----curIndex:$currentIndex');
|
||||||
// 预加载新的相邻视频,并释放多余控制器
|
// 预加载新的相邻视频,并释放多余控制器
|
||||||
_preloadAdjacentVideos();
|
_preloadAdjacentVideos();
|
||||||
@ -241,7 +329,8 @@ class VideoPlayLogic extends GetxController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await controller.initialize();
|
await controller.initialize();
|
||||||
if (index == currentIndex && (episode.isLock == false || userLogic.state.userInfo.isVip == true)) {
|
if (index == currentIndex &&
|
||||||
|
(episode.isLock == false || userLogic.state.userInfo.isVip == true)) {
|
||||||
controller.play();
|
controller.play();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
@ -251,7 +340,7 @@ class VideoPlayLogic extends GetxController {
|
|||||||
if (currentIndex == index && !_disposed) update();
|
if (currentIndex == index && !_disposed) update();
|
||||||
if (currentIndex == state.episodeList.length - 1 &&
|
if (currentIndex == state.episodeList.length - 1 &&
|
||||||
(controllers.last?.value.isCompleted ?? false)) {
|
(controllers.last?.value.isCompleted ?? false)) {
|
||||||
// showRecommendDialog();
|
showRecommendDialog();
|
||||||
}
|
}
|
||||||
if (controller.value.isCompleted && !controller.value.isBuffering) {
|
if (controller.value.isCompleted && !controller.value.isBuffering) {
|
||||||
onPageChanged(index + 1, isToggle: true);
|
onPageChanged(index + 1, isToggle: true);
|
||||||
@ -291,20 +380,21 @@ class VideoPlayLogic extends GetxController {
|
|||||||
|
|
||||||
Future<void> likeVideo() async {
|
Future<void> likeVideo() async {
|
||||||
if (state.video == null) return;
|
if (state.video == null) return;
|
||||||
|
|
||||||
Map<String, dynamic> params = {
|
Map<String, dynamic> params = {
|
||||||
"short_play_id": state.video?.shortPlayInfo?.shortPlayId,
|
"short_play_id": state.video?.shortPlayInfo?.shortPlayId,
|
||||||
"video_id": state.episodeList[currentIndex].id,
|
"video_id": state.episodeList[currentIndex].id,
|
||||||
};
|
};
|
||||||
if (state.video?.shortPlayInfo?.isCollect ?? false) {
|
if (state.video?.shortPlayInfo?.isCollect ?? false) {
|
||||||
await KtHttpClient().request(KtApis.deleteFavoriteVideo, data: params);
|
// await KtHttpClient().request(KtApis.deleteFavoriteVideo, data: params);
|
||||||
|
cancelCollect(state.video!.shortPlayInfo!.shortPlayId!);
|
||||||
} else {
|
} else {
|
||||||
await KtHttpClient().request(KtApis.collectVideo, data: params);
|
await KtHttpClient().request(KtApis.collectVideo, data: params);
|
||||||
|
state.video?.shortPlayInfo?.isCollect =
|
||||||
|
!(state.video?.shortPlayInfo?.isCollect ?? false);
|
||||||
|
update();
|
||||||
|
mylistLogic.getCollectList(refresh: true);
|
||||||
|
mylistLogic.getHistoryList(refresh: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.video?.shortPlayInfo?.isCollect =
|
|
||||||
!(state.video?.shortPlayInfo?.isCollect ?? false);
|
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 购买剧集
|
// 购买剧集
|
||||||
@ -428,4 +518,202 @@ class VideoPlayLogic extends GetxController {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelCollect(num id) async {
|
||||||
|
Get.dialog(
|
||||||
|
KtDialog(
|
||||||
|
title: 'Remove from your list?',
|
||||||
|
subTitle: 'This drama will be removed from your saved list.',
|
||||||
|
rightBtnText: 'Remove',
|
||||||
|
rightBtnIcon: 'ic_dialog_delete.png',
|
||||||
|
rightBtnFunc: () async {
|
||||||
|
ApiResponse res = await KtHttpClient().request(
|
||||||
|
KtApis.deleteFavoriteVideo,
|
||||||
|
queryParameters: {'short_play_id': id},
|
||||||
|
);
|
||||||
|
if (res.success) {
|
||||||
|
state.video?.shortPlayInfo?.isCollect =
|
||||||
|
!(state.video?.shortPlayInfo?.isCollect ?? false);
|
||||||
|
update();
|
||||||
|
// state.favoriteList.removeWhere((item) => id == item.shortPlayId);
|
||||||
|
mylistState.chestList.removeWhere((item) => id == item.shortPlayId);
|
||||||
|
mylistState.historyList
|
||||||
|
.firstWhereOrNull((item) => id == item.shortPlayId)
|
||||||
|
?.isCollect =
|
||||||
|
0;
|
||||||
|
mylistLogic.update();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
showRecommendDialog() {
|
||||||
|
EasyThrottle.throttle('show-recommend', Duration(seconds: 3), () async {
|
||||||
|
controllers[currentIndex]?.pause();
|
||||||
|
Get.bottomSheet(
|
||||||
|
isScrollControlled: true,
|
||||||
|
isDismissible: false,
|
||||||
|
enableDrag: false,
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
top: ScreenUtil().statusBarHeight + 10.w,
|
||||||
|
left: 16.w,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
EasyThrottle.throttle(
|
||||||
|
'back-recommend',
|
||||||
|
Duration(seconds: 3),
|
||||||
|
() async {
|
||||||
|
Get.back();
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Image.asset('ic_back_white.png'.ktIcon, width: 24.w),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
child: Container(
|
||||||
|
height: 503.w,
|
||||||
|
width: ScreenUtil().screenWidth,
|
||||||
|
padding: EdgeInsets.fromLTRB(0.w, 75.w, 0.w, 20.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('video_recommend_bg.png'.ktIcon),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(width: 15.w),
|
||||||
|
Image.asset('ip.png'.ktIcon, width: 38.w, height: 40.w),
|
||||||
|
SizedBox(width: 6.w),
|
||||||
|
Container(
|
||||||
|
height: 30.w,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 14.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFF1E1E20),
|
||||||
|
borderRadius: BorderRadius.circular(15.w),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'More Drama Gold Below!',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFFA7F62F),
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 290.w,
|
||||||
|
child: Swiper(
|
||||||
|
layout: SwiperLayout.CUSTOM,
|
||||||
|
customLayoutOption:
|
||||||
|
CustomLayoutOption(startIndex: -1, stateCount: 3)
|
||||||
|
..addRotate([-20.0 / 180, 0.0, 20.0 / 180])
|
||||||
|
..addTranslate([
|
||||||
|
Offset(-220.w, 0),
|
||||||
|
Offset(0, 0),
|
||||||
|
Offset(220.w, 0),
|
||||||
|
]),
|
||||||
|
itemWidth: 190.w,
|
||||||
|
itemHeight: 226.w,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final item =
|
||||||
|
state.recommendList[index %
|
||||||
|
state.recommendList.length];
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
initData(
|
||||||
|
state.recommendList[index].shortPlayId ?? -1,
|
||||||
|
state.recommendList[index].imageUrl ?? '',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: KtNetworkImage(
|
||||||
|
imageUrl: item.imageUrl ?? '',
|
||||||
|
width: 190.w,
|
||||||
|
height: 226.w,
|
||||||
|
borderRadius: BorderRadius.circular(20.w),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: state.recommendList.length,
|
||||||
|
loop: true,
|
||||||
|
autoplay: true,
|
||||||
|
onIndexChanged: (index) => state.recommendIndex = index,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
initData(
|
||||||
|
state
|
||||||
|
.recommendList[state.recommendIndex]
|
||||||
|
.shortPlayId ??
|
||||||
|
-1,
|
||||||
|
state
|
||||||
|
.recommendList[state.recommendIndex]
|
||||||
|
.imageUrl ??
|
||||||
|
'',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 280.w,
|
||||||
|
height: 64.w,
|
||||||
|
padding: EdgeInsets.only(bottom: 16.w),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(
|
||||||
|
'video_recommend_btn.png'.ktIcon,
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
height: 48.w,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'video_recommend_play.png'.ktIcon,
|
||||||
|
width: 18.w,
|
||||||
|
height: 18.w,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Text(
|
||||||
|
'watch now',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import '../../kt_model/kt_video_detail_bean.dart';
|
import '../../kt_model/kt_video_detail_bean.dart';
|
||||||
import '../../kt_widgets/kt_status_widget.dart';
|
import '../../kt_widgets/kt_status_widget.dart';
|
||||||
|
import '../../kt_model/kt_short_video_bean.dart';
|
||||||
|
|
||||||
class VideoPlayState {
|
class VideoPlayState {
|
||||||
String imageUrl = '';
|
String imageUrl = '';
|
||||||
int shortPlayId = -1;
|
num shortPlayId = -1;
|
||||||
num videoId = -1;
|
num videoId = -1;
|
||||||
|
int videoFirstTime = 0;
|
||||||
int curUnlock = 999;
|
int curUnlock = 999;
|
||||||
int? activityId;
|
int? activityId;
|
||||||
bool isFromDiscover = false;
|
bool isFromDiscover = false;
|
||||||
@ -15,4 +19,12 @@ class VideoPlayState {
|
|||||||
int currentVideoIndex = 0;
|
int currentVideoIndex = 0;
|
||||||
double currentSpeed = 1.0;
|
double currentSpeed = 1.0;
|
||||||
final List<double> speedList = [0.75, 1.0, 1.25, 1.5, 2.0, 3.0];
|
final List<double> speedList = [0.75, 1.0, 1.25, 1.5, 2.0, 3.0];
|
||||||
|
List<KtShortVideoBean> recommendList = [];
|
||||||
|
int recommendIndex = 0;
|
||||||
|
|
||||||
|
bool isRecommend = false;
|
||||||
|
Timer? timer;
|
||||||
|
|
||||||
|
bool isVideoctrHide = false;
|
||||||
|
Timer? videotimer;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ class _VideoPlayPageState extends State<VideoPlayPage>
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
state.imageUrl = Get.arguments['imageUrl'] ?? '';
|
state.imageUrl = Get.arguments['imageUrl'] ?? '';
|
||||||
|
// state.isFromRecommend = Get.arguments['isFromRecommend'] ?? false;
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,9 +55,16 @@ class _VideoPlayPageState extends State<VideoPlayPage>
|
|||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: true,
|
canPop: true,
|
||||||
onPopInvokedWithResult: (didPop, result) async {
|
onPopInvokedWithResult: (didPop, result) async {
|
||||||
// if (logic.controllers.isNotEmpty) {
|
if (logic.controllers.isNotEmpty) {
|
||||||
// logic.uploadHistorySeconds(logic.controllers[logic.currentIndex]?.value.position.inMilliseconds ?? 0);
|
logic.uploadHistorySeconds(
|
||||||
// }
|
logic
|
||||||
|
.controllers[logic.currentIndex]
|
||||||
|
?.value
|
||||||
|
.position
|
||||||
|
.inMilliseconds ??
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (didPop) return;
|
if (didPop) return;
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
@ -206,9 +214,22 @@ class _VideoPlayPageState extends State<VideoPlayPage>
|
|||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (episode.isLock == true) return;
|
if (episode.isLock == true) return;
|
||||||
(controller?.value.isPlaying ?? true)
|
|
||||||
? controller?.pause()
|
if (controller?.value.isPlaying ?? true) {
|
||||||
: controller?.play();
|
if (state.isVideoctrHide) {
|
||||||
|
state.isVideoctrHide = false;
|
||||||
|
logic.startVideoTimer();
|
||||||
|
} else {
|
||||||
|
controller?.pause();
|
||||||
|
state.videotimer?.cancel();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logic.startVideoTimer();
|
||||||
|
controller?.play();
|
||||||
|
}
|
||||||
|
// (controller?.value.isPlaying ?? true)
|
||||||
|
// ? controller?.pause()
|
||||||
|
// : controller?.play();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -298,123 +319,126 @@ class _VideoPlayPageState extends State<VideoPlayPage>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// 顶部返回
|
|
||||||
Positioned(
|
if (!state.isVideoctrHide) ...[
|
||||||
top: ScreenUtil().statusBarHeight + 10.w,
|
// 顶部返回
|
||||||
left: 16.w,
|
Positioned(
|
||||||
child: GestureDetector(
|
top: ScreenUtil().statusBarHeight + 10.w,
|
||||||
onTap: () {
|
left: 16.w,
|
||||||
// if (state.isFromRecommend || state.recommendList.isEmpty) {
|
child: GestureDetector(
|
||||||
Get.back();
|
onTap: () {
|
||||||
// } else {
|
if (!state.isRecommend || state.recommendList.isEmpty) {
|
||||||
// logic.showRecommendDialog();
|
Get.back();
|
||||||
// }
|
} else {
|
||||||
},
|
logic.showRecommendDialog();
|
||||||
child: Image.asset('ic_back_white.png'.ktIcon, width: 24.w),
|
}
|
||||||
),
|
},
|
||||||
),
|
child: Image.asset('ic_back_white.png'.ktIcon, width: 24.w),
|
||||||
// 底部控制器
|
|
||||||
Positioned(
|
|
||||||
bottom: 0,
|
|
||||||
left: 0.w,
|
|
||||||
child: Container(
|
|
||||||
width: ScreenUtil().screenWidth,
|
|
||||||
padding: EdgeInsets.fromLTRB(15.w, 40.w, 15.w, 40.w),
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
begin: Alignment.topCenter,
|
|
||||||
end: Alignment.bottomCenter,
|
|
||||||
colors: [
|
|
||||||
Color(0xFF001D1F).withValues(alpha: 0),
|
|
||||||
Color(0xFF001D1F),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: Column(
|
),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
// 底部控制器
|
||||||
children: [
|
Positioned(
|
||||||
SizedBox(
|
bottom: 0,
|
||||||
width: ScreenUtil().screenWidth - 100.w,
|
left: 0.w,
|
||||||
child: Text(
|
child: Container(
|
||||||
state.video?.shortPlayInfo?.name ?? '',
|
width: ScreenUtil().screenWidth,
|
||||||
maxLines: 1,
|
padding: EdgeInsets.fromLTRB(15.w, 40.w, 15.w, 40.w),
|
||||||
overflow: TextOverflow.ellipsis,
|
alignment: Alignment.bottomCenter,
|
||||||
style: TextStyle(
|
decoration: BoxDecoration(
|
||||||
fontSize: 16.sp,
|
gradient: LinearGradient(
|
||||||
color: Colors.white,
|
begin: Alignment.topCenter,
|
||||||
fontWeight: FontWeight.w500,
|
end: Alignment.bottomCenter,
|
||||||
),
|
colors: [
|
||||||
),
|
Color(0xFF001D1F).withValues(alpha: 0),
|
||||||
|
Color(0xFF001D1F),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
if (logic.controllers[index] != null)
|
),
|
||||||
CustomVideoProgressBar(
|
child: Column(
|
||||||
controller: logic.controllers[index]!,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
width: ScreenUtil().screenWidth,
|
children: [
|
||||||
),
|
SizedBox(
|
||||||
SizedBox(height: 16.w),
|
width: ScreenUtil().screenWidth - 100.w,
|
||||||
Row(
|
child: Text(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
state.video?.shortPlayInfo?.name ?? '',
|
||||||
children: [
|
maxLines: 1,
|
||||||
GestureDetector(
|
overflow: TextOverflow.ellipsis,
|
||||||
onTap: showEpSelDialog,
|
style: TextStyle(
|
||||||
child: Container(
|
fontSize: 16.sp,
|
||||||
width: 300.w,
|
color: Colors.white,
|
||||||
padding: EdgeInsets.symmetric(
|
fontWeight: FontWeight.w500,
|
||||||
horizontal: 12.w,
|
|
||||||
vertical: 9.w,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(50.w),
|
|
||||||
color: Colors.white.withValues(alpha: .1),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Image.asset('ic_ep.png'.ktIcon, width: 16.sp),
|
|
||||||
SizedBox(width: 6.w),
|
|
||||||
Text(
|
|
||||||
'EP.${index + 1}',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13.sp,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
Text(
|
|
||||||
'All ${state.video?.shortPlayInfo?.episodeTotal ?? 0} Episodes',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13.sp,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GetBuilder<VideoPlayLogic>(
|
),
|
||||||
id: 'video-like',
|
if (logic.controllers[index] != null)
|
||||||
builder: (c) {
|
CustomVideoProgressBar(
|
||||||
return GestureDetector(
|
controller: logic.controllers[index]!,
|
||||||
onTap: () => logic.likeVideo(),
|
width: ScreenUtil().screenWidth,
|
||||||
child: Column(
|
),
|
||||||
|
SizedBox(height: 16.w),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: showEpSelDialog,
|
||||||
|
child: Container(
|
||||||
|
width: 300.w,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 12.w,
|
||||||
|
vertical: 9.w,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(50.w),
|
||||||
|
color: Colors.white.withValues(alpha: .1),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
Image.asset('ic_ep.png'.ktIcon, width: 16.sp),
|
||||||
state.video?.shortPlayInfo?.isCollect == true
|
SizedBox(width: 6.w),
|
||||||
? 'ic_collect_sel.png'.ktIcon
|
Text(
|
||||||
: 'ic_collect_unsel.png'.ktIcon,
|
'EP.${index + 1}',
|
||||||
width: 32.w,
|
style: TextStyle(
|
||||||
|
fontSize: 13.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
'All ${state.video?.shortPlayInfo?.episodeTotal ?? 0} Episodes',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
),
|
GetBuilder<VideoPlayLogic>(
|
||||||
],
|
id: 'video-like',
|
||||||
),
|
builder: (c) {
|
||||||
],
|
return GestureDetector(
|
||||||
|
onTap: () => logic.likeVideo(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
state.video?.shortPlayInfo?.isCollect == true
|
||||||
|
? 'ic_collect_sel.png'.ktIcon
|
||||||
|
: 'ic_collect_unsel.png'.ktIcon,
|
||||||
|
width: 32.w,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 1.0.1+1
|
version: 1.0.1+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.8.1
|
sdk: ^3.8.0
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
|||||||