Skip to content

Commit

Permalink
refactor: breaking changes in code and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
luisburgos committed Jun 29, 2022
1 parent 3d5e66f commit 3b680e0
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 195 deletions.
65 changes: 55 additions & 10 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,61 @@
# example
# Example

A new Flutter project.
# Architecture Components

## Getting Started
## Overview

This project is a starting point for a Flutter application.
- `UiComponent` lives inside a `ViewTemplate`
- A `ViewTemplate` exposes `Callbacks`, `ViewBuilders`, `Configs` and `attributes`
- A `Callback`
- A`View` use a `ViewTemplate`
- A `Page`uses a `ViewTemplate` to bind the `StateHolder`, examples are `ViewController` or `ViewModel`
- A `StateHolder`
- Listens to data streams from `Repositories` in a read-only mode
- Exposes processed and filtered information for the `Page` to inject into the `View`.
- Could listen to `AppEvents` and request more `Commands` execution. For example using the `NavigationCommand` or the `FeedbackCommand` should be common here.
- A `StateHolder` transform `UiEvents` (user interactions requesting something to our app) to `UseCase` execution requests.
- A `UseCaseCommand` or `Command` represents the message to request business logic execution to start.
- A `CommandHandler` is the executioner of the business logic.
- It has access to `Repositories` to call WRITE async methods and wait for results to update all
the `DataProviders` supported by the `Repository`. For example, update local cache strategies or calling API services (which could be different if the use case requires it).
- A `CommandHandler` emits `AppEvents` which can be listen by `StateHolders`.
- **Q:** Should the `CommandHandler` orchestrate saving data to a cache? Or should this be taken care by the `Repository`. Maybe the `Repository` is our champion approach.
- A `Repository` is a facade for `DataProviders` or `DataSources`.
- The `Repository` handles data providers administration.
- `SmartReposities` also handles `Cache`, `Schedulers`, `Queues` implementations to provide more complex logic for data access.

A few resources to get you started if this is your first Flutter project:
**TODO:**

- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
- [ ] Change Page to Screen?
- [ ] Find a way to justify having Page -> View (ViewTemplate + StateHolder) maybe eventually Page = View + PageController where the controller can access to feature flags.

For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
---
From Atomic Design guides:
- ViewTemplate consist mostly of groups of UiComponent stitched together to form pages.
- Pages are specific instances of templates

## Presentation


## Domain

- `UseCaseCommand`
- Generated from a `StateHolder` component
- `UseCaseCommandHandler`
- Fires `AppEvents`

## Data

## Architecture Components Checklist

### Base Files

- I have a `template.dart`
- I have a `view.dart`
- I have a `screen.dart` or `page.dart`
- I have a `routes.dart`

### Nested Features

- A `feature` has its own folder with the name of the feature. Following dart packages conventions.
- A `feature` folder uses the same naming convention of the section #base-files
4 changes: 2 additions & 2 deletions example/core/lib/named_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class MainAction {
final Function()? onPressed;
}

class NamedPage extends StatelessWidget {
const NamedPage({
class BasePage extends StatelessWidget {
const BasePage({
Key? key,
required this.name,
this.action,
Expand Down
3 changes: 2 additions & 1 deletion example/lib/get/get_main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ void main() {
),
GetPage(
name: AppRoutes.profileRoot,
page: () => ProfilePage(
page: () => ProfileScreen(
onBackToHomePressed: () {
Get.find<IBuzzBase>().fire(
NavigateBackCommand(),
);
},
//TODO: Validate stream being injected here.
profileStream: Get.find<IProfileRepository>().profileStateChanges,
),
),
Expand Down
4 changes: 1 addition & 3 deletions example/lib/modular/profile_module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ class ProfileModule extends Module {
List<ModularRoute> get routes => [
ChildRoute(
AppRoutes.profileRoot,
child: (context, args) => ProfilePage(
child: (context, args) => ProfileScreen(
onBackToHomePressed: () {
Modular.get<IBuzzBase>().fire(
NavigateBackCommand(),
);
},
profileStream:
Modular.get<IProfileRepository>().profileStateChanges,
),
),
];
Expand Down
2 changes: 1 addition & 1 deletion example/lib/shared/modules/home/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class HomePage extends StatelessWidget {

@override
Widget build(BuildContext context) {
return NamedPage(
return BasePage(
name: 'Home',
action: MainAction(
label: 'Go Profile',
Expand Down
2 changes: 1 addition & 1 deletion example/lib/shared/not_found_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class NotFoundPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
return NamedPage(
return BasePage(
name: 'Not Found',
action: MainAction(
label: 'Go Home',
Expand Down
32 changes: 11 additions & 21 deletions example/profile/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
<!--
This README describes the package. If you publish this package to pub.dev,
this README's contents appear on the landing page for your package.
For information about how to write a good package README, see the guide for
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
For general information about developing packages, see the Dart guide for
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
and the Flutter guide for
[developing packages and plugins](https://flutter.dev/developing-packages).
-->

TODO: Put a short description of the package here that helps potential users
know whether this package might be useful for them.

## Features

TODO: List what your package can do. Maybe include images, gifs, or videos.
Expand All @@ -25,12 +9,18 @@ start using the package.

## Usage

TODO: Include short and useful examples for package users. Add longer examples
to `/example` folder.
### Commands

- `ChangeUserNameCommand`
- `??`

### Entities

- `??`
- `??`


```dart
const like = 'sample';
```
The ViewTemplate

## Additional information

Expand Down
66 changes: 0 additions & 66 deletions example/profile/lib/presentation/page.dart

This file was deleted.

16 changes: 16 additions & 0 deletions example/profile/lib/presentation/screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
import 'package:profile/presentation/view.dart';

class ProfileScreen extends StatelessWidget {
const ProfileScreen({
Key? key,
required this.onBackToHomePressed,
}) : super(key: key);

final Function() onBackToHomePressed;

@override
Widget build(BuildContext context) {
return const ProfileView();
}
}
127 changes: 39 additions & 88 deletions example/profile/lib/presentation/view.dart
Original file line number Diff line number Diff line change
@@ -1,99 +1,50 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../profile.dart';
import 'view_controller.dart';
import 'view_template.dart';

class ProfileView extends StatelessWidget {
const ProfileView({
Key? key,
required this.userName,
required this.items,
required this.onItemTap,
}) : super(key: key);

final String userName;
final List<ProfileOption> items;
final Function(String) onItemTap;
const ProfileView({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Column(
children: [
_ProfileHeader(userName: userName),
_ProfileOptionsList(
items: items,
onItemTap: onItemTap,
final controller = Get.put(ProfileViewController());

return Obx(() {
return BasePage(
name: 'User',
body: Column(
children: [
///TODO: Change to ProfileViewList component
///TODO: Add a new ProfileViewTemplate component.
ProfileViewTemplate(
userName: controller.profile.userInfo.name,
items: controller.profile.options,
onItemTap: (itemId) {
switch (itemId) {
case 'accounts':
controller.onOptionSelected();
break;
}
},
),
ElevatedButton(
onPressed: () {
controller.onChangeNameTapped();
},
child: const Text('Change name'),
),
],
),
],
);
}
}

class _ProfileHeader extends StatelessWidget {
const _ProfileHeader({
Key? key,
required this.userName,
}) : super(key: key);

final String userName;

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Text(
userName,
),
);
}
}

class _ProfileOptionsList extends StatelessWidget {
const _ProfileOptionsList({
Key? key,
required this.items,
required this.onItemTap,
}) : super(key: key);

final List<ProfileOption> items;
final Function(String) onItemTap;

@override
Widget build(BuildContext context) {
return ListView.builder(
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];

return _ProfileOptionListTile(
name: item.name,
onTap: () {
onItemTap(item.id);
action: MainAction(
label: 'Go Settings',
onPressed: () {
controller.onGoToSettingsTapped();
},
);
},
);
}
}

class _ProfileOptionListTile extends StatelessWidget {
const _ProfileOptionListTile({
Key? key,
required this.name,
required this.onTap,
}) : super(key: key);

final String name;
final Function() onTap;

@override
Widget build(BuildContext context) {
return ListTile(
title: Padding(
padding: const EdgeInsets.all(8),
child: Text(name),
),
onTap: onTap,
);
),
);
});
}
}
Loading

0 comments on commit 3b680e0

Please sign in to comment.