Skip to content

Commit

Permalink
Refactor product screen widget and add max history length to OctopusS…
Browse files Browse the repository at this point in the history
…tateObserver
  • Loading branch information
PlugFox committed Dec 18, 2023
1 parent 74049ff commit 20083cc
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 74 deletions.
171 changes: 97 additions & 74 deletions example/lib/src/feature/shop/widget/product_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -447,93 +447,116 @@ class _ProductPhotosListViewState extends State<_ProductPhotosListView> {
}

@override
Widget build(BuildContext context) => Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: RotatedBox(
quarterTurns: -1,
child: ListWheelScrollView(
controller: controller,
itemExtent: 256,
diameterRatio: 2.5,
/* physics: const FixedExtentScrollPhysics(), */
physics: const FixedExtentScrollPhysics(),
children: widget.product.images
.mapIndexed<Widget>(
(idx, image) => RotatedBox(
quarterTurns: 1,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
ProductImageScreen.show(
context,
id: widget.product.id,
index: idx,
);
HapticFeedback.mediumImpact().ignore();
},
child: Hero(
tag: 'product-${widget.product.id}-image-$idx',
child: Ink.image(
image: AssetImage(image),
fit: BoxFit.fitHeight,
Widget build(BuildContext context) => ShaderMask(
shaderCallback: (rect) => const LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: <Color>[
Colors.purple,
Colors.transparent,
Colors.transparent,
Colors.purple
],
stops: <double>[
0,
0.25,
0.75,
1
], // 25% purple, 50% transparent, 25% purple
).createShader(rect),
blendMode: BlendMode.dstOut,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: RotatedBox(
quarterTurns: -1,
child: ListWheelScrollView(
controller: controller,
itemExtent: 256,
diameterRatio: 2.5,
/* physics: const FixedExtentScrollPhysics(), */
physics: const FixedExtentScrollPhysics(),
children: widget.product.images
.mapIndexed<Widget>(
(idx, image) => RotatedBox(
quarterTurns: 1,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
ProductImageScreen.show(
context,
id: widget.product.id,
index: idx,
);
HapticFeedback.mediumImpact().ignore();
},
child: Hero(
tag: 'product-${widget.product.id}-image-$idx',
child: Ink.image(
image: AssetImage(image),
fit: BoxFit.cover,
height: 256,
width: 256,
alignment: Alignment.center,
),
),
),
),
),
),
)
.map<Widget>(
(child) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: child,
),
)
.toList(growable: false),
)
.map<Widget>(
(child) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: child,
),
)
.toList(growable: false),
),
),
),
),
SizedBox(
height: 24,
child: RepaintBoundary(
child: AnimatedBuilder(
animation: controller,
builder: (context, child) => Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
for (var i = 0; i < widget.product.images.length; i++)
MouseRegion(
onHover: (_) => animateTo(i),
child: GestureDetector(
onTap: () => animateTo(i),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 2),
child: SizedBox.square(
dimension: 16,
child: Material(
color: i == currentPage
? Theme.of(context).colorScheme.primary
: Theme.of(context)
.colorScheme
.secondary
.withAlpha(128),
shape: const CircleBorder(),
SizedBox(
height: 24,
child: RepaintBoundary(
child: AnimatedBuilder(
animation: controller,
builder: (context, child) => Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
for (var i = 0; i < widget.product.images.length; i++)
MouseRegion(
onHover: (_) => animateTo(i),
child: GestureDetector(
onTap: () => animateTo(i),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 2),
child: SizedBox.square(
dimension: 16,
child: Material(
color: i == currentPage
? Theme.of(context).colorScheme.primary
: Theme.of(context)
.colorScheme
.secondary
.withAlpha(128),
shape: const CircleBorder(),
),
),
),
),
),
),
],
],
),
),
),
),
),
],
],
),
);
}

Expand Down
5 changes: 5 additions & 0 deletions lib/src/controller/delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,9 @@ final class OctopusDelegate extends RouterDelegate<OctopusState>
/// Octopus state observer.
abstract interface class OctopusStateObserver<T extends OctopusState>
implements ValueListenable<T> {
/// Max history length.
static const int maxHistoryLength = 10000;

/// Current immutable state.
@override
T get value;
Expand Down Expand Up @@ -438,6 +441,8 @@ final class _OctopusStateObserver
timestamp: DateTime.now(),
),
);
if (_history.length > OctopusStateObserver.maxHistoryLength)
_history.removeAt(0);
notifyListeners();
return true;
}
Expand Down

0 comments on commit 20083cc

Please sign in to comment.