display more landmark information #21
| @@ -1,9 +1,9 @@ | |||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||||
|  | import 'package:url_launcher/url_launcher.dart'; | ||||||
|  |  | ||||||
| import 'package:anyway/structs/landmark.dart'; | import 'package:anyway/structs/landmark.dart'; | ||||||
|  |  | ||||||
|  |  | ||||||
| class LandmarkCard extends StatefulWidget { | class LandmarkCard extends StatefulWidget { | ||||||
|   final Landmark landmark; |   final Landmark landmark; | ||||||
|    |    | ||||||
| @@ -18,6 +18,10 @@ class _LandmarkCardState extends State<LandmarkCard> { | |||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     ThemeData theme = Theme.of(context); |     ThemeData theme = Theme.of(context); | ||||||
|  |     ButtonStyle buttonStyle = TextButton.styleFrom( | ||||||
|  |       backgroundColor: Colors.orange, | ||||||
|  |       fixedSize: Size.fromHeight(20) | ||||||
|  |     ); | ||||||
|     return Container( |     return Container( | ||||||
|       height: 160, |       height: 160, | ||||||
|       child: Card( |       child: Card( | ||||||
| @@ -62,15 +66,62 @@ class _LandmarkCardState extends State<LandmarkCard> { | |||||||
|                         ) |                         ) | ||||||
|                       ], |                       ], | ||||||
|                     ), |                     ), | ||||||
|  |                     if (widget.landmark.nameEN != null) | ||||||
|                       Row( |                       Row( | ||||||
|                         children: [ |                         children: [ | ||||||
|                           Flexible( |                           Flexible( | ||||||
|                             child: Text( |                             child: Text( | ||||||
|                             "${widget.landmark.name} (${widget.landmark.type.name})", |                               widget.landmark.nameEN!, | ||||||
|                             style: const TextStyle(fontSize: 14), |                               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( | ||||||
|  |                             style: buttonStyle, | ||||||
|  |                             onPressed: () {}, | ||||||
|  |                             icon: widget.landmark.type.icon, | ||||||
|  |                             label: Text(widget.landmark.type.name), | ||||||
|  |                           ), | ||||||
|  |                           if (widget.landmark.duration != null && widget.landmark.duration!.inMinutes > 0) | ||||||
|  |                             TextButton.icon( | ||||||
|  |                               style: buttonStyle, | ||||||
|  |                               onPressed: () {}, | ||||||
|  |                               icon: Icon(Icons.hourglass_bottom), | ||||||
|  |                               label: Text('${widget.landmark.duration!.inMinutes} minutes'), | ||||||
|  |                             ), | ||||||
|  |                           if (widget.landmark.websiteURL != null) | ||||||
|  |                             TextButton.icon( | ||||||
|  |                               style: buttonStyle, | ||||||
|  |                               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( | ||||||
|  |                               style: buttonStyle, | ||||||
|  |                               onPressed: () async { | ||||||
|  |                                 // open a browser with the wikipedia link | ||||||
|  |                                 await launchUrl(Uri.parse(widget.landmark.wikipediaURL!)); | ||||||
|  |                               }, | ||||||
|  |                               icon: Icon(Icons.book), | ||||||
|  |                             label: Text('Wikipedia'), | ||||||
|  |                           ), | ||||||
|  |                         ], | ||||||
|  |                       ), | ||||||
|                     ), |                     ), | ||||||
|                   ], |                   ], | ||||||
|                 ), |                 ), | ||||||
|   | |||||||
| @@ -1,15 +1,16 @@ | |||||||
| import 'dart:collection'; | import 'dart:collection'; | ||||||
| import 'dart:convert'; | import 'dart:convert'; | ||||||
|  |  | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
| import 'package:shared_preferences/shared_preferences.dart'; | import 'package:shared_preferences/shared_preferences.dart'; | ||||||
|  |  | ||||||
| const LandmarkType sightseeing = LandmarkType(name: 'sightseeing'); | LandmarkType sightseeing = LandmarkType(name: 'sightseeing'); | ||||||
| const LandmarkType nature = LandmarkType(name: 'nature'); | LandmarkType nature = LandmarkType(name: 'nature'); | ||||||
| const LandmarkType shopping = LandmarkType(name: 'shopping'); | LandmarkType shopping = LandmarkType(name: 'shopping'); | ||||||
| // const LandmarkType museum = LandmarkType(name: 'Museum'); | // LandmarkType museum = LandmarkType(name: 'Museum'); | ||||||
| // const LandmarkType restaurant = LandmarkType(name: 'Restaurant'); | // LandmarkType restaurant = LandmarkType(name: 'Restaurant'); | ||||||
| const LandmarkType start = LandmarkType(name: 'start'); | LandmarkType start = LandmarkType(name: 'start'); | ||||||
| const LandmarkType finish = LandmarkType(name: 'finish'); | LandmarkType finish = LandmarkType(name: 'finish'); | ||||||
|  |  | ||||||
|  |  | ||||||
| final class Landmark extends LinkedListEntry<Landmark>{ | final class Landmark extends LinkedListEntry<Landmark>{ | ||||||
| @@ -21,6 +22,9 @@ final class Landmark extends LinkedListEntry<Landmark>{ | |||||||
|   final bool? isSecondary; |   final bool? isSecondary; | ||||||
|  |  | ||||||
|   // description to be shown in the overview |   // description to be shown in the overview | ||||||
|  |   final String? nameEN; | ||||||
|  |   final String? websiteURL; | ||||||
|  |   final String? wikipediaURL; | ||||||
|   final String? imageURL; |   final String? imageURL; | ||||||
|   final String? description; |   final String? description; | ||||||
|   final Duration? duration; |   final Duration? duration; | ||||||
| @@ -38,6 +42,9 @@ final class Landmark extends LinkedListEntry<Landmark>{ | |||||||
|     required this.type, |     required this.type, | ||||||
|     this.isSecondary, |     this.isSecondary, | ||||||
|  |  | ||||||
|  |     this.nameEN, | ||||||
|  |     this.websiteURL, | ||||||
|  |     this.wikipediaURL, | ||||||
|     this.imageURL, |     this.imageURL, | ||||||
|     this.description, |     this.description, | ||||||
|     this.duration, |     this.duration, | ||||||
| @@ -61,15 +68,30 @@ final class Landmark extends LinkedListEntry<Landmark>{ | |||||||
|       // parse the rest separately, they could be missing |       // parse the rest separately, they could be missing | ||||||
|       LandmarkType typeFixed = LandmarkType(name: type); |       LandmarkType typeFixed = LandmarkType(name: type); | ||||||
|       final isSecondary = json['is_secondary'] as bool?; |       final isSecondary = json['is_secondary'] as bool?; | ||||||
|  |       final nameEN = json['name_en'] as String?; | ||||||
|  |       final websiteURL = json['website_url'] as String?; | ||||||
|  |       final wikipediaURL = json['wikipedia_url'] as String?; | ||||||
|       final imageURL = json['image_url'] as String?; |       final imageURL = json['image_url'] as String?; | ||||||
|       final description = json['description'] as String?; |       final description = json['description'] as String?; | ||||||
|       var duration = Duration(minutes: json['duration'] ?? 0) as Duration?; |       var duration = Duration(minutes: json['duration'] ?? 0) as Duration?; | ||||||
|       // if (duration == const Duration()) {duration = null;}; |  | ||||||
|       final visited = json['visited'] as bool?; |       final visited = json['visited'] as bool?; | ||||||
|       var tripTime = Duration(minutes: json['time_to_reach_next'] ?? 0) as Duration?; |       var tripTime = Duration(minutes: json['time_to_reach_next'] ?? 0) as Duration?; | ||||||
|        |        | ||||||
|       return Landmark( |       return Landmark( | ||||||
|         uuid: uuid, name: name, location: locationFixed, type: typeFixed, isSecondary: isSecondary, imageURL: imageURL, description: description, duration: duration, visited: visited, tripTime: tripTime); |         uuid: uuid, | ||||||
|  |         name: name, | ||||||
|  |         location: locationFixed, | ||||||
|  |         type: typeFixed, | ||||||
|  |         isSecondary: isSecondary, | ||||||
|  |         nameEN: nameEN, | ||||||
|  |         websiteURL: websiteURL, | ||||||
|  |         wikipediaURL: wikipediaURL, | ||||||
|  |         imageURL: imageURL, | ||||||
|  |         description: description, | ||||||
|  |         duration: duration, | ||||||
|  |         visited: visited, | ||||||
|  |         tripTime: tripTime | ||||||
|  |       ); | ||||||
|     } else { |     } else { | ||||||
|       throw FormatException('Invalid JSON: $json'); |       throw FormatException('Invalid JSON: $json'); | ||||||
|     } |     } | ||||||
| @@ -88,6 +110,9 @@ final class Landmark extends LinkedListEntry<Landmark>{ | |||||||
|     'location': location, |     'location': location, | ||||||
|     'type': type.name, |     'type': type.name, | ||||||
|     'is_secondary': isSecondary, |     'is_secondary': isSecondary, | ||||||
|  |     'name_en': nameEN, | ||||||
|  |     'website_url': websiteURL, | ||||||
|  |     'wikipedia_url': wikipediaURL, | ||||||
|     'image_url': imageURL, |     'image_url': imageURL, | ||||||
|     'description': description, |     'description': description, | ||||||
|     'duration': duration?.inMinutes, |     'duration': duration?.inMinutes, | ||||||
| @@ -100,13 +125,29 @@ final class Landmark extends LinkedListEntry<Landmark>{ | |||||||
| class LandmarkType { | class LandmarkType { | ||||||
|   final String name; |   final String name; | ||||||
|   // final String description; |   // final String description; | ||||||
|   // final Icon icon; |   Icon icon; | ||||||
|    |    | ||||||
|   const LandmarkType({ |   LandmarkType({required this.name, this.icon = const Icon(Icons.location_on)}) { | ||||||
|     required this.name, |     switch (name) { | ||||||
|     // required this.description, |       case 'sightseeing': | ||||||
|     // required this.icon, |         icon = Icon(Icons.church); | ||||||
|   }); |         break; | ||||||
|  |       case 'nature': | ||||||
|  |         icon = Icon(Icons.eco); | ||||||
|  |         break; | ||||||
|  |       case 'shopping': | ||||||
|  |         icon = Icon(Icons.shopping_cart); | ||||||
|  |         break; | ||||||
|  |       case 'start': | ||||||
|  |         icon = Icon(Icons.play_arrow); | ||||||
|  |         break; | ||||||
|  |       case 'finish': | ||||||
|  |         icon = Icon(Icons.flag); | ||||||
|  |         break; | ||||||
|  |       default: | ||||||
|  |         icon = Icon(Icons.location_on); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|   @override |   @override | ||||||
|   bool operator ==(Object other) { |   bool operator ==(Object other) { | ||||||
|     if (other is LandmarkType) { |     if (other is LandmarkType) { | ||||||
|   | |||||||
| @@ -6,6 +6,10 @@ | |||||||
|  |  | ||||||
| #include "generated_plugin_registrant.h" | #include "generated_plugin_registrant.h" | ||||||
|  |  | ||||||
|  | #include <url_launcher_linux/url_launcher_plugin.h> | ||||||
|  |  | ||||||
| void fl_register_plugins(FlPluginRegistry* registry) { | void fl_register_plugins(FlPluginRegistry* registry) { | ||||||
|  |   g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = | ||||||
|  |       fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); | ||||||
|  |   url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| # | # | ||||||
|  |  | ||||||
| list(APPEND FLUTTER_PLUGIN_LIST | list(APPEND FLUTTER_PLUGIN_LIST | ||||||
|  |   url_launcher_linux | ||||||
| ) | ) | ||||||
|  |  | ||||||
| list(APPEND FLUTTER_FFI_PLUGIN_LIST | list(APPEND FLUTTER_FFI_PLUGIN_LIST | ||||||
|   | |||||||
| @@ -8,9 +8,11 @@ import Foundation | |||||||
| import path_provider_foundation | import path_provider_foundation | ||||||
| import shared_preferences_foundation | import shared_preferences_foundation | ||||||
| import sqflite | import sqflite | ||||||
|  | import url_launcher_macos | ||||||
|  |  | ||||||
| func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { | ||||||
|   PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) |   PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) | ||||||
|   SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) |   SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) | ||||||
|   SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) |   SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) | ||||||
|  |   UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -661,6 +661,70 @@ packages: | |||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.3.2" |     version: "1.3.2" | ||||||
|  |   url_launcher: | ||||||
|  |     dependency: "direct main" | ||||||
|  |     description: | ||||||
|  |       name: url_launcher | ||||||
|  |       sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "6.3.0" | ||||||
|  |   url_launcher_android: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: url_launcher_android | ||||||
|  |       sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "6.3.10" | ||||||
|  |   url_launcher_ios: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: url_launcher_ios | ||||||
|  |       sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "6.3.1" | ||||||
|  |   url_launcher_linux: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: url_launcher_linux | ||||||
|  |       sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "3.2.0" | ||||||
|  |   url_launcher_macos: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: url_launcher_macos | ||||||
|  |       sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "3.2.0" | ||||||
|  |   url_launcher_platform_interface: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: url_launcher_platform_interface | ||||||
|  |       sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "2.3.2" | ||||||
|  |   url_launcher_web: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: url_launcher_web | ||||||
|  |       sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "2.3.3" | ||||||
|  |   url_launcher_windows: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: url_launcher_windows | ||||||
|  |       sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "3.1.2" | ||||||
|   uuid: |   uuid: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -705,10 +769,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: vm_service |       name: vm_service | ||||||
|       sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc |       sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "14.2.4" |     version: "14.2.5" | ||||||
|   web: |   web: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @@ -742,5 +806,5 @@ packages: | |||||||
|     source: hosted |     source: hosted | ||||||
|     version: "6.5.0" |     version: "6.5.0" | ||||||
| sdks: | sdks: | ||||||
|   dart: ">=3.4.0 <4.0.0" |   dart: ">=3.5.0 <4.0.0" | ||||||
|   flutter: ">=3.22.0" |   flutter: ">=3.24.0" | ||||||
|   | |||||||
| @@ -47,6 +47,7 @@ dependencies: | |||||||
|   auto_size_text: ^3.0.0 |   auto_size_text: ^3.0.0 | ||||||
|   map_launcher: ^3.3.1 |   map_launcher: ^3.3.1 | ||||||
|   flutter_svg: ^2.0.10+1 |   flutter_svg: ^2.0.10+1 | ||||||
|  |   url_launcher: ^6.3.0 | ||||||
|  |  | ||||||
| dev_dependencies: | dev_dependencies: | ||||||
|   flutter_test: |   flutter_test: | ||||||
|   | |||||||
| @@ -6,6 +6,9 @@ | |||||||
|  |  | ||||||
| #include "generated_plugin_registrant.h" | #include "generated_plugin_registrant.h" | ||||||
|  |  | ||||||
|  | #include <url_launcher_windows/url_launcher_windows.h> | ||||||
|  |  | ||||||
| void RegisterPlugins(flutter::PluginRegistry* registry) { | void RegisterPlugins(flutter::PluginRegistry* registry) { | ||||||
|  |   UrlLauncherWindowsRegisterWithRegistrar( | ||||||
|  |       registry->GetRegistrarForPlugin("UrlLauncherWindows")); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| # | # | ||||||
|  |  | ||||||
| list(APPEND FLUTTER_PLUGIN_LIST | list(APPEND FLUTTER_PLUGIN_LIST | ||||||
|  |   url_launcher_windows | ||||||
| ) | ) | ||||||
|  |  | ||||||
| list(APPEND FLUTTER_FFI_PLUGIN_LIST | list(APPEND FLUTTER_FFI_PLUGIN_LIST | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user