Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,6 @@ class ConversationBloc extends Bloc<ConversationEvent, ConversationState> {
on<_ConversationUpdated>(
_onConversationUpdated,
);
on<ConversationDeleted>(
_onConversationDeleted,
);
on<TypingStatusStartReceived>(
_onTypingStatusStartReceived,
transformer: typingThrottleDroppable(),
Expand Down Expand Up @@ -358,13 +355,6 @@ class ConversationBloc extends Bloc<ConversationEvent, ConversationState> {
emit(state.copyWith(conversation: event.conversation));
}

Future<void> _onConversationDeleted(
ConversationDeleted event, Emitter<ConversationState> emit) async {
await conversationRepository.deleteConversation(state.conversation)
? emit(state.copyWith(status: ConversationStatus.delete))
: emit(state.copyWith(status: ConversationStatus.failure));
}

Future<void> _onTypingStatusStartReceived(
TypingStatusStartReceived event, Emitter<ConversationState> emit) async {
var user = await userRepository.getUserById(event.from);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ final class _ConversationUpdated extends ConversationEvent {
const _ConversationUpdated(this.conversation);
}

final class ConversationDeleted extends ConversationEvent {
const ConversationDeleted();
}

final class TypingStatusStartReceived extends ConversationEvent {
final String from;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
part of 'conversation_bloc.dart';

enum ConversationStatus { initial, success, failure, delete }
enum ConversationStatus { initial, success, failure }

class TypingMessageStatus {
final TypingState typingState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import '../../../shared/ui/colors.dart';
import '../../../shared/utils/string_utils.dart';
import '../../../shared/widget/loaders.dart';
import '../../../shared/widget/typing_indicator.dart';
import '../../conversation_delete/bloc/conversation_delete_bloc.dart';
import '../../group_info/view/group_info_page.dart';
import '../bloc/ai_message/ai_message_bloc.dart';
import '../bloc/conversation_bloc.dart';
Expand Down Expand Up @@ -65,6 +66,12 @@ class ConversationPage extends StatelessWidget {
RepositoryProvider.of<MessagesRepository>(context),
),
),
BlocProvider(
create: (context) => ConversationDeleteBloc(
conversationRepository:
RepositoryProvider.of<ConversationRepository>(context),
),
),
BlocProvider(
create: (context) => MediaAttachmentBloc(
attachmentsRepository:
Expand All @@ -80,78 +87,102 @@ class ConversationPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlocBuilder<ConversationBloc, ConversationState>(
buildWhen: (previous, current) => previous.choose != current.choose,
builder: (BuildContext context, state) {
return PopScope(
onPopInvokedWithResult: (didPop, result) {
if (didPop) return;
context
.read<ConversationBloc>()
.add(const SelectMessagesMode(false));
},
canPop: !state.choose,
child: Scaffold(
appBar: AppBar(
toolbarHeight: 64,
centerTitle: false,
titleSpacing: 0.0,
backgroundColor: smokyBorough,
surfaceTintColor: Colors.transparent,
title: BlocBuilder<AiMessageBloc, AiMessageState>(
builder: (BuildContext context, aiState) {
return aiState.status == AiMessageStatus.processing
? const TitleLoader(
black,
Text('AI processing',
style: TextStyle(color: black, fontSize: 20.0)))
: ConnectionTitle(
color: black,
title: title,
);
}),
actions: [_PopupMenuButton()],
),
body: Column(
children: [
BlocListener<ConnectionBloc, ConnectionState>(
listener: (context, state) {
if (state.status == ConnectionStatus.connected) {
BlocProvider.of<ConversationBloc>(context)
.add(const MessagesRequested(refresh: true));
}
},
child: const Flexible(child: MessagesList())),
SafeArea(
child: !state.choose
? context.read<SharingIntentBloc>().state.status ==
SharingIntentStatus.processing
? BlocListener<SendMessageBloc,
SendMessageState>(
listener: (context, sendState) {
if (sendState.status ==
SendMessageStatus.success ||
sendState.status ==
SendMessageStatus.failure) {
context
return BlocListener<ConversationDeleteBloc, ConversationDeleteState>(
listener: (context, state) {
switch (state.status) {
case ConversationDeleteStatus.initial:
break;
case ConversationDeleteStatus.success:
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.popUntil(context, (route) => route.isFirst);
});
break;
case ConversationDeleteStatus.failure:
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(
SnackBar(
duration: const Duration(seconds: 3),
content: Text(state.errorMessage ?? '')),
);
}
},
child: BlocBuilder<ConversationBloc, ConversationState>(
buildWhen: (previous, current) => previous.choose != current.choose,
builder: (BuildContext context, state) {
return PopScope(
onPopInvokedWithResult: (didPop, result) {
if (didPop) return;
context
.read<ConversationBloc>()
.add(const SelectMessagesMode(false));
},
canPop: !state.choose,
child: Scaffold(
appBar: AppBar(
toolbarHeight: 64,
centerTitle: false,
titleSpacing: 0.0,
backgroundColor: smokyBorough,
surfaceTintColor: Colors.transparent,
title: BlocBuilder<AiMessageBloc, AiMessageState>(
builder: (BuildContext context, aiState) {
return aiState.status == AiMessageStatus.processing
? const TitleLoader(
black,
Text('AI processing',
style: TextStyle(
color: black, fontSize: 20.0)))
: ConnectionTitle(
color: black,
title: title,
);
}),
actions: [_PopupMenuButton()],
),
body: Column(
children: [
BlocListener<ConnectionBloc, ConnectionState>(
listener: (context, state) {
if (state.status == ConnectionStatus.connected) {
BlocProvider.of<ConversationBloc>(context).add(
const MessagesRequested(refresh: true));
}
},
child: const Flexible(child: MessagesList())),
SafeArea(
child: !state.choose
? context
.read<SharingIntentBloc>()
.add(SharingIntentCompleted());
}
},
child: ConnectionChecker(
child: MessageInput(
sharedMessage: context
.state
.status ==
SharingIntentStatus.processing
? BlocListener<SendMessageBloc,
SendMessageState>(
listener: (context, sendState) {
if (sendState.status ==
SendMessageStatus.success ||
sendState.status ==
SendMessageStatus.failure) {
context
.read<SharingIntentBloc>()
.state
.sharedFiles
.firstOrNull)),
)
: const MessageInput()
: const SelectInput())
],
),
));
});
.add(SharingIntentCompleted());
}
},
child: ConnectionChecker(
child: MessageInput(
sharedMessage: context
.read<SharingIntentBloc>()
.state
.sharedFiles
.firstOrNull)),
)
: const MessageInput()
: const SelectInput())
],
),
));
}));
}

Widget get title => BlocBuilder<ConversationBloc, ConversationState>(
Expand Down Expand Up @@ -271,9 +302,13 @@ class _PopupMenuButton extends StatelessWidget {
context
.read<SendMessageBloc>()
.add(const TextMessageClear());
context
.read<ConversationBloc>()
.add(const ConversationDeleted());
context.read<ConversationDeleteBloc>().add(
ConversationDeleted(
chat: context
.read<ConversationBloc>()
.state
.conversation));
Navigator.of(context).pop();
},
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,6 @@ class _MessagesListState extends State<MessagesList> {
});
case ConversationStatus.initial:
return const Center(child: CircularProgressIndicator());
case ConversationStatus.delete:
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.popUntil(context, (route) => route.isFirst);
});
return const SizedBox.shrink();
}
},
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import '../../../repository/conversation/conversation_repository.dart';
import '../../../db/models/conversation_model.dart';

part 'conversation_delete_event.dart';

part 'conversation_delete_state.dart';

class ConversationDeleteBloc
extends Bloc<ConversationDeleteEvent, ConversationDeleteState> {
ConversationDeleteBloc({required this.conversationRepository})
: super(const ConversationDeleteState()) {
on<ConversationDeleted>(_onConversationDeleted);
}

final ConversationRepository conversationRepository;

Future<void> _onConversationDeleted(
ConversationDeleted event,
Emitter<ConversationDeleteState> emit,
) async {
await conversationRepository.deleteConversation(event.chat)
? emit(state.copyWith(status: ConversationDeleteStatus.success))
: emit(state.copyWith(
status: ConversationDeleteStatus.failure,
errorMessage: 'Failed to delete conversation.'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
part of 'conversation_delete_bloc.dart';

sealed class ConversationDeleteEvent extends Equatable {
const ConversationDeleteEvent();

@override
List<Object> get props => [];
}

final class ConversationDeleted extends ConversationDeleteEvent {
const ConversationDeleted({required this.chat});

final ConversationModel chat;

@override
List<Object> get props => [chat];

@override
String toString() => 'ConversationDeleted { chat: $chat }';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
part of 'conversation_delete_bloc.dart';

enum ConversationDeleteStatus { initial, success, failure }

final class ConversationDeleteState extends Equatable {
const ConversationDeleteState({
this.status = ConversationDeleteStatus.initial,
this.errorMessage,
this.informationMessage,
});

final ConversationDeleteStatus status;
final String? errorMessage;
final String? informationMessage;

ConversationDeleteState copyWith({
ConversationDeleteStatus? status,
String? errorMessage,
String? informationMessage,
}) {
return ConversationDeleteState(
status: status ?? this.status,
errorMessage: errorMessage ?? this.errorMessage,
informationMessage: informationMessage ?? this.informationMessage,
);
}

@override
List<Object?> get props => [status, errorMessage, informationMessage];
}
Loading