import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:mobdr/config/constant.dart'; import 'package:mobdr/service/shared_prefs.dart'; import 'package:mobdr/config/global_style.dart'; import 'package:mobdr/main.dart'; import 'package:mobdr/ui/general/chat_us.dart'; import 'package:mobdr/ui/home/visit_photo_tag.dart'; import 'package:mobdr/db/box_photo.dart'; import 'package:mobdr/db/box_photo_typology.dart'; //TODO : faire concurrents === class VisitPhotoTypologyDetailPage extends StatefulWidget { // variables corresponding to the data parameters final int pp_id; final int pp_id_distrib; final String pp_langage; final String pp_image; final int pp_id_typologie; // Requiring data parameters VisitPhotoTypologyDetailPage({ Key? key, required this.pp_id, required this.pp_id_distrib, required this.pp_langage, required this.pp_image, required this.pp_id_typologie, }) : super(key: key); @override _VisitPhotoTypologyDetailPageState createState() => _VisitPhotoTypologyDetailPageState(); } class _VisitPhotoTypologyDetailPageState extends State { bool _isLoading = true; String _errorMessage = ''; // Typology list late List _typologyList = []; int _typologyIndex = 0; List _visibilities = []; late List tagList = []; late Photo _photo; @override void initState() { super.initState(); loadData(widget.pp_id).then((_) { setState(() { _isLoading = false; }); }); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { if (_isLoading) { return Center(child: CircularProgressIndicator()); } else if (_errorMessage.isNotEmpty) { return Center( child: AlertDialog( title: Text("Erreur"), content: Text("La photo est introuvable"), actions: [ TextButton( child: Text("OK"), onPressed: () { Navigator.of(context).pop(); }, ), ], ), ); } return Scaffold( appBar: AppBar( iconTheme: IconThemeData( color: GlobalStyle.appBarIconThemeColor, ), elevation: GlobalStyle.appBarElevation, title: Text( 'Photo', style: GlobalStyle.appBarTitle, ), backgroundColor: GlobalStyle.appBarBackgroundColor, systemOverlayStyle: GlobalStyle.appBarSystemOverlayStyle), body: WillPopScope( onWillPop: () { // fred Map result = { 'change_typologie': _typologyIndex != _typologyList.indexWhere((typology) => typology.id_photo_typologie == widget.pp_id_typologie), 'tags': tagList.join(","), 'photo_principale': _visibilities.contains('principal') ? 1 : 0, 'photo_privee': _visibilities.contains('private') ? 1 : 0, }; // return to the parent page fred Navigator.pop(context, result); return Future.value(true); }, child: Column( children: [ Flexible( child: ListView( children: [ Image.file(File(widget.pp_image), fit: BoxFit.cover), _buildPhotoTypology(), _buildPhotoVisibility(), _buildPhotoTag(context), SizedBox(height: 16) ], ), ), Container( padding: EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.grey, offset: Offset(0.0, 1.0), //(x,y) blurRadius: 2.0, ), ], ), child: Row( children: [ Container( child: GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => ChatUsPage())); }, child: ClipOval( child: Container( color: SOFT_BLUE, padding: EdgeInsets.all(9), child: Icon(Icons.chat, color: Colors.white, size: 16)), ), ), ), SizedBox( width: 10, ), Expanded( child: GestureDetector( onTap: () { setState(() { //_shoppingCartCount++; }); Fluttertoast.showToast( msg: 'Item has been added to Shopping Cart', toastLength: Toast.LENGTH_LONG); }, child: Container( alignment: Alignment.center, padding: EdgeInsets.fromLTRB(12, 8, 12, 8), margin: EdgeInsets.only(right: 8), decoration: BoxDecoration( color: Colors.white, border: Border.all(width: 1, color: SOFT_BLUE), borderRadius: BorderRadius.all(Radius.circular( 10) // <--- border radius here )), child: Text('Copier dans galerie', style: TextStyle( color: SOFT_BLUE, fontWeight: FontWeight.bold)), ), ), ), ], ), ) ], ), )); } Widget _buildPhotoTypology() { return Container( margin: EdgeInsets.only(top: 12), padding: EdgeInsets.all(16), color: Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Typologie', style: GlobalStyle.sectionTitle), SizedBox( height: 16, ), Wrap( children: List.generate(_typologyList.length, (index) { return radioSize(_typologyList[index].libelle, index); }), ), ], )); } Widget radioSize(String txt, int index) { return GestureDetector( onTap: () async { // save photo typology in the database objectbox.putPhotoTypologie( widget.pp_id, _typologyList[index].id_photo_typologie); setState(() { _typologyIndex = index; }); }, child: Container( padding: EdgeInsets.fromLTRB(12, 8, 12, 8), margin: EdgeInsets.only(right: 8, top: 8), decoration: BoxDecoration( color: _typologyIndex == index ? SOFT_BLUE : Colors.white, border: Border.all( width: 1, color: _typologyIndex == index ? SOFT_BLUE : Colors.grey[300]!), borderRadius: BorderRadius.all( Radius.circular(10) // <--- border radius here )), child: Text(txt, style: TextStyle( color: _typologyIndex == index ? Colors.white : CHARCOAL)), ), ); } Widget _checkboxVisibility({value, primaryText}) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { if (_visibilities.contains(value)) { _visibilities.remove(value); } else { _visibilities.add(value); } }); // save photo visibilities in the database objectbox.putPhotoVisibilities(widget.pp_id, _visibilities); }, child: Row( children: [ Container( decoration: BoxDecoration( border: Border.all( width: 1, color: (_visibilities.contains(value)) ? PRIMARY_COLOR : BLACK77), borderRadius: BorderRadius.all(Radius.circular(4.0)), ), child: Padding( padding: const EdgeInsets.all(2), child: (_visibilities.contains(value)) ? Icon( Icons.check, size: 12.0, color: PRIMARY_COLOR, ) : Icon( Icons.check_box_outline_blank, size: 12.0, color: Colors.white, ), ), ), SizedBox(width: 16), Text(primaryText, style: TextStyle( fontSize: 13, color: BLACK77, fontWeight: (_visibilities.contains(value)) ? FontWeight.bold : FontWeight.normal)), ], ), ); } Widget _buildPhotoVisibility() { return Container( margin: EdgeInsets.only(top: 12), padding: EdgeInsets.all(16), color: Colors.white, child: Column( children: [ Row( children: [ Text('Visibility', style: GlobalStyle.sectionTitle), ], ), SizedBox(height: 16), _checkboxVisibility(value: 'private', primaryText: 'Privée'), Divider( height: 32, color: Colors.grey[400], ), _checkboxVisibility(value: 'principal', primaryText: 'Principale') ], ), ); } Widget _buildPhotoTag(BuildContext context) { return GestureDetector( onTap: () async { // Navigation to the PhotoTagPage final newTags = await Navigator.push>( context, MaterialPageRoute( builder: (context) => PhotoTagPage( pp_langage: widget.pp_langage, pp_id_distrib: widget.pp_id_distrib, pp_photoId: this._photo.id, pp_currentTags: tagList), ), ); // Checking changes made to tags if (newTags != null && !listEquals(tagList, newTags)) { setState(() { tagList = newTags; }); } }, child: Container( margin: EdgeInsets.only(top: 12), padding: EdgeInsets.all(16), color: Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text('Tags', style: GlobalStyle.sectionTitle), ], ), Wrap( spacing: 8.0, runSpacing: 8.0, alignment: WrapAlignment.start, children: tagList.map((tag) { return Chip( label: Text(tag), backgroundColor: Colors.grey[300], ); }).toList(), ), ], ), ), ); } /// Initializes data when the page loads. Future loadData(int photoId) async { String tags = ""; try { // photo typologies initialization _typologyList = objectbox.getPhotoTypologiesList(); _typologyIndex = _typologyList.indexWhere( (typology) => typology.id_photo_typologie == widget.pp_id_typologie); // get photo object _photo = objectbox.getPhotoById(photoId)!; // visibilities initialization if (_photo.photo_privee == 1) _visibilities.add('private'); if (_photo.photo_principale == 1) _visibilities.add('principal'); // photo tag initialization tags = _photo.tags; tagList = tags.isEmpty ? [] : _photo.tags.split(","); } catch (e) { // set errorMessage for debug _errorMessage = 'Error loading photo: $e'; } } }