home_page.dart 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_hbb/mobile/pages/server_page.dart';
  3. import 'package:flutter_hbb/mobile/pages/settings_page.dart';
  4. import 'package:flutter_hbb/web/settings_page.dart';
  5. import 'package:get/get.dart';
  6. import '../../common.dart';
  7. import '../../common/widgets/chat_page.dart';
  8. import '../../models/platform_model.dart';
  9. import '../../models/state_model.dart';
  10. import 'connection_page.dart';
  11. abstract class PageShape extends Widget {
  12. final String title = "";
  13. final Widget icon = Icon(null);
  14. final List<Widget> appBarActions = [];
  15. }
  16. class HomePage extends StatefulWidget {
  17. static final homeKey = GlobalKey<HomePageState>();
  18. HomePage() : super(key: homeKey);
  19. @override
  20. HomePageState createState() => HomePageState();
  21. }
  22. class HomePageState extends State<HomePage> {
  23. var _selectedIndex = 0;
  24. int get selectedIndex => _selectedIndex;
  25. final List<PageShape> _pages = [];
  26. int _chatPageTabIndex = -1;
  27. bool get isChatPageCurrentTab => isAndroid
  28. ? _selectedIndex == _chatPageTabIndex
  29. : false; // change this when ios have chat page
  30. void refreshPages() {
  31. setState(() {
  32. initPages();
  33. });
  34. }
  35. @override
  36. void initState() {
  37. super.initState();
  38. initPages();
  39. }
  40. void initPages() {
  41. _pages.clear();
  42. if (!bind.isIncomingOnly()) {
  43. _pages.add(ConnectionPage(
  44. appBarActions: [],
  45. ));
  46. }
  47. if (isAndroid && !bind.isOutgoingOnly()) {
  48. _chatPageTabIndex = _pages.length;
  49. _pages.addAll([ChatPage(type: ChatPageType.mobileMain), ServerPage()]);
  50. }
  51. _pages.add(SettingsPage());
  52. }
  53. @override
  54. Widget build(BuildContext context) {
  55. return WillPopScope(
  56. onWillPop: () async {
  57. if (_selectedIndex != 0) {
  58. setState(() {
  59. _selectedIndex = 0;
  60. });
  61. } else {
  62. return true;
  63. }
  64. return false;
  65. },
  66. child: Scaffold(
  67. // backgroundColor: MyTheme.grayBg,
  68. appBar: AppBar(
  69. centerTitle: true,
  70. title: appTitle(),
  71. actions: _pages.elementAt(_selectedIndex).appBarActions,
  72. ),
  73. bottomNavigationBar: BottomNavigationBar(
  74. key: navigationBarKey,
  75. items: _pages
  76. .map((page) =>
  77. BottomNavigationBarItem(icon: page.icon, label: page.title))
  78. .toList(),
  79. currentIndex: _selectedIndex,
  80. type: BottomNavigationBarType.fixed,
  81. selectedItemColor: MyTheme.accent, //
  82. unselectedItemColor: MyTheme.darkGray,
  83. onTap: (index) => setState(() {
  84. // close chat overlay when go chat page
  85. if (_selectedIndex != index) {
  86. _selectedIndex = index;
  87. if (isChatPageCurrentTab) {
  88. gFFI.chatModel.hideChatIconOverlay();
  89. gFFI.chatModel.hideChatWindowOverlay();
  90. gFFI.chatModel.mobileClearClientUnread(
  91. gFFI.chatModel.currentKey.connId);
  92. }
  93. }
  94. }),
  95. ),
  96. body: _pages.elementAt(_selectedIndex),
  97. ));
  98. }
  99. Widget appTitle() {
  100. final currentUser = gFFI.chatModel.currentUser;
  101. final currentKey = gFFI.chatModel.currentKey;
  102. if (isChatPageCurrentTab &&
  103. currentUser != null &&
  104. currentKey.peerId.isNotEmpty) {
  105. final connected =
  106. gFFI.serverModel.clients.any((e) => e.id == currentKey.connId);
  107. return Row(
  108. mainAxisAlignment: MainAxisAlignment.center,
  109. children: [
  110. Tooltip(
  111. message: currentKey.isOut
  112. ? translate('Outgoing connection')
  113. : translate('Incoming connection'),
  114. child: Icon(
  115. currentKey.isOut
  116. ? Icons.call_made_rounded
  117. : Icons.call_received_rounded,
  118. ),
  119. ),
  120. Expanded(
  121. child: Center(
  122. child: Row(
  123. mainAxisAlignment: MainAxisAlignment.center,
  124. children: [
  125. Text(
  126. "${currentUser.firstName} ${currentUser.id}",
  127. ),
  128. if (connected)
  129. Container(
  130. width: 10,
  131. height: 10,
  132. decoration: BoxDecoration(
  133. shape: BoxShape.circle,
  134. color: Color.fromARGB(255, 133, 246, 199)),
  135. ).marginSymmetric(horizontal: 2),
  136. ],
  137. ),
  138. ),
  139. ),
  140. ],
  141. );
  142. }
  143. return Text(bind.mainGetAppNameSync());
  144. }
  145. }
  146. class WebHomePage extends StatelessWidget {
  147. final connectionPage =
  148. ConnectionPage(appBarActions: <Widget>[const WebSettingsPage()]);
  149. @override
  150. Widget build(BuildContext context) {
  151. stateGlobal.isInMainPage = true;
  152. handleUnilink(context);
  153. return Scaffold(
  154. // backgroundColor: MyTheme.grayBg,
  155. appBar: AppBar(
  156. centerTitle: true,
  157. title: Text("${bind.mainGetAppNameSync()} (Preview)"),
  158. actions: connectionPage.appBarActions,
  159. ),
  160. body: connectionPage,
  161. );
  162. }
  163. handleUnilink(BuildContext context) {
  164. if (webInitialLink.isEmpty) {
  165. return;
  166. }
  167. final link = webInitialLink;
  168. webInitialLink = '';
  169. final splitter = ["/#/", "/#", "#/", "#"];
  170. var fakelink = '';
  171. for (var s in splitter) {
  172. if (link.contains(s)) {
  173. var list = link.split(s);
  174. if (list.length < 2 || list[1].isEmpty) {
  175. return;
  176. }
  177. list.removeAt(0);
  178. fakelink = "rustdesk://${list.join(s)}";
  179. break;
  180. }
  181. }
  182. if (fakelink.isEmpty) {
  183. return;
  184. }
  185. final uri = Uri.tryParse(fakelink);
  186. if (uri == null) {
  187. return;
  188. }
  189. final args = urlLinkToCmdArgs(uri);
  190. if (args == null || args.isEmpty) {
  191. return;
  192. }
  193. bool isFileTransfer = false;
  194. String? id;
  195. String? password;
  196. for (int i = 0; i < args.length; i++) {
  197. switch (args[i]) {
  198. case '--connect':
  199. case '--play':
  200. isFileTransfer = false;
  201. id = args[i + 1];
  202. i++;
  203. break;
  204. case '--file-transfer':
  205. isFileTransfer = true;
  206. id = args[i + 1];
  207. i++;
  208. break;
  209. case '--password':
  210. password = args[i + 1];
  211. i++;
  212. break;
  213. default:
  214. break;
  215. }
  216. }
  217. if (id != null) {
  218. connect(context, id, isFileTransfer: isFileTransfer, password: password);
  219. }
  220. }
  221. }