Skip to content

Instantly share code, notes, and snippets.

@omatt
Created September 10, 2021 04:49

Revisions

  1. omatt created this gist Sep 10, 2021.
    147 changes: 147 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,147 @@
    import 'dart:async';

    import 'package:flutter/material.dart';

    void main() {
    runApp(MyApp());
    }

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    title: 'BloC Demo',
    theme: ThemeData(
    primarySwatch: Colors.blue,
    ),
    home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
    }
    }

    class MyHomePage extends StatefulWidget {
    MyHomePage({Key? key, required this.title}) : super(key: key);

    final String title;

    @override
    _MyHomePageState createState() => _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
    int _counter = 0;

    void _incrementCounter() {
    bloc.fetchUpdatedNumber('${++_counter}');
    // setState(() {
    // _counter++;
    // });
    }

    @override
    Widget build(BuildContext context) {
    return StreamBuilder<bool>(
    stream: bloc.showProgress,
    builder: (BuildContext context, AsyncSnapshot<bool> progressBarData) {
    /// To display/hide LinearProgressBar
    /// call bloc.updateShowProgress(bool)
    var showProgress = false;
    if (progressBarData.hasData && progressBarData.data != null)
    showProgress = progressBarData.data!;
    return Scaffold(
    appBar: AppBar(
    title: Text(widget.title),
    bottom: showProgress
    ? PreferredSize(
    preferredSize: Size(double.infinity, 4.0),
    child: LinearProgressIndicator())
    : null,
    ),
    body: StreamBuilder<String>(
    stream: bloc.updatedNumber,
    builder: (BuildContext context,
    AsyncSnapshot<String> numberSnapshot) {
    var number = '0';
    if (numberSnapshot.hasData && numberSnapshot.data != null)
    number = numberSnapshot.data!;
    return Center(
    child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
    Text(
    'You have pushed the button this many times:',
    ),
    Text(
    '$number',
    style: Theme.of(context).textTheme.headline4,
    ),
    ],
    ),
    );
    }),
    floatingActionButton: FloatingActionButton(
    onPressed: _incrementCounter,
    tooltip: 'Increment',
    child: Icon(Icons.add),
    ),
    );
    });
    }
    }

    class Bloc {
    /// UI updates can be handled in Bloc
    final _repository = Repository();
    final _progressIndicator = StreamController<bool>.broadcast();
    final _updatedNumber = StreamController<String>.broadcast();

    /// StreamBuilder listens to [showProgress] to update UI
    Stream<bool> get showProgress => _progressIndicator.stream;

    Stream<String> get updatedNumber => _updatedNumber.stream;

    updateShowProgress(bool showProgress) {
    _progressIndicator.sink.add(showProgress);
    }

    /// Updates the List<UserThreads> Stream
    fetchUpdatedNumber(String number) async {
    bloc.updateShowProgress(true); // Show ProgressBar

    /// Timer mocks an instance where we're waiting for
    /// a response from the HTTP request
    Timer(Duration(seconds: 2), () async {
    // delay for 4 seconds to display LinearProgressBar
    var updatedNumber = await _repository.fetchUpdatedNumber(number);
    _updatedNumber.sink.add(updatedNumber); // Update Stream
    bloc.updateShowProgress(false); // Hide ProgressBar
    });
    }

    dispose() {
    _updatedNumber.close();
    }

    disposeProgressIndicator() {
    _progressIndicator.close();
    }
    }

    /// this enables Bloc to be globally accessible
    final bloc = Bloc();

    /// Class where we can keep Repositories that can be accessed in Bloc class
    class Repository {
    final provider = Provider();

    Future<String> fetchUpdatedNumber(String number) =>
    provider.updateNumber(number);
    }

    /// Class where all backend tasks can be handled
    class Provider {
    Future<String> updateNumber(String number) async {
    /// HTTP requests can be done here
    return number;
    }
    }