Merge pull request #1635 from Kingtous/master

refactor: global scroll
This commit is contained in:
RustDesk 2022-09-28 12:48:37 +08:00 committed by GitHub
commit a4774b0824
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 72 deletions

View File

@ -18,7 +18,6 @@ class PeerTabPage extends StatefulWidget {
class _PeerTabPageState extends State<PeerTabPage> class _PeerTabPageState extends State<PeerTabPage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late final PageController _pageController = PageController();
final RxInt _tabIndex = 0.obs; final RxInt _tabIndex = 0.obs;
@override @override
@ -28,7 +27,6 @@ class _PeerTabPageState extends State<PeerTabPage>
if (value == '') return; if (value == '') return;
final tab = int.parse(value); final tab = int.parse(value);
_tabIndex.value = tab; _tabIndex.value = tab;
_pageController.jumpToPage(tab);
}); });
await bind.mainGetLocalOption(key: 'peer-card-ui-type').then((value) { await bind.mainGetLocalOption(key: 'peer-card-ui-type').then((value) {
if (value == '') return; if (value == '') return;
@ -45,7 +43,6 @@ class _PeerTabPageState extends State<PeerTabPage>
_tabIndex.value = index; _tabIndex.value = index;
await bind.mainSetLocalOption( await bind.mainSetLocalOption(
key: 'peer-tab-index', value: index.toString()); key: 'peer-tab-index', value: index.toString());
_pageController.jumpToPage(index);
switch (index) { switch (index) {
case 0: case 0:
bind.mainLoadRecentPeers(); bind.mainLoadRecentPeers();
@ -64,7 +61,6 @@ class _PeerTabPageState extends State<PeerTabPage>
@override @override
void dispose() { void dispose() {
_pageController.dispose();
super.dispose(); super.dispose();
} }
@ -82,7 +78,7 @@ class _PeerTabPageState extends State<PeerTabPage>
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Expanded(child: _createTabBar(context)), Expanded(child: _createSwitchBar(context)),
const SizedBox(width: 10), const SizedBox(width: 10),
const PeerSearchBar(), const PeerSearchBar(),
Offstage( Offstage(
@ -92,12 +88,12 @@ class _PeerTabPageState extends State<PeerTabPage>
], ],
)), )),
), ),
_createTabBarView(), _createPeersView(),
], ],
); );
} }
Widget _createTabBar(BuildContext context) { Widget _createSwitchBar(BuildContext context) {
final textColor = Theme.of(context).textTheme.titleLarge?.color; final textColor = Theme.of(context).textTheme.titleLarge?.color;
return ListView( return ListView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@ -131,17 +127,13 @@ class _PeerTabPageState extends State<PeerTabPage>
}).toList()); }).toList());
} }
Widget _createTabBarView() { Widget _createPeersView() {
final verticalMargin = isDesktop ? 12.0 : 6.0; final verticalMargin = isDesktop ? 12.0 : 6.0;
return Expanded( return Expanded(
child: PageView( child: Obx(() => widget
physics: isDesktop .children[_tabIndex.value]) //: (to) => _tabIndex.value = to)
? NeverScrollableScrollPhysics() .marginSymmetric(vertical: verticalMargin),
: BouncingScrollPhysics(), );
controller: _pageController,
children: super.widget.children,
onPageChanged: (to) => _tabIndex.value = to)
.marginSymmetric(vertical: verticalMargin));
} }
Widget _createPeerViewTypeSwitch(BuildContext context) { Widget _createPeerViewTypeSwitch(BuildContext context) {

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart'; import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -25,12 +26,14 @@ class _PeersView extends StatefulWidget {
final Peers peers; final Peers peers;
final OffstageFunc offstageFunc; final OffstageFunc offstageFunc;
final PeerCardBuilder peerCardBuilder; final PeerCardBuilder peerCardBuilder;
final ScrollController? scrollController;
const _PeersView( const _PeersView(
{required this.peers, {required this.peers,
required this.offstageFunc, required this.offstageFunc,
required this.peerCardBuilder, required this.peerCardBuilder,
Key? key}) Key? key,
this.scrollController})
: super(key: key); : super(key: key);
@override @override
@ -42,7 +45,6 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
static const int _maxQueryCount = 3; static const int _maxQueryCount = 3;
final space = isDesktop ? 12.0 : 8.0; final space = isDesktop ? 12.0 : 8.0;
final _curPeers = <String>{}; final _curPeers = <String>{};
final _scrollController = ScrollController();
var _lastChangeTime = DateTime.now(); var _lastChangeTime = DateTime.now();
var _lastQueryPeers = <String>{}; var _lastQueryPeers = <String>{};
var _lastQueryTime = DateTime.now().subtract(const Duration(hours: 1)); var _lastQueryTime = DateTime.now().subtract(const Duration(hours: 1));
@ -93,9 +95,10 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
create: (context) => widget.peers, create: (context) => widget.peers,
child: Consumer<Peers>( child: Consumer<Peers>(
builder: (context, peers, child) => peers.peers.isEmpty builder: (context, peers, child) => peers.peers.isEmpty
? Center( ? Container(
child: Text(translate("Empty")), margin: EdgeInsets.only(top: kEmptyMarginTop),
) alignment: Alignment.topCenter,
child: Text(translate("Empty")))
: _buildPeersView(peers)), : _buildPeersView(peers)),
); );
} }
@ -147,21 +150,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener {
); );
}, peerSearchText); }, peerSearchText);
if (isDesktop) { return body;
return DesktopScrollWrapper(
scrollController: _scrollController,
child: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
controller: _scrollController,
child: body),
);
} else {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
controller: _scrollController,
child: body,
);
}
} }
// ignore: todo // ignore: todo
@ -224,7 +213,8 @@ abstract class BasePeersView extends StatelessWidget {
} }
class RecentPeersView extends BasePeersView { class RecentPeersView extends BasePeersView {
RecentPeersView({Key? key, EdgeInsets? menuPadding}) RecentPeersView(
{Key? key, EdgeInsets? menuPadding, ScrollController? scrollController})
: super( : super(
key: key, key: key,
name: 'recent peer', name: 'recent peer',
@ -246,7 +236,8 @@ class RecentPeersView extends BasePeersView {
} }
class FavoritePeersView extends BasePeersView { class FavoritePeersView extends BasePeersView {
FavoritePeersView({Key? key, EdgeInsets? menuPadding}) FavoritePeersView(
{Key? key, EdgeInsets? menuPadding, ScrollController? scrollController})
: super( : super(
key: key, key: key,
name: 'favorite peer', name: 'favorite peer',
@ -268,7 +259,8 @@ class FavoritePeersView extends BasePeersView {
} }
class DiscoveredPeersView extends BasePeersView { class DiscoveredPeersView extends BasePeersView {
DiscoveredPeersView({Key? key, EdgeInsets? menuPadding}) DiscoveredPeersView(
{Key? key, EdgeInsets? menuPadding, ScrollController? scrollController})
: super( : super(
key: key, key: key,
name: 'discovered peer', name: 'discovered peer',
@ -290,7 +282,8 @@ class DiscoveredPeersView extends BasePeersView {
} }
class AddressBookPeersView extends BasePeersView { class AddressBookPeersView extends BasePeersView {
AddressBookPeersView({Key? key, EdgeInsets? menuPadding}) AddressBookPeersView(
{Key? key, EdgeInsets? menuPadding, ScrollController? scrollController})
: super( : super(
key: key, key: key,
name: 'address book peer', name: 'address book peer',

View File

@ -20,6 +20,9 @@ const int kDesktopDefaultDisplayWidth = 1080;
const int kDesktopDefaultDisplayHeight = 720; const int kDesktopDefaultDisplayHeight = 720;
const Size kConnectionManagerWindowSize = Size(300, 400); const Size kConnectionManagerWindowSize = Size(300, 400);
// Tabbar transition duration, now we remove the duration
const Duration kTabTransitionDuration = Duration.zero;
const double kEmptyMarginTop = 50;
/// [kDefaultScrollAmountMultiplier] indicates how many rows can be scrolled after a minimum scroll action of mouse /// [kDefaultScrollAmountMultiplier] indicates how many rows can be scrolled after a minimum scroll action of mouse
const kDefaultScrollAmountMultiplier = 5.0; const kDefaultScrollAmountMultiplier = 5.0;

View File

@ -6,6 +6,7 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hbb/common/widgets/address_book.dart'; import 'package:flutter_hbb/common/widgets/address_book.dart';
import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
@ -25,10 +26,14 @@ class ConnectionPage extends StatefulWidget {
} }
/// State for the connection page. /// State for the connection page.
class _ConnectionPageState extends State<ConnectionPage> { class _ConnectionPageState extends State<ConnectionPage>
with SingleTickerProviderStateMixin {
/// Controller for the id input bar. /// Controller for the id input bar.
final _idController = IDTextEditingController(); final _idController = IDTextEditingController();
/// Nested scroll controller
final _scrollController = ScrollController();
Timer? _updateTimer; Timer? _updateTimer;
@override @override
@ -51,15 +56,16 @@ class _ConnectionPageState extends State<ConnectionPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Column(
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.start, Expanded(
mainAxisSize: MainAxisSize.max, child: DesktopScrollWrapper(
crossAxisAlignment: CrossAxisAlignment.start, scrollController: _scrollController,
children: <Widget>[ child: CustomScrollView(
Expanded( controller: _scrollController,
child: Column( slivers: [
children: [ SliverList(
delegate: SliverChildListDelegate([
Row( Row(
children: [ children: [
_buildRemoteIDTextField(context), _buildRemoteIDTextField(context),
@ -67,8 +73,10 @@ class _ConnectionPageState extends State<ConnectionPage> {
).marginOnly(top: 22), ).marginOnly(top: 22),
SizedBox(height: 12), SizedBox(height: 12),
Divider(), Divider(),
Expanded( ])),
child: PeerTabPage( SliverFillRemaining(
hasScrollBody: false,
child: PeerTabPage(
tabs: [ tabs: [
translate('Recent Sessions'), translate('Recent Sessions'),
translate('Favorites'), translate('Favorites'),
@ -89,14 +97,16 @@ class _ConnectionPageState extends State<ConnectionPage> {
menuPadding: EdgeInsets.only(left: 12.0, right: 3.0), menuPadding: EdgeInsets.only(left: 12.0, right: 3.0),
), ),
], ],
)), ),
], )
).marginSymmetric(horizontal: 22), ],
), ).marginSymmetric(horizontal: 12.0),
const Divider(), ),
SizedBox(child: Obx(() => buildStatus())) ),
.paddingOnly(bottom: 12, top: 6), const Divider(),
]), SizedBox(child: Obx(() => buildStatus()))
.paddingOnly(bottom: 12, top: 6),
],
); );
} }

View File

@ -7,6 +7,7 @@ import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/desktop/pages/connection_page.dart'; import 'package:flutter_hbb/desktop/pages/connection_page.dart';
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart'; import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart'; import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/server_model.dart'; import 'package:flutter_hbb/models/server_model.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart';
@ -29,6 +30,8 @@ const borderColor = Color(0xFF2F65BA);
class _DesktopHomePageState extends State<DesktopHomePage> class _DesktopHomePageState extends State<DesktopHomePage>
with TrayListener, WindowListener, AutomaticKeepAliveClientMixin { with TrayListener, WindowListener, AutomaticKeepAliveClientMixin {
final _leftPaneScrollController = ScrollController();
@override @override
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
var updateUrl = ''; var updateUrl = '';
@ -56,6 +59,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
buildLeftPane(context), buildLeftPane(context),
const VerticalDivider( const VerticalDivider(
@ -69,19 +73,25 @@ class _DesktopHomePageState extends State<DesktopHomePage>
); );
} }
buildLeftPane(BuildContext context) { Widget buildLeftPane(BuildContext context) {
return ChangeNotifierProvider.value( return ChangeNotifierProvider.value(
value: gFFI.serverModel, value: gFFI.serverModel,
child: Container( child: Container(
width: 200, width: 200,
color: Theme.of(context).backgroundColor, color: Theme.of(context).backgroundColor,
child: Column( child: DesktopScrollWrapper(
children: [ scrollController: _leftPaneScrollController,
buildTip(context), child: SingleChildScrollView(
buildIDBoard(context), controller: _leftPaneScrollController,
buildPasswordBoard(context), child: Column(
buildHelpCards(), children: [
], buildTip(context),
buildIDBoard(context),
buildPasswordBoard(context),
buildHelpCards(),
],
),
),
), ),
), ),
); );

View File

@ -194,10 +194,8 @@ void runConnectionManagerScreen() async {
getHiddenTitleBarWindowOptions(size: kConnectionManagerWindowSize); getHiddenTitleBarWindowOptions(size: kConnectionManagerWindowSize);
// ensure initial window size to be changed // ensure initial window size to be changed
await windowManager.setSize(kConnectionManagerWindowSize); await windowManager.setSize(kConnectionManagerWindowSize);
await Future.wait([ await Future.wait(
windowManager.setAlignment(Alignment.topRight), [windowManager.setAlignment(Alignment.topRight), initEnv(kAppTypeMain)]);
initEnv(kAppTypeMain)
]);
runApp(GetMaterialApp( runApp(GetMaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: MyTheme.lightTheme, theme: MyTheme.lightTheme,