Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion flutter_module/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import 'package:flutter_module/presentation/screens//main_screen.dart';
import 'package:flutter_module/presentation/screens/details_screen.dart';
import 'package:flutter_module/presentation/screens/login_screen.dart';
import 'package:flutter_module/utils/extensions/text_extensions.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router_plus/go_router_plus.dart';

void main() => runApp(MyApp());
void main() => runApp(ProviderScope(child: MyApp()));

class MyApp extends StatelessWidget {
MyApp({super.key});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:flutter_module/model/main_model.dart';
import 'package:flutter_module/presentation/providers/model_bridge_provider.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final detailsPageStateProvider =
StateNotifierProvider<_DetailPageStateNotifier, DetailModelStateData>(
(ref) => _DetailPageStateNotifier(detailsBridge: ref.read(detailsBridge)),
);

final detailsPageEventProvider = StateNotifierProvider<_DetailPageEventNotifier, DetailModelEventData>(
(ref) => _DetailPageEventNotifier(detailsBridge: ref.read(detailsBridge)),
);

class _DetailPageStateNotifier extends StateNotifier<DetailModelStateData> {
_DetailPageStateNotifier({
required this.detailsBridge,
}) : super(DetailModelStateData()) {
// Simulate hook's state & event refreshing
Stream.periodic(
const Duration(milliseconds: 500),
(_) => detailsBridge.getState(),
).listen((newState) async => state = await newState);
}

final DetailModelBridge detailsBridge;
}

class _DetailPageEventNotifier extends StateNotifier<DetailModelEventData> {
_DetailPageEventNotifier({
required this.detailsBridge,
}) : super(DetailModelEventData()) {
// Simulate hook's state & event refreshing
Stream.periodic(
const Duration(milliseconds: 500),
(_) => detailsBridge.getEvent(),
).listen((newEvent) async => state = await newEvent);
}

final DetailModelBridge detailsBridge;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:flutter_module/model/main_model.dart';
import 'package:flutter_module/presentation/providers/model_bridge_provider.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final loginPageStateProvider =
StateNotifierProvider<_LoginPageStateNotifier, LoginModelStateData>(
(ref) => _LoginPageStateNotifier(loginBridge: ref.read(loginBridge)),
);

final loginPageEventProvider = StateNotifierProvider<_LoginPageEventNotifier, LoginModelEventData>(
(ref) => _LoginPageEventNotifier(loginBridge: ref.read(loginBridge)),
);

class _LoginPageStateNotifier extends StateNotifier<LoginModelStateData> {
_LoginPageStateNotifier({
required this.loginBridge,
}) : super(LoginModelStateData()) {
// Simulate hook's state & event refreshing
Stream.periodic(
const Duration(milliseconds: 500),
(_) => loginBridge.getState(),
).listen((newState) async => state = await newState);
}

final LoginModelBridge loginBridge;
}

class _LoginPageEventNotifier extends StateNotifier<LoginModelEventData> {
_LoginPageEventNotifier({
required this.loginBridge,
}) : super(LoginModelEventData()) {
// Simulate hook's state & event refreshing
Stream.periodic(
const Duration(milliseconds: 500),
(_) => loginBridge.getEvent(),
).listen((newEvent) async => state = await newEvent);
}

final LoginModelBridge loginBridge;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:flutter_module/model/main_model.dart';
import 'package:flutter_module/presentation/providers/model_bridge_provider.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final mainPageStateProvider =
StateNotifierProvider<_MainPageStateNotifier, MainModelStateData>(
(ref) => _MainPageStateNotifier(mainBridge: ref.read(mainBridge)),
);

final mainPageEventProvider = StateNotifierProvider<_MainPageEventNotifier, MainModelEventData>(
(ref) => _MainPageEventNotifier(mainBridge: ref.read(mainBridge)),
);

class _MainPageStateNotifier extends StateNotifier<MainModelStateData> {
_MainPageStateNotifier({
required this.mainBridge,
}) : super(MainModelStateData()) {
// Simulate hook's state & event refreshing
Stream.periodic(
const Duration(milliseconds: 500),
(_) => mainBridge.getState(),
).listen((newState) async => state = await newState);
}

final MainModelBridge mainBridge;
}

class _MainPageEventNotifier extends StateNotifier<MainModelEventData> {
_MainPageEventNotifier({
required this.mainBridge,
}) : super(MainModelEventData()) {
// Simulate hook's state & event refreshing
Stream.periodic(
const Duration(milliseconds: 500),
(_) => mainBridge.getEvent(),
).listen((newEvent) async => state = await newEvent);
}

final MainModelBridge mainBridge;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:flutter_module/model/main_model.dart';

final loginBridge = Provider((ref) => LoginModelBridge());
final mainBridge = Provider((ref) => MainModelBridge());
final detailsBridge = Provider((ref) => DetailModelBridge());
39 changes: 17 additions & 22 deletions flutter_module/lib/presentation/screens/details_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_module/model/main_model.dart';
import 'package:flutter_module/presentation/navigation/details/details_navigator.dart';
import 'package:flutter_module/presentation/providers/details_page_state_provider.dart';
import 'package:flutter_module/presentation/providers/model_bridge_provider.dart';
import 'package:flutter_module/presentation/screens/named_screen.dart';
import 'package:flutter_module/presentation/styles/color_styles.dart';
import 'package:flutter_module/presentation/styles/dimens.dart';
Expand All @@ -15,6 +17,7 @@ import 'package:flutter_module/utils/extensions/state_extensions.dart';
import 'package:flutter_module/utils/hooks/use_navigator.dart';
import 'package:flutter_module/utils/hooks/use_observable_state_hook.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class DetailsScreen extends NamedScreen {
DetailsScreen({
Expand All @@ -34,10 +37,9 @@ class DetailsScreen extends NamedScreen {
model: model,
);
}

}

class _DetailsPage extends HookWidget {
class _DetailsPage extends HookConsumerWidget {
const _DetailsPage({
required this.navigator,
required this.model,
Expand All @@ -47,24 +49,17 @@ class _DetailsPage extends HookWidget {
final DetailModelBridge model;

@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
useNavigator([navigator]);

final state = useObservableState(
DetailModelStateData(),
() => model.getState(),
(current, newState) => (current as DetailModelStateData).equals(newState),
).value;

final event = useObservableState(
DetailModelEventData(),
() => model.getEvent(),
(current, newState) => (current as DetailModelEventData).equals(newState),
).value;
final stateNotification = ref.watch(detailsPageStateProvider);
final state = stateNotification.state;
final eventNotification = ref.watch(detailsPageEventProvider);
final event = eventNotification.event;

WidgetsBinding.instance.addPostFrameCallback((_) {
if (event.event == DetailModelEvent.saved) {
final snippetId = event.value;
if (event == DetailModelEvent.saved) {
final snippetId = eventNotification.value;
if (snippetId == null) {
_exit();
return;
Expand All @@ -78,7 +73,7 @@ class _DetailsPage extends HookWidget {
});

WidgetsBinding.instance.addPostFrameCallback((_) {
if (event.event == DetailModelEvent.deleted) {
if (event == DetailModelEvent.deleted) {
_exit();
}
});
Expand All @@ -91,23 +86,23 @@ class _DetailsPage extends HookWidget {
return Scaffold(
backgroundColor: ColorStyles.surfacePrimary(),
appBar: AppBar(
title: Text(state.data?.title ?? ''),
title: Text(stateNotification.data?.title ?? ''),
backgroundColor: ColorStyles.surfacePrimary(),
foregroundColor: Colors.black,
elevation: 0,
leading: BackButton(
onPressed: navigator.back,
color: Colors.black,
),
actions: state.data?.isPrivate == true
actions: stateNotification.data?.isPrivate == true
? [const PaddingStyles.regular(Icon(Icons.lock_outlined))]
: null,
),
body: ViewStateWrapper<Snippet>(
isLoading:
state.state == ModelState.loading || state.isLoading == true,
error: state.error,
data: state.data,
state == ModelState.loading || stateNotification.isLoading == true,
error: stateNotification.error,
data: stateNotification.data,
builder: (_, snippet) => _DetailPageData(
model: model,
snippet: snippet,
Expand Down
28 changes: 10 additions & 18 deletions flutter_module/lib/presentation/screens/login_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_module/generated/assets.dart';
import 'package:flutter_module/model/main_model.dart';
import 'package:flutter_module/presentation/navigation/login/login_navigator.dart';
import 'package:flutter_module/presentation/providers/login_page_state_provider.dart';
import 'package:flutter_module/presentation/screens/named_screen.dart';
import 'package:flutter_module/presentation/styles/dimens.dart';
import 'package:flutter_module/presentation/styles/padding_styles.dart';
Expand All @@ -11,10 +12,9 @@ import 'package:flutter_module/presentation/widgets/login_input_card.dart';
import 'package:flutter_module/presentation/widgets/no_overscroll_single_child_scroll_view.dart';
import 'package:flutter_module/presentation/widgets/rounded_action_button.dart';
import 'package:flutter_module/presentation/widgets/view_state_wrapper.dart';
import 'package:flutter_module/utils/extensions/state_extensions.dart';
import 'package:flutter_module/utils/hooks/use_navigator.dart';
import 'package:flutter_module/utils/hooks/use_observable_state_hook.dart';
import 'package:go_router_plus/go_router_plus.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class LoginScreen extends NamedScreen implements InitialScreen, GuestScreen {
LoginScreen({
Expand All @@ -35,7 +35,7 @@ class LoginScreen extends NamedScreen implements InitialScreen, GuestScreen {
}
}

class _MainPage extends HookWidget {
class _MainPage extends HookConsumerWidget {
const _MainPage({
required this.navigator,
required this.model,
Expand All @@ -45,32 +45,24 @@ class _MainPage extends HookWidget {
final LoginModelBridge model;

@override
Widget build(BuildContext context) {
Widget build(BuildContext context, WidgetRef ref) {
useNavigator([navigator]);

final email = useState('mail@o2.pl');
final password = useState('12345678');
final validationCorrect = useState(true);

final state = useObservableState(
LoginModelStateData(),
() => model.getState(),
(current, newState) => (current as LoginModelStateData).equals(newState),
).value;

final event = useObservableState(
LoginModelEventData(),
() => model.getEvent(),
(current, newState) => (current as LoginModelEventData).equals(newState),
).value;
final stateNotification = ref.watch(loginPageStateProvider);
final eventNotification = ref.watch(loginPageEventProvider);
final event = eventNotification.event;

useEffect(() {
model.checkLoginState();
return null;
}, []);

WidgetsBinding.instance.addPostFrameCallback((_) {
if (event.event == LoginModelEvent.logged) {
if (event == LoginModelEvent.logged) {
model.resetEvent();
navigator.login();
}
Expand All @@ -79,8 +71,8 @@ class _MainPage extends HookWidget {
return Scaffold(
body: SafeArea(
child: ViewStateWrapper(
isLoading: state.state == ModelState.loading,
data: state.state,
isLoading: stateNotification.state == ModelState.loading,
data: stateNotification,
builder: (BuildContext context, _) {
return NoOverscrollSingleChildScrollView(
child: Column(
Expand Down
Loading