Skip to content

Commit

Permalink
Merge pull request #10 from shubham-gupta-16/improve_view_model
Browse files Browse the repository at this point in the history
Fixed ViewModel Dispose major bug
  • Loading branch information
shubham16g authored Jan 20, 2023
2 parents e6a0710 + d34ba63 commit 22a4bfa
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 4 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Publish to pub.dev

on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+*'

jobs:
publish:
uses: dart-lang/setup-dart/blob/main/.github/workflows/publish.yml
# with:
# working-directory: path/to/package/within/repository
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.5.3
Fixed ViewModel Dispose major bug
- ViewModel not disposing fixed
- Responsive Example added

## 0.5.2
Fixed Bugs and make package simpler
- ViewModelStatelessWidget removed
Expand Down
2 changes: 2 additions & 0 deletions example/lib/more_examples_section.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:example/multiple_view_models_example/multiple_view_models_example.dart';
import 'package:example/post_frame_callback_example/post_frame_callback_example.dart';
import 'package:example/responsive_example/responsive_example.dart';
import 'package:flutter/material.dart';

final _moreExamples = {
"Multiple ViewModels Example": const MultipleViewModelsExample(),
"PostFrameCallback Example": const PostFrameCallbackExample(),
"Responsive Example": const ResponsiveExample(),
};

class MoreExamplesSection extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ class SecondViewModel extends ViewModel {
@override
void dispose() {
_messageSharedFlow.dispose();
debugPrint("FirstViewModel disposed");
debugPrint("SecondViewModel disposed");
}
}
55 changes: 55 additions & 0 deletions example/lib/responsive_example/responsive_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:view_model_x/view_model_x.dart';

import 'view_model/first_view_model.dart';
import 'view_model/second_view_model.dart';

class ResponsiveExample extends StatelessWidget {
const ResponsiveExample({super.key});

@override
Widget build(BuildContext context) {
final isDesktop = MediaQuery.of(context).size.width > 600;
return Scaffold(
appBar: AppBar(
title: const Text("Responsive"),
),
body: isDesktop
? const FirstSection()
: ViewModelProvider(
create: (context) => SecondViewModel(),
child: const SecondSection()),
);
}
}

class FirstSection extends StatelessWidget {
const FirstSection({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return ViewModelProvider(
create: (c) => FirstViewModel(),
builder: (ctx, v) => Container(
color: Colors.green,
child: Center(
child: Text(ViewModelProvider.of<FirstViewModel>(ctx)
.counterStateFlow
.value
.toString()),
),
),
);
}
}

class SecondSection extends StatelessWidget {
const SecondSection({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
);
}
}
21 changes: 21 additions & 0 deletions example/lib/responsive_example/view_model/first_view_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:flutter/cupertino.dart';
import 'package:view_model_x/view_model_x.dart';

class FirstViewModel extends ViewModel {
// initialize StateFlow
final _counterStateFlow = MutableStateFlow<int>(1);

StateFlow<int> get counterStateFlow => _counterStateFlow;

void increment() {
// by changing the value, listeners were notified
_counterStateFlow.value = _counterStateFlow.value + 1;
}

@override
void dispose() {
// must dispose all flows
_counterStateFlow.dispose();
debugPrint("FirstViewModel disposed");
}
}
26 changes: 26 additions & 0 deletions example/lib/responsive_example/view_model/second_view_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:flutter/foundation.dart';
import 'package:view_model_x/view_model_x.dart';

class SecondViewModel extends ViewModel {
// initialize SharedFlow
final _messageSharedFlow = MutableSharedFlow<String>();

SharedFlow<String> get messageSharedFlow => _messageSharedFlow;

void showPopupMessage() {
// by emitting the value, listeners were notified
debugPrint("hi");
_messageSharedFlow.emit("Hello from MyViewModel!");
}

@override
void init() {
debugPrint("init inside vm");
}

@override
void dispose() {
_messageSharedFlow.dispose();
debugPrint("SecondViewModel disposed");
}
}
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.5.2"
version: "0.5.3"
sdks:
dart: ">=2.18.6 <3.0.0"
flutter: ">=1.17.0"
19 changes: 18 additions & 1 deletion lib/src/view_model_provider.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';

import 'provider_single_child_widget.dart';
import 'view_model.dart';

/// [ViewModelProvider] is used to wrap the widget with your custom [ViewModel].
/// This requires [create] which accepts custom [ViewModel] and [child] Widget.
class VMP<T extends ViewModel> extends SingleChildStatelessWidget {
const VMP({super.key, super.child});

@override
Widget buildWithChild(BuildContext context, Widget? child) {
// TODO: implement buildWithChild
throw UnimplementedError();
}
}

class ViewModelProvider<T extends ViewModel> extends Provider<T>
with ProviderSingleChildWidget {
ViewModelProvider(
{super.key,
required super.create,
super.lazy,
super.builder,
super.child});
super.child})
: super(dispose: _dispose);

static void _dispose<T extends ViewModel>(BuildContext context, T viewModel) {
debugPrint('provider dispose');
viewModel.dispose();
}

/// [ViewModelProvider].[of] method allows to get the custom [ViewModel] from anywhere nested inside [ViewModelProvider]'s [child]
static F of<F extends ViewModel>(BuildContext context) {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: view_model_x
description: An Android similar state management package (StateFlow and SharedFlow with ViewModel) which helps to implement MVVM pattern easily.
version: 0.5.2
version: 0.5.3
homepage: https://github.com/shubham-gupta-16/view_model_x
repository: https://github.com/shubham-gupta-16/view_model_x
issue_tracker: https://github.com/shubham-gupta-16/view_model_x/issues
Expand Down

0 comments on commit 22a4bfa

Please sign in to comment.