diff --git a/app/lib/core/api/eq_api.dart b/app/lib/core/api/eq_api.dart index 0a87e9ceb..90d2ad6d1 100644 --- a/app/lib/core/api/eq_api.dart +++ b/app/lib/core/api/eq_api.dart @@ -1,7 +1,11 @@ import 'package:dio/dio.dart'; import 'package:eqapi_client/eqapi_client.dart'; import 'package:eqmonitor/core/provider/dio_provider.dart'; +import 'package:eqmonitor/core/provider/log/talker.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:talker_dio_logger/talker_dio_logger_interceptor.dart'; +import 'package:talker_dio_logger/talker_dio_logger_settings.dart'; +import 'package:talker_flutter/talker_flutter.dart'; part 'eq_api.g.dart'; @@ -18,9 +22,19 @@ EqApi eqApi(EqApiRef ref) { dio: dio, objectsDio: Dio( BaseOptions( - baseUrl: 'https://objects.eqmonitor.app', + baseUrl: 'https://object.eqmonitor.app', + + ), + )..interceptors.add( + TalkerDioLogger( + settings: TalkerDioLoggerSettings( + errorPen: AnsiPen()..red(), + requestPen: AnsiPen()..yellow(), + responsePen: AnsiPen()..green(), + ), + talker: ref.watch(talkerProvider), + ), ), - ), ); } diff --git a/app/lib/core/api/eq_api.g.dart b/app/lib/core/api/eq_api.g.dart index 06810400b..888528a1c 100644 --- a/app/lib/core/api/eq_api.g.dart +++ b/app/lib/core/api/eq_api.g.dart @@ -8,7 +8,7 @@ part of 'eq_api.dart'; // RiverpodGenerator // ************************************************************************** -String _$eqApiHash() => r'd928a09649aa70249237dcc36b5c9934e871ea03'; +String _$eqApiHash() => r'2d428be676594b0a88b12075bd528aebf9d491a8'; /// See also [eqApi]. @ProviderFor(eqApi) diff --git a/app/lib/core/api/jma_parameter_api.g.dart b/app/lib/core/api/jma_parameter_api.g.dart index 25b8c8cdb..9142ac94f 100644 --- a/app/lib/core/api/jma_parameter_api.g.dart +++ b/app/lib/core/api/jma_parameter_api.g.dart @@ -9,7 +9,7 @@ part of 'jma_parameter_api.dart'; // ************************************************************************** String _$jmaParameterApiClientHash() => - r'8376451bacb718f92fd9eac9792b82f54c9bdde6'; + r'7c110a35d1041f823d6333b2c69121f95150ef08'; /// See also [jmaParameterApiClient]. @ProviderFor(jmaParameterApiClient) diff --git a/app/lib/core/component/intenisty/jma_forecast_intensity_icon.dart b/app/lib/core/component/intenisty/jma_forecast_intensity_icon.dart index c8fb9197f..94b958e88 100644 --- a/app/lib/core/component/intenisty/jma_forecast_intensity_icon.dart +++ b/app/lib/core/component/intenisty/jma_forecast_intensity_icon.dart @@ -104,3 +104,158 @@ class JmaForecastIntensityWidget extends ConsumerWidget { ); } } + +class JmaForecastIntensityIcon extends ConsumerWidget { + const JmaForecastIntensityIcon({ + required this.intensity, + required this.type, + this.customText, + super.key, + this.size = 50, + this.showSuffix = true, + }); + final JmaForecastIntensity intensity; + final IntensityIconType type; + final double size; + final String? customText; + final bool showSuffix; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final intensityColorModel = ref.watch(intensityColorProvider); + final colorScheme = intensityColorModel.fromJmaForecastIntensity(intensity); + final (fg, bg) = (colorScheme.foreground, colorScheme.background); + // 震度の整数部分 + final intensityMainText = + intensity.type.replaceAll('-', '').replaceAll('+', ''); + // 震度の弱・強の表記 + final suffix = intensity.type.contains('-') + ? '-' + : intensity.type.contains('+') + ? '+' + : ''; + final intensitySubText = intensity.type.contains('-') + ? '弱' + : intensity.type.contains('+') + ? '強' + : ''; + final borderColor = Color.lerp( + bg, + fg, + 0.3, + )!; + return switch (type) { + IntensityIconType.small => SizedBox( + height: size, + width: size, + child: DecoratedBox( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: bg, + border: Border.all( + color: borderColor, + width: 5, + ), + ), + child:Center( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + intensityMainText, + style: TextStyle( + color: fg, + fontSize: 100, + fontWeight: FontWeight.w900, + fontFamily: FontFamily.jetBrainsMono, + ), + ), + Text( + suffix, + style: TextStyle( + color: fg, + fontSize: 80, + fontWeight: FontWeight.w900, + fontFamily: FontFamily.jetBrainsMono, + fontFamilyFallback: const [FontFamily.notoSansJP], + ), + ), + ], + ), + ), + ), + ), + ), + IntensityIconType.smallWithoutText => SizedBox( + height: size, + width: size, + child: DecoratedBox( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: bg, + border: Border.all( + color: borderColor, + width: 5, + ), + ), + ), + ), + IntensityIconType.filled => SizedBox( + height: size, + width: size, + child: DecoratedBox( + decoration: BoxDecoration( + color: bg, + // 角丸にする + borderRadius: BorderRadius.circular(size / 5), + ), + child: Center( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + if (customText != null) + Text( + customText!, + style: TextStyle( + color: fg, + fontSize: 100, + fontWeight: FontWeight.w900, + fontFamily: FontFamily.jetBrainsMono, + ), + ) + else ...[ + Text( + intensityMainText, + style: TextStyle( + color: fg, + fontSize: 100, + fontWeight: FontWeight.w900, + fontFamily: FontFamily.jetBrainsMono, + ), + ), + if (showSuffix) + Text( + intensitySubText, + style: TextStyle( + color: fg, + fontSize: 50, + fontWeight: FontWeight.w900, + fontFamily: FontFamily.jetBrainsMono, + fontFamilyFallback: const [FontFamily.notoSansJP], + ), + ), + ], + ], + ), + ), + ), + ), + ), + }; + } +} diff --git a/app/lib/core/component/intenisty/jma_intensity_icon.dart b/app/lib/core/component/intenisty/jma_intensity_icon.dart index cc5ab3777..414e253ce 100644 --- a/app/lib/core/component/intenisty/jma_intensity_icon.dart +++ b/app/lib/core/component/intenisty/jma_intensity_icon.dart @@ -66,31 +66,35 @@ class JmaIntensityIcon extends ConsumerWidget { child: (intensity == JmaIntensity.fiveUpperNoInput) ? const SizedBox.shrink() : Center( - child: FittedBox( - fit: BoxFit.scaleDown, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - intensityMainText, - style: TextStyle( - color: fg, - fontSize: 100, - fontWeight: FontWeight.w900, - fontFamily: FontFamily.jetBrainsMono, + child: Padding( + padding: const EdgeInsets.all(2), + child: FittedBox( + fit: BoxFit.scaleDown, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + intensityMainText, + style: TextStyle( + color: fg, + fontSize: 100, + fontWeight: FontWeight.bold, + fontFamily: FontFamily.jetBrainsMono, + ), ), - ), - Text( - suffix, - style: TextStyle( - color: fg, - fontSize: 80, - fontWeight: FontWeight.w900, - fontFamily: FontFamily.jetBrainsMono, - fontFamilyFallback: const [FontFamily.notoSansJP], + Text( + suffix, + style: TextStyle( + color: fg, + fontSize: 80, + fontFamily: FontFamily.jetBrainsMono, + fontFamilyFallback: const [ + FontFamily.notoSansJP, + ], + ), ), - ), - ], + ], + ), ), ), ), diff --git a/app/lib/core/provider/dio_provider.dart b/app/lib/core/provider/dio_provider.dart index 55567b119..3bf316577 100644 --- a/app/lib/core/provider/dio_provider.dart +++ b/app/lib/core/provider/dio_provider.dart @@ -20,9 +20,7 @@ Dio dio(DioRef ref) { final dio = Dio( BaseOptions( headers: { - 'user-agent': 'eqmonitor-${kIsWeb ? "web" : Platform.version}', - 'x-operation-system-version': - kIsWeb ? 'web' : Platform.operatingSystemVersion, + 'user-agent': 'eqmonitor', if (authorization != null) 'authorization': authorization, }, baseUrl: ref.watch(telegramUrlProvider).restApiUrl, diff --git a/app/lib/core/provider/map/map_style.dart b/app/lib/core/provider/map/map_style.dart index a55abb191..42c647dfa 100644 --- a/app/lib/core/provider/map/map_style.dart +++ b/app/lib/core/provider/map/map_style.dart @@ -51,7 +51,8 @@ class MapStyle { }, 'sprite': '', 'glyphs': - 'https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf', +// 'https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf', + 'https://glyphs.geolonia.com/{fontstack}/{range}.pbf', 'layers': [ { 'id': BaseLayer.background.name, diff --git a/app/lib/core/router/router.dart b/app/lib/core/router/router.dart index 34e57f4cc..8fc92c617 100644 --- a/app/lib/core/router/router.dart +++ b/app/lib/core/router/router.dart @@ -9,6 +9,7 @@ import 'package:eqmonitor/feature/donation/ui/donation_executed_screen.dart'; import 'package:eqmonitor/feature/donation/ui/donation_screen.dart'; import 'package:eqmonitor/feature/earthquake_history/ui/earthquake_history_screen.dart'; import 'package:eqmonitor/feature/earthquake_history_details/screen/earthquake_history_details.dart'; +import 'package:eqmonitor/feature/earthquake_history_early/ui/earthquake_history_early_details_screen.dart'; import 'package:eqmonitor/feature/earthquake_history_early/ui/earthquake_history_early_screen.dart'; import 'package:eqmonitor/feature/home/view/home_view.dart'; import 'package:eqmonitor/feature/information_history/page/information_history_page.dart'; @@ -141,6 +142,11 @@ class InformationHistoryDetailsRoute extends GoRouteData { routes: [ TypedGoRoute( path: 'earthquake-history-early', + routes: [ + TypedGoRoute( + path: 'details/:id', + ), + ], ), ], ) diff --git a/app/lib/core/router/router.g.dart b/app/lib/core/router/router.g.dart index d641bac54..19d195224 100644 --- a/app/lib/core/router/router.g.dart +++ b/app/lib/core/router/router.g.dart @@ -149,6 +149,12 @@ RouteBase get $homeRoute => GoRouteData.$route( GoRouteData.$route( path: 'earthquake-history-early', factory: $EarthquakeHistoryEarlyRouteExtension._fromState, + routes: [ + GoRouteData.$route( + path: 'details/:id', + factory: $EarthquakeHistoryEarlyDetailsRouteExtension._fromState, + ), + ], ), ], ); @@ -188,6 +194,27 @@ extension $EarthquakeHistoryEarlyRouteExtension on EarthquakeHistoryEarlyRoute { void replace(BuildContext context) => context.replace(location); } +extension $EarthquakeHistoryEarlyDetailsRouteExtension + on EarthquakeHistoryEarlyDetailsRoute { + static EarthquakeHistoryEarlyDetailsRoute _fromState(GoRouterState state) => + EarthquakeHistoryEarlyDetailsRoute( + id: state.pathParameters['id']!, + ); + + String get location => GoRouteData.$location( + '/earthquake-history-early/details/${Uri.encodeComponent(id)}', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); + + void replace(BuildContext context) => context.replace(location); +} + RouteBase get $talkerRoute => GoRouteData.$route( path: '/talker', factory: $TalkerRouteExtension._fromState, diff --git a/app/lib/feature/earthquake_history_details/component/earthquake_map.dart b/app/lib/feature/earthquake_history_details/component/earthquake_map.dart index 33255625c..c55f92d7f 100644 --- a/app/lib/feature/earthquake_history_details/component/earthquake_map.dart +++ b/app/lib/feature/earthquake_history_details/component/earthquake_map.dart @@ -785,16 +785,18 @@ class _StationAction extends _Action { 'station-intensity-symbol', SymbolLayerProperties( textField: ['get', 'name'], - textSize: 12, + textSize: 13, + textColor: Colors.black.toHexStringRGB(), textHaloColor: Colors.white.toHexStringRGB(), - textHaloWidth: 0.5, + textHaloWidth: 2, + textFont: ['Noto Sans CJK JP Bold'], textOffset: [ map_libre.Expressions.literal, [0, 2], ], ), sourceLayer: 'station-intensity', - minzoom: 10, + minzoom: 9, ); } diff --git a/app/lib/feature/earthquake_history_early/data/earthquake_history_early_details_notifier.dart b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_details_notifier.dart new file mode 100644 index 000000000..cbcbcc255 --- /dev/null +++ b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_details_notifier.dart @@ -0,0 +1,16 @@ +import 'package:eqapi_types/model/v1/earthquake_early.dart'; +import 'package:eqmonitor/feature/earthquake_history_early/data/earthquake_history_early_repository.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'earthquake_history_early_details_notifier.g.dart'; + +@riverpod +Future earthquakeHistoryEarlyEvent( + EarthquakeHistoryEarlyEventRef ref, + String id, +) => + ref + .watch(earthquakeHistoryEarlyRepositoryProvider) + .fetchEarthquakeEarlyEvent( + id: id, + ); diff --git a/app/lib/feature/earthquake_history_early/data/earthquake_history_early_details_notifier.g.dart b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_details_notifier.g.dart new file mode 100644 index 000000000..3ada6fe39 --- /dev/null +++ b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_details_notifier.g.dart @@ -0,0 +1,212 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ignore_for_file: type=lint, duplicate_ignore + +part of 'earthquake_history_early_details_notifier.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$earthquakeHistoryEarlyEventHash() => + r'13fa4d382824e1367de0f53cd8c9fa2a360de781'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [earthquakeHistoryEarlyEvent]. +@ProviderFor(earthquakeHistoryEarlyEvent) +const earthquakeHistoryEarlyEventProvider = EarthquakeHistoryEarlyEventFamily(); + +/// See also [earthquakeHistoryEarlyEvent]. +class EarthquakeHistoryEarlyEventFamily extends Family { + /// See also [earthquakeHistoryEarlyEvent]. + const EarthquakeHistoryEarlyEventFamily(); + + static const Iterable? _dependencies = null; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'earthquakeHistoryEarlyEventProvider'; + + /// See also [earthquakeHistoryEarlyEvent]. + EarthquakeHistoryEarlyEventProvider call( + String id, + ) { + return EarthquakeHistoryEarlyEventProvider( + id, + ); + } + + @visibleForOverriding + @override + EarthquakeHistoryEarlyEventProvider getProviderOverride( + covariant EarthquakeHistoryEarlyEventProvider provider, + ) { + return call( + provider.id, + ); + } + + /// Enables overriding the behavior of this provider, no matter the parameters. + Override overrideWith( + FutureOr Function( + EarthquakeHistoryEarlyEventRef ref) + create) { + return _$EarthquakeHistoryEarlyEventFamilyOverride(this, create); + } +} + +class _$EarthquakeHistoryEarlyEventFamilyOverride implements FamilyOverride { + _$EarthquakeHistoryEarlyEventFamilyOverride( + this.overriddenFamily, this.create); + + final FutureOr Function( + EarthquakeHistoryEarlyEventRef ref) create; + + @override + final EarthquakeHistoryEarlyEventFamily overriddenFamily; + + @override + EarthquakeHistoryEarlyEventProvider getProviderOverride( + covariant EarthquakeHistoryEarlyEventProvider provider, + ) { + return provider._copyWith(create); + } +} + +/// See also [earthquakeHistoryEarlyEvent]. +class EarthquakeHistoryEarlyEventProvider + extends AutoDisposeFutureProvider { + /// See also [earthquakeHistoryEarlyEvent]. + EarthquakeHistoryEarlyEventProvider( + String id, + ) : this._internal( + (ref) => earthquakeHistoryEarlyEvent( + ref as EarthquakeHistoryEarlyEventRef, + id, + ), + from: earthquakeHistoryEarlyEventProvider, + name: r'earthquakeHistoryEarlyEventProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') + ? null + : _$earthquakeHistoryEarlyEventHash, + dependencies: EarthquakeHistoryEarlyEventFamily._dependencies, + allTransitiveDependencies: + EarthquakeHistoryEarlyEventFamily._allTransitiveDependencies, + id: id, + ); + + EarthquakeHistoryEarlyEventProvider._internal( + super.create, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.id, + }) : super.internal(); + + final String id; + + @override + Override overrideWith( + FutureOr Function(EarthquakeHistoryEarlyEventRef ref) + create, + ) { + return ProviderOverride( + origin: this, + override: EarthquakeHistoryEarlyEventProvider._internal( + (ref) => create(ref as EarthquakeHistoryEarlyEventRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + id: id, + ), + ); + } + + @override + (String,) get argument { + return (id,); + } + + @override + AutoDisposeFutureProviderElement createElement() { + return _EarthquakeHistoryEarlyEventProviderElement(this); + } + + EarthquakeHistoryEarlyEventProvider _copyWith( + FutureOr Function(EarthquakeHistoryEarlyEventRef ref) + create, + ) { + return EarthquakeHistoryEarlyEventProvider._internal( + (ref) => create(ref as EarthquakeHistoryEarlyEventRef), + name: name, + dependencies: dependencies, + allTransitiveDependencies: allTransitiveDependencies, + debugGetCreateSourceHash: debugGetCreateSourceHash, + from: from, + id: id, + ); + } + + @override + bool operator ==(Object other) { + return other is EarthquakeHistoryEarlyEventProvider && other.id == id; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, id.hashCode); + + return _SystemHash.finish(hash); + } +} + +mixin EarthquakeHistoryEarlyEventRef + on AutoDisposeFutureProviderRef { + /// The parameter `id` of this provider. + String get id; +} + +class _EarthquakeHistoryEarlyEventProviderElement + extends AutoDisposeFutureProviderElement + with EarthquakeHistoryEarlyEventRef { + _EarthquakeHistoryEarlyEventProviderElement(super.provider); + + @override + String get id => (origin as EarthquakeHistoryEarlyEventProvider).id; +} +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, inference_failure_on_uninitialized_variable, inference_failure_on_function_return_type, inference_failure_on_untyped_parameter, deprecated_member_use_from_same_package diff --git a/app/lib/feature/earthquake_history_early/data/earthquake_history_early_notifier.g.dart b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_notifier.g.dart index df534ad1b..6dde1dc3f 100644 --- a/app/lib/feature/earthquake_history_early/data/earthquake_history_early_notifier.g.dart +++ b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_notifier.g.dart @@ -9,7 +9,7 @@ part of 'earthquake_history_early_notifier.dart'; // ************************************************************************** String _$earthquakeHistoryEarlyNotifierHash() => - r'50f31f7a9119a168ae8ede41d00902f1c17e43c3'; + r'449c1da0665f241e5f2580660255afec094bc60f'; /// Copied from Dart SDK class _SystemHash { diff --git a/app/lib/feature/earthquake_history_early/data/earthquake_history_early_repository.dart b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_repository.dart index 9575a2fde..44de593f7 100644 --- a/app/lib/feature/earthquake_history_early/data/earthquake_history_early_repository.dart +++ b/app/lib/feature/earthquake_history_early/data/earthquake_history_early_repository.dart @@ -55,4 +55,11 @@ class EarthquakeHistoryEarlyRepository { items: response.data, ); } + + Future fetchEarthquakeEarlyEvent({ + required String id, + }) async { + final result = await _api.objects.getEarthquakeEarlyEvent(id: id); + return result.data; + } } diff --git a/app/lib/feature/earthquake_history_early/ui/components/bar_sheet.dart b/app/lib/feature/earthquake_history_early/ui/components/bar_sheet.dart new file mode 100644 index 000000000..6139714d7 --- /dev/null +++ b/app/lib/feature/earthquake_history_early/ui/components/bar_sheet.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:sheet/route.dart'; + +const Radius _defaultBarTopRadius = Radius.circular(15); + +class BarBottomSheet extends StatelessWidget { + const BarBottomSheet({ + super.key, + required this.child, + this.control, + this.clipBehavior, + this.shape, + this.elevation, + }); + final Widget child; + final Widget? control; + final Clip? clipBehavior; + final double? elevation; + final ShapeBorder? shape; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 12), + SafeArea( + bottom: false, + child: control ?? + Container( + height: 6, + width: 40, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(6), + ), + ), + ), + const SizedBox(height: 8), + Flexible( + child: Material( + color: const Color.fromRGBO(1, 0, 27, 1), + shape: shape ?? + const RoundedRectangleBorder( + side: BorderSide(), + borderRadius: BorderRadius.only( + topLeft: _defaultBarTopRadius, + topRight: _defaultBarTopRadius, + ), + ), + clipBehavior: clipBehavior ?? Clip.hardEdge, + elevation: elevation ?? 2, + child: SizedBox( + width: double.infinity, + child: MediaQuery.removePadding( + context: context, + removeTop: true, + child: child, + ), + ), + ), + ), + ], + ); + } +} + +class BarSheetRoute extends SheetRoute { + BarSheetRoute({ + required WidgetBuilder builder, + double? elevation, + ShapeBorder? shape, + Clip? clipBehavior, + Color super.barrierColor = Colors.black87, + super.fit, + super.animationCurve, + bool isDismissible = true, + bool enableDrag = true, + Widget? topControl, + super.duration, + }) : super( + builder: (BuildContext context) { + return BarBottomSheet( + control: topControl, + clipBehavior: clipBehavior, + shape: shape, + elevation: elevation, + child: Builder(builder: builder), + ); + }, + barrierDismissible: isDismissible, + draggable: enableDrag, + ); +} diff --git a/app/lib/feature/earthquake_history_early/ui/components/earthquake_early_hypo_info_widget.dart b/app/lib/feature/earthquake_history_early/ui/components/earthquake_early_hypo_info_widget.dart new file mode 100644 index 000000000..a573c8890 --- /dev/null +++ b/app/lib/feature/earthquake_history_early/ui/components/earthquake_early_hypo_info_widget.dart @@ -0,0 +1,243 @@ +import 'package:eqapi_types/eqapi_types.dart'; +import 'package:eqapi_types/model/v1/earthquake_early.dart'; +import 'package:eqmonitor/core/component/intenisty/intensity_icon_type.dart'; +import 'package:eqmonitor/core/component/intenisty/jma_forecast_intensity_icon.dart'; +import 'package:eqmonitor/core/provider/config/theme/intensity_color/intensity_color_provider.dart'; +import 'package:eqmonitor/core/provider/config/theme/intensity_color/model/intensity_color_model.dart'; +import 'package:eqmonitor/gen/fonts.gen.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:intl/intl.dart'; + +class EarthquakeEarlyHypoInfoWidget extends HookConsumerWidget { + const EarthquakeEarlyHypoInfoWidget({ + super.key, + required this.item, + }); + + final EarthquakeEarlyEvent item; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final theme = Theme.of(context); + final textTheme = theme.textTheme; + final intensityColorScheme = ref.watch(intensityColorProvider); + + final maxIntensity = item.maxIntensity; + final colorScheme = switch (maxIntensity) { + final JmaForecastIntensity intensity => + intensityColorScheme.fromJmaForecastIntensity(intensity), + _ => null, + }; + + final maxIntensityWidget = maxIntensity != null + ? Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text('最大震度', style: TextStyle(fontWeight: FontWeight.bold)), + const SizedBox(height: 4), + JmaForecastIntensityIcon( + type: IntensityIconType.filled, + size: 60, + intensity: maxIntensity, + showSuffix: !item.maxIntensityIsEarly, + ), + ], + ) + : null; + + // 「MaxInt, 震源地, 規模」 + final hypoWidget = Row( + textBaseline: TextBaseline.ideographic, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.baseline, + children: [ + Text( + '震源地', + style: textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.bold, + color: textTheme.bodyMedium!.color!.withOpacity(0.8), + ), + ), + const SizedBox(width: 4), + Flexible( + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: item.name, + style: textTheme.headlineMedium!.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ], + ); + + // 地震発生時刻 + final originTime = item.originTime.toLocal(); + final timeText = switch (item.originTimePrecision) { + OriginTimePrecision.millisecond || + OriginTimePrecision.second => + DateFormat('yyyy/MM/dd HH:mm:ss ').format(originTime), + OriginTimePrecision.minute => + DateFormat('yyyy/MM/dd HH:mm ').format(originTime), + OriginTimePrecision.hour => + DateFormat('yyyy/MM/dd HH ').format(originTime), + OriginTimePrecision.day => DateFormat('yyyy/MM/dd ').format(originTime), + OriginTimePrecision.month => DateFormat('yyyy/MM ').format(originTime), + }; + final timeWidget = Text(timeText); + + // 「M 8.0 / 深さ100km」 + final magnitudeWidget = Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Text( + 'M', + style: textTheme.titleMedium!.copyWith( + color: textTheme.titleMedium!.color!.withOpacity(0.8), + ), + ), + Flexible( + child: Text( + switch (item.magnitude) { + final double value => value.toStringAsFixed(1), + // vxse53がある場合 + _ => '不明', + }, + style: textTheme.headlineLarge?.copyWith( + fontWeight: FontWeight.bold, + fontFamily: FontFamily.notoSansJP, + ), + ), + ), + ], + ); + final depthWidget = Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Text( + '深さ', + style: textTheme.titleMedium!.copyWith( + color: textTheme.titleMedium!.color!.withOpacity(0.8), + ), + ), + if (item.depth != null && item.depth != 0) ...[ + Text( + item.depth.toString(), + style: textTheme.displaySmall!.copyWith( + fontWeight: FontWeight.bold, + fontFamily: FontFamily.notoSansJP, + ), + ), + Text( + 'km', + style: textTheme.titleMedium!.copyWith( + color: textTheme.titleMedium!.color!.withOpacity(0.8), + ), + ), + ] else + Text( + switch (item.depth) { + 0 => 'ごく浅い', + _ => '不明', + }, + style: textTheme.displaySmall!.copyWith( + fontWeight: FontWeight.bold, + fontFamily: FontFamily.notoSansJP, + ), + ), + ], + ); + // M・深さ ともに不明の場合 + final isMagnitudeAndDepthUnknown = + (item.magnitude == null) && item.depth == null; + final magnitudeDepthUnknownWidget = Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Text( + 'M・深さ', + style: textTheme.titleMedium!.copyWith( + color: textTheme.titleMedium!.color!.withOpacity(0.8), + ), + ), + Text( + switch (item.depth) { + _ => '不明', + }, + style: textTheme.displaySmall!.copyWith( + fontWeight: FontWeight.w900, + fontFamily: FontFamily.jetBrainsMono, + fontFamilyFallback: [FontFamily.notoSansJP], + ), + ), + ], + ); + + final body = Wrap( + spacing: 8, + crossAxisAlignment: WrapCrossAlignment.end, + alignment: WrapAlignment.center, + children: [ + const Row(), + if (isMagnitudeAndDepthUnknown) ...[ + magnitudeDepthUnknownWidget, + hypoWidget, + ] else ...[ + magnitudeWidget, + depthWidget, + hypoWidget, + ], + timeWidget, + ], + ); + + final card = Card( + margin: const EdgeInsets.symmetric( + horizontal: 8, + ).add( + const EdgeInsets.only(bottom: 4), + ), + elevation: 0, + + shadowColor: Colors.transparent, + // 角丸にして Border + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: BorderSide( + color: colorScheme?.background ?? Colors.transparent, + width: 0, + ), + ), + color: (colorScheme?.background ?? Colors.transparent).withOpacity(0.3), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Column( + children: [ + Row( + children: [ + if (maxIntensityWidget != null) maxIntensityWidget, + const SizedBox(width: 4), + Expanded(child: body), + ], + ), + ], + ), + ), + ); + return card; + } +} diff --git a/app/lib/feature/earthquake_history_early/ui/components/earthquake_early_map.dart b/app/lib/feature/earthquake_history_early/ui/components/earthquake_early_map.dart new file mode 100644 index 000000000..091542661 --- /dev/null +++ b/app/lib/feature/earthquake_history_early/ui/components/earthquake_early_map.dart @@ -0,0 +1,476 @@ +// ignore_for_file: lines_longer_than_80_chars + +import 'dart:async'; + +import 'package:collection/collection.dart'; +import 'package:eqapi_types/eqapi_types.dart'; +import 'package:eqapi_types/model/v1/earthquake_early.dart'; +import 'package:eqmonitor/core/provider/capture/intensity_icon_render.dart'; +import 'package:eqmonitor/core/provider/config/earthquake_history/earthquake_history_config_provider.dart'; +import 'package:eqmonitor/core/provider/config/earthquake_history/model/earthquake_history_config_model.dart'; +import 'package:eqmonitor/core/provider/config/theme/intensity_color/intensity_color_provider.dart'; +import 'package:eqmonitor/core/provider/config/theme/intensity_color/model/intensity_color_model.dart'; +import 'package:eqmonitor/core/provider/jma_parameter/jma_parameter.dart'; +import 'package:eqmonitor/core/provider/map/jma_map_provider.dart'; +import 'package:eqmonitor/core/provider/map/map_style.dart'; +import 'package:extensions/extensions.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:maplibre_gl/maplibre_gl.dart' as map_libre; +import 'package:maplibre_gl/maplibre_gl.dart'; + +class EarthquakeEarlyMapWidget extends HookConsumerWidget { + const EarthquakeEarlyMapWidget({ + required this.item, + required this.showIntensityIcon, + required this.registerNavigateToHome, + super.key, + }); + + final EarthquakeEarlyEvent item; + final bool showIntensityIcon; + final void Function(void Function() func) registerNavigateToHome; + + Future addImageFromAsset( + MapLibreMapController controller, + String name, + String assetName, + ) async { + final bytes = await rootBundle.load(assetName); + final list = bytes.buffer.asUint8List(); + return controller.addImage(name, list); + } + + Future addImageFromBuffer( + MapLibreMapController controller, + String name, + Uint8List buffer, + ) => + controller.addImage(name, buffer); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final colorModel = ref.watch(intensityColorProvider); + final earthquakeParams = + ref.watch(jmaParameterProvider).valueOrNull?.earthquake; + final intensityIconData = ref.watch(intensityIconRenderProvider); + final intensityIconFillData = ref.watch(intensityIconFillRenderProvider); + final lpgmIntensityIconData = ref.watch(lpgmIntensityIconRenderProvider); + final lpgmIntensityIconFillData = + ref.watch(lpgmIntensityIconFillRenderProvider); + + final hypocenterIconRender = ref.watch(hypocenterIconRenderProvider); + final jmaMap = ref.watch(jmaMapProvider).valueOrNull; + final mapStyle = ref.watch(mapStyleProvider); + + final isDark = Theme.of(context).brightness == Brightness.dark; + final styleJsonFutureing = useMemoized( + () => mapStyle.getStyle( + isDark: isDark, + scheme: Theme.of(context).colorScheme, + ), + [isDark], + ); + final styleJsonFuture = useFuture(styleJsonFutureing); + final path = styleJsonFuture.data; + + if (earthquakeParams == null || + !intensityIconData.isAllRendered() || + !intensityIconFillData.isAllRendered() || + !lpgmIntensityIconData.isAllRendered() || + !lpgmIntensityIconFillData.isAllRendered() || + jmaMap == null || + hypocenterIconRender == null || + path == null) { + // どれが条件を満たしていないのか表示 + return const Scaffold( + body: Center( + child: CircularProgressIndicator.adaptive(), + ), + ); + } + + final mapController = useState(null); + + final cameraUpdate = useMemoized( + () { + final (latitude, longitude) = (item.lat, item.lon); + if (latitude != null && longitude != null) { + return CameraUpdate.newLatLngZoom( + map_libre.LatLng(latitude, longitude), + 2, + ); + } else { + return CameraUpdate.newLatLngZoom( + const map_libre.LatLng(35, 139), + 6, + ); + } + }, + [item], + ); + + final stationsItem = useMemoized( + () { + final points = + item.cities.map((city) => city.observationPoints).flattened; + return ( + points.groupListsBy((element) => element.intensity), + points.length + ); + }, + [item.cities], + ); + + // * Display mode related + List<_Action> getActions(EarthquakeHistoryDetailConfig config) => [ + _HypocenterAction( + earthquake: item, + ), + ...[ + _StationAction( + stations: stationsItem.$1, + showSmallIcon: stationsItem.$2 < 100, + colorModel: colorModel, + ), + ], + ]; + final config = ref.watch( + earthquakeHistoryConfigProvider.select((value) => value.detail), + ); + final currentActions = useState>(getActions(config)); + + Future disposeActions(List<_Action> actions) async { + for (final action in actions) { + await action.dispose(mapController.value!); + } + } + + Future initActions(List<_Action> actions) async { + await actions + .map>( + (e) => e.init(mapController.value!), + ) + .wait; + } + + Future onDisplayModeChanged({ + required map_libre.MapLibreMapController controller, + required EarthquakeHistoryDetailConfig config, + }) async { + // まずはdispose + await disposeActions(currentActions.value); + // 次にinit + final actions = getActions(config); + + // 状態更新 + currentActions.value = actions; + await initActions(actions); + } + + ref.listen( + earthquakeHistoryConfigProvider.select((v) => v.detail), + (_, next) async => onDisplayModeChanged( + controller: mapController.value!, + config: next, + ), + ); + + useEffect( + () { + WidgetsBinding.instance.endOfFrame.then( + (_) { + registerNavigateToHome(() { + final controller = mapController.value; + if (controller == null) { + return; + } + controller.animateCamera( + cameraUpdate, + ); + }); + final controller = mapController.value; + if (controller == null) { + return; + } + onDisplayModeChanged( + controller: mapController.value!, + config: config, + ); + }, + ); + return null; + }, + [item], + ); + final maxZoomLevel = useState(6); + + return RepaintBoundary( + child: MapLibreMap( + initialCameraPosition: CameraPosition( + target: map_libre.LatLng( + item.lat ?? 35, + item.lon ?? 139, + ), + zoom: 7, + ), + styleString: path, + minMaxZoomPreference: MinMaxZoomPreference(0, maxZoomLevel.value), + onMapCreated: (controller) => mapController.value = controller, + onStyleLoadedCallback: () async { + final controller = mapController.value!; + await [ + addImageFromBuffer( + controller, + 'hypocenter', + hypocenterIconRender, + ), + for (final intensity in JmaIntensity.values) ...[ + addImageFromBuffer( + controller, + 'intensity-${intensity.type}', + intensityIconData.getOrNull(intensity)!, + ), + addImageFromBuffer( + controller, + 'intensity-${intensity.type}-fill', + intensityIconFillData.getOrNull(intensity)!, + ), + ], + for (final intensity in JmaLgIntensity.values) ...[ + addImageFromBuffer( + controller, + 'lpgm-intensity-${intensity.type}', + lpgmIntensityIconData.getOrNull(intensity)!, + ), + addImageFromBuffer( + controller, + 'lpgm-intensity-${intensity.type}-fill', + lpgmIntensityIconFillData.getOrNull(intensity)!, + ), + ], + ].wait; + await initActions(currentActions.value); + await controller.moveCamera(cameraUpdate); + maxZoomLevel.value = 12; + }, + rotateGesturesEnabled: false, + tiltGesturesEnabled: false, + ), + ); + } +} + +sealed class _Action { + Future init(map_libre.MapLibreMapController controller); + Future dispose(map_libre.MapLibreMapController controller); +} + +class _StationAction extends _Action { + _StationAction({ + required this.stations, + required this.colorModel, + required this.showSmallIcon, + }); + + final Map> + stations; + final IntensityColorModel colorModel; + final bool showSmallIcon; + + @override + Future init( + map_libre.MapLibreMapController controller, + ) async { + await dispose(controller); + await controller.setSymbolIconAllowOverlap(true); + await controller.setSymbolIconIgnorePlacement(true); + await controller.addGeoJsonSource( + 'station-intensity', + { + 'type': 'FeatureCollection', + 'features': stations.entries + .map((e) { + final color = e.key == null + ? const TextColorModel( + background: Color(0x00000000), + foreground: Color(0x00000000), + ) + : colorModel.fromJmaForecastIntensity(e.key!); + return e.value.map( + (point) => { + 'type': 'Feature', + 'geometry': { + 'type': 'Point', + 'coordinates': [ + point.lon, + point.lat, + ], + }, + 'properties': { + 'color': color.background.toHexStringRGB(), + 'intensity': e.key?.type, + 'name': point.name, + }, + }, + ); + }) + .flattened + .toList(), + }, + ); + for (final intensity in JmaIntensity.values) { + await controller.addLayer( + 'station-intensity', + 'station-intensity-${intensity.type}', + SymbolLayerProperties( + iconImage: 'intensity-${intensity.type}', + iconSize: [ + 'interpolate', + ['linear'], + ['zoom'], + 3, + 0.2, + 20, + 1, + ], + textAllowOverlap: true, + iconAllowOverlap: true, + ), + filter: [ + '==', + 'intensity', + intensity.type, + ], + sourceLayer: 'station-intensity', + minzoom: 7, + ); + + await controller.addLayer( + 'station-intensity', + 'station-intensity-${intensity.type}-circle', + SymbolLayerProperties( + iconImage: 'intensity-${intensity.type}-fill', + iconSize: [ + 'interpolate', + ['linear'], + ['zoom'], + 3, + 0.04, + 7, + 0.3, + ], + textAllowOverlap: true, + iconAllowOverlap: true, + ), + maxzoom: 7, + filter: [ + '==', + 'intensity', + intensity.type, + ], + sourceLayer: 'station-intensity', + belowLayerId: 'hypocenter', + ); + } + + await controller.addSymbolLayer( + 'station-intensity', + 'station-intensity-symbol', + SymbolLayerProperties( + textField: ['get', 'name'], + textSize: 13, + textColor: Colors.black.toHexStringRGB(), + textHaloColor: Colors.white.toHexStringRGB(), + textHaloWidth: 2, + textFont: ['Noto Sans CJK JP Bold'], + textOffset: [ + map_libre.Expressions.literal, + [0, 2], + ], + ), + sourceLayer: 'station-intensity', + minzoom: 9, + ); + } + + @override + Future dispose(map_libre.MapLibreMapController controller) async { + // Layer + await [ + for (final intensity in JmaIntensity.values) + controller.removeLayer('station-intensity-${intensity.type}'), + for (final intensity in JmaIntensity.values) + controller.removeLayer('station-intensity-${intensity.type}-circle'), + controller.removeLayer('station-intensity-symbol'), + ].wait; + // Source + await controller.removeSource('station-intensity'); + } +} + +class _HypocenterAction extends _Action { + _HypocenterAction({ + required this.earthquake, + }); + + final EarthquakeEarlyEvent earthquake; + + @override + Future init(map_libre.MapLibreMapController controller) async { + final (latitude, longitude) = (earthquake.lat, earthquake.lon); + if (latitude != null && longitude != null) { + await controller.setSymbolIconAllowOverlap(true); + await controller.setSymbolIconIgnorePlacement(true); + await controller.addGeoJsonSource('hypocenter', { + 'type': 'FeatureCollection', + 'features': [ + { + 'type': 'Feature', + 'geometry': { + 'type': 'Point', + 'coordinates': [longitude, latitude], + }, + 'properties': { + 'magnitude': earthquake.magnitude?.toString(), + }, + } + ], + }); + await controller.addSymbolLayer( + 'hypocenter', + 'hypocenter', + const SymbolLayerProperties( + iconImage: 'hypocenter', + iconSize: [ + 'interpolate', + ['linear'], + ['zoom'], + 3, + 0.3, + 20, + 1, + ], + iconOpacity: [ + 'interpolate', + ['linear'], + ['zoom'], + 6, + 1.0, + 10, + 0.8, + ], + iconAllowOverlap: true, + ), + ); + } + } + + @override + Future dispose(map_libre.MapLibreMapController controller) async { + await controller.removeLayer('hypocenter'); + await controller.removeSource('hypocenter'); + } +} diff --git a/app/lib/feature/earthquake_history_early/ui/components/earthquake_history_early_list_tile.dart b/app/lib/feature/earthquake_history_early/ui/components/earthquake_history_early_list_tile.dart index 02a345333..f00e8be3a 100644 --- a/app/lib/feature/earthquake_history_early/ui/components/earthquake_history_early_list_tile.dart +++ b/app/lib/feature/earthquake_history_early/ui/components/earthquake_history_early_list_tile.dart @@ -1,7 +1,7 @@ import 'package:eqapi_types/eqapi_types.dart'; import 'package:eqapi_types/model/v1/earthquake_early.dart'; import 'package:eqmonitor/core/component/intenisty/intensity_icon_type.dart'; -import 'package:eqmonitor/core/component/intenisty/jma_intensity_icon.dart'; +import 'package:eqmonitor/core/component/intenisty/jma_forecast_intensity_icon.dart'; import 'package:eqmonitor/core/provider/config/theme/intensity_color/intensity_color_provider.dart'; import 'package:eqmonitor/core/provider/config/theme/intensity_color/model/intensity_color_model.dart'; import 'package:flutter/material.dart'; @@ -34,7 +34,7 @@ class EarthquakeHistoryEarlyListTile extends HookConsumerWidget { )) { ( final String hypoName, - final JmaIntensity _, + final JmaForecastIntensity _, ) => hypoName, ( @@ -65,7 +65,7 @@ class EarthquakeHistoryEarlyListTile extends HookConsumerWidget { }; final intensityColorState = ref.watch(intensityColorProvider); final intensityColor = maxIntensity != null - ? intensityColorState.fromJmaIntensity(maxIntensity).background + ? intensityColorState.fromJmaForecastIntensity(maxIntensity).background : null; // 5 -> 5.0, 5.123 -> 5.1 final magnitude = item.magnitude?.toStringAsFixed(1); @@ -94,7 +94,7 @@ class EarthquakeHistoryEarlyListTile extends HookConsumerWidget { ], ), leading: maxIntensity != null - ? JmaIntensityIcon( + ? JmaForecastIntensityIcon( intensity: maxIntensity, type: IntensityIconType.filled, showSuffix: !item.maxIntensityIsEarly, diff --git a/app/lib/feature/earthquake_history_early/ui/earthquake_history_early_details_screen.dart b/app/lib/feature/earthquake_history_early/ui/earthquake_history_early_details_screen.dart new file mode 100644 index 000000000..3c8dae3fd --- /dev/null +++ b/app/lib/feature/earthquake_history_early/ui/earthquake_history_early_details_screen.dart @@ -0,0 +1,195 @@ +import 'dart:developer'; + +import 'package:eqapi_types/eqapi_types.dart'; +import 'package:eqapi_types/model/v1/earthquake_early.dart'; +import 'package:eqmonitor/core/component/container/bordered_container.dart'; +import 'package:eqmonitor/core/component/intenisty/intensity_icon_type.dart'; +import 'package:eqmonitor/core/component/intenisty/jma_forecast_intensity_icon.dart'; +import 'package:eqmonitor/core/component/sheet/basic_modal_sheet.dart'; +import 'package:eqmonitor/core/component/sheet/sheet_floating_action_buttons.dart'; +import 'package:eqmonitor/feature/earthquake_history_early/data/earthquake_history_early_details_notifier.dart'; +import 'package:eqmonitor/feature/earthquake_history_early/ui/components/earthquake_early_hypo_info_widget.dart'; +import 'package:eqmonitor/feature/earthquake_history_early/ui/components/earthquake_early_map.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:sheet/sheet.dart'; + +class EarthquakeHistoryEarlyDetailsRoute extends GoRouteData { + const EarthquakeHistoryEarlyDetailsRoute({ + required this.id, + }); + + final String id; + + @override + Widget build(BuildContext context, GoRouterState state) { + return EarthquakeHistoryEarlyDetailsScreen( + id: id, + ); + } +} + +class EarthquakeHistoryEarlyDetailsScreen extends HookConsumerWidget { + const EarthquakeHistoryEarlyDetailsScreen({ + required this.id, + super.key, + }); + + final String id; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final sheetController = SheetController(); + final navigateToHomeFunction = useState(null); + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + + final state = ref.watch(earthquakeHistoryEarlyEventProvider(id)); + return switch (state) { + AsyncError(:final error) => Scaffold( + appBar: AppBar(), + body: Center( + child: Text('Error: $error'), + ), + ), + AsyncLoading() => Scaffold( + appBar: AppBar(), + body: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const CircularProgressIndicator.adaptive(), + const SizedBox(height: 8), + Text( + '各地の震度データを取得中...', + style: Theme.of(context).textTheme.titleSmall?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + AsyncData(:final value) => Scaffold( + body: Stack( + children: [ + EarthquakeEarlyMapWidget( + item: value, + showIntensityIcon: true, + registerNavigateToHome: (func) { + log('registerNavigateToHome'); + }, + ), + + IgnorePointer( + child: SafeArea( + child: Align( + alignment: Alignment.topRight, + child: Padding( + padding: const EdgeInsets.all(8), + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 250), + child: BorderedContainer( + margin: const EdgeInsets.all(4), + padding: const EdgeInsets.all(4), + borderRadius: BorderRadius.circular((25 / 5) + 5), + child: Wrap( + spacing: 8, + runSpacing: 8, + children: [ + for (final intensity in [ + ...JmaForecastIntensity.values, + ].where( + (e) => e <= value.maxIntensity!, + )) + JmaForecastIntensityIcon( + type: IntensityIconType.filled, + intensity: intensity, + size: 25, + ), + ], + ), + ), + ), + ), + ), + ), + ), + SheetFloatingActionButtons( + hasAppBar: false, + controller: sheetController, + fab: [ + Column( + children: [ + FloatingActionButton.small( + heroTag: 'earthquake_history_details_fab', + tooltip: '表示領域を地図に合わせる', + onPressed: () { + if (navigateToHomeFunction.value != null) { + navigateToHomeFunction.value!.call(); + } + }, + elevation: 4, + child: const Icon(Icons.home), + ), + ], + ), + ], + ), + // Sheet + _Sheet( + sheetController: sheetController, + item: value, + ), + if (Navigator.canPop(context)) + // 戻るボタン + SafeArea( + child: IconButton.filledTonal( + style: ButtonStyle( + shape: WidgetStatePropertyAll( + RoundedRectangleBorder( + side: BorderSide( + color: colorScheme.primary.withOpacity(0.2), + ), + borderRadius: BorderRadius.circular(128), + ), + ), + ), + icon: const Icon(Icons.arrow_back), + onPressed: () => context.pop(), + color: colorScheme.primary, + ), + ), + ], + ), + ), + }; + } +} + +class _Sheet extends StatelessWidget { + const _Sheet({ + required this.sheetController, + required this.item, + }); + + final SheetController sheetController; + final EarthquakeEarlyEvent item; + + @override + Widget build(BuildContext context) { + return SafeArea( + bottom: false, + child: BasicModalSheet( + hasAppBar: false, + controller: sheetController, + children: [ + EarthquakeEarlyHypoInfoWidget(item: item), + const Divider(), + ], + ), + ); + } +} diff --git a/app/lib/feature/earthquake_history_early/ui/earthquake_history_early_screen.dart b/app/lib/feature/earthquake_history_early/ui/earthquake_history_early_screen.dart index 35a27f838..69ef7e952 100644 --- a/app/lib/feature/earthquake_history_early/ui/earthquake_history_early_screen.dart +++ b/app/lib/feature/earthquake_history_early/ui/earthquake_history_early_screen.dart @@ -5,11 +5,13 @@ import 'package:eqmonitor/core/component/chip/depth_filter_chip.dart'; import 'package:eqmonitor/core/component/chip/intensity_filter_chip.dart'; import 'package:eqmonitor/core/component/chip/magnitude_filter_chip.dart'; import 'package:eqmonitor/core/component/widget/error_widget.dart'; +import 'package:eqmonitor/core/router/router.dart'; import 'package:eqmonitor/feature/earthquake_history_early/data/earthquake_history_early_notifier.dart'; import 'package:eqmonitor/feature/earthquake_history_early/data/model/earthquake_history_early_parameter.dart'; import 'package:eqmonitor/feature/earthquake_history_early/ui/components/chip/earthquake_history_early_sort_chip.dart'; import 'package:eqmonitor/feature/earthquake_history_early/ui/components/earthquake_history_early_list_tile.dart'; import 'package:eqmonitor/feature/earthquake_history_early/ui/components/earthquake_history_early_not_found.dart'; +import 'package:eqmonitor/feature/earthquake_history_early/ui/earthquake_history_early_details_screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; @@ -209,6 +211,9 @@ class _SliverListBody extends HookConsumerWidget { final item = data.$1[index]; return EarthquakeHistoryEarlyListTile( item: item, + onTap: () async => EarthquakeHistoryEarlyDetailsRoute( + id: item.id, + ).push(context), ); }, ), diff --git a/packages/eqapi_client/lib/src/children/objects.dart b/packages/eqapi_client/lib/src/children/objects.dart index 79e86b237..4436d54d6 100644 --- a/packages/eqapi_client/lib/src/children/objects.dart +++ b/packages/eqapi_client/lib/src/children/objects.dart @@ -8,7 +8,7 @@ part 'objects.g.dart'; abstract class Objects { factory Objects(Dio dio, {String baseUrl}) = _Objects; - @GET('/earthquake-early/{id},json') + @GET('/earthquake-early/{id}.json') Future> getEarthquakeEarlyEvent({ @Path('id') required String id, }); diff --git a/packages/eqapi_client/lib/src/children/objects.g.dart b/packages/eqapi_client/lib/src/children/objects.g.dart index cf8a109d6..ca16bc0a2 100644 --- a/packages/eqapi_client/lib/src/children/objects.g.dart +++ b/packages/eqapi_client/lib/src/children/objects.g.dart @@ -35,7 +35,7 @@ class _Objects implements Objects { ) .compose( _dio.options, - '/earthquake-early/${id},json', + '/earthquake-early/${id}.json', queryParameters: queryParameters, data: _data, ) diff --git a/packages/eqapi_types/lib/model/v1/earthquake_early.dart b/packages/eqapi_types/lib/model/v1/earthquake_early.dart index f1c4b9e15..2ded3b1d8 100644 --- a/packages/eqapi_types/lib/model/v1/earthquake_early.dart +++ b/packages/eqapi_types/lib/model/v1/earthquake_early.dart @@ -12,7 +12,7 @@ class EarthquakeEarly with _$EarthquakeEarly { required double? latitude, required double? longitude, required double? magnitude, - required JmaIntensity? maxIntensity, + required JmaForecastIntensity? maxIntensity, required bool maxIntensityIsEarly, required String name, required DateTime originTime, @@ -38,14 +38,16 @@ class EarthquakeEarlyEvent with _$EarthquakeEarlyEvent { const factory EarthquakeEarlyEvent({ required String id, required String name, - required double? latitude, - required double? longitude, + required double? lat, + required double? lon, required double? depth, required double? magnitude, required DateTime originTime, required OriginTimePrecision originTimePrecision, - required JmaIntensity? maxIntensity, + required JmaForecastIntensity? maxIntensity, + required bool maxIntensityIsEarly, required List regions, + required List cities, }) = _EarthquakeEarlyEvent; factory EarthquakeEarlyEvent.fromJson(Map json) => @@ -56,9 +58,8 @@ class EarthquakeEarlyEvent with _$EarthquakeEarlyEvent { class EarthquakeEarlyRegion with _$EarthquakeEarlyRegion { const factory EarthquakeEarlyRegion({ required String name, - required int code, - required JmaIntensity maxIntensity, - required List cities, + required String code, + required JmaForecastIntensity maxIntensity, }) = _EarthquakeEarlyRegion; factory EarthquakeEarlyRegion.fromJson(Map json) => @@ -69,8 +70,8 @@ class EarthquakeEarlyRegion with _$EarthquakeEarlyRegion { class EarthquakeEarlyCity with _$EarthquakeEarlyCity { const factory EarthquakeEarlyCity({ required String name, - required int code, - required JmaIntensity maxIntensity, + required String code, + required JmaForecastIntensity maxIntensity, required List observationPoints, }) = _EarthquakeEarlyCity; @@ -82,9 +83,9 @@ class EarthquakeEarlyCity with _$EarthquakeEarlyCity { class EarthquakeEarlyObservationPoint with _$EarthquakeEarlyObservationPoint { const factory EarthquakeEarlyObservationPoint({ required String name, - required double latitude, - required double longitude, - required JmaIntensity intensity, + required double lat, + required double lon, + required JmaForecastIntensity intensity, }) = _EarthquakeEarlyObservationPoint; factory EarthquakeEarlyObservationPoint.fromJson(Map json) => diff --git a/packages/eqapi_types/lib/model/v1/earthquake_early.freezed.dart b/packages/eqapi_types/lib/model/v1/earthquake_early.freezed.dart index ed17901d4..87fbfa2c3 100644 --- a/packages/eqapi_types/lib/model/v1/earthquake_early.freezed.dart +++ b/packages/eqapi_types/lib/model/v1/earthquake_early.freezed.dart @@ -25,7 +25,7 @@ mixin _$EarthquakeEarly { double? get latitude => throw _privateConstructorUsedError; double? get longitude => throw _privateConstructorUsedError; double? get magnitude => throw _privateConstructorUsedError; - JmaIntensity? get maxIntensity => throw _privateConstructorUsedError; + JmaForecastIntensity? get maxIntensity => throw _privateConstructorUsedError; bool get maxIntensityIsEarly => throw _privateConstructorUsedError; String get name => throw _privateConstructorUsedError; DateTime get originTime => throw _privateConstructorUsedError; @@ -50,7 +50,7 @@ abstract class $EarthquakeEarlyCopyWith<$Res> { double? latitude, double? longitude, double? magnitude, - JmaIntensity? maxIntensity, + JmaForecastIntensity? maxIntensity, bool maxIntensityIsEarly, String name, DateTime originTime, @@ -105,7 +105,7 @@ class _$EarthquakeEarlyCopyWithImpl<$Res, $Val extends EarthquakeEarly> maxIntensity: freezed == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity?, + as JmaForecastIntensity?, maxIntensityIsEarly: null == maxIntensityIsEarly ? _value.maxIntensityIsEarly : maxIntensityIsEarly // ignore: cast_nullable_to_non_nullable @@ -140,7 +140,7 @@ abstract class _$$EarthquakeEarlyImplCopyWith<$Res> double? latitude, double? longitude, double? magnitude, - JmaIntensity? maxIntensity, + JmaForecastIntensity? maxIntensity, bool maxIntensityIsEarly, String name, DateTime originTime, @@ -193,7 +193,7 @@ class __$$EarthquakeEarlyImplCopyWithImpl<$Res> maxIntensity: freezed == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity?, + as JmaForecastIntensity?, maxIntensityIsEarly: null == maxIntensityIsEarly ? _value.maxIntensityIsEarly : maxIntensityIsEarly // ignore: cast_nullable_to_non_nullable @@ -243,7 +243,7 @@ class _$EarthquakeEarlyImpl implements _EarthquakeEarly { @override final double? magnitude; @override - final JmaIntensity? maxIntensity; + final JmaForecastIntensity? maxIntensity; @override final bool maxIntensityIsEarly; @override @@ -319,7 +319,7 @@ abstract class _EarthquakeEarly implements EarthquakeEarly { required final double? latitude, required final double? longitude, required final double? magnitude, - required final JmaIntensity? maxIntensity, + required final JmaForecastIntensity? maxIntensity, required final bool maxIntensityIsEarly, required final String name, required final DateTime originTime, @@ -340,7 +340,7 @@ abstract class _EarthquakeEarly implements EarthquakeEarly { @override double? get magnitude; @override - JmaIntensity? get maxIntensity; + JmaForecastIntensity? get maxIntensity; @override bool get maxIntensityIsEarly; @override @@ -363,15 +363,17 @@ EarthquakeEarlyEvent _$EarthquakeEarlyEventFromJson(Map json) { mixin _$EarthquakeEarlyEvent { String get id => throw _privateConstructorUsedError; String get name => throw _privateConstructorUsedError; - double? get latitude => throw _privateConstructorUsedError; - double? get longitude => throw _privateConstructorUsedError; + double? get lat => throw _privateConstructorUsedError; + double? get lon => throw _privateConstructorUsedError; double? get depth => throw _privateConstructorUsedError; double? get magnitude => throw _privateConstructorUsedError; DateTime get originTime => throw _privateConstructorUsedError; OriginTimePrecision get originTimePrecision => throw _privateConstructorUsedError; - JmaIntensity? get maxIntensity => throw _privateConstructorUsedError; + JmaForecastIntensity? get maxIntensity => throw _privateConstructorUsedError; + bool get maxIntensityIsEarly => throw _privateConstructorUsedError; List get regions => throw _privateConstructorUsedError; + List get cities => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -388,14 +390,16 @@ abstract class $EarthquakeEarlyEventCopyWith<$Res> { $Res call( {String id, String name, - double? latitude, - double? longitude, + double? lat, + double? lon, double? depth, double? magnitude, DateTime originTime, OriginTimePrecision originTimePrecision, - JmaIntensity? maxIntensity, - List regions}); + JmaForecastIntensity? maxIntensity, + bool maxIntensityIsEarly, + List regions, + List cities}); } /// @nodoc @@ -414,14 +418,16 @@ class _$EarthquakeEarlyEventCopyWithImpl<$Res, $Res call({ Object? id = null, Object? name = null, - Object? latitude = freezed, - Object? longitude = freezed, + Object? lat = freezed, + Object? lon = freezed, Object? depth = freezed, Object? magnitude = freezed, Object? originTime = null, Object? originTimePrecision = null, Object? maxIntensity = freezed, + Object? maxIntensityIsEarly = null, Object? regions = null, + Object? cities = null, }) { return _then(_value.copyWith( id: null == id @@ -432,13 +438,13 @@ class _$EarthquakeEarlyEventCopyWithImpl<$Res, ? _value.name : name // ignore: cast_nullable_to_non_nullable as String, - latitude: freezed == latitude - ? _value.latitude - : latitude // ignore: cast_nullable_to_non_nullable + lat: freezed == lat + ? _value.lat + : lat // ignore: cast_nullable_to_non_nullable as double?, - longitude: freezed == longitude - ? _value.longitude - : longitude // ignore: cast_nullable_to_non_nullable + lon: freezed == lon + ? _value.lon + : lon // ignore: cast_nullable_to_non_nullable as double?, depth: freezed == depth ? _value.depth @@ -459,11 +465,19 @@ class _$EarthquakeEarlyEventCopyWithImpl<$Res, maxIntensity: freezed == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity?, + as JmaForecastIntensity?, + maxIntensityIsEarly: null == maxIntensityIsEarly + ? _value.maxIntensityIsEarly + : maxIntensityIsEarly // ignore: cast_nullable_to_non_nullable + as bool, regions: null == regions ? _value.regions : regions // ignore: cast_nullable_to_non_nullable as List, + cities: null == cities + ? _value.cities + : cities // ignore: cast_nullable_to_non_nullable + as List, ) as $Val); } } @@ -479,14 +493,16 @@ abstract class _$$EarthquakeEarlyEventImplCopyWith<$Res> $Res call( {String id, String name, - double? latitude, - double? longitude, + double? lat, + double? lon, double? depth, double? magnitude, DateTime originTime, OriginTimePrecision originTimePrecision, - JmaIntensity? maxIntensity, - List regions}); + JmaForecastIntensity? maxIntensity, + bool maxIntensityIsEarly, + List regions, + List cities}); } /// @nodoc @@ -502,14 +518,16 @@ class __$$EarthquakeEarlyEventImplCopyWithImpl<$Res> $Res call({ Object? id = null, Object? name = null, - Object? latitude = freezed, - Object? longitude = freezed, + Object? lat = freezed, + Object? lon = freezed, Object? depth = freezed, Object? magnitude = freezed, Object? originTime = null, Object? originTimePrecision = null, Object? maxIntensity = freezed, + Object? maxIntensityIsEarly = null, Object? regions = null, + Object? cities = null, }) { return _then(_$EarthquakeEarlyEventImpl( id: null == id @@ -520,13 +538,13 @@ class __$$EarthquakeEarlyEventImplCopyWithImpl<$Res> ? _value.name : name // ignore: cast_nullable_to_non_nullable as String, - latitude: freezed == latitude - ? _value.latitude - : latitude // ignore: cast_nullable_to_non_nullable + lat: freezed == lat + ? _value.lat + : lat // ignore: cast_nullable_to_non_nullable as double?, - longitude: freezed == longitude - ? _value.longitude - : longitude // ignore: cast_nullable_to_non_nullable + lon: freezed == lon + ? _value.lon + : lon // ignore: cast_nullable_to_non_nullable as double?, depth: freezed == depth ? _value.depth @@ -547,11 +565,19 @@ class __$$EarthquakeEarlyEventImplCopyWithImpl<$Res> maxIntensity: freezed == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity?, + as JmaForecastIntensity?, + maxIntensityIsEarly: null == maxIntensityIsEarly + ? _value.maxIntensityIsEarly + : maxIntensityIsEarly // ignore: cast_nullable_to_non_nullable + as bool, regions: null == regions ? _value._regions : regions // ignore: cast_nullable_to_non_nullable as List, + cities: null == cities + ? _value._cities + : cities // ignore: cast_nullable_to_non_nullable + as List, )); } } @@ -562,15 +588,18 @@ class _$EarthquakeEarlyEventImpl implements _EarthquakeEarlyEvent { const _$EarthquakeEarlyEventImpl( {required this.id, required this.name, - required this.latitude, - required this.longitude, + required this.lat, + required this.lon, required this.depth, required this.magnitude, required this.originTime, required this.originTimePrecision, required this.maxIntensity, - required final List regions}) - : _regions = regions; + required this.maxIntensityIsEarly, + required final List regions, + required final List cities}) + : _regions = regions, + _cities = cities; factory _$EarthquakeEarlyEventImpl.fromJson(Map json) => _$$EarthquakeEarlyEventImplFromJson(json); @@ -580,9 +609,9 @@ class _$EarthquakeEarlyEventImpl implements _EarthquakeEarlyEvent { @override final String name; @override - final double? latitude; + final double? lat; @override - final double? longitude; + final double? lon; @override final double? depth; @override @@ -592,7 +621,9 @@ class _$EarthquakeEarlyEventImpl implements _EarthquakeEarlyEvent { @override final OriginTimePrecision originTimePrecision; @override - final JmaIntensity? maxIntensity; + final JmaForecastIntensity? maxIntensity; + @override + final bool maxIntensityIsEarly; final List _regions; @override List get regions { @@ -601,9 +632,17 @@ class _$EarthquakeEarlyEventImpl implements _EarthquakeEarlyEvent { return EqualUnmodifiableListView(_regions); } + final List _cities; + @override + List get cities { + if (_cities is EqualUnmodifiableListView) return _cities; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_cities); + } + @override String toString() { - return 'EarthquakeEarlyEvent(id: $id, name: $name, latitude: $latitude, longitude: $longitude, depth: $depth, magnitude: $magnitude, originTime: $originTime, originTimePrecision: $originTimePrecision, maxIntensity: $maxIntensity, regions: $regions)'; + return 'EarthquakeEarlyEvent(id: $id, name: $name, lat: $lat, lon: $lon, depth: $depth, magnitude: $magnitude, originTime: $originTime, originTimePrecision: $originTimePrecision, maxIntensity: $maxIntensity, maxIntensityIsEarly: $maxIntensityIsEarly, regions: $regions, cities: $cities)'; } @override @@ -613,10 +652,8 @@ class _$EarthquakeEarlyEventImpl implements _EarthquakeEarlyEvent { other is _$EarthquakeEarlyEventImpl && (identical(other.id, id) || other.id == id) && (identical(other.name, name) || other.name == name) && - (identical(other.latitude, latitude) || - other.latitude == latitude) && - (identical(other.longitude, longitude) || - other.longitude == longitude) && + (identical(other.lat, lat) || other.lat == lat) && + (identical(other.lon, lon) || other.lon == lon) && (identical(other.depth, depth) || other.depth == depth) && (identical(other.magnitude, magnitude) || other.magnitude == magnitude) && @@ -626,7 +663,10 @@ class _$EarthquakeEarlyEventImpl implements _EarthquakeEarlyEvent { other.originTimePrecision == originTimePrecision) && (identical(other.maxIntensity, maxIntensity) || other.maxIntensity == maxIntensity) && - const DeepCollectionEquality().equals(other._regions, _regions)); + (identical(other.maxIntensityIsEarly, maxIntensityIsEarly) || + other.maxIntensityIsEarly == maxIntensityIsEarly) && + const DeepCollectionEquality().equals(other._regions, _regions) && + const DeepCollectionEquality().equals(other._cities, _cities)); } @JsonKey(ignore: true) @@ -635,14 +675,16 @@ class _$EarthquakeEarlyEventImpl implements _EarthquakeEarlyEvent { runtimeType, id, name, - latitude, - longitude, + lat, + lon, depth, magnitude, originTime, originTimePrecision, maxIntensity, - const DeepCollectionEquality().hash(_regions)); + maxIntensityIsEarly, + const DeepCollectionEquality().hash(_regions), + const DeepCollectionEquality().hash(_cities)); @JsonKey(ignore: true) @override @@ -664,14 +706,16 @@ abstract class _EarthquakeEarlyEvent implements EarthquakeEarlyEvent { const factory _EarthquakeEarlyEvent( {required final String id, required final String name, - required final double? latitude, - required final double? longitude, + required final double? lat, + required final double? lon, required final double? depth, required final double? magnitude, required final DateTime originTime, required final OriginTimePrecision originTimePrecision, - required final JmaIntensity? maxIntensity, - required final List regions}) = + required final JmaForecastIntensity? maxIntensity, + required final bool maxIntensityIsEarly, + required final List regions, + required final List cities}) = _$EarthquakeEarlyEventImpl; factory _EarthquakeEarlyEvent.fromJson(Map json) = @@ -682,9 +726,9 @@ abstract class _EarthquakeEarlyEvent implements EarthquakeEarlyEvent { @override String get name; @override - double? get latitude; + double? get lat; @override - double? get longitude; + double? get lon; @override double? get depth; @override @@ -694,10 +738,14 @@ abstract class _EarthquakeEarlyEvent implements EarthquakeEarlyEvent { @override OriginTimePrecision get originTimePrecision; @override - JmaIntensity? get maxIntensity; + JmaForecastIntensity? get maxIntensity; + @override + bool get maxIntensityIsEarly; @override List get regions; @override + List get cities; + @override @JsonKey(ignore: true) _$$EarthquakeEarlyEventImplCopyWith<_$EarthquakeEarlyEventImpl> get copyWith => throw _privateConstructorUsedError; @@ -711,9 +759,8 @@ EarthquakeEarlyRegion _$EarthquakeEarlyRegionFromJson( /// @nodoc mixin _$EarthquakeEarlyRegion { String get name => throw _privateConstructorUsedError; - int get code => throw _privateConstructorUsedError; - JmaIntensity get maxIntensity => throw _privateConstructorUsedError; - List get cities => throw _privateConstructorUsedError; + String get code => throw _privateConstructorUsedError; + JmaForecastIntensity get maxIntensity => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -727,11 +774,7 @@ abstract class $EarthquakeEarlyRegionCopyWith<$Res> { $Res Function(EarthquakeEarlyRegion) then) = _$EarthquakeEarlyRegionCopyWithImpl<$Res, EarthquakeEarlyRegion>; @useResult - $Res call( - {String name, - int code, - JmaIntensity maxIntensity, - List cities}); + $Res call({String name, String code, JmaForecastIntensity maxIntensity}); } /// @nodoc @@ -751,7 +794,6 @@ class _$EarthquakeEarlyRegionCopyWithImpl<$Res, Object? name = null, Object? code = null, Object? maxIntensity = null, - Object? cities = null, }) { return _then(_value.copyWith( name: null == name @@ -761,15 +803,11 @@ class _$EarthquakeEarlyRegionCopyWithImpl<$Res, code: null == code ? _value.code : code // ignore: cast_nullable_to_non_nullable - as int, + as String, maxIntensity: null == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity, - cities: null == cities - ? _value.cities - : cities // ignore: cast_nullable_to_non_nullable - as List, + as JmaForecastIntensity, ) as $Val); } } @@ -783,11 +821,7 @@ abstract class _$$EarthquakeEarlyRegionImplCopyWith<$Res> __$$EarthquakeEarlyRegionImplCopyWithImpl<$Res>; @override @useResult - $Res call( - {String name, - int code, - JmaIntensity maxIntensity, - List cities}); + $Res call({String name, String code, JmaForecastIntensity maxIntensity}); } /// @nodoc @@ -805,7 +839,6 @@ class __$$EarthquakeEarlyRegionImplCopyWithImpl<$Res> Object? name = null, Object? code = null, Object? maxIntensity = null, - Object? cities = null, }) { return _then(_$EarthquakeEarlyRegionImpl( name: null == name @@ -815,15 +848,11 @@ class __$$EarthquakeEarlyRegionImplCopyWithImpl<$Res> code: null == code ? _value.code : code // ignore: cast_nullable_to_non_nullable - as int, + as String, maxIntensity: null == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity, - cities: null == cities - ? _value._cities - : cities // ignore: cast_nullable_to_non_nullable - as List, + as JmaForecastIntensity, )); } } @@ -832,11 +861,7 @@ class __$$EarthquakeEarlyRegionImplCopyWithImpl<$Res> @JsonSerializable() class _$EarthquakeEarlyRegionImpl implements _EarthquakeEarlyRegion { const _$EarthquakeEarlyRegionImpl( - {required this.name, - required this.code, - required this.maxIntensity, - required final List cities}) - : _cities = cities; + {required this.name, required this.code, required this.maxIntensity}); factory _$EarthquakeEarlyRegionImpl.fromJson(Map json) => _$$EarthquakeEarlyRegionImplFromJson(json); @@ -844,20 +869,13 @@ class _$EarthquakeEarlyRegionImpl implements _EarthquakeEarlyRegion { @override final String name; @override - final int code; + final String code; @override - final JmaIntensity maxIntensity; - final List _cities; - @override - List get cities { - if (_cities is EqualUnmodifiableListView) return _cities; - // ignore: implicit_dynamic_type - return EqualUnmodifiableListView(_cities); - } + final JmaForecastIntensity maxIntensity; @override String toString() { - return 'EarthquakeEarlyRegion(name: $name, code: $code, maxIntensity: $maxIntensity, cities: $cities)'; + return 'EarthquakeEarlyRegion(name: $name, code: $code, maxIntensity: $maxIntensity)'; } @override @@ -868,14 +886,12 @@ class _$EarthquakeEarlyRegionImpl implements _EarthquakeEarlyRegion { (identical(other.name, name) || other.name == name) && (identical(other.code, code) || other.code == code) && (identical(other.maxIntensity, maxIntensity) || - other.maxIntensity == maxIntensity) && - const DeepCollectionEquality().equals(other._cities, _cities)); + other.maxIntensity == maxIntensity)); } @JsonKey(ignore: true) @override - int get hashCode => Object.hash(runtimeType, name, code, maxIntensity, - const DeepCollectionEquality().hash(_cities)); + int get hashCode => Object.hash(runtimeType, name, code, maxIntensity); @JsonKey(ignore: true) @override @@ -895,9 +911,8 @@ class _$EarthquakeEarlyRegionImpl implements _EarthquakeEarlyRegion { abstract class _EarthquakeEarlyRegion implements EarthquakeEarlyRegion { const factory _EarthquakeEarlyRegion( {required final String name, - required final int code, - required final JmaIntensity maxIntensity, - required final List cities}) = + required final String code, + required final JmaForecastIntensity maxIntensity}) = _$EarthquakeEarlyRegionImpl; factory _EarthquakeEarlyRegion.fromJson(Map json) = @@ -906,11 +921,9 @@ abstract class _EarthquakeEarlyRegion implements EarthquakeEarlyRegion { @override String get name; @override - int get code; - @override - JmaIntensity get maxIntensity; + String get code; @override - List get cities; + JmaForecastIntensity get maxIntensity; @override @JsonKey(ignore: true) _$$EarthquakeEarlyRegionImplCopyWith<_$EarthquakeEarlyRegionImpl> @@ -924,8 +937,8 @@ EarthquakeEarlyCity _$EarthquakeEarlyCityFromJson(Map json) { /// @nodoc mixin _$EarthquakeEarlyCity { String get name => throw _privateConstructorUsedError; - int get code => throw _privateConstructorUsedError; - JmaIntensity get maxIntensity => throw _privateConstructorUsedError; + String get code => throw _privateConstructorUsedError; + JmaForecastIntensity get maxIntensity => throw _privateConstructorUsedError; List get observationPoints => throw _privateConstructorUsedError; @@ -943,8 +956,8 @@ abstract class $EarthquakeEarlyCityCopyWith<$Res> { @useResult $Res call( {String name, - int code, - JmaIntensity maxIntensity, + String code, + JmaForecastIntensity maxIntensity, List observationPoints}); } @@ -974,11 +987,11 @@ class _$EarthquakeEarlyCityCopyWithImpl<$Res, $Val extends EarthquakeEarlyCity> code: null == code ? _value.code : code // ignore: cast_nullable_to_non_nullable - as int, + as String, maxIntensity: null == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity, + as JmaForecastIntensity, observationPoints: null == observationPoints ? _value.observationPoints : observationPoints // ignore: cast_nullable_to_non_nullable @@ -997,8 +1010,8 @@ abstract class _$$EarthquakeEarlyCityImplCopyWith<$Res> @useResult $Res call( {String name, - int code, - JmaIntensity maxIntensity, + String code, + JmaForecastIntensity maxIntensity, List observationPoints}); } @@ -1026,11 +1039,11 @@ class __$$EarthquakeEarlyCityImplCopyWithImpl<$Res> code: null == code ? _value.code : code // ignore: cast_nullable_to_non_nullable - as int, + as String, maxIntensity: null == maxIntensity ? _value.maxIntensity : maxIntensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity, + as JmaForecastIntensity, observationPoints: null == observationPoints ? _value._observationPoints : observationPoints // ignore: cast_nullable_to_non_nullable @@ -1055,9 +1068,9 @@ class _$EarthquakeEarlyCityImpl implements _EarthquakeEarlyCity { @override final String name; @override - final int code; + final String code; @override - final JmaIntensity maxIntensity; + final JmaForecastIntensity maxIntensity; final List _observationPoints; @override List get observationPoints { @@ -1108,8 +1121,8 @@ class _$EarthquakeEarlyCityImpl implements _EarthquakeEarlyCity { abstract class _EarthquakeEarlyCity implements EarthquakeEarlyCity { const factory _EarthquakeEarlyCity( {required final String name, - required final int code, - required final JmaIntensity maxIntensity, + required final String code, + required final JmaForecastIntensity maxIntensity, required final List observationPoints}) = _$EarthquakeEarlyCityImpl; @@ -1119,9 +1132,9 @@ abstract class _EarthquakeEarlyCity implements EarthquakeEarlyCity { @override String get name; @override - int get code; + String get code; @override - JmaIntensity get maxIntensity; + JmaForecastIntensity get maxIntensity; @override List get observationPoints; @override @@ -1138,9 +1151,9 @@ EarthquakeEarlyObservationPoint _$EarthquakeEarlyObservationPointFromJson( /// @nodoc mixin _$EarthquakeEarlyObservationPoint { String get name => throw _privateConstructorUsedError; - double get latitude => throw _privateConstructorUsedError; - double get longitude => throw _privateConstructorUsedError; - JmaIntensity get intensity => throw _privateConstructorUsedError; + double get lat => throw _privateConstructorUsedError; + double get lon => throw _privateConstructorUsedError; + JmaForecastIntensity get intensity => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -1157,7 +1170,7 @@ abstract class $EarthquakeEarlyObservationPointCopyWith<$Res> { EarthquakeEarlyObservationPoint>; @useResult $Res call( - {String name, double latitude, double longitude, JmaIntensity intensity}); + {String name, double lat, double lon, JmaForecastIntensity intensity}); } /// @nodoc @@ -1175,8 +1188,8 @@ class _$EarthquakeEarlyObservationPointCopyWithImpl<$Res, @override $Res call({ Object? name = null, - Object? latitude = null, - Object? longitude = null, + Object? lat = null, + Object? lon = null, Object? intensity = null, }) { return _then(_value.copyWith( @@ -1184,18 +1197,18 @@ class _$EarthquakeEarlyObservationPointCopyWithImpl<$Res, ? _value.name : name // ignore: cast_nullable_to_non_nullable as String, - latitude: null == latitude - ? _value.latitude - : latitude // ignore: cast_nullable_to_non_nullable + lat: null == lat + ? _value.lat + : lat // ignore: cast_nullable_to_non_nullable as double, - longitude: null == longitude - ? _value.longitude - : longitude // ignore: cast_nullable_to_non_nullable + lon: null == lon + ? _value.lon + : lon // ignore: cast_nullable_to_non_nullable as double, intensity: null == intensity ? _value.intensity : intensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity, + as JmaForecastIntensity, ) as $Val); } } @@ -1210,7 +1223,7 @@ abstract class _$$EarthquakeEarlyObservationPointImplCopyWith<$Res> @override @useResult $Res call( - {String name, double latitude, double longitude, JmaIntensity intensity}); + {String name, double lat, double lon, JmaForecastIntensity intensity}); } /// @nodoc @@ -1227,8 +1240,8 @@ class __$$EarthquakeEarlyObservationPointImplCopyWithImpl<$Res> @override $Res call({ Object? name = null, - Object? latitude = null, - Object? longitude = null, + Object? lat = null, + Object? lon = null, Object? intensity = null, }) { return _then(_$EarthquakeEarlyObservationPointImpl( @@ -1236,18 +1249,18 @@ class __$$EarthquakeEarlyObservationPointImplCopyWithImpl<$Res> ? _value.name : name // ignore: cast_nullable_to_non_nullable as String, - latitude: null == latitude - ? _value.latitude - : latitude // ignore: cast_nullable_to_non_nullable + lat: null == lat + ? _value.lat + : lat // ignore: cast_nullable_to_non_nullable as double, - longitude: null == longitude - ? _value.longitude - : longitude // ignore: cast_nullable_to_non_nullable + lon: null == lon + ? _value.lon + : lon // ignore: cast_nullable_to_non_nullable as double, intensity: null == intensity ? _value.intensity : intensity // ignore: cast_nullable_to_non_nullable - as JmaIntensity, + as JmaForecastIntensity, )); } } @@ -1258,8 +1271,8 @@ class _$EarthquakeEarlyObservationPointImpl implements _EarthquakeEarlyObservationPoint { const _$EarthquakeEarlyObservationPointImpl( {required this.name, - required this.latitude, - required this.longitude, + required this.lat, + required this.lon, required this.intensity}); factory _$EarthquakeEarlyObservationPointImpl.fromJson( @@ -1269,15 +1282,15 @@ class _$EarthquakeEarlyObservationPointImpl @override final String name; @override - final double latitude; + final double lat; @override - final double longitude; + final double lon; @override - final JmaIntensity intensity; + final JmaForecastIntensity intensity; @override String toString() { - return 'EarthquakeEarlyObservationPoint(name: $name, latitude: $latitude, longitude: $longitude, intensity: $intensity)'; + return 'EarthquakeEarlyObservationPoint(name: $name, lat: $lat, lon: $lon, intensity: $intensity)'; } @override @@ -1286,18 +1299,15 @@ class _$EarthquakeEarlyObservationPointImpl (other.runtimeType == runtimeType && other is _$EarthquakeEarlyObservationPointImpl && (identical(other.name, name) || other.name == name) && - (identical(other.latitude, latitude) || - other.latitude == latitude) && - (identical(other.longitude, longitude) || - other.longitude == longitude) && + (identical(other.lat, lat) || other.lat == lat) && + (identical(other.lon, lon) || other.lon == lon) && (identical(other.intensity, intensity) || other.intensity == intensity)); } @JsonKey(ignore: true) @override - int get hashCode => - Object.hash(runtimeType, name, latitude, longitude, intensity); + int get hashCode => Object.hash(runtimeType, name, lat, lon, intensity); @JsonKey(ignore: true) @override @@ -1319,9 +1329,9 @@ abstract class _EarthquakeEarlyObservationPoint implements EarthquakeEarlyObservationPoint { const factory _EarthquakeEarlyObservationPoint( {required final String name, - required final double latitude, - required final double longitude, - required final JmaIntensity intensity}) = + required final double lat, + required final double lon, + required final JmaForecastIntensity intensity}) = _$EarthquakeEarlyObservationPointImpl; factory _EarthquakeEarlyObservationPoint.fromJson(Map json) = @@ -1330,11 +1340,11 @@ abstract class _EarthquakeEarlyObservationPoint @override String get name; @override - double get latitude; + double get lat; @override - double get longitude; + double get lon; @override - JmaIntensity get intensity; + JmaForecastIntensity get intensity; @override @JsonKey(ignore: true) _$$EarthquakeEarlyObservationPointImplCopyWith< diff --git a/packages/eqapi_types/lib/model/v1/earthquake_early.g.dart b/packages/eqapi_types/lib/model/v1/earthquake_early.g.dart index f32227658..ca188f56e 100644 --- a/packages/eqapi_types/lib/model/v1/earthquake_early.g.dart +++ b/packages/eqapi_types/lib/model/v1/earthquake_early.g.dart @@ -23,7 +23,7 @@ _$EarthquakeEarlyImpl _$$EarthquakeEarlyImplFromJson( magnitude: $checkedConvert('magnitude', (v) => (v as num?)?.toDouble()), maxIntensity: $checkedConvert('max_intensity', - (v) => $enumDecodeNullable(_$JmaIntensityEnumMap, v)), + (v) => $enumDecodeNullable(_$JmaForecastIntensityEnumMap, v)), maxIntensityIsEarly: $checkedConvert('max_intensity_is_early', (v) => v as bool), name: $checkedConvert('name', (v) => v as String), @@ -50,7 +50,7 @@ Map _$$EarthquakeEarlyImplToJson( 'latitude': instance.latitude, 'longitude': instance.longitude, 'magnitude': instance.magnitude, - 'max_intensity': _$JmaIntensityEnumMap[instance.maxIntensity], + 'max_intensity': _$JmaForecastIntensityEnumMap[instance.maxIntensity], 'max_intensity_is_early': instance.maxIntensityIsEarly, 'name': instance.name, 'origin_time': instance.originTime.toIso8601String(), @@ -58,17 +58,18 @@ Map _$$EarthquakeEarlyImplToJson( _$OriginTimePrecisionEnumMap[instance.originTimePrecision]!, }; -const _$JmaIntensityEnumMap = { - JmaIntensity.one: '1', - JmaIntensity.two: '2', - JmaIntensity.three: '3', - JmaIntensity.four: '4', - JmaIntensity.fiveLower: '5-', - JmaIntensity.fiveUpper: '5+', - JmaIntensity.sixLower: '6-', - JmaIntensity.sixUpper: '6+', - JmaIntensity.seven: '7', - JmaIntensity.fiveUpperNoInput: '!5-', +const _$JmaForecastIntensityEnumMap = { + JmaForecastIntensity.zero: '0', + JmaForecastIntensity.one: '1', + JmaForecastIntensity.two: '2', + JmaForecastIntensity.three: '3', + JmaForecastIntensity.four: '4', + JmaForecastIntensity.fiveLower: '5-', + JmaForecastIntensity.fiveUpper: '5+', + JmaForecastIntensity.sixLower: '6-', + JmaForecastIntensity.sixUpper: '6+', + JmaForecastIntensity.seven: '7', + JmaForecastIntensity.unknown: '不明', }; const _$OriginTimePrecisionEnumMap = { @@ -89,9 +90,8 @@ _$EarthquakeEarlyEventImpl _$$EarthquakeEarlyEventImplFromJson( final val = _$EarthquakeEarlyEventImpl( id: $checkedConvert('id', (v) => v as String), name: $checkedConvert('name', (v) => v as String), - latitude: $checkedConvert('latitude', (v) => (v as num?)?.toDouble()), - longitude: - $checkedConvert('longitude', (v) => (v as num?)?.toDouble()), + lat: $checkedConvert('lat', (v) => (v as num?)?.toDouble()), + lon: $checkedConvert('lon', (v) => (v as num?)?.toDouble()), depth: $checkedConvert('depth', (v) => (v as num?)?.toDouble()), magnitude: $checkedConvert('magnitude', (v) => (v as num?)?.toDouble()), @@ -100,20 +100,29 @@ _$EarthquakeEarlyEventImpl _$$EarthquakeEarlyEventImplFromJson( originTimePrecision: $checkedConvert('origin_time_precision', (v) => $enumDecode(_$OriginTimePrecisionEnumMap, v)), maxIntensity: $checkedConvert('max_intensity', - (v) => $enumDecodeNullable(_$JmaIntensityEnumMap, v)), + (v) => $enumDecodeNullable(_$JmaForecastIntensityEnumMap, v)), + maxIntensityIsEarly: + $checkedConvert('max_intensity_is_early', (v) => v as bool), regions: $checkedConvert( 'regions', (v) => (v as List) .map((e) => EarthquakeEarlyRegion.fromJson(e as Map)) .toList()), + cities: $checkedConvert( + 'cities', + (v) => (v as List) + .map((e) => + EarthquakeEarlyCity.fromJson(e as Map)) + .toList()), ); return val; }, fieldKeyMap: const { 'originTime': 'origin_time', 'originTimePrecision': 'origin_time_precision', - 'maxIntensity': 'max_intensity' + 'maxIntensity': 'max_intensity', + 'maxIntensityIsEarly': 'max_intensity_is_early' }, ); @@ -122,15 +131,17 @@ Map _$$EarthquakeEarlyEventImplToJson( { 'id': instance.id, 'name': instance.name, - 'latitude': instance.latitude, - 'longitude': instance.longitude, + 'lat': instance.lat, + 'lon': instance.lon, 'depth': instance.depth, 'magnitude': instance.magnitude, 'origin_time': instance.originTime.toIso8601String(), 'origin_time_precision': _$OriginTimePrecisionEnumMap[instance.originTimePrecision]!, - 'max_intensity': _$JmaIntensityEnumMap[instance.maxIntensity], + 'max_intensity': _$JmaForecastIntensityEnumMap[instance.maxIntensity], + 'max_intensity_is_early': instance.maxIntensityIsEarly, 'regions': instance.regions, + 'cities': instance.cities, }; _$EarthquakeEarlyRegionImpl _$$EarthquakeEarlyRegionImplFromJson( @@ -141,15 +152,9 @@ _$EarthquakeEarlyRegionImpl _$$EarthquakeEarlyRegionImplFromJson( ($checkedConvert) { final val = _$EarthquakeEarlyRegionImpl( name: $checkedConvert('name', (v) => v as String), - code: $checkedConvert('code', (v) => (v as num).toInt()), - maxIntensity: $checkedConvert( - 'max_intensity', (v) => $enumDecode(_$JmaIntensityEnumMap, v)), - cities: $checkedConvert( - 'cities', - (v) => (v as List) - .map((e) => - EarthquakeEarlyCity.fromJson(e as Map)) - .toList()), + code: $checkedConvert('code', (v) => v as String), + maxIntensity: $checkedConvert('max_intensity', + (v) => $enumDecode(_$JmaForecastIntensityEnumMap, v)), ); return val; }, @@ -161,8 +166,7 @@ Map _$$EarthquakeEarlyRegionImplToJson( { 'name': instance.name, 'code': instance.code, - 'max_intensity': _$JmaIntensityEnumMap[instance.maxIntensity]!, - 'cities': instance.cities, + 'max_intensity': _$JmaForecastIntensityEnumMap[instance.maxIntensity]!, }; _$EarthquakeEarlyCityImpl _$$EarthquakeEarlyCityImplFromJson( @@ -173,9 +177,9 @@ _$EarthquakeEarlyCityImpl _$$EarthquakeEarlyCityImplFromJson( ($checkedConvert) { final val = _$EarthquakeEarlyCityImpl( name: $checkedConvert('name', (v) => v as String), - code: $checkedConvert('code', (v) => (v as num).toInt()), - maxIntensity: $checkedConvert( - 'max_intensity', (v) => $enumDecode(_$JmaIntensityEnumMap, v)), + code: $checkedConvert('code', (v) => v as String), + maxIntensity: $checkedConvert('max_intensity', + (v) => $enumDecode(_$JmaForecastIntensityEnumMap, v)), observationPoints: $checkedConvert( 'observation_points', (v) => (v as List) @@ -196,7 +200,7 @@ Map _$$EarthquakeEarlyCityImplToJson( { 'name': instance.name, 'code': instance.code, - 'max_intensity': _$JmaIntensityEnumMap[instance.maxIntensity]!, + 'max_intensity': _$JmaForecastIntensityEnumMap[instance.maxIntensity]!, 'observation_points': instance.observationPoints, }; @@ -208,12 +212,10 @@ _$EarthquakeEarlyObservationPointImpl ($checkedConvert) { final val = _$EarthquakeEarlyObservationPointImpl( name: $checkedConvert('name', (v) => v as String), - latitude: - $checkedConvert('latitude', (v) => (v as num).toDouble()), - longitude: - $checkedConvert('longitude', (v) => (v as num).toDouble()), - intensity: $checkedConvert( - 'intensity', (v) => $enumDecode(_$JmaIntensityEnumMap, v)), + lat: $checkedConvert('lat', (v) => (v as num).toDouble()), + lon: $checkedConvert('lon', (v) => (v as num).toDouble()), + intensity: $checkedConvert('intensity', + (v) => $enumDecode(_$JmaForecastIntensityEnumMap, v)), ); return val; }, @@ -223,7 +225,7 @@ Map _$$EarthquakeEarlyObservationPointImplToJson( _$EarthquakeEarlyObservationPointImpl instance) => { 'name': instance.name, - 'latitude': instance.latitude, - 'longitude': instance.longitude, - 'intensity': _$JmaIntensityEnumMap[instance.intensity]!, + 'lat': instance.lat, + 'lon': instance.lon, + 'intensity': _$JmaForecastIntensityEnumMap[instance.intensity]!, };