Skip to content

Commit

Permalink
Update history and add gallery screen
Browse files Browse the repository at this point in the history
  • Loading branch information
PlugFox committed Nov 29, 2023
1 parent 24166f8 commit b5a48a7
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 73 deletions.
2 changes: 1 addition & 1 deletion example/lib/src/common/router/authentication_guard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class AuthenticationGuard extends OctopusGuard {

@override
FutureOr<OctopusState?> call(
List<OctopusState> history,
List<OctopusHistoryEntry> history,
OctopusState state,
) async {
final user = await _getUser(); // Get the current user.
Expand Down
163 changes: 112 additions & 51 deletions example/lib/src/common/widget/router_state_observer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,45 +53,51 @@ class RouterStateObserver extends StatelessWidget {
child: DefaultTabController(
initialIndex: 0,
length: 3,
child: Scaffold(
body: Column(
children: <Widget>[
const SizedBox(
height: 72,
child: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.navigation),
text: 'State',
),
Tab(
icon: Icon(Icons.history),
text: 'History',
),
Tab(
icon: Icon(Icons.error),
text: 'Errors',
),
],
),
),
Expanded(
child: TabBarView(
child: Overlay(
initialEntries: [
OverlayEntry(
builder: (context) => Scaffold(
body: Column(
children: <Widget>[
_RouterStateObserver$Tree(
observer: octopus.stateObserver,
const SizedBox(
height: 72,
child: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.navigation),
text: 'State',
),
Tab(
icon: Icon(Icons.history),
text: 'History',
),
Tab(
icon: Icon(Icons.error),
text: 'Errors',
),
],
),
),
_RouterStateObserver$History(
octopus: octopus,
),
_RouterStateObserver$Errors(
observer: errorsObserver,
Expanded(
child: TabBarView(
children: <Widget>[
_RouterStateObserver$Tree(
observer: octopus.stateObserver,
),
_RouterStateObserver$History(
octopus: octopus,
),
_RouterStateObserver$Errors(
observer: errorsObserver,
),
],
),
),
],
),
),
],
),
),
],
),
),
),
Expand Down Expand Up @@ -125,7 +131,7 @@ class _RouterStateObserver$Tree extends StatelessWidget {
);
}

class _RouterStateObserver$History extends StatelessWidget {
class _RouterStateObserver$History extends StatefulWidget {
const _RouterStateObserver$History({
required this.octopus,
super.key,
Expand All @@ -134,27 +140,82 @@ class _RouterStateObserver$History extends StatelessWidget {
final Octopus octopus;

@override
Widget build(BuildContext context) => ValueListenableBuilder<OctopusState>(
valueListenable: octopus.stateObserver,
builder: (context, state, child) {
final history = octopus.history;
return ListView.builder(
/* physics: const NeverScrollableScrollPhysics(), */
itemCount: history.length,
itemBuilder: (context, index) {
final state = history[index];
final location = state.location;
return ListTile(
onTap: () => octopus.setState((_) => state),
State<_RouterStateObserver$History> createState() =>
_RouterStateObserver$HistoryState();
}

class _RouterStateObserver$HistoryState
extends State<_RouterStateObserver$History> {
List<OctopusHistoryEntry> history = <OctopusHistoryEntry>[];
final ScrollController scrollController = ScrollController();

@override
void initState() {
super.initState();
widget.octopus.stateObserver.addListener(_listener);
history = widget.octopus.history;
}

@override
void didUpdateWidget(covariant _RouterStateObserver$History oldWidget) {
super.didUpdateWidget(oldWidget);
oldWidget.octopus.stateObserver.removeListener(_listener);
widget.octopus.stateObserver.addListener(_listener);
}

@override
void dispose() {
widget.octopus.stateObserver.removeListener(_listener);
super.dispose();
}

void _listener() {
if (!mounted) return;
setState(() {
history = widget.octopus.history;
});
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
scrollController.animateTo(
scrollController.position.maxScrollExtent + 42,
duration: const Duration(milliseconds: 250),
curve: Curves.easeOut,
);
});
}

@override
Widget build(BuildContext context) => ListView.builder(
/* physics: const NeverScrollableScrollPhysics(), */
controller: scrollController,
itemCount: history.length,
itemExtent: 42,
scrollDirection: Axis.vertical,
reverse: true,
itemBuilder: (context, index) {
final entry = history[index];
final state = entry.state;
final location = state.location;
return SizedBox(
height: 42,
child: Tooltip(
message: location,
child: ListTile(
key: ValueKey<int>(entry.hashCode),
onTap: index == history.length - 1
? null
: () => widget.octopus.setState((_) => state),
dense: true,
title: Text(
location,
/* style: const TextStyle(
overflow: TextOverflow.clip,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 12,
), */
),
),
);
},
),
),
);
},
);
Expand Down
69 changes: 66 additions & 3 deletions example/lib/src/feature/gallery/widget/gallery_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,72 @@ class GalleryScreen extends StatelessWidget {
appBar: AppBar(
title: const Text('Gallery'),
),
body: const SafeArea(
child: Center(
child: Text('Gallery'),
body: SafeArea(
child: GridView.builder(
padding: const EdgeInsets.all(24),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 152,
//mainAxisExtent: 180,
childAspectRatio: 152 / 180,
crossAxisSpacing: 24,
mainAxisSpacing: 24,
),
itemCount: 1000,
itemBuilder: (context, index) => _GalleryTile(index),
),
),
);
}

class _GalleryTile extends StatelessWidget {
// ignore: unused_element
const _GalleryTile(this.index, {super.key});

final int index;

@override
Widget build(BuildContext context) => Card(
color: const Color(0xFFcfd8dc),
margin: EdgeInsets.zero,
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: Center(
child: AspectRatio(
aspectRatio: 1,
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(8),
),
child: const Padding(
padding: EdgeInsets.all(8),
child: Placeholder(),
),
),
),
),
),
SizedBox(
height: 36,
child: Center(
child: Text(
'Item\n$index',
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodySmall,
),
),
),
],
),
),
);
Expand Down
3 changes: 2 additions & 1 deletion lib/octopus.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
library octopus;

export 'src/controller/delegate.dart' show OctopusStateObserver;
export 'src/controller/delegate.dart'
show OctopusStateObserver, OctopusHistoryEntry;
export 'src/controller/guard.dart';
export 'src/controller/octopus.dart';
export 'src/state/state.dart' show OctopusState, OctopusNode, OctopusRoute;
Expand Down
Loading

0 comments on commit b5a48a7

Please sign in to comment.