diff --git a/flutter_hbb/assets/linux.png b/flutter_hbb/assets/linux.png new file mode 100644 index 000000000..198131142 Binary files /dev/null and b/flutter_hbb/assets/linux.png differ diff --git a/flutter_hbb/assets/mac.png b/flutter_hbb/assets/mac.png new file mode 100644 index 000000000..e0d71d8d3 Binary files /dev/null and b/flutter_hbb/assets/mac.png differ diff --git a/flutter_hbb/assets/win.png b/flutter_hbb/assets/win.png new file mode 100644 index 000000000..155f4e75d Binary files /dev/null and b/flutter_hbb/assets/win.png differ diff --git a/flutter_hbb/lib/common.dart b/flutter_hbb/lib/common.dart index 469564182..9c93e513c 100644 --- a/flutter_hbb/lib/common.dart +++ b/flutter_hbb/lib/common.dart @@ -127,3 +127,11 @@ class _PasswordWidgetState extends State { ); } } + +Color str2color(String str, [alpha = 0xFF]) { + var hash = 160 << 16 + 114 << 8 + 91; + for (var i = 0; i < str.length; i += 1) { + hash = str.codeUnitAt(i) + ((hash << 5) - hash); + } + return Color((hash & 0xFFFFFF) | (alpha << 24)); +} diff --git a/flutter_hbb/lib/home_page.dart b/flutter_hbb/lib/home_page.dart index 66ca89384..f9446067e 100644 --- a/flutter_hbb/lib/home_page.dart +++ b/flutter_hbb/lib/home_page.dart @@ -33,6 +33,7 @@ class _HomePageState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ getSearchBarUI(), + getPeers(), Expanded(child: Container()) ]), padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0), @@ -41,13 +42,20 @@ class _HomePageState extends State { void onConnect() { var id = _idController.text.trim(); + connect(id); + } + + void connect(String id) { if (id == '') return; - Navigator.push( - context, - MaterialPageRoute( - builder: (BuildContext context) => RemotePage(id: id), - ), - ); + () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => RemotePage(id: id), + ), + ); + setState(() {}); + }(); FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); @@ -133,4 +141,49 @@ class _HomePageState extends State { _idController.dispose(); super.dispose(); } + + Widget getPlatformImage(String platform) { + platform = platform.toLowerCase(); + if (platform == 'osx') + platform = 'mac'; + else if (platform != 'linux') platform = 'win'; + return Image.asset('assets/$platform.png', width: 36, height: 36); + } + + Widget getPeers() { + final cards = []; + var peers = FFI.peers(); + peers.forEach((p) { + cards.add(Card( + child: GestureDetector( + onTap: () => connect('${p.id}'), + onLongPressStart: (details) { + var x = details.globalPosition.dx; + var y = details.globalPosition.dy; + () async { + var value = await showMenu( + context: context, + position: RelativeRect.fromLTRB(x, y, x, y), + items: [ + PopupMenuItem( + child: Text('Remove'), value: 'remove'), + ], + elevation: 8, + ); + if (value == 'remove') { + setState(() => FFI.setByName('remove', '${p.id}')); + } + }(); + }, + child: ListTile( + subtitle: Text('${p.username}@${p.hostname}'), + title: Text('${p.id}'), + leading: Container( + padding: const EdgeInsets.all(6), + child: getPlatformImage('${p.platform}'), + color: str2color('${p.id}${p.platform}', 0x77)), + )))); + }); + return Wrap(children: cards); + } } diff --git a/flutter_hbb/lib/model.dart b/flutter_hbb/lib/model.dart index e61f1f283..58a37de3b 100644 --- a/flutter_hbb/lib/model.dart +++ b/flutter_hbb/lib/model.dart @@ -389,6 +389,7 @@ class CursorModel with ChangeNotifier { } class FFI { + static String _dir = ''; static F1 _freeCString; static F2 _getByName; static F3 _setByName; @@ -535,8 +536,8 @@ class FFI { _freeRgba = dylib .lookupFunction), F4>('free_rgba'); _getRgba = dylib.lookupFunction('get_rgba'); - final dir = (await getApplicationDocumentsDirectory()).path; - setByName('init', dir); + _dir = (await getApplicationDocumentsDirectory()).path; + setByName('init', _dir); } }