moc_input 0.0.1
moc_input: ^0.0.1 copied to clipboard
chat input
example/lib/main.dart
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:moc_input/moc_input.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Moc Input Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.indigo,
useMaterial3: true),
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.indigo,
useMaterial3: true),
themeMode: ThemeMode.system,
home: const ChatScreen(),
);
}
}
class ChatScreen extends StatefulWidget {
const ChatScreen({super.key});
@override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final List<String> _messages = [];
bool _sendOnEnter = false;
// --- NEW STATE for the typing indicator ---
bool _isOtherUserTyping = false;
void _addMessage(String message) =>
setState(() => _messages.insert(0, message));
void _handleSendText(String text) => _addMessage("💬 Text: $text");
void _handleSendVoice(String path) =>
_addMessage("🎤 Voice: ${path.split('/').last}");
void _handleSendFile(List<Object> files) {
for (final file in files) {
String fileName;
if (kIsWeb && file is PlatformFile) {
fileName = "📎 Web File: ${file.name} (${file.size} bytes)";
} else if (file is File) {
fileName = "📁 Native File: ${file.path.split('/').last}";
} else {
fileName = "❓ Unknown File";
}
_addMessage(fileName);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Moc Input Demo')),
body: Column(
children: [
SwitchListTile(
title: const Text('Send on Enter'),
subtitle: const Text('(Shift+Enter for new line)'),
value: _sendOnEnter,
onChanged: (bool value) => setState(() => _sendOnEnter = value),
),
const Divider(height: 1),
Expanded(
child: ListView.builder(
reverse: true,
padding: const EdgeInsets.all(8.0),
itemCount: _messages.length,
itemBuilder: (context, index) {
return Align(
alignment: Alignment.centerRight,
child: Container(
margin: const EdgeInsets.symmetric(vertical: 4.0),
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primaryContainer,
borderRadius: BorderRadius.circular(16),
),
child: Text(
_messages[index],
style: TextStyle(
color:
Theme.of(context).colorScheme.onPrimaryContainer),
),
),
);
},
),
),
// --- NEW WIDGET: The typing indicator ---
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
child: Visibility(
visible: _isOtherUserTyping,
child: const Align(
alignment: Alignment.centerLeft,
child: Text(
"User is typing...",
style: TextStyle(
fontStyle: FontStyle.italic,
color: Colors.grey,
),
),
),
),
),
// --- Pass the new callbacks to the ChatInputBar ---
ChatInputBar(
sendOnEnter: _sendOnEnter,
onSendText: _handleSendText,
onSendFile: _handleSendFile,
onSendVoice: _handleSendVoice,
onTypingStart: () {
setState(() {
_isOtherUserTyping = true;
});
},
onTypingEnd: () {
setState(() {
_isOtherUserTyping = false;
});
},
),
],
),
);
}
}