This app serves the purpose of staying up-to-date with the latest changes across Dart and Flutter ecosystem. The way this app works is by fetching markdowns from Dart and Flutter's official Github repo via REST API and rendering the information in a WebView
widget.
- Display Dart CHANGELOG
- Display Flutter What's New
- Display Flutter Release Notes
- Offline Support
The app follows a simple but effective architecture. It relies on a feature-driven architecture with some sub-features.
Inside lib/features/ directory, you can find two sub-features: detail
and home
.
The home sub-feature is responsible for showing a scaffold with a bottom navigation bar. It also contains logic for maintaining bottom navigation bar's state.
The detail feature is divided into two sub-features: dart_detail and flutter_detail. Each of these sub-features has similar structure and is divided into three layers.
- Application Layer: Contains state management logic and acts as a mediator between the presentation and the data layer.
- Data Layer: Responsible for making all the necessary API calls and local cache operations.
- Presentation Layer: Associated with the UI
To check the fpdart
implementation, consider taking a look at the data
layer of each of the sub-features.
The project uses flutter_bloc for managing the app's state.
The app stores fetched data locally on user's device for offline support. The project uses the latest isar plugin for local storage.
The unit test has been written based on the fpdart
refactoring and can be found in the test directory.
The project makes use of few third-party packages for rapid development. Some of them are listed below:
- dio (To perform network calls)
- equatable (To achieve value equality)
- flash (To display customizable toast)
- flutter_bloc (State Management)
- fpdart (Functional Programming)
- isar (Local Storage)
- url_launcher (To display information from hyperlinks in a browser interface within the app)
- webview_flutter (To display markdowns)
- mocktail (As a mocking library)
TaskEither
: Used instead ofFuture
to make async request that may failIOEither
: Used to represent a synchronous computation that may failDo
Notation: Used to write functional code that looks like normal imperative code and to avoid methods chaining