11import 'package:flutter/material.dart' ;
22import 'package:peerchat_secure/src/utils/google_fonts.dart' ;
3+ import 'package:url_launcher/url_launcher.dart' ;
34import '../../theme.dart' ;
45
56class AboutScreen extends StatelessWidget {
67 const AboutScreen ({super .key});
78
89 static const String _appVersion = '1.0.0' ;
10+ static const String _baseUrl = 'https://peerchat.mathi.live' ;
11+ static const String _changelogUrl = '$_baseUrl /changelog' ;
12+ static const String _tosUrl = '$_baseUrl /tos' ;
13+ static const String _policiesUrl = '$_baseUrl /policies' ;
14+ static const String _githubUrl = 'https://github.com/Mathi4Raja/P2P-app' ;
15+
16+ Future <void > _launch (BuildContext context, String url) async {
17+ final uri = Uri .parse (url);
18+ if (await canLaunchUrl (uri)) {
19+ await launchUrl (uri, mode: LaunchMode .externalApplication);
20+ } else if (context.mounted) {
21+ ScaffoldMessenger .of (context).showSnackBar (
22+ const SnackBar (content: Text ('Could not open link' )),
23+ );
24+ }
25+ }
926
1027 @override
1128 Widget build (BuildContext context) {
1229 return Scaffold (
1330 appBar: AppBar (
14- title: Text (
15- 'About' ,
16- style: GoogleFonts .inter (fontWeight: FontWeight .w700),
17- ),
31+ title: Text ('About' , style: GoogleFonts .inter (fontWeight: FontWeight .w700)),
1832 ),
1933 body: ListView (
20- padding: const EdgeInsets .all (14 ),
34+ padding: const EdgeInsets .fromLTRB (14 , 14 , 14 , 24 ),
2135 children: [
2236 Container (
23- padding: const EdgeInsets .all (14 ),
37+ padding: const EdgeInsets .all (16 ),
2438 decoration: BoxDecoration (
2539 color: AppTheme .bgSurface,
2640 borderRadius: BorderRadius .circular (12 ),
2741 border: Border .all (color: Colors .white.withValues (alpha: 0.06 )),
2842 ),
29- child: Column (
30- crossAxisAlignment: CrossAxisAlignment .start,
43+ child: Row (
3144 children: [
32- Row (
33- children: [
34- ClipRRect (
35- borderRadius: BorderRadius .circular (12 ),
36- child: Image .asset (
37- 'assets/image.png' ,
38- height: 48 ,
39- width: 48 ,
40- fit: BoxFit .contain,
41- errorBuilder: (context, error, stackTrace) => Container (
42- width: 48 ,
43- height: 48 ,
44- decoration: BoxDecoration (
45- gradient: AppTheme .primaryGradient,
46- borderRadius: BorderRadius .circular (10 ),
47- ),
48- child: const Icon (Icons .shield, size: 24 , color: AppTheme .bgDeep),
49- ),
50- ),
51- ),
52- const SizedBox (width: 16 ),
53- Expanded (
54- child: Column (
55- crossAxisAlignment: CrossAxisAlignment .start,
56- children: [
57- Text (
58- 'PeerChat' ,
59- style: GoogleFonts .inter (
60- fontSize: 18 ,
61- fontWeight: FontWeight .w800,
62- color: AppTheme .textPrimary,
63- ),
64- ),
65- const SizedBox (height: 6 ),
66- Text (
67- 'App version: $_appVersion ' ,
68- style: GoogleFonts .inter (
69- fontSize: 13 ,
70- color: AppTheme .textSecondary,
71- ),
72- ),
73- ],
74- ),
75- ),
76- ],
45+ Container (
46+ width: 52 , height: 52 ,
47+ decoration: BoxDecoration (
48+ gradient: AppTheme .primaryGradient,
49+ borderRadius: BorderRadius .circular (12 ),
50+ ),
51+ child: const Icon (Icons .shield, size: 28 , color: AppTheme .bgDeep),
52+ ),
53+ const SizedBox (width: 16 ),
54+ Expanded (
55+ child: Column (
56+ crossAxisAlignment: CrossAxisAlignment .start,
57+ children: [
58+ Text ('PeerChat' , style: GoogleFonts .inter (fontSize: 20 , fontWeight: FontWeight .w800, color: AppTheme .textPrimary)),
59+ const SizedBox (height: 4 ),
60+ Text ('Version $_appVersion — Secure Mesh' , style: GoogleFonts .inter (fontSize: 12 , color: AppTheme .textSecondary)),
61+ const SizedBox (height: 2 ),
62+ Text ('Serverless · E2E Encrypted · Open Source' , style: GoogleFonts .inter (fontSize: 11 , color: AppTheme .accent.withValues (alpha: 0.8 ), fontWeight: FontWeight .w500)),
63+ ],
64+ ),
7765 ),
7866 ],
7967 ),
8068 ),
81- const SizedBox (height: 10 ),
82- _LinkCard (
83- title: 'Changelog' ,
84- subtitle: 'See what is new in recent versions' ,
85- onTap: () => _showPlaceholder (context, 'Changelog link' ),
86- ),
87- _LinkCard (
88- title: 'Terms of Service' ,
89- subtitle: 'Read usage terms and conditions' ,
90- onTap: () => _showPlaceholder (context, 'Terms of Service link' ),
91- ),
92- _LinkCard (
93- title: 'Policies' ,
94- subtitle: 'Privacy and security policy details' ,
95- onTap: () => _showPlaceholder (context, 'Policies link' ),
96- ),
69+ const SizedBox (height: 12 ),
70+ _LinkCard (icon: Icons .history_rounded, iconColor: AppTheme .primary, title: 'Changelog' , subtitle: "What's new in recent versions" , onTap: () => _launch (context, _changelogUrl)),
71+ _LinkCard (icon: Icons .article_outlined, iconColor: AppTheme .accent, title: 'Terms of Service' , subtitle: 'Usage terms and conditions' , onTap: () => _launch (context, _tosUrl)),
72+ _LinkCard (icon: Icons .shield_outlined, iconColor: AppTheme .accentPurple, title: 'Privacy Policy' , subtitle: 'How we handle your data' , onTap: () => _launch (context, _policiesUrl)),
73+ _LinkCard (icon: Icons .code_rounded, iconColor: AppTheme .textSecondary, title: 'Source Code' , subtitle: 'Audit the protocol on GitHub' , onTap: () => _launch (context, _githubUrl)),
9774 ],
9875 ),
9976 );
10077 }
101-
102- void _showPlaceholder (BuildContext context, String label) {
103- ScaffoldMessenger .of (context).showSnackBar (
104- SnackBar (content: Text ('$label (UI only for now)' )),
105- );
106- }
10778}
10879
10980class _LinkCard extends StatelessWidget {
81+ final IconData icon;
82+ final Color iconColor;
11083 final String title;
11184 final String subtitle;
11285 final VoidCallback onTap;
11386
114- const _LinkCard ({
115- required this .title,
116- required this .subtitle,
117- required this .onTap,
118- });
87+ const _LinkCard ({required this .icon, required this .iconColor, required this .title, required this .subtitle, required this .onTap});
11988
12089 @override
12190 Widget build (BuildContext context) {
@@ -127,43 +96,27 @@ class _LinkCard extends StatelessWidget {
12796 onTap: onTap,
12897 borderRadius: BorderRadius .circular (12 ),
12998 child: Container (
130- padding: const EdgeInsets .all ( 12 ),
99+ padding: const EdgeInsets .symmetric (horizontal : 14 , vertical : 14 ),
131100 decoration: BoxDecoration (
132101 color: AppTheme .bgSurface,
133102 borderRadius: BorderRadius .circular (12 ),
134103 border: Border .all (color: Colors .white.withValues (alpha: 0.06 )),
135104 ),
136105 child: Row (
137106 children: [
107+ Icon (icon, size: 18 , color: iconColor),
108+ const SizedBox (width: 14 ),
138109 Expanded (
139110 child: Column (
140111 crossAxisAlignment: CrossAxisAlignment .start,
141112 children: [
142- Text (
143- title,
144- style: GoogleFonts .inter (
145- fontWeight: FontWeight .w700,
146- color: AppTheme .accent,
147- decoration: TextDecoration .underline,
148- ),
149- ),
150- const SizedBox (height: 4 ),
151- Text (
152- subtitle,
153- style: GoogleFonts .inter (
154- fontSize: 12 ,
155- color: AppTheme .textSecondary,
156- ),
157- ),
113+ Text (title, style: GoogleFonts .inter (fontWeight: FontWeight .w700, color: AppTheme .textPrimary)),
114+ const SizedBox (height: 2 ),
115+ Text (subtitle, style: GoogleFonts .inter (fontSize: 12 , color: AppTheme .textSecondary)),
158116 ],
159117 ),
160118 ),
161- const SizedBox (width: 8 ),
162- Icon (
163- Icons .open_in_new_rounded,
164- color: AppTheme .textSecondary.withValues (alpha: 0.7 ),
165- size: 18 ,
166- ),
119+ Icon (Icons .open_in_new_rounded, color: AppTheme .textSecondary.withValues (alpha: 0.5 ), size: 16 ),
167120 ],
168121 ),
169122 ),
@@ -172,4 +125,3 @@ class _LinkCard extends StatelessWidget {
172125 );
173126 }
174127}
175-
0 commit comments