import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hiddingsel_app/appflow/model/location.dart'; import 'package:hiddingsel_app/appflow/view/widgets/gallery.dart'; import 'package:hiddingsel_app/packages/html_view/html_view.dart'; import 'package:hiddingsel_app/constants/constant.dart'; import '../further_pages/article.dart'; import '../../../services/environment.dart'; import '../home.dart'; import '../../model/articles.dart'; import '../../model/companies.dart'; import '../../model/pois.dart'; import '../../model/represented_organisations.dart'; import '../../../packages/icon_switch/icon_switch.dart'; class ItemCard extends StatelessWidget { final Widget _title; final ImageProvider? _imageProvider; final Widget _child; final Function()? _onShare; final Function(bool favorite) _onFavorite; final Future _initFavorite; final Function(bool notify) _onNotify; final Future _initNotify; final Gradient _gradientColor; final bool _right; ItemCard(this._title, this._imageProvider, this._child, this._onShare, {onFavorite, initFavorite, onNotify, initNotify, gradientColor, right = true}) : _onFavorite = onFavorite, _initFavorite = initFavorite ?? Future.value(false), _onNotify = onNotify, _initNotify = initNotify ?? Future.value(false), _gradientColor = gradientColor ?? LinearGradient( colors: [ UIColors.white, UIColors.white, ], ), _right = right; @override Widget build(BuildContext context) { int space = 20; List buttons = [ IconButton( icon: Icon(Icons.share, color: UIColors.white), tooltip: 'Share', onPressed: _onShare, ), ]; buttons.add(Spacer()); /*buttons.add( IconSwitch( _onFavorite, initFavorite: _initFavorite, gradientColor: _gradientColor, defaultColor: UIColors.white, ), ); buttons.add(Spacer());*/ buttons.add( IconSwitch( _onNotify, initFavorite: _initNotify, gradientColor: _gradientColor, defaultColor: UIColors.white, iconFavorite: Icons.notifications_active, iconDefavorite: Icons.notifications_outlined, ), ); return LayoutBuilder( builder: (context, constraints) { Widget image; if (_imageProvider != null) { image = Image( image: _imageProvider, fit: BoxFit.cover, width: constraints.maxWidth - 48 - space, ); } else { image = Container( width: constraints.maxWidth - 48 - space, child: Center( child: CircularProgressIndicator(), ), ); } RoundedRectangleBorder border; double paddingLeft = 0; double paddingRight = 0; if (_right) { border = UIShapes.leftRoundedRectangleWithBorder; paddingLeft = UIShapes.paddingSimple + space / 2; } else { border = UIShapes.rightRoundedRectangleWithBorder; paddingRight = UIShapes.paddingSimple + space / 2; } return Container( margin: EdgeInsets.symmetric(vertical: UIShapes.paddingSimple), child: Stack( alignment: Alignment.topRight, children: [ Positioned.fill( left: paddingLeft, right: paddingRight, child: Container( decoration: ShapeDecoration(shape: border), width: constraints.maxWidth - UIShapes.paddingDouble, ), ), Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.fromLTRB( _right? UIShapes.paddingMax + UIShapes.paddingDouble : UIShapes.paddingMax, UIShapes.paddingDouble, UIShapes.paddingSimple, UIShapes.paddingSimple), child: _title, ), Container( height: constraints.maxWidth * 0.6, decoration: BoxDecoration( color: UIColors.grey5, ), child: Row( children: [ Padding( padding: EdgeInsets.fromLTRB( 0, UIShapes.paddingSimple, 0, UIShapes.paddingSimple, ), child: ClipRRect( borderRadius: UIShapes.rightRoundedRectangle, child: image, ), ), Padding( padding: EdgeInsets.fromLTRB( 0, UIShapes.paddingSimple, 0, UIShapes.paddingSimple, ), child: Column(children: buttons), ), VerticalDivider( color: _right ? Colors.transparent : UIColors.white, width: 2, ) ], ), ), Padding( padding: EdgeInsets.fromLTRB( UIShapes.paddingMax + paddingLeft, UIShapes.paddingSimple, UIShapes.paddingSimple + paddingRight, UIShapes.paddingDouble), child: _child, ), ], ), ], ), ); }, ); } } class ItemWithPersonAndText extends StatelessWidget { final String _title; final String _assetLogo; final String _assetPerson; final String _personName; final String? _personText; final InlineSpan _text; final String? _mail; final String? _phone; final Uri? _website; final LocationModel? _location; final String? _facebook; final String? _instagram; final Function() _onShare; final Function(bool favorite) _onFavorite; final Future _initFavorite; final Function(bool notify) _onNotify; final Future _initNotify; final Gradient _gradientColor; ItemWithPersonAndText.fromOrganisation(RepresentedOrganisationModel _organisation) : _title = _organisation.name, _assetLogo = _organisation.image.resource, _assetPerson = _organisation.person.image.resource, _personName = _organisation.person.name, _personText = _organisation.person.position, _mail = _organisation.contact.mail, _phone = _organisation.contact.phone, _website = _organisation.contact.website, _location = _organisation.contact.location, _facebook = _organisation.contact.facebook, _instagram = _organisation.contact.instagram, _text = _organisation.text, _onShare = shareOrganisation(_organisation), _onFavorite = _organisation.favorize, _initFavorite = _organisation.favorized, _onNotify = _organisation.subscribe, _initNotify = _organisation.subscribed, _gradientColor = UIGradiants.yellow; ItemWithPersonAndText.fromCompany(CompanyModel _company) : _title = _company.name, _assetLogo = _company.image.resource, _assetPerson = _company.person.image.resource, _personName = _company.person.name, _personText = _company.person.position, _text = _company.text, _mail = _company.contact.mail, _phone = _company.contact.phone, _website = _company.contact.website, _location = _company.contact.location, _facebook = _company.contact.facebook, _instagram = _company.contact.instagram, _onShare = shareCompany(_company), _onFavorite = doNothing, _initFavorite = Future(() => false), _onNotify = _company.subscribe, _initNotify = _company.subscribed, _gradientColor = UIGradiants.purple; static doNothing(s) {} @override Widget build( BuildContext context) { Text title = Text( _title, style: UITheme.theme.textTheme.displaySmall, ); ImageProvider image = AssetImage(_assetLogo); List iconButtons = []; if (_mail != null) { iconButtons.add( IconButton( icon: const Icon( Icons.mail, color: UIColors.grey5, ), tooltip: 'Mail', onPressed: () { EnvironmentConnector.openMail(_mail); }, ), ); } if (_phone != null) { iconButtons.add( IconButton( icon: const Icon( Icons.phone, color: UIColors.grey5, ), tooltip: 'Phone', onPressed: () { EnvironmentConnector.openPhone(_phone); }, ), ); } if (_website != null) { iconButtons.add( IconButton( icon: const Icon( Icons.web, color: UIColors.grey5, ), tooltip: 'Website', onPressed: () { EnvironmentConnector.openBrowser(_website); }, ), ); } if (_location != null) { iconButtons.add( IconButton( icon: const Icon( Icons.place, color: UIColors.grey5, ), tooltip: 'Location', onPressed: () {EnvironmentConnector.openMaps(_location);}, ), ); } if (_facebook != null) { iconButtons.add( IconButton( icon: const Icon( Icons.facebook, color: UIColors.grey5, ), tooltip: 'Facebook', onPressed: () {EnvironmentConnector.openFacebook(_facebook);}, ), ); } if (_instagram != null) { iconButtons.add( IconButton( icon: const Icon( FontAwesomeIcons.instagram, color: UIColors.grey5, ), tooltip: 'Instagram', onPressed: () {EnvironmentConnector.openInstagram(_instagram);}, ), ); } Widget child = Column( crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ Row( children: [ ClipRRect( borderRadius: BorderRadius.circular(UIShapes.paddingDouble), child: Image( image: AssetImage(_assetPerson), fit: BoxFit.cover, width: 100, height: 100, ), ), VerticalDivider(width: UIShapes.paddingSimple), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _personName, style: UITheme.theme.textTheme.displaySmall, ), Text( _personText??'', style: UITheme.theme.textTheme.bodyLarge, ), ], ), ), Column( children: iconButtons, ), ], ), RichText(text: _text,), ], ); return ItemCard( title, image, child, _onShare, onFavorite: _onFavorite, initFavorite: _initFavorite, onNotify: _onNotify, initNotify: _initNotify, gradientColor: _gradientColor, ); } } class ItemWithText extends StatelessWidget { final String _title; final String _assetTitle; final String? _subtitle; final String _text; final Function() _onShare; final Function()? _onFavorite; final Function()? _onNotify; ItemWithText.fromPoi(PointOfInterestModel _poi) : _title = _poi.name, _assetTitle = _poi.image.resource, _subtitle = _poi.subtitle, _text = _poi.text, _onShare = sharePoi(_poi), _onFavorite = null, _onNotify = null; @override Widget build(BuildContext context) { Text title = Text( _title, style: UITheme.theme.textTheme.headlineSmall, ); ImageProvider image = AssetImage(_assetTitle); Column child = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _subtitle ?? '', style: UITheme.theme.textTheme.displaySmall, ), Text( _text, style: UITheme.theme.textTheme.bodyLarge, ), ], ); return ItemCard( title, image, child, _onShare, onFavorite: _onFavorite, onNotify: _onNotify, ); } } class ItemWithTitle extends StatelessWidget { final ArticleModel _article; final String _title; final String? _thumbnailPictureUrl; final String _subtitle; final Function()? _onShare; final Function(bool favorite)? _onFavorite; final Future? _initFavorite; final Function(bool notify)? _onNotify; final Future? _initNotify; final bool _right; final Function(PreferredSizeWidget appBar, Widget body)? _onChange; ItemWithTitle.fromNull() : _title = '', _thumbnailPictureUrl = null, _subtitle = '', _onShare = null, _onFavorite = null, _initFavorite = null, _onNotify = null, _initNotify = null, _right = false, _onChange = null, _article = ArticleModel(-1, '', '', DateTime.now(), '', Uri()); ItemWithTitle.fromArticle(this._article, this._onChange) : _title = '${_article.publishedAt.year}-${_article.publishedAt.month}-${_article.publishedAt.day}', _thumbnailPictureUrl = _article.image.resource, _subtitle = _article.title, _onShare = shareArticle(_article), _onFavorite = favorizeAll(_article.categories), _initFavorite = allFavorized(_article.categories), _onNotify = subscribeAll(_article.categories), _initNotify = allSubscribed(_article.categories), _right = false; static favorizeAll(List list) { return (fav) => list.forEach((e) => e.favorize(fav)); } static Future allFavorized(List list) async { bool favorized = false; for(RepresentedOrganisationModel e in list) { favorized = favorized || await e.favorized; } return favorized; } static subscribeAll(List list) { return (sub) => list.forEach((e) => e.subscribe(sub)); } static Future allSubscribed(List list) async { bool subscribed = false; for(RepresentedOrganisationModel e in list) { subscribed = subscribed || await e.subscribed; } return subscribed; } @override Widget build(BuildContext context) { Text title = Text( _title, style: UITheme.theme.textTheme.headlineSmall, ); ImageProvider? image = _thumbnailPictureUrl != null ? CachedNetworkImageProvider(_thumbnailPictureUrl) : null; Widget child = Row( children: [ Expanded( child: Text( _subtitle, style: UITheme.theme.textTheme.displaySmall, ), ), Icon( Icons.arrow_forward_ios, color: UIColors.grey4, ), ], ); var onTap; if (_article.id != -1) { onTap = () { Home.openPage(ArticleView(_article), _onChange); }; } return GestureDetector( child: ItemCard( title, image, child, _onShare, onFavorite: _onFavorite, initFavorite: _initFavorite, onNotify: _onNotify, initNotify: _initNotify, right: _right, gradientColor: UIGradiants.yellow, ), onTap: onTap, ); } } class ItemWithWebView extends StatelessWidget { final ArticleModel _article; final String _title; final String _thumbnailPictureUrl; final String _subtitle; final Function() _onShare; final Function(bool favorite) _onFavorite; final Future _initFavorite; final Function(bool notify) _onNotify; final Future _initNotify; final bool _right; ItemWithWebView.fromArticle(this._article) : _title = '${_article.publishedAt.year}-${_article.publishedAt.month}-${_article.publishedAt.day}', _thumbnailPictureUrl = _article.image.resource, _subtitle = _article.title, _onShare = shareArticle(_article), _onFavorite = favorizeAll(_article.categories), _initFavorite = allFavorized(_article.categories), _onNotify = subscribeAll(_article.categories), _initNotify = allSubscribed(_article.categories), _right = true; static favorizeAll(List list) { return (fav) => list.forEach((e) => e.favorize(fav)); } static Future allFavorized(List list) async { bool favorized = false; for(RepresentedOrganisationModel e in list) { favorized = favorized || await e.favorized; } return favorized; } static subscribeAll(List list) { return (sub) => list.forEach((e) => e.subscribe(sub)); } static Future allSubscribed(List list) async { bool subscribed = false; for(RepresentedOrganisationModel e in list) { subscribed = subscribed || await e.subscribed; } return subscribed; } @override Widget build(BuildContext context) { Text title = Text( _title, style: UITheme.theme.textTheme.headlineSmall, ); ImageProvider image = CachedNetworkImageProvider(_thumbnailPictureUrl); Widget child = Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _subtitle, style: UITheme.theme.textTheme.displaySmall, textAlign: TextAlign.left, ), HtmlView( _article.content, ), ], ); SizedBox otherImages = SizedBox( height: 200, child: HiddingselGallery(_article.otherImages.map((e) => e.image).toList()), ); return ListView( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), children: [ ItemCard( title, image, child, _onShare, onFavorite: _onFavorite, initFavorite: _initFavorite, onNotify: _onNotify, initNotify: _initNotify, right: _right, gradientColor: UIGradiants.yellow, ), otherImages ], ); } } Function() sharePoi(PointOfInterestModel poi) => () { EnvironmentConnector.share( 'Ich habe eine interessante Sehenswürdigkeit auf hiddingsel.de gefunden:\n${poi.name}'); }; Function() shareOrganisation(RepresentedOrganisationModel organisation) => () { EnvironmentConnector.share( 'Ich habe einen interessanten Verein auf hiddingsel.de gefunden:\n${organisation.name}'); }; Function() shareCompany(CompanyModel company) => () { String text = 'Ich habe ein interessantes Unternehmen auf hiddingsel.de gefunden:\n${company.name}'; if(company.contact.mail != null) { text = text + '\nE-Mail: ${company.contact.mail}'; } if(company.contact.phone != null) { text = text + '\nTelefon: ${company.contact.phone}'; } if(company.contact.website != null) { text = text + '\nWebseite: ${company.contact.website}'; } if(company.contact.instagram != null) { text = text + '\nInstagram: ${company.contact.instagram}'; } if(company.contact.facebook != null) { text = text + '\nFacebook: ${company.contact.facebook}'; } if(company.contact.twitter != null) { text = text + '\nTwitter: ${company.contact.twitter}'; } if(company.contact.location?.address != null) { text = text + '\nAdresse: ${company.contact.location?.address}'; } EnvironmentConnector.share(text); }; Function() shareArticle(ArticleModel article) => () { EnvironmentConnector.share( 'Ich habe einen interessanten Artikel auf hiddingsel.de gefunden:\n${article.url}'); };