flutter_gen_ai_chat_ui 2.20.0 copy "flutter_gen_ai_chat_ui: ^2.20.0" to clipboard
flutter_gen_ai_chat_ui: ^2.20.0 copied to clipboard

AI chat UI for Flutter. Streaming text, markdown, LaTeX, rich inline widgets, function-calling/agent surface, RTL, theming. ChatGPT/Claude/Gemini ready.

example/lib/main.dart

import 'package:flutter/material.dart';

import 'home_screen.dart';
import 'shell/app_theme.dart';
import 'examples/basic_chat.dart';
import 'examples/streaming_chat.dart';
import 'examples/themed_chat.dart';
import 'examples/actions_chat.dart';
import 'examples/rich_widgets_chat.dart';
import 'examples/rtl_chat.dart';
import 'examples/attachments_chat.dart';
import 'examples/voice_chat.dart';

void main() {
  runApp(const ExampleApp());
}

/// Snappy, uniform page transitions across platforms. The default per-platform
/// builders (notably the slow horizontal slide on web/desktop) made navigating
/// between demos feel sluggish; a short fade reads as instant.
const _fastPageTransitions = PageTransitionsTheme(
  builders: {
    TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
    TargetPlatform.iOS: FadeUpwardsPageTransitionsBuilder(),
    TargetPlatform.macOS: FadeUpwardsPageTransitionsBuilder(),
    TargetPlatform.windows: FadeUpwardsPageTransitionsBuilder(),
    TargetPlatform.linux: FadeUpwardsPageTransitionsBuilder(),
    TargetPlatform.fuchsia: FadeUpwardsPageTransitionsBuilder(),
  },
);

/// Normalizes a route name pushed by the platform (e.g. a browser URL hash
/// change on web) so it can be looked up in the demo route table: strips any
/// query string and fragment, drops trailing slashes (but keeps "/"),
/// lower-cases, and ensures a leading "/".
String _normalizeRouteName(String? name) {
  var normalized = (name == null || name.isEmpty) ? '/' : name;
  final queryIndex = normalized.indexOf('?');
  if (queryIndex >= 0) {
    normalized = normalized.substring(0, queryIndex);
  }
  final fragmentIndex = normalized.indexOf('#');
  if (fragmentIndex >= 0) {
    normalized = normalized.substring(0, fragmentIndex);
  }
  normalized = normalized.toLowerCase();
  if (!normalized.startsWith('/')) {
    normalized = '/$normalized';
  }
  while (normalized.length > 1 && normalized.endsWith('/')) {
    normalized = normalized.substring(0, normalized.length - 1);
  }
  return normalized;
}

class ExampleApp extends StatefulWidget {
  const ExampleApp({super.key});

  @override
  State<ExampleApp> createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  // Follows the system theme until the in-app toggle is used; from then on
  // the manual choice overrides it for the rest of the session.
  ThemeMode _themeMode = ThemeMode.system;

  void _toggleTheme() {
    setState(() {
      final isCurrentlyDark = _themeMode == ThemeMode.dark ||
          (_themeMode == ThemeMode.system &&
              WidgetsBinding.instance.platformDispatcher.platformBrightness ==
                  Brightness.dark);
      _themeMode = isCurrentlyDark ? ThemeMode.light : ThemeMode.dark;
    });
  }

  @override
  Widget build(BuildContext context) {
    final routes = <String, WidgetBuilder>{
      '/basic': (_) => BasicChatExample(onToggleTheme: _toggleTheme),
      '/streaming': (_) => StreamingChatExample(onToggleTheme: _toggleTheme),
      '/themed': (_) => ThemedChatExample(onToggleTheme: _toggleTheme),
      '/actions': (_) => ActionsChatExample(onToggleTheme: _toggleTheme),
      '/rich-widgets': (_) =>
          RichWidgetsChatExample(onToggleTheme: _toggleTheme),
      '/rtl': (_) => RtlChatExample(onToggleTheme: _toggleTheme),
      '/attachments': (_) =>
          AttachmentsChatExample(onToggleTheme: _toggleTheme),
      '/voice': (_) => VoiceChatExample(onToggleTheme: _toggleTheme),
    };
    return MaterialApp(
      title: 'Flutter Gen AI Chat UI',
      debugShowCheckedModeBanner: false,
      themeMode: _themeMode,
      theme: AppTheme.light().copyWith(
        pageTransitionsTheme: _fastPageTransitions,
      ),
      darkTheme: AppTheme.dark().copyWith(
        pageTransitionsTheme: _fastPageTransitions,
      ),
      home: HomeScreen(onToggleTheme: _toggleTheme),
      routes: routes,
      // On web the browser pushes raw URL paths (any case, trailing slash,
      // query string); normalize before looking them up in the route table.
      onGenerateRoute: (settings) {
        final name = _normalizeRouteName(settings.name);
        final builder = routes[name];
        if (builder == null) {
          return null;
        }
        return MaterialPageRoute<void>(
          builder: builder,
          settings: RouteSettings(
            name: name,
            arguments: settings.arguments,
          ),
        );
      },
      // Unknown paths land on home instead of throwing from _onUnknownRoute.
      onUnknownRoute: (settings) => MaterialPageRoute<void>(
        builder: (_) => HomeScreen(onToggleTheme: _toggleTheme),
        settings: settings,
      ),
    );
  }
}
101
likes
160
points
4.18k
downloads
screenshot

Documentation

Documentation
API reference

Publisher

verified publisherdilacode.com

Weekly Downloads

AI chat UI for Flutter. Streaming text, markdown, LaTeX, rich inline widgets, function-calling/agent surface, RTL, theming. ChatGPT/Claude/Gemini ready.

Repository (GitHub)
View/report issues
Contributing

Topics

#ai #chat #llm #streaming #markdown

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

clock, flutter, flutter_markdown_plus, flutter_math_fork, flutter_streaming_text_markdown, google_fonts, markdown, url_launcher

More

Packages that depend on flutter_gen_ai_chat_ui