From 976bd00740ad1688e295d82d9252436279d8bbb4 Mon Sep 17 00:00:00 2001 From: Amoghhosamane Date: Fri, 20 Feb 2026 00:15:31 +0530 Subject: [PATCH] feat: replace home screen with a simple example to save and read to POD #23 Reworked the home page to include NAME and COMMENT fields that can be saved to and restored from the Solid Pod. The overview information is still included below the data entry fields. Closes #23 --- example/lib/home.dart | 241 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 210 insertions(+), 31 deletions(-) diff --git a/example/lib/home.dart b/example/lib/home.dart index c073c18..a130507 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -28,7 +28,10 @@ library; +import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:solidpod/solidpod.dart'; +import 'package:solidui/solidui.dart'; class Home extends StatefulWidget { const Home({super.key, required this.title}); @@ -40,44 +43,220 @@ class Home extends StatefulWidget { } class _HomeState extends State { + final TextEditingController _nameController = TextEditingController(); + final TextEditingController _commentController = TextEditingController(); + bool _isLoading = false; + + @override + void initState() { + super.initState(); + _loadData(); + } + + @override + void dispose() { + _nameController.dispose(); + _commentController.dispose(); + super.dispose(); + } + + Future _loadData() async { + if (!mounted) return; + setState(() => _isLoading = true); + + try { + final appDataPath = await getDataDirPath(); + final filePath = PathUtils.combine(appDataPath, 'user_info.enc.ttl'); + + final content = await readPod(filePath, pathType: PathType.relativeToPod); + + if (content != SolidFunctionCallStatus.fail.toString() && + content != SolidFunctionCallStatus.notLoggedIn.toString() && + content.isNotEmpty) { + final data = jsonDecode(content); + _nameController.text = data['name'] ?? ''; + _commentController.text = data['comment'] ?? ''; + } + } catch (e) { + debugPrint('Error loading data: $e'); + } finally { + if (mounted) setState(() => _isLoading = false); + } + } + + Future _saveData() async { + if (!mounted) return; + setState(() => _isLoading = true); + + try { + // Ensure the security key is available before writing encrypted data. + await getKeyFromUserIfRequired( + context, + const Text('Please enter your security key to save the data'), + ); + + if (!mounted) return; + + final data = { + 'name': _nameController.text, + 'comment': _commentController.text, + 'lastUpdated': DateTime.now().toIso8601String(), + }; + + final appDataPath = await getDataDirPath(); + final filePath = PathUtils.combine(appDataPath, 'user_info.enc.ttl'); + + await writePod( + filePath, + jsonEncode(data), + encrypted: true, + pathType: PathType.relativeToPod, + ); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Data saved to POD successfully!'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Error saving data: $e'), + backgroundColor: Colors.red, + ), + ); + } + } finally { + if (mounted) setState(() => _isLoading = false); + } + } + @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(24.0), child: Center( - child: Card( - child: Padding( - padding: const EdgeInsets.all(32.0), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Icon( - Icons.home, - size: 64, - color: Theme.of(context).primaryColor, - ), - const SizedBox(height: 16), - Text( - widget.title, - style: Theme.of(context).textTheme.headlineMedium, + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 800), + child: Column( + children: [ + Card( + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.home, + size: 48, + color: Theme.of(context).primaryColor, + ), + const SizedBox(width: 16), + Expanded( + child: Text( + widget.title, + style: Theme.of(context).textTheme.headlineSmall, + ), + ), + ], + ), + const SizedBox(height: 24), + const Text( + 'POD Data Storage Example', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + const SizedBox(height: 8), + const Text( + 'This data is stored securely and encrypted on your POD.', + style: TextStyle(color: Colors.grey), + ), + const SizedBox(height: 24), + TextFormField( + controller: _nameController, + decoration: const InputDecoration( + labelText: 'NAME', + hintText: 'Enter your name', + border: OutlineInputBorder(), + prefixIcon: Icon(Icons.person), + ), + enabled: !_isLoading, + ), + const SizedBox(height: 16), + TextFormField( + controller: _commentController, + decoration: const InputDecoration( + labelText: 'COMMENT', + hintText: 'Enter a comment', + border: OutlineInputBorder(), + prefixIcon: Icon(Icons.comment), + ), + maxLines: 3, + enabled: !_isLoading, + ), + const SizedBox(height: 24), + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _isLoading ? null : _saveData, + icon: _isLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + ), + ) + : const Icon(Icons.save), + label: const Text('Save to POD'), + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + ), + ), + ), + ], + ), ), - const SizedBox(height: 24), - Text( - 'Welcome to the SolidUI Template App!\n\n' - 'This template demonstrates the key features of SolidUI:\n\n' - '• Responsive navigation (rail ↔ drawer)\n' - '• Theme switching (light/dark/system)\n' - '• Customisable About dialogues\n' - '• Version information display\n' - '• Security key management\n' - '• Status bar integration\n' - '• User information display\n\n' - 'Explore the different tabs to see these features in action!', - style: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox(height: 24), + Card( + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'About SolidUI', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 16), + Text( + 'Welcome to the SolidUI Template App!\n\n' + 'This template demonstrates the key features of SolidUI:\n\n' + '• Responsive navigation (rail ↔ drawer)\n' + '• Theme switching (light/dark/system)\n' + '• Customisable About dialogues\n' + '• Version information display\n' + '• Security key management\n' + '• Status bar integration\n' + '• User information display\n\n' + 'Explore the different tabs to see these features in action!', + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), ), - ], - ), + ), + ], ), ), ),