From 7cbf5a037c2ae31eb74af8948507e18dd711d206 Mon Sep 17 00:00:00 2001 From: Remy Moll Date: Tue, 10 Sep 2024 16:15:08 +0200 Subject: [PATCH] display more landmark information --- frontend/lib/modules/landmark_card.dart | 69 +++++++++++++++--- frontend/lib/structs/landmark.dart | 71 ++++++++++++++---- .../flutter/generated_plugin_registrant.cc | 4 ++ .../linux/flutter/generated_plugins.cmake | 1 + .../Flutter/GeneratedPluginRegistrant.swift | 2 + frontend/pubspec.lock | 72 +++++++++++++++++-- frontend/pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + .../windows/flutter/generated_plugins.cmake | 1 + 9 files changed, 196 insertions(+), 28 deletions(-) diff --git a/frontend/lib/modules/landmark_card.dart b/frontend/lib/modules/landmark_card.dart index 636153c..3c027e5 100644 --- a/frontend/lib/modules/landmark_card.dart +++ b/frontend/lib/modules/landmark_card.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:url_launcher/url_launcher.dart'; import 'package:anyway/structs/landmark.dart'; - class LandmarkCard extends StatefulWidget { final Landmark landmark; @@ -18,6 +18,10 @@ class _LandmarkCardState extends State { @override Widget build(BuildContext context) { ThemeData theme = Theme.of(context); + ButtonStyle buttonStyle = TextButton.styleFrom( + backgroundColor: Colors.orange, + fixedSize: Size.fromHeight(20) + ); return Container( height: 160, child: Card( @@ -62,15 +66,62 @@ class _LandmarkCardState extends State { ) ], ), - Row( - children: [ - Flexible( - child: Text( - "${widget.landmark.name} (${widget.landmark.type.name})", - style: const TextStyle(fontSize: 14), + 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( + 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'), + ), + ], + ), ), ], ), diff --git a/frontend/lib/structs/landmark.dart b/frontend/lib/structs/landmark.dart index 50918af..e6d3734 100644 --- a/frontend/lib/structs/landmark.dart +++ b/frontend/lib/structs/landmark.dart @@ -1,15 +1,16 @@ import 'dart:collection'; import 'dart:convert'; +import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; -const LandmarkType sightseeing = LandmarkType(name: 'sightseeing'); -const LandmarkType nature = LandmarkType(name: 'nature'); -const LandmarkType shopping = LandmarkType(name: 'shopping'); -// const LandmarkType museum = LandmarkType(name: 'Museum'); -// const LandmarkType restaurant = LandmarkType(name: 'Restaurant'); -const LandmarkType start = LandmarkType(name: 'start'); -const LandmarkType finish = LandmarkType(name: 'finish'); +LandmarkType sightseeing = LandmarkType(name: 'sightseeing'); +LandmarkType nature = LandmarkType(name: 'nature'); +LandmarkType shopping = LandmarkType(name: 'shopping'); +// LandmarkType museum = LandmarkType(name: 'Museum'); +// LandmarkType restaurant = LandmarkType(name: 'Restaurant'); +LandmarkType start = LandmarkType(name: 'start'); +LandmarkType finish = LandmarkType(name: 'finish'); final class Landmark extends LinkedListEntry{ @@ -21,6 +22,9 @@ final class Landmark extends LinkedListEntry{ final bool? isSecondary; // description to be shown in the overview + final String? nameEN; + final String? websiteURL; + final String? wikipediaURL; final String? imageURL; final String? description; final Duration? duration; @@ -38,6 +42,9 @@ final class Landmark extends LinkedListEntry{ required this.type, this.isSecondary, + this.nameEN, + this.websiteURL, + this.wikipediaURL, this.imageURL, this.description, this.duration, @@ -61,15 +68,30 @@ final class Landmark extends LinkedListEntry{ // parse the rest separately, they could be missing LandmarkType typeFixed = LandmarkType(name: type); 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 description = json['description'] as String?; var duration = Duration(minutes: json['duration'] ?? 0) as Duration?; - // if (duration == const Duration()) {duration = null;}; final visited = json['visited'] as bool?; var tripTime = Duration(minutes: json['time_to_reach_next'] ?? 0) as Duration?; 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 { throw FormatException('Invalid JSON: $json'); } @@ -88,6 +110,9 @@ final class Landmark extends LinkedListEntry{ 'location': location, 'type': type.name, 'is_secondary': isSecondary, + 'name_en': nameEN, + 'website_url': websiteURL, + 'wikipedia_url': wikipediaURL, 'image_url': imageURL, 'description': description, 'duration': duration?.inMinutes, @@ -100,13 +125,29 @@ final class Landmark extends LinkedListEntry{ class LandmarkType { final String name; // final String description; - // final Icon icon; + Icon icon; - const LandmarkType({ - required this.name, - // required this.description, - // required this.icon, - }); + LandmarkType({required this.name, this.icon = const Icon(Icons.location_on)}) { + switch (name) { + case 'sightseeing': + 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 bool operator ==(Object other) { if (other is LandmarkType) { diff --git a/frontend/linux/flutter/generated_plugin_registrant.cc b/frontend/linux/flutter/generated_plugin_registrant.cc index e71a16d..f6f23bf 100644 --- a/frontend/linux/flutter/generated_plugin_registrant.cc +++ b/frontend/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include 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); } diff --git a/frontend/linux/flutter/generated_plugins.cmake b/frontend/linux/flutter/generated_plugins.cmake index 2e1de87..f16b4c3 100644 --- a/frontend/linux/flutter/generated_plugins.cmake +++ b/frontend/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/frontend/macos/Flutter/GeneratedPluginRegistrant.swift b/frontend/macos/Flutter/GeneratedPluginRegistrant.swift index eefcc6d..63ad0d1 100644 --- a/frontend/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/frontend/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,9 +8,11 @@ import Foundation import path_provider_foundation import shared_preferences_foundation import sqflite +import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/frontend/pubspec.lock b/frontend/pubspec.lock index 1c7e0ec..fe94184 100644 --- a/frontend/pubspec.lock +++ b/frontend/pubspec.lock @@ -661,6 +661,70 @@ packages: url: "https://pub.dev" source: hosted 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: dependency: transitive description: @@ -705,10 +769,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.2.4" + version: "14.2.5" web: dependency: transitive description: @@ -742,5 +806,5 @@ packages: source: hosted version: "6.5.0" sdks: - dart: ">=3.4.0 <4.0.0" - flutter: ">=3.22.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index 10514e6..e36bf03 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -47,6 +47,7 @@ dependencies: auto_size_text: ^3.0.0 map_launcher: ^3.3.1 flutter_svg: ^2.0.10+1 + url_launcher: ^6.3.0 dev_dependencies: flutter_test: diff --git a/frontend/windows/flutter/generated_plugin_registrant.cc b/frontend/windows/flutter/generated_plugin_registrant.cc index 8b6d468..4f78848 100644 --- a/frontend/windows/flutter/generated_plugin_registrant.cc +++ b/frontend/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/frontend/windows/flutter/generated_plugins.cmake b/frontend/windows/flutter/generated_plugins.cmake index b93c4c3..88b22e5 100644 --- a/frontend/windows/flutter/generated_plugins.cmake +++ b/frontend/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + url_launcher_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST -- 2.47.2