2828
2929library ;
3030
31+ import 'dart:convert' ;
3132import 'package:flutter/material.dart' ;
33+ import 'package:solidpod/solidpod.dart' ;
34+ import 'package:solidui/solidui.dart' ;
3235
3336class Home extends StatefulWidget {
3437 const Home ({super .key, required this .title});
@@ -40,44 +43,220 @@ class Home extends StatefulWidget {
4043}
4144
4245class _HomeState extends State <Home > {
46+ final TextEditingController _nameController = TextEditingController ();
47+ final TextEditingController _commentController = TextEditingController ();
48+ bool _isLoading = false ;
49+
50+ @override
51+ void initState () {
52+ super .initState ();
53+ _loadData ();
54+ }
55+
56+ @override
57+ void dispose () {
58+ _nameController.dispose ();
59+ _commentController.dispose ();
60+ super .dispose ();
61+ }
62+
63+ Future <void > _loadData () async {
64+ if (! mounted) return ;
65+ setState (() => _isLoading = true );
66+
67+ try {
68+ final appDataPath = await getDataDirPath ();
69+ final filePath = PathUtils .combine (appDataPath, 'user_info.enc.ttl' );
70+
71+ final content = await readPod (filePath, pathType: PathType .relativeToPod);
72+
73+ if (content != SolidFunctionCallStatus .fail.toString () &&
74+ content != SolidFunctionCallStatus .notLoggedIn.toString () &&
75+ content.isNotEmpty) {
76+ final data = jsonDecode (content);
77+ _nameController.text = data['name' ] ?? '' ;
78+ _commentController.text = data['comment' ] ?? '' ;
79+ }
80+ } catch (e) {
81+ debugPrint ('Error loading data: $e ' );
82+ } finally {
83+ if (mounted) setState (() => _isLoading = false );
84+ }
85+ }
86+
87+ Future <void > _saveData () async {
88+ if (! mounted) return ;
89+ setState (() => _isLoading = true );
90+
91+ try {
92+ // Ensure the security key is available before writing encrypted data.
93+ await getKeyFromUserIfRequired (
94+ context,
95+ const Text ('Please enter your security key to save the data' ),
96+ );
97+
98+ if (! mounted) return ;
99+
100+ final data = {
101+ 'name' : _nameController.text,
102+ 'comment' : _commentController.text,
103+ 'lastUpdated' : DateTime .now ().toIso8601String (),
104+ };
105+
106+ final appDataPath = await getDataDirPath ();
107+ final filePath = PathUtils .combine (appDataPath, 'user_info.enc.ttl' );
108+
109+ await writePod (
110+ filePath,
111+ jsonEncode (data),
112+ encrypted: true ,
113+ pathType: PathType .relativeToPod,
114+ );
115+
116+ if (mounted) {
117+ ScaffoldMessenger .of (context).showSnackBar (
118+ const SnackBar (
119+ content: Text ('Data saved to POD successfully!' ),
120+ backgroundColor: Colors .green,
121+ ),
122+ );
123+ }
124+ } catch (e) {
125+ if (mounted) {
126+ ScaffoldMessenger .of (context).showSnackBar (
127+ SnackBar (
128+ content: Text ('Error saving data: $e ' ),
129+ backgroundColor: Colors .red,
130+ ),
131+ );
132+ }
133+ } finally {
134+ if (mounted) setState (() => _isLoading = false );
135+ }
136+ }
137+
43138 @override
44139 Widget build (BuildContext context) {
45140 return SingleChildScrollView (
46141 padding: const EdgeInsets .all (24.0 ),
47142 child: Center (
48- child: Card (
49- child: Padding (
50- padding: const EdgeInsets .all (32.0 ),
51- child: Column (
52- mainAxisSize: MainAxisSize .min,
53- crossAxisAlignment: CrossAxisAlignment .start,
54- children: [
55- Icon (
56- Icons .home,
57- size: 64 ,
58- color: Theme .of (context).primaryColor,
59- ),
60- const SizedBox (height: 16 ),
61- Text (
62- widget.title,
63- style: Theme .of (context).textTheme.headlineMedium,
143+ child: ConstrainedBox (
144+ constraints: const BoxConstraints (maxWidth: 800 ),
145+ child: Column (
146+ children: [
147+ Card (
148+ child: Padding (
149+ padding: const EdgeInsets .all (32.0 ),
150+ child: Column (
151+ mainAxisSize: MainAxisSize .min,
152+ crossAxisAlignment: CrossAxisAlignment .start,
153+ children: [
154+ Row (
155+ children: [
156+ Icon (
157+ Icons .home,
158+ size: 48 ,
159+ color: Theme .of (context).primaryColor,
160+ ),
161+ const SizedBox (width: 16 ),
162+ Expanded (
163+ child: Text (
164+ widget.title,
165+ style: Theme .of (context).textTheme.headlineSmall,
166+ ),
167+ ),
168+ ],
169+ ),
170+ const SizedBox (height: 24 ),
171+ const Text (
172+ 'POD Data Storage Example' ,
173+ style: TextStyle (
174+ fontWeight: FontWeight .bold,
175+ fontSize: 18 ,
176+ ),
177+ ),
178+ const SizedBox (height: 8 ),
179+ const Text (
180+ 'This data is stored securely and encrypted on your POD.' ,
181+ style: TextStyle (color: Colors .grey),
182+ ),
183+ const SizedBox (height: 24 ),
184+ TextFormField (
185+ controller: _nameController,
186+ decoration: const InputDecoration (
187+ labelText: 'NAME' ,
188+ hintText: 'Enter your name' ,
189+ border: OutlineInputBorder (),
190+ prefixIcon: Icon (Icons .person),
191+ ),
192+ enabled: ! _isLoading,
193+ ),
194+ const SizedBox (height: 16 ),
195+ TextFormField (
196+ controller: _commentController,
197+ decoration: const InputDecoration (
198+ labelText: 'COMMENT' ,
199+ hintText: 'Enter a comment' ,
200+ border: OutlineInputBorder (),
201+ prefixIcon: Icon (Icons .comment),
202+ ),
203+ maxLines: 3 ,
204+ enabled: ! _isLoading,
205+ ),
206+ const SizedBox (height: 24 ),
207+ SizedBox (
208+ width: double .infinity,
209+ child: ElevatedButton .icon (
210+ onPressed: _isLoading ? null : _saveData,
211+ icon: _isLoading
212+ ? const SizedBox (
213+ width: 20 ,
214+ height: 20 ,
215+ child: CircularProgressIndicator (
216+ strokeWidth: 2 ,
217+ ),
218+ )
219+ : const Icon (Icons .save),
220+ label: const Text ('Save to POD' ),
221+ style: ElevatedButton .styleFrom (
222+ padding: const EdgeInsets .symmetric (vertical: 16 ),
223+ ),
224+ ),
225+ ),
226+ ],
227+ ),
64228 ),
65- const SizedBox (height: 24 ),
66- Text (
67- 'Welcome to the SolidUI Template App!\n\n '
68- 'This template demonstrates the key features of SolidUI:\n\n '
69- '• Responsive navigation (rail ↔ drawer)\n '
70- '• Theme switching (light/dark/system)\n '
71- '• Customisable About dialogues\n '
72- '• Version information display\n '
73- '• Security key management\n '
74- '• Status bar integration\n '
75- '• User information display\n\n '
76- 'Explore the different tabs to see these features in action!' ,
77- style: Theme .of (context).textTheme.bodyLarge,
229+ ),
230+ const SizedBox (height: 24 ),
231+ Card (
232+ child: Padding (
233+ padding: const EdgeInsets .all (32.0 ),
234+ child: Column (
235+ crossAxisAlignment: CrossAxisAlignment .start,
236+ children: [
237+ Text (
238+ 'About SolidUI' ,
239+ style: Theme .of (context).textTheme.titleLarge,
240+ ),
241+ const SizedBox (height: 16 ),
242+ Text (
243+ 'Welcome to the SolidUI Template App!\n\n '
244+ 'This template demonstrates the key features of SolidUI:\n\n '
245+ '• Responsive navigation (rail ↔ drawer)\n '
246+ '• Theme switching (light/dark/system)\n '
247+ '• Customisable About dialogues\n '
248+ '• Version information display\n '
249+ '• Security key management\n '
250+ '• Status bar integration\n '
251+ '• User information display\n\n '
252+ 'Explore the different tabs to see these features in action!' ,
253+ style: Theme .of (context).textTheme.bodyLarge,
254+ ),
255+ ],
256+ ),
78257 ),
79- ] ,
80- ) ,
258+ ) ,
259+ ] ,
81260 ),
82261 ),
83262 ),
0 commit comments