Added ads
This commit is contained in:
parent
eed999d2ab
commit
7c47298cd7
|
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
"cmake.ignoreCMakeListsMissing": true
|
"cmake.ignoreCMakeListsMissing": true,
|
||||||
|
"java.configuration.updateBuildConfiguration": "disabled"
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="QuickSSH"
|
android:label="QuickSSH"
|
||||||
|
|
@ -33,6 +34,9 @@
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
||||||
|
android:value="ca-app-pub-2626773788355001~4397436505"/>
|
||||||
</application>
|
</application>
|
||||||
<!-- Required to query activities that can process text, see:
|
<!-- Required to query activities that can process text, see:
|
||||||
https://developer.android.com/training/package-visibility and
|
https://developer.android.com/training/package-visibility and
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.example.quick_ssh
|
package com.example.quick_ssh
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterFragmentActivity
|
||||||
|
|
||||||
class MainActivity : FlutterActivity()
|
class MainActivity : FlutterFragmentActivity(){
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
<style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
|
||||||
<!-- Show a splash screen on the activity. Automatically removed when
|
|
||||||
the Flutter engine draws its first frame -->
|
|
||||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||||
</style>
|
</style>
|
||||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
|
||||||
This theme determines the color of the Android Window while your
|
|
||||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
|
||||||
running.
|
|
||||||
|
|
||||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
<style name="NormalTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
|
||||||
<item name="android:windowBackground">?android:colorBackground</item>
|
<item name="android:windowBackground">?android:colorBackground</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -45,5 +45,8 @@
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSFaceIDUsageDescription</key>
|
||||||
|
<string>QuickSSH needs FaceID to protect your terminal access.</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,13 @@ import 'package:QuickSSH/services/theme_controller.dart';
|
||||||
final themeController = ThemeController();
|
final themeController = ThemeController();
|
||||||
final settingsController = SettingsController();
|
final settingsController = SettingsController();
|
||||||
|
|
||||||
void main() {
|
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
await settingsController.initializationFuture;
|
||||||
|
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,6 +28,8 @@ class MyApp extends StatelessWidget {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Quick SSH',
|
title: 'Quick SSH',
|
||||||
|
|
||||||
|
navigatorKey: navigatorKey,
|
||||||
|
|
||||||
theme: MyThemes.lightTheme,
|
theme: MyThemes.lightTheme,
|
||||||
darkTheme: MyThemes.darkTheme,
|
darkTheme: MyThemes.darkTheme,
|
||||||
themeMode: themeController.themeMode,
|
themeMode: themeController.themeMode,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ import 'add_client.dart';
|
||||||
import 'package:QuickSSH/classes/ServerCommand.dart';
|
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||||
import 'package:QuickSSH/services/storage_service.dart';
|
import 'package:QuickSSH/services/storage_service.dart';
|
||||||
import 'package:QuickSSH/screens/settings.dart';
|
import 'package:QuickSSH/screens/settings.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:QuickSSH/main.dart';
|
||||||
|
import 'package:QuickSSH/widgets/ad_banner.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
const HomeScreen({super.key});
|
const HomeScreen({super.key});
|
||||||
|
|
@ -20,6 +23,13 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_loadData();
|
_loadData();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
bool allowed = await settingsController.checkSecurity();
|
||||||
|
|
||||||
|
if (!allowed) {
|
||||||
|
SystemNavigator.pop();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadData() async {
|
void _loadData() async {
|
||||||
|
|
@ -106,6 +116,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
bottomNavigationBar: SafeArea(
|
||||||
|
child: MyBannerAd(isEnabled: settingsController.adsEnabled),
|
||||||
|
),
|
||||||
backgroundColor: theme.surface,
|
backgroundColor: theme.surface,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +164,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
_openSettings() {
|
_openSettings() {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => const Settings()),
|
MaterialPageRoute(builder: (context) => Settings()),
|
||||||
);
|
).then((_) {
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,64 @@ class _SettingsState extends State<Settings> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
"Biometric Unlock",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
color: theme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Switch(
|
||||||
|
activeTrackColor: theme.primary,
|
||||||
|
activeThumbColor: theme.onPrimary,
|
||||||
|
inactiveThumbColor: theme.onSurface,
|
||||||
|
inactiveTrackColor: theme.surface,
|
||||||
|
value: settingsController.biometricEnabled,
|
||||||
|
onChanged: (bool value) {
|
||||||
|
settingsController.toggleBiometric(value);
|
||||||
|
if (value) HapticFeedback.mediumImpact();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
"Enable Ads",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
color: theme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Switch(
|
||||||
|
activeTrackColor: theme.primary,
|
||||||
|
activeThumbColor: theme.onPrimary,
|
||||||
|
inactiveThumbColor: theme.onSurface,
|
||||||
|
inactiveTrackColor: theme.surface,
|
||||||
|
value: settingsController.adsEnabled,
|
||||||
|
onChanged: (bool value) {
|
||||||
|
settingsController.toggleAds(value);
|
||||||
|
if (value) HapticFeedback.mediumImpact();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,71 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:local_auth/local_auth.dart';
|
||||||
|
|
||||||
class SettingsController extends ChangeNotifier {
|
class SettingsController extends ChangeNotifier {
|
||||||
bool _vibrationEnabled = true;
|
bool _vibrationEnabled = true;
|
||||||
bool get vibrationEnabled => _vibrationEnabled;
|
bool get vibrationEnabled => _vibrationEnabled;
|
||||||
|
|
||||||
|
bool _biometricEnabled = false;
|
||||||
|
bool get biometricEnabled => _biometricEnabled;
|
||||||
|
|
||||||
|
bool _adsEnabled = true;
|
||||||
|
bool get adsEnabled => _adsEnabled;
|
||||||
|
|
||||||
|
final LocalAuthentication auth = LocalAuthentication();
|
||||||
|
|
||||||
|
late Future<void> initializationFuture;
|
||||||
|
|
||||||
SettingsController() {
|
SettingsController() {
|
||||||
_loadSettings();
|
initializationFuture = _loadSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadSettings() async {
|
Future<void> _loadSettings() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
_vibrationEnabled = prefs.getBool('vibration_enabled') ?? true;
|
_vibrationEnabled = prefs.getBool('vibration_enabled') ?? true;
|
||||||
|
_biometricEnabled = prefs.getBool('biometric_enabled') ?? false;
|
||||||
|
_adsEnabled = prefs.getBool('ads_enabled') ?? true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> toggleVibration(bool value) async {
|
Future<void> toggleVibration(bool value) async {
|
||||||
print("Toggling vibration to: $value");
|
|
||||||
_vibrationEnabled = value;
|
_vibrationEnabled = value;
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
await prefs.setBool('vibration_enabled', value);
|
await prefs.setBool('vibration_enabled', value);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> toggleBiometric(bool value) async {
|
||||||
|
_biometricEnabled = value;
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setBool('biometric_enabled', value);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleAds(bool value) async {
|
||||||
|
_adsEnabled = value;
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setBool('ads_enabled', value);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> checkSecurity() async {
|
||||||
|
await initializationFuture;
|
||||||
|
|
||||||
|
if (!_biometricEnabled) return true;
|
||||||
|
|
||||||
|
bool canCheck = await auth.canCheckBiometrics;
|
||||||
|
bool isSupported = await auth.isDeviceSupported();
|
||||||
|
|
||||||
|
if (!canCheck && !isSupported) return true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await auth.authenticate(
|
||||||
|
localizedReason: 'Unlock QuickSSH',
|
||||||
|
biometricOnly: false,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import 'package:google_mobile_ads/google_mobile_ads.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class MyBannerAd extends StatefulWidget {
|
||||||
|
final bool isEnabled;
|
||||||
|
const MyBannerAd({super.key, required this.isEnabled});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MyBannerAd> createState() => _MyBannerAdState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyBannerAdState extends State<MyBannerAd> {
|
||||||
|
BannerAd? _bannerAd;
|
||||||
|
bool _isLoaded = false;
|
||||||
|
bool _isInitializing = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
if (widget.isEnabled) {
|
||||||
|
_loadAd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadAd() async {
|
||||||
|
_bannerAd = BannerAd(
|
||||||
|
adUnitId: 'ca-app-pub-2626773788355001/7557216229',
|
||||||
|
request: const AdRequest(),
|
||||||
|
size: AdSize.banner,
|
||||||
|
listener: BannerAdListener(
|
||||||
|
onAdLoaded: (ad) => setState(() => _isLoaded = true),
|
||||||
|
onAdFailedToLoad: (ad, error) {
|
||||||
|
ad.dispose();
|
||||||
|
print('Ad failed to load: $error');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)..load();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_bannerAd?.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (!widget.isEnabled || !_isLoaded || _bannerAd == null) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
width: double.infinity,
|
||||||
|
height: _bannerAd!.size.height.toDouble(),
|
||||||
|
child: AdWidget(ad: _bannerAd!),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,10 +9,12 @@ import flutter_secure_storage_macos
|
||||||
import local_auth_darwin
|
import local_auth_darwin
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
import webview_flutter_wkwebview
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||||
LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin"))
|
LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
|
WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
56
pubspec.lock
56
pubspec.lock
|
|
@ -224,6 +224,14 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
google_mobile_ads:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: google_mobile_ads
|
||||||
|
sha256: "0d4a3744b5e8ed1b8be6a1b452d309f811688855a497c6113fc4400f922db603"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.3.1"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -292,26 +300,26 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: local_auth
|
name: local_auth
|
||||||
sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b"
|
sha256: a4f1bf57f0236a4aeb5e8f0ec180e197f4b112a3456baa6c1e73b546630b0422
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "3.0.0"
|
||||||
local_auth_android:
|
local_auth_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: local_auth_android
|
name: local_auth_android
|
||||||
sha256: a0bdfcc0607050a26ef5b31d6b4b254581c3d3ce3c1816ab4d4f4a9173e84467
|
sha256: "162b8e177fd9978c4620da2a8002a5c6bed4d20f0c6daf5137e72e9a8b767d2e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.56"
|
version: "2.0.4"
|
||||||
local_auth_darwin:
|
local_auth_darwin:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: local_auth_darwin
|
name: local_auth_darwin
|
||||||
sha256: "699873970067a40ef2f2c09b4c72eb1cfef64224ef041b3df9fdc5c4c1f91f49"
|
sha256: "668ea65edaab17380956e9713f57e34f78ede505ca0cfd8d39db34e2f260bfee"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.1"
|
version: "2.0.1"
|
||||||
local_auth_platform_interface:
|
local_auth_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -324,10 +332,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: local_auth_windows
|
name: local_auth_windows
|
||||||
sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5
|
sha256: be12c5b8ba5e64896983123655c5f67d2484ecfcc95e367952ad6e3bff94cb16
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.11"
|
version: "2.0.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -597,6 +605,38 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
webview_flutter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: webview_flutter
|
||||||
|
sha256: a3da219916aba44947d3a5478b1927876a09781174b5a2b67fa5be0555154bf9
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.13.1"
|
||||||
|
webview_flutter_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: webview_flutter_android
|
||||||
|
sha256: eeeb3fcd5f0ff9f8446c9f4bbc18a99b809e40297528a3395597d03aafb9f510
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.10.11"
|
||||||
|
webview_flutter_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: webview_flutter_platform_interface
|
||||||
|
sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.14.0"
|
||||||
|
webview_flutter_wkwebview:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: webview_flutter_wkwebview
|
||||||
|
sha256: "0412b657a2828fb301e73509909e6ec02b77cd2b441ae9f77125d482b3ddf0e7"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.23.6"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ dependencies:
|
||||||
shared_preferences: ^2.5.0
|
shared_preferences: ^2.5.0
|
||||||
dartssh2: ^2.0.0
|
dartssh2: ^2.0.0
|
||||||
flutter_secure_storage: ^9.2.2
|
flutter_secure_storage: ^9.2.2
|
||||||
local_auth: ^2.3.0
|
local_auth: ^3.0.0
|
||||||
|
google_mobile_ads: ^5.1.0
|
||||||
|
|
||||||
# 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.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue