Completed basic functionality
|
|
@ -1,6 +1,6 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<application
|
<application
|
||||||
android:label="quick_ssh"
|
android:label="QuickSSH"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 6.6 KiB |
|
|
@ -0,0 +1,3 @@
|
||||||
|
description: This file stores settings for Dart & Flutter DevTools.
|
||||||
|
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||||
|
extensions:
|
||||||
|
|
@ -427,7 +427,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
|
@ -484,7 +484,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 775 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 995 B |
|
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -0,0 +1,37 @@
|
||||||
|
class ServerCommand {
|
||||||
|
String name;
|
||||||
|
String ip;
|
||||||
|
String username;
|
||||||
|
String password;
|
||||||
|
String command;
|
||||||
|
|
||||||
|
ServerCommand({
|
||||||
|
required this.name,
|
||||||
|
required this.ip,
|
||||||
|
required this.username,
|
||||||
|
required this.password,
|
||||||
|
required this.command,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert Object to Map
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'name': name,
|
||||||
|
'ip': ip,
|
||||||
|
'username': username,
|
||||||
|
'password': password,
|
||||||
|
'command': command,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Object from Map
|
||||||
|
factory ServerCommand.fromMap(Map<String, dynamic> map) {
|
||||||
|
return ServerCommand(
|
||||||
|
name: map['name'],
|
||||||
|
ip: map['ip'],
|
||||||
|
username: map['username'],
|
||||||
|
password: map['password'],
|
||||||
|
command: map['command'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
// 2. THE MAIN THEME DEFINITIONS
|
||||||
|
class MyThemes {
|
||||||
|
static final darkTheme = ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
colorScheme: const ColorScheme.dark(
|
||||||
|
primary: Color.fromARGB(255, 30, 90, 173),
|
||||||
|
onPrimary: Color.fromARGB(255, 255, 255, 255),
|
||||||
|
surface: Color.fromARGB(255, 24, 24, 24), // <--- Use this for Card BG
|
||||||
|
onSurface: Color.fromARGB(255, 255, 255, 255), // Card Text
|
||||||
|
onSurfaceVariant: Color.fromARGB(255, 155, 155, 155),
|
||||||
|
primaryContainer: Color.fromARGB(255, 30, 30, 30),
|
||||||
|
error: Color.fromARGB(255, 255, 0, 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
static final lightTheme = ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
brightness: Brightness.light,
|
||||||
|
colorScheme: const ColorScheme.light(
|
||||||
|
primary: Color.fromARGB(255, 30, 90, 173),
|
||||||
|
onPrimary: Color.fromARGB(255, 15, 15, 15),
|
||||||
|
surface: Color.fromARGB(255, 245, 245, 245), // <--- Use this for Card BG
|
||||||
|
onSurface: Color.fromARGB(255, 19, 19, 19), // Card Text
|
||||||
|
onSurfaceVariant: Color.fromARGB(255, 61, 61, 61),
|
||||||
|
primaryContainer: Color.fromARGB(255, 236, 236, 236),
|
||||||
|
error: Color.fromARGB(255, 255, 0, 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,36 +1,25 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'screens/home_screen.dart';
|
||||||
|
import 'package:QuickSSH/classes/theme_provider.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatefulWidget {
|
class MyApp extends StatelessWidget {
|
||||||
const MyApp({super.key});
|
const MyApp({super.key});
|
||||||
|
|
||||||
@override
|
|
||||||
State<MyApp> createState() => _MyAppState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
home: Scaffold(
|
title: 'Quick SSH',
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: const Color(0xFF37364A),
|
theme: MyThemes.lightTheme,
|
||||||
title: const Text("Qucik SSH"),
|
darkTheme: MyThemes.darkTheme,
|
||||||
),
|
|
||||||
body: const Center(
|
themeMode: ThemeMode.system,
|
||||||
child: Text('Hello, World!', style: TextStyle(color: Colors.white)),
|
|
||||||
),
|
home: HomeScreen(),
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
onPressed: null,
|
|
||||||
backgroundColor: const Color(0xFF6264AE),
|
|
||||||
shape: const CircleBorder(),
|
|
||||||
child: const Icon(Icons.add, color: const Color(0xFF22202B)),
|
|
||||||
),
|
|
||||||
backgroundColor: const Color(0xFF22202B),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,234 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||||
|
|
||||||
|
class AddClient extends StatefulWidget {
|
||||||
|
const AddClient({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AddClient> createState() => _AddClientState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddClientState extends State<AddClient> {
|
||||||
|
final nameController = TextEditingController();
|
||||||
|
final ipController = TextEditingController();
|
||||||
|
final userController = TextEditingController();
|
||||||
|
final cmdController = TextEditingController();
|
||||||
|
final passController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
nameController.dispose();
|
||||||
|
ipController.dispose();
|
||||||
|
userController.dispose();
|
||||||
|
cmdController.dispose();
|
||||||
|
passController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context).colorScheme;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
backgroundColor: theme.surface,
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: theme.surface,
|
||||||
|
title: Text("Add command", style: TextStyle(color: theme.onSurface)),
|
||||||
|
leading: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios_rounded, color: theme.onSurface),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: nameController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Command name',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: ipController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Host (IP address)',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: userController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Login as (user)',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: passController,
|
||||||
|
obscureText: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Password',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: cmdController,
|
||||||
|
minLines: 3,
|
||||||
|
maxLines: 100,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Command',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Spacer(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
_onSaved();
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: theme.primary,
|
||||||
|
fixedSize: const Size(140, 40),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Add',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.onPrimary,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSaved() {
|
||||||
|
// Create the object using the controller text
|
||||||
|
final newCmd = ServerCommand(
|
||||||
|
name: nameController.text,
|
||||||
|
ip: ipController.text,
|
||||||
|
username: userController.text,
|
||||||
|
command: cmdController.text,
|
||||||
|
password: passController.text,
|
||||||
|
);
|
||||||
|
|
||||||
|
print("Saving: ${newCmd.name}");
|
||||||
|
|
||||||
|
// Send the object BACK to the previous screen (Home)
|
||||||
|
Navigator.pop(context, newCmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,319 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||||
|
|
||||||
|
class EditClient extends StatefulWidget {
|
||||||
|
final ServerCommand? existingCommand; // Null if adding, not null if editing
|
||||||
|
final int? index;
|
||||||
|
|
||||||
|
const EditClient({super.key, this.existingCommand, this.index});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<EditClient> createState() => _EditClientState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EditClientState extends State<EditClient> {
|
||||||
|
final nameController = TextEditingController();
|
||||||
|
final ipController = TextEditingController();
|
||||||
|
final userController = TextEditingController();
|
||||||
|
final cmdController = TextEditingController();
|
||||||
|
final passController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
nameController.dispose();
|
||||||
|
ipController.dispose();
|
||||||
|
userController.dispose();
|
||||||
|
cmdController.dispose();
|
||||||
|
passController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
if (widget.existingCommand != null) {
|
||||||
|
nameController.text = widget.existingCommand!.name;
|
||||||
|
ipController.text = widget.existingCommand!.ip;
|
||||||
|
userController.text = widget.existingCommand!.username;
|
||||||
|
passController.text = widget.existingCommand!.password;
|
||||||
|
cmdController.text = widget.existingCommand!.command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context).colorScheme;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: theme.surface,
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: theme.surface,
|
||||||
|
title: Text("Edit", style: TextStyle(color: theme.onSurface)),
|
||||||
|
leading: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios_rounded, color: theme.onSurface),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: nameController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Command name',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: ipController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Host (IP address)',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: userController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Login as (user)',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: passController,
|
||||||
|
obscureText: true,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Password',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
TextField(
|
||||||
|
style: TextStyle(color: theme.onSurface),
|
||||||
|
controller: cmdController,
|
||||||
|
minLines: 3,
|
||||||
|
maxLines: 100,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: theme.primaryContainer,
|
||||||
|
labelText: 'Command',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: theme.onSurfaceVariant,
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
borderSide: BorderSide(color: Color.fromARGB(0, 0, 0, 0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Spacer(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 20),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.circular(25.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 400,
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'Remove this command?',
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
Navigator.pop(context, "DELETE");
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: theme.error,
|
||||||
|
fixedSize: const Size(140, 40),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Yes, remove',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.surface,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: theme.onSurface,
|
||||||
|
fixedSize: const Size(140, 40),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'No',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.surface,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: theme.error,
|
||||||
|
fixedSize: const Size(140, 40),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Remove',
|
||||||
|
style: TextStyle(
|
||||||
|
color: const Color.fromARGB(255, 0, 0, 0),
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _save,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: theme.onSurface,
|
||||||
|
fixedSize: const Size(140, 40),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Save',
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.surface,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _save() {
|
||||||
|
final updatedCommand = ServerCommand(
|
||||||
|
name: nameController.text,
|
||||||
|
ip: ipController.text,
|
||||||
|
username: userController.text,
|
||||||
|
command: cmdController.text,
|
||||||
|
password: passController.text,
|
||||||
|
);
|
||||||
|
|
||||||
|
Navigator.pop(context, updatedCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:QuickSSH/screens/edit_client.dart';
|
||||||
|
import '../widgets/server_status_tile.dart';
|
||||||
|
import 'add_client.dart';
|
||||||
|
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||||
|
import 'package:QuickSSH/services/storage_service.dart';
|
||||||
|
|
||||||
|
class HomeScreen extends StatefulWidget {
|
||||||
|
const HomeScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HomeScreen> createState() => _HomeScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomeScreenState extends State<HomeScreen> {
|
||||||
|
List<ServerCommand> allCommands = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadData() async {
|
||||||
|
allCommands = await SecureStorageService.loadCommands();
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context).colorScheme;
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: theme.surface,
|
||||||
|
leading: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: Icon(Icons.menu, color: theme.onSurface),
|
||||||
|
onPressed: () {
|
||||||
|
Scaffold.of(context).openDrawer();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
drawer: Drawer(
|
||||||
|
backgroundColor: theme.primaryContainer,
|
||||||
|
child: ListView(
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
"Settings",
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.onSurface,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
"Help",
|
||||||
|
style: TextStyle(
|
||||||
|
color: theme.onSurface,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: ListView.builder(
|
||||||
|
itemCount: allCommands.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
// You can keep this as 'context' or rename it
|
||||||
|
return ServerStatusTile(
|
||||||
|
command: allCommands[index],
|
||||||
|
onEdit: () => _editCommand(allCommands[index], index),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
floatingActionButton: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return FloatingActionButton(
|
||||||
|
backgroundColor: theme.primary,
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.add,
|
||||||
|
color: Color.fromARGB(255, 0, 0, 0),
|
||||||
|
size: 32,
|
||||||
|
weight: 50,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_addCommand();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
backgroundColor: theme.surface,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _addCommand() async {
|
||||||
|
// 1. Must be async
|
||||||
|
print("Opening Add Screen...");
|
||||||
|
|
||||||
|
final result = await Navigator.push(
|
||||||
|
// 2. Must have await
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => const AddClient()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// This part only runs AFTER you come back from AddClient
|
||||||
|
if (result != null) {
|
||||||
|
print("Received data: ${result.name}");
|
||||||
|
setState(() {
|
||||||
|
allCommands.add(result);
|
||||||
|
});
|
||||||
|
SecureStorageService.saveCommands(allCommands);
|
||||||
|
} else {
|
||||||
|
print("Result was null - user might have just hit 'Back'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_editCommand(ServerCommand cmdToEdit, int index) async {
|
||||||
|
final result = await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => EditClient(existingCommand: cmdToEdit),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
if (result == "DELETE") {
|
||||||
|
setState(() {
|
||||||
|
allCommands.removeAt(index);
|
||||||
|
});
|
||||||
|
SecureStorageService.saveCommands(allCommands);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Received edited data: ${result.name}");
|
||||||
|
setState(() {
|
||||||
|
allCommands[index] = result;
|
||||||
|
});
|
||||||
|
SecureStorageService.saveCommands(allCommands);
|
||||||
|
} else {
|
||||||
|
print("Edit result was null - user might have just hit 'Back'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:dartssh2/dartssh2.dart';
|
||||||
|
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||||
|
|
||||||
|
class SSHService {
|
||||||
|
static Future<String> execute(ServerCommand server) async {
|
||||||
|
try {
|
||||||
|
// 1. Connect to the IP and Port
|
||||||
|
final socket = await SSHSocket.connect(
|
||||||
|
server.ip,
|
||||||
|
22,
|
||||||
|
timeout: const Duration(seconds: 10),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2. Authenticate
|
||||||
|
final client = SSHClient(
|
||||||
|
socket,
|
||||||
|
username: server.username,
|
||||||
|
onPasswordRequest: () => server.password,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 3. Run the specific command
|
||||||
|
final result = await client.run(server.command);
|
||||||
|
|
||||||
|
client.close();
|
||||||
|
await client.done;
|
||||||
|
|
||||||
|
// 4. Return the server's response
|
||||||
|
return utf8.decode(result);
|
||||||
|
} catch (e) {
|
||||||
|
return "Error: $e";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||||
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
|
||||||
|
class SecureStorageService {
|
||||||
|
static const _storage = FlutterSecureStorage();
|
||||||
|
static const _key = 'mc_commands_list';
|
||||||
|
|
||||||
|
// SAVE: Converts list to JSON, then encrypts and stores it
|
||||||
|
static Future<void> saveCommands(List<ServerCommand> commands) async {
|
||||||
|
final String jsonData = jsonEncode(commands.map((c) => c.toMap()).toList());
|
||||||
|
await _storage.write(key: _key, value: jsonData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOAD: Decrypts data, then converts JSON back to Objects
|
||||||
|
static Future<List<ServerCommand>> loadCommands() async {
|
||||||
|
final String? encryptedData = await _storage.read(key: _key);
|
||||||
|
|
||||||
|
if (encryptedData == null) return [];
|
||||||
|
|
||||||
|
final List<dynamic> decodedData = jsonDecode(encryptedData);
|
||||||
|
return decodedData.map((item) => ServerCommand.fromMap(item)).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||||
|
import 'package:QuickSSH/services/SSHService.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class ServerStatusTile extends StatelessWidget {
|
||||||
|
final ServerCommand command;
|
||||||
|
final VoidCallback onEdit;
|
||||||
|
|
||||||
|
const ServerStatusTile({
|
||||||
|
super.key,
|
||||||
|
required this.command,
|
||||||
|
required this.onEdit,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context).colorScheme;
|
||||||
|
|
||||||
|
return Card(
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
color: theme.primaryContainer,
|
||||||
|
child: InkWell(
|
||||||
|
splashColor: const Color.fromARGB(
|
||||||
|
47,
|
||||||
|
255,
|
||||||
|
255,
|
||||||
|
255,
|
||||||
|
), // Custom ripple color!
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
|
|
||||||
|
onDoubleTap: () {
|
||||||
|
HapticFeedback.heavyImpact();
|
||||||
|
_handleCommandTap(context, command);
|
||||||
|
},
|
||||||
|
|
||||||
|
onLongPress: () {
|
||||||
|
HapticFeedback.heavyImpact();
|
||||||
|
onEdit();
|
||||||
|
},
|
||||||
|
|
||||||
|
child: IgnorePointer(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(
|
||||||
|
command.name,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
color: theme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
"${command.username}@${command.ip}",
|
||||||
|
style: TextStyle(color: theme.onSurfaceVariant),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleCommandTap(BuildContext context, ServerCommand cmd) async {
|
||||||
|
// Show a "Loading" snackbar
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
content: Text("Connecting to ${cmd.ip} as ${cmd.username}..."),
|
||||||
|
duration: Duration(seconds: 2),
|
||||||
|
backgroundColor: const Color.fromARGB(255, 56, 159, 243),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Run the SSH command
|
||||||
|
String output = await SSHService.execute(cmd);
|
||||||
|
|
||||||
|
// Show the final result from the server
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
content: Text(output.isEmpty ? "Command executed (no output)" : output),
|
||||||
|
backgroundColor: output.contains("Error") ? Colors.red : Colors.green,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,10 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
||||||
|
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
flutter_secure_storage_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import flutter_secure_storage_macos
|
||||||
|
import path_provider_foundation
|
||||||
|
import shared_preferences_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||||
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
{
|
{
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
},
|
||||||
"images": [
|
"images": [
|
||||||
{
|
{
|
||||||
"size": "16x16",
|
"size": "16x16",
|
||||||
|
|
@ -60,9 +64,5 @@
|
||||||
"filename": "app_icon_1024.png",
|
"filename": "app_icon_1024.png",
|
||||||
"scale": "2x"
|
"scale": "2x"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 712 B |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.9 KiB |
367
pubspec.lock
|
|
@ -1,6 +1,30 @@
|
||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.7"
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.7.0"
|
||||||
|
asn1lib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: asn1lib
|
||||||
|
sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.6.5"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -25,6 +49,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
|
checked_yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: checked_yaml
|
||||||
|
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.4"
|
||||||
|
cli_util:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cli_util
|
||||||
|
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.4.2"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -41,6 +81,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.19.1"
|
version: "1.19.1"
|
||||||
|
convert:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: convert
|
||||||
|
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
|
crypto:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: crypto
|
||||||
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.7"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -49,6 +105,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
|
dartssh2:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dartssh2
|
||||||
|
sha256: bb242396c1d90f05c261b5eb8338cc67167e803c0948b0207029339cc568a66c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.0"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -57,11 +121,35 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.3.3"
|
||||||
|
ffi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ffi
|
||||||
|
sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.5"
|
||||||
|
file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file
|
||||||
|
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_launcher_icons:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: flutter_launcher_icons
|
||||||
|
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.1"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
|
@ -70,11 +158,88 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.0"
|
||||||
|
flutter_secure_storage:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage
|
||||||
|
sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.2.4"
|
||||||
|
flutter_secure_storage_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_linux
|
||||||
|
sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.3"
|
||||||
|
flutter_secure_storage_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_macos
|
||||||
|
sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.3"
|
||||||
|
flutter_secure_storage_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_platform_interface
|
||||||
|
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_secure_storage_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_web
|
||||||
|
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
|
flutter_secure_storage_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_windows
|
||||||
|
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
sha256: "492bd52f6c4fbb6ee41f781ff27765ce5f627910e1e0cbecfa3d9add5562604c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.7.2"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.7"
|
||||||
|
json_annotation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
sha256: "805fa86df56383000f640384b282ce0cb8431f1a7a2396de92fb66186d8c57df"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.10.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -139,6 +304,158 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
|
path_provider:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider
|
||||||
|
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.5"
|
||||||
|
path_provider_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_android
|
||||||
|
sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.22"
|
||||||
|
path_provider_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_foundation
|
||||||
|
sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.1"
|
||||||
|
path_provider_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_linux
|
||||||
|
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.1"
|
||||||
|
path_provider_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_platform_interface
|
||||||
|
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.2"
|
||||||
|
path_provider_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_windows
|
||||||
|
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.1"
|
||||||
|
pinenacl:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pinenacl
|
||||||
|
sha256: "57e907beaacbc3c024a098910b6240758e899674de07d6949a67b52fd984cbdf"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.0"
|
||||||
|
platform:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: platform
|
||||||
|
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.6"
|
||||||
|
plugin_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: plugin_platform_interface
|
||||||
|
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.8"
|
||||||
|
pointycastle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointycastle
|
||||||
|
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.9.1"
|
||||||
|
posix:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: posix
|
||||||
|
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.3"
|
||||||
|
shared_preferences:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: shared_preferences
|
||||||
|
sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.4"
|
||||||
|
shared_preferences_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_android
|
||||||
|
sha256: cbc40be9be1c5af4dab4d6e0de4d5d3729e6f3d65b89d21e1815d57705644a6f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.20"
|
||||||
|
shared_preferences_foundation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_foundation
|
||||||
|
sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.6"
|
||||||
|
shared_preferences_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_linux
|
||||||
|
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.1"
|
||||||
|
shared_preferences_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_platform_interface
|
||||||
|
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.1"
|
||||||
|
shared_preferences_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_web
|
||||||
|
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.3"
|
||||||
|
shared_preferences_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_windows
|
||||||
|
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.1"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
@ -192,6 +509,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.6"
|
version: "0.7.6"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -208,6 +533,46 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.0.2"
|
version: "15.0.2"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
|
win32:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32
|
||||||
|
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.15.0"
|
||||||
|
xdg_directories:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xdg_directories
|
||||||
|
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.6.1"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.9.2 <4.0.0"
|
dart: ">=3.9.2 <4.0.0"
|
||||||
flutter: ">=3.18.0-18.0.pre.54"
|
flutter: ">=3.35.0"
|
||||||
|
|
|
||||||
23
pubspec.yaml
|
|
@ -1,5 +1,5 @@
|
||||||
name: quick_ssh
|
name: QuickSSH
|
||||||
description: "A new Flutter project."
|
description: "SSH command sender"
|
||||||
# The following line prevents the package from being accidentally published to
|
# The following line prevents the package from being accidentally published to
|
||||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
# pub.dev using `flutter 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
|
||||||
|
|
@ -30,21 +30,28 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
shared_preferences: ^2.5.0
|
||||||
|
dartssh2: ^2.0.0
|
||||||
|
flutter_secure_storage: ^9.2.2
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
flutter_lints: ^5.0.0
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_launcher_icons: ^0.13.1
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
flutter_launcher_icons:
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
image_path: "lib/assets/images/app_icon.png"
|
||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
android: true
|
||||||
# package. See that file for information about deactivating specific lint
|
ios: true
|
||||||
# rules and activating additional ones.
|
windows:
|
||||||
flutter_lints: ^5.0.0
|
generate: true
|
||||||
|
macos:
|
||||||
|
generate: true
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
flutter_secure_storage_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 1.5 KiB |