From bdd26b16b2c3ab935ded67fb6ee16912310792db Mon Sep 17 00:00:00 2001
From: Ryotaro Onoue <73390859+YumNumm@users.noreply.github.com>
Date: Fri, 31 May 2024 21:06:00 +0900
Subject: [PATCH] =?UTF-8?q?[FEATURE]=20Deep=20Link=E3=81=AE=E5=AE=9F?=
=?UTF-8?q?=E8=A3=85=E3=83=BB=E9=80=9A=E7=9F=A5=E3=82=BF=E3=83=83=E3=83=97?=
=?UTF-8?q?=E6=99=82=E3=81=AE=E7=94=BB=E9=9D=A2=E9=81=B7=E7=A7=BB=E5=AE=9F?=
=?UTF-8?q?=E8=A3=85=20(#712)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* add
---
app/ios/Runner.xcodeproj/project.pbxproj | 28 ++-----
app/ios/Runner/Info.plist | 2 +
app/ios/Runner/Runner.entitlements | 5 ++
app/lib/core/theme/build_theme.dart | 6 ++
.../earthquake_history_details_notifier.dart | 8 +-
.../home/component/sheet/status_widget.dart | 1 -
.../map/viewmodel/main_map_viewmodel.dart | 78 ++++++++++---------
app/lib/feature/home/view/home_view.dart | 68 +++++++++-------
.../children/config/debug/debugger_page.dart | 69 ++++++++++++++++
...ation_remote_settings_migrate_service.dart | 3 +
10 files changed, 176 insertions(+), 92 deletions(-)
diff --git a/app/ios/Runner.xcodeproj/project.pbxproj b/app/ios/Runner.xcodeproj/project.pbxproj
index eee8dce18..6cb79b001 100644
--- a/app/ios/Runner.xcodeproj/project.pbxproj
+++ b/app/ios/Runner.xcodeproj/project.pbxproj
@@ -584,11 +584,9 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Ryotaro Onoue (CPL7H8SHVM)";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1169;
- DEVELOPMENT_TEAM = "";
- "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
+ DEVELOPMENT_TEAM = CPL7H8SHVM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = EQMonitor;
@@ -601,7 +599,6 @@
PRODUCT_BUNDLE_IDENTIFIER = net.yumnumm.eqmonitor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore net.yumnumm.eqmonitor";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -621,11 +618,9 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = FcmServiceExtension/FcmServiceExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development: Ryotaro Onoue (7PWJ49VWRZ)";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1169;
- DEVELOPMENT_TEAM = "";
- "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
+ DEVELOPMENT_TEAM = CPL7H8SHVM;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
@@ -645,7 +640,6 @@
PRODUCT_BUNDLE_IDENTIFIER = net.yumnumm.eqmonitor.FcmServiceExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development net.yumnumm.eqmonitor.FcmServiceExtension";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -861,11 +855,9 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development: Ryotaro Onoue (7PWJ49VWRZ)";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1169;
- DEVELOPMENT_TEAM = "";
- "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
+ DEVELOPMENT_TEAM = CPL7H8SHVM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = EQMonitor;
@@ -878,7 +870,6 @@
PRODUCT_BUNDLE_IDENTIFIER = net.yumnumm.eqmonitor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development net.yumnumm.eqmonitor";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -895,11 +886,9 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Ryotaro Onoue (CPL7H8SHVM)";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1169;
- DEVELOPMENT_TEAM = "";
- "DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
+ DEVELOPMENT_TEAM = CPL7H8SHVM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = EQMonitor;
@@ -912,7 +901,6 @@
PRODUCT_BUNDLE_IDENTIFIER = net.yumnumm.eqmonitor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore net.yumnumm.eqmonitor";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
diff --git a/app/ios/Runner/Info.plist b/app/ios/Runner/Info.plist
index c49fea8ba..80054cd98 100644
--- a/app/ios/Runner/Info.plist
+++ b/app/ios/Runner/Info.plist
@@ -48,6 +48,8 @@
LaunchScreen
UIMainStoryboardFile
Main
+ FlutterDeepLinkingEnabled
+
UISupportedInterfaceOrientations
UIInterfaceOrientationLandscapeLeft
diff --git a/app/ios/Runner/Runner.entitlements b/app/ios/Runner/Runner.entitlements
index fead5277b..7327fe69c 100644
--- a/app/ios/Runner/Runner.entitlements
+++ b/app/ios/Runner/Runner.entitlements
@@ -4,6 +4,11 @@
aps-environment
production
+ com.apple.developer.associated-domains
+
+ applinks:deeplink.eqmonitor.app
+ applinks:deeplink.eqmonitor.app?mode=developer
+
com.apple.developer.usernotifications.critical-alerts
com.apple.developer.usernotifications.time-sensitive
diff --git a/app/lib/core/theme/build_theme.dart b/app/lib/core/theme/build_theme.dart
index 63745e106..ca4fca6fe 100644
--- a/app/lib/core/theme/build_theme.dart
+++ b/app/lib/core/theme/build_theme.dart
@@ -12,6 +12,12 @@ ThemeData buildTheme({
extensions: [if (customColors != null) customColors],
useMaterial3: true,
fontFamily: FontFamily.notoSansJP,
+ pageTransitionsTheme: const PageTransitionsTheme(
+ builders: {
+ // MEMO(YumNumm): PredictiveBackを使うと、MediaQuery.sizeOf(context)の値が変わるので無効
+ // TargetPlatform.android: PredictiveBackPageTransitionsBuilder(),
+ },
+ ),
);
}
diff --git a/app/lib/feature/earthquake_history_details/data/earthquake_history_details_notifier.dart b/app/lib/feature/earthquake_history_details/data/earthquake_history_details_notifier.dart
index c03d1ff82..dbf57d1d9 100644
--- a/app/lib/feature/earthquake_history_details/data/earthquake_history_details_notifier.dart
+++ b/app/lib/feature/earthquake_history_details/data/earthquake_history_details_notifier.dart
@@ -28,12 +28,8 @@ class EarthquakeHistoryDetailsNotifier
final target = earthquakes?.$1.firstWhereOrNull(
(earthquake) => earthquake.eventId == eventId,
);
- if (target != null) {
- if (target.intensityRegions != null) {
- state = AsyncData(target);
- } else {
- ref.invalidateSelf();
- }
+ if (target?.intensityRegions != null) {
+ state = AsyncData(target!);
}
}
});
diff --git a/app/lib/feature/home/component/sheet/status_widget.dart b/app/lib/feature/home/component/sheet/status_widget.dart
index 882be2fd4..59ca311f6 100644
--- a/app/lib/feature/home/component/sheet/status_widget.dart
+++ b/app/lib/feature/home/component/sheet/status_widget.dart
@@ -59,7 +59,6 @@ class SheetStatusWidget extends ConsumerWidget {
}
return BorderedContainer(
- elevation: 1,
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
diff --git a/app/lib/feature/home/features/map/viewmodel/main_map_viewmodel.dart b/app/lib/feature/home/features/map/viewmodel/main_map_viewmodel.dart
index 1f6eac478..086300fb2 100644
--- a/app/lib/feature/home/features/map/viewmodel/main_map_viewmodel.dart
+++ b/app/lib/feature/home/features/map/viewmodel/main_map_viewmodel.dart
@@ -759,6 +759,21 @@ class _EewHypocenterService {
double _lastOpacity = 0;
+ Future _changeOpacity(double opacity) => (
+ controller.setLayerProperties(
+ hypocenterIconId,
+ SymbolLayerProperties(
+ iconOpacity: opacity,
+ ),
+ ),
+ controller.setLayerProperties(
+ hypocenterLowPreciseIconId,
+ SymbolLayerProperties(
+ iconOpacity: opacity,
+ ),
+ ),
+ ).wait;
+
Future tick() async {
if (!hasInitialized) {
return;
@@ -768,24 +783,13 @@ class _EewHypocenterService {
if (_lastOpacity == 1.0) {
return;
}
- _lastOpacity = 1.0;
- await controller.setLayerProperties(
- hypocenterIconId,
- const SymbolLayerProperties(
- iconOpacity: 1.0,
- ),
- );
+ await _changeOpacity(1);
} else {
if (_lastOpacity == 0.5) {
return;
}
_lastOpacity = 0.5;
- await controller.setLayerProperties(
- hypocenterIconId,
- const SymbolLayerProperties(
- iconOpacity: 0.5,
- ),
- );
+ await _changeOpacity(0.5);
}
}
@@ -834,7 +838,7 @@ class _EewPsWaveService {
_EewPWaveLineService(controller: controller),
_EewSWaveLineService(controller: controller),
// _EewPWaveFillService(controller: controller),
- // _EewSWaveFillService(controller: controller),
+ _EewSWaveFillService(controller: controller),
);
final MaplibreMapController controller;
@@ -844,7 +848,7 @@ class _EewPsWaveService {
_EewPWaveLineService,
_EewSWaveLineService,
// _EewPWaveFillService,
- // _EewSWaveFillService
+ _EewSWaveFillService
) _children;
Future init() async {
@@ -860,7 +864,7 @@ class _EewPsWaveService {
_children.$2.init(),
).wait;
// fill
- // await _children.$3.init();
+ await _children.$3.init();
//_children.$4.init(),
}
@@ -930,26 +934,28 @@ class _EewPsWaveService {
{
'type': 'Feature',
'geometry': {
- 'type': 'LineString',
+ 'type': 'Polygon',
'coordinates': [
- // 0...360
- for (final bearing
- in List.generate(361, (index) => index))
- () {
- final latLng = const latlong2.Distance().offset(
- latlong2.LatLng(
- result.$2.lat,
- result.$2.lon,
- ),
- ((type == _WaveType.sWave
- ? result.$1.sDistance ?? 0
- : result.$1.pDistance ?? 0) *
- 1000)
- .toInt(),
- bearing,
- );
- return [latLng.longitude, latLng.latitude];
- }(),
+ [
+ // 0...360
+ for (final bearing
+ in List.generate(181, (index) => index * 2))
+ () {
+ final latLng = const latlong2.Distance().offset(
+ latlong2.LatLng(
+ result.$2.lat,
+ result.$2.lon,
+ ),
+ ((type == _WaveType.sWave
+ ? result.$1.sDistance ?? 0
+ : result.$1.pDistance ?? 0) *
+ 1000)
+ .toInt(),
+ bearing,
+ );
+ return [latLng.longitude, latLng.latitude];
+ }(),
+ ]
],
},
'properties': {
@@ -1044,7 +1050,6 @@ class _EewSWaveLineService {
static String get layerId => 's-wave-line';
}
-/*
class _EewPWaveFillService {
_EewPWaveFillService({
required this.controller,
@@ -1104,7 +1109,6 @@ class _EewSWaveFillService {
static String get layerId => 's-wave-fill';
}
-*/
@freezed
class _EewHypocenterProperties with _$EewHypocenterProperties {
diff --git a/app/lib/feature/home/view/home_view.dart b/app/lib/feature/home/view/home_view.dart
index f24a026c1..a39bb96a7 100644
--- a/app/lib/feature/home/view/home_view.dart
+++ b/app/lib/feature/home/view/home_view.dart
@@ -232,24 +232,28 @@ class _HomeBodyWidget extends HookConsumerWidget {
firebaseMessagingInteractionProvider,
(_, next) async {
if (next case AsyncData(:final value)) {
- ref.read(talkerProvider).log(
- 'Handle Firebase Message: '
- "${const JsonEncoder.withIndent(' ').convert(value.toMap())}",
- );
+ await WidgetsBinding.instance.endOfFrame.then((_) async {
+ ref.read(talkerProvider).log(
+ 'Handle Firebase Message: '
+ "${const JsonEncoder.withIndent(' ').convert(value.toMap())}",
+ );
- final route = value.data['route'];
- if (route is String) {
- ref.read(goRouterProvider).go(route);
- return;
- }
- final url = value.data['url'];
- if (url is String) {
- final canLaunch = await canLaunchUrlString(url);
- if (canLaunch) {
- await launchUrlString(url);
+ final route = value.data['route'];
+ if (route is String) {
+ unawaited(
+ ref.read(goRouterProvider).push(route),
+ );
+ return;
+ }
+ final url = value.data['url'];
+ if (url is String) {
+ final canLaunch = await canLaunchUrlString(url);
+ if (canLaunch) {
+ await launchUrlString(url);
+ }
+ return;
}
- return;
- }
+ });
}
},
);
@@ -495,12 +499,15 @@ class _NotificationMigrationWidget extends ConsumerWidget {
return switch (state) {
AsyncLoading() => const ListTile(
title: Text('通知設定の移行中'),
- leading: CircularProgressIndicator(),
+ leading: CircularProgressIndicator.adaptive(),
),
- AsyncError(:final error) => ListTile(
- title: const Text('通知設定の移行に失敗しました'),
- subtitle: Text(error.toString()),
- leading: const Icon(Icons.error),
+ AsyncError(:final error) => BorderedContainer(
+ elevation: 1,
+ child: ListTile(
+ title: const Text('通知設定の初期化に失敗しました。アプリケーションを再起動することで 再度初期化を試みます。'),
+ subtitle: Text(error.runtimeType.toString()),
+ leading: const Icon(Icons.error),
+ ),
),
AsyncData(:final value) => switch (value) {
NotificationRemoteSettingsSetupState.initial ||
@@ -511,23 +518,28 @@ class _NotificationMigrationWidget extends ConsumerWidget {
child: switch (value) {
NotificationRemoteSettingsSetupState.waitingForFcmToken =>
const ListTile(
- title: Text('FCMトークンの取得中'),
- leading: CircularProgressIndicator(),
+ title: Text('通知配信用トークンの取得中...'),
+ leading: CircularProgressIndicator.adaptive(),
),
NotificationRemoteSettingsSetupState.registering =>
const ListTile(
- title: Text('FCMトークンの登録中'),
- leading: CircularProgressIndicator(),
+ title: Text('通知配信用トークンの登録中...'),
+ leading: CircularProgressIndicator.adaptive(),
),
NotificationRemoteSettingsSetupState.migrating =>
const ListTile(
- title: Text('通知設定の移行中'),
- leading: CircularProgressIndicator(),
+ title: Text('通知設定の初期化中...'),
+ leading: CircularProgressIndicator.adaptive(),
),
NotificationRemoteSettingsSetupState.unsubscribingOldTopics =>
const ListTile(
title: Text('旧通知設定の解除中'),
- leading: CircularProgressIndicator(),
+ leading: CircularProgressIndicator.adaptive(),
+ ),
+ NotificationRemoteSettingsSetupState.completing =>
+ const ListTile(
+ title: Text('通知設定のセットアップが完了しました'),
+ leading: Icon(Icons.check),
),
_ => const SizedBox.shrink(),
},
diff --git a/app/lib/feature/settings/children/config/debug/debugger_page.dart b/app/lib/feature/settings/children/config/debug/debugger_page.dart
index 36d484e02..35db1688b 100644
--- a/app/lib/feature/settings/children/config/debug/debugger_page.dart
+++ b/app/lib/feature/settings/children/config/debug/debugger_page.dart
@@ -1,11 +1,14 @@
import 'package:eqmonitor/core/component/container/bordered_container.dart';
import 'package:eqmonitor/core/provider/dio_provider.dart';
+import 'package:eqmonitor/core/provider/notification_token.dart';
import 'package:eqmonitor/core/provider/telegram_url/provider/telegram_url_provider.dart';
+import 'package:eqmonitor/core/provider/websocket/websocket_provider.dart';
import 'package:eqmonitor/core/router/router.dart';
import 'package:eqmonitor/feature/home/component/kmoni/kmoni_settings_dialog.dart';
import 'package:eqmonitor/feature/home/component/sheet/sheet_header.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@@ -60,6 +63,47 @@ class _DebugWidget extends ConsumerWidget {
leading: const Icon(Icons.list),
onTap: () => context.push(const TalkerRoute().location),
),
+ ListTile(
+ title: const Text('EEW Test'),
+ leading: const Icon(Icons.list),
+ onTap: () async {
+ final demoPayload = {
+ 'commit_timestamp': '2024-04-01T12:10:32.747Z',
+ 'eventType': 'INSERT',
+ 'new': {
+ 'id': -1,
+ 'event_id': 20240401210952,
+ 'info_type': '発表',
+ 'schema_type': 'eew-information',
+ 'status': '訓練',
+ 'type': '緊急地震速報(地震動予報)',
+ 'headline': null,
+ 'serial_no': 1,
+ 'is_canceled': false,
+ 'is_last_info': false,
+ 'arrival_time': DateTime.now().toIso8601String(),
+ 'depth': 40,
+ 'forecast_max_intensity': '1',
+ 'forecast_max_intensity_is_over': false,
+ 'forecast_max_lpgm_intensity': '0',
+ 'forecast_max_lpgm_intensity_is_over': false,
+ 'hypo_name': '石垣島北西沖',
+ 'is_warning': false,
+ 'latitude': 25.2,
+ 'longitude': 123.6,
+ 'magnitude': 3.6,
+ 'origin_time': DateTime.now().toIso8601String(),
+ 'regions': [],
+ 'report_time': DateTime.now().toIso8601String(),
+ },
+ 'old': {},
+ 'schema': 'public',
+ 'table': 'eew',
+ 'errors': null,
+ };
+ ref.read(websocketMessagesProvider.notifier).emit(demoPayload);
+ },
+ ),
ListTile(
title: const Text('強震モニタ'),
leading: const Icon(Icons.settings),
@@ -152,6 +196,31 @@ class _DebugWidget extends ConsumerWidget {
}
},
),
+ ListTile(
+ title: const Text('FCM Token'),
+ subtitle: Text(
+ ref
+ .watch(notificationTokenProvider)
+ .valueOrNull
+ ?.fcmToken
+ ?.toString() ??
+ 'null',
+ ),
+ onTap: () async {
+ final token = await FirebaseMessaging.instance.getToken();
+ await Clipboard.setData(ClipboardData(text: token ?? ''));
+ },
+ ),
+ FilledButton.icon(
+ onPressed: () =>
+ context.push('/earthquake-history-details/20240526142329'),
+ // const EarthquakeHistoryDetailsRoute(eventId: 20201122190603)
+ // .push(context),
+ icon: const Icon(Icons.list),
+ label: const Text(
+ "context.push('/earthquake-history-details/20240526142329')",
+ ),
+ ),
SwitchListTile.adaptive(
value: ref.watch(isDioProxyEnabledProvider),
onChanged: (value) => ref
diff --git a/app/lib/feature/settings/features/notification_remote_settings/data/service/notification_remote_settings_migrate_service.dart b/app/lib/feature/settings/features/notification_remote_settings/data/service/notification_remote_settings_migrate_service.dart
index 06c54e4c6..dbd614afa 100644
--- a/app/lib/feature/settings/features/notification_remote_settings/data/service/notification_remote_settings_migrate_service.dart
+++ b/app/lib/feature/settings/features/notification_remote_settings/data/service/notification_remote_settings_migrate_service.dart
@@ -54,6 +54,8 @@ class NotificationRemoteSettingsInitialSetupNotifier
await _migrate();
}
+ yield NotificationRemoteSettingsSetupState.completing;
+ await Future.delayed(const Duration(seconds: 1));
yield NotificationRemoteSettingsSetupState.completed;
}
@@ -179,6 +181,7 @@ enum NotificationRemoteSettingsSetupState {
registering,
migrating,
unsubscribingOldTopics,
+ completing,
completed,
;
}