diff --git a/lib/screens/main_window_screen.dart b/lib/screens/main_window_screen.dart index e6514900..d2c07275 100644 --- a/lib/screens/main_window_screen.dart +++ b/lib/screens/main_window_screen.dart @@ -1,18 +1,14 @@ -import 'dart:convert'; -import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_settings_screens/flutter_settings_screens.dart'; import 'package:otzaria/models/app_model.dart'; import 'package:otzaria/screens/favoriets.dart'; import 'package:otzaria/screens/reading_screen.dart'; -import 'package:updat/theme/chips/flat.dart'; -import 'package:updat/updat_window_manager.dart'; -import 'package:http/http.dart' as http; //imports from otzaria import 'package:otzaria/screens/library_browser.dart'; import 'package:otzaria/screens/settings_screen.dart'; import 'package:otzaria/widgets/keyboard_shortcuts.dart'; +import 'package:otzaria/widgets/my_updat_widget.dart'; import 'package:provider/provider.dart'; class MainWindowScreen extends StatefulWidget { @@ -77,48 +73,73 @@ class MainWindowScreenState extends State return SafeArea( child: KeyboardShortcuts( child: Consumer( - builder: (context, appModel, child) => UpdatWindowManager( - getLatestVersion: () async { - // Github gives us a super useful latest endpoint, and we can use it to get the latest stable release - final data = await http.get(Uri.parse( - Settings.getValue('key-dev-channel') ?? false - ? "https://api.github.com/repos/sivan22/otzaria-dev-channel/releases/latest" - : "https://api.github.com/repos/sivan22/otzaria/releases/latest", - )); - - // Return the tag name, which is always a semantically versioned string. - return jsonDecode(data.body)["tag_name"]; - }, - getBinaryUrl: (version) async { - // Github also gives us a great way to download the binary for a certain release (as long as we use a consistent naming scheme) - - // Make sure that this link includes the platform extension with which to save your binary. - // If you use https://exapmle.com/latest/macos for instance then you need to create your own file using `getDownloadFileLocation` - - final repo = Settings.getValue('key-dev-channel') ?? false - ? "otzaria-dev-channel" - : "otzaria"; - return "https://github.com/sivan22/$repo/releases/download/$version/otzaria-$version-${Platform.operatingSystem}.$platformExt"; - }, - appName: "otzaria", // This is used to name the downloaded files. - getChangelog: (_, __) async { - // That same latest endpoint gives us access to a markdown-flavored release body. Perfect! - final repo = Settings.getValue('key-dev-channel') ?? false - ? "otzaria-dev-channel" - : "otzaria"; - final data = await http.get(Uri.parse( - "https://api.github.com/repos/sivan22/$repo/releases/latest", - )); - return jsonDecode(data.body)["body"]; - }, - currentVersion: '0.1.8-dev.2', - updateChipBuilder: flatChip, - - callback: (status) {}, + builder: (context, appModel, child) => MyUpdatWidget( child: Scaffold( body: OrientationBuilder(builder: (context, orientation) { if (orientation == Orientation.landscape) { - return buildHorizontalLayout(appModel); + return Row(children: [ + SizedBox.fromSize( + size: const Size.fromWidth(80), + child: LayoutBuilder( + builder: (context, constraints) => NavigationRail( + labelType: NavigationRailLabelType.all, + destinations: [ + const NavigationRailDestination( + icon: Icon(Icons.library_books), + label: Text('ספרייה'), + ), + const NavigationRailDestination( + icon: Icon(Icons.menu_book), + label: Text('עיון'), + ), + const NavigationRailDestination( + icon: Icon(Icons.search), + label: Text('חיפוש'), + ), + const NavigationRailDestination( + icon: Icon(Icons.star), + label: Text('מועדפים'), + ), + NavigationRailDestination( + icon: const Icon(Icons.settings), + label: const Text('הגדרות'), + padding: EdgeInsets.only( + top: constraints.maxHeight - 340), + ), + ], + selectedIndex: appModel.currentView.value.index, + onDestinationSelected: (int index) { + appModel.currentView.value = Screens.values[index]; + pageController = PageController( + initialPage: index, keepPage: true); + switch (index) { + case 2: + appModel.openNewSearchTab(); + } + setState(() {}); + }), + ), + ), + //mainWindow + Expanded( + child: OrientationBuilder(builder: (context, orientation) { + return PageView( + scrollDirection: orientation == Orientation.landscape + ? Axis.vertical + : Axis.horizontal, + physics: const NeverScrollableScrollPhysics(), + controller: pageController, + children: const [ + LibraryBrowser(), + ReadingScreen(), + SizedBox.shrink(), + FavouritesScreen(), + MySettingsScreen(), + ], + ); + }), + ), + ]); } else { return Column(children: [ Expanded( @@ -135,7 +156,43 @@ class MainWindowScreenState extends State ], ), ), - buildNavigationBottomBar(), + Consumer( + builder: (context, appModel, child) => NavigationBar( + destinations: const [ + NavigationDestination( + icon: Icon(Icons.library_books), + label: 'ספרייה', + ), + NavigationDestination( + icon: Icon(Icons.menu_book), + label: 'עיון', + ), + NavigationDestination( + icon: Icon(Icons.search), + label: 'חיפוש', + ), + NavigationDestination( + icon: Icon(Icons.star), + label: 'מועדפים', + ), + NavigationDestination( + icon: Icon(Icons.settings), + label: 'הגדרות', + ), + ], + selectedIndex: appModel.currentView.value.index, + onDestinationSelected: (int index) { + setState(() { + appModel.currentView.value = Screens.values[index]; + pageController = PageController( + initialPage: index, keepPage: true); + switch (index) { + case 2: + appModel.openNewSearchTab(); + } + }); + }), + ), ]); } }), @@ -145,146 +202,4 @@ class MainWindowScreenState extends State // ) )); } - - Widget buildHorizontalLayout(AppModel appModel) { - return Row(children: [ - buildNavigationSideBar(appModel), - //mainWindow - Expanded( - child: OrientationBuilder(builder: (context, orientation) { - return PageView( - scrollDirection: orientation == Orientation.landscape - ? Axis.vertical - : Axis.horizontal, - physics: const NeverScrollableScrollPhysics(), - controller: pageController, - children: const [ - LibraryBrowser(), - ReadingScreen(), - SizedBox.shrink(), - FavouritesScreen(), - MySettingsScreen(), - ], - ); - }), - ), - ]); - } - - Widget buildLibraryBrowser(AppModel appModel) { - return const Expanded( - child: LibraryBrowser(), - ); - } - - Widget buildSettingsScreen() { - return const Expanded( - child: MySettingsScreen(), - ); - } - - SizedBox buildNavigationSideBar(AppModel appModel) { - return SizedBox.fromSize( - size: const Size.fromWidth(80), - child: NavigationRail( - labelType: NavigationRailLabelType.all, - destinations: const [ - NavigationRailDestination( - icon: Icon(Icons.library_books), - label: Text('ספרייה'), - ), - NavigationRailDestination( - icon: Icon(Icons.menu_book), - label: Text('עיון'), - ), - NavigationRailDestination( - icon: Icon(Icons.search), - label: Text('חיפוש'), - ), - NavigationRailDestination( - icon: Icon(Icons.star), - label: Text('מועדפים'), - ), - NavigationRailDestination( - icon: Icon(Icons.settings), - label: Text('הגדרות'), - ), - ], - selectedIndex: appModel.currentView.value.index, - onDestinationSelected: (int index) { - appModel.currentView.value = Screens.values[index]; - pageController = PageController(initialPage: index, keepPage: true); - switch (index) { - case 2: - appModel.openNewSearchTab(); - } - setState(() {}); - }), - ); - } - - Widget buildNavigationBottomBar() { - return Consumer( - builder: (context, appModel, child) => NavigationBar( - destinations: const [ - NavigationDestination( - icon: Icon(Icons.library_books), - label: 'ספרייה', - ), - NavigationDestination( - icon: Icon(Icons.menu_book), - label: 'עיון', - ), - NavigationDestination( - icon: Icon(Icons.search), - label: 'חיפוש', - ), - NavigationDestination( - icon: Icon(Icons.star), - label: 'מועדפים', - ), - NavigationDestination( - icon: Icon(Icons.settings), - label: 'הגדרות', - ), - ], - selectedIndex: appModel.currentView.value.index, - onDestinationSelected: (int index) { - setState(() { - appModel.currentView.value = Screens.values[index]; - pageController = - PageController(initialPage: index, keepPage: true); - switch (index) { - case 2: - appModel.openNewSearchTab(); - } - }); - }), - ); - } - - String get platformExt { - switch (Platform.operatingSystem) { - case 'windows': - { - return Settings.getValue('key-dev-channel') ?? false - ? 'msix' - : 'exe'; - } - - case 'macos': - { - return 'dmg'; - } - - case 'linux': - { - return 'AppImage'; - } - default: - { - return 'zip'; - } - } - } } diff --git a/lib/screens/simple_book_view.dart b/lib/screens/simple_book_view.dart index 1159fb62..d848b45b 100644 --- a/lib/screens/simple_book_view.dart +++ b/lib/screens/simple_book_view.dart @@ -32,36 +32,42 @@ class _SimpleBookViewState extends State { @override Widget build(BuildContext context) { - return SelectionArea( - key: PageStorageKey(widget.tab), - child: ScrollablePositionedList.builder( - initialScrollIndex: widget.tab.index, - itemPositionsListener: widget.tab.positionsListener, - itemScrollController: widget.tab.scrollController, - scrollOffsetController: widget.tab.scrollOffsetController, - itemCount: widget.data.length, - itemBuilder: (context, index) { - return ValueListenableBuilder( - valueListenable: widget.tab.removeNikud, - builder: (context, removeNikud, child) => InkWell( - onTap: () => widget.tab.selectedIndex.value = index, - child: Html( - //remove nikud if needed - data: removeNikud - ? highLight(removeVolwels(widget.data[index]), - widget.tab.searchTextController.text) - : highLight(widget.data[index], - widget.tab.searchTextController.text), - style: { - 'body': Style( - fontSize: FontSize(widget.textSize), - fontFamily: - Settings.getValue('key-font-family') ?? 'candara', - textAlign: TextAlign.justify), - }), - ), - ); - }), + return ProgressiveScroll( + scrollController: widget.tab.scrollOffsetController, + maxSpeed: 10000.0, + curve: 10.0, + accelerationFactor: 5, + child: SelectionArea( + key: PageStorageKey(widget.tab), + child: ScrollablePositionedList.builder( + initialScrollIndex: widget.tab.index, + itemPositionsListener: widget.tab.positionsListener, + itemScrollController: widget.tab.scrollController, + scrollOffsetController: widget.tab.scrollOffsetController, + itemCount: widget.data.length, + itemBuilder: (context, index) { + return ValueListenableBuilder( + valueListenable: widget.tab.removeNikud, + builder: (context, removeNikud, child) => InkWell( + onTap: () => widget.tab.selectedIndex.value = index, + child: Html( + //remove nikud if needed + data: removeNikud + ? highLight(removeVolwels(widget.data[index]), + widget.tab.searchTextController.text) + : highLight(widget.data[index], + widget.tab.searchTextController.text), + style: { + 'body': Style( + fontSize: FontSize(widget.textSize), + fontFamily: Settings.getValue('key-font-family') ?? + 'candara', + textAlign: TextAlign.justify), + }), + ), + ); + }), + ), ); } } diff --git a/lib/widgets/commentary_list.dart b/lib/widgets/commentary_list.dart index 27766ede..19fb2322 100644 --- a/lib/widgets/commentary_list.dart +++ b/lib/widgets/commentary_list.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:otzaria/models/tabs.dart'; import 'package:otzaria/models/links.dart'; import 'package:otzaria/widgets/commentary_content.dart'; +import 'package:otzaria/widgets/progressive_scrolling.dart'; +import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; class CommentaryList extends StatefulWidget { final Function(TextBookTab) openBookCallback; @@ -26,6 +28,7 @@ class CommentaryList extends StatefulWidget { class _CommentaryListState extends State { late Future> thisLinks; late List indexes; + final ScrollOffsetController scrollController = ScrollOffsetController(); void _updateThisLinks() { thisLinks = getLinksforIndexs( @@ -89,20 +92,26 @@ class _CommentaryListState extends State { : ValueListenableBuilder( valueListenable: widget.textBookTab.removeNikud, builder: (context, _, child) { - return ListView.builder( - key: PageStorageKey(thisLinksSnapshot.data![0].heRef), - physics: const ClampingScrollPhysics(), - primary: true, - shrinkWrap: true, - itemCount: thisLinksSnapshot.data!.length, - itemBuilder: (context, index1) => GestureDetector( - child: ListTile( - title: Text(thisLinksSnapshot.data![index1].heRef), - subtitle: CommentaryContent( - link: thisLinksSnapshot.data![index1], - fontSize: widget.fontSize, - openBookCallback: widget.openBookCallback, - removeNikud: widget.textBookTab.removeNikud.value, + return ProgressiveScroll( + scrollController: scrollController, + maxSpeed: 10000.0, + curve: 10.0, + accelerationFactor: 5, + child: ScrollablePositionedList.builder( + key: PageStorageKey(thisLinksSnapshot.data![0].heRef), + physics: const ClampingScrollPhysics(), + scrollOffsetController: scrollController, + shrinkWrap: true, + itemCount: thisLinksSnapshot.data!.length, + itemBuilder: (context, index1) => GestureDetector( + child: ListTile( + title: Text(thisLinksSnapshot.data![index1].heRef), + subtitle: CommentaryContent( + link: thisLinksSnapshot.data![index1], + fontSize: widget.fontSize, + openBookCallback: widget.openBookCallback, + removeNikud: widget.textBookTab.removeNikud.value, + ), ), ), ), diff --git a/lib/widgets/my_updat_widget.dart b/lib/widgets/my_updat_widget.dart new file mode 100644 index 00000000..3fa55019 --- /dev/null +++ b/lib/widgets/my_updat_widget.dart @@ -0,0 +1,79 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_settings_screens/flutter_settings_screens.dart'; +import 'package:updat/theme/chips/flat.dart'; +import 'package:updat/updat_window_manager.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert'; + +class MyUpdatWidget extends StatelessWidget { + const MyUpdatWidget({Key? key, required this.child}) : super(key: key); + final Widget child; + @override + Widget build(BuildContext context) => UpdatWindowManager( + getLatestVersion: () async { + // Github gives us a super useful latest endpoint, and we can use it to get the latest stable release + final data = await http.get(Uri.parse( + Settings.getValue('key-dev-channel') ?? false + ? "https://api.github.com/repos/sivan22/otzaria-dev-channel/releases/latest" + : "https://api.github.com/repos/sivan22/otzaria/releases/latest", + )); + + // Return the tag name, which is always a semantically versioned string. + return jsonDecode(data.body)["tag_name"]; + }, + getBinaryUrl: (version) async { + // Github also gives us a great way to download the binary for a certain release (as long as we use a consistent naming scheme) + + // Make sure that this link includes the platform extension with which to save your binary. + // If you use https://exapmle.com/latest/macos for instance then you need to create your own file using `getDownloadFileLocation` + + final repo = Settings.getValue('key-dev-channel') ?? false + ? "otzaria-dev-channel" + : "otzaria"; + return "https://github.com/sivan22/$repo/releases/download/$version/otzaria-$version-${Platform.operatingSystem}.$platformExt"; + }, + appName: "otzaria", // This is used to name the downloaded files. + getChangelog: (_, __) async { + // That same latest endpoint gives us access to a markdown-flavored release body. Perfect! + final repo = Settings.getValue('key-dev-channel') ?? false + ? "otzaria-dev-channel" + : "otzaria"; + final data = await http.get(Uri.parse( + "https://api.github.com/repos/sivan22/$repo/releases/latest", + )); + return jsonDecode(data.body)["body"]; + }, + currentVersion: '0.1.8-dev.2', + updateChipBuilder: flatChip, + + callback: (status) {}, + child: child, + ); + + String get platformExt { + switch (Platform.operatingSystem) { + case 'windows': + { + return Settings.getValue('key-dev-channel') ?? false + ? 'msix' + : 'exe'; + } + + case 'macos': + { + return 'dmg'; + } + + case 'linux': + { + return 'AppImage'; + } + default: + { + return 'zip'; + } + } + } +} diff --git a/lib/widgets/progressive_scrolling.dart b/lib/widgets/progressive_scrolling.dart index d367741e..7acc2f27 100644 --- a/lib/widgets/progressive_scrolling.dart +++ b/lib/widgets/progressive_scrolling.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:otzaria/models/app_model.dart'; +import 'package:provider/provider.dart'; import 'dart:math'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; @@ -44,7 +46,7 @@ class _ProgressiveScrollState extends State { double curvedT = exp(widget.curve * t); _scrollSpeed = (curvedT * widget.accelerationFactor * _scrollDirection) .clamp(-widget.maxSpeed, widget.maxSpeed); - print('scroll speed: $_scrollSpeed'); + //print('scroll speed: $_scrollSpeed'); } else { _scrollSpeed = 0; _timePressedInSeconds = 0; @@ -78,7 +80,7 @@ class _ProgressiveScrollState extends State { _isKeyPressed = false; widget.scrollController.animateScroll( offset: 100.0 * _scrollDirection, - duration: const Duration(milliseconds: 300), + duration: const Duration(milliseconds: 150), ); _scrollDirection = 0; } @@ -88,7 +90,7 @@ class _ProgressiveScrollState extends State { @override Widget build(BuildContext context) { return KeyboardListener( - focusNode: FocusNode(), + focusNode: Provider.of(context).bookLocatorFocusNode, onKeyEvent: _handleKeyEvent, autofocus: true, child: widget.child,