-
Notifications
You must be signed in to change notification settings - Fork 24
Adding package:listen #898
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
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,16 @@ | ||
# Don’t commit the following directories created by pub. | ||
.buildlog | ||
.pub/ | ||
.dart_tool/ | ||
build/ | ||
packages | ||
.packages | ||
|
||
# Or the files created by dart2js. | ||
*.dart.js | ||
*.js_ | ||
*.js.deps | ||
*.js.map | ||
|
||
# Include when developing application packages. | ||
pubspec.lock |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## 1.0.0-beta.0 | ||
|
||
- First release. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Copyright 2014 The Flutter Authors. All rights reserved. | ||
|
||
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 @@ | ||
Very prototype package |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# https://dart.dev/guides/language/analysis-options | ||
|
||
include: package:dart_flutter_team_lints/analysis_options.yaml | ||
|
||
analyzer: | ||
language: | ||
strict-raw-types: true | ||
|
||
linter: | ||
rules: | ||
- avoid_unused_constructor_parameters | ||
- cancel_subscriptions | ||
- literal_only_boolean_expressions | ||
- missing_whitespace_between_adjacent_strings | ||
- no_adjacent_strings_in_list | ||
- no_runtimeType_toString | ||
- unnecessary_await_in_return |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright 2014 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
/// An object that maintains a list of listeners. | ||
/// | ||
/// The listeners are typically used to notify clients that the object has been | ||
/// updated. | ||
/// | ||
/// There are two variants of this interface: | ||
/// | ||
/// * [ValueListenable], an interface that augments the [Listenable] interface | ||
/// with the concept of a _current value_. | ||
/// | ||
/// * [Animation], an interface that augments the [ValueListenable] interface | ||
/// to add the concept of direction (forward or reverse). | ||
/// | ||
/// Many classes in the Flutter API use or implement these interfaces. The | ||
/// following subclasses are especially relevant: | ||
/// | ||
/// * [ChangeNotifier], which can be subclassed or mixed in to create objects | ||
/// that implement the [Listenable] interface. | ||
/// | ||
/// * [ValueNotifier], which implements the [ValueListenable] interface with | ||
/// a mutable value that triggers the notifications when modified. | ||
/// | ||
/// The terms "notify clients", "send notifications", "trigger notifications", | ||
/// and "fire notifications" are used interchangeably. | ||
/// | ||
/// See also: | ||
/// | ||
/// * [AnimatedBuilder], a widget that uses a builder callback to rebuild | ||
/// whenever a given [Listenable] triggers its notifications. This widget is | ||
/// commonly used with [Animation] subclasses, hence its name, but is by no | ||
/// means limited to animations, as it can be used with any [Listenable]. It | ||
/// is a subclass of [AnimatedWidget], which can be used to create widgets | ||
/// that are driven from a [Listenable]. | ||
/// * [ValueListenableBuilder], a widget that uses a builder callback to | ||
/// rebuild whenever a [ValueListenable] object triggers its notifications, | ||
/// providing the builder with the value of the object. | ||
/// * [InheritedNotifier], an abstract superclass for widgets that use a | ||
/// [Listenable]'s notifications to trigger rebuilds in descendant widgets | ||
/// that declare a dependency on them, using the [InheritedWidget] mechanism. | ||
/// * [Listenable.merge], which creates a [Listenable] that triggers | ||
/// notifications whenever any of a list of other [Listenable]s trigger their | ||
/// notifications. | ||
abstract class Listenable { | ||
/// Abstract const constructor. This constructor enables subclasses to provide | ||
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. It's not abstract. Just "Const constructor". |
||
/// const constructors so that they can be used in const expressions. | ||
const Listenable(); | ||
|
||
/// Return a [Listenable] that triggers when any of the given [Listenable]s | ||
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. "Return" -> "Creates" |
||
/// themselves trigger. | ||
/// | ||
/// Once the factory is called, items must not be added or removed from the | ||
/// iterable. | ||
/// Doing so will lead to memory leaks or exceptions. | ||
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's a bad API. If the class plans to iterate the argument more than once, it should copy it, or request a |
||
/// | ||
/// The iterable may contain nulls; they are ignored. | ||
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. Really not great API to allowing |
||
factory Listenable.merge(Iterable<Listenable?> listenables) = | ||
_MergingListenable; | ||
|
||
/// Register a closure to be called when the object notifies its listeners. | ||
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. "Registers", and "Removes" below. Check using third person present tense everywhere. |
||
void addListener(void Function() listener); | ||
|
||
/// Remove a previously registered closure from the list of closures that the | ||
/// object notifies. | ||
void removeListener(void Function() listener); | ||
} | ||
|
||
/// An interface for subclasses of [Listenable] that expose a [value]. | ||
/// | ||
/// This interface is implemented by [ValueNotifier<T>] and [Animation<T>], and | ||
/// allows other APIs to accept either of those implementations interchangeably. | ||
/// | ||
/// See also: | ||
/// | ||
/// * [ValueListenableBuilder], a widget that uses a builder callback to | ||
/// rebuild whenever a [ValueListenable] object triggers its notifications, | ||
/// providing the builder with the value of the object. | ||
abstract class ValueListenable<T> extends Listenable { | ||
/// Abstract const constructor. This constructor enables subclasses to provide | ||
/// const constructors so that they can be used in const expressions. | ||
const ValueListenable(); | ||
|
||
/// The current value of the object. When the value changes, the callbacks | ||
/// registered with [addListener] will be invoked. | ||
T get value; | ||
} | ||
|
||
class _MergingListenable extends Listenable { | ||
_MergingListenable(this._children); | ||
|
||
final Iterable<Listenable?> _children; | ||
|
||
@override | ||
void addListener(void Function() listener) { | ||
for (final child in _children) { | ||
child?.addListener(listener); | ||
} | ||
} | ||
|
||
@override | ||
void removeListener(void Function() listener) { | ||
for (final child in _children) { | ||
child?.removeListener(listener); | ||
} | ||
} | ||
|
||
@override | ||
String toString() { | ||
return 'Listenable.merge([${_children.join(", ")}])'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
name: listen | ||
version: 1.0.0-beta.0 | ||
description: Includes core Flutter types Listenable and ValueListenable | ||
|
||
environment: | ||
sdk: ^3.7.0 | ||
|
||
dev_dependencies: | ||
dart_flutter_team_lints: ^3.5.0 | ||
test: any |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright 2014 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import 'package:listen/listen.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import 'test_listenable.dart'; | ||
|
||
void main() { | ||
test('Listenable.merge', () { | ||
final listenableA = TestListenable(); | ||
final listenableB = TestListenable(); | ||
|
||
final merged = Listenable.merge([listenableA, listenableB]); | ||
|
||
var callCount = 0; | ||
|
||
void testListener() { | ||
callCount++; | ||
} | ||
|
||
merged.addListener(testListener); | ||
|
||
expect(callCount, 0); | ||
|
||
listenableA.notify(); | ||
expect(callCount, 1); | ||
|
||
listenableB.notify(); | ||
expect(callCount, 2); | ||
|
||
merged.removeListener(testListener); | ||
|
||
listenableA.notify(); | ||
expect(callCount, 2); | ||
|
||
listenableB.notify(); | ||
expect(callCount, 2); | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import 'package:listen/listen.dart'; | ||
|
||
class TestListenable extends Listenable { | ||
final _listeners = <void Function()>{}; | ||
|
||
void notify() { | ||
for (final listener in _listeners) { | ||
listener(); | ||
} | ||
} | ||
|
||
@override | ||
void addListener(void Function() listener) { | ||
_listeners.add(listener); | ||
} | ||
|
||
@override | ||
void removeListener(void Function() listener) { | ||
_listeners.remove(listener); | ||
} | ||
} |
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.
Is that class in scope? Same for
ValueListenableBuilder
.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.
Nope! This is a draft PR. These will need to be cleaned up!