mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
mod: 无障碍语义适配
This commit is contained in:
@@ -87,7 +87,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
errMsg: snapshot.data['msg'],
|
||||
btnText: snapshot.data['code'] == -404 ||
|
||||
snapshot.data['code'] == 62002
|
||||
? '返回上一页'
|
||||
? '上一页'
|
||||
: null,
|
||||
fn: () => Get.back(),
|
||||
);
|
||||
@@ -285,8 +285,8 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
StatDanMu(
|
||||
theme: 'gray',
|
||||
danmu: !loadingStatus
|
||||
? widget.videoDetail!.stat!.danmaku
|
||||
: videoItem['stat'].danmaku,
|
||||
? widget.videoDetail!.stat!.danmu
|
||||
: videoItem['stat'].danmu,
|
||||
size: 'medium',
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
@@ -335,17 +335,19 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
Positioned(
|
||||
right: 10,
|
||||
top: 6,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final res =
|
||||
await videoIntroController.aiConclusion();
|
||||
if (res['status']) {
|
||||
showAiBottomSheet();
|
||||
}
|
||||
},
|
||||
child:
|
||||
Image.asset('assets/images/ai.png', height: 22),
|
||||
),
|
||||
child: Semantics(
|
||||
label: 'AI总结',
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final res =
|
||||
await videoIntroController.aiConclusion();
|
||||
if (res['status']) {
|
||||
showAiBottomSheet();
|
||||
}
|
||||
},
|
||||
child: Image.asset('assets/images/ai.png',
|
||||
height: 22),
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
@@ -406,11 +408,15 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
fadeOutDuration: Duration.zero,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(owner.name,
|
||||
style: const TextStyle(fontSize: 13)),
|
||||
Text(
|
||||
owner.name,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
// semanticsLabel: "Up主:${owner.name}",
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
follower,
|
||||
semanticsLabel: "粉丝数:$follower",
|
||||
style: TextStyle(
|
||||
fontSize: t.textTheme.labelSmall!.fontSize,
|
||||
color: outline,
|
||||
@@ -498,8 +504,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
onTap: handleState(videoIntroController.actionLikeVideo),
|
||||
selectStatus: videoIntroController.hasLike.value,
|
||||
loadingStatus: loadingStatus,
|
||||
semanticsLabel: '点赞',
|
||||
text: !loadingStatus
|
||||
? widget.videoDetail!.stat!.like!.toString()
|
||||
? Utils.numFormat(widget.videoDetail!.stat!.like!)
|
||||
: '-'),
|
||||
),
|
||||
// ActionItem(
|
||||
@@ -515,8 +522,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
onTap: handleState(videoIntroController.actionCoinVideo),
|
||||
selectStatus: videoIntroController.hasCoin.value,
|
||||
loadingStatus: loadingStatus,
|
||||
semanticsLabel: '投币',
|
||||
text: !loadingStatus
|
||||
? widget.videoDetail!.stat!.coin!.toString()
|
||||
? Utils.numFormat(widget.videoDetail!.stat!.coin!)
|
||||
: '-'),
|
||||
),
|
||||
Obx(
|
||||
@@ -527,8 +535,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
onLongPress: () => showFavBottomSheet(type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
loadingStatus: loadingStatus,
|
||||
semanticsLabel: '收藏',
|
||||
text: !loadingStatus
|
||||
? widget.videoDetail!.stat!.favorite!.toString()
|
||||
? Utils.numFormat(widget.videoDetail!.stat!.favorite!)
|
||||
: '-'),
|
||||
),
|
||||
ActionItem(
|
||||
@@ -536,15 +545,19 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
onTap: () => videoDetailCtr.tabCtr.animateTo(1),
|
||||
selectStatus: false,
|
||||
loadingStatus: loadingStatus,
|
||||
semanticsLabel: '评论',
|
||||
text: !loadingStatus
|
||||
? widget.videoDetail!.stat!.reply!.toString()
|
||||
? Utils.numFormat(widget.videoDetail!.stat!.reply!)
|
||||
: '评论'),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||
onTap: () => videoIntroController.actionShareVideo(),
|
||||
selectStatus: false,
|
||||
loadingStatus: loadingStatus,
|
||||
text: '分享'),
|
||||
semanticsLabel: '分享',
|
||||
text: !loadingStatus
|
||||
? Utils.numFormat(widget.videoDetail!.stat!.share!)
|
||||
: '分享'),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ class ActionItem extends StatelessWidget {
|
||||
final bool? loadingStatus;
|
||||
final String? text;
|
||||
final bool selectStatus;
|
||||
final String semanticsLabel;
|
||||
|
||||
const ActionItem({
|
||||
Key? key,
|
||||
@@ -20,11 +21,15 @@ class ActionItem extends StatelessWidget {
|
||||
this.loadingStatus,
|
||||
this.text,
|
||||
this.selectStatus = false,
|
||||
required this.semanticsLabel,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
return Semantics(
|
||||
label: (text ?? "") + (selectStatus ? "已" :"") + semanticsLabel,
|
||||
child:
|
||||
InkWell(
|
||||
onTap: () => {
|
||||
feedBack(),
|
||||
onTap!(),
|
||||
@@ -37,11 +42,15 @@ class ActionItem extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
selectStatus
|
||||
? Icon(selectIcon!.icon!,
|
||||
size: 18, color: Theme.of(context).colorScheme.primary)
|
||||
: Icon(icon!.icon!,
|
||||
size: 18, color: Theme.of(context).colorScheme.outline),
|
||||
Icon(
|
||||
selectStatus
|
||||
? selectIcon!.icon!
|
||||
: icon!.icon!,
|
||||
size: 18,
|
||||
color: selectStatus
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
AnimatedOpacity(
|
||||
opacity: loadingStatus! ? 0 : 1,
|
||||
@@ -59,11 +68,12 @@ class ActionItem extends StatelessWidget {
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).colorScheme.outline,
|
||||
fontSize: Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||
semanticsLabel: "",
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ class _FavPanelState extends State<FavPanel> {
|
||||
centerTitle: false,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
tooltip: '关闭',
|
||||
onPressed: () => Get.back(),
|
||||
icon: const Icon(Icons.close_outlined)),
|
||||
title:
|
||||
|
||||
@@ -61,6 +61,7 @@ class _GroupPanelState extends State<GroupPanel> {
|
||||
centerTitle: false,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
tooltip: '关闭',
|
||||
onPressed: () => Get.back(),
|
||||
icon: const Icon(Icons.close_outlined)),
|
||||
title:
|
||||
|
||||
@@ -61,7 +61,7 @@ class IntroDetail extends StatelessWidget {
|
||||
const SizedBox(width: 10),
|
||||
StatDanMu(
|
||||
theme: 'gray',
|
||||
danmu: videoDetail!.stat!.danmaku,
|
||||
danmu: videoDetail!.stat!.danmu,
|
||||
size: 'medium',
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
|
||||
@@ -115,6 +115,7 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
.titleMedium,
|
||||
),
|
||||
IconButton(
|
||||
tooltip: '关闭',
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
|
||||
@@ -210,28 +210,30 @@ class ReplyItem extends StatelessWidget {
|
||||
// title
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 10, left: 45, right: 6, bottom: 4),
|
||||
child: Text.rich(
|
||||
style: const TextStyle(height: 1.75),
|
||||
maxLines:
|
||||
replyItem!.content!.isText! && replyLevel == '1' ? 3 : 999,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
TextSpan(
|
||||
children: [
|
||||
if (replyItem!.isTop!)
|
||||
const WidgetSpan(
|
||||
alignment: PlaceholderAlignment.top,
|
||||
child: PBadge(
|
||||
text: 'TOP',
|
||||
size: 'small',
|
||||
stack: 'normal',
|
||||
type: 'line',
|
||||
fs: 9,
|
||||
),
|
||||
),
|
||||
buildContent(context, replyItem!, replyReply, null),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Semantics(
|
||||
label: replyItem?.content?.message ?? "",
|
||||
child: Text.rich(
|
||||
style: const TextStyle(height: 1.75),
|
||||
maxLines:
|
||||
replyItem!.content!.isText! && replyLevel == '1' ? 3 : 999,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
TextSpan(
|
||||
children: [
|
||||
if (replyItem!.isTop!)
|
||||
const WidgetSpan(
|
||||
alignment: PlaceholderAlignment.top,
|
||||
child: PBadge(
|
||||
text: 'TOP',
|
||||
size: 'small',
|
||||
stack: 'normal',
|
||||
type: 'line',
|
||||
fs: 9,
|
||||
),
|
||||
),
|
||||
buildContent(context, replyItem!, replyReply, null),
|
||||
],
|
||||
),
|
||||
)),
|
||||
),
|
||||
// 操作区域
|
||||
bottonAction(context, replyItem!.replyControl),
|
||||
|
||||
@@ -76,6 +76,7 @@ class _ZanButtonState extends State<ZanButton> {
|
||||
: FontAwesomeIcons.thumbsUp,
|
||||
size: 16,
|
||||
color: widget.replyItem!.action == 1 ? primary : color,
|
||||
semanticLabel: widget.replyItem!.action == 1 ? '已赞' : '点赞',
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
AnimatedSwitcher(
|
||||
|
||||
@@ -5,6 +5,7 @@ class ToolbarIconButton extends StatelessWidget {
|
||||
final Icon icon;
|
||||
final String toolbarType;
|
||||
final bool selected;
|
||||
final String tooltip;
|
||||
|
||||
const ToolbarIconButton({
|
||||
super.key,
|
||||
@@ -12,6 +13,7 @@ class ToolbarIconButton extends StatelessWidget {
|
||||
required this.icon,
|
||||
required this.toolbarType,
|
||||
required this.selected,
|
||||
required this.tooltip,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -20,6 +22,7 @@ class ToolbarIconButton extends StatelessWidget {
|
||||
width: 36,
|
||||
height: 36,
|
||||
child: IconButton(
|
||||
tooltip: tooltip,
|
||||
onPressed: onPressed,
|
||||
icon: icon,
|
||||
highlightColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||
|
||||
@@ -192,6 +192,7 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ToolbarIconButton(
|
||||
tooltip: '输入',
|
||||
onPressed: () {
|
||||
if (toolbarType == 'emote') {
|
||||
setState(() {
|
||||
@@ -206,6 +207,7 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
ToolbarIconButton(
|
||||
tooltip: '表情',
|
||||
onPressed: () {
|
||||
if (toolbarType == 'input') {
|
||||
setState(() {
|
||||
|
||||
@@ -85,6 +85,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
|
||||
children: <Widget>[
|
||||
const Text('评论详情'),
|
||||
IconButton(
|
||||
tooltip: '关闭',
|
||||
icon: const Icon(Icons.close, size: 20),
|
||||
onPressed: () {
|
||||
_videoReplyReplyController.currentPage = 0;
|
||||
|
||||
@@ -1027,6 +1027,7 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
children: [
|
||||
// SizedBox(width: MediaQuery.of(context).padding.left,),
|
||||
ComBtn(
|
||||
tooltip: '上一页',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.arrowLeft,
|
||||
size: 15,
|
||||
@@ -1048,8 +1049,9 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
},
|
||||
),
|
||||
SizedBox(width: buttonSpace),
|
||||
if ((videoIntroController.videoDetail.value.title != null) && (isFullScreen ||
|
||||
(!isFullScreen && isLandscape && !horizontalScreen))) ...[
|
||||
if ((videoIntroController.videoDetail.value.title != null) &&
|
||||
(isFullScreen ||
|
||||
(!isFullScreen && isLandscape && !horizontalScreen))) ...[
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -1090,6 +1092,7 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
)
|
||||
] else ...[
|
||||
ComBtn(
|
||||
tooltip: '返回主页',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.house,
|
||||
size: 15,
|
||||
@@ -1118,12 +1121,13 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
width: 34,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
tooltip: '发弹幕',
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => showShootDanmakuSheet(),
|
||||
icon: const Icon(
|
||||
Icons.add_card_outlined,
|
||||
Icons.add_comment_outlined,
|
||||
size: 19,
|
||||
color: Colors.white,
|
||||
),
|
||||
@@ -1135,6 +1139,7 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
height: 34,
|
||||
child: Obx(
|
||||
() => IconButton(
|
||||
tooltip: "${_.isOpenDanmu.value ? '关闭' : '开启'}弹幕",
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
@@ -1143,8 +1148,8 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
},
|
||||
icon: Icon(
|
||||
_.isOpenDanmu.value
|
||||
? Icons.subtitles_outlined
|
||||
: Icons.subtitles_off_outlined,
|
||||
? Icons.comment_outlined
|
||||
: Icons.comments_disabled_outlined,
|
||||
size: 19,
|
||||
color: Colors.white,
|
||||
),
|
||||
@@ -1157,6 +1162,7 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
width: 34,
|
||||
height: 34,
|
||||
child: IconButton(
|
||||
tooltip: '画中画',
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
@@ -1182,6 +1188,7 @@ class _HeaderControlState extends State<HeaderControl> {
|
||||
SizedBox(width: buttonSpace),
|
||||
],
|
||||
ComBtn(
|
||||
tooltip: '更多设置',
|
||||
icon: const Icon(
|
||||
Icons.more_vert_outlined,
|
||||
size: 18,
|
||||
|
||||
Reference in New Issue
Block a user