mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-04-20 11:08:03 +08:00
@@ -55,18 +55,19 @@ class ColorPalette extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: showBgColor
|
||||
? BoxDecoration(
|
||||
color: colorScheme.onInverseSurface,
|
||||
borderRadius: StyleString.mdRadius,
|
||||
)
|
||||
: null,
|
||||
child: child,
|
||||
);
|
||||
if (showBgColor) {
|
||||
return Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.onInverseSurface,
|
||||
borderRadius: StyleString.mdRadius,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
static Widget _coloredBox(Color color) => Expanded(
|
||||
|
||||
@@ -11,34 +11,32 @@ Future<bool> showConfirmDialog({
|
||||
assert(content is String? || content is Widget);
|
||||
return await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(title),
|
||||
content: content is String
|
||||
? Text(content)
|
||||
: content is Widget
|
||||
? content
|
||||
: null,
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(title),
|
||||
content: content is String
|
||||
? Text(content)
|
||||
: content is Widget
|
||||
? content
|
||||
: null,
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back(result: true);
|
||||
onConfirm?.call();
|
||||
},
|
||||
child: const Text('确认'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back(result: true);
|
||||
onConfirm?.call();
|
||||
},
|
||||
child: const Text('确认'),
|
||||
),
|
||||
],
|
||||
),
|
||||
) ??
|
||||
false;
|
||||
}
|
||||
|
||||
@@ -19,116 +19,114 @@ Future<void> autoWrapReportDialog(
|
||||
late final key = GlobalKey<FormFieldState<String>>();
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('举报'),
|
||||
titlePadding: const .only(left: 22, top: 16, right: 22),
|
||||
contentPadding: const .symmetric(vertical: 5),
|
||||
actionsPadding: const .only(left: 16, right: 16, bottom: 10),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Flexible(
|
||||
child: SingleChildScrollView(
|
||||
child: AnimatedSize(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Builder(
|
||||
builder: (context) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: .only(left: 22, right: 22, bottom: 5),
|
||||
child: Text('请选择举报的理由:'),
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('举报'),
|
||||
titlePadding: const .only(left: 22, top: 16, right: 22),
|
||||
contentPadding: const .symmetric(vertical: 5),
|
||||
actionsPadding: const .only(left: 16, right: 16, bottom: 10),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Flexible(
|
||||
child: SingleChildScrollView(
|
||||
child: AnimatedSize(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Builder(
|
||||
builder: (context) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: .only(left: 22, right: 22, bottom: 5),
|
||||
child: Text('请选择举报的理由:'),
|
||||
),
|
||||
RadioGroup(
|
||||
onChanged: (value) {
|
||||
reasonType = value;
|
||||
(context as Element).markNeedsBuild();
|
||||
},
|
||||
groupValue: reasonType,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: options.entries.map((entry) {
|
||||
return WrapRadioOptionsGroup<int>(
|
||||
groupTitle: entry.key,
|
||||
options: entry.value,
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
RadioGroup(
|
||||
onChanged: (value) {
|
||||
reasonType = value;
|
||||
(context as Element).markNeedsBuild();
|
||||
},
|
||||
groupValue: reasonType,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: options.entries.map((entry) {
|
||||
return WrapRadioOptionsGroup<int>(
|
||||
groupTitle: entry.key,
|
||||
options: entry.value,
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
if (reasonType == 0)
|
||||
Padding(
|
||||
padding: const .only(left: 22, top: 5, right: 22),
|
||||
child: TextFormField(
|
||||
key: key,
|
||||
autofocus: true,
|
||||
minLines: 2,
|
||||
maxLines: 4,
|
||||
initialValue: reasonDesc,
|
||||
decoration: const InputDecoration(
|
||||
labelText: '为帮助审核人员更快处理,请补充问题类型和出现位置等详细信息',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: .all(10),
|
||||
labelStyle: TextStyle(fontSize: 14),
|
||||
floatingLabelStyle: TextStyle(fontSize: 14),
|
||||
),
|
||||
onChanged: (value) => reasonDesc = value,
|
||||
validator: (value) =>
|
||||
value.isNullOrEmpty ? '理由不能为空' : null,
|
||||
),
|
||||
if (reasonType == 0)
|
||||
Padding(
|
||||
padding: const .only(left: 22, top: 5, right: 22),
|
||||
child: TextFormField(
|
||||
key: key,
|
||||
autofocus: true,
|
||||
minLines: 2,
|
||||
maxLines: 4,
|
||||
initialValue: reasonDesc,
|
||||
decoration: const InputDecoration(
|
||||
labelText: '为帮助审核人员更快处理,请补充问题类型和出现位置等详细信息',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: .all(10),
|
||||
labelStyle: TextStyle(fontSize: 14),
|
||||
floatingLabelStyle: TextStyle(fontSize: 14),
|
||||
),
|
||||
onChanged: (value) => reasonDesc = value,
|
||||
validator: (value) =>
|
||||
value.isNullOrEmpty ? '理由不能为空' : null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (ban)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 14, top: 6),
|
||||
child: CheckBoxText(
|
||||
text: '拉黑该用户',
|
||||
onChanged: (value) => banUid = value,
|
||||
),
|
||||
),
|
||||
if (ban)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 14, top: 6),
|
||||
child: CheckBoxText(
|
||||
text: '拉黑该用户',
|
||||
onChanged: (value) => banUid = value,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(color: ColorScheme.of(context).outline),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (reasonType == null ||
|
||||
(reasonType == 0 && key.currentState?.validate() != true)) {
|
||||
return;
|
||||
}
|
||||
SmartDialog.showLoading();
|
||||
try {
|
||||
final res = await onSuccess(reasonType!, reasonDesc, banUid);
|
||||
SmartDialog.dismiss();
|
||||
if (res.isSuccess) {
|
||||
Get.back();
|
||||
SmartDialog.showToast('举报成功');
|
||||
} else {
|
||||
res.toast();
|
||||
}
|
||||
} catch (e, s) {
|
||||
SmartDialog.dismiss();
|
||||
SmartDialog.showToast('提交失败:$e');
|
||||
Utils.reportError(e, s);
|
||||
}
|
||||
},
|
||||
child: const Text('确定'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(color: ColorScheme.of(context).outline),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (reasonType == null ||
|
||||
(reasonType == 0 && key.currentState?.validate() != true)) {
|
||||
return;
|
||||
}
|
||||
SmartDialog.showLoading();
|
||||
try {
|
||||
final res = await onSuccess(reasonType!, reasonDesc, banUid);
|
||||
SmartDialog.dismiss();
|
||||
if (res.isSuccess) {
|
||||
Get.back();
|
||||
SmartDialog.showToast('举报成功');
|
||||
} else {
|
||||
res.toast();
|
||||
}
|
||||
} catch (e, s) {
|
||||
SmartDialog.dismiss();
|
||||
SmartDialog.showToast('提交失败:$e');
|
||||
Utils.reportError(e, s);
|
||||
}
|
||||
},
|
||||
child: const Text('确定'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -415,79 +415,77 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
HapticFeedback.mediumImpact();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (PlatformUtils.isMobile)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
ImageUtils.onShareImg(item.url);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('分享', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
builder: (context) => AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 12),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (PlatformUtils.isMobile)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Utils.copyText(item.url);
|
||||
ImageUtils.onShareImg(item.url);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('复制链接', style: TextStyle(fontSize: 14)),
|
||||
title: const Text('分享', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Utils.copyText(item.url);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('复制链接', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
ImageUtils.downloadImg([item.url]);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('保存图片', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
if (PlatformUtils.isDesktop)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
ImageUtils.downloadImg([item.url]);
|
||||
PageUtils.launchURL(item.url);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('保存图片', style: TextStyle(fontSize: 14)),
|
||||
title: const Text('网页打开', style: TextStyle(fontSize: 14)),
|
||||
)
|
||||
else if (widget.sources.length > 1)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
ImageUtils.downloadImg(
|
||||
widget.sources.map((item) => item.url).toList(),
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('保存全部图片', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
if (PlatformUtils.isDesktop)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
PageUtils.launchURL(item.url);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('网页打开', style: TextStyle(fontSize: 14)),
|
||||
)
|
||||
else if (widget.sources.length > 1)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
ImageUtils.downloadImg(
|
||||
widget.sources.map((item) => item.url).toList(),
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('保存全部图片', style: TextStyle(fontSize: 14)),
|
||||
if (item.sourceType == SourceType.livePhoto)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
ImageUtils.downloadLivePhoto(
|
||||
url: item.url,
|
||||
liveUrl: item.liveUrl!,
|
||||
width: item.width!,
|
||||
height: item.height!,
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
title: Text(
|
||||
'保存${Platform.isIOS ? ' Live Photo' : '视频'}',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
if (item.sourceType == SourceType.livePhoto)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
ImageUtils.downloadLivePhoto(
|
||||
url: item.url,
|
||||
liveUrl: item.liveUrl!,
|
||||
width: item.width!,
|
||||
height: item.height!,
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
title: Text(
|
||||
'保存${Platform.isIOS ? ' Live Photo' : '视频'}',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,19 +102,17 @@ class VideoPopupMenu extends StatelessWidget {
|
||||
if (res != null && context.mounted) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Dialog(
|
||||
child: Padding(
|
||||
padding: const .symmetric(vertical: 14),
|
||||
child: AiConclusionPanel.buildContent(
|
||||
context,
|
||||
Theme.of(context),
|
||||
res,
|
||||
tap: false,
|
||||
),
|
||||
builder: (context) => Dialog(
|
||||
child: Padding(
|
||||
padding: const .symmetric(vertical: 14),
|
||||
child: AiConclusionPanel.buildContent(
|
||||
context,
|
||||
Theme.of(context),
|
||||
res,
|
||||
tap: false,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -242,74 +240,70 @@ class VideoPopupMenu extends StatelessWidget {
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 5),
|
||||
const Text("web端暂不支持精细选择"),
|
||||
const SizedBox(height: 5),
|
||||
Wrap(
|
||||
spacing: 5.0,
|
||||
runSpacing: 2.0,
|
||||
children: [
|
||||
FilledButton.tonal(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
SmartDialog.showLoading(
|
||||
msg: '正在提交',
|
||||
);
|
||||
final res =
|
||||
await VideoHttp.dislikeVideo(
|
||||
bvid: videoItem.bvid!,
|
||||
type: true,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
if (res.isSuccess) {
|
||||
SmartDialog.showToast('点踩成功');
|
||||
onRemove?.call();
|
||||
} else {
|
||||
res.toast();
|
||||
}
|
||||
},
|
||||
style: FilledButton.styleFrom(
|
||||
visualDensity:
|
||||
VisualDensity.compact,
|
||||
),
|
||||
child: const Text("点踩"),
|
||||
builder: (context) => AlertDialog(
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 5),
|
||||
const Text("web端暂不支持精细选择"),
|
||||
const SizedBox(height: 5),
|
||||
Wrap(
|
||||
spacing: 5.0,
|
||||
runSpacing: 2.0,
|
||||
children: [
|
||||
FilledButton.tonal(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
SmartDialog.showLoading(
|
||||
msg: '正在提交',
|
||||
);
|
||||
final res =
|
||||
await VideoHttp.dislikeVideo(
|
||||
bvid: videoItem.bvid!,
|
||||
type: true,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
if (res.isSuccess) {
|
||||
SmartDialog.showToast('点踩成功');
|
||||
onRemove?.call();
|
||||
} else {
|
||||
res.toast();
|
||||
}
|
||||
},
|
||||
style: FilledButton.styleFrom(
|
||||
visualDensity: VisualDensity.compact,
|
||||
),
|
||||
FilledButton.tonal(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
SmartDialog.showLoading(
|
||||
msg: '正在提交',
|
||||
);
|
||||
final res =
|
||||
await VideoHttp.dislikeVideo(
|
||||
bvid: videoItem.bvid!,
|
||||
type: false,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
SmartDialog.showToast(
|
||||
res.isSuccess
|
||||
? '取消踩'
|
||||
: res.toString(),
|
||||
);
|
||||
},
|
||||
style: FilledButton.styleFrom(
|
||||
visualDensity:
|
||||
VisualDensity.compact,
|
||||
),
|
||||
child: const Text("撤销"),
|
||||
child: const Text("点踩"),
|
||||
),
|
||||
FilledButton.tonal(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
SmartDialog.showLoading(
|
||||
msg: '正在提交',
|
||||
);
|
||||
final res =
|
||||
await VideoHttp.dislikeVideo(
|
||||
bvid: videoItem.bvid!,
|
||||
type: false,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
SmartDialog.showToast(
|
||||
res.isSuccess
|
||||
? '取消踩'
|
||||
: res.toString(),
|
||||
);
|
||||
},
|
||||
style: FilledButton.styleFrom(
|
||||
visualDensity: VisualDensity.compact,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
child: const Text("撤销"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user