litecloud/lightcloud_app/lib/sharedialog.dart
Mercurio a95d455b2e feat: implement file sharing and management functionality
- Add config.dart for API configuration
- Implement sidebar navigation with logout functionality
- Add file sharing dialog with public/private options
- Create shares page to view and manage shared files
- Implement file upload/download/delete operations
- Add authentication persistence using shared preferences
- Configure CORS for API to enable cross-origin requests
2025-06-02 15:37:06 +02:00

179 lines
5.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/services.dart';
import 'config.dart';
class ShareDialog extends StatefulWidget {
final int fileId;
final String fileName;
const ShareDialog({
required this.fileId,
required this.fileName,
super.key,
});
@override
State<ShareDialog> createState() => _ShareDialogState();
}
class _ShareDialogState extends State<ShareDialog> {
bool _isPublicShare = true;
int _expirationDays = 7;
bool _isLoading = false;
String? shareLink;
String? _error;
Future<void> _createShare() async {
setState(() {
_isLoading = true;
_error = null;
});
try {
final prefs = await SharedPreferences.getInstance();
final jwt = prefs.getString('jwt');
if (jwt == null) {
setState(() {
_error = 'Sessione scaduta, effettua di nuovo il login.';
_isLoading = false;
});
return;
}
final uri = Uri.parse('${Config.apiUrl}/share');
final response = await http.post(
uri,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $jwt',
},
body: jsonEncode({
'file_id': widget.fileId,
'expires_in_days': _isPublicShare ? _expirationDays : null,
}),
);
if (response.statusCode == 200) {
final shareId = jsonDecode(response.body);
setState(() {
shareLink = '${Config.apiUrl}/shared/$shareId';
_isLoading = false;
});
} else {
setState(() {
_error = 'Errore durante la creazione del link di condivisione.';
_isLoading = false;
});
}
} catch (e) {
setState(() {
_error = 'Errore di rete: ${e.toString()}';
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Condividi "${widget.fileName}"'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SwitchListTile(
title: const Text('Link pubblico'),
subtitle: const Text('Chiunque con il link può accedere al file'),
value: _isPublicShare,
onChanged: (value) {
setState(() {
_isPublicShare = value;
});
},
),
if (_isPublicShare) ...[
const SizedBox(height: 16),
const Text('Scadenza del link:'),
Slider(
value: _expirationDays.toDouble(),
min: 1,
max: 30,
divisions: 29,
label: _expirationDays.toString(),
onChanged: (value) {
setState(() {
_expirationDays = value.round();
});
},
),
Text('Il link scadrà dopo $_expirationDays giorni'),
],
if (shareLink != null) ...[
const SizedBox(height: 16),
const Text('Link di condivisione:'),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
Expanded(
child: Text(
shareLink!,
style: const TextStyle(fontFamily: 'monospace'),
),
),
IconButton(
icon: const Icon(Icons.copy),
tooltip: 'Copia link',
onPressed: () {
Clipboard.setData(ClipboardData(text: shareLink ?? ''));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Link copiato negli appunti')),
);
},
),
],
),
),
],
if (_error != null) ...[
const SizedBox(height: 16),
Text(
_error!,
style: TextStyle(color: Theme.of(context).colorScheme.error),
),
],
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Chiudi'),
),
if (shareLink == null)
ElevatedButton(
onPressed: _isLoading ? null : _createShare,
child: _isLoading
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('Crea link'),
),
],
);
}
}