add settings page so set ssh login
request storage permissions on android
This commit is contained in:
		@@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
 | 
				
			|||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 | 
					apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
android {
 | 
					android {
 | 
				
			||||||
    compileSdkVersion flutter.compileSdkVersion
 | 
					    compileSdkVersion 33
 | 
				
			||||||
    ndkVersion flutter.ndkVersion
 | 
					    ndkVersion flutter.ndkVersion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    compileOptions {
 | 
					    compileOptions {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
					<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
    package="eu.heili.gallery">
 | 
					    package="eu.heili.gallery">
 | 
				
			||||||
 | 
					    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 | 
				
			||||||
 | 
					    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 | 
				
			||||||
   <application
 | 
					   <application
 | 
				
			||||||
        android:label="gallery"
 | 
					        android:label="gallery"
 | 
				
			||||||
        android:name="${applicationName}"
 | 
					        android:name="${applicationName}"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,11 @@ class Item {
 | 
				
			|||||||
  String name;
 | 
					  String name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Item(this.isFolder, this.uri, this.name);
 | 
					  Item(this.isFolder, this.uri, this.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  String toString() {
 | 
				
			||||||
 | 
					    return 'Item{isFolder: $isFolder, uri: $uri, name: $name}';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Folder {
 | 
					class Folder {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,11 +10,11 @@ import 'dart:ui' as ui show Codec, ImmutableBuffer;
 | 
				
			|||||||
import 'package:path_provider/path_provider.dart';
 | 
					import 'package:path_provider/path_provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SSHDataProvider extends DataProvider {
 | 
					class SSHDataProvider extends DataProvider {
 | 
				
			||||||
  final String host;
 | 
					  final Future<String> host;
 | 
				
			||||||
  final int port;
 | 
					  final Future<int> port;
 | 
				
			||||||
  final String username;
 | 
					  final Future<String> username;
 | 
				
			||||||
  final String password;
 | 
					  final Future<String> password;
 | 
				
			||||||
  final String initialPath;
 | 
					  final Future<String> initialPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SftpClient? sftpClient;
 | 
					  SftpClient? sftpClient;
 | 
				
			||||||
  SSHClient? sshClient;
 | 
					  SSHClient? sshClient;
 | 
				
			||||||
@@ -31,8 +31,8 @@ class SSHDataProvider extends DataProvider {
 | 
				
			|||||||
    if (sshClient != null && !sshClient!.isClosed) return;
 | 
					    if (sshClient != null && !sshClient!.isClosed) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sshClient = SSHClient(
 | 
					    sshClient = SSHClient(
 | 
				
			||||||
      await SSHSocket.connect(host, port),
 | 
					      await SSHSocket.connect(await host, await port),
 | 
				
			||||||
      username: username,
 | 
					      username: await username,
 | 
				
			||||||
      onPasswordRequest: () => password,
 | 
					      onPasswordRequest: () => password,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    await sshClient?.authenticated;
 | 
					    await sshClient?.authenticated;
 | 
				
			||||||
@@ -45,7 +45,8 @@ class SSHDataProvider extends DataProvider {
 | 
				
			|||||||
    await connect();
 | 
					    await connect();
 | 
				
			||||||
    if (sftpClient == null) throw const FormatException("");
 | 
					    if (sftpClient == null) throw const FormatException("");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final dir = uri != null ? Directory.fromUri(uri) : Directory(initialPath);
 | 
					    final dir =
 | 
				
			||||||
 | 
					        uri != null ? Directory.fromUri(uri) : Directory(await initialPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final items = await sftpClient!.listdir(dir.path);
 | 
					    final items = await sftpClient!.listdir(dir.path);
 | 
				
			||||||
    List<Item> res = [];
 | 
					    List<Item> res = [];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,9 @@
 | 
				
			|||||||
import 'dart:io';
 | 
					import 'dart:io';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:gallery/data_provider/data_provider.dart';
 | 
					import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 | 
				
			||||||
import 'package:gallery/image_grid.dart';
 | 
					import 'package:gallery/image_grid.dart';
 | 
				
			||||||
 | 
					import 'package:gallery/settings_page.dart';
 | 
				
			||||||
import 'package:path_provider/path_provider.dart';
 | 
					import 'package:path_provider/path_provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'data_provider/local_data_provider.dart';
 | 
					import 'data_provider/local_data_provider.dart';
 | 
				
			||||||
@@ -17,7 +18,7 @@ class MyHomePage extends StatefulWidget {
 | 
				
			|||||||
  State<MyHomePage> createState() => _MyHomePageState();
 | 
					  State<MyHomePage> createState() => _MyHomePageState();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum Page { local, remote }
 | 
					enum Page { local, remote, settings }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _MyHomePageState extends State<MyHomePage> {
 | 
					class _MyHomePageState extends State<MyHomePage> {
 | 
				
			||||||
  Page page = Page.local;
 | 
					  Page page = Page.local;
 | 
				
			||||||
@@ -34,19 +35,27 @@ class _MyHomePageState extends State<MyHomePage> {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget _buildPage() {
 | 
					  Widget _buildPage() {
 | 
				
			||||||
    DataProvider provider;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    switch (page) {
 | 
					    switch (page) {
 | 
				
			||||||
      case Page.local:
 | 
					      case Page.local:
 | 
				
			||||||
        provider = LocalDataProvider(_getLocalDir());
 | 
					        return ImageGrid(dProvider: LocalDataProvider(_getLocalDir()));
 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case Page.remote:
 | 
					      case Page.remote:
 | 
				
			||||||
        // todo do not generate a new provider on each tab switch
 | 
					        // todo do not generate a new provider on each tab switch
 | 
				
			||||||
        provider = SSHDataProvider(
 | 
					        const storage = FlutterSecureStorage();
 | 
				
			||||||
            initialPath: "/", host: "", password: "", port: 0, username: "");
 | 
					
 | 
				
			||||||
        break;
 | 
					        return ImageGrid(
 | 
				
			||||||
 | 
					            dProvider: SSHDataProvider(
 | 
				
			||||||
 | 
					                initialPath:
 | 
				
			||||||
 | 
					                    Future.value("/media/3TBRaid/3TBRaid/Bilder/2022/"),
 | 
				
			||||||
 | 
					                host: (() async => (await storage.read(key: "host")) ?? "")
 | 
				
			||||||
 | 
					                    .call(),
 | 
				
			||||||
 | 
					                password:
 | 
				
			||||||
 | 
					                    (() async => (await storage.read(key: "pwd")) ?? "").call(),
 | 
				
			||||||
 | 
					                port: Future.value(22),
 | 
				
			||||||
 | 
					                username: (() async => (await storage.read(key: "user")) ?? "")
 | 
				
			||||||
 | 
					                    .call()));
 | 
				
			||||||
 | 
					      case Page.settings:
 | 
				
			||||||
 | 
					        return const SettingsPage();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ImageGrid(dProvider: provider);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
@@ -84,6 +93,15 @@ class _MyHomePageState extends State<MyHomePage> {
 | 
				
			|||||||
                Navigator.pop(context);
 | 
					                Navigator.pop(context);
 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 | 
					            ListTile(
 | 
				
			||||||
 | 
					              title: const Text('Settings'),
 | 
				
			||||||
 | 
					              onTap: () {
 | 
				
			||||||
 | 
					                setState(() {
 | 
				
			||||||
 | 
					                  page = Page.settings;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                Navigator.pop(context);
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					import 'dart:io';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'data_provider/data_provider.dart';
 | 
					import 'data_provider/data_provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,13 +43,15 @@ class _ImageGridState extends State<ImageGrid> {
 | 
				
			|||||||
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 | 
					              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 | 
				
			||||||
                crossAxisSpacing: 0,
 | 
					                crossAxisSpacing: 0,
 | 
				
			||||||
                mainAxisSpacing: 0,
 | 
					                mainAxisSpacing: 0,
 | 
				
			||||||
                crossAxisCount: width ~/ 300,
 | 
					                crossAxisCount:
 | 
				
			||||||
 | 
					                    Platform.isAndroid ? width ~/ 100 : width ~/ 300,
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
              itemCount: data.items.length + 1,
 | 
					              itemCount: data.items.length + 1,
 | 
				
			||||||
              itemBuilder: (context, index) {
 | 
					              itemBuilder: (context, index) {
 | 
				
			||||||
                if (index == 0) {
 | 
					                if (index == 0) {
 | 
				
			||||||
                  return ImageTile(
 | 
					                  return ImageTile(
 | 
				
			||||||
                    child: const Icon(Icons.arrow_back, size: 142),
 | 
					                    child: Icon(Icons.arrow_back,
 | 
				
			||||||
 | 
					                        size: Platform.isAndroid ? 64 : 142),
 | 
				
			||||||
                    onClick: () {
 | 
					                    onClick: () {
 | 
				
			||||||
                      setState(() {
 | 
					                      setState(() {
 | 
				
			||||||
                        folder = widget.dProvider.listOfFiles(uri: data.parent);
 | 
					                        folder = widget.dProvider.listOfFiles(uri: data.parent);
 | 
				
			||||||
@@ -93,7 +97,8 @@ class _ImageGridState extends State<ImageGrid> {
 | 
				
			|||||||
                        ? Column(
 | 
					                        ? Column(
 | 
				
			||||||
                            mainAxisAlignment: MainAxisAlignment.center,
 | 
					                            mainAxisAlignment: MainAxisAlignment.center,
 | 
				
			||||||
                            children: [
 | 
					                            children: [
 | 
				
			||||||
                              const Icon(Icons.folder_open, size: 142),
 | 
					                              Icon(Icons.folder_open,
 | 
				
			||||||
 | 
					                                  size: Platform.isAndroid ? 64 : 142),
 | 
				
			||||||
                              Text(elem.name)
 | 
					                              Text(elem.name)
 | 
				
			||||||
                            ],
 | 
					                            ],
 | 
				
			||||||
                          )
 | 
					                          )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,22 @@
 | 
				
			|||||||
 | 
					import 'dart:io';
 | 
				
			||||||
import 'dart:ui';
 | 
					import 'dart:ui';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:permission_handler/permission_handler.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'home_page.dart';
 | 
					import 'home_page.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main() async {
 | 
				
			||||||
 | 
					  WidgetsFlutterBinding.ensureInitialized();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (Platform.isAndroid) {
 | 
				
			||||||
 | 
					    if (await Permission.storage.request().isGranted) {
 | 
				
			||||||
      runApp(const MyApp());
 | 
					      runApp(const MyApp());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    runApp(const MyApp());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AppScrollBehavior extends MaterialScrollBehavior {
 | 
					class AppScrollBehavior extends MaterialScrollBehavior {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								lib/settings_page.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								lib/settings_page.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SettingsPage extends StatefulWidget {
 | 
				
			||||||
 | 
					  const SettingsPage({Key? key}) : super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  State<SettingsPage> createState() => _SettingsPageState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _SettingsPageState extends State<SettingsPage> {
 | 
				
			||||||
 | 
					  late TextEditingController _controllerHost;
 | 
				
			||||||
 | 
					  late TextEditingController _controllerUser;
 | 
				
			||||||
 | 
					  late TextEditingController _controllerPwd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void initState() {
 | 
				
			||||||
 | 
					    super.initState();
 | 
				
			||||||
 | 
					    _controllerHost = TextEditingController();
 | 
				
			||||||
 | 
					    _controllerUser = TextEditingController();
 | 
				
			||||||
 | 
					    _controllerPwd = TextEditingController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const storage = FlutterSecureStorage();
 | 
				
			||||||
 | 
					    storage
 | 
				
			||||||
 | 
					        .read(key: "host")
 | 
				
			||||||
 | 
					        .then((value) => _controllerHost.text = value ?? "");
 | 
				
			||||||
 | 
					    storage
 | 
				
			||||||
 | 
					        .read(key: "user")
 | 
				
			||||||
 | 
					        .then((value) => _controllerUser.text = value ?? "");
 | 
				
			||||||
 | 
					    storage.read(key: "pwd").then((value) => _controllerPwd.text = value ?? "");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Padding(
 | 
				
			||||||
 | 
					      padding: const EdgeInsets.all(5),
 | 
				
			||||||
 | 
					      child: Column(
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          const SizedBox(
 | 
				
			||||||
 | 
					            height: 10,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          TextField(
 | 
				
			||||||
 | 
					            decoration: const InputDecoration(
 | 
				
			||||||
 | 
					                border: OutlineInputBorder(), labelText: "host"),
 | 
				
			||||||
 | 
					            controller: _controllerHost,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          const SizedBox(
 | 
				
			||||||
 | 
					            height: 5,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          TextField(
 | 
				
			||||||
 | 
					            decoration: const InputDecoration(
 | 
				
			||||||
 | 
					                border: OutlineInputBorder(), labelText: "user"),
 | 
				
			||||||
 | 
					            controller: _controllerUser,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          const SizedBox(
 | 
				
			||||||
 | 
					            height: 5,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          TextField(
 | 
				
			||||||
 | 
					            obscureText: true,
 | 
				
			||||||
 | 
					            decoration: const InputDecoration(
 | 
				
			||||||
 | 
					                border: OutlineInputBorder(), labelText: "password"),
 | 
				
			||||||
 | 
					            controller: _controllerPwd,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          const SizedBox(
 | 
				
			||||||
 | 
					            height: 5,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          TextButton(
 | 
				
			||||||
 | 
					              onPressed: () {
 | 
				
			||||||
 | 
					                const storage = FlutterSecureStorage();
 | 
				
			||||||
 | 
					                storage.write(key: "host", value: _controllerHost.value.text);
 | 
				
			||||||
 | 
					                storage.write(key: "user", value: _controllerUser.value.text);
 | 
				
			||||||
 | 
					                storage.write(key: "pwd", value: _controllerPwd.value.text);
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              child: const Text("Save"))
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										82
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -111,11 +111,58 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dartlang.org"
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "2.0.1"
 | 
					    version: "2.0.1"
 | 
				
			||||||
 | 
					  flutter_secure_storage:
 | 
				
			||||||
 | 
					    dependency: "direct main"
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: flutter_secure_storage
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "6.0.0"
 | 
				
			||||||
 | 
					  flutter_secure_storage_linux:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: flutter_secure_storage_linux
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "1.1.1"
 | 
				
			||||||
 | 
					  flutter_secure_storage_macos:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: flutter_secure_storage_macos
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "1.1.1"
 | 
				
			||||||
 | 
					  flutter_secure_storage_platform_interface:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: flutter_secure_storage_platform_interface
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "1.0.0"
 | 
				
			||||||
 | 
					  flutter_secure_storage_web:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: flutter_secure_storage_web
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "1.0.2"
 | 
				
			||||||
 | 
					  flutter_secure_storage_windows:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: flutter_secure_storage_windows
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "1.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"
 | 
				
			||||||
  intl:
 | 
					  intl:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
@@ -214,6 +261,41 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dartlang.org"
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "2.1.3"
 | 
					    version: "2.1.3"
 | 
				
			||||||
 | 
					  permission_handler:
 | 
				
			||||||
 | 
					    dependency: "direct main"
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: permission_handler
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "10.0.2"
 | 
				
			||||||
 | 
					  permission_handler_android:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: permission_handler_android
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "10.0.0"
 | 
				
			||||||
 | 
					  permission_handler_apple:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: permission_handler_apple
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "9.0.4"
 | 
				
			||||||
 | 
					  permission_handler_platform_interface:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: permission_handler_platform_interface
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "3.8.0"
 | 
				
			||||||
 | 
					  permission_handler_windows:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: permission_handler_windows
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "0.1.0"
 | 
				
			||||||
  pinenacl:
 | 
					  pinenacl:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,6 +38,8 @@ dependencies:
 | 
				
			|||||||
  cupertino_icons: ^1.0.2
 | 
					  cupertino_icons: ^1.0.2
 | 
				
			||||||
  path_provider: ^2.0.11
 | 
					  path_provider: ^2.0.11
 | 
				
			||||||
  dartssh2: ^2.7.2+3
 | 
					  dartssh2: ^2.7.2+3
 | 
				
			||||||
 | 
					  permission_handler: ^10.0.2
 | 
				
			||||||
 | 
					  flutter_secure_storage: ^6.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dev_dependencies:
 | 
					dev_dependencies:
 | 
				
			||||||
  flutter_test:
 | 
					  flutter_test:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user