Added about page
Some checks failed
/ mirror (push) Successful in 8s
/ build (push) Has been cancelled
/ build-stealth (push) Has been cancelled

This commit is contained in:
AlexisDanlos 2025-03-22 23:10:48 +01:00
parent fb5f155430
commit 0023f1a7c5
3 changed files with 343 additions and 0 deletions

View File

@ -0,0 +1,331 @@
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart';
class AboutPage extends StatefulWidget {
const AboutPage({Key? key}) : super(key: key);
@override
_AboutPageState createState() => _AboutPageState();
}
class _AboutPageState extends State<AboutPage> {
String _version = '';
String _buildNumber = '';
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadPackageInfo();
}
Future<void> _loadPackageInfo() async {
final packageInfo = await PackageInfo.fromPlatform();
setState(() {
_version = packageInfo.version;
_buildNumber = packageInfo.buildNumber;
_isLoading = false;
});
}
Future<void> _launchURL(String url) async {
final uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} else {
throw 'Could not launch $url';
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: const Text('About'),
backgroundColor: Colors.black,
elevation: 0,
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// App Logo and Name
Center(
child: Column(
children: [
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(20),
),
child: const Icon(
Icons.phone,
size: 60,
color: Colors.white,
),
),
const SizedBox(height: 16),
const Text(
'Icing Dialer',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
Text(
'Version $_version (Build $_buildNumber)',
style: TextStyle(
color: Colors.grey[400],
fontSize: 14,
),
),
],
),
),
const SizedBox(height: 32),
// App Description
const _SectionHeader(title: 'About This App'),
const _ContentCard(
child: Text(
'Icing Dialer is a secure and privacy-focused phone dialer application '
'designed to provide a modern, user-friendly interface for making calls, '
'managing contacts, and accessing your call history. With features like '
'contact obfuscation and encryption protocols, your communication remains '
'private and secure.',
style: TextStyle(color: Colors.white, height: 1.5),
),
),
const SizedBox(height: 24),
// Features
const _SectionHeader(title: 'Key Features'),
const _ContentCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_FeatureItem(
icon: Icons.phone,
title: 'Intuitive Calling Interface',
description: 'Easy-to-use dialer with quick access to frequent contacts.',
),
SizedBox(height: 16),
_FeatureItem(
icon: Icons.lock,
title: 'Secure Communications',
description: 'End-to-end encrypted calls with the Icing protocol.',
),
SizedBox(height: 16),
_FeatureItem(
icon: Icons.history,
title: 'Comprehensive Call History',
description: 'View, filter, and manage your recent calls.',
),
SizedBox(height: 16),
_FeatureItem(
icon: Icons.contacts,
title: 'Advanced Contact Management',
description: 'Organize, share, and secure your contacts.',
),
],
),
),
const SizedBox(height: 24),
// Support & Privacy
const _SectionHeader(title: 'Support & Privacy'),
_ContentCard(
child: Column(
children: [
_LinkButton(
icon: Icons.help_outline,
text: 'Help & Support',
onTap: () => _launchURL('https://icing.org/support'),
),
const SizedBox(height: 12),
_LinkButton(
icon: Icons.privacy_tip_outlined,
text: 'Privacy Policy',
onTap: () => _launchURL('https://icing.org/privacy'),
),
const SizedBox(height: 12),
_LinkButton(
icon: Icons.description_outlined,
text: 'Terms of Service',
onTap: () => _launchURL('https://icing.org/terms'),
),
],
),
),
const SizedBox(height: 24),
// Credits
const _SectionHeader(title: 'Credits'),
const _ContentCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Developed by Icing Team',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
'This application utilizes open-source libraries and follows best '
'practices for secure software development.',
style: TextStyle(color: Colors.white70, height: 1.5),
),
SizedBox(height: 12),
Text(
'© 2023 Icing Organization. All Rights Reserved.',
style: TextStyle(color: Colors.grey, fontSize: 12),
),
],
),
),
const SizedBox(height: 40),
],
),
),
);
}
}
class _SectionHeader extends StatelessWidget {
final String title;
const _SectionHeader({Key? key, required this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
title,
style: const TextStyle(
color: Colors.blue,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
}
class _ContentCard extends StatelessWidget {
final Widget child;
const _ContentCard({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[900],
borderRadius: BorderRadius.circular(12),
),
child: child,
);
}
}
class _FeatureItem extends StatelessWidget {
final IconData icon;
final String title;
final String description;
const _FeatureItem({
Key? key,
required this.icon,
required this.title,
required this.description,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(icon, color: Colors.blue, size: 20),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
description,
style: const TextStyle(color: Colors.white70),
),
],
),
),
],
);
}
}
class _LinkButton extends StatelessWidget {
final IconData icon;
final String text;
final VoidCallback onTap;
const _LinkButton({
Key? key,
required this.icon,
required this.text,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(8),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
Icon(icon, color: Colors.blue),
const SizedBox(width: 16),
Text(
text,
style: const TextStyle(color: Colors.white),
),
const Spacer(),
const Icon(
Icons.arrow_forward_ios,
color: Colors.white70,
size: 16,
),
],
),
),
);
}
}

View File

@ -9,6 +9,7 @@ import 'package:dialer/features/settings/settings.dart';
import '../../services/contact_service.dart';
import 'package:dialer/features/voicemail/voicemail_page.dart';
import '../contacts/widgets/contact_modal.dart';
import 'package:dialer/features/about/about.dart'; // Add this import
class _MyHomePageState extends State<MyHomePage>
@ -233,6 +234,10 @@ class _MyHomePageState extends State<MyHomePage>
value: 'settings',
child: Text('Settings'),
),
const PopupMenuItem<String>( // Add About menu item
value: 'about',
child: Text('About'),
),
],
onSelected: (String value) {
if (value == 'settings') {
@ -241,6 +246,12 @@ class _MyHomePageState extends State<MyHomePage>
MaterialPageRoute(
builder: (context) => const SettingsPage()),
);
} else if (value == 'about') { // Handle About selection
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AboutPage()),
);
}
},
),

View File

@ -55,6 +55,7 @@ dependencies:
encrypt: ^5.0.3
uuid: ^4.5.1
provider: ^6.1.2
package_info_plus: ^8.3.0
intl: any