Files
PiliPlus/lib/pages/dynamics/repost_dyn_panel.dart
bggRGjQaUbCoE a115b5e91b mod: refine reply/publish page
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
2025-01-25 15:02:01 +08:00

368 lines
11 KiB
Dart

import 'package:PiliPlus/common/widgets/network_img_layer.dart';
import 'package:PiliPlus/http/msg.dart';
import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:PiliPlus/pages/common/common_publish_page.dart';
import 'package:PiliPlus/pages/emote/controller.dart';
import 'package:PiliPlus/pages/emote/view.dart';
import 'package:PiliPlus/pages/video/detail/reply_new/toolbar_icon_button.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
class RepostPanel extends CommonPublishPage {
const RepostPanel({
super.key,
required this.item,
required this.callback,
});
final dynamic item;
final Function callback;
@override
State<RepostPanel> createState() => _RepostPanelState();
}
class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
bool _isMax = false;
late final dynamic _pic = (widget.item as DynamicItemModel?)
?.modules
?.moduleDynamic
?.major
?.archive
?.cover ??
(widget.item as DynamicItemModel?)
?.modules
?.moduleDynamic
?.major
?.pgc
?.cover ??
(widget.item as DynamicItemModel?)
?.modules
?.moduleDynamic
?.major
?.opus
?.pics
?.firstOrNull
?.url;
late final _text = (widget.item as DynamicItemModel?)
?.modules
?.moduleDynamic
?.major
?.opus
?.summary
?.text ??
(widget.item as DynamicItemModel?)?.modules?.moduleDynamic?.desc?.text ??
(widget.item as DynamicItemModel?)
?.modules
?.moduleDynamic
?.major
?.archive
?.title ??
(widget.item as DynamicItemModel?)
?.modules
?.moduleDynamic
?.major
?.pgc
?.title ??
'';
@override
void dispose() {
try {
Get.delete<EmotePanelController>();
} catch (_) {}
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedSize(
alignment: Alignment.topCenter,
curve: Curves.ease,
duration: const Duration(milliseconds: 300),
child: Column(
mainAxisSize: _isMax ? MainAxisSize.max : MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: _isMax ? 16 : 10),
_buildAppBar,
if (_isMax) Expanded(child: _buildEditPanel) else _buildEditPanel,
if (_isMax.not)
..._biuldDismiss
else ...[
_buildToolbar,
buildPanelContainer(Colors.transparent),
]
],
),
);
}
Widget get _buildEditPanel => Column(
mainAxisSize: _isMax ? MainAxisSize.max : MainAxisSize.min,
children: [
Flexible(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Container(
width: double.infinity,
decoration: _isMax.not
? BoxDecoration(
border: Border(
left: BorderSide(
width: 2,
color: Theme.of(context).colorScheme.primary,
),
),
)
: null,
child: _isMax.not ? _buildEditPlaceHolder : _buildEditWidget,
),
),
),
const SizedBox(height: 10),
_buildRefWidget,
],
);
Widget get _buildRefWidget => Container(
padding: const EdgeInsets.all(10),
margin: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerHigh ==
Theme.of(context).colorScheme.surface
? Theme.of(context).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
if (_pic != null) ...[
NetworkImgLayer(
radius: 8,
width: 40,
height: 40,
src: _pic,
),
const SizedBox(width: 10),
],
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'@${(widget.item as DynamicItemModel?)?.modules?.moduleAuthor?.name}',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: 13,
),
),
Text(
_text,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
);
Widget get _buildEditPlaceHolder => GestureDetector(
onTap: () async {
setState(() => _isMax = true);
await Future.delayed(const Duration(milliseconds: 300));
if (mounted) {
focusNode.requestFocus();
}
},
child: Text(
'说点什么吧',
style: TextStyle(
height: 1.75,
fontSize: 15,
color: Theme.of(context).colorScheme.outline,
),
),
);
Widget get _buildEditWidget => Form(
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Listener(
onPointerUp: (event) {
if (readOnly.value) {
updatePanelType(PanelType.keyboard);
selectKeyboard.value = true;
}
},
child: Obx(
() => TextField(
controller: editController,
minLines: 4,
maxLines: null,
focusNode: focusNode,
readOnly: readOnly.value,
decoration: const InputDecoration(
hintText: '说点什么吧',
border: OutlineInputBorder(
borderSide: BorderSide.none,
gapPadding: 0,
),
contentPadding: EdgeInsets.symmetric(vertical: 10),
),
),
),
),
);
Widget get _buildAppBar => _isMax.not
? Row(
children: [
const SizedBox(width: 16),
const Text(
'转发动态',
style: TextStyle(fontWeight: FontWeight.bold),
),
const Spacer(),
TextButton(
onPressed: onPublish,
style: TextButton.styleFrom(
padding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
visualDensity: const VisualDensity(
horizontal: -2,
vertical: -2,
),
),
child: const Text('立即转发'),
),
const SizedBox(width: 16),
],
)
: Container(
height: 34,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Stack(
alignment: Alignment.center,
children: [
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: 34,
height: 34,
child: IconButton(
tooltip: '返回',
style: ButtonStyle(
padding: WidgetStateProperty.all(EdgeInsets.zero),
backgroundColor:
WidgetStateProperty.resolveWith((states) {
return Theme.of(context).colorScheme.secondaryContainer;
}),
),
onPressed: Get.back,
icon: Icon(
Icons.arrow_back_outlined,
size: 18,
color: Theme.of(context).colorScheme.onSecondaryContainer,
),
),
),
),
Center(
child: const Text(
'转发动态',
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
),
Align(
alignment: Alignment.centerRight,
child: FilledButton.tonal(
onPressed: onPublish,
style: FilledButton.styleFrom(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
visualDensity: const VisualDensity(
horizontal: -2,
vertical: -2,
),
),
child: const Text('转发'),
),
),
],
),
);
Widget get _buildToolbar => Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
children: [
Obx(
() => ToolbarIconButton(
onPressed: () {
selectKeyboard.value = PanelType.emoji == currentPanelType;
updatePanelType(
PanelType.emoji == currentPanelType
? PanelType.keyboard
: PanelType.emoji,
);
},
icon: const Icon(Icons.emoji_emotions, size: 22),
tooltip: '表情',
selected: !selectKeyboard.value,
),
),
],
),
);
List<Widget> get _biuldDismiss => [
const SizedBox(height: 10),
Divider(
height: 1,
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
),
ListTile(
dense: true,
onTap: Get.back,
title: Center(
child: Text(
'取消',
style: TextStyle(color: Theme.of(context).colorScheme.outline),
),
),
),
SizedBox(height: 10 + MediaQuery.of(context).padding.bottom),
];
@override
Widget? customPanel(double height) => SizedBox(
height: height,
child: EmotePanel(onChoose: onChooseEmote),
);
@override
Future onCustomPublish({required String message, List? pictures}) async {
dynamic result = await MsgHttp.createDynamic(
mid: GStorage.userInfo.get('userInfoCache')?.mid,
dynIdStr: widget.item.idStr,
rawText: editController.text,
);
if (result['status']) {
Get.back();
SmartDialog.showToast('转发成功');
widget.callback();
} else {
SmartDialog.showToast(result['msg']);
}
}
}