Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
leoafarias committed Aug 9, 2024
1 parent 9e19286 commit d20b299
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

import '../../helpers/hooks.dart';
import '../../helpers/routes.dart';
import '../../helpers/utils.dart';
import '../../providers/controller.dart';
import '../atoms/slide_thumbnail.dart';
Expand All @@ -18,8 +19,8 @@ class SlideThumbnailList extends HookWidget {

@override
Widget build(BuildContext context) {
final navigation = useNavigation();
final currentPage = navigation.page;
final currentSlideIndex = context.currentSlideIndex;

final slides = useSlides();
final controller = useScrollVisibleController();
final visibleItems = controller.visibleItems;
Expand All @@ -28,12 +29,12 @@ class SlideThumbnailList extends HookWidget {
if (visibleItems.isEmpty) return;

final visibleItem =
visibleItems.firstWhereOrNull((e) => e.index == currentPage);
visibleItems.firstWhereOrNull((e) => e.index == currentSlideIndex);

double alignment;

if (visibleItem == null) {
final isBeginning = visibleItems.first.index > currentPage;
final isBeginning = visibleItems.first.index > currentSlideIndex;

alignment = isBeginning ? 0 : 0.7;
} else {
Expand All @@ -48,14 +49,14 @@ class SlideThumbnailList extends HookWidget {
}
}
controller.itemScrollController.scrollTo(
index: currentPage,
index: currentSlideIndex,
alignment: alignment,
duration: _duration,
curve: _curve,
);

return;
}, [currentPage, slides]);
}, [currentSlideIndex, slides]);

return Container(
color: Colors.black,
Expand All @@ -73,8 +74,8 @@ class SlideThumbnailList extends HookWidget {
),
child: SlideThumbnail(
page: index + 1,
selected: currentPage == index,
onTap: () => navigation.goToPage(index),
selected: currentSlideIndex == index,
onTap: () => context.goToSlide(index),
slide: slides[index],
),
);
Expand Down
38 changes: 17 additions & 21 deletions packages/superdeck/lib/components/molecules/split_view.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';

import '../../helpers/hooks.dart';
import '../../helpers/routes.dart';
import '../../helpers/utils.dart';
import '../../superdeck.dart';
import '../atoms/sized_transition.dart';
import 'navigation_rail.dart';
import 'slide_thumbnail_list.dart';
Expand All @@ -21,16 +20,18 @@ class SplitView extends HookWidget {

@override
Widget build(BuildContext context) {
final navigation = useNavigation();
final sideSize = useState(context.isMobileLandscape ? 200.0 : _maxWidth);
final location = useRouteLocation();

final locationIndex = switch (location) {
'/' => 0,
'/export' => 1,
'/settings' => 2,
_ => 0,
};
int locationIndex() {
final currentPath = context.currentPath;
if (currentPath.startsWith(SDPaths.home.path)) {
return 0;
}
if (currentPath.startsWith(SDPaths.export.path)) {
return 1;
}
return 0;
}

final animationController = useAnimationController(
duration: Durations.medium1,
Expand All @@ -40,14 +41,14 @@ class SplitView extends HookWidget {
parent: animationController,
curve: Curves.ease,
));

print('Drawer is open: ${context.isDrawerOpen}');
usePostFrameEffect(() {
if (navigation.sideIsOpen) {
if (context.isDrawerOpen) {
animationController.forward();
} else {
animationController.reverse();
}
}, [navigation.sideIsOpen]);
}, [context.isDrawerOpen]);

const sideHeight = 200.0;

Expand Down Expand Up @@ -75,12 +76,11 @@ class SplitView extends HookWidget {
child: Row(
children: [
CustomNavigationRail(
selectedIndex: locationIndex,
selectedIndex: locationIndex(),
onDestinationSelected: (value) {
return switch (value) {
0 => context.go('/'),
1 => context.push('/export'),
2 => context.go('/settings'),
0 => context.goPath(SDPaths.home),
1 => context.pushPath(SDPaths.export),
_ => null,
};
},
Expand All @@ -94,10 +94,6 @@ class SplitView extends HookWidget {
icon: Icons.save_alt,
label: 'Export',
),
CustomNavigationRailDestination(
icon: Icons.settings,
label: 'Settings',
),
],
),
const Expanded(
Expand Down
34 changes: 9 additions & 25 deletions packages/superdeck/lib/components/organisms/app_shell.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';

import '../../helpers/routes.dart';
import '../../helpers/utils.dart';
import '../../superdeck.dart';
import '../molecules/split_view.dart';
Expand All @@ -23,44 +24,27 @@ class AppShell extends HookWidget {
@override
Widget build(BuildContext context) {
final isSmall = context.isSmall;
final navigation = useNavigation();
final slides = useSlides();
final invalidSlides = slides.whereType<InvalidSlide>().toList();

final handlePrevious = useCallback(() {
if (navigation.page == 0) return;
navigation.goToPage(navigation.page - 1);
}, [navigation]);

final handleNext = useCallback(() {
if (navigation.page == slides.length - 1) return;
navigation.goToPage(navigation.page + 1);
}, [navigation, slides.length]);
final slides = useSlides();

final handleToggleSide = useCallback(() {
if (navigation.sideIsOpen) {
navigation.closeSide();
} else {
navigation.openSide();
}
}, [navigation.sideIsOpen]);
final invalidSlides = slides.whereType<InvalidSlide>().toList();

final bindings = {
const SingleActivator(
LogicalKeyboardKey.arrowRight,
): handleNext,
): context.nextSlide,
const SingleActivator(
LogicalKeyboardKey.arrowDown,
): handleNext,
): context.nextSlide,
const SingleActivator(
LogicalKeyboardKey.space,
): handleNext,
): context.nextSlide,
const SingleActivator(
LogicalKeyboardKey.arrowLeft,
): handlePrevious,
): context.previousSlide,
const SingleActivator(
LogicalKeyboardKey.arrowUp,
): handlePrevious,
): context.previousSlide,
};

return CallbackShortcuts(
Expand All @@ -75,7 +59,7 @@ class AppShell extends HookWidget {
? FloatingActionButtonLocation.miniEndFloat
: FloatingActionButtonLocation.miniStartFloat,
floatingActionButton: FloatingActionButton.small(
onPressed: handleToggleSide,
onPressed: context.toggleDrawer,
child: Badge(
label: Text(invalidSlides.length.toString()),
isLabelVisible: invalidSlides.isNotEmpty,
Expand Down
1 change: 0 additions & 1 deletion packages/superdeck/lib/components/superdeck_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class SuperDeckApp extends HookWidget {

await Future.wait([
SuperDeckController.initialize(),
NavigationController.initialize(),
SyntaxHighlight.initialize(),
_initializeWindowManager(),
]);
Expand Down
13 changes: 0 additions & 13 deletions packages/superdeck/lib/helpers/hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,3 @@ GoRouter useGoRouter() {
final context = useContext();
return GoRouter.of(context);
}

String useRouteLocation() {
final router = useGoRouter();
final uri = useState(router.routeInformationProvider.value.uri);

useEffect(() {
router.routerDelegate.addListener(() {
uri.value = router.routeInformationProvider.value.uri;
});
}, [router.routerDelegate]);

return uri.value.toString();
}
117 changes: 111 additions & 6 deletions packages/superdeck/lib/helpers/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import '../screens/export_screen.dart';
import '../screens/presentation_screen.dart';

class SDPaths {
static Path get presentation => Path('/');
static Path get home => Path('/');
static ExportPath get export => ExportPath();

static Param<Param> get slides => Param('slides', 'page');
static SlidesPath get slides => SlidesPath();
}

class SlidesPath extends Path<SlidesPath> {
SlidesPath() : super('slides');

SlidePageIndexPath get _pageIndex => SlidePageIndexPath(this);
}

class ExportPath extends Path<ExportPath> {
Expand All @@ -23,26 +29,53 @@ class ExportPath extends Path<ExportPath> {
Path get best => Path('best', parent: this);
}

class SlidePageIndexPath extends Param<SlidePageIndexPath> {
SlidePageIndexPath(SlidesPath parent)
: super.only('pageIndex', parent: parent);
}

final _rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root');
final _sectionANavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'sectionANav');

final goRouterConfig = GoRouter(
navigatorKey: _rootNavigatorKey,
initialLocation: '/',
initialLocation: SDPaths.home.goRoute,
routes: <RouteBase>[
StatefulShellRoute.indexedStack(
builder: (context, state, navigationShell) {
return AppShell(navigationShell: navigationShell);
},
branches: [
// The route branch for the first tab of the bottom navigation bar.
StatefulShellBranch(
navigatorKey: _sectionANavigatorKey,
routes: [
GoRoute(
path: SDPaths.presentation.goRoute,
builder: (context, state) => const PresentationScreen(),
path: SDPaths.home.goRoute,
builder: (context, state) {
return PresentationScreen(slideIndex: 0);
},
),
GoRoute(
path: SDPaths.slides.goRoute,
// Dynamic path for slides/pageNumber
builder: (context, state) {
return PresentationScreen();
},
routes: [
GoRoute(
path: SDPaths.slides._pageIndex.goRoute,
builder: (context, state) {
// Extract the page number
final slideIndex = int.tryParse(state
.pathParameters[SDPaths.slides._pageIndex.id] ??
'0') ??
0;

return PresentationScreen(slideIndex: slideIndex);
},
),
],
),
],
),
Expand All @@ -66,3 +99,75 @@ final goRouterConfig = GoRouter(
),
],
);

extension BuildContextRoutesX on BuildContext {
int get currentSlideIndex {
final currentPath = GoRouterState.of(this).uri.toString();
final slidesPath = SDPaths.slides.path;
final match = RegExp("$slidesPath" + r'/(\d+)').firstMatch(currentPath);

if (match == null) {
return 0;
}

return int.parse(match.group(1)!);
}

void goToSlide(int index) {
go(SDPaths.slides._pageIndex
.define('$index')
.query(_drawerQueryParam)
.path);
}

void nextSlide() {
goToSlide(currentSlideIndex + 1);
}

String get currentPath {
return GoRouterState.of(this).uri.toString();
}

void previousSlide() {
goToSlide(currentSlideIndex - 1);
}

String _replaceQueryParam(String key, String value) {
final uri = GoRouterState.of(this).uri;
final queryParameters = Map<String, String>.from(uri.queryParameters);
queryParameters[key] = value;
return uri.replace(queryParameters: queryParameters).toString();
}

void openDrawer() {
go(_replaceQueryParam('drawer', 'open'));
}

void closeDrawer() {
go(_replaceQueryParam('drawer', 'close'));
}

void toggleDrawer() {
if (isDrawerOpen) {
closeDrawer();
} else {
openDrawer();
}
}

bool get isDrawerOpen {
return GoRouterState.of(this).uri.queryParameters['drawer'] == 'open';
}

Map<String, String> get _drawerQueryParam {
return {'drawer': isDrawerOpen ? 'open' : 'close'};
}

void goPath(Path path) {
go(path.query(_drawerQueryParam).path);
}

void pushPath(Path path) {
push(path.query(_drawerQueryParam).path);
}
}
Loading

0 comments on commit d20b299

Please sign in to comment.