Приложение на флаторе, настройки

This commit is contained in:
Халимов Рустам
2026-05-13 17:21:37 +03:00
parent 89e325556c
commit e8161d23d4
119 changed files with 18469 additions and 0 deletions
@@ -0,0 +1,23 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'chat_event.dart';
import 'chat_state.dart';
class ChatBloc extends Bloc<ChatEvent, ChatState> {
ChatBloc() : super(const ChatState.initial()) {
on<ChatEventStarted>(_onStarted);
on<ChatEventChatsLoaded>(_onChatsLoaded);
on<ChatEventChatSelected>(_onChatSelected);
on<ChatEventMessagesRequested>(_onMessagesRequested);
on<ChatEventMessageSent>(_onMessageSent);
}
Future<void> _onStarted(ChatEventStarted event, emit) async {
emit(const ChatState.loading());
emit(const ChatState.chatsLoaded([]));
}
Future<void> _onChatsLoaded(ChatEventChatsLoaded event, emit) async {}
Future<void> _onChatSelected(ChatEventChatSelected event, emit) async {}
Future<void> _onMessagesRequested(ChatEventMessagesRequested event, emit) async {}
Future<void> _onMessageSent(ChatEventMessageSent event, emit) async {}
}
@@ -0,0 +1,14 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_event.freezed.dart';
@freezed
class ChatEvent with _$ChatEvent {
const factory ChatEvent.started() = ChatEventStarted;
const factory ChatEvent.chatsLoaded() = ChatEventChatsLoaded;
const factory ChatEvent.chatSelected(String chatId) = ChatEventChatSelected;
const factory ChatEvent.messagesRequested(String chatId, {String? lastMessageId}) = ChatEventMessagesRequested;
const factory ChatEvent.messageSent(String chatId, String content) = ChatEventMessageSent;
const factory ChatEvent.messageRead(String chatId, String messageId) = ChatEventMessageRead;
const factory ChatEvent.chatCreated(String title, List<String> participantIds) = ChatEventChatCreated;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,14 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_state.freezed.dart';
@freezed
class ChatState with _$ChatState {
const factory ChatState.initial() = ChatInitial;
const factory ChatState.loading() = ChatLoading;
const factory ChatState.chatsLoaded(List<dynamic> chats) = _ChatsLoaded;
const factory ChatState.chatSelected(String chat, List<dynamic> messages) = _ChatSelected;
const factory ChatState.messagesLoaded(List<dynamic> messages) = _MessagesLoaded;
const factory ChatState.messageSent() = _MessageSent;
const factory ChatState.error(String message) = ChatError;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,105 @@
import 'package:flutter/material.dart';
class ChatDetailPage extends StatefulWidget {
final String chatId;
final String chatTitle;
const ChatDetailPage({
super.key,
required this.chatId,
required this.chatTitle,
});
@override
State<ChatDetailPage> createState() => _ChatDetailPageState();
}
class _ChatDetailPageState extends State<ChatDetailPage> {
final _messageController = TextEditingController();
@override
void dispose() {
_messageController.dispose();
super.dispose();
}
void _sendMessage() {
if (_messageController.text.trim().isEmpty) return;
_messageController.clear();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.chatTitle),
),
body: const Center(child: Text('Chat Detail')),
bottomNavigationBar: _MessageInput(
controller: _messageController,
onSend: _sendMessage,
),
);
}
}
class _MessageInput extends StatelessWidget {
final TextEditingController controller;
final VoidCallback onSend;
const _MessageInput({
required this.controller,
required this.onSend,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 4,
offset: const Offset(0, -2),
),
],
),
child: Row(
children: [
IconButton(
icon: const Icon(Icons.attach_file),
onPressed: () {},
),
Expanded(
child: TextField(
controller: controller,
decoration: InputDecoration(
hintText: 'Сообщение',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(24),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Colors.grey[200],
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
),
maxLines: null,
onSubmitted: (_) => onSend(),
),
),
const SizedBox(width: 8),
IconButton(
icon: const Icon(Icons.send),
color: Theme.of(context).primaryColor,
onPressed: onSend,
),
],
),
);
}
}
@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../bloc/chat_bloc.dart';
import '../bloc/chat_state.dart';
class ChatsPage extends StatelessWidget {
const ChatsPage({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<ChatBloc, ChatState>(
builder: (context, state) {
return state.when(
initial: () => const Center(child: CircularProgressIndicator()),
loading: () => const Center(child: CircularProgressIndicator()),
chatsLoaded: (_) => const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.chat_bubble_outline, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text('У вас пока нет чатов'),
],
),
),
chatSelected: (_, __) => const Center(child: Text('Chat selected')),
messagesLoaded: (_) => const Center(child: Text('Messages loaded')),
messageSent: () => const Center(child: Text('Message sent')),
error: (message) => Center(child: Text('Ошибка: $message')),
);
},
);
}
}