mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-17 23:56:13 +08:00
dyn addcard
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -77,11 +77,6 @@ class Fallback {
|
|||||||
id: json['id'],
|
id: json['id'],
|
||||||
type: json['type'],
|
type: json['type'],
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'id': id,
|
|
||||||
'type': type,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单个动态详情
|
// 单个动态详情
|
||||||
@@ -241,12 +236,32 @@ class Button {
|
|||||||
String? icon;
|
String? icon;
|
||||||
String? jumpUrl;
|
String? jumpUrl;
|
||||||
String? text;
|
String? text;
|
||||||
|
JumpStyle? jumpStyle;
|
||||||
|
int? status;
|
||||||
|
int? type;
|
||||||
|
Check? check;
|
||||||
|
|
||||||
Button.fromJson(Map<String, dynamic> json) {
|
Button.fromJson(Map<String, dynamic> json) {
|
||||||
handleType = json['handle_type'];
|
handleType = json['handle_type'];
|
||||||
icon = json['icon'];
|
icon = json['icon'];
|
||||||
jumpUrl = json['jump_url'];
|
jumpUrl = json['jump_url'];
|
||||||
text = json['text'];
|
text = json['text'];
|
||||||
|
jumpStyle = json['jump_style'] == null
|
||||||
|
? null
|
||||||
|
: JumpStyle.fromJson(json['jump_style']);
|
||||||
|
status = json['status'];
|
||||||
|
type = json['type'];
|
||||||
|
check = json['check'] == null ? null : Check.fromJson(json['check']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Check {
|
||||||
|
int? disable;
|
||||||
|
String? text;
|
||||||
|
|
||||||
|
Check.fromJson(Map<String, dynamic> json) {
|
||||||
|
disable = json['disable'];
|
||||||
|
text = json['text'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,12 +372,9 @@ class DynamicAddModel {
|
|||||||
Ugc? ugc;
|
Ugc? ugc;
|
||||||
Reserve? reserve;
|
Reserve? reserve;
|
||||||
Good? goods;
|
Good? goods;
|
||||||
|
UpowerLottery? upowerLottery;
|
||||||
/// TODO 比赛vs
|
AddCommon? common;
|
||||||
String? match;
|
AddMatch? match;
|
||||||
|
|
||||||
/// TODO 游戏信息
|
|
||||||
String? common;
|
|
||||||
|
|
||||||
DynamicAddModel.fromJson(Map<String, dynamic> json) {
|
DynamicAddModel.fromJson(Map<String, dynamic> json) {
|
||||||
type = json['type'];
|
type = json['type'];
|
||||||
@@ -371,9 +383,200 @@ class DynamicAddModel {
|
|||||||
reserve =
|
reserve =
|
||||||
json['reserve'] != null ? Reserve.fromJson(json['reserve']) : null;
|
json['reserve'] != null ? Reserve.fromJson(json['reserve']) : null;
|
||||||
goods = json['goods'] != null ? Good.fromJson(json['goods']) : null;
|
goods = json['goods'] != null ? Good.fromJson(json['goods']) : null;
|
||||||
|
upowerLottery = json['upower_lottery'] != null
|
||||||
|
? UpowerLottery.fromJson(json['upower_lottery'])
|
||||||
|
: null;
|
||||||
|
common = json['common'] != null ? AddCommon.fromJson(json['common']) : null;
|
||||||
|
match = json['match'] != null ? AddMatch.fromJson(json['match']) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AddMatch {
|
||||||
|
Button? button;
|
||||||
|
String? headText;
|
||||||
|
String? idStr;
|
||||||
|
String? jumpUrl;
|
||||||
|
MatchInfo? matchInfo;
|
||||||
|
|
||||||
|
AddMatch({
|
||||||
|
this.button,
|
||||||
|
this.headText,
|
||||||
|
this.idStr,
|
||||||
|
this.jumpUrl,
|
||||||
|
this.matchInfo,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory AddMatch.fromJson(Map<String, dynamic> json) => AddMatch(
|
||||||
|
button: json["button"] == null ? null : Button.fromJson(json["button"]),
|
||||||
|
headText: json["head_text"],
|
||||||
|
idStr: json["id_str"],
|
||||||
|
jumpUrl: json["jump_url"],
|
||||||
|
matchInfo: json["match_info"] == null
|
||||||
|
? null
|
||||||
|
: MatchInfo.fromJson(json["match_info"]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MatchInfo {
|
||||||
|
String? centerBottom;
|
||||||
|
List? centerTop;
|
||||||
|
TTeam? leftTeam;
|
||||||
|
TTeam? rightTeam;
|
||||||
|
int? status;
|
||||||
|
dynamic subTitle;
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
MatchInfo({
|
||||||
|
this.centerBottom,
|
||||||
|
this.centerTop,
|
||||||
|
this.leftTeam,
|
||||||
|
this.rightTeam,
|
||||||
|
this.status,
|
||||||
|
this.subTitle,
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory MatchInfo.fromJson(Map<String, dynamic> json) => MatchInfo(
|
||||||
|
centerBottom: json["center_bottom"],
|
||||||
|
centerTop: json["center_top"],
|
||||||
|
leftTeam: json["left_team"] == null
|
||||||
|
? null
|
||||||
|
: TTeam.fromJson(json["left_team"]),
|
||||||
|
rightTeam: json["right_team"] == null
|
||||||
|
? null
|
||||||
|
: TTeam.fromJson(json["right_team"]),
|
||||||
|
status: json["status"],
|
||||||
|
subTitle: json["sub_title"],
|
||||||
|
title: json["title"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TTeam {
|
||||||
|
int? id;
|
||||||
|
String? name;
|
||||||
|
String? pic;
|
||||||
|
|
||||||
|
TTeam({
|
||||||
|
this.id,
|
||||||
|
this.name,
|
||||||
|
this.pic,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TTeam.fromJson(Map<String, dynamic> json) => TTeam(
|
||||||
|
id: json["id"],
|
||||||
|
name: json["name"],
|
||||||
|
pic: json["pic"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddCommon {
|
||||||
|
Button? button;
|
||||||
|
String? cover;
|
||||||
|
String? desc1;
|
||||||
|
String? desc2;
|
||||||
|
String? headText;
|
||||||
|
String? idStr;
|
||||||
|
String? jumpUrl;
|
||||||
|
int? style;
|
||||||
|
String? subType;
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
AddCommon({
|
||||||
|
this.button,
|
||||||
|
this.cover,
|
||||||
|
this.desc1,
|
||||||
|
this.desc2,
|
||||||
|
this.headText,
|
||||||
|
this.idStr,
|
||||||
|
this.jumpUrl,
|
||||||
|
this.style,
|
||||||
|
this.subType,
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory AddCommon.fromJson(Map<String, dynamic> json) => AddCommon(
|
||||||
|
button: json["button"] == null ? null : Button.fromJson(json["button"]),
|
||||||
|
cover: json["cover"],
|
||||||
|
desc1: json["desc1"],
|
||||||
|
desc2: json["desc2"],
|
||||||
|
headText: json["head_text"],
|
||||||
|
idStr: json["id_str"],
|
||||||
|
jumpUrl: json["jump_url"],
|
||||||
|
style: json["style"],
|
||||||
|
subType: json["sub_type"],
|
||||||
|
title: json["title"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpowerLottery {
|
||||||
|
Button? button;
|
||||||
|
Desc? desc;
|
||||||
|
Hint? hint;
|
||||||
|
String? jumpUrl;
|
||||||
|
int? rid;
|
||||||
|
int? state;
|
||||||
|
String? title;
|
||||||
|
int? upMid;
|
||||||
|
int? upowerActionState;
|
||||||
|
int? upowerLevel;
|
||||||
|
|
||||||
|
UpowerLottery({
|
||||||
|
this.button,
|
||||||
|
this.desc,
|
||||||
|
this.hint,
|
||||||
|
this.jumpUrl,
|
||||||
|
this.rid,
|
||||||
|
this.state,
|
||||||
|
this.title,
|
||||||
|
this.upMid,
|
||||||
|
this.upowerActionState,
|
||||||
|
this.upowerLevel,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UpowerLottery.fromJson(Map<String, dynamic> json) => UpowerLottery(
|
||||||
|
button: json["button"] == null ? null : Button.fromJson(json["button"]),
|
||||||
|
desc: json["desc"] == null ? null : Desc.fromJson(json["desc"]),
|
||||||
|
hint: json["hint"] == null ? null : Hint.fromJson(json["hint"]),
|
||||||
|
jumpUrl: json["jump_url"],
|
||||||
|
rid: json["rid"],
|
||||||
|
state: json["state"],
|
||||||
|
title: json["title"],
|
||||||
|
upMid: json["up_mid"],
|
||||||
|
upowerActionState: json["upower_action_state"],
|
||||||
|
upowerLevel: json["upower_level"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Hint {
|
||||||
|
int? style;
|
||||||
|
String? text;
|
||||||
|
|
||||||
|
Hint({
|
||||||
|
this.style,
|
||||||
|
this.text,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Hint.fromJson(Map<String, dynamic> json) => Hint(
|
||||||
|
style: json["style"],
|
||||||
|
text: json["text"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class JumpStyle {
|
||||||
|
String? iconUrl;
|
||||||
|
String? text;
|
||||||
|
|
||||||
|
JumpStyle({
|
||||||
|
this.iconUrl,
|
||||||
|
this.text,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory JumpStyle.fromJson(Map<String, dynamic> json) => JumpStyle(
|
||||||
|
iconUrl: json["icon_url"],
|
||||||
|
text: json["text"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class Vote {
|
class Vote {
|
||||||
Vote({
|
Vote({
|
||||||
this.choiceCnt,
|
this.choiceCnt,
|
||||||
@@ -452,6 +655,7 @@ class Reserve {
|
|||||||
this.button,
|
this.button,
|
||||||
this.desc1,
|
this.desc1,
|
||||||
this.desc2,
|
this.desc2,
|
||||||
|
this.desc3,
|
||||||
this.jumpUrl,
|
this.jumpUrl,
|
||||||
this.reserveTotal,
|
this.reserveTotal,
|
||||||
this.rid,
|
this.rid,
|
||||||
@@ -464,6 +668,7 @@ class Reserve {
|
|||||||
ReserveBtn? button;
|
ReserveBtn? button;
|
||||||
Desc? desc1;
|
Desc? desc1;
|
||||||
Desc? desc2;
|
Desc? desc2;
|
||||||
|
Desc? desc3;
|
||||||
String? jumpUrl;
|
String? jumpUrl;
|
||||||
int? reserveTotal;
|
int? reserveTotal;
|
||||||
int? rid;
|
int? rid;
|
||||||
@@ -477,6 +682,7 @@ class Reserve {
|
|||||||
json['button'] == null ? null : ReserveBtn.fromJson(json['button']);
|
json['button'] == null ? null : ReserveBtn.fromJson(json['button']);
|
||||||
desc1 = json['desc1'] == null ? null : Desc.fromJson(json['desc1']);
|
desc1 = json['desc1'] == null ? null : Desc.fromJson(json['desc1']);
|
||||||
desc2 = json['desc2'] == null ? null : Desc.fromJson(json['desc2']);
|
desc2 = json['desc2'] == null ? null : Desc.fromJson(json['desc2']);
|
||||||
|
desc3 = json['desc3'] == null ? null : Desc.fromJson(json['desc3']);
|
||||||
jumpUrl = json['jump_url'];
|
jumpUrl = json['jump_url'];
|
||||||
reserveTotal = json['reserve_total'];
|
reserveTotal = json['reserve_total'];
|
||||||
rid = json['rid'];
|
rid = json['rid'];
|
||||||
@@ -520,16 +726,19 @@ class Desc {
|
|||||||
this.style,
|
this.style,
|
||||||
this.text,
|
this.text,
|
||||||
this.visible,
|
this.visible,
|
||||||
|
this.jumpUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
int? style;
|
int? style;
|
||||||
String? text;
|
String? text;
|
||||||
bool? visible;
|
bool? visible;
|
||||||
|
String? jumpUrl;
|
||||||
|
|
||||||
Desc.fromJson(Map<String, dynamic> json) {
|
Desc.fromJson(Map<String, dynamic> json) {
|
||||||
style = json['style'];
|
style = json['style'];
|
||||||
text = json['text'];
|
text = json['text'];
|
||||||
visible = json['visible'];
|
visible = json['visible'];
|
||||||
|
jumpUrl = json["jump_url"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import 'package:PiliPlus/models/dynamics/result.dart';
|
|||||||
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
|
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
|
||||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
Widget addWidget(
|
Widget addWidget(
|
||||||
ThemeData theme, DynamicItemModel item, BuildContext context, type,
|
ThemeData theme, DynamicItemModel item, BuildContext context, type,
|
||||||
@@ -102,22 +104,60 @@ Widget addWidget(
|
|||||||
TextSpan(
|
TextSpan(
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: theme.colorScheme.outline,
|
color: theme.colorScheme.outline,
|
||||||
fontSize: theme
|
fontSize: 13,
|
||||||
.textTheme.labelMedium!.fontSize,
|
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
if (reserve.desc1 != null)
|
if (reserve.desc1?.text?.isNotEmpty ==
|
||||||
|
true)
|
||||||
TextSpan(text: reserve.desc1!.text),
|
TextSpan(text: reserve.desc1!.text),
|
||||||
const TextSpan(text: ' '),
|
if (reserve.desc2?.text?.isNotEmpty ==
|
||||||
if (reserve.desc2 != null)
|
true)
|
||||||
TextSpan(text: reserve.desc2!.text),
|
TextSpan(
|
||||||
|
text:
|
||||||
|
' ${reserve.desc2!.text}'),
|
||||||
|
if (reserve.desc3?.text?.isNotEmpty ==
|
||||||
|
true) ...[
|
||||||
|
const TextSpan(text: '\n'),
|
||||||
|
WidgetSpan(
|
||||||
|
alignment:
|
||||||
|
PlaceholderAlignment.middle,
|
||||||
|
child: Icon(
|
||||||
|
size: 17,
|
||||||
|
Icons.card_giftcard,
|
||||||
|
color:
|
||||||
|
theme.colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: ' ${reserve.desc3!.text}',
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
theme.colorScheme.primary,
|
||||||
|
),
|
||||||
|
recognizer:
|
||||||
|
reserve.desc3!.jumpUrl == null
|
||||||
|
? null
|
||||||
|
: (TapGestureRecognizer()
|
||||||
|
..onTap = () {
|
||||||
|
Get.toNamed(
|
||||||
|
'/webview',
|
||||||
|
parameters: {
|
||||||
|
'url': reserve
|
||||||
|
.desc3!
|
||||||
|
.jumpUrl!
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (reserve.button != null)
|
if (reserve.button != null) ...[
|
||||||
|
const SizedBox(width: 10),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final btn = reserve.button!;
|
final btn = reserve.button!;
|
||||||
@@ -188,6 +228,7 @@ Widget addWidget(
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -195,6 +236,104 @@ Widget addWidget(
|
|||||||
)
|
)
|
||||||
: const SizedBox.shrink()
|
: const SizedBox.shrink()
|
||||||
: const SizedBox.shrink();
|
: const SizedBox.shrink();
|
||||||
|
case 'ADDITIONAL_TYPE_UPOWER_LOTTERY':
|
||||||
|
final content = item.modules.moduleDynamic!.additional!.upowerLottery!;
|
||||||
|
final borderRadius = floor == 1 ? null : StyleString.mdRadius;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 6),
|
||||||
|
child: Material(
|
||||||
|
color: bgColor,
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
onTap: content.jumpUrl == null
|
||||||
|
? null
|
||||||
|
: () => PiliScheme.routePushFromUrl(content.jumpUrl!),
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
spacing: 2,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (content.title?.isNotEmpty == true)
|
||||||
|
Text(content.title!),
|
||||||
|
if (content.hint?.text?.isNotEmpty == true)
|
||||||
|
Text(
|
||||||
|
content.hint!.text!,
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
fontSize: 13,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (content.desc?.text?.isNotEmpty == true)
|
||||||
|
Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
WidgetSpan(
|
||||||
|
alignment: PlaceholderAlignment.middle,
|
||||||
|
child: Icon(
|
||||||
|
size: 17,
|
||||||
|
Icons.card_giftcard,
|
||||||
|
color: theme.colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: ' ${content.desc!.text!}',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.colorScheme.primary,
|
||||||
|
fontSize: 13,
|
||||||
|
),
|
||||||
|
recognizer: content.desc!.jumpUrl == null
|
||||||
|
? null
|
||||||
|
: (TapGestureRecognizer()
|
||||||
|
..onTap = () {
|
||||||
|
Get.toNamed(
|
||||||
|
'/webview',
|
||||||
|
parameters: {
|
||||||
|
'url': content.desc!.jumpUrl!
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (content.button != null) ...[
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
FilledButton.tonal(
|
||||||
|
onPressed: content.button!.jumpUrl == null
|
||||||
|
? null
|
||||||
|
: () => PiliScheme.routePushFromUrl(
|
||||||
|
content.button!.jumpUrl!,
|
||||||
|
),
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6)),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
visualDensity:
|
||||||
|
const VisualDensity(horizontal: -2, vertical: -3),
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
),
|
||||||
|
child: Text(content.button!.jumpStyle?.text ??
|
||||||
|
content.button!.check?.text ??
|
||||||
|
''),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
// 商品
|
// 商品
|
||||||
case 'ADDITIONAL_TYPE_GOODS':
|
case 'ADDITIONAL_TYPE_GOODS':
|
||||||
final content = item.modules.moduleDynamic!.additional!.goods!;
|
final content = item.modules.moduleDynamic!.additional!.goods!;
|
||||||
@@ -283,12 +422,6 @@ Widget addWidget(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
// case 'ADDITIONAL_TYPE_MATCH':
|
|
||||||
// final content = item.modules.moduleDynamic!.additional!.match;
|
|
||||||
// return const SizedBox.shrink();
|
|
||||||
// case 'ADDITIONAL_TYPE_COMMON':
|
|
||||||
// final content = item.modules.moduleDynamic!.additional!.common;
|
|
||||||
// return const SizedBox.shrink();
|
|
||||||
case 'ADDITIONAL_TYPE_VOTE':
|
case 'ADDITIONAL_TYPE_VOTE':
|
||||||
final vote = item.modules.moduleDynamic!.additional!.vote!;
|
final vote = item.modules.moduleDynamic!.additional!.vote!;
|
||||||
final borderRadius = floor == 1 ? null : StyleString.mdRadius;
|
final borderRadius = floor == 1 ? null : StyleString.mdRadius;
|
||||||
@@ -376,6 +509,204 @@ Widget addWidget(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case 'ADDITIONAL_TYPE_COMMON':
|
||||||
|
final content = item.modules.moduleDynamic!.additional!.common!;
|
||||||
|
final borderRadius = floor == 1 ? null : StyleString.mdRadius;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 6),
|
||||||
|
child: Material(
|
||||||
|
color: bgColor,
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
onTap: content.jumpUrl == null
|
||||||
|
? null
|
||||||
|
: () => PiliScheme.routePushFromUrl(content.jumpUrl!),
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
if (content.cover?.isNotEmpty == true) ...[
|
||||||
|
NetworkImgLayer(
|
||||||
|
width: 45,
|
||||||
|
height: 45,
|
||||||
|
src: content.cover,
|
||||||
|
radius: 6,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
],
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
spacing: 2,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (content.title?.isNotEmpty == true)
|
||||||
|
Text(content.title!),
|
||||||
|
if (content.desc1?.isNotEmpty == true)
|
||||||
|
Text(
|
||||||
|
content.desc1!,
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
fontSize: 13,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (content.desc2?.isNotEmpty == true)
|
||||||
|
Text(
|
||||||
|
content.desc2!,
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
fontSize: 13,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (content.button?.jumpUrl?.isNotEmpty == true) ...[
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
FilledButton.tonal(
|
||||||
|
onPressed: () => PiliScheme.routePushFromUrl(
|
||||||
|
content.button!.jumpUrl!,
|
||||||
|
),
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6)),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
visualDensity:
|
||||||
|
const VisualDensity(horizontal: -2, vertical: -3),
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
),
|
||||||
|
child: Text(content.button!.jumpStyle?.text ?? ''),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case 'ADDITIONAL_TYPE_MATCH':
|
||||||
|
final content = item.modules.moduleDynamic!.additional!.match!;
|
||||||
|
final borderRadius = floor == 1 ? null : StyleString.mdRadius;
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 6),
|
||||||
|
child: Material(
|
||||||
|
color: bgColor,
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
onTap: content.jumpUrl == null
|
||||||
|
? null
|
||||||
|
: () => PiliScheme.routePushFromUrl(content.jumpUrl!),
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (content.matchInfo?.title?.isNotEmpty == true)
|
||||||
|
Text(
|
||||||
|
content.matchInfo!.title!,
|
||||||
|
style: const TextStyle(fontSize: 13),
|
||||||
|
),
|
||||||
|
if (content.matchInfo?.subTitle?.isNotEmpty == true)
|
||||||
|
Text(
|
||||||
|
content.matchInfo!.subTitle!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
if (content.matchInfo?.leftTeam != null) ...[
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
NetworkImgLayer(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
src: content.matchInfo!.leftTeam!.pic,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
content.matchInfo!.leftTeam!.name!,
|
||||||
|
style: const TextStyle(fontSize: 13),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
],
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
if (content.matchInfo?.centerTop?.isNotEmpty == true)
|
||||||
|
Container(
|
||||||
|
height: 35,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
content.matchInfo!.centerTop!.join(' '),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (content.matchInfo?.centerBottom?.isNotEmpty == true)
|
||||||
|
Text(
|
||||||
|
content.matchInfo!.centerBottom!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (content.matchInfo?.rightTeam != null) ...[
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
NetworkImgLayer(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
src: content.matchInfo!.rightTeam!.pic,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
content.matchInfo!.rightTeam!.name!,
|
||||||
|
style: const TextStyle(fontSize: 13),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const Spacer(),
|
||||||
|
if (content.button != null)
|
||||||
|
FilledButton.tonal(
|
||||||
|
onPressed: () => PiliScheme.routePushFromUrl(
|
||||||
|
content.button!.jumpUrl!,
|
||||||
|
),
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(6)),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
visualDensity:
|
||||||
|
const VisualDensity(horizontal: -2, vertical: -3),
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
),
|
||||||
|
child: Text(content.button!.jumpStyle?.text ?? ''),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
if (BuildConfig.isDebug) {
|
if (BuildConfig.isDebug) {
|
||||||
return Padding(
|
return Padding(
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ Widget content(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (richNodes != null)
|
if (richNodes != null)
|
||||||
source == 'detail'
|
source == 'detail' && floor == 1
|
||||||
? SelectableText.rich(
|
? SelectableText.rich(
|
||||||
richNodes,
|
richNodes,
|
||||||
style: isSave
|
style: isSave
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/badge.dart';
|
|||||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||||
import 'package:PiliPlus/models/common/badge_type.dart';
|
import 'package:PiliPlus/models/common/badge_type.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||||
|
import 'package:PiliPlus/pages/dynamics/widgets/additional_panel.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics/widgets/content_panel.dart';
|
import 'package:PiliPlus/pages/dynamics/widgets/content_panel.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics/widgets/rich_node_panel.dart';
|
import 'package:PiliPlus/pages/dynamics/widgets/rich_node_panel.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
@@ -201,6 +202,14 @@ Widget videoSeasonWidget(
|
|||||||
overflow: source == 'detail' ? null : TextOverflow.ellipsis,
|
overflow: source == 'detail' ? null : TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (item.modules.moduleDynamic?.additional != null)
|
||||||
|
addWidget(
|
||||||
|
theme,
|
||||||
|
item,
|
||||||
|
context,
|
||||||
|
item.modules.moduleDynamic?.additional?.type,
|
||||||
|
floor: floor,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ class _HotPageState extends CommonPageState<HotPage, HotController>
|
|||||||
'url':
|
'url':
|
||||||
'https://www.bilibili.com/h5/weekly-recommend'
|
'https://www.bilibili.com/h5/weekly-recommend'
|
||||||
},
|
},
|
||||||
arguments: {'off': false},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_buildEntranceItem(
|
_buildEntranceItem(
|
||||||
@@ -122,7 +121,6 @@ class _HotPageState extends CommonPageState<HotPage, HotController>
|
|||||||
'url':
|
'url':
|
||||||
'https://www.bilibili.com/h5/good-history'
|
'https://www.bilibili.com/h5/good-history'
|
||||||
},
|
},
|
||||||
arguments: {'off': false},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class _WebviewPageState extends State<WebviewPage> {
|
|||||||
final RxString title = ''.obs;
|
final RxString title = ''.obs;
|
||||||
final RxDouble progress = 1.0.obs;
|
final RxDouble progress = 1.0.obs;
|
||||||
bool? _inApp;
|
bool? _inApp;
|
||||||
bool? _off;
|
bool _off = false;
|
||||||
|
|
||||||
InAppWebViewController? _webViewController;
|
InAppWebViewController? _webViewController;
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ class _WebviewPageState extends State<WebviewPage> {
|
|||||||
bool hasMatch = await PiliScheme.routePush(
|
bool hasMatch = await PiliScheme.routePush(
|
||||||
navigationAction.request.url?.uriValue ?? Uri(),
|
navigationAction.request.url?.uriValue ?? Uri(),
|
||||||
selfHandle: true,
|
selfHandle: true,
|
||||||
off: _off ?? true,
|
off: _off,
|
||||||
);
|
);
|
||||||
// debugPrint('webview: [$url], [$hasMatch]');
|
// debugPrint('webview: [$url], [$hasMatch]');
|
||||||
if (hasMatch) {
|
if (hasMatch) {
|
||||||
|
|||||||
@@ -108,13 +108,15 @@ class PiliScheme {
|
|||||||
// to video reply
|
// to video reply
|
||||||
String? oid = uriDigitRegExp.firstMatch(path)?.group(1);
|
String? oid = uriDigitRegExp.firstMatch(path)?.group(1);
|
||||||
int? rpid = int.tryParse(queryParameters['comment_root_id']!);
|
int? rpid = int.tryParse(queryParameters['comment_root_id']!);
|
||||||
|
String? commentSecondaryId =
|
||||||
|
queryParameters['comment_secondary_id'];
|
||||||
if (oid != null && rpid != null) {
|
if (oid != null && rpid != null) {
|
||||||
Get.to(
|
Get.to(
|
||||||
arguments: {
|
arguments: {
|
||||||
'oid': oid,
|
'oid': oid,
|
||||||
'rpid': rpid,
|
'rpid': rpid,
|
||||||
'type': 1,
|
'type': 1,
|
||||||
'id': queryParameters['comment_secondary_id'],
|
'id': commentSecondaryId,
|
||||||
},
|
},
|
||||||
() => Scaffold(
|
() => Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
@@ -142,9 +144,8 @@ class PiliScheme {
|
|||||||
source: 'routePush',
|
source: 'routePush',
|
||||||
replyType: 1,
|
replyType: 1,
|
||||||
firstFloor: null,
|
firstFloor: null,
|
||||||
id: queryParameters['comment_secondary_id'] != null
|
id: commentSecondaryId != null
|
||||||
? int.tryParse(
|
? int.tryParse(commentSecondaryId)
|
||||||
queryParameters['comment_secondary_id']!)
|
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -369,13 +370,15 @@ class PiliScheme {
|
|||||||
if (commentRootId != null) {
|
if (commentRootId != null) {
|
||||||
String? dynId = uriDigitRegExp.firstMatch(path)?.group(1);
|
String? dynId = uriDigitRegExp.firstMatch(path)?.group(1);
|
||||||
int? rpid = int.tryParse(commentRootId);
|
int? rpid = int.tryParse(commentRootId);
|
||||||
|
final commentSecondaryId =
|
||||||
|
queryParameters['comment_secondary_id'];
|
||||||
if (dynId != null && rpid != null) {
|
if (dynId != null && rpid != null) {
|
||||||
Get.to(
|
Get.to(
|
||||||
arguments: {
|
arguments: {
|
||||||
'oid': oid ?? dynId,
|
'oid': oid ?? dynId,
|
||||||
'rpid': rpid,
|
'rpid': rpid,
|
||||||
'type': businessId ?? 17,
|
'type': businessId ?? 17,
|
||||||
'id': queryParameters['comment_secondary_id'],
|
'id': commentSecondaryId,
|
||||||
},
|
},
|
||||||
() => Scaffold(
|
() => Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
@@ -399,9 +402,8 @@ class PiliScheme {
|
|||||||
source: 'routePush',
|
source: 'routePush',
|
||||||
replyType: businessId ?? 17,
|
replyType: businessId ?? 17,
|
||||||
firstFloor: null,
|
firstFloor: null,
|
||||||
id: queryParameters['comment_secondary_id'] != null
|
id: commentSecondaryId != null
|
||||||
? int.tryParse(
|
? int.tryParse(commentSecondaryId)
|
||||||
queryParameters['comment_secondary_id']!)
|
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -448,8 +450,7 @@ class PiliScheme {
|
|||||||
return false;
|
return false;
|
||||||
case 'm.bilibili.com':
|
case 'm.bilibili.com':
|
||||||
// bilibili://m.bilibili.com/topic-detail?topic_id=1028161&frommodule=H5&h5awaken=xxx
|
// bilibili://m.bilibili.com/topic-detail?topic_id=1028161&frommodule=H5&h5awaken=xxx
|
||||||
final id =
|
final id = uri.queryParameters['topic_id'];
|
||||||
RegExp(r'topic_id=(\d+)').firstMatch(uri.query)?.group(1);
|
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
PageUtils.toDupNamed(
|
PageUtils.toDupNamed(
|
||||||
'/dynTopic',
|
'/dynTopic',
|
||||||
@@ -589,16 +590,14 @@ class PiliScheme {
|
|||||||
launchURL();
|
launchURL();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final String? area = pathSegments.first == 'mobile'
|
final String? area =
|
||||||
|
pathSegments.first == 'mobile' || pathSegments.first == 'h5'
|
||||||
? pathSegments.getOrNull(1)
|
? pathSegments.getOrNull(1)
|
||||||
: pathSegments.first;
|
: pathSegments.first;
|
||||||
debugPrint('area: $area');
|
debugPrint('area: $area');
|
||||||
switch (area) {
|
switch (area) {
|
||||||
case 'h5':
|
case 'note':
|
||||||
if (path.startsWith('/h5/note')) {
|
String? id = uri.queryParameters['cvid'];
|
||||||
String? id = RegExp(r'cvid=(\d+)', caseSensitive: false)
|
|
||||||
.firstMatch(uri.query)
|
|
||||||
?.group(1);
|
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
PageUtils.toDupNamed(
|
PageUtils.toDupNamed(
|
||||||
'/articlePage',
|
'/articlePage',
|
||||||
@@ -610,7 +609,6 @@ class PiliScheme {
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
launchURL();
|
launchURL();
|
||||||
return false;
|
return false;
|
||||||
case 'dynamic' || 'opus':
|
case 'dynamic' || 'opus':
|
||||||
@@ -742,7 +740,7 @@ class PiliScheme {
|
|||||||
launchURL();
|
launchURL();
|
||||||
return false;
|
return false;
|
||||||
case 'topic-detail':
|
case 'topic-detail':
|
||||||
String? id = RegExp(r'topic_id=(\d+)').firstMatch(uri.query)?.group(1);
|
String? id = uri.queryParameters['topic_id'];
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
PageUtils.toDupNamed(
|
PageUtils.toDupNamed(
|
||||||
'/dynTopic',
|
'/dynTopic',
|
||||||
@@ -753,6 +751,58 @@ class PiliScheme {
|
|||||||
}
|
}
|
||||||
launchURL();
|
launchURL();
|
||||||
return false;
|
return false;
|
||||||
|
case 'comment':
|
||||||
|
// https://www.bilibili.com/h5/comment/sub?oid=123456&pageType=1&root=87654321
|
||||||
|
final queryParameters = uri.queryParameters;
|
||||||
|
String? oid = queryParameters['oid'];
|
||||||
|
String? root = queryParameters['root'];
|
||||||
|
String? pageType = queryParameters['pageType'];
|
||||||
|
if (oid != null && root != null && pageType != null) {
|
||||||
|
String? commentSecondaryId = queryParameters['comment_secondary_id'];
|
||||||
|
Get.to(
|
||||||
|
arguments: {
|
||||||
|
'oid': oid,
|
||||||
|
'rpid': root,
|
||||||
|
'type': pageType,
|
||||||
|
'id': commentSecondaryId,
|
||||||
|
},
|
||||||
|
() => Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('评论详情'),
|
||||||
|
actions: pageType == '1'
|
||||||
|
? [
|
||||||
|
IconButton(
|
||||||
|
tooltip: '前往',
|
||||||
|
onPressed: () {
|
||||||
|
videoPush(int.parse(oid), null);
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.open_in_new),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
top: false,
|
||||||
|
bottom: false,
|
||||||
|
child: VideoReplyReplyPanel(
|
||||||
|
enableSlide: false,
|
||||||
|
oid: int.parse(oid),
|
||||||
|
rpid: int.parse(root),
|
||||||
|
source: 'routePush',
|
||||||
|
replyType: int.parse(pageType),
|
||||||
|
firstFloor: null,
|
||||||
|
id: commentSecondaryId != null
|
||||||
|
? int.tryParse(commentSecondaryId)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
launchURL();
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
Map map = IdUtils.matchAvorBv(input: area?.split('?').first);
|
Map map = IdUtils.matchAvorBv(input: area?.split('?').first);
|
||||||
if (map.isNotEmpty) {
|
if (map.isNotEmpty) {
|
||||||
|
|||||||
Reference in New Issue
Block a user