mod: 排名
This commit is contained in:
@ -51,6 +51,7 @@ android {
|
|||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
minSdkVersion 17
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
BIN
assets/fonts/fansCard.ttf
Normal file
BIN
assets/fonts/fansCard.ttf
Normal file
Binary file not shown.
@ -30,8 +30,11 @@ class NetworkImgLayer extends StatelessWidget {
|
|||||||
// double pr = 2;
|
// double pr = 2;
|
||||||
return src != ''
|
return src != ''
|
||||||
? ClipRRect(
|
? ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(
|
borderRadius: BorderRadius.circular(type == 'avatar'
|
||||||
type == 'avatar' ? 50 : StyleString.imgRadius.x),
|
? 50
|
||||||
|
: type == 'emote'
|
||||||
|
? 0
|
||||||
|
: StyleString.imgRadius.x),
|
||||||
child: CachedNetworkImage(
|
child: CachedNetworkImage(
|
||||||
imageUrl: src!,
|
imageUrl: src!,
|
||||||
width: width ?? double.infinity,
|
width: width ?? double.infinity,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import 'dart:convert' as convert;
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
class ReplyMember {
|
class ReplyMember {
|
||||||
ReplyMember({
|
ReplyMember({
|
||||||
@ -22,6 +22,7 @@ class ReplyMember {
|
|||||||
Map? officialVerify;
|
Map? officialVerify;
|
||||||
Map? vip;
|
Map? vip;
|
||||||
Map? fansDetail;
|
Map? fansDetail;
|
||||||
|
UserSailing? userSailing;
|
||||||
|
|
||||||
ReplyMember.fromJson(Map<String, dynamic> json) {
|
ReplyMember.fromJson(Map<String, dynamic> json) {
|
||||||
mid = json['mid'];
|
mid = json['mid'];
|
||||||
@ -30,9 +31,12 @@ class ReplyMember {
|
|||||||
avatar = json['avatar'];
|
avatar = json['avatar'];
|
||||||
level = json['level_info']['current_level'];
|
level = json['level_info']['current_level'];
|
||||||
pendant = Pendant.fromJson(json['pendant']);
|
pendant = Pendant.fromJson(json['pendant']);
|
||||||
officialVerify = json['officia_vVerify'];
|
officialVerify = json['officia_verify'];
|
||||||
vip = json['vip'];
|
vip = json['vip'];
|
||||||
fansDetail = json['fans_detail'];
|
fansDetail = json['fans_detail'];
|
||||||
|
userSailing = json['user_sailing'] != null
|
||||||
|
? UserSailing.fromJson(json['user_sailing'])
|
||||||
|
: UserSailing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,3 +57,15 @@ class Pendant {
|
|||||||
image = json['image'];
|
image = json['image'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UserSailing {
|
||||||
|
UserSailing({this.pendant, this.cardbg});
|
||||||
|
|
||||||
|
Map? pendant;
|
||||||
|
Map? cardbg;
|
||||||
|
|
||||||
|
UserSailing.fromJson(Map<String, dynamic> json) {
|
||||||
|
pendant = json['pendant'];
|
||||||
|
cardbg = json['cardbg'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ class VideoReplyController extends GetxController {
|
|||||||
// 当前页
|
// 当前页
|
||||||
int currentPage = 0;
|
int currentPage = 0;
|
||||||
bool isLoadingMore = false;
|
bool isLoadingMore = false;
|
||||||
bool noMore = false;
|
RxBool noMore = false.obs;
|
||||||
|
|
||||||
Future queryReplyList({type = 'init'}) async {
|
Future queryReplyList({type = 'init'}) async {
|
||||||
isLoadingMore = true;
|
isLoadingMore = true;
|
||||||
@ -36,14 +36,17 @@ class VideoReplyController extends GetxController {
|
|||||||
res['data'] = ReplyData.fromJson(res['data']);
|
res['data'] = ReplyData.fromJson(res['data']);
|
||||||
if (res['data'].replies.isNotEmpty) {
|
if (res['data'].replies.isNotEmpty) {
|
||||||
currentPage = currentPage + 1;
|
currentPage = currentPage + 1;
|
||||||
noMore = false;
|
noMore.value = false;
|
||||||
} else {
|
} else {
|
||||||
if (currentPage == 0) {
|
if (currentPage == 0) {
|
||||||
} else {
|
} else {
|
||||||
noMore = true;
|
noMore.value = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (res['data'].replies.length >= res['data'].page.count) {
|
||||||
|
noMore.value = true;
|
||||||
|
}
|
||||||
if (type == 'init') {
|
if (type == 'init') {
|
||||||
List<ReplyItemModel> replies = res['data'].replies;
|
List<ReplyItemModel> replies = res['data'].replies;
|
||||||
// 添加置顶回复
|
// 添加置顶回复
|
||||||
|
|||||||
@ -90,9 +90,10 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
|||||||
height:
|
height:
|
||||||
MediaQuery.of(context).padding.bottom + 60,
|
MediaQuery.of(context).padding.bottom + 60,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(_videoReplyController.noMore
|
child: Obx(() => Text(
|
||||||
? '没有更多了'
|
_videoReplyController.noMore.value
|
||||||
: '加载中'),
|
? '没有更多了'
|
||||||
|
: '加载中')),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -33,14 +33,42 @@ class ReplyItem extends StatelessWidget {
|
|||||||
|
|
||||||
Widget lfAvtar(context) {
|
Widget lfAvtar(context) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(top: 5),
|
margin: const EdgeInsets.only(top: 5),
|
||||||
child: NetworkImgLayer(
|
child: Stack(
|
||||||
src: replyItem!.member!.avatar,
|
children: [
|
||||||
width: 30,
|
NetworkImgLayer(
|
||||||
height: 30,
|
src: replyItem!.member!.avatar,
|
||||||
type: 'avatar',
|
width: 34,
|
||||||
),
|
height: 34,
|
||||||
);
|
type: 'avatar',
|
||||||
|
),
|
||||||
|
if (replyItem!.member!.officialVerify != null &&
|
||||||
|
replyItem!.member!.officialVerify!['type'] == 0)
|
||||||
|
Positioned(
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(7),
|
||||||
|
color: Theme.of(context).colorScheme.background,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.offline_bolt,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
// child:
|
||||||
|
// NetworkImgLayer(
|
||||||
|
// src: replyItem!.member!.avatar,
|
||||||
|
// width: 30,
|
||||||
|
// height: 30,
|
||||||
|
// type: 'avatar',
|
||||||
|
// ),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget content(context) {
|
Widget content(context) {
|
||||||
@ -54,39 +82,73 @@ class ReplyItem extends StatelessWidget {
|
|||||||
// 'memberAvatar': reply.avatar,
|
// 'memberAvatar': reply.avatar,
|
||||||
// 'heroTag': reply.userName + heroTag,
|
// 'heroTag': reply.userName + heroTag,
|
||||||
// }),
|
// }),
|
||||||
child: Row(
|
child: Container(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
width: double.infinity,
|
||||||
mainAxisSize: MainAxisSize.min,
|
decoration: BoxDecoration(
|
||||||
children: <Widget>[
|
image: replyItem!.member!.userSailing!.cardbg != null
|
||||||
lfAvtar(context),
|
? DecorationImage(
|
||||||
const SizedBox(width: 12),
|
fit: BoxFit.cover,
|
||||||
Column(
|
image: NetworkImage(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
replyItem!.member!.userSailing!.cardbg!['image'],
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
replyItem!.member!.uname!,
|
|
||||||
style: TextStyle(
|
|
||||||
color: replyItem!.isUp!
|
|
||||||
? Theme.of(context).colorScheme.primary
|
|
||||||
: Theme.of(context).colorScheme.outline,
|
|
||||||
fontSize:
|
|
||||||
Theme.of(context).textTheme.titleSmall!.fontSize,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
)
|
||||||
Image.asset(
|
: null,
|
||||||
'assets/images/lv/lv${replyItem!.member!.level}.png',
|
),
|
||||||
height: 11,
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
lfAvtar(context),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Text(
|
||||||
|
replyItem!.member!.uname!,
|
||||||
|
style: TextStyle(
|
||||||
|
color: replyItem!.isUp! ||
|
||||||
|
replyItem!.member!.vip!['vipType'] > 0
|
||||||
|
? Theme.of(context).colorScheme.primary
|
||||||
|
: Theme.of(context).colorScheme.outline,
|
||||||
|
fontSize:
|
||||||
|
Theme.of(context).textTheme.titleSmall!.fontSize,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
),
|
||||||
if (replyItem!.isUp!) UpTag()
|
const SizedBox(width: 6),
|
||||||
],
|
Image.asset(
|
||||||
|
'assets/images/lv/lv${replyItem!.member!.level}.png',
|
||||||
|
height: 11,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
if (replyItem!.isUp!) UpTag(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (replyItem!.member!.userSailing!.cardbg != null &&
|
||||||
|
replyItem!.member!.userSailing!.cardbg!['fan']['number'] >
|
||||||
|
0)
|
||||||
|
Positioned(
|
||||||
|
top: 8,
|
||||||
|
left: Get.size.width / 7 * 5.6,
|
||||||
|
child: DefaultTextStyle(
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'fansCard',
|
||||||
|
fontSize: 9,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Text('NO.'),
|
||||||
|
Text(
|
||||||
|
replyItem!.member!.userSailing!.cardbg!['fan']
|
||||||
|
['num_desc'],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// title
|
// title
|
||||||
@ -329,14 +391,16 @@ InlineSpan buildContent(BuildContext context, content) {
|
|||||||
RegExp(r"\[.*?\]"),
|
RegExp(r"\[.*?\]"),
|
||||||
onMatch: (Match match) {
|
onMatch: (Match match) {
|
||||||
String matchStr = match[0]!;
|
String matchStr = match[0]!;
|
||||||
|
int size = content.emote[matchStr]['meta']['size'];
|
||||||
if (content.emote.isNotEmpty) {
|
if (content.emote.isNotEmpty) {
|
||||||
if (content.emote.keys.contains(matchStr)) {
|
if (content.emote.keys.contains(matchStr)) {
|
||||||
spanChilds.add(
|
spanChilds.add(
|
||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
child: NetworkImgLayer(
|
child: NetworkImgLayer(
|
||||||
src: content.emote[matchStr]['url'],
|
src: content.emote[matchStr]['url'],
|
||||||
width: 20,
|
type: 'emote',
|
||||||
height: 20,
|
width: size * 20,
|
||||||
|
height: size * 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
18
pubspec.yaml
18
pubspec.yaml
@ -102,17 +102,11 @@ flutter:
|
|||||||
# "family" key with the font family name, and a "fonts" key with a
|
# "family" key with the font family name, and a "fonts" key with a
|
||||||
# list giving the asset and other descriptors for the font. For
|
# list giving the asset and other descriptors for the font. For
|
||||||
# example:
|
# example:
|
||||||
# fonts:
|
fonts:
|
||||||
# - family: Schyler
|
- family: fansCard
|
||||||
# fonts:
|
fonts:
|
||||||
# - asset: fonts/Schyler-Regular.ttf
|
- asset: assets/fonts/fansCard.ttf
|
||||||
# - asset: fonts/Schyler-Italic.ttf
|
|
||||||
# style: italic
|
|
||||||
# - family: Trajan Pro
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/TrajanPro.ttf
|
|
||||||
# - asset: fonts/TrajanPro_Bold.ttf
|
|
||||||
# weight: 700
|
|
||||||
#
|
|
||||||
# For details regarding fonts from package dependencies,
|
# For details regarding fonts from package dependencies,
|
||||||
# see https://flutter.dev/custom-fonts/#from-packages
|
# see https://flutter.dev/custom-fonts/#from-packages
|
||||||
|
|||||||
Reference in New Issue
Block a user