import 'package:flutter/material.dart'; import 'package:flutter_hbb/mobile/pages/server_page.dart'; import 'package:flutter_hbb/mobile/pages/settings_page.dart'; import 'package:flutter_hbb/web/settings_page.dart'; import 'package:get/get.dart'; import '../../common.dart'; import '../../common/widgets/chat_page.dart'; import '../../models/platform_model.dart'; import '../../models/state_model.dart'; import 'connection_page.dart'; abstract class PageShape extends Widget { final String title = ""; final Widget icon = Icon(null); final List appBarActions = []; } class HomePage extends StatefulWidget { static final homeKey = GlobalKey(); HomePage() : super(key: homeKey); @override HomePageState createState() => HomePageState(); } class HomePageState extends State { var _selectedIndex = 0; int get selectedIndex => _selectedIndex; final List _pages = []; int _chatPageTabIndex = -1; bool get isChatPageCurrentTab => isAndroid ? _selectedIndex == _chatPageTabIndex : false; // change this when ios have chat page void refreshPages() { setState(() { initPages(); }); } @override void initState() { super.initState(); initPages(); } void initPages() { _pages.clear(); if (!bind.isIncomingOnly()) { _pages.add(ConnectionPage( appBarActions: [], )); } if (isAndroid && !bind.isOutgoingOnly()) { _chatPageTabIndex = _pages.length; _pages.addAll([ChatPage(type: ChatPageType.mobileMain), ServerPage()]); } _pages.add(SettingsPage()); } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { if (_selectedIndex != 0) { setState(() { _selectedIndex = 0; }); } else { return true; } return false; }, child: Scaffold( // backgroundColor: MyTheme.grayBg, appBar: AppBar( centerTitle: true, title: appTitle(), actions: _pages.elementAt(_selectedIndex).appBarActions, ), bottomNavigationBar: BottomNavigationBar( key: navigationBarKey, items: _pages .map((page) => BottomNavigationBarItem(icon: page.icon, label: page.title)) .toList(), currentIndex: _selectedIndex, type: BottomNavigationBarType.fixed, selectedItemColor: MyTheme.accent, // unselectedItemColor: MyTheme.darkGray, onTap: (index) => setState(() { // close chat overlay when go chat page if (_selectedIndex != index) { _selectedIndex = index; if (isChatPageCurrentTab) { gFFI.chatModel.hideChatIconOverlay(); gFFI.chatModel.hideChatWindowOverlay(); gFFI.chatModel.mobileClearClientUnread( gFFI.chatModel.currentKey.connId); } } }), ), body: _pages.elementAt(_selectedIndex), )); } Widget appTitle() { final currentUser = gFFI.chatModel.currentUser; final currentKey = gFFI.chatModel.currentKey; if (isChatPageCurrentTab && currentUser != null && currentKey.peerId.isNotEmpty) { final connected = gFFI.serverModel.clients.any((e) => e.id == currentKey.connId); return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Tooltip( message: currentKey.isOut ? translate('Outgoing connection') : translate('Incoming connection'), child: Icon( currentKey.isOut ? Icons.call_made_rounded : Icons.call_received_rounded, ), ), Expanded( child: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "${currentUser.firstName} ${currentUser.id}", ), if (connected) Container( width: 10, height: 10, decoration: BoxDecoration( shape: BoxShape.circle, color: Color.fromARGB(255, 133, 246, 199)), ).marginSymmetric(horizontal: 2), ], ), ), ), ], ); } return Text(bind.mainGetAppNameSync()); } } class WebHomePage extends StatelessWidget { final connectionPage = ConnectionPage(appBarActions: [const WebSettingsPage()]); @override Widget build(BuildContext context) { stateGlobal.isInMainPage = true; handleUnilink(context); return Scaffold( // backgroundColor: MyTheme.grayBg, appBar: AppBar( centerTitle: true, title: Text("${bind.mainGetAppNameSync()} (Preview)"), actions: connectionPage.appBarActions, ), body: connectionPage, ); } handleUnilink(BuildContext context) { if (webInitialLink.isEmpty) { return; } final link = webInitialLink; webInitialLink = ''; final splitter = ["/#/", "/#", "#/", "#"]; var fakelink = ''; for (var s in splitter) { if (link.contains(s)) { var list = link.split(s); if (list.length < 2 || list[1].isEmpty) { return; } list.removeAt(0); fakelink = "rustdesk://${list.join(s)}"; break; } } if (fakelink.isEmpty) { return; } final uri = Uri.tryParse(fakelink); if (uri == null) { return; } final args = urlLinkToCmdArgs(uri); if (args == null || args.isEmpty) { return; } bool isFileTransfer = false; String? id; String? password; for (int i = 0; i < args.length; i++) { switch (args[i]) { case '--connect': case '--play': isFileTransfer = false; id = args[i + 1]; i++; break; case '--file-transfer': isFileTransfer = true; id = args[i + 1]; i++; break; case '--password': password = args[i + 1]; i++; break; default: break; } } if (id != null) { connect(context, id, isFileTransfer: isFileTransfer, password: password); } } }