example work

This commit is contained in:
John Smith 2022-12-09 18:59:31 -05:00
parent 855a5a0756
commit 8c96373cfd
20 changed files with 713 additions and 30 deletions

@ -1 +1 @@
Subproject commit b127b2d3c653fea163a776dd58b3798f28aeeee3 Subproject commit c153eb3015d6d118e5d467865510d053ddd84533

View File

@ -832,10 +832,12 @@ impl Network {
let mut editor = routing_table.edit_routing_domain(RoutingDomain::PublicInternet); let mut editor = routing_table.edit_routing_domain(RoutingDomain::PublicInternet);
editor.clear_dial_info_details(); editor.clear_dial_info_details();
editor.set_network_class(None);
editor.commit().await; editor.commit().await;
let mut editor = routing_table.edit_routing_domain(RoutingDomain::LocalNetwork); let mut editor = routing_table.edit_routing_domain(RoutingDomain::LocalNetwork);
editor.clear_dial_info_details(); editor.clear_dial_info_details();
editor.set_network_class(None);
editor.commit().await; editor.commit().await;
// Reset state including network class // Reset state including network class

View File

@ -290,6 +290,7 @@ impl Network {
protocol_config.inbound, protocol_config.inbound,
protocol_config.family_global, protocol_config.family_global,
); );
editor_public_internet.set_network_class(Some(NetworkClass::WebApp));
// commit routing table edits // commit routing table edits
editor_public_internet.commit().await; editor_public_internet.commit().await;
@ -319,6 +320,7 @@ impl Network {
// Drop all dial info // Drop all dial info
let mut editor = routing_table.edit_routing_domain(RoutingDomain::PublicInternet); let mut editor = routing_table.edit_routing_domain(RoutingDomain::PublicInternet);
editor.clear_dial_info_details(); editor.clear_dial_info_details();
editor.set_network_class(None);
editor.commit().await; editor.commit().await;
// Cancels all async background tasks by dropping join handles // Cancels all async background tasks by dropping join handles
@ -348,15 +350,6 @@ impl Network {
false false
} }
pub fn get_network_class(&self, _routing_domain: RoutingDomain) -> Option<NetworkClass> {
// xxx eventually detect tor browser?
return if self.inner.lock().network_started {
Some(NetworkClass::WebApp)
} else {
None
};
}
pub fn get_protocol_config(&self) -> ProtocolConfig { pub fn get_protocol_config(&self) -> ProtocolConfig {
self.inner.lock().protocol_config.clone() self.inner.lock().protocol_config.clone()
} }

Binary file not shown.

View File

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>9.0</string> <string>11.0</string>
</dict> </dict>
</plist> </plist>

View File

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
# platform :ios, '9.0' # platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -21,8 +21,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
veilid: 41ea3fb86dbe06d0ff436d5002234dac45ccf1ea veilid: f5c2e662f91907b30cf95762619526ac3e4512fd
PODFILE CHECKSUM: 7368163408c647b7eb699d0d788ba6718e18fb8d PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
COCOAPODS: 1.11.3 COCOAPODS: 1.11.3

View File

@ -342,7 +342,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -420,7 +420,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -470,7 +470,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;

View File

@ -0,0 +1,102 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_pty/flutter_pty.dart';
import 'package:xterm/xterm.dart';
class Home extends StatefulWidget {
Home({Key? key}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final terminal = Terminal(
maxLines: 10000,
);
final terminalController = TerminalController();
late final Pty pty;
@override
void initState() {
super.initState();
WidgetsBinding.instance.endOfFrame.then(
(_) {
if (mounted) _startPty();
},
);
}
void _startPty() {
pty = Pty.start(
shell,
columns: terminal.viewWidth,
rows: terminal.viewHeight,
);
pty.output
.cast<List<int>>()
.transform(Utf8Decoder())
.listen(terminal.write);
pty.exitCode.then((code) {
terminal.write('the process exited with exit code $code');
});
terminal.onOutput = (data) {
pty.write(const Utf8Encoder().convert(data));
};
terminal.onResize = (w, h, pw, ph) {
pty.resize(h, w);
};
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: TerminalView(
terminal,
controller: terminalController,
autofocus: true,
backgroundOpacity: 0.7,
onSecondaryTapDown: (details, offset) async {
final selection = terminalController.selection;
if (selection != null) {
final text = terminal.buffer.getText(selection);
terminalController.clearSelection();
await Clipboard.setData(ClipboardData(text: text));
} else {
final data = await Clipboard.getData('text/plain');
final text = data?.text;
if (text != null) {
terminal.paste(text);
}
}
},
),
),
);
}
}
String get shell {
if (Platform.isMacOS || Platform.isLinux) {
return Platform.environment['SHELL'] ?? 'bash';
}
if (Platform.isWindows) {
return 'cmd.exe';
}
return 'sh';
}

View File

@ -1,12 +1,20 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/foundation.dart';
import 'package:veilid/veilid.dart'; import 'package:veilid/veilid.dart';
import 'package:flutter_loggy/flutter_loggy.dart'; //import 'package:flutter_loggy/flutter_loggy.dart';
import 'package:loggy/loggy.dart'; import 'package:loggy/loggy.dart';
import 'platform_menu.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_acrylic/flutter_acrylic.dart';
import 'package:xterm/xterm.dart';
import 'home.dart';
import 'config.dart'; import 'config.dart';
@ -62,15 +70,33 @@ void setRootLogLevel(LogLevel? level) {
} }
void initLoggy() { void initLoggy() {
Loggy.initLoggy( // Loggy.initLoggy(
logPrinter: StreamPrinter(ConsolePrinter( // logPrinter: StreamPrinter(ConsolePrinter(
const PrettyDeveloperPrinter(), // const PrettyDeveloperPrinter(),
)), // )),
logOptions: getLogOptions(null), // logOptions: getLogOptions(null),
); // );
} }
// Entrypoint /////////////////////////////// Acrylic
bool get isDesktop {
if (kIsWeb) return false;
return [
TargetPlatform.windows,
TargetPlatform.linux,
TargetPlatform.macOS,
].contains(defaultTargetPlatform);
}
Future<void> setupAcrylic() async {
await Window.initialize();
await Window.makeTitlebarTransparent();
await Window.setEffect(effect: WindowEffect.aero, color: Color(0xFFFFFFFF));
await Window.setBlurViewState(MacOSBlurViewState.active);
}
/////////////////////////////// Entrypoint
void main() { void main() {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
@ -106,7 +132,7 @@ void main() {
runApp(MaterialApp( runApp(MaterialApp(
title: 'Veilid Plugin Demo', title: 'Veilid Plugin Demo',
theme: ThemeData( theme: ThemeData(
primarySwatch: Colors.blue, primarySwatch: '#6667AB',
visualDensity: VisualDensity.adaptivePlatformDensity, visualDensity: VisualDensity.adaptivePlatformDensity,
), ),
home: const MyApp())); home: const MyApp()));
@ -220,7 +246,28 @@ class _MyAppState extends State<MyApp> with UiLoggy {
child: Container( child: Container(
color: ThemeData.dark().scaffoldBackgroundColor, color: ThemeData.dark().scaffoldBackgroundColor,
height: MediaQuery.of(context).size.height * 0.4, height: MediaQuery.of(context).size.height * 0.4,
child: LoggyStreamWidget(logLevel: loggy.level.logLevel), child: SafeArea(
child: TerminalView(
terminal,
controller: terminalController,
autofocus: true,
backgroundOpacity: 0.7,
onSecondaryTapDown: (details, offset) async {
final selection = terminalController.selection;
if (selection != null) {
final text = terminal.buffer.getText(selection);
terminalController.clearSelection();
await Clipboard.setData(ClipboardData(text: text));
} else {
final data = await Clipboard.getData('text/plain');
final text = data?.text;
if (text != null) {
terminal.paste(text);
}
}
},
),
),
)), )),
Container( Container(
padding: const EdgeInsets.fromLTRB(8, 8, 8, 12), padding: const EdgeInsets.fromLTRB(8, 8, 8, 12),

View File

@ -0,0 +1,149 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
class AppPlatformMenu extends StatefulWidget {
const AppPlatformMenu({super.key, required this.child});
final Widget child;
@override
State<AppPlatformMenu> createState() => _AppPlatformMenuState();
}
class _AppPlatformMenuState extends State<AppPlatformMenu> {
@override
Widget build(BuildContext context) {
if (defaultTargetPlatform != TargetPlatform.macOS) {
return widget.child;
}
return PlatformMenuBar(
menus: <MenuItem>[
PlatformMenu(
label: 'TerminalStudio',
menus: [
if (PlatformProvidedMenuItem.hasMenu(
PlatformProvidedMenuItemType.about,
))
const PlatformProvidedMenuItem(
type: PlatformProvidedMenuItemType.about,
),
PlatformMenuItemGroup(
members: [
if (PlatformProvidedMenuItem.hasMenu(
PlatformProvidedMenuItemType.servicesSubmenu,
))
const PlatformProvidedMenuItem(
type: PlatformProvidedMenuItemType.servicesSubmenu,
),
],
),
PlatformMenuItemGroup(
members: [
if (PlatformProvidedMenuItem.hasMenu(
PlatformProvidedMenuItemType.hide,
))
const PlatformProvidedMenuItem(
type: PlatformProvidedMenuItemType.hide,
),
if (PlatformProvidedMenuItem.hasMenu(
PlatformProvidedMenuItemType.hideOtherApplications,
))
const PlatformProvidedMenuItem(
type: PlatformProvidedMenuItemType.hideOtherApplications,
),
],
),
if (PlatformProvidedMenuItem.hasMenu(
PlatformProvidedMenuItemType.quit,
))
const PlatformProvidedMenuItem(
type: PlatformProvidedMenuItemType.quit,
),
],
),
PlatformMenu(
label: 'Edit',
menus: [
PlatformMenuItemGroup(
members: [
PlatformMenuItem(
label: 'Copy',
shortcut: const SingleActivator(
LogicalKeyboardKey.keyC,
meta: true,
),
onSelected: () {
final primaryContext = primaryFocus?.context;
if (primaryContext == null) {
return;
}
Actions.invoke(
primaryContext,
CopySelectionTextIntent.copy,
);
},
),
PlatformMenuItem(
label: 'Paste',
shortcut: const SingleActivator(
LogicalKeyboardKey.keyV,
meta: true,
),
onSelected: () {
final primaryContext = primaryFocus?.context;
if (primaryContext == null) {
return;
}
Actions.invoke(
primaryContext,
const PasteTextIntent(SelectionChangedCause.keyboard),
);
},
),
PlatformMenuItem(
label: 'Select All',
shortcut: const SingleActivator(
LogicalKeyboardKey.keyA,
meta: true,
),
onSelected: () {
final primaryContext = primaryFocus?.context;
if (primaryContext == null) {
return;
}
print(primaryContext);
try {
final action = Actions.maybeFind<Intent>(
primaryContext,
intent: const SelectAllTextIntent(
SelectionChangedCause.keyboard,
),
);
print('action: $action');
} catch (e) {
print(e);
}
Actions.invoke<Intent>(
primaryContext,
const SelectAllTextIntent(SelectionChangedCause.keyboard),
);
},
),
],
),
if (PlatformProvidedMenuItem.hasMenu(
PlatformProvidedMenuItemType.quit,
))
const PlatformProvidedMenuItem(
type: PlatformProvidedMenuItemType.quit,
),
],
),
],
child: widget.child,
);
}
}

View File

@ -0,0 +1,234 @@
// Veilid Colors
// -------------
//
// Base is origin color as annotated
//
// Shades from material color tool at:
// https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors
//
import 'package:flutter/material.dart';
const Map<int, Color> primaryColorSwatch = {
50: Color(0xffe9e9f3),
100: Color(0xffc7c8e2),
200: Color(0xffa2a5ce),
300: Color(0xff7f82ba),
400: Color(0xff6667ab), // Base (6667ab)
500: Color(0xff4f4d9d),
600: Color(0xff484594),
700: Color(0xff403b88),
800: Color(0xff39327c),
900: Color(0xff2b2068),
};
const MaterialColor materialPrimaryColor =
MaterialColor(0xff6667ab, primaryColorSwatch);
const Map<int, Color> primaryComplementaryColorSwatch = {
50: Color(0xfffafdee),
100: Color(0xfff4f9d3),
200: Color(0xffedf6b8),
300: Color(0xffe7f29f),
400: Color(0xffe2ed8d),
500: Color(0xffdde97d),
600: Color(0xffd0d776),
700: Color(0xffbdc16d),
800: Color(0xffabaa66), // Base (#abaa66)
900: Color(0xff8b845c),
};
const MaterialColor materialPrimaryComplementaryColor =
MaterialColor(0xffabaa66, primaryComplementaryColorSwatch);
const Map<int, Color> primaryTriadicColorASwatch = {
50: Color(0xfff0e4f0),
100: Color(0xffdabcdb),
200: Color(0xffc290c3),
300: Color(0xffaa66ab), // Base (#aa66ab)
400: Color(0xff98489a),
500: Color(0xff892a8c),
600: Color(0xff7d2786),
700: Color(0xff6d217e),
800: Color(0xff5e1b76),
900: Color(0xff441168),
};
const MaterialColor materialPrimaryTriadicColorA =
MaterialColor(0xffaa66ab, primaryTriadicColorASwatch);
const Map<int, Color> primaryTriadicColorBSwatch = {
50: Color(0xffffe3dc),
100: Color(0xfff7c4c2),
200: Color(0xffdba2a2),
300: Color(0xffc08180),
400: Color(0xffab6667), // Base (#ab6667)
500: Color(0xff964c4f),
600: Color(0xff894347),
700: Color(0xff78373d),
800: Color(0xff672b35),
900: Color(0xff551e2a),
};
const MaterialColor materialPrimaryTriadicColorB =
MaterialColor(0xffab6667, primaryTriadicColorBSwatch);
const Map<int, Color> secondaryColorSwatch = {
50: Color(0xffe3e8f7),
100: Color(0xffb8c6eb),
200: Color(0xff87a1dd), // Base (#87a1dd)
300: Color(0xff527dce),
400: Color(0xff1a61c1),
500: Color(0xff0048b5),
600: Color(0xff0040ab),
700: Color(0xff0037a0),
800: Color(0xff002e94),
900: Color(0xff001d7f),
};
const MaterialColor materialSecondaryColor =
MaterialColor(0xff87a1dd, secondaryColorSwatch);
const Map<int, Color> secondaryComplementaryColorSwatch = {
50: Color(0xfff6f1e2),
100: Color(0xffeadbb6),
200: Color(0xffddc387), // Base (#ddc387)
300: Color(0xffd2ac55),
400: Color(0xffcd9c2d),
500: Color(0xffc88c05),
600: Color(0xffc58200),
700: Color(0xffbf7400),
800: Color(0xffb96700),
900: Color(0xffb15000),
};
const MaterialColor materialSecondaryComplementaryColor =
MaterialColor(0xffddc387, secondaryComplementaryColorSwatch);
const Map<int, Color> backgroundColorSwatch = {
50: Color(0xffe3e5eb),
100: Color(0xffb9bdce),
200: Color(0xff8c93ac),
300: Color(0xff626a8c),
400: Color(0xff454d76),
500: Color(0xff273263),
600: Color(0xff222c5b),
700: Color(0xff1a2451),
800: Color(0xff131c45),
900: Color(0xff0b0b2f), // Base (#0b0b2f)
};
const MaterialColor materialBackgroundColor =
MaterialColor(0xff0b0b2f, backgroundColorSwatch);
const Map<int, Color> backgroundComplementaryColorSwatch = {
50: Color(0xfffffed2),
100: Color(0xfffdf9cd),
200: Color(0xfff8f5c8),
300: Color(0xfff3efc3),
400: Color(0xffd1cea3),
500: Color(0xffb4b187),
600: Color(0xff89865e),
700: Color(0xff73714a),
800: Color(0xff53512c),
900: Color(0xff2f2f0b), // Base (#2f2f0b)
};
const MaterialColor materialBackgroundComplementaryColor =
MaterialColor(0xff2f2f0b, backgroundComplementaryColorSwatch);
const Map<int, Color> desaturatedColorSwatch = {
50: Color(0xfff7fbff),
100: Color(0xfff2f6ff),
200: Color(0xffedf1fd),
300: Color(0xffe3e7f2),
400: Color(0xffc1c5d0), // Base (#c1c5d0)
500: Color(0xffa3a7b2),
600: Color(0xff797d87),
700: Color(0xff656973),
800: Color(0xff464952),
900: Color(0xff242830),
};
const MaterialColor materialDesaturatedColor =
MaterialColor(0xffc1c5d0, desaturatedColorSwatch);
const Map<int, Color> desaturatedComplementaryColorSwatch = {
50: Color(0xffecebe5),
100: Color(0xffd0ccc1), // Base (#d0ccc1)
200: Color(0xffb0aa9a),
300: Color(0xff908972),
400: Color(0xff796f54),
500: Color(0xff615837),
600: Color(0xff584e31),
700: Color(0xff4a4128),
800: Color(0xff3e341f),
900: Color(0xff312715),
};
const MaterialColor materialDesaturatedComplementaryColor =
MaterialColor(0xffd0ccc1, desaturatedComplementaryColorSwatch);
const Map<int, Color> auxiliaryColorSwatch = {
50: Color(0xffe7e4da), // Base (#e7e4da)
100: Color(0xffc2bbac),
200: Color(0xff988e7b),
300: Color(0xff6f634c),
400: Color(0xff53472b),
500: Color(0xff372c0a),
600: Color(0xff302403),
700: Color(0xff261a00),
800: Color(0xff1e0c00),
900: Color(0xff160000),
};
const MaterialColor materialAuxiliaryColor =
MaterialColor(0xffe7e4da, auxiliaryColorSwatch);
const Map<int, Color> auxiliaryComplementaryColorSwatch = {
50: Color(0xffdadde7), // Base (#dadde7)
100: Color(0xffa2abc6),
200: Color(0xff6575a2),
300: Color(0xff224580),
400: Color(0xff00266c),
500: Color(0xff000357),
600: Color(0xff000051),
700: Color(0xff000051),
800: Color(0xff000050),
900: Color(0xff00004f),
};
const MaterialColor materialAuxiliaryComplementaryColor =
MaterialColor(0xffdadde7, auxiliaryComplementaryColorSwatch);
const Map<int, Color> popColorSwatch = {
50: Color(0xfffee5f5),
100: Color(0xfffbbde7),
200: Color(0xfff88fd9),
300: Color(0xfff259c9), // Base (#f259c9)
400: Color(0xffec15bd),
500: Color(0xffe100b0),
600: Color(0xffd200ac),
700: Color(0xffbe00a7),
800: Color(0xffad00a1),
900: Color(0xff8e0097),
};
const MaterialColor materialPopColor =
MaterialColor(0xfff259c9, popColorSwatch);
const Map<int, Color> popComplentaryColorSwatch = {
50: Color(0xffe6fdea),
100: Color(0xffc2f9cb),
200: Color(0xff96f6a9),
300: Color(0xff59f282), // Base (#59f282)
400: Color(0xff00ec60),
500: Color(0xff00e446),
600: Color(0xff00d33b),
700: Color(0xff00bf2d),
800: Color(0xff00ad21),
900: Color(0xff008b05),
};
const MaterialColor materialPopComplementaryColor =
MaterialColor(0xff59f282, popComplentaryColorSwatch);

View File

@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:xterm/xterm.dart';
class VirtualKeyboardView extends StatelessWidget {
const VirtualKeyboardView(this.keyboard, {super.key});
final VirtualKeyboard keyboard;
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: keyboard,
builder: (context, child) => ToggleButtons(
children: [Text('Ctrl'), Text('Alt'), Text('Shift')],
isSelected: [keyboard.ctrl, keyboard.alt, keyboard.shift],
onPressed: (index) {
switch (index) {
case 0:
keyboard.ctrl = !keyboard.ctrl;
break;
case 1:
keyboard.alt = !keyboard.alt;
break;
case 2:
keyboard.shift = !keyboard.shift;
break;
}
},
),
);
}
}
class VirtualKeyboard extends TerminalInputHandler with ChangeNotifier {
final TerminalInputHandler _inputHandler;
VirtualKeyboard(this._inputHandler);
bool _ctrl = false;
bool get ctrl => _ctrl;
set ctrl(bool value) {
if (_ctrl != value) {
_ctrl = value;
notifyListeners();
}
}
bool _shift = false;
bool get shift => _shift;
set shift(bool value) {
if (_shift != value) {
_shift = value;
notifyListeners();
}
}
bool _alt = false;
bool get alt => _alt;
set alt(bool value) {
if (_alt != value) {
_alt = value;
notifyListeners();
}
}
@override
String? call(TerminalKeyboardEvent event) {
return _inputHandler.call(event.copyWith(
ctrl: event.ctrl || _ctrl,
shift: event.shift || _shift,
alt: event.alt || _alt,
));
}
}

View File

@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <flutter_acrylic/flutter_acrylic_plugin.h>
#include <veilid/veilid_plugin.h> #include <veilid/veilid_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_acrylic_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterAcrylicPlugin");
flutter_acrylic_plugin_register_with_registrar(flutter_acrylic_registrar);
g_autoptr(FlPluginRegistrar) veilid_registrar = g_autoptr(FlPluginRegistrar) veilid_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "VeilidPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "VeilidPlugin");
veilid_plugin_register_with_registrar(veilid_registrar); veilid_plugin_register_with_registrar(veilid_registrar);

View File

@ -3,10 +3,12 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
flutter_acrylic
veilid veilid
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
flutter_pty
) )
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)

View File

@ -5,10 +5,12 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import flutter_acrylic
import path_provider_macos import path_provider_macos
import veilid import veilid
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterAcrylicPlugin.register(with: registry.registrar(forPlugin: "FlutterAcrylicPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
VeilidPlugin.register(with: registry.registrar(forPlugin: "VeilidPlugin")) VeilidPlugin.register(with: registry.registrar(forPlugin: "VeilidPlugin"))
} }

View File

@ -43,6 +43,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.16.0" version: "1.16.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -50,6 +57,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.0.5"
equatable:
dependency: transitive
description:
name: equatable
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -76,6 +90,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_acrylic:
dependency: "direct main"
description:
name: flutter_acrylic
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0+2"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -90,6 +111,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.2" version: "2.0.2"
flutter_pty:
dependency: "direct main"
description:
name: flutter_pty
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.1"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -205,6 +233,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.0" version: "3.1.0"
platform_info:
dependency: transitive
description:
name: platform_info
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.0"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -219,6 +254,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.2.4" version: "4.2.4"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
@ -273,6 +315,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.12" version: "0.4.12"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -301,6 +350,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0+2" version: "0.2.0+2"
xterm:
dependency: "direct main"
description:
name: xterm
url: "https://pub.dartlang.org"
source: hosted
version: "3.4.0"
sdks: sdks:
dart: ">=2.17.0 <3.0.0" dart: ">=2.18.0 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"

View File

@ -7,7 +7,7 @@ version: 1.0.0+1
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
environment: environment:
sdk: ">=2.16.1 <3.0.0" sdk: ">=2.17.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work. # Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions # To automatically upgrade your package dependencies to the latest versions
@ -36,6 +36,9 @@ dependencies:
flutter_loggy: ^2.0.1 flutter_loggy: ^2.0.1
path_provider: ^2.0.11 path_provider: ^2.0.11
path: ^1.8.1 path: ^1.8.1
xterm: ^3.4.0
flutter_pty: ^0.3.1
flutter_acrylic: ^1.0.0+2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -88,3 +91,7 @@ flutter:
# #
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages # see https://flutter.dev/custom-fonts/#from-packages
fonts:
- family: Cascadia Mono
fonts:
- asset: fonts/CascadiaMonoPL.ttf

View File

@ -6,9 +6,12 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <flutter_acrylic/flutter_acrylic_plugin.h>
#include <veilid/veilid_plugin.h> #include <veilid/veilid_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
FlutterAcrylicPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterAcrylicPlugin"));
VeilidPluginRegisterWithRegistrar( VeilidPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("VeilidPlugin")); registry->GetRegistrarForPlugin("VeilidPlugin"));
} }

View File

@ -3,10 +3,12 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
flutter_acrylic
veilid veilid
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
flutter_pty
) )
set(PLUGIN_BUNDLED_LIBRARIES) set(PLUGIN_BUNDLED_LIBRARIES)