fyral_comms 0.3.3
fyral_comms: ^0.3.3 copied to clipboard
Communication feature package for Fleet Glide Admin
fyral_comms #
A premium, responsive, and interactive messaging and team communication package for Flutter applications. Specifically tailored to handle both mobile and tablet interfaces seamlessly.
Features #
- Fullscreen Interactive Media Viewer (
FullscreenMediaViewer): Tapping any image or video attachment opens a dedicated fullscreen gallery view. Includes pinch-to-zoom and pan viaInteractiveViewer, double-tap quick zoom toggle (1.0x <-> 2.5x), horizontal swipe page navigation (PageView) with dynamic gesture resolution when zoomed, and top toolbar counter (1 of N). Integrates full video playback controls (video_player) with tap-to-play gestures and format detection for network, file, and asset videos. - BlurHash Placeholder Loading: Integrated
flutter_blurhashto render smooth blurred image placeholders (BlurHash) during remote image network requests. - Automatic Video Thumbnail Previews:
MediaGridrenders video frame thumbnails automatically or uses explicit thumbnail URLs (thumbnail_url,thumbnail,poster) with translucent play button badges. - WhatsApp-Style Media Preview (
MediaPreviewPage): Interactive fullscreen preview for selected or captured photos and videos. Includes pinch-to-zoom support, video playback controls with live video frame thumbnails, horizontal swipe gestures (PageView), bottom thumbnail gallery strip, embedded Emoji Picker, and popup attachment actions. - Dual-Source Attachment Picker: Clean popup menu on
MessageBoxsupporting both Camera (ImagePicker) and Gallery (wechat_assets_picker/pickMultipleMedia) with Android 13+ / 14+ runtime permission handling and theme-adaptive upward popups. - Responsive Dual-Pane Split-Screen: Automatically switches to a split-screen view on tablet-sized screens (width $\ge 600\text{px}$ in landscape, or $\ge 900\text{px}$ in portrait). Includes:
- Left navigation sidebar panel showing active conversations.
- Right viewport panel loading detail message logs.
- Integrated WhatsApp-style Replies: Reply card previews are nested cleanly inside the text input pill widget rather than covering the whole screen width, with rounded borders and color contrasts matching light/dark theme modes.
- Dynamic Mentions Suggestions Overlay: Typing
@displays a filtered user list overlay directly above the input container, presenting usernames and initials-based circular avatars. - Rich-text Mentions Highlighting: Automatically colors active mentions in bold orange text both inside sent/received message bubbles and dynamically as you type inside the text input field.
- Dynamic Selection Highlighting: Sidebars highlight selected conversations with matching theme outline borders.
- Unified Gradient Headers: Left and right app bars share matching, beautiful steel-blue gradient backdrops.
- Morphing AI FAB Input Field: Circular Floating Action Button morphs into a full-width input query box at the bottom of the viewport with a fluid shape-morphing size and cross-fade animation.
- Adaptive Layout Adjustments: Conditionally suppresses screen navigation (like back arrows) in tablet views to prevent accidental page pops.
- Full Theme Support: Adapts typography, background colors, and borders automatically to match system light and dark themes.
Getting started #
Add fyral_comms as a dependency in your pubspec.yaml file:
dependencies:
fyral_comms: ^0.3.3
Or run:
flutter pub add fyral_comms
Platform & WeChat Asset Picker Setup #
fyral_comms uses wechat_assets_picker for multi-media gallery picking with WeChat UI aesthetics, alongside image_picker for camera captures. To ensure smooth operation across Android and iOS, configure your host application with the required permissions and localizations:
1. Android Configuration (android/app/src/main/AndroidManifest.xml)
Add the following permissions to your AndroidManifest.xml:
<!-- Storage & Media Permissions -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- Camera Permission for photo captures -->
<uses-permission android:name="android.permission.CAMERA" />
Note: Ensure your
android/app/build.gradlehascompileSdkVersionset to 33 or higher.
2. iOS Configuration (ios/Runner/Info.plist)
Add the permission keys to your Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>Requires photo library access to pick photos and videos to share in conversations.</string>
<key>NSCameraUsageDescription</key>
<string>Requires camera access to capture photos and videos for messaging.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Requires microphone access to record videos with audio.</string>
3. Localization Setup (Recommended)
wechat_assets_picker relies on Flutter's localization system to render gallery UI labels (e.g. "Cancel", "Preview", "Send"). Add flutter_localizations to your pubspec.yaml and configure your MaterialApp:
dependencies:
flutter_localizations:
sdk: flutter
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
// ...
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
// Add additional supported locales as needed
],
);
4. Automatic Fallback Mechanism
If photo library permissions are restricted or denied on Android/iOS, fyral_comms automatically falls back to system photo picker (image_picker / pickMultipleMedia()), ensuring an uninterrupted user experience.
Usage #
Embed the CommsPage inside your application route configuration (e.g. using GoRouter):
import 'package:fyral_comms/comms.dart';
// Use CommsPage in your build widget tree:
@override
Widget build(BuildContext context) {
return const Scaffold(
body: CommsPage(),
);
}
Conversation Detail View #
ConversationDetailPage provides a modular chat details view that supports a hybrid state management pattern.
Uncontrolled Mode (Stateful Fallback)
For quick prototyping, testing, or simple apps, you can instantiate the page with just a title. It will automatically initialize and manage its own messages list, text controllers, focus nodes, emoji pickers, and search states:
ConversationDetailPage(
title: 'Operations Room',
)
Controlled Mode (Stateless Style)
For production applications, or when integrating with state management frameworks like BLoC, Riverpod, or Redux, you can fully drive the page externally by supplying controllers, state values, and event callbacks:
ConversationDetailPage(
title: 'Operations Room',
messages: state.messages,
isSearching: state.isSearching,
searchQuery: state.searchQuery,
showEmojiPicker: state.showEmojiPicker,
messageController: _messageController,
searchController: _searchController,
focusNode: _focusNode,
onSendMessage: () => bloc.add(SendMessageEvent()),
onSearchQueryChanged: (query) => bloc.add(SearchChangedEvent(query)),
onToggleEmojiPicker: () => bloc.add(ToggleEmojiEvent()),
onToggleSearch: () => bloc.add(ToggleSearchEvent()),
onClearSearch: () => bloc.add(ClearSearchEvent()),
onMediaPicked: (List<File> files) => bloc.add(MediaPickedEvent(files)),
onBackPressed: () => Navigator.pop(context),
)
Customization Options
onMediaPicked(ValueChanged<List<File>>?): Callback invoked when media files are selected/captured and confirmed from the preview screen.showMediaPicker(bool?, default:true): Controls visibility of the attachment picker button in the message box.addDemoData(bool, default:true): Iftrue, populates mock demo messages on initialization when in uncontrolled mode. Set tofalseto start with an empty chat log.showAppBar(bool, default:true): Set tofalseto hide the Scaffold's AppBar, allowing you to embed the page inside parent navigators or custom layouts.
Refer to the /example directory for a complete demonstration, including premium custom ThemeData configurations for both light and dark display modes.
Media Preview View (MediaPreviewPage) #
You can launch MediaPreviewPage directly to preview picked photos and videos with captions before sending:
final MediaPreviewResult? result = await Navigator.push<MediaPreviewResult>(
context,
MaterialPageRoute(
builder: (context) => MediaPreviewPage(
filePaths: ['/path/to/image.png', '/path/to/video.mp4'],
initialCaption: 'Check out the site photos',
),
),
);
if (result != null) {
print('Selected files: ${result.filePaths}');
print('Caption: ${result.caption}');
}
Additional information #
- Repository: Find the source code and file issues on GitHub.
- Contributing: Feedback and pull requests are welcome. Feel free to file issues or request enhancements on the repository.