diff --git a/Cargo.lock b/Cargo.lock index e6942ef72..441b49c58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1476,9 +1476,8 @@ dependencies = [ [[package]] name = "flutter_rust_bridge_codegen" -version = "1.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3209735fd687b06b8d770ec008874119b91f7f46b4a73d17226d5c337435bb74" +version = "1.32.0" +source = "git+https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge#827fc60143988dfc3759f7e8ce16a20d80edd710" dependencies = [ "anyhow", "cargo_metadata", diff --git a/Cargo.toml b/Cargo.toml index 2b707a688..b395da582 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,7 +119,7 @@ winapi = { version = "0.3", features = [ "winnt" ] } [build-dependencies] cc = "1.0" hbb_common = { path = "libs/hbb_common" } -flutter_rust_bridge_codegen = "1.30.0" +flutter_rust_bridge_codegen = { git = "https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge" } [dev-dependencies] hound = "3.4" diff --git a/flutter/.gitignore b/flutter/.gitignore index 7dc95a613..c8ff34feb 100644 --- a/flutter/.gitignore +++ b/flutter/.gitignore @@ -45,6 +45,7 @@ jniLibs # flutter rust bridge lib/generated_bridge.dart +lib/generated_bridge.freezed.dart # Flutter Generated Files linux/flutter/generated_plugin_registrant.cc diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 703d0a79a..6659986d8 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -53,6 +53,7 @@ class _ConnectionPageState extends State { children: [ getUpdateUI(), Row( + mainAxisAlignment: MainAxisAlignment.start, children: [ getSearchBarUI(), ], diff --git a/flutter/lib/desktop/pages/connection_tab_page.dart b/flutter/lib/desktop/pages/connection_tab_page.dart index ca53224f1..5ebf7b54e 100644 --- a/flutter/lib/desktop/pages/connection_tab_page.dart +++ b/flutter/lib/desktop/pages/connection_tab_page.dart @@ -1,8 +1,9 @@ import 'dart:convert'; +import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/desktop/pages/remote_page.dart'; -import 'package:flutter_hbb/models/model.dart'; +import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart'; class ConnectionTabPage extends StatefulWidget { @@ -18,11 +19,13 @@ class _ConnectionTabPageState extends State with SingleTickerProviderStateMixin { // refactor List when using multi-tab // this singleton is only for test - late String connectionId; - late TabController tabController; + List connectionIds = List.empty(growable: true); + var initialIndex = 0; _ConnectionTabPageState(Map params) { - connectionId = params['id'] ?? ""; + if (params['id'] != null) { + connectionIds.add(params['id']); + } } @override @@ -34,33 +37,88 @@ class _ConnectionTabPageState extends State // for simplify, just replace connectionId if (call.method == "new_remote_desktop") { setState(() { - FFI.close(); - connectionId = jsonDecode(call.arguments)["id"]; + final args = jsonDecode(call.arguments); + final id = args['id']; + final indexOf = connectionIds.indexOf(id); + if (indexOf >= 0) { + setState(() { + initialIndex = indexOf; + }); + } else { + connectionIds.add(id); + setState(() { + initialIndex = connectionIds.length - 1; + }); + } }); } }); - tabController = TabController(length: 1, vsync: this); } @override Widget build(BuildContext context) { - return Column( - children: [ - TabBar( - controller: tabController, - isScrollable: true, - labelColor: Colors.black87, - physics: NeverScrollableScrollPhysics(), - tabs: [ - Tab( - text: connectionId, + return Scaffold( + body: DefaultTabController( + initialIndex: initialIndex, + length: connectionIds.length, + animationDuration: Duration.zero, + child: Column( + children: [ + SizedBox( + height: 50, + child: DesktopTitleBar( + child: TabBar( + isScrollable: true, + labelColor: Colors.white, + physics: NeverScrollableScrollPhysics(), + indicatorColor: Colors.white, + tabs: connectionIds + .map((e) => Tab( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(e), + SizedBox( + width: 4, + ), + InkWell( + onTap: () { + onRemoveId(e); + }, + child: Icon( + Icons.highlight_remove, + size: 20, + )) + ], + ), + )) + .toList()), ), - ]), - Expanded( - child: TabBarView(controller: tabController, children: [ - RemotePage(key: ValueKey(connectionId), id: connectionId) - ])) - ], + ), + Expanded( + child: TabBarView( + children: connectionIds + .map((e) => Container( + child: RemotePage( + key: ValueKey(e), + id: e))) //RemotePage(key: ValueKey(e), id: e)) + .toList()), + ) + ], + ), + ), ); } + + void onRemoveId(String id) { + final indexOf = connectionIds.indexOf(id); + if (indexOf == -1) { + return; + } + setState(() { + connectionIds.removeAt(indexOf); + initialIndex = max(0, initialIndex - 1); + }); + } } diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 4eaa1c877..1ba610f19 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -1,6 +1,20 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "40.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" archive: dependency: transitive description: @@ -64,6 +78,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.11" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.3" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.3.2" characters: dependency: transitive description: @@ -78,6 +148,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" clock: dependency: transitive description: @@ -85,6 +162,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" collection: dependency: transitive description: @@ -92,6 +176,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" cross_file: dependency: transitive description: @@ -113,6 +204,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" dash_chat: dependency: "direct main" description: @@ -319,6 +417,41 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed: + dependency: "direct dev" + description: + name: freezed + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3+1" + freezed_annotation: + dependency: "direct main" + description: + name: freezed_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" http: dependency: "direct main" description: @@ -326,6 +459,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.13.4" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" http_parser: dependency: transitive description: @@ -382,6 +522,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.17.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" js: dependency: transitive description: @@ -389,6 +536,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.4" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.0" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" matcher: dependency: transitive description: @@ -410,6 +571,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" nested: dependency: transitive description: @@ -417,6 +585,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" package_info_plus: dependency: "direct main" description: @@ -543,6 +718,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" process: dependency: transitive description: @@ -557,6 +739,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" qr_code_scanner: dependency: "direct main" description: @@ -636,11 +832,32 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.2" source_span: dependency: transitive description: @@ -662,6 +879,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" string_scanner: dependency: transitive description: @@ -683,6 +907,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.9" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" toggle_switch: dependency: "direct main" description: @@ -816,6 +1047,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" win32: dependency: transitive description: diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 008d4ef9d..21b1857eb 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -3,7 +3,7 @@ description: Your Remote Desktop Software # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -19,102 +19,102 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.1.10+27 environment: - sdk: ">=2.16.1" + sdk: ">=2.16.1" dependencies: - flutter: - sdk: flutter + flutter: + sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.3 - ffi: ^1.1.2 - path_provider: ^2.0.2 - external_path: ^1.0.1 - provider: ^5.0.0 - tuple: ^2.0.0 - wakelock: ^0.5.2 - device_info_plus: ^3.2.3 - firebase_analytics: ^9.1.5 - package_info_plus: ^1.4.2 - url_launcher: ^6.0.9 - shared_preferences: ^2.0.6 - toggle_switch: ^1.4.0 - dash_chat: ^1.1.16 - draggable_float_widget: ^0.0.2 - settings_ui: ^2.0.2 - flutter_breadcrumb: ^1.0.1 - http: ^0.13.4 - qr_code_scanner: - git: - url: https://github.com/Heap-Hop/qr_code_scanner.git - ref: fix_break_changes_platform - zxing2: ^0.1.0 - image_picker: ^0.8.5 - image: ^3.1.3 - flutter_smart_dialog: ^4.3.1 - flutter_rust_bridge: ^1.30.0 - window_manager: ^0.2.3 - desktop_multi_window: - git: - url: https://github.com/Kingtous/rustdesk_desktop_multi_window - ref: master - bitsdojo_window: ^0.1.2 + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.3 + ffi: ^1.1.2 + path_provider: ^2.0.2 + external_path: ^1.0.1 + provider: ^5.0.0 + tuple: ^2.0.0 + wakelock: ^0.5.2 + device_info_plus: ^3.2.3 + firebase_analytics: ^9.1.5 + package_info_plus: ^1.4.2 + url_launcher: ^6.0.9 + shared_preferences: ^2.0.6 + toggle_switch: ^1.4.0 + dash_chat: ^1.1.16 + draggable_float_widget: ^0.0.2 + settings_ui: ^2.0.2 + flutter_breadcrumb: ^1.0.1 + http: ^0.13.4 + qr_code_scanner: + git: + url: https://github.com/Heap-Hop/qr_code_scanner.git + ref: fix_break_changes_platform + zxing2: ^0.1.0 + image_picker: ^0.8.5 + image: ^3.1.3 + flutter_smart_dialog: ^4.3.1 + flutter_rust_bridge: ^1.30.0 + window_manager: ^0.2.3 + desktop_multi_window: + git: + url: https://github.com/Kingtous/rustdesk_desktop_multi_window + ref: master + bitsdojo_window: ^0.1.2 + freezed_annotation: ^2.0.3 dev_dependencies: - flutter_launcher_icons: ^0.9.1 - flutter_test: - sdk: flutter - + flutter_launcher_icons: ^0.9.1 + flutter_test: + sdk: flutter + build_runner: ^2.1.11 + freezed: ^2.0.3 # rerun: flutter pub run flutter_launcher_icons:main flutter_icons: - android: "ic_launcher" - ios: true - image_path: "../1024-rec.png" + android: "ic_launcher" + ios: true + image_path: "../1024-rec.png" # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter. flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true + # To add assets to your application, add an assets section, like this: + assets: + - assets/ - # To add assets to your application, add an assets section, like this: - assets: - - assets/ + fonts: + - family: GestureIcons + fonts: + - asset: assets/gestures.ttf - fonts: - - family: GestureIcons - fonts: - - asset: assets/gestures.ttf + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages