-
Notifications
You must be signed in to change notification settings - Fork 6
[listen] Creates listen package #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
753f2b5
ddb441d
70d66bc
b928281
23dda28
5a09f6c
ed19257
8659b4b
9be184a
b3b3ff8
f758e93
4adb1f3
3a4717c
cea97ac
aa8474e
bd82d72
5b6a595
75fd887
2521f2e
1d927b5
fbc785f
f3fe60a
0370c2c
bd4b999
02e2d32
19a9b1b
8aa7aca
f9d12c6
c8ae2f8
e0105b9
84440f2
8b034f2
3cd601c
003ce83
2dca3d3
e3335e8
e75fc4e
407052a
592b64b
bd2c3ff
1064ef9
599a359
a1dc2dd
5f22f52
075b144
46c3bbe
120772a
2c68313
4ee3d62
18139a9
4ef2c3b
2180621
d9976c4
2538ba6
9e3eaf5
caaf888
049ecbd
af72157
70a1d53
bcfd499
77d3dc2
f476d22
ae484e4
8920924
55352a4
0867a08
cf527c8
00c6aee
ad97e24
f41901a
752591f
c95bf13
c0d40af
7317aae
badb5ec
1351c01
1e6f91e
11835bb
e114036
856914a
2de98b9
1179330
ddf33c6
a55eb7c
52c3962
32cf983
550efcb
0977b2a
f61d571
795dc97
6b04285
a0b459b
bc766be
f0a1d75
98b3ef0
c9a5ebe
419db80
99f64b9
95ac2da
bae7241
7b46eeb
927822b
55ed68c
0a91f20
8386a09
65e165d
6cd45de
0be3949
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| .children | ||
| .project | ||
| .DS_Store | ||
| packages | ||
| pubspec.lock | ||
| .pub | ||
| .packages | ||
| .dart_tool | ||
| .idea |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # Below is a list of people and organizations that have contributed | ||
| # to the project. Names should be added to the list like so: | ||
| # | ||
| # Name/Organization <email address> | ||
|
|
||
| Google Inc. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| ## 1.0.0-beta.1 | ||
|
|
||
| - Adjusts source code to be publishable. | ||
| - Moves source code from `flutter/flutter` to `flutter/core-packages`. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't just a move, it's an extraction as a stand-alone package. We should clarify what the full scope of the change is.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just realized that changing this would require a new CLA override. Feel free to just adjust in in the next PR to this package.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated since i will have to squash new commits into a single one and will require a CLA override anyway |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| Copyright 2013 The Flutter Authors | ||
|
|
||
| Redistribution and use in source and binary forms, with or without modification, | ||
| are permitted provided that the following conditions are met: | ||
|
|
||
| * Redistributions of source code must retain the above copyright | ||
| notice, this list of conditions and the following disclaimer. | ||
| * Redistributions in binary form must reproduce the above | ||
| copyright notice, this list of conditions and the following | ||
| disclaimer in the documentation and/or other materials provided | ||
| with the distribution. | ||
| * Neither the name of Google Inc. nor the names of its | ||
| contributors may be used to endorse or promote products derived | ||
| from this software without specific prior written permission. | ||
|
|
||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
| ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| <?code-excerpt path-base="example/lib"?> | ||
|
|
||
| # listen | ||
|
|
||
| A package to notify state changes to interested listeners in pure Dart. | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Using ValueNotifier | ||
|
|
||
| `ValueNotifier` wraps a single value and notifies listeners whenever the value changes: | ||
|
|
||
| <?code-excerpt "readme_excerpts.dart (ValueNotifier)"?> | ||
| ```dart | ||
| void valueNotifierExample() { | ||
| final counter = ValueNotifier<int>(0); | ||
|
|
||
| counter.addListener(() { | ||
| print('Value changed: ${counter.value}'); | ||
| }); | ||
|
|
||
| counter.value = 5; // Prints: Value changed: 5 | ||
| counter.value = 10; // Prints: Value changed: 10 | ||
| counter.value = 10; // Does not print because the value is == 10 | ||
|
|
||
| counter.dispose(); | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| ### Using ChangeNotifier | ||
|
|
||
| Extend or mix in `ChangeNotifier` to manage state and notify listeners manually: | ||
|
|
||
| <?code-excerpt "readme_excerpts.dart (ChangeNotifierClass)"?> | ||
| ```dart | ||
| /// A [ChangeNotifier] subclass that encapsulates a list of items and notifies | ||
| /// listeners whenever items are added or removed. | ||
| class ItemListNotifier extends ChangeNotifier { | ||
| final List<String> _items = <String>[]; | ||
|
|
||
| /// The unmodifiable list of current items. | ||
| List<String> get items => List<String>.unmodifiable(_items); | ||
|
|
||
| /// Adds an [item] to the list and notifies listeners. | ||
| void addItem(String item) { | ||
| _items.add(item); | ||
| notifyListeners(); | ||
| } | ||
|
|
||
| /// Removes an [item] from the list and notifies listeners if it was present. | ||
| void removeItem(String item) { | ||
| if (_items.remove(item)) { | ||
| notifyListeners(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| Then, listen to changes and update state: | ||
|
|
||
| <?code-excerpt "readme_excerpts.dart (ChangeNotifierUsage)"?> | ||
| ```dart | ||
| void changeNotifierExample() { | ||
| final listNotifier = ItemListNotifier(); | ||
|
|
||
| listNotifier.addListener(() { | ||
| print('Current items: ${listNotifier.items}'); | ||
| }); | ||
|
|
||
| listNotifier.addItem('Apple'); // Prints: Current items: [Apple] | ||
| listNotifier.addItem('Banana'); // Prints: Current items: [Apple, Banana] | ||
| listNotifier.removeItem('Apple'); // Prints: Current items: [Banana] | ||
|
|
||
| listNotifier.dispose(); | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| ### Merging listenables | ||
|
|
||
| Use `Listenable.merge` to listen to multiple objects simultaneously: | ||
|
|
||
| <?code-excerpt "readme_excerpts.dart (Merge)"?> | ||
| ```dart | ||
| void mergeExample() { | ||
| final first = ValueNotifier<String>('Hello'); | ||
| final second = ValueNotifier<String>('World'); | ||
|
|
||
| final merged = Listenable.merge(<Listenable>[first, second]); | ||
|
|
||
| merged.addListener(() { | ||
| print('Merged listenable triggered: ${first.value} ${second.value}'); | ||
| }); | ||
|
|
||
| first.value = 'Hi'; // Prints: Merged listenable triggered: Hi World | ||
| second.value = 'Dart'; // Prints: Merged listenable triggered: Hi Dart | ||
|
|
||
| first.dispose(); | ||
| second.dispose(); | ||
| } | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| // ignore_for_file: avoid_print | ||
|
|
||
| import 'package:listen/listen.dart'; | ||
|
|
||
| /// A simple counter that extends [ChangeNotifier] to notify listeners | ||
| /// whenever its value changes. | ||
| class Counter extends ChangeNotifier { | ||
| int _count = 0; | ||
|
|
||
| /// The current count value. | ||
| int get count => _count; | ||
|
|
||
| /// Increments the count by one and notifies listeners. | ||
| void increment() { | ||
| _count++; | ||
| notifyListeners(); | ||
| } | ||
| } | ||
|
|
||
| void main() { | ||
| final counter = Counter(); | ||
|
|
||
| counter.addListener(() { | ||
| print('Counter value changed to: ${counter.count}'); | ||
| }); | ||
|
|
||
| counter.increment(); // Prints: Counter value changed to: 1 | ||
| counter.increment(); // Prints: Counter value changed to: 2 | ||
|
|
||
| counter.dispose(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| // ignore_for_file: avoid_print | ||
|
|
||
| import 'package:listen/listen.dart'; | ||
|
|
||
| /// A [ChangeNotifier] subclass that encapsulates a list of items and notifies | ||
| /// listeners whenever items are added or removed. | ||
| class ItemListNotifier extends ChangeNotifier { | ||
| final List<String> _items = <String>[]; | ||
|
|
||
| /// The unmodifiable list of current items. | ||
| List<String> get items => List<String>.unmodifiable(_items); | ||
|
|
||
| /// Adds an [item] to the list and notifies listeners. | ||
| void addItem(String item) { | ||
| _items.add(item); | ||
| notifyListeners(); | ||
| } | ||
|
|
||
| /// Removes an [item] from the list and notifies listeners if it was present. | ||
| void removeItem(String item) { | ||
| if (_items.remove(item)) { | ||
| notifyListeners(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void main() { | ||
| final listNotifier = ItemListNotifier(); | ||
|
|
||
| listNotifier.addListener(() { | ||
| print('Current items: ${listNotifier.items}'); | ||
| }); | ||
|
|
||
| listNotifier.addItem('Apple'); // Prints: Current items: [Apple] | ||
| listNotifier.addItem('Banana'); // Prints: Current items: [Apple, Banana] | ||
| listNotifier.removeItem('Apple'); // Prints: Current items: [Banana] | ||
|
|
||
| listNotifier.dispose(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| // ignore_for_file: avoid_print | ||
|
|
||
| import 'package:listen/listen.dart'; | ||
|
|
||
| void main() { | ||
| final first = ValueNotifier<String>('Hello'); | ||
| final second = ValueNotifier<String>('World'); | ||
|
|
||
| final merged = Listenable.merge(<Listenable>[first, second]); | ||
|
|
||
| merged.addListener(() { | ||
| print('Merged listenable triggered: ${first.value} ${second.value}'); | ||
| }); | ||
|
|
||
| first.value = 'Hi'; // Prints: Merged listenable triggered: Hi World | ||
| second.value = 'Dart'; // Prints: Merged listenable triggered: Hi Dart | ||
|
|
||
| first.dispose(); | ||
| second.dispose(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| // ignore_for_file: avoid_print | ||
|
|
||
| import 'package:listen/listen.dart'; | ||
|
|
||
| void main() { | ||
| final counter = ValueNotifier<int>(0); | ||
|
|
||
| counter.addListener(() { | ||
| print('Counter changed to: ${counter.value}'); | ||
| }); | ||
|
|
||
| counter.value = 1; // Prints: Counter changed to: 1 | ||
| counter.value = 2; // Prints: Counter changed to: 2 | ||
|
|
||
| counter.dispose(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| // Copyright 2013 The Flutter Authors | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| // This file exists solely to host compiled excerpts for README.md, and is not | ||
| // intended for use as an actual example application. | ||
|
|
||
| // ignore_for_file: avoid_print | ||
|
|
||
| import 'package:listen/listen.dart'; | ||
|
|
||
| /// Demonstrates [ValueNotifier] usage for README. | ||
| // #docregion ValueNotifier | ||
| void valueNotifierExample() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason this is duplicated almost exactly here from
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That will require adding the #docregion identifier on the main.dart, which I think may be confusing for people looking at the example. so I intentionally group all excerpt related code in one file even if I can probably grab the code from some other example. Let me know reducing duplication here is more preferred.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Traditionally we haven't worried about having it in main.dart, and only use readme_excerpts.dart when there were things we wanted to show in the README that weren't in the example. It's not a rule though, so if you are concerned about the comments in the example this is fine.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will keep this as-is |
||
| final counter = ValueNotifier<int>(0); | ||
|
|
||
| counter.addListener(() { | ||
| print('Value changed: ${counter.value}'); | ||
| }); | ||
|
|
||
| counter.value = 5; // Prints: Value changed: 5 | ||
| counter.value = 10; // Prints: Value changed: 10 | ||
| counter.value = 10; // Does not print because the value is == 10 | ||
|
|
||
| counter.dispose(); | ||
| } | ||
|
|
||
| // #enddocregion ValueNotifier | ||
|
|
||
| // #docregion ChangeNotifierClass | ||
| /// A [ChangeNotifier] subclass that encapsulates a list of items and notifies | ||
| /// listeners whenever items are added or removed. | ||
| class ItemListNotifier extends ChangeNotifier { | ||
| final List<String> _items = <String>[]; | ||
|
|
||
| /// The unmodifiable list of current items. | ||
| List<String> get items => List<String>.unmodifiable(_items); | ||
|
|
||
| /// Adds an [item] to the list and notifies listeners. | ||
| void addItem(String item) { | ||
| _items.add(item); | ||
| notifyListeners(); | ||
| } | ||
|
|
||
| /// Removes an [item] from the list and notifies listeners if it was present. | ||
| void removeItem(String item) { | ||
| if (_items.remove(item)) { | ||
| notifyListeners(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // #enddocregion ChangeNotifierClass | ||
|
|
||
| /// Demonstrates [ChangeNotifier] usage for README. | ||
| // #docregion ChangeNotifierUsage | ||
| void changeNotifierExample() { | ||
| final listNotifier = ItemListNotifier(); | ||
|
|
||
| listNotifier.addListener(() { | ||
| print('Current items: ${listNotifier.items}'); | ||
| }); | ||
|
|
||
| listNotifier.addItem('Apple'); // Prints: Current items: [Apple] | ||
| listNotifier.addItem('Banana'); // Prints: Current items: [Apple, Banana] | ||
| listNotifier.removeItem('Apple'); // Prints: Current items: [Banana] | ||
|
|
||
| listNotifier.dispose(); | ||
| } | ||
|
|
||
| // #enddocregion ChangeNotifierUsage | ||
|
|
||
| /// Demonstrates [Listenable.merge] usage for README. | ||
| // #docregion Merge | ||
| void mergeExample() { | ||
| final first = ValueNotifier<String>('Hello'); | ||
| final second = ValueNotifier<String>('World'); | ||
|
|
||
| final merged = Listenable.merge(<Listenable>[first, second]); | ||
|
|
||
| merged.addListener(() { | ||
| print('Merged listenable triggered: ${first.value} ${second.value}'); | ||
| }); | ||
|
|
||
| first.value = 'Hi'; // Prints: Merged listenable triggered: Hi World | ||
| second.value = 'Dart'; // Prints: Merged listenable triggered: Hi Dart | ||
|
|
||
| first.dispose(); | ||
| second.dispose(); | ||
| } | ||
| // #enddocregion Merge | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We never do releases like this, so I'm not entirely sure our CI will handle it correctly. It looks like presubmit is fine, so fingers crossed, but be sure to verify that publishing actually worked after it lands.