delete direct messages + bug fixes
This commit is contained in:
parent
0c47465d2a
commit
5072704b86
|
|
@ -12,7 +12,7 @@ class ServerDataProvider {
|
||||||
static int labelToTypeId(String label) {
|
static int labelToTypeId(String label) {
|
||||||
if (label.contains('پشتیبانی اپلیکیشن')) {
|
if (label.contains('پشتیبانی اپلیکیشن')) {
|
||||||
return 8;
|
return 8;
|
||||||
} else if (label.contains('پشتیبانی')) {
|
} else if (label.contains('پشتیبانی محتوا')) {
|
||||||
return 7;
|
return 7;
|
||||||
} else {
|
} else {
|
||||||
return directTypes
|
return directTypes
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ class RequestHelper {
|
||||||
static String direct(int id) => _baseDirectUrl + '/$id';
|
static String direct(int id) => _baseDirectUrl + '/$id';
|
||||||
static String sendDirectMessage(int id) =>
|
static String sendDirectMessage(int id) =>
|
||||||
_baseDirectUrl + '/$id/sendMessage';
|
_baseDirectUrl + '/$id/sendMessage';
|
||||||
|
static String deleteDirect(int id, int messageId) =>
|
||||||
|
_baseDirectUrl + '/$id/message/$messageId';
|
||||||
static String tag({
|
static String tag({
|
||||||
required List<int> ids,
|
required List<int> ids,
|
||||||
String? type,
|
String? type,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/constants/assets.dart';
|
import 'package:didvan/constants/assets.dart';
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
import 'package:didvan/models/view/app_bar_data.dart';
|
import 'package:didvan/models/view/app_bar_data.dart';
|
||||||
|
|
@ -6,7 +7,9 @@ import 'package:didvan/services/media/media.dart';
|
||||||
import 'package:didvan/views/home/direct/direct_state.dart';
|
import 'package:didvan/views/home/direct/direct_state.dart';
|
||||||
import 'package:didvan/views/home/direct/widgets/message.dart';
|
import 'package:didvan/views/home/direct/widgets/message.dart';
|
||||||
import 'package:didvan/views/home/direct/widgets/message_box.dart';
|
import 'package:didvan/views/home/direct/widgets/message_box.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
|
import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
@ -52,11 +55,12 @@ class _DirectState extends State<Direct> {
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: DidvanScaffold(
|
child: DidvanScaffold(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
reverse: true,
|
reverse: true,
|
||||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
appBarData: AppBarData(
|
appBarData: AppBarData(
|
||||||
hasBack: true,
|
hasBack: true,
|
||||||
subtitle: widget.pageData['type'] == null
|
subtitle: widget.pageData['type'].contains('پشتیبانی')
|
||||||
? null
|
? null
|
||||||
: 'ارتباط با سردبیر',
|
: 'ارتباط با سردبیر',
|
||||||
title: widget.pageData['type'] ?? 'پشتیبانی اپلیکیشن',
|
title: widget.pageData['type'] ?? 'پشتیبانی اپلیکیشن',
|
||||||
|
|
@ -105,6 +109,43 @@ class _DirectState extends State<Direct> {
|
||||||
left: 0,
|
left: 0,
|
||||||
child: const MessageBox(),
|
child: const MessageBox(),
|
||||||
),
|
),
|
||||||
|
if (state.deletionQueue.isNotEmpty)
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: d.padding.top,
|
||||||
|
child: Container(
|
||||||
|
height: 72,
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
DidvanIconButton(
|
||||||
|
icon: DidvanIcons.close_solid,
|
||||||
|
size: 32,
|
||||||
|
gestureSize: 48,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
onPressed: () {
|
||||||
|
state.deletionQueue.clear();
|
||||||
|
state.update();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
DidvanText(
|
||||||
|
'${state.deletionQueue.length} مورد انتخاب شد',
|
||||||
|
style: Theme.of(context).textTheme.subtitle1,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
DidvanIconButton(
|
||||||
|
icon: DidvanIcons.trash_solid,
|
||||||
|
size: 32,
|
||||||
|
gestureSize: 48,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
onPressed: state.delete,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class DirectState extends CoreProvier {
|
||||||
final List<MessageData> messages = [];
|
final List<MessageData> messages = [];
|
||||||
late final int typeId;
|
late final int typeId;
|
||||||
final Map<String, List<int>> dailyMessages = {};
|
final Map<String, List<int>> dailyMessages = {};
|
||||||
|
final List<int> deletionQueue = [];
|
||||||
|
|
||||||
String? text;
|
String? text;
|
||||||
RadarAttachment? replyRadar;
|
RadarAttachment? replyRadar;
|
||||||
|
|
@ -77,6 +78,18 @@ class DirectState extends CoreProvier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delete() {
|
||||||
|
for (var i = 0; i < deletionQueue.length; i++) {
|
||||||
|
final service = RequestService(
|
||||||
|
RequestHelper.deleteDirect(typeId, deletionQueue[i]),
|
||||||
|
);
|
||||||
|
service.delete();
|
||||||
|
messages.removeWhere((element) => element.id == deletionQueue[i]);
|
||||||
|
}
|
||||||
|
deletionQueue.clear();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
void _addToDailyGrouped(MessageData message) {
|
void _addToDailyGrouped(MessageData message) {
|
||||||
String createdAt = message.createdAt.replaceAll('T', ' ').split(' ').first;
|
String createdAt = message.createdAt.replaceAll('T', ' ').split(' ').first;
|
||||||
if (!dailyMessages.containsKey(createdAt)) {
|
if (!dailyMessages.containsKey(createdAt)) {
|
||||||
|
|
|
||||||
|
|
@ -20,24 +20,24 @@ class AudioWidget extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StreamBuilder<bool>(
|
return Row(
|
||||||
stream: MediaService.audioPlayer.isPlaying,
|
children: [
|
||||||
builder: (context, snapshot) {
|
Expanded(
|
||||||
return Row(
|
child: AudioSlider(
|
||||||
children: [
|
tag: 'message-$id',
|
||||||
Expanded(
|
),
|
||||||
child: AudioSlider(
|
),
|
||||||
tag: 'message-$id',
|
StreamBuilder<bool>(
|
||||||
),
|
stream: MediaService.audioPlayer.isPlaying,
|
||||||
),
|
builder: (context, snapshot) {
|
||||||
_AudioControllerButton(
|
return _AudioControllerButton(
|
||||||
audioFile: audioFile,
|
audioFile: audioFile,
|
||||||
audioUrl: audioUrl,
|
audioUrl: audioUrl,
|
||||||
id: id,
|
id: id,
|
||||||
),
|
);
|
||||||
],
|
},
|
||||||
);
|
),
|
||||||
},
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,85 +18,109 @@ class Message extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final firstMessageOfGroupId = context
|
final state = context.read<DirectState>();
|
||||||
.read<DirectState>()
|
final firstMessageOfGroupId = state
|
||||||
.dailyMessages[message.createdAt.replaceAll('T', ' ').split(' ').first]!
|
.dailyMessages[message.createdAt.replaceAll('T', ' ').split(' ').first]!
|
||||||
.last;
|
.last;
|
||||||
return Column(
|
return GestureDetector(
|
||||||
crossAxisAlignment: message.writedByAdmin
|
onLongPress: () {
|
||||||
? CrossAxisAlignment.end
|
if (state.deletionQueue.contains(message.id) || message.writedByAdmin) {
|
||||||
: CrossAxisAlignment.start,
|
return;
|
||||||
children: [
|
}
|
||||||
if (message.id == firstMessageOfGroupId)
|
state.deletionQueue.add(message.id);
|
||||||
Center(
|
state.update();
|
||||||
child: Container(
|
},
|
||||||
margin: const EdgeInsets.only(bottom: 12),
|
onTap: () {
|
||||||
padding: const EdgeInsets.all(4),
|
if (state.deletionQueue.isEmpty || message.writedByAdmin) return;
|
||||||
decoration: BoxDecoration(
|
if (!state.deletionQueue.contains(message.id)) {
|
||||||
color: Theme.of(context).colorScheme.splash,
|
state.deletionQueue.add(message.id);
|
||||||
borderRadius: DesignConfig.lowBorderRadius,
|
} else {
|
||||||
),
|
state.deletionQueue.remove(message.id);
|
||||||
child: DidvanText(
|
}
|
||||||
DateTime.parse(message.createdAt).toPersianDateStr(),
|
state.update();
|
||||||
style: Theme.of(context).textTheme.overline,
|
},
|
||||||
color: DesignConfig.isDark
|
child: Container(
|
||||||
? Theme.of(context).colorScheme.white
|
color: state.deletionQueue.contains(message.id)
|
||||||
: Theme.of(context).colorScheme.black,
|
? Theme.of(context).colorScheme.secondaryDisabled.withOpacity(0.5)
|
||||||
),
|
: null,
|
||||||
),
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
),
|
child: Column(
|
||||||
Padding(
|
crossAxisAlignment: message.writedByAdmin
|
||||||
padding: EdgeInsets.only(
|
? CrossAxisAlignment.end
|
||||||
right: message.writedByAdmin ? 20 : 0,
|
: CrossAxisAlignment.start,
|
||||||
left: !message.writedByAdmin ? 20 : 0,
|
children: [
|
||||||
),
|
if (message.id == firstMessageOfGroupId)
|
||||||
child: Column(
|
Center(
|
||||||
crossAxisAlignment: message.writedByAdmin
|
child: Container(
|
||||||
? CrossAxisAlignment.start
|
margin: const EdgeInsets.only(bottom: 12),
|
||||||
: CrossAxisAlignment.end,
|
padding: const EdgeInsets.all(4),
|
||||||
children: [
|
decoration: BoxDecoration(
|
||||||
_MessageContainer(
|
color: Theme.of(context).colorScheme.splash,
|
||||||
writedByAdmin: message.writedByAdmin,
|
borderRadius: DesignConfig.lowBorderRadius,
|
||||||
child: Column(
|
),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: DidvanText(
|
||||||
children: [
|
DateTime.parse(message.createdAt).toPersianDateStr(),
|
||||||
if (message.text != null) DidvanText(message.text!),
|
style: Theme.of(context).textTheme.overline,
|
||||||
if (message.audio != null || message.audioFile != null)
|
color: DesignConfig.isDark
|
||||||
AudioWidget(
|
? Theme.of(context).colorScheme.white
|
||||||
audioFile: message.audioFile,
|
: Theme.of(context).colorScheme.black,
|
||||||
audioUrl: message.audio,
|
),
|
||||||
id: message.id,
|
|
||||||
),
|
|
||||||
if (message.radar != null) const DidvanDivider(),
|
|
||||||
if (message.radar != null) const SizedBox(height: 4),
|
|
||||||
if (message.radar != null)
|
|
||||||
_ReplyRadarOverview(message: message),
|
|
||||||
if (message.radar != null) const SizedBox(height: 4),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
Padding(
|
||||||
Row(
|
padding: EdgeInsets.only(
|
||||||
mainAxisSize: MainAxisSize.min,
|
right: message.writedByAdmin ? 20 : 0,
|
||||||
|
left: !message.writedByAdmin ? 20 : 0,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: message.writedByAdmin
|
||||||
|
? CrossAxisAlignment.start
|
||||||
|
: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
DidvanText(
|
_MessageContainer(
|
||||||
DateTimeUtils.timeWithAmPm(message.createdAt),
|
writedByAdmin: message.writedByAdmin,
|
||||||
style: Theme.of(context).textTheme.overline,
|
child: Column(
|
||||||
color: Theme.of(context).colorScheme.caption,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (message.text != null) DidvanText(message.text!),
|
||||||
|
if (message.audio != null || message.audioFile != null)
|
||||||
|
AudioWidget(
|
||||||
|
audioFile: message.audioFile,
|
||||||
|
audioUrl: message.audio,
|
||||||
|
id: message.id,
|
||||||
|
),
|
||||||
|
if (message.radar != null) const DidvanDivider(),
|
||||||
|
if (message.radar != null) const SizedBox(height: 4),
|
||||||
|
if (message.radar != null)
|
||||||
|
_ReplyRadarOverview(message: message),
|
||||||
|
if (message.radar != null) const SizedBox(height: 4),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
DidvanText(
|
||||||
|
DateTimeUtils.timeWithAmPm(message.createdAt),
|
||||||
|
style: Theme.of(context).textTheme.overline,
|
||||||
|
color: Theme.of(context).colorScheme.caption,
|
||||||
|
),
|
||||||
|
if (!message.writedByAdmin)
|
||||||
|
Icon(
|
||||||
|
message.readed
|
||||||
|
? DidvanIcons.check_double_light
|
||||||
|
: DidvanIcons.check_light,
|
||||||
|
size: 16,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
if (!message.writedByAdmin)
|
|
||||||
Icon(
|
|
||||||
message.readed
|
|
||||||
? DidvanIcons.check_double_light
|
|
||||||
: DidvanIcons.check_light,
|
|
||||||
size: 16,
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +201,10 @@ class _MessageContainer extends StatelessWidget {
|
||||||
bottomLeft: writedByAdmin ? Radius.zero : null,
|
bottomLeft: writedByAdmin ? Radius.zero : null,
|
||||||
bottomRight: !writedByAdmin ? Radius.zero : null,
|
bottomRight: !writedByAdmin ? Radius.zero : null,
|
||||||
),
|
),
|
||||||
color: writedByAdmin ? null : Theme.of(context).colorScheme.focused,
|
color: (writedByAdmin
|
||||||
|
? Theme.of(context).colorScheme.surface
|
||||||
|
: Theme.of(context).colorScheme.focused)
|
||||||
|
.withOpacity(0.9),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Theme.of(context).colorScheme.border,
|
color: Theme.of(context).colorScheme.border,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue