mirror of
https://github.com/MoxiFoxi411/QuickSSH.git
synced 2026-11-08 19:24:54 +00:00
Added ads
This commit is contained in:
1 parent
eed999d2ab
commit
7c47298cd7
13 files changed
+258
-29
No files matched your search
+9
-1
@@ -7,7 +7,13 @@ import 'package:QuickSSH/services/theme_controller.dart';
|
||||
final themeController = ThemeController();
|
||||
final settingsController = SettingsController();
|
||||
|
||||
void main() {
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
await settingsController.initializationFuture;
|
||||
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
@@ -22,6 +28,8 @@ class MyApp extends StatelessWidget {
|
||||
return MaterialApp(
|
||||
title: 'Quick SSH',
|
||||
|
||||
navigatorKey: navigatorKey,
|
||||
|
||||
theme: MyThemes.lightTheme,
|
||||
darkTheme: MyThemes.darkTheme,
|
||||
themeMode: themeController.themeMode,
|
||||
|
||||
@@ -5,6 +5,9 @@ import 'add_client.dart';
|
||||
import 'package:QuickSSH/classes/ServerCommand.dart';
|
||||
import 'package:QuickSSH/services/storage_service.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 {
|
||||
const HomeScreen({super.key});
|
||||
@@ -20,6 +23,13 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadData();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
bool allowed = await settingsController.checkSecurity();
|
||||
|
||||
if (!allowed) {
|
||||
SystemNavigator.pop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _loadData() async {
|
||||
@@ -106,6 +116,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
);
|
||||
},
|
||||
),
|
||||
bottomNavigationBar: SafeArea(
|
||||
child: MyBannerAd(isEnabled: settingsController.adsEnabled),
|
||||
),
|
||||
backgroundColor: theme.surface,
|
||||
);
|
||||
}
|
||||
@@ -151,7 +164,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
_openSettings() {
|
||||
Navigator.push(
|
||||
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:shared_preferences/shared_preferences.dart';
|
||||
import 'package:local_auth/local_auth.dart';
|
||||
|
||||
class SettingsController extends ChangeNotifier {
|
||||
bool _vibrationEnabled = true;
|
||||
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() {
|
||||
_loadSettings();
|
||||
initializationFuture = _loadSettings();
|
||||
}
|
||||
|
||||
Future<void> _loadSettings() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_vibrationEnabled = prefs.getBool('vibration_enabled') ?? true;
|
||||
_biometricEnabled = prefs.getBool('biometric_enabled') ?? false;
|
||||
_adsEnabled = prefs.getBool('ads_enabled') ?? true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> toggleVibration(bool value) async {
|
||||
print("Toggling vibration to: $value");
|
||||
_vibrationEnabled = value;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool('vibration_enabled', value);
|
||||
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!),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user