Merge pull request #1373 from Heap-Hop/fix/view_page_key

fix: PageView tab dispose bug & peercard double click
This commit is contained in:
RustDesk 2022-08-26 13:09:12 +08:00 committed by GitHub
commit fc46952c98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 71 deletions

View File

@ -30,12 +30,13 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
_ConnectionTabPageState(Map<String, dynamic> params) { _ConnectionTabPageState(Map<String, dynamic> params) {
if (params['id'] != null) { if (params['id'] != null) {
tabController.state.value.tabs.add(TabInfo( tabController.add(TabInfo(
key: params['id'], key: params['id'],
label: params['id'], label: params['id'],
selectedIcon: selectedIcon, selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon, unselectedIcon: unselectedIcon,
page: RemotePage( page: RemotePage(
key: ValueKey(params['id']),
id: params['id'], id: params['id'],
tabBarHeight: tabBarHeight:
_fullscreenID.value.isNotEmpty ? 0 : kDesktopRemoteTabBarHeight, _fullscreenID.value.isNotEmpty ? 0 : kDesktopRemoteTabBarHeight,
@ -63,8 +64,8 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
label: id, label: id,
selectedIcon: selectedIcon, selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon, unselectedIcon: unselectedIcon,
closable: false,
page: RemotePage( page: RemotePage(
key: ValueKey(id),
id: id, id: id,
tabBarHeight: _fullscreenID.value.isNotEmpty tabBarHeight: _fullscreenID.value.isNotEmpty
? 0 ? 0

View File

@ -19,13 +19,15 @@ class _DesktopTabPageState extends State<DesktopTabPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
tabController.state.value.tabs.add(TabInfo( tabController.add(TabInfo(
key: kTabLabelHomePage, key: kTabLabelHomePage,
label: kTabLabelHomePage, label: kTabLabelHomePage,
selectedIcon: Icons.home_sharp, selectedIcon: Icons.home_sharp,
unselectedIcon: Icons.home_outlined, unselectedIcon: Icons.home_outlined,
closable: false, closable: false,
page: DesktopHomePage())); page: DesktopHomePage(
key: const ValueKey(kTabLabelHomePage),
)));
} }
@override @override
@ -59,6 +61,6 @@ class _DesktopTabPageState extends State<DesktopTabPage> {
label: kTabLabelSettingPage, label: kTabLabelSettingPage,
selectedIcon: Icons.build_sharp, selectedIcon: Icons.build_sharp,
unselectedIcon: Icons.build_outlined, unselectedIcon: Icons.build_outlined,
page: DesktopSettingPage())); page: DesktopSettingPage(key: const ValueKey(kTabLabelSettingPage))));
} }
} }

View File

@ -26,12 +26,12 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> {
static final IconData unselectedIcon = Icons.file_copy_outlined; static final IconData unselectedIcon = Icons.file_copy_outlined;
_FileManagerTabPageState(Map<String, dynamic> params) { _FileManagerTabPageState(Map<String, dynamic> params) {
tabController.state.value.tabs.add(TabInfo( tabController.add(TabInfo(
key: params['id'], key: params['id'],
label: params['id'], label: params['id'],
selectedIcon: selectedIcon, selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon, unselectedIcon: unselectedIcon,
page: FileManagerPage(id: params['id']))); page: FileManagerPage(key: ValueKey(params['id']), id: params['id'])));
} }
@override @override
@ -53,7 +53,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> {
label: id, label: id,
selectedIcon: selectedIcon, selectedIcon: selectedIcon,
unselectedIcon: unselectedIcon, unselectedIcon: unselectedIcon,
page: FileManagerPage(id: id))); page: FileManagerPage(key: ValueKey(id), id: id)));
} else if (call.method == "onDestroy") { } else if (call.method == "onDestroy") {
tabController.state.value.tabs.forEach((tab) { tabController.state.value.tabs.forEach((tab) {
print("executing onDestroy hook, closing ${tab.label}}"); print("executing onDestroy hook, closing ${tab.label}}");

View File

@ -35,9 +35,10 @@ class _PeerCard extends StatefulWidget {
/// State for the connection page. /// State for the connection page.
class _PeerCardState extends State<_PeerCard> class _PeerCardState extends State<_PeerCard>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
var _menuPos; var _menuPos = RelativeRect.fill;
final double _cardRadis = 20; final double _cardRadis = 20;
final double _borderWidth = 2; final double _borderWidth = 2;
final RxBool _iconMoreHover = false.obs;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -64,7 +65,7 @@ class _PeerCardState extends State<_PeerCard>
: null); : null);
}, },
child: GestureDetector( child: GestureDetector(
onDoubleTapDown: (_) => _connect(peer.id), onDoubleTap: () => _connect(peer.id),
child: Obx(() => peerCardUiType.value == PeerUiType.grid child: Obx(() => peerCardUiType.value == PeerUiType.grid
? _buildPeerCard(context, peer, deco) ? _buildPeerCard(context, peer, deco)
: _buildPeerTile(context, peer, deco))), : _buildPeerTile(context, peer, deco))),
@ -75,7 +76,6 @@ class _PeerCardState extends State<_PeerCard>
BuildContext context, Peer peer, Rx<BoxDecoration?> deco) { BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
final greyStyle = final greyStyle =
TextStyle(fontSize: 12, color: MyTheme.color(context).lighterText); TextStyle(fontSize: 12, color: MyTheme.color(context).lighterText);
RxBool iconHover = false.obs;
return Obx( return Obx(
() => Container( () => Container(
foregroundDecoration: deco.value, foregroundDecoration: deco.value,
@ -147,30 +147,7 @@ class _PeerCardState extends State<_PeerCard>
], ],
), ),
), ),
InkWell( _actionMore(peer),
child: CircleAvatar(
radius: 12,
backgroundColor: iconHover.value
? MyTheme.color(context).grayBg!
: MyTheme.color(context).bg!,
child: Icon(
Icons.more_vert,
size: 18,
color: iconHover.value
? MyTheme.color(context).text
: MyTheme.color(context).lightText,
),
),
onTapDown: (e) {
final x = e.globalPosition.dx;
final y = e.globalPosition.dy;
_menuPos = RelativeRect.fromLTRB(x, y, x, y);
},
onTap: () {
_showPeerMenu(context, peer.id);
},
onHover: (value) => iconHover.value = value,
),
], ],
).paddingSymmetric(horizontal: 4.0), ).paddingSymmetric(horizontal: 4.0),
), ),
@ -183,7 +160,6 @@ class _PeerCardState extends State<_PeerCard>
Widget _buildPeerCard( Widget _buildPeerCard(
BuildContext context, Peer peer, Rx<BoxDecoration?> deco) { BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
RxBool iconHover = false.obs;
return Card( return Card(
color: Colors.transparent, color: Colors.transparent,
elevation: 0, elevation: 0,
@ -272,29 +248,10 @@ class _PeerCardState extends State<_PeerCard>
? Colors.green ? Colors.green
: Colors.yellow)), : Colors.yellow)),
Text('${peer.id}') Text('${peer.id}')
]), ]).paddingSymmetric(vertical: 8),
InkWell( _actionMore(peer),
child: CircleAvatar(
radius: 12,
backgroundColor: iconHover.value
? MyTheme.color(context).grayBg!
: MyTheme.color(context).bg!,
child: Icon(Icons.more_vert,
size: 18,
color: iconHover.value
? MyTheme.color(context).text
: MyTheme.color(context).lightText)),
onTapDown: (e) {
final x = e.globalPosition.dx;
final y = e.globalPosition.dy;
_menuPos = RelativeRect.fromLTRB(x, y, x, y);
},
onTap: () {
_showPeerMenu(context, peer.id);
},
onHover: (value) => iconHover.value = value),
], ],
).paddingSymmetric(vertical: 8.0, horizontal: 12.0), ).paddingSymmetric(horizontal: 12.0),
) )
], ],
), ),
@ -304,6 +261,27 @@ class _PeerCardState extends State<_PeerCard>
); );
} }
Widget _actionMore(Peer peer) => Listener(
onPointerDown: (e) {
final x = e.position.dx;
final y = e.position.dy;
_menuPos = RelativeRect.fromLTRB(x, y, x, y);
},
onPointerUp: (_) => _showPeerMenu(context, peer.id),
child: MouseRegion(
onEnter: (_) => _iconMoreHover.value = true,
onExit: (_) => _iconMoreHover.value = false,
child: CircleAvatar(
radius: 14,
backgroundColor: _iconMoreHover.value
? MyTheme.color(context).grayBg!
: MyTheme.color(context).bg!,
child: Icon(Icons.more_vert,
size: 18,
color: _iconMoreHover.value
? MyTheme.color(context).text
: MyTheme.color(context).lightText))));
/// Connect to a peer with [id]. /// Connect to a peer with [id].
/// If [isFileTransfer], starts a session only for file transfer. /// If [isFileTransfer], starts a session only for file transfer.
void _connect(String id, {bool isFileTransfer = false}) async { void _connect(String id, {bool isFileTransfer = false}) async {
@ -325,7 +303,7 @@ class _PeerCardState extends State<_PeerCard>
void _showPeerMenu(BuildContext context, String id) async { void _showPeerMenu(BuildContext context, String id) async {
var value = await showMenu( var value = await showMenu(
context: context, context: context,
position: this._menuPos, position: _menuPos,
items: await super.widget.popupMenuItemsFunc(), items: await super.widget.popupMenuItemsFunc(),
elevation: 8, elevation: 8,
); );

View File

@ -49,7 +49,7 @@ packages:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.9.0" version: "2.8.2"
back_button_interceptor: back_button_interceptor:
dependency: "direct main" dependency: "direct main"
description: description:
@ -147,7 +147,7 @@ packages:
name: characters name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.1" version: "1.2.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -168,7 +168,7 @@ packages:
name: clock name: clock
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.1" version: "1.1.0"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
@ -326,7 +326,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.1" version: "1.3.0"
ffi: ffi:
dependency: "direct main" dependency: "direct main"
description: description:
@ -423,6 +423,13 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.9.3" version: "0.9.3"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.1"
flutter_parsed_text: flutter_parsed_text:
dependency: transitive dependency: transitive
description: description:
@ -596,6 +603,13 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "4.6.0" version: "4.6.0"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.0"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -609,14 +623,14 @@ packages:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.12" version: "0.12.11"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.5" version: "0.1.4"
menu_base: menu_base:
dependency: transitive dependency: transitive
description: description:
@ -630,7 +644,7 @@ packages:
name: meta name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0" version: "1.7.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -707,7 +721,7 @@ packages:
name: path name: path
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.2" version: "1.8.1"
path_provider: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -957,7 +971,7 @@ packages:
name: source_span name: source_span
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.9.0" version: "1.8.2"
sqflite: sqflite:
dependency: transitive dependency: transitive
description: description:
@ -999,7 +1013,7 @@ packages:
name: string_scanner name: string_scanner
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.1" version: "1.1.0"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:
@ -1013,14 +1027,14 @@ packages:
name: term_glyph name: term_glyph
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.1" version: "1.2.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.4.12" version: "0.4.9"
timing: timing:
dependency: transitive dependency: transitive
description: description:

View File

@ -83,6 +83,8 @@ dev_dependencies:
sdk: flutter sdk: flutter
build_runner: ^2.1.11 build_runner: ^2.1.11
freezed: ^2.0.3 freezed: ^2.0.3
flutter_lints: ^2.0.0
# rerun: flutter pub run flutter_launcher_icons:main # rerun: flutter pub run flutter_launcher_icons:main
flutter_icons: flutter_icons:
android: "ic_launcher" android: "ic_launcher"