Skip to content

Commit

Permalink
feat: add scrollable_positioned_list dependency by source code
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasXu0 committed Sep 11, 2023
1 parent 1e6564b commit 1e685f3
Show file tree
Hide file tree
Showing 16 changed files with 2,785 additions and 17 deletions.
7 changes: 0 additions & 7 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@ dev_dependencies:
flutter_test:
sdk: flutter

dependency_overrides:
scrollable_positioned_list:
git:
url: https://github.com/LucasXu0/flutter.widgets.git
ref: 93d78cbcd689a89a8fa6deb87eeb70dc90cc7700
path: packages/scrollable_positioned_list

# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/flutter/scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

class PageBlockKeys {
static const String type = 'page';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:async';
import 'dart:math';

import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/flutter/scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

/// This class controls the scroll behavior of the editor.
///
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

export 'src/item_positions_listener.dart';
export 'src/scrollable_positioned_list.dart';
export 'src/scroll_offset_listener.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2019 The Fuchsia 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:flutter/widgets.dart';

/// A registry to track some [Element]s in the tree.
class RegistryWidget extends StatefulWidget {
/// Creates a [RegistryWidget].
const RegistryWidget({Key? key, this.elementNotifier, required this.child})
: super(key: key);

/// The widget below this widget in the tree.
final Widget child;

/// Contains the current set of all [Element]s created by
/// [RegisteredElementWidget]s in the tree below this widget.
///
/// Note that if there is another [RegistryWidget] in this widget's subtree
/// that registry, and not this one, will collect elements in its subtree.
final ValueNotifier<Set<Element>?>? elementNotifier;

@override
State<StatefulWidget> createState() => _RegistryWidgetState();
}

/// A widget whose [Element] will be added its nearest ancestor
/// [RegistryWidget].
class RegisteredElementWidget extends ProxyWidget {
/// Creates a [RegisteredElementWidget].
const RegisteredElementWidget({Key? key, required Widget child})
: super(key: key, child: child);

@override
Element createElement() => _RegisteredElement(this);
}

class _RegistryWidgetState extends State<RegistryWidget> {
final Set<Element> registeredElements = {};

@override
Widget build(BuildContext context) => _InheritedRegistryWidget(
state: this,
child: widget.child,
);
}

class _InheritedRegistryWidget extends InheritedWidget {
final _RegistryWidgetState state;

const _InheritedRegistryWidget({
Key? key,
required this.state,
required Widget child,
}) : super(key: key, child: child);

@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
}

class _RegisteredElement extends ProxyElement {
_RegisteredElement(ProxyWidget widget) : super(widget);

@override
void notifyClients(ProxyWidget oldWidget) {}

late _RegistryWidgetState _registryWidgetState;

@override
void mount(Element? parent, dynamic newSlot) {
super.mount(parent, newSlot);
final inheritedRegistryWidget =
dependOnInheritedWidgetOfExactType<_InheritedRegistryWidget>()!;
_registryWidgetState = inheritedRegistryWidget.state;
_registryWidgetState.registeredElements.add(this);
_registryWidgetState.widget.elementNotifier?.value =
_registryWidgetState.registeredElements;
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
final inheritedRegistryWidget =
dependOnInheritedWidgetOfExactType<_InheritedRegistryWidget>()!;
_registryWidgetState = inheritedRegistryWidget.state;
_registryWidgetState.registeredElements.add(this);
_registryWidgetState.widget.elementNotifier?.value =
_registryWidgetState.registeredElements;
}

@override
void unmount() {
_registryWidgetState.registeredElements.remove(this);
_registryWidgetState.widget.elementNotifier?.value =
_registryWidgetState.registeredElements;
super.unmount();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2019 The Fuchsia 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:flutter/foundation.dart';

import 'item_positions_notifier.dart';
import 'scrollable_positioned_list.dart';

/// Provides a listenable iterable of [itemPositions] of items that are on
/// screen and their locations.
abstract class ItemPositionsListener {
/// Creates an [ItemPositionsListener] that can be used by a
/// [ScrollablePositionedList] to return the current position of items.
factory ItemPositionsListener.create() => ItemPositionsNotifier();

/// The position of items that are at least partially visible in the viewport.
ValueListenable<Iterable<ItemPosition>> get itemPositions;
}

/// Position information for an item in the list.
class ItemPosition {
/// Create an [ItemPosition].
const ItemPosition({
required this.index,
required this.itemLeadingEdge,
required this.itemTrailingEdge,
});

/// Index of the item.
final int index;

/// Distance in proportion of the viewport's main axis length from the leading
/// edge of the viewport to the leading edge of the item.
///
/// May be negative if the item is partially visible.
final double itemLeadingEdge;

/// Distance in proportion of the viewport's main axis length from the leading
/// edge of the viewport to the trailing edge of the item.
///
/// May be greater than one if the item is partially visible.
final double itemTrailingEdge;

@override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final ItemPosition otherPosition = other;
return otherPosition.index == index &&
otherPosition.itemLeadingEdge == itemLeadingEdge &&
otherPosition.itemTrailingEdge == itemTrailingEdge;
}

@override
int get hashCode =>
31 * (31 * (7 + index.hashCode) + itemLeadingEdge.hashCode) +
itemTrailingEdge.hashCode;

@override
String toString() =>
'ItemPosition(index: $index, itemLeadingEdge: $itemLeadingEdge, itemTrailingEdge: $itemTrailingEdge)';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2019 The Fuchsia 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:flutter/foundation.dart';

import 'item_positions_listener.dart';

/// Internal implementation of [ItemPositionsListener].
class ItemPositionsNotifier implements ItemPositionsListener {
@override
final ValueNotifier<Iterable<ItemPosition>> itemPositions = ValueNotifier([]);
}
Loading

0 comments on commit 1e685f3

Please sign in to comment.