mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-31 08:08:19 +08:00
opt: create dynamic panel
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -149,6 +149,7 @@ class MsgHttp {
|
|||||||
List? pics,
|
List? pics,
|
||||||
int? publishTime,
|
int? publishTime,
|
||||||
ReplyOption replyOption = ReplyOption.allow,
|
ReplyOption replyOption = ReplyOption.allow,
|
||||||
|
int? privatePub,
|
||||||
}) async {
|
}) async {
|
||||||
String csrf = await Request.getCsrf();
|
String csrf = await Request.getCsrf();
|
||||||
var res = await Request().post(
|
var res = await Request().post(
|
||||||
@@ -181,6 +182,10 @@ class MsgHttp {
|
|||||||
: pics != null
|
: pics != null
|
||||||
? 2
|
? 2
|
||||||
: 1,
|
: 1,
|
||||||
|
if (privatePub != null)
|
||||||
|
'create_option': {
|
||||||
|
'private_pub': privatePub,
|
||||||
|
},
|
||||||
if (pics != null) 'pics': pics,
|
if (pics != null) 'pics': pics,
|
||||||
"attach_card": null,
|
"attach_card": null,
|
||||||
"upload_id":
|
"upload_id":
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class SearchHttp {
|
|||||||
if (pubEnd != null) 'pubtime_end_s': pubEnd,
|
if (pubEnd != null) 'pubtime_end_s': pubEnd,
|
||||||
};
|
};
|
||||||
var res = await Request().get(Api.searchByType, queryParameters: reqData);
|
var res = await Request().get(Api.searchByType, queryParameters: reqData);
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] is int && res.data['code'] == 0) {
|
||||||
dynamic data;
|
dynamic data;
|
||||||
try {
|
try {
|
||||||
switch (searchType) {
|
switch (searchType) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import 'package:PiliPalaX/utils/feed_back.dart';
|
|||||||
import 'package:PiliPalaX/utils/storage.dart';
|
import 'package:PiliPalaX/utils/storage.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
import 'package:nil/nil.dart';
|
import 'package:nil/nil.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
@@ -23,6 +24,12 @@ enum ReplyOption { allow, close, choose }
|
|||||||
|
|
||||||
extension ReplyOptionExtension on ReplyOption {
|
extension ReplyOptionExtension on ReplyOption {
|
||||||
String get title => ['允许评论', '关闭评论', '精选评论'][index];
|
String get title => ['允许评论', '关闭评论', '精选评论'][index];
|
||||||
|
|
||||||
|
IconData get iconData => [
|
||||||
|
MdiIcons.commentTextOutline,
|
||||||
|
MdiIcons.commentOffOutline,
|
||||||
|
MdiIcons.commentProcessingOutline,
|
||||||
|
][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
class DynamicsPage extends StatefulWidget {
|
class DynamicsPage extends StatefulWidget {
|
||||||
@@ -241,21 +248,18 @@ class CreatePanel extends StatefulWidget {
|
|||||||
|
|
||||||
class _CreatePanelState extends State<CreatePanel> {
|
class _CreatePanelState extends State<CreatePanel> {
|
||||||
final _ctr = TextEditingController();
|
final _ctr = TextEditingController();
|
||||||
bool _isEnable = false;
|
|
||||||
final _isEnableStream = StreamController<bool>();
|
|
||||||
late final _imagePicker = ImagePicker();
|
late final _imagePicker = ImagePicker();
|
||||||
late final _pathList = <String>[];
|
late final int _limit = 18;
|
||||||
late final _pathStream = StreamController<List<String>>();
|
|
||||||
|
|
||||||
|
final RxBool _isEnablePub = false.obs;
|
||||||
|
late final RxList<String> _pathList = <String>[].obs;
|
||||||
|
|
||||||
|
bool _isPrivate = false;
|
||||||
DateTime? _publishTime;
|
DateTime? _publishTime;
|
||||||
ReplyOption _replyOption = ReplyOption.allow;
|
ReplyOption _replyOption = ReplyOption.allow;
|
||||||
|
|
||||||
late final int _limit = 18;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_isEnableStream.close();
|
|
||||||
_pathStream.close();
|
|
||||||
_ctr.dispose();
|
_ctr.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
@@ -298,6 +302,7 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SmartDialog.showLoading(msg: '正在发布');
|
||||||
dynamic result = await MsgHttp.createDynamic(
|
dynamic result = await MsgHttp.createDynamic(
|
||||||
mid: GStorage.userInfo.get('userInfoCache')?.mid,
|
mid: GStorage.userInfo.get('userInfoCache')?.mid,
|
||||||
rawText: _ctr.text,
|
rawText: _ctr.text,
|
||||||
@@ -306,11 +311,14 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
? _publishTime!.millisecondsSinceEpoch ~/ 1000
|
? _publishTime!.millisecondsSinceEpoch ~/ 1000
|
||||||
: null,
|
: null,
|
||||||
replyOption: _replyOption,
|
replyOption: _replyOption,
|
||||||
|
privatePub: _isPrivate ? 1 : null,
|
||||||
);
|
);
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
Get.back();
|
Get.back();
|
||||||
|
SmartDialog.dismiss();
|
||||||
SmartDialog.showToast('发布成功');
|
SmartDialog.showToast('发布成功');
|
||||||
} else {
|
} else {
|
||||||
|
SmartDialog.dismiss();
|
||||||
SmartDialog.showToast(result['msg']);
|
SmartDialog.showToast(result['msg']);
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
@@ -318,12 +326,14 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Scaffold(
|
||||||
mainAxisSize: MainAxisSize.max,
|
backgroundColor: Colors.transparent,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
resizeToAvoidBottomInset: true,
|
||||||
children: [
|
appBar: PreferredSize(
|
||||||
const SizedBox(height: 16),
|
preferredSize: Size.fromHeight(66),
|
||||||
Row(
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 16, bottom: 16),
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
@@ -353,26 +363,30 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
StreamBuilder(
|
Obx(
|
||||||
initialData: false,
|
() => FilledButton.tonal(
|
||||||
stream: _isEnableStream.stream,
|
onPressed: _isEnablePub.value ? _onCreate : null,
|
||||||
builder: (context, snapshot) => FilledButton.tonal(
|
|
||||||
onPressed: snapshot.data == true ? _onCreate : null,
|
|
||||||
style: FilledButton.styleFrom(
|
style: FilledButton.styleFrom(
|
||||||
padding:
|
padding: const EdgeInsets.symmetric(
|
||||||
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
horizontal: 20, vertical: 10),
|
||||||
visualDensity: const VisualDensity(
|
visualDensity: const VisualDensity(
|
||||||
horizontal: -2,
|
horizontal: -2,
|
||||||
vertical: -2,
|
vertical: -2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Text('发布'),
|
child: Text(_publishTime == null ? '发布' : '定时发布'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
),
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
@@ -381,14 +395,11 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
maxLines: 8,
|
maxLines: 8,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
bool isEmpty =
|
bool isEmpty = value.trim().isEmpty && _pathList.isEmpty;
|
||||||
value.replaceAll('\n', '').isEmpty && _pathList.isEmpty;
|
if (!isEmpty && !_isEnablePub.value) {
|
||||||
if (!isEmpty && !_isEnable) {
|
_isEnablePub.value = true;
|
||||||
_isEnable = true;
|
} else if (isEmpty && _isEnablePub.value) {
|
||||||
_isEnableStream.add(true);
|
_isEnablePub.value = false;
|
||||||
} else if (isEmpty && _isEnable) {
|
|
||||||
_isEnable = false;
|
|
||||||
_isEnableStream.add(false);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
@@ -397,10 +408,11 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
borderSide: BorderSide.none,
|
borderSide: BorderSide.none,
|
||||||
gapPadding: 0,
|
gapPadding: 0,
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.symmetric(vertical: 10),
|
contentPadding: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -418,7 +430,9 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
vertical: -2,
|
vertical: -2,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: _isPrivate
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
DateTime nowDate = DateTime.now();
|
DateTime nowDate = DateTime.now();
|
||||||
showDatePicker(
|
showDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -431,30 +445,35 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
),
|
),
|
||||||
).then(
|
).then(
|
||||||
(selectedDate) {
|
(selectedDate) {
|
||||||
if (selectedDate != null && context.mounted) {
|
if (selectedDate != null &&
|
||||||
if (selectedDate.day == nowDate.day) {
|
context.mounted) {
|
||||||
SmartDialog.showToast('至少选择10分钟之后');
|
|
||||||
}
|
|
||||||
TimeOfDay nowTime = TimeOfDay.now();
|
TimeOfDay nowTime = TimeOfDay.now();
|
||||||
showTimePicker(
|
showTimePicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialTime: nowTime.replacing(
|
initialTime: nowTime.replacing(
|
||||||
hour: nowTime.minute + 10 >= 60
|
hour: nowTime.minute + 6 >= 60
|
||||||
? (nowTime.hour + 1) % 24
|
? (nowTime.hour + 1) % 24
|
||||||
: nowTime.hour,
|
: nowTime.hour,
|
||||||
minute: (nowTime.minute + 10) % 60,
|
minute: (nowTime.minute + 6) % 60,
|
||||||
),
|
),
|
||||||
).then((selectedTime) {
|
).then((selectedTime) {
|
||||||
if (selectedTime != null) {
|
if (selectedTime != null) {
|
||||||
if (selectedDate.day == nowDate.day) {
|
if (selectedDate.day ==
|
||||||
if (selectedTime.hour < nowTime.hour) {
|
nowDate.day) {
|
||||||
SmartDialog.showToast('时间设置错误');
|
if (selectedTime.hour <
|
||||||
|
nowTime.hour) {
|
||||||
|
SmartDialog.showToast(
|
||||||
|
'时间设置错误,至少选择6分钟之后');
|
||||||
return;
|
return;
|
||||||
} else if (selectedTime.hour ==
|
} else if (selectedTime.hour ==
|
||||||
nowTime.hour) {
|
nowTime.hour) {
|
||||||
if (selectedTime.minute <
|
if (selectedTime.minute <
|
||||||
nowTime.minute + 10) {
|
nowTime.minute + 6) {
|
||||||
SmartDialog.showToast('时间设置错误');
|
if (selectedDate.day ==
|
||||||
|
nowDate.day) {
|
||||||
|
SmartDialog.showToast(
|
||||||
|
'时间设置错误,至少选择6分钟之后');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -492,11 +511,87 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
_publishTime = null;
|
_publishTime = null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
label: Text(
|
label: Text(DateFormat('yyyy-MM-dd HH:mm')
|
||||||
DateFormat('yyyy-MM-dd HH:mm').format(_publishTime!)),
|
.format(_publishTime!)),
|
||||||
icon: Icon(Icons.clear, size: 20),
|
icon: Icon(Icons.clear, size: 20),
|
||||||
iconAlignment: IconAlignment.end,
|
iconAlignment: IconAlignment.end,
|
||||||
),
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
PopupMenuButton(
|
||||||
|
enabled: _publishTime == null,
|
||||||
|
initialValue: _isPrivate,
|
||||||
|
onSelected: (value) {
|
||||||
|
setState(() {
|
||||||
|
_isPrivate = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
itemBuilder: (context) => List.generate(
|
||||||
|
2,
|
||||||
|
(index) => PopupMenuItem<bool>(
|
||||||
|
value: index == 0 ? false : true,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
size: 19,
|
||||||
|
index == 0
|
||||||
|
? Icons.visibility
|
||||||
|
: Icons.visibility_off,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(index == 0 ? '所有人可见' : '仅自己可见'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
size: 19,
|
||||||
|
_isPrivate
|
||||||
|
? Icons.visibility_off
|
||||||
|
: Icons.visibility,
|
||||||
|
color: _publishTime == null
|
||||||
|
? _isPrivate
|
||||||
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context).colorScheme.primary
|
||||||
|
: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
_isPrivate ? '仅自己可见' : '所有人可见',
|
||||||
|
style: TextStyle(
|
||||||
|
height: 1,
|
||||||
|
color: _publishTime == null
|
||||||
|
? _isPrivate
|
||||||
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.primary
|
||||||
|
: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
strutStyle: StrutStyle(leading: 0, height: 1),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
size: 20,
|
||||||
|
Icons.keyboard_arrow_right,
|
||||||
|
color: _publishTime == null
|
||||||
|
? _isPrivate
|
||||||
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context).colorScheme.primary
|
||||||
|
: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 5),
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
initialValue: _replyOption,
|
initialValue: _replyOption,
|
||||||
onSelected: (item) {
|
onSelected: (item) {
|
||||||
@@ -505,57 +600,85 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
itemBuilder: (context) => ReplyOption.values
|
itemBuilder: (context) => ReplyOption.values
|
||||||
.map((item) => PopupMenuItem<ReplyOption>(
|
.map(
|
||||||
|
(item) => PopupMenuItem<ReplyOption>(
|
||||||
value: item,
|
value: item,
|
||||||
child: Text(item.title),
|
|
||||||
))
|
|
||||||
.toList(),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
Icon(
|
||||||
|
size: 19,
|
||||||
|
item.iconData,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(item.title),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
size: 19,
|
||||||
|
_replyOption.iconData,
|
||||||
|
color: _replyOption == ReplyOption.close
|
||||||
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
_replyOption.title,
|
_replyOption.title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
height: 1,
|
height: 1,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: _replyOption == ReplyOption.close
|
||||||
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
strutStyle: StrutStyle(leading: 0, height: 1),
|
strutStyle: StrutStyle(leading: 0, height: 1),
|
||||||
),
|
),
|
||||||
Icon(
|
Icon(
|
||||||
size: 20,
|
size: 20,
|
||||||
Icons.keyboard_arrow_right,
|
Icons.keyboard_arrow_right,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: _replyOption == ReplyOption.close
|
||||||
)
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
StreamBuilder(
|
Obx(
|
||||||
initialData: const [],
|
() => SizedBox(
|
||||||
stream: _pathStream.stream,
|
height: 100,
|
||||||
builder: (context, snapshot) => SizedBox(
|
|
||||||
height: 75,
|
|
||||||
child: ListView.separated(
|
child: ListView.separated(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
physics: const AlwaysScrollableScrollPhysics(
|
physics: const AlwaysScrollableScrollPhysics(
|
||||||
parent: BouncingScrollPhysics(),
|
parent: BouncingScrollPhysics(),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
itemCount:
|
itemCount: _pathList.length == _limit
|
||||||
_pathList.length == _limit ? _limit : _pathList.length + 1,
|
? _limit
|
||||||
|
: _pathList.length + 1,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (_pathList.length != _limit && index == _pathList.length) {
|
if (_pathList.length != _limit &&
|
||||||
|
index == _pathList.length) {
|
||||||
return Material(
|
return Material(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
EasyThrottle.throttle(
|
EasyThrottle.throttle('imagePicker',
|
||||||
'imagePicker', const Duration(milliseconds: 500),
|
const Duration(milliseconds: 500), () async {
|
||||||
() async {
|
|
||||||
try {
|
try {
|
||||||
List<XFile> pickedFiles =
|
List<XFile> pickedFiles =
|
||||||
await _imagePicker.pickMultiImage(
|
await _imagePicker.pickMultiImage(
|
||||||
@@ -566,20 +689,14 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
for (int i = 0; i < pickedFiles.length; i++) {
|
for (int i = 0; i < pickedFiles.length; i++) {
|
||||||
if (_pathList.length == _limit) {
|
if (_pathList.length == _limit) {
|
||||||
SmartDialog.showToast('最多选择$_limit张图片');
|
SmartDialog.showToast('最多选择$_limit张图片');
|
||||||
if (i != 0) {
|
|
||||||
_pathStream.add(_pathList);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
_pathList.add(pickedFiles[i].path);
|
_pathList.add(pickedFiles[i].path);
|
||||||
if (i == pickedFiles.length - 1) {
|
|
||||||
_pathStream.add(_pathList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (_pathList.isNotEmpty &&
|
||||||
if (_pathList.isNotEmpty && !_isEnable) {
|
!_isEnablePub.value) {
|
||||||
_isEnable = true;
|
_isEnablePub.value = true;
|
||||||
_isEnableStream.add(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -588,14 +705,15 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Ink(
|
child: Ink(
|
||||||
width: 75,
|
width: 100,
|
||||||
height: 75,
|
height: 100,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
color:
|
color: Theme.of(context)
|
||||||
Theme.of(context).colorScheme.secondaryContainer,
|
.colorScheme
|
||||||
|
.secondaryContainer,
|
||||||
),
|
),
|
||||||
child: Center(child: Icon(Icons.add)),
|
child: Center(child: Icon(Icons.add, size: 35)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -603,15 +721,12 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_pathList.removeAt(index);
|
_pathList.removeAt(index);
|
||||||
_pathStream.add(_pathList);
|
if (_pathList.isEmpty && _ctr.text.trim().isEmpty) {
|
||||||
if (_pathList.isEmpty &&
|
_isEnablePub.value = false;
|
||||||
_ctr.text.replaceAll('\n', '').isEmpty) {
|
|
||||||
_isEnable = false;
|
|
||||||
_isEnableStream.add(false);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Image(
|
child: Image(
|
||||||
height: 75,
|
height: 100,
|
||||||
fit: BoxFit.fitHeight,
|
fit: BoxFit.fitHeight,
|
||||||
filterQuality: FilterQuality.low,
|
filterQuality: FilterQuality.low,
|
||||||
image: FileImage(File(_pathList[index])),
|
image: FileImage(File(_pathList[index])),
|
||||||
@@ -619,11 +734,17 @@ class _CreatePanelState extends State<CreatePanel> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
separatorBuilder: (context, index) => const SizedBox(width: 10),
|
separatorBuilder: (context, index) =>
|
||||||
|
const SizedBox(width: 10),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.paddingOf(context).bottom + 25,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ class _ReplyPageState extends State<ReplyPage>
|
|||||||
autofocus: false,
|
autofocus: false,
|
||||||
readOnly: snapshot.data ?? false,
|
readOnly: snapshot.data ?? false,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
bool isEmpty = value.replaceAll('\n', '').isEmpty;
|
bool isEmpty = value.trim().isEmpty;
|
||||||
if (!isEmpty && !_enablePublish) {
|
if (!isEmpty && !_enablePublish) {
|
||||||
_enablePublish = true;
|
_enablePublish = true;
|
||||||
_publishStream.add(true);
|
_publishStream.add(true);
|
||||||
|
|||||||
@@ -239,8 +239,14 @@ class _WhisperDetailPageState extends State<WhisperDetailPage> {
|
|||||||
|
|
||||||
Widget _buildInputView() {
|
Widget _buildInputView() {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(16),
|
||||||
|
topRight: Radius.circular(16),
|
||||||
|
),
|
||||||
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
@@ -273,7 +279,7 @@ class _WhisperDetailPageState extends State<WhisperDetailPage> {
|
|||||||
minLines: 1,
|
minLines: 1,
|
||||||
maxLines: 4,
|
maxLines: 4,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
bool isNotEmpty = value.replaceAll('\n', '').isNotEmpty;
|
bool isNotEmpty = value.trim().isNotEmpty;
|
||||||
if (isNotEmpty && !_visibleSend) {
|
if (isNotEmpty && !_visibleSend) {
|
||||||
_visibleSend = true;
|
_visibleSend = true;
|
||||||
_enableSend.add(true);
|
_enableSend.add(true);
|
||||||
@@ -289,7 +295,7 @@ class _WhisperDetailPageState extends State<WhisperDetailPage> {
|
|||||||
fillColor: Theme.of(context).colorScheme.surface,
|
fillColor: Theme.of(context).colorScheme.surface,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderSide: BorderSide.none,
|
borderSide: BorderSide.none,
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(6),
|
||||||
gapPadding: 0,
|
gapPadding: 0,
|
||||||
),
|
),
|
||||||
contentPadding: const EdgeInsets.all(10),
|
contentPadding: const EdgeInsets.all(10),
|
||||||
@@ -364,8 +370,7 @@ class _WhisperDetailPageState extends State<WhisperDetailPage> {
|
|||||||
height = max(200, keyboardHeight);
|
height = max(200, keyboardHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
return SizedBox(
|
||||||
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
|
|
||||||
height: height,
|
height: height,
|
||||||
child: EmotePanel(
|
child: EmotePanel(
|
||||||
onChoose: onChooseEmote,
|
onChoose: onChooseEmote,
|
||||||
|
|||||||
Reference in New Issue
Block a user