From d186a51a8771505e0f5c2343e097371f3cc255e2 Mon Sep 17 00:00:00 2001 From: Remy Moll Date: Sun, 15 Dec 2024 16:30:17 +0100 Subject: [PATCH] WIP: ladnmark card adjustments --- .../modules/current_trip_landmarks_list.dart | 26 +- frontend/lib/modules/landmark_card.dart | 238 +++++++++++------- 2 files changed, 145 insertions(+), 119 deletions(-) diff --git a/frontend/lib/modules/current_trip_landmarks_list.dart b/frontend/lib/modules/current_trip_landmarks_list.dart index b486a97..39333f6 100644 --- a/frontend/lib/modules/current_trip_landmarks_list.dart +++ b/frontend/lib/modules/current_trip_landmarks_list.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:anyway/modules/landmark_card.dart'; import 'package:anyway/structs/landmark.dart'; import 'package:anyway/structs/trip.dart'; -import 'package:anyway/main.dart'; @@ -25,30 +24,7 @@ List landmarksList(Trip trip) { for (Landmark landmark in trip.landmarks) { children.add( - Dismissible( - key: ValueKey(landmark.hashCode), - child: LandmarkCard(landmark), - dismissThresholds: {DismissDirection.endToStart: 0.95, DismissDirection.startToEnd: 0.95}, - onDismissed: (direction) { - log('Removing ${landmark.name}'); - trip.removeLandmark(landmark); - - rootScaffoldMessengerKey.currentState!.showSnackBar( - SnackBar(content: Text("We won't show ${landmark.name} again")) - ); - }, - - background: Container(color: Colors.red), - secondaryBackground: Container( - color: Colors.red, - child: Icon( - Icons.delete, - color: Colors.white, - ), - padding: EdgeInsets.all(15), - alignment: Alignment.centerRight, - ), - ) + LandmarkCard(landmark, trip), ); if (landmark.next != null) { diff --git a/frontend/lib/modules/landmark_card.dart b/frontend/lib/modules/landmark_card.dart index 8b2d824..1b49fc2 100644 --- a/frontend/lib/modules/landmark_card.dart +++ b/frontend/lib/modules/landmark_card.dart @@ -1,3 +1,5 @@ +import 'package:anyway/main.dart'; +import 'package:anyway/structs/trip.dart'; import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -6,8 +8,12 @@ import 'package:anyway/structs/landmark.dart'; class LandmarkCard extends StatefulWidget { final Landmark landmark; + final Trip parentTrip; - LandmarkCard(this.landmark); + LandmarkCard( + this.landmark, + this.parentTrip, + ); @override _LandmarkCardState createState() => _LandmarkCardState(); @@ -18,106 +24,150 @@ class _LandmarkCardState extends State { @override Widget build(BuildContext context) { return Container( - height: 160, child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0), ), elevation: 5, clipBehavior: Clip.antiAliasWithSaveLayer, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( // the image on the left - // inherit the height of the parent container - height: double.infinity, - // force a fixed width - width: 160, - child: CachedNetworkImage( - imageUrl: widget.landmark.imageURL ?? '', - placeholder: (context, url) => Center(child: CircularProgressIndicator()), - errorWidget: (context, error, stackTrace) => Icon(Icons.question_mark_outlined), - fit: BoxFit.cover, - ), - ), - Flexible( - child: Padding( - padding: EdgeInsets.all(10), - child: Column( - children: [ - Row( - children: [ - Flexible( - child: Text( - widget.landmark.name, - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - maxLines: 2, - ), - ) - ], - ), - if (widget.landmark.nameEN != null) - Row( - children: [ - Flexible( - child: Text( - widget.landmark.nameEN!, - style: const TextStyle( - fontSize: 16, - ), - maxLines: 1, - ), - ) - ], - ), - SingleChildScrollView( - // allows the buttons to be scrolled - scrollDirection: Axis.horizontal, - child: Wrap( - spacing: 10, - // show the type, the website, and the wikipedia link as buttons/labels in a row - children: [ - TextButton.icon( - onPressed: () {}, - icon: widget.landmark.type.icon, - label: Text(widget.landmark.type.name), - ), - if (widget.landmark.duration != null && widget.landmark.duration!.inMinutes > 0) - TextButton.icon( - onPressed: () {}, - icon: Icon(Icons.hourglass_bottom), - label: Text('${widget.landmark.duration!.inMinutes} minutes'), - ), - if (widget.landmark.websiteURL != null) - TextButton.icon( - onPressed: () async { - // open a browser with the website link - await launchUrl(Uri.parse(widget.landmark.websiteURL!)); - }, - icon: Icon(Icons.link), - label: Text('Website'), - ), - // if (widget.landmark.wikipediaURL != null) - // TextButton.icon( - // onPressed: () async { - // // open a browser with the wikipedia link - // await launchUrl(Uri.parse(widget.landmark.wikipediaURL!)); - // }, - // icon: Icon(Icons.book), - // label: Text('Wikipedia'), - // ), - ], - ), - ), - ], - ), - ), - ), - ], + // if the image is available, display it on the left side of the card, otherwise only display the text + child: widget.landmark.imageURL != null ? splitLayout() : textLayout(), + ), + ); + } + + Widget splitLayout() { + // If an image is available, display it on the left side of the card + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + // the image on the left + width: 160, + height: 160, + + child: CachedNetworkImage( + imageUrl: widget.landmark.imageURL ?? '', + placeholder: (context, url) => Center(child: CircularProgressIndicator()), + errorWidget: (context, error, stackTrace) => Icon(Icons.question_mark_outlined), + fit: BoxFit.cover, + ), ), + Flexible( + child: textLayout(), + ), + ], + ); + } + + Widget textLayout() { + return Padding( + padding: EdgeInsets.all(10), + child: Column( + children: [ + Row( + children: [ + Flexible( + child: Text( + widget.landmark.name, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + maxLines: 2, + ), + ) + ], + ), + if (widget.landmark.nameEN != null) + Row( + children: [ + Flexible( + child: Text( + widget.landmark.nameEN!, + style: const TextStyle( + fontSize: 16, + ), + maxLines: 1, + ), + ) + ], + ), + SingleChildScrollView( + // allows the buttons to be scrolled + scrollDirection: Axis.horizontal, + child: Wrap( + spacing: 10, + // show the type, the website, and the wikipedia link as buttons/labels in a row + children: [ + TextButton.icon( + onPressed: () {}, + icon: widget.landmark.type.icon, + label: Text(widget.landmark.type.name), + ), + if (widget.landmark.duration != null && widget.landmark.duration!.inMinutes > 0) + TextButton.icon( + onPressed: () {}, + icon: Icon(Icons.hourglass_bottom), + label: Text('${widget.landmark.duration!.inMinutes} minutes'), + ), + if (widget.landmark.websiteURL != null) + TextButton.icon( + onPressed: () async { + // open a browser with the website link + await launchUrl(Uri.parse(widget.landmark.websiteURL!)); + }, + icon: Icon(Icons.link), + label: Text('Website'), + ), + // if (widget.landmark.wikipediaURL != null) + // TextButton.icon( + // onPressed: () async { + // // open a browser with the wikipedia link + // await launchUrl(Uri.parse(widget.landmark.wikipediaURL!)); + // }, + // icon: Icon(Icons.book), + // label: Text('Wikipedia'), + // ), + PopupMenuButton( + icon: Icon(Icons.settings), + style: TextButtonTheme.of(context).style, + itemBuilder: (context) => [ + PopupMenuItem( + child: ListTile( + leading: Icon(Icons.delete), + title: Text('Delete'), + onTap: () async { + setState(() { + widget.parentTrip.removeLandmark(widget.landmark); + }); + rootScaffoldMessengerKey.currentState!.showSnackBar( + SnackBar(content: Text("We won't show ${widget.landmark.name} again")) + ); + + + }, + ), + ), + PopupMenuItem( + child: ListTile( + leading: Icon(Icons.star), + title: Text('Favorite'), + onTap: () async { + // delete the landmark + // await deleteLandmark(widget.landmark); + + }, + ), + ), + + ], + ) + + ], + ), + ), + ], ), ); }