nocterm_bloc 1.0.3 copy "nocterm_bloc: ^1.0.3" to clipboard
nocterm_bloc: ^1.0.3 copied to clipboard

Terminal-friendly Bloc & Cubit helpers for nocterm.dev and related CLI apps.

example/main.dart

import 'package:nocterm/nocterm.dart';
import 'package:nocterm_bloc/nocterm_bloc.dart';

Future<void> main() => runApp(
  NoctermApp(
    home: BlocProvider(
      create: (context) => CounterCubit(),
      child: CounterDemo(),
    ),
  ),
);

class CounterDemo extends StatelessComponent {
  static const maxCount = 20;
  Component build(BuildContext context) {
    return Focusable(
      onKeyEvent: (event) {
        final cubit = context.read<CounterCubit>();
        if (event.logicalKey == LogicalKey.arrowRight) {
          cubit.increment();
          return true;
        }
        if (event.logicalKey == LogicalKey.arrowLeft) {
          cubit.decrement();
          return true;
        }
        if (event.logicalKey == LogicalKey.keyR) {
          cubit.reset();
          return true;
        }
        return false;
      },
      child: BlocListener<CounterCubit, int>(
        listenWhen: (previous, current) => current != previous,
        listener: (context, count) {
          if (count == maxCount) {
            Navigator.of(context)
                .showDialog<bool>(builder: (context) => ConfirmDialogContent())
                .then((value) => context.read<CounterCubit>().reset());
          }
        },
        child: Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const TitleLabel(),
            const SizedBox(height: 1),
            const CounterComponent(),
            const SizedBox(height: 1),
            const ProgressRow(),
            const SizedBox(height: 1),
            const HintsComponent(),
          ],
        ),
      ),
      focused: true,
    );
  }
}

/// A simple component that displays the title of the app.
class TitleLabel extends StatelessComponent {
  const TitleLabel();
  Component build(BuildContext context) {
    return Text(
      '⚡ Counter',
      style: TextStyle(
        fontWeight: FontWeight.bold,
        color: Colors.white,
      ),
    );
  }
}

/// A component that listens to the `CounterCubit` and displays the current count.
class CounterComponent extends StatelessComponent {
  const CounterComponent();
  Component build(BuildContext context) {
    return BlocBuilder<CounterCubit, int>(
      builder: (context, count) {
        return Text(
          '$count',
          style: TextStyle(
            fontWeight: FontWeight.bold,
            color: Colors.cyan,
          ),
        );
      },
    );
  }
}

/// A component that listens to the `CounterCubit` and displays a progress bar based on the current count.
class ProgressRow extends StatelessComponent {
  const ProgressRow();
  Component build(BuildContext context) {
    return BlocBuilder<CounterCubit, int>(
      builder: (context, count) {
        final progress = (count % 20) / 20;
        final barWidth = 30;
        final filled = (progress * barWidth).round();
        return Row(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('▕', style: TextStyle(color: Colors.gray)),
                Text('█' * filled, style: TextStyle(color: Colors.magenta)),
                Text(
                  '░' * (barWidth - filled),
                  style: TextStyle(color: Colors.gray),
                ),
                Text('▏', style: TextStyle(color: Colors.gray)),
              ],
            ),
          ],
        );
      },
    );
  }
}

/// A component that displays hints for the user on how to interact with the app.
class HintsComponent extends StatelessComponent {
  const HintsComponent();
  Component build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Right arrow', style: TextStyle(color: Colors.yellow)),
        Text(' +1  ', style: TextStyle(color: Colors.gray)),
        Text('Left arrow', style: TextStyle(color: Colors.yellow)),
        Text(' -1  ', style: TextStyle(color: Colors.gray)),
        Text('R', style: TextStyle(color: Colors.yellow)),
        Text(' reset', style: TextStyle(color: Colors.gray)),
      ],
    );
  }
}

class ConfirmDialogContent extends StatelessComponent {
  Component build(BuildContext context) {
    final theme = TuiTheme.of(context);
    return Container(
      width: 40,
      height: 7,
      padding: EdgeInsets.all(1),
      decoration: BoxDecoration(
        color: theme.success,
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Text(
            'Max count reached!',
            style: TextStyle(
              color: theme.onSuccess,
              fontWeight: FontWeight.bold,
            ),
          ),
          SizedBox(height: 1),
          Text(
            'Press ESC to close.',
            style: TextStyle(
              color: theme.onSuccess,
              fontWeight: FontWeight.bold,
            ),
          ),
        ],
      ),
    );
  }
}

/// A simple Cubit that manages an integer state representing a counter.
// ignore: prefer_file_naming_conventions
class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0);

  void increment() => emit(state + 1);
  void decrement() => emit(state - 1);
  void reset() => emit(0);
}
1
likes
150
points
127
downloads
screenshot

Publisher

verified publisherzoocityboy.space

Weekly Downloads

Terminal-friendly Bloc & Cubit helpers for nocterm.dev and related CLI apps.

Repository (GitHub)
View/report issues

Topics

#bloc #nocterm #state-management

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

bloc, collection, meta, nocterm

More

Packages that depend on nocterm_bloc