diff --git a/.gitattributes b/.gitattributes
index 31bf7c6d7..73acaa8da 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,2 @@
-*.freezed.dart linguist-generated=true
-*.g.dart linguist-generated=true
-*.gen.dart linguist-generated=true
\ No newline at end of file
+*.*.dart linguist-generated=true
+*.lock linguist-generated=true
\ No newline at end of file
diff --git a/app/DistributionSummary.plist b/app/DistributionSummary.plist
deleted file mode 100644
index 6b4f1b516..000000000
--- a/app/DistributionSummary.plist
+++ /dev/null
@@ -1,1044 +0,0 @@
-
-
-
-
- eqmonitor.ipa
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1161
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- embeddedBinaries
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1.0
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- App.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 1.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FBLPromises.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 2.4.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FirebaseCore.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.22.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FirebaseCoreExtension.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.22.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FirebaseCoreInternal.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.22.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FirebaseCrashlytics.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.22.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FirebaseInstallations.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.22.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FirebaseMessaging.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.22.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- FirebaseSessions.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.22.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1.0
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- Flutter.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 1.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- GoogleDataTransport.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 9.4.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- GoogleUtilities.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 7.13.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 15256
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- Mapbox.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 5.9.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- Promises.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 2.4.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- PurchasesHybridCommon.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 10.3.2
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- RevenueCat.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 4.39.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- app_settings.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 5.1.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- device_info_plus.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- flutter_local_notifications.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- in_app_review.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.2.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- integration_test.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- maplibre_gl.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- nanopb.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 2.30910.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- package_info_plus.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.4.5
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- path_provider_foundation.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- purchases_flutter.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 6.25.0
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- share_plus.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- shared_preferences_foundation.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- name
- url_launcher_ios.framework
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 0.0.1
-
-
- architectures
-
- arm64
-
- bitcode
-
- buildNumber
- 1161
- certificate
-
- SHA1
- 4609FE8A819F994F4AD5C990A8447BCFAB4F40A5
- dateExpires
- 2024/07/16
- type
- Apple Distribution
-
- entitlements
-
- application-identifier
- CPL7H8SHVM.net.yumnumm.eqmonitor.FcmServiceExtension
- beta-reports-active
-
- com.apple.developer.team-identifier
- CPL7H8SHVM
- get-task-allow
-
-
- name
- FcmServiceExtension.appex
- profile
-
- UUID
- 21396a7c-9872-4293-93d3-28285b96236a
- dateExpires
- 2024/07/16
- name
- iOS Team Store Provisioning Profile: net.yumnumm.eqmonitor.FcmServiceExtension
-
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 2.4.0
-
-
- entitlements
-
- application-identifier
- CPL7H8SHVM.net.yumnumm.eqmonitor
- beta-reports-active
-
- com.apple.developer.team-identifier
- CPL7H8SHVM
- get-task-allow
-
-
- name
- Runner.app
- profile
-
- UUID
- 62d4e6fc-1c4e-4e51-bed5-f1f76c4d215d
- dateExpires
- 2024/07/16
- name
- iOS Team Store Provisioning Profile: net.yumnumm.eqmonitor
-
- symbols
-
- team
-
- id
- CPL7H8SHVM
- name
-
-
- versionNumber
- 2.4.0
-
-
-
-
diff --git a/app/ExportOptions.plist b/app/ExportOptions.plist
deleted file mode 100644
index e3825bdfe..000000000
--- a/app/ExportOptions.plist
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
- destination
- export
- generateAppStoreInformation
-
- manageAppVersionAndBuildNumber
-
- method
- app-store-connect
- signingStyle
- automatic
- stripSwiftSymbols
-
- teamID
- CPL7H8SHVM
- testFlightInternalTestingOnly
-
- uploadSymbols
-
-
-
diff --git a/app/assets/jma_code_table.pb b/app/assets/jma_code_table.pb
index 2a704190f..13d00dfb2 100644
Binary files a/app/assets/jma_code_table.pb and b/app/assets/jma_code_table.pb differ
diff --git a/app/ios/FcmServiceExtension/FcmServiceExtension.entitlements b/app/ios/FcmServiceExtension/FcmServiceExtension.entitlements
new file mode 100644
index 000000000..16800aca2
--- /dev/null
+++ b/app/ios/FcmServiceExtension/FcmServiceExtension.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.application-groups
+
+ group.net.yumnumm.eqmonitor
+
+
+
diff --git a/app/ios/FcmServiceExtension/Info.plist b/app/ios/FcmServiceExtension/Info.plist
index 7d7e9e5d9..57421ebf9 100644
--- a/app/ios/FcmServiceExtension/Info.plist
+++ b/app/ios/FcmServiceExtension/Info.plist
@@ -7,7 +7,7 @@
NSExtensionPointIdentifier
com.apple.usernotifications.service
NSExtensionPrincipalClass
- NotificationService
+ $(PRODUCT_MODULE_NAME).NotificationService
diff --git a/app/ios/FcmServiceExtension/NotificationService.h b/app/ios/FcmServiceExtension/NotificationService.h
deleted file mode 100644
index fcaabddc2..000000000
--- a/app/ios/FcmServiceExtension/NotificationService.h
+++ /dev/null
@@ -1,12 +0,0 @@
-//
-// NotificationService.h
-// FcmServiceExtension
-//
-// Created by 尾上 遼太朗 on 2023/12/05.
-//
-
-#import
-
-@interface NotificationService : UNNotificationServiceExtension
-
-@end
diff --git a/app/ios/FcmServiceExtension/NotificationService.m b/app/ios/FcmServiceExtension/NotificationService.m
deleted file mode 100644
index 9af1aba78..000000000
--- a/app/ios/FcmServiceExtension/NotificationService.m
+++ /dev/null
@@ -1,46 +0,0 @@
-#import "NotificationService.h"
-#import "FirebaseMessaging.h"
-// #import "FirebaseAuth.h" // Add this line if you are using FirebaseAuth phone authentication
-// #import // Add this line if you are using FirebaseAuth phone authentication
-
-@interface NotificationService ()
-
-@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
-@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
-
-@end
-
-@implementation NotificationService
-
-/* Uncomment this if you are using Firebase Auth
-- (BOOL)application:(UIApplication *)app
- openURL:(NSURL *)url
- options:(NSDictionary *)options {
- if ([[FIRAuth auth] canHandleURL:url]) {
- return YES;
- }
- return NO;
-}
-
-- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts {
- for (UIOpenURLContext *urlContext in URLContexts) {
- [FIRAuth.auth canHandleURL:urlContext.URL];
- }
-}
-*/
-
-- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
- self.contentHandler = contentHandler;
- self.bestAttemptContent = [request.content mutableCopy];
-
- // Modify the notification content here...
- [[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent withContentHandler:contentHandler];
-}
-
-- (void)serviceExtensionTimeWillExpire {
- // Called just before the extension will be terminated by the system.
- // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
- self.contentHandler(self.bestAttemptContent);
-}
-
-@end
diff --git a/app/ios/FcmServiceExtension/NotificationService.swift b/app/ios/FcmServiceExtension/NotificationService.swift
new file mode 100644
index 000000000..a84bcd965
--- /dev/null
+++ b/app/ios/FcmServiceExtension/NotificationService.swift
@@ -0,0 +1,149 @@
+//
+// NotificationService.swift
+// FcmServiceExtension
+//
+// Created by 尾上 遼太朗 on 2024/05/23.
+//
+
+import Gzip
+import UserNotifications
+
+class NotificationService: UNNotificationServiceExtension {
+
+ var contentHandler: ((UNNotificationContent) -> Void)?
+ var bestAttemptContent: UNMutableNotificationContent?
+
+ override func didReceive(
+ _ request: UNNotificationRequest,
+ withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
+ ) {
+ self.contentHandler = contentHandler
+ bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
+
+ let notificationSettings = try? loadNotificationSettings()
+ let payload = request.content.userInfo["payload"] as? String
+ if notificationSettings == nil || payload == nil {
+ contentHandler(bestAttemptContent!)
+ return
+ }
+
+ /* DEBUG */
+ bestAttemptContent!.interruptionLevel = .critical
+ /* DEBUG END*/
+
+ let notificationPayload = try? decodePayload(payload: payload!)
+ if notificationPayload == nil {
+ contentHandler(bestAttemptContent!)
+ return
+ }
+ /* DEBUG */
+ // notificationPayloadをJSON化
+ let encoder = JSONEncoder()
+ encoder.outputFormatting = .prettyPrinted
+
+ let jsonData = try!
+ encoder.encode(notificationPayload)
+
+ let jsonString = String(data: jsonData, encoding: .utf8)!
+ bestAttemptContent!.body = bestAttemptContent!.body + "\n" + jsonString
+
+ contentHandler(bestAttemptContent!)
+ return
+ /* DEBUG END */
+
+ // EEW
+ if notificationPayload!.type == .eew
+ {
+ var shouldSilent = false
+ var shouldCritical = true // false
+
+ // 最大震度の検証
+ if notificationPayload!.eewInformation.maxIntensity.rawValue
+ >= notificationSettings!.eewSettings.emergencyIntensity.rawValue
+ {
+ shouldCritical = true
+ }
+ if notificationPayload!.eewInformation.maxIntensity.rawValue
+ <= notificationSettings!.eewSettings.silentIntensity.rawValue
+ {
+ shouldSilent = true
+ }
+ var replaceSubTitle: String?
+ // 各地域ごとの検証
+ for area in notificationPayload!.eewInformation.regionIntensities {
+ let matchedArea = notificationSettings!.eewSettings.regions.first(where: {
+ $0.code == area.code
+ })
+ if matchedArea != nil {
+ if area.intensity.rawValue >= matchedArea!.emergencyIntensity.rawValue {
+ shouldCritical = true
+ }
+ if area.intensity.rawValue <= matchedArea!.silentIntensity.rawValue {
+ shouldSilent = true
+ }
+ if matchedArea!.isMain {
+ replaceSubTitle = "\(matchedArea!.name)で予想震度\(area.intensity)"
+ if area.hasArrivalTime {
+ let arrivalTime = area.arrivalTime.date
+ let now = Date()
+ let diffInSeconds = arrivalTime.timeIntervalSince(now)
+ if diffInSeconds > 0 {
+ replaceSubTitle = "あと\(diffInSeconds)秒で到達 \(replaceSubTitle!)"
+ } else {
+ replaceSubTitle = "到達済み \(replaceSubTitle!)"
+ }
+ }
+ }
+ }
+ }
+ if shouldSilent {
+ bestAttemptContent!.sound = nil
+ bestAttemptContent!.interruptionLevel = .passive
+ }
+ if shouldCritical {
+ bestAttemptContent!.interruptionLevel = .critical
+ }
+
+ if replaceSubTitle != nil {
+ bestAttemptContent!.subtitle = replaceSubTitle!
+ }
+
+ contentHandler(bestAttemptContent!)
+ return
+
+ }
+
+ }
+
+ override func serviceExtensionTimeWillExpire() {
+ // Called just before the extension will be terminated by the system.
+ // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
+ if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
+ contentHandler(bestAttemptContent)
+ }
+ }
+
+ /// ProtoBufのデコード
+ func decodePayload(payload: String) throws -> Eqmonitor_NotificationPayload {
+ // decode base64
+ let base64String = payload
+ let decodedData = Data(base64Encoded: base64String)!
+ // gunzip
+ let gunzippedData = try! decodedData.gunzipped()
+ // decode protobuf
+ let notificationPayload = try Eqmonitor_NotificationPayload(serializedData: gunzippedData)
+ return notificationPayload
+ }
+
+ // 設定の読み出し
+ func loadNotificationSettings() throws -> Eqmonitor_NotificationSettings {
+ let appGroup = UserDefaults(suiteName: "group.net.yumnumm.eqmonitor")!
+ let value = appGroup.string(forKey: "notification_settings")
+ if let value = value {
+ let data = Data(base64Encoded: value)!
+ return try Eqmonitor_NotificationSettings(serializedData: data)
+ }
+ throw NSError()
+
+ }
+}
diff --git a/app/ios/FcmServiceExtension/Protocol Buffers/notification_payload.pb.swift b/app/ios/FcmServiceExtension/Protocol Buffers/notification_payload.pb.swift
new file mode 100644
index 000000000..99eb03214
--- /dev/null
+++ b/app/ios/FcmServiceExtension/Protocol Buffers/notification_payload.pb.swift
@@ -0,0 +1,690 @@
+// DO NOT EDIT.
+// swift-format-ignore-file
+//
+// Generated by the Swift generator plugin for the protocol buffer compiler.
+// Source: notification_payload.proto
+//
+// For information on using the generated types, please see the documentation:
+// https://github.com/apple/swift-protobuf/
+
+import Foundation
+import SwiftProtobuf
+
+// If the compiler emits an error on this type, it is because this file
+// was generated by a version of the `protoc` Swift plug-in that is
+// incompatible with the version of SwiftProtobuf to which you are linking.
+// Please ensure that you are building against the same version of the API
+// that was used to generate this file.
+fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
+ struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
+ typealias Version = _2
+}
+
+enum Eqmonitor_JmaIntensity: SwiftProtobuf.Enum {
+ typealias RawValue = Int
+ case unspecified // = 0
+ case jmaIntensity0 // = 10
+ case jmaIntensity1 // = 20
+ case jmaIntensity2 // = 30
+ case jmaIntensity3 // = 40
+ case jmaIntensity4 // = 45
+ case jmaIntensity5Minus // = 50
+ case jmaIntensity5Plus // = 55
+ case jmaIntensity6Minus // = 60
+ case jmaIntensity6Plus // = 65
+ case jmaIntensity7 // = 70
+ case UNRECOGNIZED(Int)
+
+ init() {
+ self = .unspecified
+ }
+
+ init?(rawValue: Int) {
+ switch rawValue {
+ case 0: self = .unspecified
+ case 10: self = .jmaIntensity0
+ case 20: self = .jmaIntensity1
+ case 30: self = .jmaIntensity2
+ case 40: self = .jmaIntensity3
+ case 45: self = .jmaIntensity4
+ case 50: self = .jmaIntensity5Minus
+ case 55: self = .jmaIntensity5Plus
+ case 60: self = .jmaIntensity6Minus
+ case 65: self = .jmaIntensity6Plus
+ case 70: self = .jmaIntensity7
+ default: self = .UNRECOGNIZED(rawValue)
+ }
+ }
+
+ var rawValue: Int {
+ switch self {
+ case .unspecified: return 0
+ case .jmaIntensity0: return 10
+ case .jmaIntensity1: return 20
+ case .jmaIntensity2: return 30
+ case .jmaIntensity3: return 40
+ case .jmaIntensity4: return 45
+ case .jmaIntensity5Minus: return 50
+ case .jmaIntensity5Plus: return 55
+ case .jmaIntensity6Minus: return 60
+ case .jmaIntensity6Plus: return 65
+ case .jmaIntensity7: return 70
+ case .UNRECOGNIZED(let i): return i
+ }
+ }
+
+}
+
+#if swift(>=4.2)
+
+extension Eqmonitor_JmaIntensity: CaseIterable {
+ // The compiler won't synthesize support with the UNRECOGNIZED case.
+ static let allCases: [Eqmonitor_JmaIntensity] = [
+ .unspecified,
+ .jmaIntensity0,
+ .jmaIntensity1,
+ .jmaIntensity2,
+ .jmaIntensity3,
+ .jmaIntensity4,
+ .jmaIntensity5Minus,
+ .jmaIntensity5Plus,
+ .jmaIntensity6Minus,
+ .jmaIntensity6Plus,
+ .jmaIntensity7,
+ ]
+}
+
+#endif // swift(>=4.2)
+
+struct Eqmonitor_NotificationPayload {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var eventID: String = String()
+
+ var type: Eqmonitor_NotificationPayload.TypeEnum = .unspecified
+
+ var information: Eqmonitor_NotificationPayload.OneOf_Information? = nil
+
+ var eewInformation: Eqmonitor_NotificationPayload.EewInformation {
+ get {
+ if case .eewInformation(let v)? = information {return v}
+ return Eqmonitor_NotificationPayload.EewInformation()
+ }
+ set {information = .eewInformation(newValue)}
+ }
+
+ var earthquakeInformation: Eqmonitor_NotificationPayload.EarthquakeInformation {
+ get {
+ if case .earthquakeInformation(let v)? = information {return v}
+ return Eqmonitor_NotificationPayload.EarthquakeInformation()
+ }
+ set {information = .earthquakeInformation(newValue)}
+ }
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ enum OneOf_Information: Equatable {
+ case eewInformation(Eqmonitor_NotificationPayload.EewInformation)
+ case earthquakeInformation(Eqmonitor_NotificationPayload.EarthquakeInformation)
+
+ #if !swift(>=4.1)
+ static func ==(lhs: Eqmonitor_NotificationPayload.OneOf_Information, rhs: Eqmonitor_NotificationPayload.OneOf_Information) -> Bool {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch (lhs, rhs) {
+ case (.eewInformation, .eewInformation): return {
+ guard case .eewInformation(let l) = lhs, case .eewInformation(let r) = rhs else { preconditionFailure() }
+ return l == r
+ }()
+ case (.earthquakeInformation, .earthquakeInformation): return {
+ guard case .earthquakeInformation(let l) = lhs, case .earthquakeInformation(let r) = rhs else { preconditionFailure() }
+ return l == r
+ }()
+ default: return false
+ }
+ }
+ #endif
+ }
+
+ enum TypeEnum: SwiftProtobuf.Enum {
+ typealias RawValue = Int
+ case unspecified // = 0
+ case earthquake // = 1
+ case eew // = 2
+ case UNRECOGNIZED(Int)
+
+ init() {
+ self = .unspecified
+ }
+
+ init?(rawValue: Int) {
+ switch rawValue {
+ case 0: self = .unspecified
+ case 1: self = .earthquake
+ case 2: self = .eew
+ default: self = .UNRECOGNIZED(rawValue)
+ }
+ }
+
+ var rawValue: Int {
+ switch self {
+ case .unspecified: return 0
+ case .earthquake: return 1
+ case .eew: return 2
+ case .UNRECOGNIZED(let i): return i
+ }
+ }
+
+ }
+
+ struct EewInformation {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var hypoInformation: Eqmonitor_NotificationPayload.HypoInformation {
+ get {return _hypoInformation ?? Eqmonitor_NotificationPayload.HypoInformation()}
+ set {_hypoInformation = newValue}
+ }
+ /// Returns true if `hypoInformation` has been explicitly set.
+ var hasHypoInformation: Bool {return self._hypoInformation != nil}
+ /// Clears the value of `hypoInformation`. Subsequent reads from it will return its default value.
+ mutating func clearHypoInformation() {self._hypoInformation = nil}
+
+ var maxIntensity: Eqmonitor_JmaIntensity {
+ get {return _maxIntensity ?? .unspecified}
+ set {_maxIntensity = newValue}
+ }
+ /// Returns true if `maxIntensity` has been explicitly set.
+ var hasMaxIntensity: Bool {return self._maxIntensity != nil}
+ /// Clears the value of `maxIntensity`. Subsequent reads from it will return its default value.
+ mutating func clearMaxIntensity() {self._maxIntensity = nil}
+
+ var regionIntensities: [Eqmonitor_NotificationPayload.EewRegionIntensity] = []
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ init() {}
+
+ fileprivate var _hypoInformation: Eqmonitor_NotificationPayload.HypoInformation? = nil
+ fileprivate var _maxIntensity: Eqmonitor_JmaIntensity? = nil
+ }
+
+ struct EarthquakeInformation {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var hypoInformation: Eqmonitor_NotificationPayload.HypoInformation {
+ get {return _hypoInformation ?? Eqmonitor_NotificationPayload.HypoInformation()}
+ set {_hypoInformation = newValue}
+ }
+ /// Returns true if `hypoInformation` has been explicitly set.
+ var hasHypoInformation: Bool {return self._hypoInformation != nil}
+ /// Clears the value of `hypoInformation`. Subsequent reads from it will return its default value.
+ mutating func clearHypoInformation() {self._hypoInformation = nil}
+
+ var maxIntensity: Eqmonitor_JmaIntensity {
+ get {return _maxIntensity ?? .unspecified}
+ set {_maxIntensity = newValue}
+ }
+ /// Returns true if `maxIntensity` has been explicitly set.
+ var hasMaxIntensity: Bool {return self._maxIntensity != nil}
+ /// Clears the value of `maxIntensity`. Subsequent reads from it will return its default value.
+ mutating func clearMaxIntensity() {self._maxIntensity = nil}
+
+ var regionIntensities: [Eqmonitor_NotificationPayload.RegionIntensity] = []
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ init() {}
+
+ fileprivate var _hypoInformation: Eqmonitor_NotificationPayload.HypoInformation? = nil
+ fileprivate var _maxIntensity: Eqmonitor_JmaIntensity? = nil
+ }
+
+ struct RegionIntensity {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var code: String = String()
+
+ var intensity: Eqmonitor_JmaIntensity = .unspecified
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ init() {}
+ }
+
+ struct EewRegionIntensity {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var code: String = String()
+
+ var intensity: Eqmonitor_JmaIntensity = .unspecified
+
+ var arrivalTime: SwiftProtobuf.Google_Protobuf_Timestamp {
+ get {return _arrivalTime ?? SwiftProtobuf.Google_Protobuf_Timestamp()}
+ set {_arrivalTime = newValue}
+ }
+ /// Returns true if `arrivalTime` has been explicitly set.
+ var hasArrivalTime: Bool {return self._arrivalTime != nil}
+ /// Clears the value of `arrivalTime`. Subsequent reads from it will return its default value.
+ mutating func clearArrivalTime() {self._arrivalTime = nil}
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ init() {}
+
+ fileprivate var _arrivalTime: SwiftProtobuf.Google_Protobuf_Timestamp? = nil
+ }
+
+ struct HypoInformation {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var code: Int32 = 0
+
+ var name: String = String()
+
+ var latitude: Float = 0
+
+ var longitude: Float = 0
+
+ var depth: Int32 = 0
+
+ var magnitude: Float = 0
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ init() {}
+ }
+
+ init() {}
+}
+
+#if swift(>=4.2)
+
+extension Eqmonitor_NotificationPayload.TypeEnum: CaseIterable {
+ // The compiler won't synthesize support with the UNRECOGNIZED case.
+ static let allCases: [Eqmonitor_NotificationPayload.TypeEnum] = [
+ .unspecified,
+ .earthquake,
+ .eew,
+ ]
+}
+
+#endif // swift(>=4.2)
+
+#if swift(>=5.5) && canImport(_Concurrency)
+extension Eqmonitor_JmaIntensity: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload.OneOf_Information: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload.TypeEnum: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload.EewInformation: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload.EarthquakeInformation: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload.RegionIntensity: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload.EewRegionIntensity: @unchecked Sendable {}
+extension Eqmonitor_NotificationPayload.HypoInformation: @unchecked Sendable {}
+#endif // swift(>=5.5) && canImport(_Concurrency)
+
+// MARK: - Code below here is support for the SwiftProtobuf runtime.
+
+fileprivate let _protobuf_package = "eqmonitor"
+
+extension Eqmonitor_JmaIntensity: SwiftProtobuf._ProtoNameProviding {
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 0: .same(proto: "JMA_INTENSITY_UNSPECIFIED"),
+ 10: .same(proto: "JMA_INTENSITY_0"),
+ 20: .same(proto: "JMA_INTENSITY_1"),
+ 30: .same(proto: "JMA_INTENSITY_2"),
+ 40: .same(proto: "JMA_INTENSITY_3"),
+ 45: .same(proto: "JMA_INTENSITY_4"),
+ 50: .same(proto: "JMA_INTENSITY_5_MINUS"),
+ 55: .same(proto: "JMA_INTENSITY_5_PLUS"),
+ 60: .same(proto: "JMA_INTENSITY_6_MINUS"),
+ 65: .same(proto: "JMA_INTENSITY_6_PLUS"),
+ 70: .same(proto: "JMA_INTENSITY_7"),
+ ]
+}
+
+extension Eqmonitor_NotificationPayload: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = _protobuf_package + ".NotificationPayload"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .standard(proto: "event_id"),
+ 2: .same(proto: "type"),
+ 3: .standard(proto: "eew_information"),
+ 4: .standard(proto: "earthquake_information"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularStringField(value: &self.eventID) }()
+ case 2: try { try decoder.decodeSingularEnumField(value: &self.type) }()
+ case 3: try {
+ var v: Eqmonitor_NotificationPayload.EewInformation?
+ var hadOneofValue = false
+ if let current = self.information {
+ hadOneofValue = true
+ if case .eewInformation(let m) = current {v = m}
+ }
+ try decoder.decodeSingularMessageField(value: &v)
+ if let v = v {
+ if hadOneofValue {try decoder.handleConflictingOneOf()}
+ self.information = .eewInformation(v)
+ }
+ }()
+ case 4: try {
+ var v: Eqmonitor_NotificationPayload.EarthquakeInformation?
+ var hadOneofValue = false
+ if let current = self.information {
+ hadOneofValue = true
+ if case .earthquakeInformation(let m) = current {v = m}
+ }
+ try decoder.decodeSingularMessageField(value: &v)
+ if let v = v {
+ if hadOneofValue {try decoder.handleConflictingOneOf()}
+ self.information = .earthquakeInformation(v)
+ }
+ }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every if/case branch local when no optimizations
+ // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
+ // https://github.com/apple/swift-protobuf/issues/1182
+ if !self.eventID.isEmpty {
+ try visitor.visitSingularStringField(value: self.eventID, fieldNumber: 1)
+ }
+ if self.type != .unspecified {
+ try visitor.visitSingularEnumField(value: self.type, fieldNumber: 2)
+ }
+ switch self.information {
+ case .eewInformation?: try {
+ guard case .eewInformation(let v)? = self.information else { preconditionFailure() }
+ try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
+ }()
+ case .earthquakeInformation?: try {
+ guard case .earthquakeInformation(let v)? = self.information else { preconditionFailure() }
+ try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
+ }()
+ case nil: break
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationPayload, rhs: Eqmonitor_NotificationPayload) -> Bool {
+ if lhs.eventID != rhs.eventID {return false}
+ if lhs.type != rhs.type {return false}
+ if lhs.information != rhs.information {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationPayload.TypeEnum: SwiftProtobuf._ProtoNameProviding {
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 0: .same(proto: "TYPE_UNSPECIFIED"),
+ 1: .same(proto: "TYPE_EARTHQUAKE"),
+ 2: .same(proto: "TYPE_EEW"),
+ ]
+}
+
+extension Eqmonitor_NotificationPayload.EewInformation: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationPayload.protoMessageName + ".EewInformation"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .standard(proto: "hypo_information"),
+ 2: .standard(proto: "max_intensity"),
+ 3: .standard(proto: "region_intensities"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularMessageField(value: &self._hypoInformation) }()
+ case 2: try { try decoder.decodeSingularEnumField(value: &self._maxIntensity) }()
+ case 3: try { try decoder.decodeRepeatedMessageField(value: &self.regionIntensities) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every if/case branch local when no optimizations
+ // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
+ // https://github.com/apple/swift-protobuf/issues/1182
+ try { if let v = self._hypoInformation {
+ try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
+ } }()
+ try { if let v = self._maxIntensity {
+ try visitor.visitSingularEnumField(value: v, fieldNumber: 2)
+ } }()
+ if !self.regionIntensities.isEmpty {
+ try visitor.visitRepeatedMessageField(value: self.regionIntensities, fieldNumber: 3)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationPayload.EewInformation, rhs: Eqmonitor_NotificationPayload.EewInformation) -> Bool {
+ if lhs._hypoInformation != rhs._hypoInformation {return false}
+ if lhs._maxIntensity != rhs._maxIntensity {return false}
+ if lhs.regionIntensities != rhs.regionIntensities {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationPayload.EarthquakeInformation: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationPayload.protoMessageName + ".EarthquakeInformation"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .standard(proto: "hypo_information"),
+ 2: .standard(proto: "max_intensity"),
+ 3: .standard(proto: "region_intensities"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularMessageField(value: &self._hypoInformation) }()
+ case 2: try { try decoder.decodeSingularEnumField(value: &self._maxIntensity) }()
+ case 3: try { try decoder.decodeRepeatedMessageField(value: &self.regionIntensities) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every if/case branch local when no optimizations
+ // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
+ // https://github.com/apple/swift-protobuf/issues/1182
+ try { if let v = self._hypoInformation {
+ try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
+ } }()
+ try { if let v = self._maxIntensity {
+ try visitor.visitSingularEnumField(value: v, fieldNumber: 2)
+ } }()
+ if !self.regionIntensities.isEmpty {
+ try visitor.visitRepeatedMessageField(value: self.regionIntensities, fieldNumber: 3)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationPayload.EarthquakeInformation, rhs: Eqmonitor_NotificationPayload.EarthquakeInformation) -> Bool {
+ if lhs._hypoInformation != rhs._hypoInformation {return false}
+ if lhs._maxIntensity != rhs._maxIntensity {return false}
+ if lhs.regionIntensities != rhs.regionIntensities {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationPayload.RegionIntensity: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationPayload.protoMessageName + ".RegionIntensity"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .same(proto: "code"),
+ 2: .same(proto: "intensity"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularStringField(value: &self.code) }()
+ case 2: try { try decoder.decodeSingularEnumField(value: &self.intensity) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ if !self.code.isEmpty {
+ try visitor.visitSingularStringField(value: self.code, fieldNumber: 1)
+ }
+ if self.intensity != .unspecified {
+ try visitor.visitSingularEnumField(value: self.intensity, fieldNumber: 2)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationPayload.RegionIntensity, rhs: Eqmonitor_NotificationPayload.RegionIntensity) -> Bool {
+ if lhs.code != rhs.code {return false}
+ if lhs.intensity != rhs.intensity {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationPayload.EewRegionIntensity: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationPayload.protoMessageName + ".EewRegionIntensity"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .same(proto: "code"),
+ 2: .same(proto: "intensity"),
+ 3: .standard(proto: "arrival_time"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularStringField(value: &self.code) }()
+ case 2: try { try decoder.decodeSingularEnumField(value: &self.intensity) }()
+ case 3: try { try decoder.decodeSingularMessageField(value: &self._arrivalTime) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every if/case branch local when no optimizations
+ // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
+ // https://github.com/apple/swift-protobuf/issues/1182
+ if !self.code.isEmpty {
+ try visitor.visitSingularStringField(value: self.code, fieldNumber: 1)
+ }
+ if self.intensity != .unspecified {
+ try visitor.visitSingularEnumField(value: self.intensity, fieldNumber: 2)
+ }
+ try { if let v = self._arrivalTime {
+ try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
+ } }()
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationPayload.EewRegionIntensity, rhs: Eqmonitor_NotificationPayload.EewRegionIntensity) -> Bool {
+ if lhs.code != rhs.code {return false}
+ if lhs.intensity != rhs.intensity {return false}
+ if lhs._arrivalTime != rhs._arrivalTime {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationPayload.HypoInformation: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationPayload.protoMessageName + ".HypoInformation"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .same(proto: "code"),
+ 2: .same(proto: "name"),
+ 3: .same(proto: "latitude"),
+ 4: .same(proto: "longitude"),
+ 5: .same(proto: "depth"),
+ 6: .same(proto: "magnitude"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularInt32Field(value: &self.code) }()
+ case 2: try { try decoder.decodeSingularStringField(value: &self.name) }()
+ case 3: try { try decoder.decodeSingularFloatField(value: &self.latitude) }()
+ case 4: try { try decoder.decodeSingularFloatField(value: &self.longitude) }()
+ case 5: try { try decoder.decodeSingularInt32Field(value: &self.depth) }()
+ case 6: try { try decoder.decodeSingularFloatField(value: &self.magnitude) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ if self.code != 0 {
+ try visitor.visitSingularInt32Field(value: self.code, fieldNumber: 1)
+ }
+ if !self.name.isEmpty {
+ try visitor.visitSingularStringField(value: self.name, fieldNumber: 2)
+ }
+ if self.latitude != 0 {
+ try visitor.visitSingularFloatField(value: self.latitude, fieldNumber: 3)
+ }
+ if self.longitude != 0 {
+ try visitor.visitSingularFloatField(value: self.longitude, fieldNumber: 4)
+ }
+ if self.depth != 0 {
+ try visitor.visitSingularInt32Field(value: self.depth, fieldNumber: 5)
+ }
+ if self.magnitude != 0 {
+ try visitor.visitSingularFloatField(value: self.magnitude, fieldNumber: 6)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationPayload.HypoInformation, rhs: Eqmonitor_NotificationPayload.HypoInformation) -> Bool {
+ if lhs.code != rhs.code {return false}
+ if lhs.name != rhs.name {return false}
+ if lhs.latitude != rhs.latitude {return false}
+ if lhs.longitude != rhs.longitude {return false}
+ if lhs.depth != rhs.depth {return false}
+ if lhs.magnitude != rhs.magnitude {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
diff --git a/app/ios/FcmServiceExtension/Protocol Buffers/notification_payload.proto b/app/ios/FcmServiceExtension/Protocol Buffers/notification_payload.proto
new file mode 100644
index 000000000..b806b2c04
--- /dev/null
+++ b/app/ios/FcmServiceExtension/Protocol Buffers/notification_payload.proto
@@ -0,0 +1,67 @@
+
+syntax = "proto3";
+import "google/protobuf/timestamp.proto";
+
+package eqmonitor;
+
+message NotificationPayload {
+ string event_id = 1;
+ Type type = 2;
+
+ oneof information {
+ EewInformation eew_information = 3;
+ EarthquakeInformation earthquake_information = 4;
+ }
+
+ enum Type {
+ TYPE_UNSPECIFIED = 0;
+ TYPE_EARTHQUAKE = 1;
+ TYPE_EEW = 2;
+ }
+
+ message EewInformation {
+ HypoInformation hypo_information = 1;
+ optional JmaIntensity max_intensity = 2;
+ repeated EewRegionIntensity region_intensities = 3;
+ }
+
+ message EarthquakeInformation {
+ HypoInformation hypo_information = 1;
+ optional JmaIntensity max_intensity = 2;
+ repeated RegionIntensity region_intensities = 3;
+ }
+
+ message RegionIntensity {
+ string code = 1;
+ JmaIntensity intensity = 2;
+ }
+
+ message EewRegionIntensity {
+ string code = 1;
+ JmaIntensity intensity = 2;
+ optional google.protobuf.Timestamp arrival_time = 3;
+ }
+
+ message HypoInformation {
+ int32 code = 1;
+ string name = 2;
+ float latitude = 3;
+ float longitude = 4;
+ int32 depth = 5;
+ float magnitude = 6;
+ }
+}
+
+enum JmaIntensity {
+ JMA_INTENSITY_UNSPECIFIED = 0;
+ JMA_INTENSITY_0 = 10;
+ JMA_INTENSITY_1 = 20;
+ JMA_INTENSITY_2 = 30;
+ JMA_INTENSITY_3 = 40;
+ JMA_INTENSITY_4 = 45;
+ JMA_INTENSITY_5_MINUS = 50;
+ JMA_INTENSITY_5_PLUS = 55;
+ JMA_INTENSITY_6_MINUS = 60;
+ JMA_INTENSITY_6_PLUS = 65;
+ JMA_INTENSITY_7 = 70;
+}
\ No newline at end of file
diff --git a/app/ios/FcmServiceExtension/Protocol Buffers/notification_settings.pb.swift b/app/ios/FcmServiceExtension/Protocol Buffers/notification_settings.pb.swift
new file mode 100644
index 000000000..0b47a4f65
--- /dev/null
+++ b/app/ios/FcmServiceExtension/Protocol Buffers/notification_settings.pb.swift
@@ -0,0 +1,420 @@
+// DO NOT EDIT.
+// swift-format-ignore-file
+//
+// Generated by the Swift generator plugin for the protocol buffer compiler.
+// Source: notification_settings.proto
+//
+// For information on using the generated types, please see the documentation:
+// https://github.com/apple/swift-protobuf/
+
+import Foundation
+import SwiftProtobuf
+
+// If the compiler emits an error on this type, it is because this file
+// was generated by a version of the `protoc` Swift plug-in that is
+// incompatible with the version of SwiftProtobuf to which you are linking.
+// Please ensure that you are building against the same version of the API
+// that was used to generate this file.
+fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
+ struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
+ typealias Version = _2
+}
+
+struct Eqmonitor_NotificationSettings {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var eewSettings: Eqmonitor_NotificationSettings.EewSettings {
+ get {return _eewSettings ?? Eqmonitor_NotificationSettings.EewSettings()}
+ set {_eewSettings = newValue}
+ }
+ /// Returns true if `eewSettings` has been explicitly set.
+ var hasEewSettings: Bool {return self._eewSettings != nil}
+ /// Clears the value of `eewSettings`. Subsequent reads from it will return its default value.
+ mutating func clearEewSettings() {self._eewSettings = nil}
+
+ var earthquakeSettings: Eqmonitor_NotificationSettings.EarthquakeSettings {
+ get {return _earthquakeSettings ?? Eqmonitor_NotificationSettings.EarthquakeSettings()}
+ set {_earthquakeSettings = newValue}
+ }
+ /// Returns true if `earthquakeSettings` has been explicitly set.
+ var hasEarthquakeSettings: Bool {return self._earthquakeSettings != nil}
+ /// Clears the value of `earthquakeSettings`. Subsequent reads from it will return its default value.
+ mutating func clearEarthquakeSettings() {self._earthquakeSettings = nil}
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ struct EewSettings {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var emergencyIntensity: Eqmonitor_JmaIntensity {
+ get {return _emergencyIntensity ?? .unspecified}
+ set {_emergencyIntensity = newValue}
+ }
+ /// Returns true if `emergencyIntensity` has been explicitly set.
+ var hasEmergencyIntensity: Bool {return self._emergencyIntensity != nil}
+ /// Clears the value of `emergencyIntensity`. Subsequent reads from it will return its default value.
+ mutating func clearEmergencyIntensity() {self._emergencyIntensity = nil}
+
+ var silentIntensity: Eqmonitor_JmaIntensity {
+ get {return _silentIntensity ?? .unspecified}
+ set {_silentIntensity = newValue}
+ }
+ /// Returns true if `silentIntensity` has been explicitly set.
+ var hasSilentIntensity: Bool {return self._silentIntensity != nil}
+ /// Clears the value of `silentIntensity`. Subsequent reads from it will return its default value.
+ mutating func clearSilentIntensity() {self._silentIntensity = nil}
+
+ var regions: [Eqmonitor_NotificationSettings.EewSettings.Region] = []
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ struct Region {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var code: String = String()
+
+ var name: String = String()
+
+ var emergencyIntensity: Eqmonitor_JmaIntensity = .unspecified
+
+ var silentIntensity: Eqmonitor_JmaIntensity = .unspecified
+
+ var isMain: Bool = false
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ init() {}
+ }
+
+ init() {}
+
+ fileprivate var _emergencyIntensity: Eqmonitor_JmaIntensity? = nil
+ fileprivate var _silentIntensity: Eqmonitor_JmaIntensity? = nil
+ }
+
+ struct EarthquakeSettings {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var emergencyIntensity: Eqmonitor_JmaIntensity {
+ get {return _emergencyIntensity ?? .unspecified}
+ set {_emergencyIntensity = newValue}
+ }
+ /// Returns true if `emergencyIntensity` has been explicitly set.
+ var hasEmergencyIntensity: Bool {return self._emergencyIntensity != nil}
+ /// Clears the value of `emergencyIntensity`. Subsequent reads from it will return its default value.
+ mutating func clearEmergencyIntensity() {self._emergencyIntensity = nil}
+
+ var silentIntensity: Eqmonitor_JmaIntensity {
+ get {return _silentIntensity ?? .unspecified}
+ set {_silentIntensity = newValue}
+ }
+ /// Returns true if `silentIntensity` has been explicitly set.
+ var hasSilentIntensity: Bool {return self._silentIntensity != nil}
+ /// Clears the value of `silentIntensity`. Subsequent reads from it will return its default value.
+ mutating func clearSilentIntensity() {self._silentIntensity = nil}
+
+ var regions: [Eqmonitor_NotificationSettings.EarthquakeSettings.Region] = []
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ struct Region {
+ // SwiftProtobuf.Message conformance is added in an extension below. See the
+ // `Message` and `Message+*Additions` files in the SwiftProtobuf library for
+ // methods supported on all messages.
+
+ var code: String = String()
+
+ var name: String = String()
+
+ var emergencyIntensity: Eqmonitor_JmaIntensity = .unspecified
+
+ var silentIntensity: Eqmonitor_JmaIntensity = .unspecified
+
+ var isMain: Bool = false
+
+ var unknownFields = SwiftProtobuf.UnknownStorage()
+
+ init() {}
+ }
+
+ init() {}
+
+ fileprivate var _emergencyIntensity: Eqmonitor_JmaIntensity? = nil
+ fileprivate var _silentIntensity: Eqmonitor_JmaIntensity? = nil
+ }
+
+ init() {}
+
+ fileprivate var _eewSettings: Eqmonitor_NotificationSettings.EewSettings? = nil
+ fileprivate var _earthquakeSettings: Eqmonitor_NotificationSettings.EarthquakeSettings? = nil
+}
+
+#if swift(>=5.5) && canImport(_Concurrency)
+extension Eqmonitor_NotificationSettings: @unchecked Sendable {}
+extension Eqmonitor_NotificationSettings.EewSettings: @unchecked Sendable {}
+extension Eqmonitor_NotificationSettings.EewSettings.Region: @unchecked Sendable {}
+extension Eqmonitor_NotificationSettings.EarthquakeSettings: @unchecked Sendable {}
+extension Eqmonitor_NotificationSettings.EarthquakeSettings.Region: @unchecked Sendable {}
+#endif // swift(>=5.5) && canImport(_Concurrency)
+
+// MARK: - Code below here is support for the SwiftProtobuf runtime.
+
+fileprivate let _protobuf_package = "eqmonitor"
+
+extension Eqmonitor_NotificationSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = _protobuf_package + ".NotificationSettings"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .standard(proto: "eew_settings"),
+ 2: .standard(proto: "earthquake_settings"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularMessageField(value: &self._eewSettings) }()
+ case 2: try { try decoder.decodeSingularMessageField(value: &self._earthquakeSettings) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every if/case branch local when no optimizations
+ // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
+ // https://github.com/apple/swift-protobuf/issues/1182
+ try { if let v = self._eewSettings {
+ try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
+ } }()
+ try { if let v = self._earthquakeSettings {
+ try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
+ } }()
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationSettings, rhs: Eqmonitor_NotificationSettings) -> Bool {
+ if lhs._eewSettings != rhs._eewSettings {return false}
+ if lhs._earthquakeSettings != rhs._earthquakeSettings {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationSettings.EewSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationSettings.protoMessageName + ".EewSettings"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .standard(proto: "emergency_intensity"),
+ 2: .standard(proto: "silent_intensity"),
+ 3: .same(proto: "regions"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularEnumField(value: &self._emergencyIntensity) }()
+ case 2: try { try decoder.decodeSingularEnumField(value: &self._silentIntensity) }()
+ case 3: try { try decoder.decodeRepeatedMessageField(value: &self.regions) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every if/case branch local when no optimizations
+ // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
+ // https://github.com/apple/swift-protobuf/issues/1182
+ try { if let v = self._emergencyIntensity {
+ try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
+ } }()
+ try { if let v = self._silentIntensity {
+ try visitor.visitSingularEnumField(value: v, fieldNumber: 2)
+ } }()
+ if !self.regions.isEmpty {
+ try visitor.visitRepeatedMessageField(value: self.regions, fieldNumber: 3)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationSettings.EewSettings, rhs: Eqmonitor_NotificationSettings.EewSettings) -> Bool {
+ if lhs._emergencyIntensity != rhs._emergencyIntensity {return false}
+ if lhs._silentIntensity != rhs._silentIntensity {return false}
+ if lhs.regions != rhs.regions {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationSettings.EewSettings.Region: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationSettings.EewSettings.protoMessageName + ".Region"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .same(proto: "code"),
+ 2: .same(proto: "name"),
+ 3: .standard(proto: "emergency_intensity"),
+ 4: .standard(proto: "silent_intensity"),
+ 5: .standard(proto: "is_main"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularStringField(value: &self.code) }()
+ case 2: try { try decoder.decodeSingularStringField(value: &self.name) }()
+ case 3: try { try decoder.decodeSingularEnumField(value: &self.emergencyIntensity) }()
+ case 4: try { try decoder.decodeSingularEnumField(value: &self.silentIntensity) }()
+ case 5: try { try decoder.decodeSingularBoolField(value: &self.isMain) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ if !self.code.isEmpty {
+ try visitor.visitSingularStringField(value: self.code, fieldNumber: 1)
+ }
+ if !self.name.isEmpty {
+ try visitor.visitSingularStringField(value: self.name, fieldNumber: 2)
+ }
+ if self.emergencyIntensity != .unspecified {
+ try visitor.visitSingularEnumField(value: self.emergencyIntensity, fieldNumber: 3)
+ }
+ if self.silentIntensity != .unspecified {
+ try visitor.visitSingularEnumField(value: self.silentIntensity, fieldNumber: 4)
+ }
+ if self.isMain != false {
+ try visitor.visitSingularBoolField(value: self.isMain, fieldNumber: 5)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationSettings.EewSettings.Region, rhs: Eqmonitor_NotificationSettings.EewSettings.Region) -> Bool {
+ if lhs.code != rhs.code {return false}
+ if lhs.name != rhs.name {return false}
+ if lhs.emergencyIntensity != rhs.emergencyIntensity {return false}
+ if lhs.silentIntensity != rhs.silentIntensity {return false}
+ if lhs.isMain != rhs.isMain {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationSettings.EarthquakeSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationSettings.protoMessageName + ".EarthquakeSettings"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .standard(proto: "emergency_intensity"),
+ 2: .standard(proto: "silent_intensity"),
+ 3: .same(proto: "regions"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularEnumField(value: &self._emergencyIntensity) }()
+ case 2: try { try decoder.decodeSingularEnumField(value: &self._silentIntensity) }()
+ case 3: try { try decoder.decodeRepeatedMessageField(value: &self.regions) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every if/case branch local when no optimizations
+ // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
+ // https://github.com/apple/swift-protobuf/issues/1182
+ try { if let v = self._emergencyIntensity {
+ try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
+ } }()
+ try { if let v = self._silentIntensity {
+ try visitor.visitSingularEnumField(value: v, fieldNumber: 2)
+ } }()
+ if !self.regions.isEmpty {
+ try visitor.visitRepeatedMessageField(value: self.regions, fieldNumber: 3)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationSettings.EarthquakeSettings, rhs: Eqmonitor_NotificationSettings.EarthquakeSettings) -> Bool {
+ if lhs._emergencyIntensity != rhs._emergencyIntensity {return false}
+ if lhs._silentIntensity != rhs._silentIntensity {return false}
+ if lhs.regions != rhs.regions {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
+
+extension Eqmonitor_NotificationSettings.EarthquakeSettings.Region: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
+ static let protoMessageName: String = Eqmonitor_NotificationSettings.EarthquakeSettings.protoMessageName + ".Region"
+ static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
+ 1: .same(proto: "code"),
+ 2: .same(proto: "name"),
+ 3: .standard(proto: "emergency_intensity"),
+ 4: .standard(proto: "silent_intensity"),
+ 5: .standard(proto: "is_main"),
+ ]
+
+ mutating func decodeMessage(decoder: inout D) throws {
+ while let fieldNumber = try decoder.nextFieldNumber() {
+ // The use of inline closures is to circumvent an issue where the compiler
+ // allocates stack space for every case branch when no optimizations are
+ // enabled. https://github.com/apple/swift-protobuf/issues/1034
+ switch fieldNumber {
+ case 1: try { try decoder.decodeSingularStringField(value: &self.code) }()
+ case 2: try { try decoder.decodeSingularStringField(value: &self.name) }()
+ case 3: try { try decoder.decodeSingularEnumField(value: &self.emergencyIntensity) }()
+ case 4: try { try decoder.decodeSingularEnumField(value: &self.silentIntensity) }()
+ case 5: try { try decoder.decodeSingularBoolField(value: &self.isMain) }()
+ default: break
+ }
+ }
+ }
+
+ func traverse(visitor: inout V) throws {
+ if !self.code.isEmpty {
+ try visitor.visitSingularStringField(value: self.code, fieldNumber: 1)
+ }
+ if !self.name.isEmpty {
+ try visitor.visitSingularStringField(value: self.name, fieldNumber: 2)
+ }
+ if self.emergencyIntensity != .unspecified {
+ try visitor.visitSingularEnumField(value: self.emergencyIntensity, fieldNumber: 3)
+ }
+ if self.silentIntensity != .unspecified {
+ try visitor.visitSingularEnumField(value: self.silentIntensity, fieldNumber: 4)
+ }
+ if self.isMain != false {
+ try visitor.visitSingularBoolField(value: self.isMain, fieldNumber: 5)
+ }
+ try unknownFields.traverse(visitor: &visitor)
+ }
+
+ static func ==(lhs: Eqmonitor_NotificationSettings.EarthquakeSettings.Region, rhs: Eqmonitor_NotificationSettings.EarthquakeSettings.Region) -> Bool {
+ if lhs.code != rhs.code {return false}
+ if lhs.name != rhs.name {return false}
+ if lhs.emergencyIntensity != rhs.emergencyIntensity {return false}
+ if lhs.silentIntensity != rhs.silentIntensity {return false}
+ if lhs.isMain != rhs.isMain {return false}
+ if lhs.unknownFields != rhs.unknownFields {return false}
+ return true
+ }
+}
diff --git a/app/ios/FcmServiceExtension/Protocol Buffers/notification_settings.proto b/app/ios/FcmServiceExtension/Protocol Buffers/notification_settings.proto
new file mode 100644
index 000000000..0d612dccf
--- /dev/null
+++ b/app/ios/FcmServiceExtension/Protocol Buffers/notification_settings.proto
@@ -0,0 +1,37 @@
+syntax = "proto3";
+
+import "notification_payload.proto";
+package eqmonitor;
+
+message NotificationSettings {
+ EewSettings eew_settings = 1;
+ EarthquakeSettings earthquake_settings = 2;
+
+ message EewSettings {
+ optional JmaIntensity emergency_intensity = 1;
+ optional JmaIntensity silent_intensity = 2;
+ repeated Region regions = 3;
+
+ message Region {
+ string code = 1;
+ string name = 2;
+ JmaIntensity emergency_intensity = 3;
+ JmaIntensity silent_intensity = 4;
+ bool is_main = 5;
+ }
+ }
+
+ message EarthquakeSettings {
+ optional JmaIntensity emergency_intensity = 1;
+ optional JmaIntensity silent_intensity = 2;
+ repeated Region regions = 3;
+
+ message Region {
+ string code = 1;
+ string name = 2;
+ JmaIntensity emergency_intensity = 3;
+ JmaIntensity silent_intensity = 4;
+ bool is_main = 5;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/ios/Podfile b/app/ios/Podfile
index d40be56b9..0e8e68987 100644
--- a/app/ios/Podfile
+++ b/app/ios/Podfile
@@ -1,3 +1,4 @@
+
# Uncomment this line to define a global platform for your project
platform :ios, '15.0'
@@ -37,6 +38,7 @@ end
target 'FcmServiceExtension' do
use_frameworks!
pod 'Firebase/Messaging'
+ pod 'SwiftProtobuf', '~> 1.0'
end
post_install do |installer|
diff --git a/app/ios/Podfile.lock b/app/ios/Podfile.lock
index dccd9fea5..77f30d263 100644
--- a/app/ios/Podfile.lock
+++ b/app/ios/Podfile.lock
@@ -13,6 +13,9 @@ PODS:
- Firebase/Crashlytics (10.25.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 10.25.0)
+ - Firebase/Installations (10.25.0):
+ - Firebase/CoreOnly
+ - FirebaseInstallations (~> 10.25.0)
- Firebase/Messaging (10.25.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 10.25.0)
@@ -20,7 +23,11 @@ PODS:
- Firebase/Analytics (= 10.25.0)
- firebase_core
- Flutter
- - firebase_core (2.31.0):
+ - firebase_app_installations (0.2.5-6):
+ - Firebase/Installations (= 10.25.0)
+ - firebase_core
+ - Flutter
+ - firebase_core (2.31.1):
- Firebase/CoreOnly (= 10.25.0)
- Flutter
- firebase_crashlytics (3.5.5):
@@ -93,6 +100,8 @@ PODS:
- Flutter (1.0.0)
- flutter_local_notifications (0.0.1):
- Flutter
+ - flutter_secure_storage (6.0.0):
+ - Flutter
- GoogleAppMeasurement (10.25.0):
- GoogleAppMeasurement/AdIdSupport (= 10.25.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.11)
@@ -190,9 +199,12 @@ PODS:
- RevenueCat (4.41.2)
- share_plus (0.0.1):
- Flutter
+ - shared_preference_app_group (1.0.0):
+ - Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
+ - SwiftProtobuf (1.26.0)
- url_launcher_ios (0.0.1):
- Flutter
@@ -201,11 +213,13 @@ DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Firebase/Messaging
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
+ - firebase_app_installations (from `.symlinks/plugins/firebase_app_installations/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
+ - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- GoogleUtilities
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
- maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`)
@@ -214,7 +228,9 @@ DEPENDENCIES:
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
+ - shared_preference_app_group (from `.symlinks/plugins/shared_preference_app_group/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
+ - SwiftProtobuf (~> 1.0)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
@@ -238,6 +254,7 @@ SPEC REPOS:
- PromisesSwift
- PurchasesHybridCommon
- RevenueCat
+ - SwiftProtobuf
EXTERNAL SOURCES:
app_settings:
@@ -246,6 +263,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/device_info_plus/ios"
firebase_analytics:
:path: ".symlinks/plugins/firebase_analytics/ios"
+ firebase_app_installations:
+ :path: ".symlinks/plugins/firebase_app_installations/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_crashlytics:
@@ -256,6 +275,8 @@ EXTERNAL SOURCES:
:path: Flutter
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
+ flutter_secure_storage:
+ :path: ".symlinks/plugins/flutter_secure_storage/ios"
in_app_review:
:path: ".symlinks/plugins/in_app_review/ios"
maplibre_gl:
@@ -270,6 +291,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/purchases_flutter/ios"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
+ shared_preference_app_group:
+ :path: ".symlinks/plugins/shared_preference_app_group/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
url_launcher_ios:
@@ -280,7 +303,8 @@ SPEC CHECKSUMS:
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
Firebase: 0312a2352584f782ea56f66d91606891d4607f06
firebase_analytics: 0b2b459312872129295c3f9c44225eda552fd8f3
- firebase_core: 0b39f4f424e02eecabb2356ddf331fa07b772af8
+ firebase_app_installations: be1eea0d27920495af41e3e1df947721f61c6b92
+ firebase_core: 22e117a2e0dec3cb318c8f53f2dd01c140375617
firebase_crashlytics: 5adb9a5ac7858811cef7a9447a011bb4dcb540c3
firebase_messaging: 8999827b6efc9c3ab4b1f9dc246deaa7f13dbf88
FirebaseAnalytics: ec00fe8b93b41dc6fe4a28784b8e51da0647a248
@@ -294,6 +318,7 @@ SPEC CHECKSUMS:
FirebaseSessions: c0939656253a1fa0e94ecc266ccf770cc8b33732
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
+ flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
GoogleAppMeasurement: 9abf64b682732fed36da827aa2a68f0221fd2356
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
@@ -310,9 +335,11 @@ SPEC CHECKSUMS:
PurchasesHybridCommon: 120cdca2b40fb5947a51b75e121da4f2cde0a137
RevenueCat: 0250867579677899de94f96ad9be342be865560f
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
+ shared_preference_app_group: 46aee3873e1da581d4904bece9876596d7f66725
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
+ SwiftProtobuf: 5e8349171e7c2f88f5b9e683cb3cb79d1dc780b3
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
-PODFILE CHECKSUM: ed004133a4fb69edf7b8ec637bafb0286877f367
+PODFILE CHECKSUM: 0b8b5903d4f7ea7ba6bf199382a502476fb3b42d
COCOAPODS: 1.15.2
diff --git a/app/ios/Runner.xcodeproj/project.pbxproj b/app/ios/Runner.xcodeproj/project.pbxproj
index b6e48e26d..ae859c989 100644
--- a/app/ios/Runner.xcodeproj/project.pbxproj
+++ b/app/ios/Runner.xcodeproj/project.pbxproj
@@ -12,11 +12,16 @@
4A6E6F82172719E05F9BD593 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = AD5D302A98B76C01E6D49E1B /* GoogleService-Info.plist */; };
4F115C462BE9682B00DAAD73 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 4F115C452BE9682B00DAAD73 /* PrivacyInfo.xcprivacy */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
- 85145B222B1F5A0100784C85 /* NotificationService.m in Sources */ = {isa = PBXBuildFile; fileRef = 85145B212B1F5A0100784C85 /* NotificationService.m */; };
- 85145B262B1F5A0100784C85 /* FcmServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 85145B1E2B1F5A0100784C85 /* FcmServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
- 85145B2B2B1F5A6300784C85 /* Pods_FcmServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 99B391858A4EFC95F561B05E /* Pods_FcmServiceExtension.framework */; };
+ 7B7B782513B5BD61B436275F /* Pods_FcmServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 99B391858A4EFC95F561B05E /* Pods_FcmServiceExtension.framework */; };
+ 854858802BFF92D90025EC74 /* notification_settings.proto in Sources */ = {isa = PBXBuildFile; fileRef = 8548587E2BFF92D90025EC74 /* notification_settings.proto */; };
+ 854858812BFF92D90025EC74 /* notification_settings.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8548587F2BFF92D90025EC74 /* notification_settings.pb.swift */; };
859DF75C2BBE9FFC00B827B1 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 859DF75B2BBE9FFC00B827B1 /* StoreKit.framework */; };
859DF75E2BBEA0F000B827B1 /* Synced - EQMonitor.storekit in Resources */ = {isa = PBXBuildFile; fileRef = 859DF75D2BBEA0F000B827B1 /* Synced - EQMonitor.storekit */; };
+ 85B0048F2C077A9B0063ADD5 /* Gzip in Frameworks */ = {isa = PBXBuildFile; productRef = 85B0048E2C077A9B0063ADD5 /* Gzip */; };
+ 85E609552BFF792C00C21983 /* FcmServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 85E6094E2BFF792C00C21983 /* FcmServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ 85E6095B2BFF7AC300C21983 /* notification_payload.proto in Sources */ = {isa = PBXBuildFile; fileRef = 85E6095A2BFF7AC300C21983 /* notification_payload.proto */; };
+ 85E6095E2BFF7B6400C21983 /* notification_payload.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E6095C2BFF7B6400C21983 /* notification_payload.pb.swift */; };
+ 85E6095F2BFF7B6400C21983 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E6095D2BFF7B6400C21983 /* NotificationService.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@@ -24,11 +29,11 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- 85145B242B1F5A0100784C85 /* PBXContainerItemProxy */ = {
+ 85E609532BFF792C00C21983 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 85145B1D2B1F5A0100784C85;
+ remoteGlobalIDString = 85E6094D2BFF792C00C21983;
remoteInfo = FcmServiceExtension;
};
/* End PBXContainerItemProxy section */
@@ -40,7 +45,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
- 85145B262B1F5A0100784C85 /* FcmServiceExtension.appex in Embed Foundation Extensions */,
+ 85E609552BFF792C00C21983 /* FcmServiceExtension.appex in Embed Foundation Extensions */,
);
name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0;
@@ -68,14 +73,18 @@
78BBC9D30B7DD3A0C4B4AFEE /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
85145B082B1F59A900784C85 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; };
- 85145B1E2B1F5A0100784C85 /* FcmServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FcmServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
- 85145B202B1F5A0100784C85 /* NotificationService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationService.h; sourceTree = ""; };
- 85145B212B1F5A0100784C85 /* NotificationService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationService.m; sourceTree = ""; };
- 85145B232B1F5A0100784C85 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 8548587E2BFF92D90025EC74 /* notification_settings.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = notification_settings.proto; sourceTree = ""; };
+ 8548587F2BFF92D90025EC74 /* notification_settings.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = notification_settings.pb.swift; sourceTree = ""; };
859DF75B2BBE9FFC00B827B1 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
859DF75D2BBEA0F000B827B1 /* Synced - EQMonitor.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Synced - EQMonitor.storekit"; sourceTree = ""; };
85C945A22BE2AAC70099687E /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = ""; };
85C945A32BE2AAC90099687E /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/LaunchScreen.strings; sourceTree = ""; };
+ 85E6094E2BFF792C00C21983 /* FcmServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FcmServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
+ 85E609522BFF792C00C21983 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 85E6095A2BFF7AC300C21983 /* notification_payload.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = notification_payload.proto; sourceTree = ""; };
+ 85E6095C2BFF7B6400C21983 /* notification_payload.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = notification_payload.pb.swift; sourceTree = ""; };
+ 85E6095D2BFF7B6400C21983 /* NotificationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; };
+ 85E609652BFF858900C21983 /* FcmServiceExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FcmServiceExtension.entitlements; sourceTree = ""; };
86D3A5225875F01D12D8F080 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
@@ -93,11 +102,12 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
- 85145B1B2B1F5A0100784C85 /* Frameworks */ = {
+ 85E6094B2BFF792C00C21983 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 85145B2B2B1F5A6300784C85 /* Pods_FcmServiceExtension.framework in Frameworks */,
+ 85B0048F2C077A9B0063ADD5 /* Gzip in Frameworks */,
+ 7B7B782513B5BD61B436275F /* Pods_FcmServiceExtension.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -136,12 +146,24 @@
name = Frameworks;
sourceTree = "";
};
- 85145B1F2B1F5A0100784C85 /* FcmServiceExtension */ = {
+ 8548587D2BFF900A0025EC74 /* Protocol Buffers */ = {
isa = PBXGroup;
children = (
- 85145B202B1F5A0100784C85 /* NotificationService.h */,
- 85145B212B1F5A0100784C85 /* NotificationService.m */,
- 85145B232B1F5A0100784C85 /* Info.plist */,
+ 8548587F2BFF92D90025EC74 /* notification_settings.pb.swift */,
+ 8548587E2BFF92D90025EC74 /* notification_settings.proto */,
+ 85E6095A2BFF7AC300C21983 /* notification_payload.proto */,
+ 85E6095C2BFF7B6400C21983 /* notification_payload.pb.swift */,
+ );
+ path = "Protocol Buffers";
+ sourceTree = "";
+ };
+ 85E6094F2BFF792C00C21983 /* FcmServiceExtension */ = {
+ isa = PBXGroup;
+ children = (
+ 8548587D2BFF900A0025EC74 /* Protocol Buffers */,
+ 85E6095D2BFF7B6400C21983 /* NotificationService.swift */,
+ 85E609652BFF858900C21983 /* FcmServiceExtension.entitlements */,
+ 85E609522BFF792C00C21983 /* Info.plist */,
);
path = FcmServiceExtension;
sourceTree = "";
@@ -163,7 +185,7 @@
859DF75D2BBEA0F000B827B1 /* Synced - EQMonitor.storekit */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
- 85145B1F2B1F5A0100784C85 /* FcmServiceExtension */,
+ 85E6094F2BFF792C00C21983 /* FcmServiceExtension */,
97C146EF1CF9000F007C117D /* Products */,
37E217C7AA5B870CF2ADE991 /* Pods */,
780B8182ACE31F9AF11ED5CF /* Frameworks */,
@@ -175,7 +197,7 @@
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
- 85145B1E2B1F5A0100784C85 /* FcmServiceExtension.appex */,
+ 85E6094E2BFF792C00C21983 /* FcmServiceExtension.appex */,
);
name = Products;
sourceTree = "";
@@ -200,22 +222,25 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
- 85145B1D2B1F5A0100784C85 /* FcmServiceExtension */ = {
+ 85E6094D2BFF792C00C21983 /* FcmServiceExtension */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 85145B272B1F5A0100784C85 /* Build configuration list for PBXNativeTarget "FcmServiceExtension" */;
+ buildConfigurationList = 85E609562BFF792C00C21983 /* Build configuration list for PBXNativeTarget "FcmServiceExtension" */;
buildPhases = (
- DBC832C47A23EACAA2112386 /* [CP] Check Pods Manifest.lock */,
- 85145B1A2B1F5A0100784C85 /* Sources */,
- 85145B1B2B1F5A0100784C85 /* Frameworks */,
- 85145B1C2B1F5A0100784C85 /* Resources */,
+ 581C84711FC571AFFFD771E9 /* [CP] Check Pods Manifest.lock */,
+ 85E6094A2BFF792C00C21983 /* Sources */,
+ 85E6094B2BFF792C00C21983 /* Frameworks */,
+ 85E6094C2BFF792C00C21983 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = FcmServiceExtension;
+ packageProductDependencies = (
+ 85B0048E2C077A9B0063ADD5 /* Gzip */,
+ );
productName = FcmServiceExtension;
- productReference = 85145B1E2B1F5A0100784C85 /* FcmServiceExtension.appex */;
+ productReference = 85E6094E2BFF792C00C21983 /* FcmServiceExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
97C146ED1CF9000F007C117D /* Runner */ = {
@@ -237,7 +262,7 @@
buildRules = (
);
dependencies = (
- 85145B252B1F5A0100784C85 /* PBXTargetDependency */,
+ 85E609542BFF792C00C21983 /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
@@ -251,12 +276,12 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
- LastSwiftUpdateCheck = 1500;
+ LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
- 85145B1D2B1F5A0100784C85 = {
- CreatedOnToolsVersion = 15.0.1;
+ 85E6094D2BFF792C00C21983 = {
+ CreatedOnToolsVersion = 15.4;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
@@ -273,18 +298,21 @@
ja,
);
mainGroup = 97C146E51CF9000F007C117D;
+ packageReferences = (
+ 85B0048D2C077A9B0063ADD5 /* XCRemoteSwiftPackageReference "GzipSwift" */,
+ );
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
- 85145B1D2B1F5A0100784C85 /* FcmServiceExtension */,
+ 85E6094D2BFF792C00C21983 /* FcmServiceExtension */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
- 85145B1C2B1F5A0100784C85 /* Resources */ = {
+ 85E6094C2BFF792C00C21983 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -364,6 +392,28 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
+ 581C84711FC571AFFFD771E9 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-FcmServiceExtension-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
82EEBE268738BCF11B78DD00 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -418,36 +468,18 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
- DBC832C47A23EACAA2112386 /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-FcmServiceExtension-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
- 85145B1A2B1F5A0100784C85 /* Sources */ = {
+ 85E6094A2BFF792C00C21983 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 85145B222B1F5A0100784C85 /* NotificationService.m in Sources */,
+ 85E6095E2BFF7B6400C21983 /* notification_payload.pb.swift in Sources */,
+ 85E6095F2BFF7B6400C21983 /* NotificationService.swift in Sources */,
+ 85E6095B2BFF7AC300C21983 /* notification_payload.proto in Sources */,
+ 854858812BFF92D90025EC74 /* notification_settings.pb.swift in Sources */,
+ 854858802BFF92D90025EC74 /* notification_settings.proto in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -463,10 +495,10 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- 85145B252B1F5A0100784C85 /* PBXTargetDependency */ = {
+ 85E609542BFF792C00C21983 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 85145B1D2B1F5A0100784C85 /* FcmServiceExtension */;
- targetProxy = 85145B242B1F5A0100784C85 /* PBXContainerItemProxy */;
+ target = 85E6094D2BFF792C00C21983 /* FcmServiceExtension */;
+ targetProxy = 85E609532BFF792C00C21983 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
@@ -547,13 +579,14 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = iOSAppIcon;
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;
- CURRENT_PROJECT_VERSION = 1166;
+ CURRENT_PROJECT_VERSION = 1169;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
ENABLE_BITCODE = NO;
@@ -568,14 +601,14 @@
PRODUCT_BUNDLE_IDENTIFIER = net.yumnumm.eqmonitor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development net.yumnumm.eqmonitor";
+ "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";
};
name = Profile;
};
- 85145B282B1F5A0100784C85 /* Debug */ = {
+ 85E609572BFF792C00C21983 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BAD419430E9ED3DD1D1D656D /* Pods-FcmServiceExtension.debug.xcconfig */;
buildSettings = {
@@ -586,10 +619,11 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = FcmServiceExtension/FcmServiceExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development: Ryotaro Onoue (7PWJ49VWRZ)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 1166;
+ CURRENT_PROJECT_VERSION = 1169;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
@@ -613,12 +647,15 @@
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;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
- 85145B292B1F5A0100784C85 /* Release */ = {
+ 85E609582BFF792C00C21983 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BB2485496F3FDA0206409B97 /* Pods-FcmServiceExtension.release.xcconfig */;
buildSettings = {
@@ -629,10 +666,11 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = FcmServiceExtension/FcmServiceExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Ryotaro Onoue (CPL7H8SHVM)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 1166;
+ CURRENT_PROJECT_VERSION = 1169;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
@@ -656,11 +694,12 @@
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore net.yumnumm.eqmonitor.FcmServiceExtension";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
- 85145B2A2B1F5A0100784C85 /* Profile */ = {
+ 85E609592BFF792C00C21983 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A44F22D7804610848A5A41DF /* Pods-FcmServiceExtension.profile.xcconfig */;
buildSettings = {
@@ -671,10 +710,11 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = FcmServiceExtension/FcmServiceExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution: Ryotaro Onoue (CPL7H8SHVM)";
CODE_SIGN_STYLE = Manual;
- CURRENT_PROJECT_VERSION = 1166;
+ CURRENT_PROJECT_VERSION = 1169;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
@@ -695,9 +735,10 @@
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";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore net.yumnumm.eqmonitor.FcmServiceExtension";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Profile;
@@ -815,13 +856,14 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = iOSAppIcon;
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;
- CURRENT_PROJECT_VERSION = 1166;
+ CURRENT_PROJECT_VERSION = 1169;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
ENABLE_BITCODE = NO;
@@ -848,13 +890,14 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = iOSAppIcon;
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;
- CURRENT_PROJECT_VERSION = 1166;
+ CURRENT_PROJECT_VERSION = 1169;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CPL7H8SHVM;
ENABLE_BITCODE = NO;
@@ -879,12 +922,12 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 85145B272B1F5A0100784C85 /* Build configuration list for PBXNativeTarget "FcmServiceExtension" */ = {
+ 85E609562BFF792C00C21983 /* Build configuration list for PBXNativeTarget "FcmServiceExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 85145B282B1F5A0100784C85 /* Debug */,
- 85145B292B1F5A0100784C85 /* Release */,
- 85145B2A2B1F5A0100784C85 /* Profile */,
+ 85E609572BFF792C00C21983 /* Debug */,
+ 85E609582BFF792C00C21983 /* Release */,
+ 85E609592BFF792C00C21983 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@@ -910,6 +953,25 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
+
+/* Begin XCRemoteSwiftPackageReference section */
+ 85B0048D2C077A9B0063ADD5 /* XCRemoteSwiftPackageReference "GzipSwift" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/1024jp/GzipSwift";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 6.0.1;
+ };
+ };
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ 85B0048E2C077A9B0063ADD5 /* Gzip */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 85B0048D2C077A9B0063ADD5 /* XCRemoteSwiftPackageReference "GzipSwift" */;
+ productName = Gzip;
+ };
+/* End XCSwiftPackageProductDependency section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
diff --git a/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644
index 000000000..4304b0873
--- /dev/null
+++ b/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -0,0 +1,15 @@
+{
+ "originHash" : "83ffce27527b281518faad7eba754e9f0ce57b67740a62356e3d9b6ced46e1b2",
+ "pins" : [
+ {
+ "identity" : "gzipswift",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/1024jp/GzipSwift",
+ "state" : {
+ "revision" : "731037f6cc2be2ec01562f6597c1d0aa3fe6fd05",
+ "version" : "6.0.1"
+ }
+ }
+ ],
+ "version" : 3
+}
diff --git a/app/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/app/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644
index 000000000..4304b0873
--- /dev/null
+++ b/app/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -0,0 +1,15 @@
+{
+ "originHash" : "83ffce27527b281518faad7eba754e9f0ce57b67740a62356e3d9b6ced46e1b2",
+ "pins" : [
+ {
+ "identity" : "gzipswift",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/1024jp/GzipSwift",
+ "state" : {
+ "revision" : "731037f6cc2be2ec01562f6597c1d0aa3fe6fd05",
+ "version" : "6.0.1"
+ }
+ }
+ ],
+ "version" : 3
+}
diff --git a/app/ios/Runner/AppDelegate.swift b/app/ios/Runner/AppDelegate.swift
index 37d7c1c02..606ed06b1 100644
--- a/app/ios/Runner/AppDelegate.swift
+++ b/app/ios/Runner/AppDelegate.swift
@@ -16,6 +16,7 @@ import flutter_local_notifications
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
}
+
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
diff --git a/app/ios/Runner/Info.plist b/app/ios/Runner/Info.plist
index 26e166f66..c49fea8ba 100644
--- a/app/ios/Runner/Info.plist
+++ b/app/ios/Runner/Info.plist
@@ -23,7 +23,7 @@
CFBundleSignature
????
CFBundleVersion
- 1166
+ 1169
LSApplicationCategoryType
LSApplicationQueriesSchemes
diff --git a/app/ios/Runner/Runner.entitlements b/app/ios/Runner/Runner.entitlements
index 5fd9a8d0f..fead5277b 100644
--- a/app/ios/Runner/Runner.entitlements
+++ b/app/ios/Runner/Runner.entitlements
@@ -1,12 +1,16 @@
-
- aps-environment
- production
- com.apple.developer.usernotifications.critical-alerts
-
- com.apple.developer.usernotifications.time-sensitive
-
-
-
\ No newline at end of file
+
+ aps-environment
+ production
+ com.apple.developer.usernotifications.critical-alerts
+
+ com.apple.developer.usernotifications.time-sensitive
+
+ com.apple.security.application-groups
+
+ group.net.yumnumm.eqmonitor
+
+
+
diff --git a/app/ios/fastlane/README.md b/app/ios/fastlane/README.md
index 82dbe7e28..2026982fc 100644
--- a/app/ios/fastlane/README.md
+++ b/app/ios/fastlane/README.md
@@ -1,4 +1,5 @@
-## fastlane documentation
+fastlane documentation
+----
# Installation
@@ -70,7 +71,7 @@ Push a new build to App Store Connect
Push a new build to Firebase App Distribution
----
+----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
diff --git a/app/lib/core/api/api_authentication_service.dart b/app/lib/core/api/api_authentication_service.dart
new file mode 100644
index 000000000..9a54e9668
--- /dev/null
+++ b/app/lib/core/api/api_authentication_service.dart
@@ -0,0 +1,55 @@
+import 'dart:convert';
+
+import 'package:eqmonitor/core/provider/secure_storage.dart';
+import 'package:eqmonitor/feature/settings/features/notification_remote_settings/data/notification_remote_settings_saved_state.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+part 'api_authentication_service.g.dart';
+
+@Riverpod(keepAlive: true)
+class ApiAuthenticationService extends _$ApiAuthenticationService {
+ @override
+ Future build() async {
+ final secureStorage = ref.watch(secureStorageProvider);
+ final result = await secureStorage.read(key: _secureStorageKey);
+ return result;
+ }
+
+ static const _secureStorageKey = 'api_token';
+
+ Future save({
+ required String token,
+ }) async {
+ final secureStorage = ref.watch(secureStorageProvider);
+ await secureStorage.write(key: _secureStorageKey, value: token);
+
+ state = AsyncData(token);
+ }
+
+ Future<
+ ({
+ String id,
+ String role,
+ })> extractPayload() async {
+ final token = state.valueOrNull;
+ if (token == null) {
+ throw UnauthorizedException();
+ }
+
+ final parts = token.split('.');
+ if (parts.length != 3) {
+ throw UnauthorizedException();
+ }
+
+ final payload = parts[1];
+ final decoded = base64Decode(payload);
+ final json = utf8.decode(decoded);
+ final map = jsonDecode(json) as Map;
+ final id = map['sub'] as String;
+ final role = map['role'] as String;
+ return (
+ id: id,
+ role: role,
+ );
+ }
+}
diff --git a/app/lib/core/api/api_authentication_service.g.dart b/app/lib/core/api/api_authentication_service.g.dart
new file mode 100644
index 000000000..9ac1b1e0d
--- /dev/null
+++ b/app/lib/core/api/api_authentication_service.g.dart
@@ -0,0 +1,29 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// ignore_for_file: type=lint, duplicate_ignore
+
+part of 'api_authentication_service.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$apiAuthenticationServiceHash() =>
+ r'ad69d966052714f99e0d0dad0a10a386000fe19c';
+
+/// See also [ApiAuthenticationService].
+@ProviderFor(ApiAuthenticationService)
+final apiAuthenticationServiceProvider =
+ AsyncNotifierProvider.internal(
+ ApiAuthenticationService.new,
+ name: r'apiAuthenticationServiceProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$apiAuthenticationServiceHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+typedef _$ApiAuthenticationService = AsyncNotifier;
+// 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/core/extension/jma_forecast_intensity.dart b/app/lib/core/extension/jma_forecast_intensity.dart
new file mode 100644
index 000000000..8bdf22805
--- /dev/null
+++ b/app/lib/core/extension/jma_forecast_intensity.dart
@@ -0,0 +1,3 @@
+extension JmaForecastIntensityPlusMinusConverter on String {
+ String get fromPlusMinus => replaceAll('+', '強').replaceAll('-', '弱');
+}
diff --git a/app/lib/core/provider/config/notification/fcm_topic_manager.dart b/app/lib/core/provider/config/notification/fcm_topic_manager.dart
index 93cd096ce..807e8e64e 100644
--- a/app/lib/core/provider/config/notification/fcm_topic_manager.dart
+++ b/app/lib/core/provider/config/notification/fcm_topic_manager.dart
@@ -2,9 +2,7 @@ import 'package:eqapi_types/eqapi_types.dart';
import 'package:eqmonitor/core/foundation/result.dart';
import 'package:eqmonitor/core/provider/firebase/firebase_crashlytics.dart';
import 'package:eqmonitor/core/provider/firebase/firebase_messaging.dart';
-import 'package:eqmonitor/core/provider/log/talker.dart';
import 'package:eqmonitor/core/provider/shared_preferences.dart';
-import 'package:flutter/foundation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'fcm_topic_manager.g.dart';
@@ -15,61 +13,11 @@ class FcmTopicManager extends _$FcmTopicManager {
List build() {
final prefs = ref.watch(sharedPreferencesProvider);
final list = prefs.getStringList(_prefsKey);
- ref.listenSelf((_, __) => _save());
return list ?? [];
}
static const String _prefsKey = 'fcmTopicManager';
- /// デフォルトで購読すべきトピックを登録する
- Future setup() async {
- if (kIsWeb) {
- ref.read(talkerProvider).log('FcmTopicManager.setup: Skipped! (Web)');
- }
- final futures = >[];
- final requireTopics = [
- FcmBasicTopic(FcmTopics.all),
- ];
- for (final topic in requireTopics) {
- futures.add(registerToTopic(topic));
- }
- final shouldBeUnregisteredTopics = [
- 'earthquake',
- 'eew',
- 'everyone',
- ];
- final messaging = ref.read(firebaseMessagingProvider);
- for (final topic in shouldBeUnregisteredTopics) {
- // bypass prefs check
- futures.add(messaging.unsubscribeFromTopic(topic));
- }
- await futures.wait;
- }
-
- Future _save() async {
- final prefs = ref.read(sharedPreferencesProvider);
- await prefs.setStringList(_prefsKey, state);
- }
-
- Future> registerToTopic(FcmTopic topic) async {
- // 既に登録済みの場合は何もしない
- if (state.contains(topic.topic)) {
- return Result.success(null);
- }
- final messaging = ref.read(firebaseMessagingProvider);
- try {
- await messaging.subscribeToTopic(topic.topic);
- state = [...state, topic.topic];
- return Result.success(null);
- } on Exception catch (error, stackTrace) {
- await ref.read(firebaseCrashlyticsProvider).recordError(
- error,
- stackTrace,
- );
- return Result.failure(error);
- }
- }
-
Future> unregisterFromTopic(FcmTopic topic) async {
// 登録されていない場合は何もしない
if (!state.contains(topic.topic)) {
diff --git a/app/lib/core/provider/config/notification/fcm_topic_manager.g.dart b/app/lib/core/provider/config/notification/fcm_topic_manager.g.dart
index 3b3076d52..ab93c2cca 100644
--- a/app/lib/core/provider/config/notification/fcm_topic_manager.g.dart
+++ b/app/lib/core/provider/config/notification/fcm_topic_manager.g.dart
@@ -8,7 +8,7 @@ part of 'fcm_topic_manager.dart';
// RiverpodGenerator
// **************************************************************************
-String _$fcmTopicManagerHash() => r'b1f7d4ce61af9d66e84ac02e72b923666da046ce';
+String _$fcmTopicManagerHash() => r'967211da3f9d8def37c763112c042f64e6fa3c91';
/// See also [FcmTopicManager].
@ProviderFor(FcmTopicManager)
diff --git a/app/lib/core/provider/dio_provider.dart b/app/lib/core/provider/dio_provider.dart
index 04fa21d1a..55567b119 100644
--- a/app/lib/core/provider/dio_provider.dart
+++ b/app/lib/core/provider/dio_provider.dart
@@ -26,14 +26,17 @@ Dio dio(DioRef ref) {
if (authorization != null) 'authorization': authorization,
},
baseUrl: ref.watch(telegramUrlProvider).restApiUrl,
+ contentType: ContentType.json.value,
+ connectTimeout: const Duration(milliseconds: 5000),
+ sendTimeout: const Duration(milliseconds: 5000),
),
);
if (ref.watch(isDioProxyEnabledProvider)) {
+ HttpOverrides.global = _HttpOverrides();
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () =>
- HttpClient()..findProxy = (url) => 'PROXY macbook-pro:9090',
+ HttpClient()..findProxy = (url) => 'PROXY 192.168.151.154:9090',
);
- HttpOverrides.global = _HttpOverrides();
}
dio.interceptors.add(
TalkerDioLogger(
@@ -52,7 +55,7 @@ class _HttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
- ..findProxy = (url) => 'PROXY macbook-pro:9090';
+ ..findProxy = (url) => 'PROXY 192.168.151.154:9090';
}
}
diff --git a/app/lib/core/provider/dio_provider.g.dart b/app/lib/core/provider/dio_provider.g.dart
index ff77df0ca..08762d484 100644
--- a/app/lib/core/provider/dio_provider.g.dart
+++ b/app/lib/core/provider/dio_provider.g.dart
@@ -8,7 +8,7 @@ part of 'dio_provider.dart';
// RiverpodGenerator
// **************************************************************************
-String _$dioHash() => r'a6786f1da0d19c0dc456c6dfad7c527044f17a4f';
+String _$dioHash() => r'd72ee736b9a14e533047e6b35c2a1d2a8bc24b65';
/// See also [dio].
@ProviderFor(dio)
diff --git a/app/lib/core/provider/secure_storage.dart b/app/lib/core/provider/secure_storage.dart
new file mode 100644
index 000000000..cf9c9f1b3
--- /dev/null
+++ b/app/lib/core/provider/secure_storage.dart
@@ -0,0 +1,15 @@
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+part 'secure_storage.g.dart';
+
+@Riverpod(keepAlive: true)
+FlutterSecureStorage secureStorage(SecureStorageRef ref) =>
+ const FlutterSecureStorage(
+ aOptions: AndroidOptions(
+ resetOnError: true,
+ ),
+ iOptions: IOSOptions(
+ groupId: 'group.net.yumnumm.eqmonitor',
+ ),
+ );
diff --git a/app/lib/core/provider/secure_storage.g.dart b/app/lib/core/provider/secure_storage.g.dart
new file mode 100644
index 000000000..22e81bfa5
--- /dev/null
+++ b/app/lib/core/provider/secure_storage.g.dart
@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// ignore_for_file: type=lint, duplicate_ignore
+
+part of 'secure_storage.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$secureStorageHash() => r'0eea8870671934e93a6ec21257140504fa3254a3';
+
+/// See also [secureStorage].
+@ProviderFor(secureStorage)
+final secureStorageProvider = Provider.internal(
+ secureStorage,
+ name: r'secureStorageProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$secureStorageHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+typedef SecureStorageRef = ProviderRef;
+// 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/core/router/router.dart b/app/lib/core/router/router.dart
index 51a0aca91..839166e34 100644
--- a/app/lib/core/router/router.dart
+++ b/app/lib/core/router/router.dart
@@ -19,9 +19,9 @@ import 'package:eqmonitor/feature/settings/children/config/color_scheme/color_sc
import 'package:eqmonitor/feature/settings/children/config/debug/api_endpoint_selector/api_endpoint_selector_page.dart';
import 'package:eqmonitor/feature/settings/children/config/debug/debugger_page.dart';
import 'package:eqmonitor/feature/settings/children/config/earthquake_history/earthquake_history_config_page.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_page.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/children/eew/eew_notification_settings_page.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/notification_setting_page.dart';
+import 'package:eqmonitor/feature/settings/features/notification_remote_settings/ui/notification_remote_settings_page.dart';
+import 'package:eqmonitor/feature/settings/features/notification_remote_settings/ui/pages/notification_remote_settings_earthquake_page.dart';
+import 'package:eqmonitor/feature/settings/features/notification_remote_settings/ui/pages/notification_remote_settings_eew_page.dart';
import 'package:eqmonitor/feature/settings/settings_screen.dart';
import 'package:eqmonitor/feature/setup/screen/setup_screen.dart';
import 'package:eqmonitor/feature/talker/talker_page.dart';
@@ -52,6 +52,7 @@ GoRouter goRouter(GoRouterRef ref) => GoRouter(
ref.watch(talkerProvider),
),
],
+ debugLogDiagnostics: true,
);
@TypedGoRoute(
@@ -84,10 +85,9 @@ class EarthquakeHistoryDetailsRoute extends GoRouteData {
@override
Widget build(BuildContext context, GoRouterState state) {
-
return EarthquakeHistoryDetailsPage(
- eventId: eventId,
- );
+ eventId: eventId,
+ );
}
}
@@ -140,6 +140,17 @@ class KmoniRoute extends GoRouteData {
@TypedGoRoute(
path: '/settings',
routes: [
+ TypedGoRoute(
+ path: 'notification',
+ routes: [
+ TypedGoRoute(
+ path: 'earthquake',
+ ),
+ TypedGoRoute(
+ path: 'eew',
+ ),
+ ],
+ ),
TypedGoRoute(
path: 'term-of-service',
),
@@ -166,17 +177,6 @@ class KmoniRoute extends GoRouteData {
),
],
),
- TypedGoRoute(
- path: 'notification',
- routes: [
- TypedGoRoute(
- path: 'eew',
- ),
- TypedGoRoute(
- path: 'earthquake',
- ),
- ],
- ),
TypedGoRoute(
path: 'debugger',
routes: [
@@ -198,6 +198,27 @@ class SettingsRoute extends GoRouteData {
const SettingsScreen();
}
+class NotificationRoute extends GoRouteData {
+ const NotificationRoute();
+ @override
+ Widget build(BuildContext context, GoRouterState state) =>
+ const NotificationRemoteSettingsPage();
+}
+
+class NotificationEarthquakeRoute extends GoRouteData {
+ const NotificationEarthquakeRoute();
+ @override
+ Widget build(BuildContext context, GoRouterState state) =>
+ const NotificationRemoteSettingsEarthquakePage();
+}
+
+class NotificationEewRoute extends GoRouteData {
+ const NotificationEewRoute();
+ @override
+ Widget build(BuildContext context, GoRouterState state) =>
+ const NotificationRemoteSettingsEewPage();
+}
+
class DebuggerRoute extends GoRouteData {
const DebuggerRoute();
@@ -277,30 +298,6 @@ class AboutThisAppRoute extends GoRouteData {
const AboutThisAppScreen();
}
-class NotificationSettingsRoute extends GoRouteData {
- const NotificationSettingsRoute();
-
- @override
- Widget build(BuildContext context, GoRouterState state) =>
- const NotificationSettingsPage();
-}
-
-class EewNotificationSettingsRoute extends GoRouteData {
- const EewNotificationSettingsRoute();
-
- @override
- Widget build(BuildContext context, GoRouterState state) =>
- const EewNotificationSettingsPage();
-}
-
-class EarthquakeNotificationSettingsRoute extends GoRouteData {
- const EarthquakeNotificationSettingsRoute();
-
- @override
- Widget build(BuildContext context, GoRouterState state) =>
- const EarthquakeNotificationSettingsPage();
-}
-
class EarthquakeParameterListRoute extends GoRouteData {
const EarthquakeParameterListRoute();
diff --git a/app/lib/core/router/router.g.dart b/app/lib/core/router/router.g.dart
index e299794a8..2324495d6 100644
--- a/app/lib/core/router/router.g.dart
+++ b/app/lib/core/router/router.g.dart
@@ -212,6 +212,20 @@ RouteBase get $settingsRoute => GoRouteData.$route(
path: '/settings',
factory: $SettingsRouteExtension._fromState,
routes: [
+ GoRouteData.$route(
+ path: 'notification',
+ factory: $NotificationRouteExtension._fromState,
+ routes: [
+ GoRouteData.$route(
+ path: 'earthquake',
+ factory: $NotificationEarthquakeRouteExtension._fromState,
+ ),
+ GoRouteData.$route(
+ path: 'eew',
+ factory: $NotificationEewRouteExtension._fromState,
+ ),
+ ],
+ ),
GoRouteData.$route(
path: 'term-of-service',
factory: $TermOfServiceRouteExtension._fromState,
@@ -246,20 +260,6 @@ RouteBase get $settingsRoute => GoRouteData.$route(
),
],
),
- GoRouteData.$route(
- path: 'notification',
- factory: $NotificationSettingsRouteExtension._fromState,
- routes: [
- GoRouteData.$route(
- path: 'eew',
- factory: $EewNotificationSettingsRouteExtension._fromState,
- ),
- GoRouteData.$route(
- path: 'earthquake',
- factory: $EarthquakeNotificationSettingsRouteExtension._fromState,
- ),
- ],
- ),
GoRouteData.$route(
path: 'debugger',
factory: $DebuggerRouteExtension._fromState,
@@ -294,6 +294,60 @@ extension $SettingsRouteExtension on SettingsRoute {
void replace(BuildContext context) => context.replace(location);
}
+extension $NotificationRouteExtension on NotificationRoute {
+ static NotificationRoute _fromState(GoRouterState state) =>
+ const NotificationRoute();
+
+ String get location => GoRouteData.$location(
+ '/settings/notification',
+ );
+
+ 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);
+}
+
+extension $NotificationEarthquakeRouteExtension on NotificationEarthquakeRoute {
+ static NotificationEarthquakeRoute _fromState(GoRouterState state) =>
+ const NotificationEarthquakeRoute();
+
+ String get location => GoRouteData.$location(
+ '/settings/notification/earthquake',
+ );
+
+ 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);
+}
+
+extension $NotificationEewRouteExtension on NotificationEewRoute {
+ static NotificationEewRoute _fromState(GoRouterState state) =>
+ const NotificationEewRoute();
+
+ String get location => GoRouteData.$location(
+ '/settings/notification/eew',
+ );
+
+ 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);
+}
+
extension $TermOfServiceRouteExtension on TermOfServiceRoute {
static TermOfServiceRoute _fromState(GoRouterState state) =>
TermOfServiceRoute(
@@ -463,62 +517,6 @@ extension $DonationExecutedRouteExtension on DonationExecutedRoute {
context.replace(location, extra: $extra);
}
-extension $NotificationSettingsRouteExtension on NotificationSettingsRoute {
- static NotificationSettingsRoute _fromState(GoRouterState state) =>
- const NotificationSettingsRoute();
-
- String get location => GoRouteData.$location(
- '/settings/notification',
- );
-
- 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);
-}
-
-extension $EewNotificationSettingsRouteExtension
- on EewNotificationSettingsRoute {
- static EewNotificationSettingsRoute _fromState(GoRouterState state) =>
- const EewNotificationSettingsRoute();
-
- String get location => GoRouteData.$location(
- '/settings/notification/eew',
- );
-
- 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);
-}
-
-extension $EarthquakeNotificationSettingsRouteExtension
- on EarthquakeNotificationSettingsRoute {
- static EarthquakeNotificationSettingsRoute _fromState(GoRouterState state) =>
- const EarthquakeNotificationSettingsRoute();
-
- String get location => GoRouteData.$location(
- '/settings/notification/earthquake',
- );
-
- 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);
-}
-
extension $DebuggerRouteExtension on DebuggerRoute {
static DebuggerRoute _fromState(GoRouterState state) => const DebuggerRoute();
@@ -597,7 +595,7 @@ bool _$boolConverter(String value) {
// RiverpodGenerator
// **************************************************************************
-String _$goRouterHash() => r'ca25653fd56b61e1ab0e3745908c1e74b25bdf8e';
+String _$goRouterHash() => r'34628ddaf293391bee61bfe6a91ef969868b751a';
/// See also [goRouter].
@ProviderFor(goRouter)
diff --git a/app/lib/feature/earthquake_history/ui/components/earthquake_history_list_tile.dart b/app/lib/feature/earthquake_history/ui/components/earthquake_history_list_tile.dart
index 3bd3990b5..2514979b4 100644
--- a/app/lib/feature/earthquake_history/ui/components/earthquake_history_list_tile.dart
+++ b/app/lib/feature/earthquake_history/ui/components/earthquake_history_list_tile.dart
@@ -12,7 +12,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart';
-import 'package:jma_code_table_types/jma_code_table_types.dart';
+import 'package:jma_code_table_types/jma_code_table.pb.dart';
List preview() => [
EarthquakeHistoryListTile(
diff --git a/app/lib/feature/home/view/home_view.dart b/app/lib/feature/home/view/home_view.dart
index 57baa0e78..3e60b1f75 100644
--- a/app/lib/feature/home/view/home_view.dart
+++ b/app/lib/feature/home/view/home_view.dart
@@ -11,12 +11,12 @@ import 'package:eqmonitor/core/component/sheet/basic_modal_sheet.dart';
import 'package:eqmonitor/core/component/sheet/sheet_floating_action_buttons.dart';
import 'package:eqmonitor/core/hook/use_sheet_controller.dart';
import 'package:eqmonitor/core/provider/capture/intensity_icon_render.dart';
-import 'package:eqmonitor/core/provider/config/notification/fcm_topic_manager.dart';
import 'package:eqmonitor/core/provider/config/permission/permission_status_provider.dart';
import 'package:eqmonitor/core/provider/eew/eew_alive_telegram.dart';
import 'package:eqmonitor/core/provider/kmoni/viewmodel/kmoni_settings.dart';
import 'package:eqmonitor/core/provider/kmoni/viewmodel/kmoni_view_model.dart';
import 'package:eqmonitor/core/provider/kmoni/widget/kmoni_maintenance_widget.dart';
+import 'package:eqmonitor/core/provider/notification_token.dart';
import 'package:eqmonitor/core/provider/ntp/ntp_provider.dart';
import 'package:eqmonitor/core/router/router.dart';
import 'package:eqmonitor/feature/home/component/eew/eew_widget.dart';
@@ -29,6 +29,9 @@ import 'package:eqmonitor/feature/home/component/sheet/status_widget.dart';
import 'package:eqmonitor/feature/home/component/sheet/update_widget.dart';
import 'package:eqmonitor/feature/home/features/map/view/main_map_view.dart';
import 'package:eqmonitor/feature/home/features/map/viewmodel/main_map_viewmodel.dart';
+import 'package:eqmonitor/feature/settings/features/notification_remote_settings/data/service/fcm_token_change_detector.dart';
+import 'package:eqmonitor/feature/settings/features/notification_remote_settings/data/service/notification_remote_authentication_service.dart';
+import 'package:eqmonitor/feature/settings/features/notification_remote_settings/data/service/notification_remote_settings_migrate_service.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
@@ -72,8 +75,24 @@ class _HomeBodyWidget extends HookConsumerWidget {
(
ref.read(kmoniViewModelProvider.notifier).initialize(),
ref.read(permissionProvider.notifier).initialize(),
- ref.read(fcmTopicManagerProvider.notifier).setup(),
ref.read(ntpProvider.notifier).sync(),
+ () async {
+ final fcmTokenHasChanged =
+ await ref.read(fcmTokenChangeDetectorProvider.future);
+ if (fcmTokenHasChanged) {
+ final token = await ref.read(notificationTokenProvider.future);
+ final fcmToken = token.fcmToken;
+ if (fcmToken == null) {
+ return;
+ }
+ await ref
+ .read(notificationRemoteAuthenticateServiceProvider)
+ .updateToken(fcmToken: fcmToken);
+ await ref
+ .read(fcmTokenChangeDetectorProvider.notifier)
+ .save(fcmToken);
+ }
+ }(),
Future.doWhile(() async {
try {
final renderer = MapComponentsRenderer();
@@ -335,6 +354,7 @@ class _Sheet extends StatelessWidget {
const EewWidgets(),
const SheetStatusWidget(),
const KmoniMaintenanceWidget(),
+ const _NotificationMigrationWidget(),
const ParameterLoaderWidget(),
const UpdateWidget(),
const EarthquakeHistorySheetWidget(),
@@ -414,3 +434,45 @@ class _KmoniScale extends ConsumerWidget {
);
}
}
+
+class _NotificationMigrationWidget extends ConsumerWidget {
+ const _NotificationMigrationWidget();
+
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ final state =
+ ref.watch(notificationRemoteSettingsInitialSetupNotifierProvider);
+ return switch (state) {
+ AsyncLoading() => const SizedBox.shrink(),
+ AsyncError(:final error) => ListTile(
+ title: const Text('通知設定の移行に失敗しました'),
+ subtitle: Text(error.toString()),
+ leading: const Icon(Icons.error),
+ ),
+ AsyncData(:final value) => switch (value) {
+ NotificationRemoteSettingsSetupState.initial =>
+ const SizedBox.shrink(),
+ NotificationRemoteSettingsSetupState.waitingForFcmToken =>
+ const ListTile(
+ title: Text('FCMトークンの取得中'),
+ leading: CircularProgressIndicator(),
+ ),
+ NotificationRemoteSettingsSetupState.registering => const ListTile(
+ title: Text('FCMトークンの登録中'),
+ leading: CircularProgressIndicator(),
+ ),
+ NotificationRemoteSettingsSetupState.migrating => const ListTile(
+ title: Text('通知設定の移行中'),
+ leading: CircularProgressIndicator(),
+ ),
+ NotificationRemoteSettingsSetupState.unsubscribingOldTopics =>
+ const ListTile(
+ title: Text('旧通知設定の解除中'),
+ leading: CircularProgressIndicator(),
+ ),
+ NotificationRemoteSettingsSetupState.completed =>
+ 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 a81c49833..36d484e02 100644
--- a/app/lib/feature/settings/children/config/debug/debugger_page.dart
+++ b/app/lib/feature/settings/children/config/debug/debugger_page.dart
@@ -1,3 +1,4 @@
+import 'package:eqmonitor/core/component/container/bordered_container.dart';
import 'package:eqmonitor/core/provider/dio_provider.dart';
import 'package:eqmonitor/core/provider/telegram_url/provider/telegram_url_provider.dart';
import 'package:eqmonitor/core/router/router.dart';
@@ -159,9 +160,56 @@ class _DebugWidget extends ConsumerWidget {
title: const Text('Dio Proxy'),
subtitle: const Text('macbook-pro:9090へのPROXY'),
),
+ BorderedContainer(
+ child: Column(
+ children:
+ ref.watch(goRouterProvider).configuration.routes.map((e) {
+ final route = e as GoRoute;
+ return _Route(
+ routes: [route],
+ );
+ }).toList(),
+ ),
+ ),
],
),
),
);
}
}
+
+class _Route extends StatelessWidget {
+ const _Route({
+ required this.routes,
+ this.depth = 0,
+ this.parent = const [],
+ });
+
+ final List routes;
+ final int depth;
+ final List parent;
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: routes.map(
+ (route) {
+ if (route.routes.isNotEmpty) {
+ return _Route(
+ routes: route.routes.cast(),
+ depth: depth + 1,
+ parent: [...parent, route],
+ );
+ }
+ return ListTile(
+ title: Text([...parent, route].map((e) => e.path).join('/')),
+ onTap: () => context.push(
+ [...parent, route].map((e) => e.path).join('/'),
+ ),
+ visualDensity: VisualDensity.compact,
+ );
+ },
+ ).toList(),
+ );
+ }
+}
diff --git a/app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_page.dart b/app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_page.dart
deleted file mode 100644
index c212247ec..000000000
--- a/app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_page.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-import 'dart:async';
-
-import 'package:eqapi_types/eqapi_types.dart';
-import 'package:eqmonitor/core/component/container/bordered_container.dart';
-import 'package:eqmonitor/core/foundation/result.dart';
-import 'package:eqmonitor/core/provider/log/talker.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.dart';
-import 'package:eqmonitor/feature/settings/component/settings_section_header.dart';
-import 'package:flutter/material.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-
-class EarthquakeNotificationSettingsPage extends ConsumerWidget {
- const EarthquakeNotificationSettingsPage({super.key});
-
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final choices = EarthquakeNotificationSettingsViewModel.choices;
- final state = ref.watch(earthquakeNotificationSettingsViewModelProvider);
-
- Future onSwitchChanged({required bool value}) async {
- showDialog(
- barrierDismissible: false,
- context: context,
- builder: (_) => const Center(
- child: CircularProgressIndicator.adaptive(),
- ),
- ).ignore();
- final Result result;
- if (value) {
- // しない -> すべて
- result = await ref
- .read(
- earthquakeNotificationSettingsViewModelProvider.notifier,
- )
- .registerToTopic(choices.first);
- } else {
- // 任意のTopic -> しない
- result = await ref
- .read(
- earthquakeNotificationSettingsViewModelProvider.notifier,
- )
- .unregisterFromTopic();
- }
- if (!context.mounted) {
- return;
- }
- if (result case Failure(:final exception, :final stackTrace)) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(
- '通知設定の変更に失敗しました: $exception',
- ),
- ),
- );
- ref.read(talkerProvider).error(exception, exception, stackTrace);
- }
- if (context.mounted && Navigator.of(context).canPop()) {
- Navigator.of(context).pop();
- }
- }
-
- return Scaffold(
- appBar: AppBar(
- title: const Text('地震情報 通知設定'),
- ),
- body: Column(
- children: [
- BorderedContainer(
- elevation: 1,
- padding: EdgeInsets.zero,
- child: SwitchListTile.adaptive(
- value: state != null,
- onChanged: (value) => onSwitchChanged(value: value),
- title: const Text('地震情報の通知を受信する'),
- ),
- ),
- const Divider(),
- Expanded(
- child: AnimatedSwitcher(
- duration: const Duration(milliseconds: 300),
- child: state == null
- ? const SizedBox.shrink()
- : Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const SettingsSectionHeader(
- text: '最大震度',
- ),
- Expanded(
- child: ListView.builder(
- itemCount: choices.length,
- itemBuilder: (context, index) {
- final choice = choices[index];
- return RadioListTile.adaptive(
- groupValue: state,
- value: choice,
- onChanged: (value) async {
- unawaited(
- showDialog(
- barrierDismissible: false,
- context: context,
- builder: (_) => const Center(
- child: CircularProgressIndicator
- .adaptive(),
- ),
- ),
- );
- final result = await ref
- .read(
- earthquakeNotificationSettingsViewModelProvider
- .notifier,
- )
- .registerToTopic(choice);
- if (!context.mounted) {
- return;
- }
- if (result
- case Failure(
- :final exception,
- :final stackTrace
- )) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(
- '通知設定の変更に失敗しました: $exception',
- ),
- ),
- );
- ref.read(talkerProvider).error(
- exception,
- exception,
- stackTrace,
- );
- }
- if (context.mounted &&
- Navigator.of(context).canPop()) {
- Navigator.of(context).pop();
- }
- },
- title: Text(
- switch (choice.intensity) {
- null => 'すべて',
- JmaIntensity.seven => '震度7',
- final JmaIntensity intensity =>
- '震度${intensity.type}以上',
- }
- .replaceAll('-', '弱')
- .replaceAll('+', '強'),
- ),
- visualDensity: VisualDensity.compact,
- );
- },
- ),
- ),
- ],
- ),
- ),
- ),
- ],
- ),
- );
- }
-}
diff --git a/app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_page.dart b/app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_page.dart
deleted file mode 100644
index ceb6dd649..000000000
--- a/app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_page.dart
+++ /dev/null
@@ -1,216 +0,0 @@
-import 'package:eqapi_types/eqapi_types.dart';
-import 'package:eqmonitor/core/component/container/bordered_container.dart';
-import 'package:eqmonitor/core/foundation/result.dart';
-import 'package:eqmonitor/core/provider/config/notification/fcm_topic_manager.dart';
-import 'package:eqmonitor/core/provider/log/talker.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.dart';
-import 'package:eqmonitor/feature/settings/component/settings_section_header.dart';
-import 'package:flutter/material.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-
-class EewNotificationSettingsPage extends ConsumerWidget {
- const EewNotificationSettingsPage({super.key});
-
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final choices = EewNotificationsSettingsViewModel.choices;
- final state = ref.watch(eewNotificationsSettingsViewModelProvider);
-
- Future onSwitchChanged({required bool value}) async {
- showDialog(
- barrierDismissible: false,
- context: context,
- builder: (_) => const Center(
- child: CircularProgressIndicator.adaptive(),
- ),
- ).ignore();
- final Result result;
- if (value) {
- // しない -> すべて
- result = await ref
- .read(
- eewNotificationsSettingsViewModelProvider.notifier,
- )
- .registerToTopic(const FcmEewAllTopic());
- } else {
- // 任意のTopic -> しない
- result = await ref
- .read(
- eewNotificationsSettingsViewModelProvider.notifier,
- )
- .unregisterFromTopic();
- }
- if (!context.mounted) {
- return;
- }
- if (result case Failure(:final exception, :final stackTrace)) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(
- '通知設定の変更に失敗しました: $exception',
- ),
- ),
- );
- ref.read(talkerProvider).error(exception, exception, stackTrace);
- }
- if (context.mounted && Navigator.of(context).canPop()) {
- Navigator.of(context).pop();
- }
- }
-
- return Scaffold(
- appBar: AppBar(
- title: const Text('緊急地震速報 通知設定'),
- ),
- body: Column(
- children: [
- BorderedContainer(
- elevation: 1,
- padding: EdgeInsets.zero,
- child: SwitchListTile.adaptive(
- value: state != null,
- onChanged: (value) => onSwitchChanged(value: value),
- title: const Text('地震情報の通知を受信する'),
- ),
- ),
- const _InformationCard(
- icon: Icon(Icons.info),
- title: '緊急地震速報通知についての注意',
- description: '現在、重大な通知には対応していません。\n'
- 'また、現在地に基づいた通知などの詳細な通知条件分岐には対応していません。\n'
- '詳しくは、ロードマップをご覧ください。',
- ),
- const Divider(),
- Expanded(
- child: AnimatedSwitcher(
- duration: const Duration(milliseconds: 300),
- child: state == null
- ? const SizedBox.shrink()
- : Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const SettingsSectionHeader(
- text: '予想最大震度',
- ),
- Expanded(
- child: ListView.builder(
- itemCount: choices.length,
- itemBuilder: (_, index) {
- final choice = choices[index];
- return RadioListTile.adaptive(
- groupValue: state,
- value: choice,
- onChanged: (value) async {
- showDialog(
- barrierDismissible: false,
- context: context,
- builder: (_) => const Center(
- child:
- CircularProgressIndicator.adaptive(),
- ),
- ).ignore();
- final result = await ref
- .read(
- eewNotificationsSettingsViewModelProvider
- .notifier,
- )
- .registerToTopic(choice);
- if (!context.mounted) {
- return;
- }
- if (result
- case Failure(
- :final exception,
- :final stackTrace
- )) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(
- '通知設定の変更に失敗しました: $exception',
- ),
- ),
- );
- ref.read(talkerProvider).error(
- exception,
- exception,
- stackTrace,
- );
- }
- if (context.mounted &&
- Navigator.of(context).canPop()) {
- Navigator.of(context).pop();
- }
- },
- title: Text(
- switch (choice) {
- FcmEewAllTopic() => 'すべて',
- FcmEewIntensityTopic(:final intensity)
- when intensity == JmaIntensity.seven =>
- '震度7',
- FcmEewIntensityTopic(:final intensity) =>
- '震度${intensity.type}以上'
- .replaceAll('+', '強')
- .replaceAll('-', '弱'),
- _ => ''
- },
- ),
- );
- },
- ),
- ),
- ],
- ),
- ),
- ),
- ],
- ),
- );
- }
-}
-
-class _InformationCard extends StatelessWidget {
- const _InformationCard({
- required this.title,
- required this.description,
- required this.icon,
- });
- final Widget icon;
- final String title;
-
- final String description;
-
- @override
- Widget build(BuildContext context) {
- final theme = Theme.of(context);
- return BorderedContainer(
- elevation: 1,
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Icon(
- Icons.info,
- color: theme.colorScheme.onSurface,
- ),
- const SizedBox(width: 8),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- title,
- style: theme.textTheme.titleMedium!.copyWith(
- fontWeight: FontWeight.bold,
- ),
- ),
- const SizedBox(height: 4),
- Text(
- description,
- ),
- ],
- ),
- ),
- ],
- ),
- );
- }
-}
diff --git a/app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.dart b/app/lib/feature/settings/children/config/notification/earthquake/earthquake_notification_settings_view_model.dart
similarity index 53%
rename from app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.dart
rename to app/lib/feature/settings/children/config/notification/earthquake/earthquake_notification_settings_view_model.dart
index 0678b94f0..273b09deb 100644
--- a/app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.dart
+++ b/app/lib/feature/settings/children/config/notification/earthquake/earthquake_notification_settings_view_model.dart
@@ -1,6 +1,5 @@
import 'package:collection/collection.dart';
import 'package:eqapi_types/eqapi_types.dart';
-import 'package:eqmonitor/core/foundation/result.dart';
import 'package:eqmonitor/core/provider/config/notification/fcm_topic_manager.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -22,36 +21,6 @@ class EarthquakeNotificationSettingsViewModel
return matchedTopic;
}
- Future> registerToTopic(
- FcmEarthquakeTopic topic,
- ) async {
- final result = await (
- ref.read(fcmTopicManagerProvider.notifier).registerToTopic(topic),
- state != null
- ? ref
- .read(fcmTopicManagerProvider.notifier)
- .unregisterFromTopic(state!)
- : Future.value(),
- ).wait;
- if (result.$1 case Success()) {
- state = topic;
- }
- return result.$1;
- }
-
- Future> unregisterFromTopic() async {
- if (state == null) {
- return Result.success(null);
- }
- final result = await ref
- .read(fcmTopicManagerProvider.notifier)
- .unregisterFromTopic(state!);
- if (result case Success()) {
- state = null;
- }
- return result;
- }
-
static List choices = [
const FcmEarthquakeTopic(null),
...([...JmaIntensity.values]..remove(JmaIntensity.fiveUpperNoInput)).map(
diff --git a/app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.g.dart b/app/lib/feature/settings/children/config/notification/earthquake/earthquake_notification_settings_view_model.g.dart
similarity index 96%
rename from app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.g.dart
rename to app/lib/feature/settings/children/config/notification/earthquake/earthquake_notification_settings_view_model.g.dart
index bd39222a6..81b50f361 100644
--- a/app/lib/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.g.dart
+++ b/app/lib/feature/settings/children/config/notification/earthquake/earthquake_notification_settings_view_model.g.dart
@@ -9,7 +9,7 @@ part of 'earthquake_notification_settings_view_model.dart';
// **************************************************************************
String _$earthquakeNotificationSettingsViewModelHash() =>
- r'bcffe637838e213309a0e7da89621b7c4c7cc79d';
+ r'5a362a2d083e95cf8afb1f35a5c913812cfc9073';
/// See also [EarthquakeNotificationSettingsViewModel].
@ProviderFor(EarthquakeNotificationSettingsViewModel)
diff --git a/app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.dart b/app/lib/feature/settings/children/config/notification/eew/eew_notification_settings_view_model.dart
similarity index 52%
rename from app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.dart
rename to app/lib/feature/settings/children/config/notification/eew/eew_notification_settings_view_model.dart
index 3b7b00581..99d660fb1 100644
--- a/app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.dart
+++ b/app/lib/feature/settings/children/config/notification/eew/eew_notification_settings_view_model.dart
@@ -1,6 +1,5 @@
import 'package:collection/collection.dart';
import 'package:eqapi_types/eqapi_types.dart';
-import 'package:eqmonitor/core/foundation/result.dart';
import 'package:eqmonitor/core/provider/config/notification/fcm_topic_manager.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -23,36 +22,6 @@ class EewNotificationsSettingsViewModel
return matchedTopic;
}
- Future> registerToTopic(
- FcmEewTopic topic,
- ) async {
- final result = await (
- ref.read(fcmTopicManagerProvider.notifier).registerToTopic(topic),
- state != null
- ? ref
- .read(fcmTopicManagerProvider.notifier)
- .unregisterFromTopic(state!)
- : Future.value(),
- ).wait;
- if (result.$1 case Success()) {
- state = topic;
- }
- return result.$1;
- }
-
- Future> unregisterFromTopic() async {
- if (state == null) {
- return Result.success(null);
- }
- final result = await ref
- .read(fcmTopicManagerProvider.notifier)
- .unregisterFromTopic(state!);
- if (result case Success()) {
- state = null;
- }
- return result;
- }
-
static List choices = [
const FcmEewAllTopic(),
...([...JmaIntensity.values]..remove(JmaIntensity.fiveUpperNoInput)).map(
diff --git a/app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.g.dart b/app/lib/feature/settings/children/config/notification/eew/eew_notification_settings_view_model.g.dart
similarity index 96%
rename from app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.g.dart
rename to app/lib/feature/settings/children/config/notification/eew/eew_notification_settings_view_model.g.dart
index aef24a8a5..30012a56c 100644
--- a/app/lib/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.g.dart
+++ b/app/lib/feature/settings/children/config/notification/eew/eew_notification_settings_view_model.g.dart
@@ -9,7 +9,7 @@ part of 'eew_notification_settings_view_model.dart';
// **************************************************************************
String _$eewNotificationsSettingsViewModelHash() =>
- r'a9de37bd8b96cd420a5294da1ee895864a770d21';
+ r'2610a9afe740d8c373a5302e56b34eecaccd65ca';
/// See also [EewNotificationsSettingsViewModel].
@ProviderFor(EewNotificationsSettingsViewModel)
diff --git a/app/lib/feature/settings/children/config/notification/notification_setting_page.dart b/app/lib/feature/settings/children/config/notification/notification_setting_page.dart
deleted file mode 100644
index f178bb3ba..000000000
--- a/app/lib/feature/settings/children/config/notification/notification_setting_page.dart
+++ /dev/null
@@ -1,326 +0,0 @@
-import 'package:eqapi_types/eqapi_types.dart';
-import 'package:eqmonitor/core/component/container/bordered_container.dart';
-import 'package:eqmonitor/core/foundation/result.dart';
-import 'package:eqmonitor/core/provider/config/notification/fcm_topic_manager.dart';
-import 'package:eqmonitor/core/provider/config/permission/permission_status_provider.dart';
-import 'package:eqmonitor/core/provider/debugger/debugger_provider.dart';
-import 'package:eqmonitor/core/provider/notification_token.dart';
-import 'package:eqmonitor/core/router/router.dart';
-import 'package:eqmonitor/core/util/fullscreen_loading_overlay.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/children/earthquake/earthquake_notification_settings_view_model.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/children/eew/eew_notification_settings_view_model.dart';
-import 'package:eqmonitor/feature/settings/children/config/notification/notifiication_settings_view_model.dart';
-import 'package:eqmonitor/feature/settings/component/settings_section_header.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter_hooks/flutter_hooks.dart';
-import 'package:go_router/go_router.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
-
-class NotificationSettingsPage extends StatelessWidget {
- const NotificationSettingsPage({super.key});
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: const Text('通知設定'),
- ),
- body: const _NotificationSettingsBody(),
- );
- }
-}
-
-class _NotificationSettingsBody extends HookConsumerWidget {
- const _NotificationSettingsBody();
-
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- useEffect(
- () {
- WidgetsBinding.instance.endOfFrame
- .then((_) => ref.read(permissionProvider.notifier).initialize());
- return null;
- },
- [],
- );
- final state = ref.watch(notificationSettingsViewModelProvider);
- if (state.isNotificatioonPermissionAllowed) {
- return const _OnNotificationPermissionAllowed();
- } else {
- return const _OnNotificationPermissionDisallowed();
- }
- }
-}
-
-class _OnNotificationPermissionAllowed extends ConsumerWidget {
- const _OnNotificationPermissionAllowed();
-
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final theme = Theme.of(context);
- final colorScheme = theme.colorScheme;
- final state = ref.watch(notificationSettingsViewModelProvider);
- return ListView(
- children: [
- // 通知権限
- BorderedContainer(
- elevation: 1,
- child: Row(
- children: [
- Icon(
- Icons.check,
- color: colorScheme.onSurface,
- ),
- const SizedBox(width: 8),
- Text(
- '通知権限が許可されています',
- style: theme.textTheme.titleMedium!.copyWith(
- fontWeight: FontWeight.bold,
- ),
- ),
- ],
- ),
- ),
- const SettingsSectionHeader(
- text: '地震情報',
- ),
- ListTile(
- title: const Text('緊急地震速報(予報・警報)'),
- subtitle: Text(
- switch (ref.watch(eewNotificationsSettingsViewModelProvider)) {
- null => '受信しない',
- FcmEewAllTopic() => 'すべて受信する',
- FcmEewIntensityTopic(:final intensity)
- when intensity == JmaIntensity.seven =>
- '震度7',
- FcmEewIntensityTopic(:final intensity) => '震度${intensity.type}以上'
- .replaceAll('+', '強')
- .replaceAll('-', '弱'),
- _ => '',
- },
- ),
- trailing: const Icon(
- Icons.arrow_forward_ios,
- size: 16,
- ),
- onTap: () =>
- context.push(const EewNotificationSettingsRoute().location),
- ),
- ListTile(
- title: const Text('震度・震源に関する情報'),
- subtitle: Text(
- switch (
- ref.watch(earthquakeNotificationSettingsViewModelProvider)) {
- null => '受信しない',
- final FcmEarthquakeTopic topic when topic.intensity == null =>
- 'すべて受信する',
- final FcmEarthquakeTopic topic
- when topic.intensity == JmaIntensity.seven =>
- '震度7のみ',
- final FcmEarthquakeTopic topic => '震度${topic.intensity!.type}以上'
- .replaceAll('-', '弱')
- .replaceAll('+', '強'),
- },
- ),
- trailing: const Icon(
- Icons.arrow_forward_ios,
- size: 16,
- ),
- onTap: () => context
- .push(const EarthquakeNotificationSettingsRoute().location),
- ),
- SwitchListTile.adaptive(
- value: state.isVzse40Subscribed,
- onChanged: (value) async {
- final notifier =
- ref.read(notificationSettingsViewModelProvider.notifier);
- final result = await showFullScreenLoadingOverlay(
- context,
- value
- ? notifier.registerToVzse40()
- : notifier.unregisterFromVzse40(),
- );
- if (!context.mounted) {
- return;
- }
- if (result case Failure(:final exception)) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(
- '設定の変更中にエラーが発生しました: $exception',
- ),
- ),
- );
- }
- },
- title: const Text('地震・津波に関するお知らせ'),
- subtitle: const Text(
- '地震・津波の試験・訓練配信のお知らせ、'
- '自治体震度データの入電停止等のお知らせを配信します',
- ),
- ),
- const SettingsSectionHeader(
- text: 'その他',
- ),
- SwitchListTile.adaptive(
- value: state.isNoticeSubscribed,
- onChanged: (value) async {
- final notifier =
- ref.read(notificationSettingsViewModelProvider.notifier);
- final result = await showFullScreenLoadingOverlay(
- context,
- value
- ? notifier.registerToNotice()
- : notifier.unregisterFromNotice(),
- );
- if (!context.mounted) {
- return;
- }
- if (result case Failure(:final exception)) {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(
- '設定の変更中にエラーが発生しました: $exception',
- ),
- ),
- );
- }
- },
- title: const Text('お知らせ'),
- subtitle: const Text('アップデート情報や開発者からのお知らせをお伝えします'),
- ),
- if (ref.watch(
- debuggerProvider.select(
- (value) => value.isDebugger,
- ),
- )) ...[
- const SettingsSectionHeader(text: 'FCM DEBUG'),
- Consumer(
- builder: (context, ref, _) {
- final notificationTokenState =
- ref.watch(notificationTokenProvider);
- return notificationTokenState.when(
- data: (value) => Column(
- children: [
- ListTile(
- title: const Text('FCM デバイストークン'),
- trailing: Text(
- value.fcmToken?.obfuscate ?? '不明',
- ),
- onTap: () => Clipboard.setData(
- ClipboardData(text: value.fcmToken ?? ''),
- ).then((_) {
- ScaffoldMessenger.of(context).showSnackBar(
- const SnackBar(
- content: Text('コピーしました'),
- ),
- );
- }),
- visualDensity: VisualDensity.compact,
- ),
- ListTile(
- title: const Text(
- 'APNS デバイストークン',
- ),
- trailing: Text(
- value.apnsToken?.obfuscate ?? '不明',
- ),
- onTap: () => Clipboard.setData(
- ClipboardData(text: value.apnsToken ?? ''),
- ).then((_) {
- ScaffoldMessenger.of(context).showSnackBar(
- const SnackBar(
- content: Text('コピーしました'),
- ),
- );
- }),
- visualDensity: VisualDensity.compact,
- ),
- ],
- ),
- error: (error, stackTrace) => Text(
- 'エラーが発生しました: $error',
- ),
- loading: () => const Center(
- child: CircularProgressIndicator.adaptive(),
- ),
- );
- },
- ),
- ],
- ],
- );
- }
-}
-
-class _OnNotificationPermissionDisallowed extends ConsumerWidget {
- const _OnNotificationPermissionDisallowed();
-
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final theme = Theme.of(context);
- final colorScheme = theme.colorScheme;
- return Column(
- children: [
- BorderedContainer(
- accentColor: Colors.redAccent.withOpacity(0.1),
- elevation: 1,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- Row(
- children: [
- Icon(
- Icons.error,
- color: theme.colorScheme.onSurface,
- ),
- const SizedBox(width: 8),
- Text(
- '通知権限が許可されていません',
- style: theme.textTheme.titleMedium!.copyWith(
- fontWeight: FontWeight.bold,
- ),
- ),
- ],
- ),
- Transform.translate(
- offset: const Offset(8, 8),
- child: TextButton(
- style: TextButton.styleFrom(
- padding: const EdgeInsets.all(8),
- ),
- onPressed: () async {
- await ref
- .read(permissionProvider.notifier)
- .requestNotificationPermission();
- },
- child: Text(
- '許可する',
- style: theme.textTheme.titleMedium!.copyWith(
- color: colorScheme.primary,
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- ],
- );
- }
-}
-
-extension StringEx on String {
- String get obfuscate {
- final length = this.length;
- if (length <= 8) {
- return '****';
- }
- return [
- substring(0, 4),
- '*' * 8,
- substring(length - 4, length),
- ].join();
- }
-}
diff --git a/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.dart b/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.dart
deleted file mode 100644
index 024057b4b..000000000
--- a/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.dart
+++ /dev/null
@@ -1,111 +0,0 @@
-import 'package:eqmonitor/core/foundation/result.dart';
-import 'package:eqmonitor/core/provider/config/notification/fcm_topic_manager.dart';
-import 'package:eqmonitor/core/provider/config/permission/permission_status_provider.dart';
-import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:riverpod_annotation/riverpod_annotation.dart';
-
-part 'notifiication_settings_view_model.freezed.dart';
-part 'notifiication_settings_view_model.g.dart';
-
-@riverpod
-class NotificationSettingsViewModel extends _$NotificationSettingsViewModel {
- @override
- NotificationSettingsState build() {
- return _init(
- subscribedFcmTopics: ref.watch(fcmTopicManagerProvider),
- isNotificationPermissionAllowed:
- ref.watch(permissionProvider.select((v) => v.notification)),
- );
- }
-
- NotificationSettingsState _init({
- required List subscribedFcmTopics,
- required bool isNotificationPermissionAllowed,
- }) {
- final vzse40Topic = FcmBasicTopic(FcmTopics.vzse40);
- final noticeTopic = FcmBasicTopic(FcmTopics.notice);
- return NotificationSettingsState(
- isNotificatioonPermissionAllowed: isNotificationPermissionAllowed,
- isVzse40Subscribed: subscribedFcmTopics.contains(vzse40Topic.topic),
- isNoticeSubscribed: subscribedFcmTopics.contains(noticeTopic.topic),
- );
- }
-
- Future> registerToVzse40() async {
- final topicNotifier = ref.read(fcmTopicManagerProvider.notifier);
- // 既に登録済みの場合は何もしない
- if (state.isVzse40Subscribed) {
- return Result.success(null);
- }
- final result = await topicNotifier.registerToTopic(
- FcmBasicTopic(FcmTopics.vzse40),
- );
- if (result case Success()) {
- state = state.copyWith(isVzse40Subscribed: true);
- }
- return result;
- }
-
- Future> unregisterFromVzse40() async {
- final topicNotifier = ref.read(fcmTopicManagerProvider.notifier);
- // 登録されていない場合は何もしない
- if (!state.isVzse40Subscribed) {
- return Result.success(null);
- }
- final result = await topicNotifier.unregisterFromTopic(
- FcmBasicTopic(FcmTopics.vzse40),
- );
- if (result case Success()) {
- state = state.copyWith(isVzse40Subscribed: false);
- }
- return result;
- }
-
- Future> registerToNotice() async {
- final topicNotifier = ref.read(fcmTopicManagerProvider.notifier);
- // 既に登録済みの場合は何もしない
- if (state.isNoticeSubscribed) {
- return Result.success(null);
- }
- final result = await topicNotifier.registerToTopic(
- FcmBasicTopic(FcmTopics.notice),
- );
- if (result case Success()) {
- state = state.copyWith(isNoticeSubscribed: true);
- }
- return result;
- }
-
- Future> unregisterFromNotice() async {
- final topicNotifier = ref.read(fcmTopicManagerProvider.notifier);
- // 登録されていない場合は何もしない
- if (!state.isNoticeSubscribed) {
- return Result.success(null);
- }
- final result = await topicNotifier.unregisterFromTopic(
- FcmBasicTopic(FcmTopics.notice),
- );
- if (result case Success()) {
- state = state.copyWith(isNoticeSubscribed: false);
- }
- return result;
- }
-}
-
-@freezed
-class NotificationSettingsState with _$NotificationSettingsState {
- factory NotificationSettingsState({
- required bool isNotificatioonPermissionAllowed,
-
- /// 地震・津波に関するお知らせ
- required bool isVzse40Subscribed,
-
- /// お知らせ
- required bool isNoticeSubscribed,
- }) = _NotificationSettingsState;
-
- factory NotificationSettingsState.fromJson(
- Map json,
- ) =>
- _$NotificationSettingsStateFromJson(json);
-}
diff --git a/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.freezed.dart b/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.freezed.dart
deleted file mode 100644
index 9d53a838e..000000000
--- a/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.freezed.dart
+++ /dev/null
@@ -1,221 +0,0 @@
-// coverage:ignore-file
-// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
-
-part of 'notifiication_settings_view_model.dart';
-
-// **************************************************************************
-// FreezedGenerator
-// **************************************************************************
-
-T _$identity(T value) => value;
-
-final _privateConstructorUsedError = UnsupportedError(
- 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
-
-NotificationSettingsState _$NotificationSettingsStateFromJson(
- Map json) {
- return _NotificationSettingsState.fromJson(json);
-}
-
-/// @nodoc
-mixin _$NotificationSettingsState {
- bool get isNotificatioonPermissionAllowed =>
- throw _privateConstructorUsedError;
-
- /// 地震・津波に関するお知らせ
- bool get isVzse40Subscribed => throw _privateConstructorUsedError;
-
- /// お知らせ
- bool get isNoticeSubscribed => throw _privateConstructorUsedError;
-
- Map toJson() => throw _privateConstructorUsedError;
- @JsonKey(ignore: true)
- $NotificationSettingsStateCopyWith get copyWith =>
- throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $NotificationSettingsStateCopyWith<$Res> {
- factory $NotificationSettingsStateCopyWith(NotificationSettingsState value,
- $Res Function(NotificationSettingsState) then) =
- _$NotificationSettingsStateCopyWithImpl<$Res, NotificationSettingsState>;
- @useResult
- $Res call(
- {bool isNotificatioonPermissionAllowed,
- bool isVzse40Subscribed,
- bool isNoticeSubscribed});
-}
-
-/// @nodoc
-class _$NotificationSettingsStateCopyWithImpl<$Res,
- $Val extends NotificationSettingsState>
- implements $NotificationSettingsStateCopyWith<$Res> {
- _$NotificationSettingsStateCopyWithImpl(this._value, this._then);
-
- // ignore: unused_field
- final $Val _value;
- // ignore: unused_field
- final $Res Function($Val) _then;
-
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? isNotificatioonPermissionAllowed = null,
- Object? isVzse40Subscribed = null,
- Object? isNoticeSubscribed = null,
- }) {
- return _then(_value.copyWith(
- isNotificatioonPermissionAllowed: null == isNotificatioonPermissionAllowed
- ? _value.isNotificatioonPermissionAllowed
- : isNotificatioonPermissionAllowed // ignore: cast_nullable_to_non_nullable
- as bool,
- isVzse40Subscribed: null == isVzse40Subscribed
- ? _value.isVzse40Subscribed
- : isVzse40Subscribed // ignore: cast_nullable_to_non_nullable
- as bool,
- isNoticeSubscribed: null == isNoticeSubscribed
- ? _value.isNoticeSubscribed
- : isNoticeSubscribed // ignore: cast_nullable_to_non_nullable
- as bool,
- ) as $Val);
- }
-}
-
-/// @nodoc
-abstract class _$$NotificationSettingsStateImplCopyWith<$Res>
- implements $NotificationSettingsStateCopyWith<$Res> {
- factory _$$NotificationSettingsStateImplCopyWith(
- _$NotificationSettingsStateImpl value,
- $Res Function(_$NotificationSettingsStateImpl) then) =
- __$$NotificationSettingsStateImplCopyWithImpl<$Res>;
- @override
- @useResult
- $Res call(
- {bool isNotificatioonPermissionAllowed,
- bool isVzse40Subscribed,
- bool isNoticeSubscribed});
-}
-
-/// @nodoc
-class __$$NotificationSettingsStateImplCopyWithImpl<$Res>
- extends _$NotificationSettingsStateCopyWithImpl<$Res,
- _$NotificationSettingsStateImpl>
- implements _$$NotificationSettingsStateImplCopyWith<$Res> {
- __$$NotificationSettingsStateImplCopyWithImpl(
- _$NotificationSettingsStateImpl _value,
- $Res Function(_$NotificationSettingsStateImpl) _then)
- : super(_value, _then);
-
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? isNotificatioonPermissionAllowed = null,
- Object? isVzse40Subscribed = null,
- Object? isNoticeSubscribed = null,
- }) {
- return _then(_$NotificationSettingsStateImpl(
- isNotificatioonPermissionAllowed: null == isNotificatioonPermissionAllowed
- ? _value.isNotificatioonPermissionAllowed
- : isNotificatioonPermissionAllowed // ignore: cast_nullable_to_non_nullable
- as bool,
- isVzse40Subscribed: null == isVzse40Subscribed
- ? _value.isVzse40Subscribed
- : isVzse40Subscribed // ignore: cast_nullable_to_non_nullable
- as bool,
- isNoticeSubscribed: null == isNoticeSubscribed
- ? _value.isNoticeSubscribed
- : isNoticeSubscribed // ignore: cast_nullable_to_non_nullable
- as bool,
- ));
- }
-}
-
-/// @nodoc
-@JsonSerializable()
-class _$NotificationSettingsStateImpl implements _NotificationSettingsState {
- _$NotificationSettingsStateImpl(
- {required this.isNotificatioonPermissionAllowed,
- required this.isVzse40Subscribed,
- required this.isNoticeSubscribed});
-
- factory _$NotificationSettingsStateImpl.fromJson(Map json) =>
- _$$NotificationSettingsStateImplFromJson(json);
-
- @override
- final bool isNotificatioonPermissionAllowed;
-
- /// 地震・津波に関するお知らせ
- @override
- final bool isVzse40Subscribed;
-
- /// お知らせ
- @override
- final bool isNoticeSubscribed;
-
- @override
- String toString() {
- return 'NotificationSettingsState(isNotificatioonPermissionAllowed: $isNotificatioonPermissionAllowed, isVzse40Subscribed: $isVzse40Subscribed, isNoticeSubscribed: $isNoticeSubscribed)';
- }
-
- @override
- bool operator ==(Object other) {
- return identical(this, other) ||
- (other.runtimeType == runtimeType &&
- other is _$NotificationSettingsStateImpl &&
- (identical(other.isNotificatioonPermissionAllowed,
- isNotificatioonPermissionAllowed) ||
- other.isNotificatioonPermissionAllowed ==
- isNotificatioonPermissionAllowed) &&
- (identical(other.isVzse40Subscribed, isVzse40Subscribed) ||
- other.isVzse40Subscribed == isVzse40Subscribed) &&
- (identical(other.isNoticeSubscribed, isNoticeSubscribed) ||
- other.isNoticeSubscribed == isNoticeSubscribed));
- }
-
- @JsonKey(ignore: true)
- @override
- int get hashCode => Object.hash(runtimeType, isNotificatioonPermissionAllowed,
- isVzse40Subscribed, isNoticeSubscribed);
-
- @JsonKey(ignore: true)
- @override
- @pragma('vm:prefer-inline')
- _$$NotificationSettingsStateImplCopyWith<_$NotificationSettingsStateImpl>
- get copyWith => __$$NotificationSettingsStateImplCopyWithImpl<
- _$NotificationSettingsStateImpl>(this, _$identity);
-
- @override
- Map toJson() {
- return _$$NotificationSettingsStateImplToJson(
- this,
- );
- }
-}
-
-abstract class _NotificationSettingsState implements NotificationSettingsState {
- factory _NotificationSettingsState(
- {required final bool isNotificatioonPermissionAllowed,
- required final bool isVzse40Subscribed,
- required final bool isNoticeSubscribed}) =
- _$NotificationSettingsStateImpl;
-
- factory _NotificationSettingsState.fromJson(Map json) =
- _$NotificationSettingsStateImpl.fromJson;
-
- @override
- bool get isNotificatioonPermissionAllowed;
- @override
-
- /// 地震・津波に関するお知らせ
- bool get isVzse40Subscribed;
- @override
-
- /// お知らせ
- bool get isNoticeSubscribed;
- @override
- @JsonKey(ignore: true)
- _$$NotificationSettingsStateImplCopyWith<_$NotificationSettingsStateImpl>
- get copyWith => throw _privateConstructorUsedError;
-}
diff --git a/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.g.dart b/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.g.dart
deleted file mode 100644
index 0a34debbd..000000000
--- a/app/lib/feature/settings/children/config/notification/notifiication_settings_view_model.g.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-// ignore_for_file: type=lint, duplicate_ignore
-
-part of 'notifiication_settings_view_model.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-_$NotificationSettingsStateImpl _$$NotificationSettingsStateImplFromJson(
- Map json) =>
- $checkedCreate(
- r'_$NotificationSettingsStateImpl',
- json,
- ($checkedConvert) {
- final val = _$NotificationSettingsStateImpl(
- isNotificatioonPermissionAllowed: $checkedConvert(
- 'isNotificatioonPermissionAllowed', (v) => v as bool),
- isVzse40Subscribed:
- $checkedConvert('isVzse40Subscribed', (v) => v as bool),
- isNoticeSubscribed:
- $checkedConvert('isNoticeSubscribed', (v) => v as bool),
- );
- return val;
- },
- );
-
-Map _$$NotificationSettingsStateImplToJson(
- _$NotificationSettingsStateImpl instance) =>
- {
- 'isNotificatioonPermissionAllowed':
- instance.isNotificatioonPermissionAllowed,
- 'isVzse40Subscribed': instance.isVzse40Subscribed,
- 'isNoticeSubscribed': instance.isNoticeSubscribed,
- };
-
-// **************************************************************************
-// RiverpodGenerator
-// **************************************************************************
-
-String _$notificationSettingsViewModelHash() =>
- r'd1daaa3edbf24a7e476a15035f21e8b1c5d18ff9';
-
-/// See also [NotificationSettingsViewModel].
-@ProviderFor(NotificationSettingsViewModel)
-final notificationSettingsViewModelProvider = AutoDisposeNotifierProvider<
- NotificationSettingsViewModel, NotificationSettingsState>.internal(
- NotificationSettingsViewModel.new,
- name: r'notificationSettingsViewModelProvider',
- debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
- ? null
- : _$notificationSettingsViewModelHash,
- dependencies: null,
- allTransitiveDependencies: null,
-);
-
-typedef _$NotificationSettingsViewModel
- = AutoDisposeNotifier;
-// 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/settings/features/notification_local_settings/data/notification_local_settings_model.dart b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.dart
new file mode 100644
index 000000000..d0328fc3b
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.dart
@@ -0,0 +1,55 @@
+import 'package:eqapi_types/eqapi_types.dart';
+import 'package:eqapi_types/lib.dart';
+import 'package:eqapi_types/model/components/core/core.dart';
+import 'package:freezed_annotation/freezed_annotation.dart';
+
+part 'notification_local_settings_model.freezed.dart';
+part 'notification_local_settings_model.g.dart';
+
+@freezed
+class NotificationLocalSettingsModel with _$NotificationLocalSettingsModel {
+ const factory NotificationLocalSettingsModel({
+ @Default(EewSettings()) EewSettings eew,
+ @Default(EarthquakeSettings()) EarthquakeSettings earthquake,
+ }) = _NotificationLocalSettingsModel;
+
+ factory NotificationLocalSettingsModel.fromJson(Map json) =>
+ _$NotificationLocalSettingsModelFromJson(json);
+}
+
+@freezed
+class EewSettings with _$EewSettings {
+ const factory EewSettings({
+ @Default(null) JmaForecastIntensity? emergencyIntensity,
+ @Default(null) JmaForecastIntensity? silentIntensity,
+ @Default([]) List regions,
+ }) = _EewSettings;
+
+ factory EewSettings.fromJson(Map json) =>
+ _$EewSettingsFromJson(json);
+}
+
+@freezed
+class EarthquakeSettings with _$EarthquakeSettings {
+ const factory EarthquakeSettings({
+ @Default(null) JmaForecastIntensity? emergencyIntensity,
+ @Default(null) JmaForecastIntensity? silentIntensity,
+ @Default([]) List regions,
+ }) = _EarthquakeSettings;
+
+ factory EarthquakeSettings.fromJson(Map json) =>
+ _$EarthquakeSettingsFromJson(json);
+}
+
+@freezed
+class Region with _$Region {
+ const factory Region({
+ required String code,
+ required String name,
+ required JmaForecastIntensity emergencyIntensity,
+ required JmaForecastIntensity silentIntensity,
+ required bool isMain,
+ }) = _Region;
+
+ factory Region.fromJson(Map json) => _$RegionFromJson(json);
+}
diff --git a/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.freezed.dart b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.freezed.dart
new file mode 100644
index 000000000..43c39e3f7
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.freezed.dart
@@ -0,0 +1,821 @@
+// coverage:ignore-file
+// GENERATED CODE - DO NOT MODIFY BY HAND
+// ignore_for_file: type=lint
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
+
+part of 'notification_local_settings_model.dart';
+
+// **************************************************************************
+// FreezedGenerator
+// **************************************************************************
+
+T _$identity(T value) => value;
+
+final _privateConstructorUsedError = UnsupportedError(
+ 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
+
+NotificationLocalSettingsModel _$NotificationLocalSettingsModelFromJson(
+ Map json) {
+ return _NotificationLocalSettingsModel.fromJson(json);
+}
+
+/// @nodoc
+mixin _$NotificationLocalSettingsModel {
+ EewSettings get eew => throw _privateConstructorUsedError;
+ EarthquakeSettings get earthquake => throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $NotificationLocalSettingsModelCopyWith
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $NotificationLocalSettingsModelCopyWith<$Res> {
+ factory $NotificationLocalSettingsModelCopyWith(
+ NotificationLocalSettingsModel value,
+ $Res Function(NotificationLocalSettingsModel) then) =
+ _$NotificationLocalSettingsModelCopyWithImpl<$Res,
+ NotificationLocalSettingsModel>;
+ @useResult
+ $Res call({EewSettings eew, EarthquakeSettings earthquake});
+
+ $EewSettingsCopyWith<$Res> get eew;
+ $EarthquakeSettingsCopyWith<$Res> get earthquake;
+}
+
+/// @nodoc
+class _$NotificationLocalSettingsModelCopyWithImpl<$Res,
+ $Val extends NotificationLocalSettingsModel>
+ implements $NotificationLocalSettingsModelCopyWith<$Res> {
+ _$NotificationLocalSettingsModelCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? eew = null,
+ Object? earthquake = null,
+ }) {
+ return _then(_value.copyWith(
+ eew: null == eew
+ ? _value.eew
+ : eew // ignore: cast_nullable_to_non_nullable
+ as EewSettings,
+ earthquake: null == earthquake
+ ? _value.earthquake
+ : earthquake // ignore: cast_nullable_to_non_nullable
+ as EarthquakeSettings,
+ ) as $Val);
+ }
+
+ @override
+ @pragma('vm:prefer-inline')
+ $EewSettingsCopyWith<$Res> get eew {
+ return $EewSettingsCopyWith<$Res>(_value.eew, (value) {
+ return _then(_value.copyWith(eew: value) as $Val);
+ });
+ }
+
+ @override
+ @pragma('vm:prefer-inline')
+ $EarthquakeSettingsCopyWith<$Res> get earthquake {
+ return $EarthquakeSettingsCopyWith<$Res>(_value.earthquake, (value) {
+ return _then(_value.copyWith(earthquake: value) as $Val);
+ });
+ }
+}
+
+/// @nodoc
+abstract class _$$NotificationLocalSettingsModelImplCopyWith<$Res>
+ implements $NotificationLocalSettingsModelCopyWith<$Res> {
+ factory _$$NotificationLocalSettingsModelImplCopyWith(
+ _$NotificationLocalSettingsModelImpl value,
+ $Res Function(_$NotificationLocalSettingsModelImpl) then) =
+ __$$NotificationLocalSettingsModelImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call({EewSettings eew, EarthquakeSettings earthquake});
+
+ @override
+ $EewSettingsCopyWith<$Res> get eew;
+ @override
+ $EarthquakeSettingsCopyWith<$Res> get earthquake;
+}
+
+/// @nodoc
+class __$$NotificationLocalSettingsModelImplCopyWithImpl<$Res>
+ extends _$NotificationLocalSettingsModelCopyWithImpl<$Res,
+ _$NotificationLocalSettingsModelImpl>
+ implements _$$NotificationLocalSettingsModelImplCopyWith<$Res> {
+ __$$NotificationLocalSettingsModelImplCopyWithImpl(
+ _$NotificationLocalSettingsModelImpl _value,
+ $Res Function(_$NotificationLocalSettingsModelImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? eew = null,
+ Object? earthquake = null,
+ }) {
+ return _then(_$NotificationLocalSettingsModelImpl(
+ eew: null == eew
+ ? _value.eew
+ : eew // ignore: cast_nullable_to_non_nullable
+ as EewSettings,
+ earthquake: null == earthquake
+ ? _value.earthquake
+ : earthquake // ignore: cast_nullable_to_non_nullable
+ as EarthquakeSettings,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$NotificationLocalSettingsModelImpl
+ implements _NotificationLocalSettingsModel {
+ const _$NotificationLocalSettingsModelImpl(
+ {this.eew = const EewSettings(),
+ this.earthquake = const EarthquakeSettings()});
+
+ factory _$NotificationLocalSettingsModelImpl.fromJson(
+ Map json) =>
+ _$$NotificationLocalSettingsModelImplFromJson(json);
+
+ @override
+ @JsonKey()
+ final EewSettings eew;
+ @override
+ @JsonKey()
+ final EarthquakeSettings earthquake;
+
+ @override
+ String toString() {
+ return 'NotificationLocalSettingsModel(eew: $eew, earthquake: $earthquake)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$NotificationLocalSettingsModelImpl &&
+ (identical(other.eew, eew) || other.eew == eew) &&
+ (identical(other.earthquake, earthquake) ||
+ other.earthquake == earthquake));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(runtimeType, eew, earthquake);
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$NotificationLocalSettingsModelImplCopyWith<
+ _$NotificationLocalSettingsModelImpl>
+ get copyWith => __$$NotificationLocalSettingsModelImplCopyWithImpl<
+ _$NotificationLocalSettingsModelImpl>(this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$NotificationLocalSettingsModelImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _NotificationLocalSettingsModel
+ implements NotificationLocalSettingsModel {
+ const factory _NotificationLocalSettingsModel(
+ {final EewSettings eew, final EarthquakeSettings earthquake}) =
+ _$NotificationLocalSettingsModelImpl;
+
+ factory _NotificationLocalSettingsModel.fromJson(Map json) =
+ _$NotificationLocalSettingsModelImpl.fromJson;
+
+ @override
+ EewSettings get eew;
+ @override
+ EarthquakeSettings get earthquake;
+ @override
+ @JsonKey(ignore: true)
+ _$$NotificationLocalSettingsModelImplCopyWith<
+ _$NotificationLocalSettingsModelImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+EewSettings _$EewSettingsFromJson(Map json) {
+ return _EewSettings.fromJson(json);
+}
+
+/// @nodoc
+mixin _$EewSettings {
+ JmaForecastIntensity? get emergencyIntensity =>
+ throw _privateConstructorUsedError;
+ JmaForecastIntensity? get silentIntensity =>
+ throw _privateConstructorUsedError;
+ List get regions => throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $EewSettingsCopyWith get copyWith =>
+ throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $EewSettingsCopyWith<$Res> {
+ factory $EewSettingsCopyWith(
+ EewSettings value, $Res Function(EewSettings) then) =
+ _$EewSettingsCopyWithImpl<$Res, EewSettings>;
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? emergencyIntensity,
+ JmaForecastIntensity? silentIntensity,
+ List regions});
+}
+
+/// @nodoc
+class _$EewSettingsCopyWithImpl<$Res, $Val extends EewSettings>
+ implements $EewSettingsCopyWith<$Res> {
+ _$EewSettingsCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? emergencyIntensity = freezed,
+ Object? silentIntensity = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_value.copyWith(
+ emergencyIntensity: freezed == emergencyIntensity
+ ? _value.emergencyIntensity
+ : emergencyIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ silentIntensity: freezed == silentIntensity
+ ? _value.silentIntensity
+ : silentIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value.regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ) as $Val);
+ }
+}
+
+/// @nodoc
+abstract class _$$EewSettingsImplCopyWith<$Res>
+ implements $EewSettingsCopyWith<$Res> {
+ factory _$$EewSettingsImplCopyWith(
+ _$EewSettingsImpl value, $Res Function(_$EewSettingsImpl) then) =
+ __$$EewSettingsImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? emergencyIntensity,
+ JmaForecastIntensity? silentIntensity,
+ List regions});
+}
+
+/// @nodoc
+class __$$EewSettingsImplCopyWithImpl<$Res>
+ extends _$EewSettingsCopyWithImpl<$Res, _$EewSettingsImpl>
+ implements _$$EewSettingsImplCopyWith<$Res> {
+ __$$EewSettingsImplCopyWithImpl(
+ _$EewSettingsImpl _value, $Res Function(_$EewSettingsImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? emergencyIntensity = freezed,
+ Object? silentIntensity = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_$EewSettingsImpl(
+ emergencyIntensity: freezed == emergencyIntensity
+ ? _value.emergencyIntensity
+ : emergencyIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ silentIntensity: freezed == silentIntensity
+ ? _value.silentIntensity
+ : silentIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value._regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$EewSettingsImpl implements _EewSettings {
+ const _$EewSettingsImpl(
+ {this.emergencyIntensity = null,
+ this.silentIntensity = null,
+ final List regions = const []})
+ : _regions = regions;
+
+ factory _$EewSettingsImpl.fromJson(Map json) =>
+ _$$EewSettingsImplFromJson(json);
+
+ @override
+ @JsonKey()
+ final JmaForecastIntensity? emergencyIntensity;
+ @override
+ @JsonKey()
+ final JmaForecastIntensity? silentIntensity;
+ final List _regions;
+ @override
+ @JsonKey()
+ List get regions {
+ if (_regions is EqualUnmodifiableListView) return _regions;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_regions);
+ }
+
+ @override
+ String toString() {
+ return 'EewSettings(emergencyIntensity: $emergencyIntensity, silentIntensity: $silentIntensity, regions: $regions)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$EewSettingsImpl &&
+ (identical(other.emergencyIntensity, emergencyIntensity) ||
+ other.emergencyIntensity == emergencyIntensity) &&
+ (identical(other.silentIntensity, silentIntensity) ||
+ other.silentIntensity == silentIntensity) &&
+ const DeepCollectionEquality().equals(other._regions, _regions));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(runtimeType, emergencyIntensity,
+ silentIntensity, const DeepCollectionEquality().hash(_regions));
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$EewSettingsImplCopyWith<_$EewSettingsImpl> get copyWith =>
+ __$$EewSettingsImplCopyWithImpl<_$EewSettingsImpl>(this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$EewSettingsImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _EewSettings implements EewSettings {
+ const factory _EewSettings(
+ {final JmaForecastIntensity? emergencyIntensity,
+ final JmaForecastIntensity? silentIntensity,
+ final List regions}) = _$EewSettingsImpl;
+
+ factory _EewSettings.fromJson(Map json) =
+ _$EewSettingsImpl.fromJson;
+
+ @override
+ JmaForecastIntensity? get emergencyIntensity;
+ @override
+ JmaForecastIntensity? get silentIntensity;
+ @override
+ List get regions;
+ @override
+ @JsonKey(ignore: true)
+ _$$EewSettingsImplCopyWith<_$EewSettingsImpl> get copyWith =>
+ throw _privateConstructorUsedError;
+}
+
+EarthquakeSettings _$EarthquakeSettingsFromJson(Map json) {
+ return _EarthquakeSettings.fromJson(json);
+}
+
+/// @nodoc
+mixin _$EarthquakeSettings {
+ JmaForecastIntensity? get emergencyIntensity =>
+ throw _privateConstructorUsedError;
+ JmaForecastIntensity? get silentIntensity =>
+ throw _privateConstructorUsedError;
+ List get regions => throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $EarthquakeSettingsCopyWith get copyWith =>
+ throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $EarthquakeSettingsCopyWith<$Res> {
+ factory $EarthquakeSettingsCopyWith(
+ EarthquakeSettings value, $Res Function(EarthquakeSettings) then) =
+ _$EarthquakeSettingsCopyWithImpl<$Res, EarthquakeSettings>;
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? emergencyIntensity,
+ JmaForecastIntensity? silentIntensity,
+ List regions});
+}
+
+/// @nodoc
+class _$EarthquakeSettingsCopyWithImpl<$Res, $Val extends EarthquakeSettings>
+ implements $EarthquakeSettingsCopyWith<$Res> {
+ _$EarthquakeSettingsCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? emergencyIntensity = freezed,
+ Object? silentIntensity = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_value.copyWith(
+ emergencyIntensity: freezed == emergencyIntensity
+ ? _value.emergencyIntensity
+ : emergencyIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ silentIntensity: freezed == silentIntensity
+ ? _value.silentIntensity
+ : silentIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value.regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ) as $Val);
+ }
+}
+
+/// @nodoc
+abstract class _$$EarthquakeSettingsImplCopyWith<$Res>
+ implements $EarthquakeSettingsCopyWith<$Res> {
+ factory _$$EarthquakeSettingsImplCopyWith(_$EarthquakeSettingsImpl value,
+ $Res Function(_$EarthquakeSettingsImpl) then) =
+ __$$EarthquakeSettingsImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? emergencyIntensity,
+ JmaForecastIntensity? silentIntensity,
+ List regions});
+}
+
+/// @nodoc
+class __$$EarthquakeSettingsImplCopyWithImpl<$Res>
+ extends _$EarthquakeSettingsCopyWithImpl<$Res, _$EarthquakeSettingsImpl>
+ implements _$$EarthquakeSettingsImplCopyWith<$Res> {
+ __$$EarthquakeSettingsImplCopyWithImpl(_$EarthquakeSettingsImpl _value,
+ $Res Function(_$EarthquakeSettingsImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? emergencyIntensity = freezed,
+ Object? silentIntensity = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_$EarthquakeSettingsImpl(
+ emergencyIntensity: freezed == emergencyIntensity
+ ? _value.emergencyIntensity
+ : emergencyIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ silentIntensity: freezed == silentIntensity
+ ? _value.silentIntensity
+ : silentIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value._regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$EarthquakeSettingsImpl implements _EarthquakeSettings {
+ const _$EarthquakeSettingsImpl(
+ {this.emergencyIntensity = null,
+ this.silentIntensity = null,
+ final List regions = const []})
+ : _regions = regions;
+
+ factory _$EarthquakeSettingsImpl.fromJson(Map json) =>
+ _$$EarthquakeSettingsImplFromJson(json);
+
+ @override
+ @JsonKey()
+ final JmaForecastIntensity? emergencyIntensity;
+ @override
+ @JsonKey()
+ final JmaForecastIntensity? silentIntensity;
+ final List _regions;
+ @override
+ @JsonKey()
+ List get regions {
+ if (_regions is EqualUnmodifiableListView) return _regions;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_regions);
+ }
+
+ @override
+ String toString() {
+ return 'EarthquakeSettings(emergencyIntensity: $emergencyIntensity, silentIntensity: $silentIntensity, regions: $regions)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$EarthquakeSettingsImpl &&
+ (identical(other.emergencyIntensity, emergencyIntensity) ||
+ other.emergencyIntensity == emergencyIntensity) &&
+ (identical(other.silentIntensity, silentIntensity) ||
+ other.silentIntensity == silentIntensity) &&
+ const DeepCollectionEquality().equals(other._regions, _regions));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(runtimeType, emergencyIntensity,
+ silentIntensity, const DeepCollectionEquality().hash(_regions));
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$EarthquakeSettingsImplCopyWith<_$EarthquakeSettingsImpl> get copyWith =>
+ __$$EarthquakeSettingsImplCopyWithImpl<_$EarthquakeSettingsImpl>(
+ this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$EarthquakeSettingsImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _EarthquakeSettings implements EarthquakeSettings {
+ const factory _EarthquakeSettings(
+ {final JmaForecastIntensity? emergencyIntensity,
+ final JmaForecastIntensity? silentIntensity,
+ final List regions}) = _$EarthquakeSettingsImpl;
+
+ factory _EarthquakeSettings.fromJson(Map json) =
+ _$EarthquakeSettingsImpl.fromJson;
+
+ @override
+ JmaForecastIntensity? get emergencyIntensity;
+ @override
+ JmaForecastIntensity? get silentIntensity;
+ @override
+ List get regions;
+ @override
+ @JsonKey(ignore: true)
+ _$$EarthquakeSettingsImplCopyWith<_$EarthquakeSettingsImpl> get copyWith =>
+ throw _privateConstructorUsedError;
+}
+
+Region _$RegionFromJson(Map json) {
+ return _Region.fromJson(json);
+}
+
+/// @nodoc
+mixin _$Region {
+ String get code => throw _privateConstructorUsedError;
+ String get name => throw _privateConstructorUsedError;
+ JmaForecastIntensity get emergencyIntensity =>
+ throw _privateConstructorUsedError;
+ JmaForecastIntensity get silentIntensity =>
+ throw _privateConstructorUsedError;
+ bool get isMain => throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $RegionCopyWith get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $RegionCopyWith<$Res> {
+ factory $RegionCopyWith(Region value, $Res Function(Region) then) =
+ _$RegionCopyWithImpl<$Res, Region>;
+ @useResult
+ $Res call(
+ {String code,
+ String name,
+ JmaForecastIntensity emergencyIntensity,
+ JmaForecastIntensity silentIntensity,
+ bool isMain});
+}
+
+/// @nodoc
+class _$RegionCopyWithImpl<$Res, $Val extends Region>
+ implements $RegionCopyWith<$Res> {
+ _$RegionCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? code = null,
+ Object? name = null,
+ Object? emergencyIntensity = null,
+ Object? silentIntensity = null,
+ Object? isMain = null,
+ }) {
+ return _then(_value.copyWith(
+ code: null == code
+ ? _value.code
+ : code // ignore: cast_nullable_to_non_nullable
+ as String,
+ name: null == name
+ ? _value.name
+ : name // ignore: cast_nullable_to_non_nullable
+ as String,
+ emergencyIntensity: null == emergencyIntensity
+ ? _value.emergencyIntensity
+ : emergencyIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ silentIntensity: null == silentIntensity
+ ? _value.silentIntensity
+ : silentIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ isMain: null == isMain
+ ? _value.isMain
+ : isMain // ignore: cast_nullable_to_non_nullable
+ as bool,
+ ) as $Val);
+ }
+}
+
+/// @nodoc
+abstract class _$$RegionImplCopyWith<$Res> implements $RegionCopyWith<$Res> {
+ factory _$$RegionImplCopyWith(
+ _$RegionImpl value, $Res Function(_$RegionImpl) then) =
+ __$$RegionImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call(
+ {String code,
+ String name,
+ JmaForecastIntensity emergencyIntensity,
+ JmaForecastIntensity silentIntensity,
+ bool isMain});
+}
+
+/// @nodoc
+class __$$RegionImplCopyWithImpl<$Res>
+ extends _$RegionCopyWithImpl<$Res, _$RegionImpl>
+ implements _$$RegionImplCopyWith<$Res> {
+ __$$RegionImplCopyWithImpl(
+ _$RegionImpl _value, $Res Function(_$RegionImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? code = null,
+ Object? name = null,
+ Object? emergencyIntensity = null,
+ Object? silentIntensity = null,
+ Object? isMain = null,
+ }) {
+ return _then(_$RegionImpl(
+ code: null == code
+ ? _value.code
+ : code // ignore: cast_nullable_to_non_nullable
+ as String,
+ name: null == name
+ ? _value.name
+ : name // ignore: cast_nullable_to_non_nullable
+ as String,
+ emergencyIntensity: null == emergencyIntensity
+ ? _value.emergencyIntensity
+ : emergencyIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ silentIntensity: null == silentIntensity
+ ? _value.silentIntensity
+ : silentIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ isMain: null == isMain
+ ? _value.isMain
+ : isMain // ignore: cast_nullable_to_non_nullable
+ as bool,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$RegionImpl implements _Region {
+ const _$RegionImpl(
+ {required this.code,
+ required this.name,
+ required this.emergencyIntensity,
+ required this.silentIntensity,
+ required this.isMain});
+
+ factory _$RegionImpl.fromJson(Map json) =>
+ _$$RegionImplFromJson(json);
+
+ @override
+ final String code;
+ @override
+ final String name;
+ @override
+ final JmaForecastIntensity emergencyIntensity;
+ @override
+ final JmaForecastIntensity silentIntensity;
+ @override
+ final bool isMain;
+
+ @override
+ String toString() {
+ return 'Region(code: $code, name: $name, emergencyIntensity: $emergencyIntensity, silentIntensity: $silentIntensity, isMain: $isMain)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$RegionImpl &&
+ (identical(other.code, code) || other.code == code) &&
+ (identical(other.name, name) || other.name == name) &&
+ (identical(other.emergencyIntensity, emergencyIntensity) ||
+ other.emergencyIntensity == emergencyIntensity) &&
+ (identical(other.silentIntensity, silentIntensity) ||
+ other.silentIntensity == silentIntensity) &&
+ (identical(other.isMain, isMain) || other.isMain == isMain));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(
+ runtimeType, code, name, emergencyIntensity, silentIntensity, isMain);
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$RegionImplCopyWith<_$RegionImpl> get copyWith =>
+ __$$RegionImplCopyWithImpl<_$RegionImpl>(this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$RegionImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _Region implements Region {
+ const factory _Region(
+ {required final String code,
+ required final String name,
+ required final JmaForecastIntensity emergencyIntensity,
+ required final JmaForecastIntensity silentIntensity,
+ required final bool isMain}) = _$RegionImpl;
+
+ factory _Region.fromJson(Map json) = _$RegionImpl.fromJson;
+
+ @override
+ String get code;
+ @override
+ String get name;
+ @override
+ JmaForecastIntensity get emergencyIntensity;
+ @override
+ JmaForecastIntensity get silentIntensity;
+ @override
+ bool get isMain;
+ @override
+ @JsonKey(ignore: true)
+ _$$RegionImplCopyWith<_$RegionImpl> get copyWith =>
+ throw _privateConstructorUsedError;
+}
diff --git a/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.g.dart b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.g.dart
new file mode 100644
index 000000000..d87ffc88b
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_model.g.dart
@@ -0,0 +1,156 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// ignore_for_file: type=lint, duplicate_ignore
+
+part of 'notification_local_settings_model.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+_$NotificationLocalSettingsModelImpl
+ _$$NotificationLocalSettingsModelImplFromJson(Map json) =>
+ $checkedCreate(
+ r'_$NotificationLocalSettingsModelImpl',
+ json,
+ ($checkedConvert) {
+ final val = _$NotificationLocalSettingsModelImpl(
+ eew: $checkedConvert(
+ 'eew',
+ (v) => v == null
+ ? const EewSettings()
+ : EewSettings.fromJson(v as Map)),
+ earthquake: $checkedConvert(
+ 'earthquake',
+ (v) => v == null
+ ? const EarthquakeSettings()
+ : EarthquakeSettings.fromJson(v as Map)),
+ );
+ return val;
+ },
+ );
+
+Map _$$NotificationLocalSettingsModelImplToJson(
+ _$NotificationLocalSettingsModelImpl instance) =>
+ {
+ 'eew': instance.eew,
+ 'earthquake': instance.earthquake,
+ };
+
+_$EewSettingsImpl _$$EewSettingsImplFromJson(Map json) =>
+ $checkedCreate(
+ r'_$EewSettingsImpl',
+ json,
+ ($checkedConvert) {
+ final val = _$EewSettingsImpl(
+ emergencyIntensity: $checkedConvert(
+ 'emergencyIntensity',
+ (v) =>
+ $enumDecodeNullable(_$JmaForecastIntensityEnumMap, v) ??
+ null),
+ silentIntensity: $checkedConvert(
+ 'silentIntensity',
+ (v) =>
+ $enumDecodeNullable(_$JmaForecastIntensityEnumMap, v) ??
+ null),
+ regions: $checkedConvert(
+ 'regions',
+ (v) =>
+ (v as List?)
+ ?.map((e) => Region.fromJson(e as Map))
+ .toList() ??
+ const []),
+ );
+ return val;
+ },
+ );
+
+Map _$$EewSettingsImplToJson(_$EewSettingsImpl instance) =>
+ {
+ 'emergencyIntensity':
+ _$JmaForecastIntensityEnumMap[instance.emergencyIntensity],
+ 'silentIntensity':
+ _$JmaForecastIntensityEnumMap[instance.silentIntensity],
+ 'regions': instance.regions,
+ };
+
+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: '不明',
+};
+
+_$EarthquakeSettingsImpl _$$EarthquakeSettingsImplFromJson(
+ Map json) =>
+ $checkedCreate(
+ r'_$EarthquakeSettingsImpl',
+ json,
+ ($checkedConvert) {
+ final val = _$EarthquakeSettingsImpl(
+ emergencyIntensity: $checkedConvert(
+ 'emergencyIntensity',
+ (v) =>
+ $enumDecodeNullable(_$JmaForecastIntensityEnumMap, v) ??
+ null),
+ silentIntensity: $checkedConvert(
+ 'silentIntensity',
+ (v) =>
+ $enumDecodeNullable(_$JmaForecastIntensityEnumMap, v) ??
+ null),
+ regions: $checkedConvert(
+ 'regions',
+ (v) =>
+ (v as List?)
+ ?.map((e) => Region.fromJson(e as Map))
+ .toList() ??
+ const []),
+ );
+ return val;
+ },
+ );
+
+Map _$$EarthquakeSettingsImplToJson(
+ _$EarthquakeSettingsImpl instance) =>
+ {
+ 'emergencyIntensity':
+ _$JmaForecastIntensityEnumMap[instance.emergencyIntensity],
+ 'silentIntensity':
+ _$JmaForecastIntensityEnumMap[instance.silentIntensity],
+ 'regions': instance.regions,
+ };
+
+_$RegionImpl _$$RegionImplFromJson(Map json) => $checkedCreate(
+ r'_$RegionImpl',
+ json,
+ ($checkedConvert) {
+ final val = _$RegionImpl(
+ code: $checkedConvert('code', (v) => v as String),
+ name: $checkedConvert('name', (v) => v as String),
+ emergencyIntensity: $checkedConvert('emergencyIntensity',
+ (v) => $enumDecode(_$JmaForecastIntensityEnumMap, v)),
+ silentIntensity: $checkedConvert('silentIntensity',
+ (v) => $enumDecode(_$JmaForecastIntensityEnumMap, v)),
+ isMain: $checkedConvert('isMain', (v) => v as bool),
+ );
+ return val;
+ },
+ );
+
+Map _$$RegionImplToJson(_$RegionImpl instance) =>
+ {
+ 'code': instance.code,
+ 'name': instance.name,
+ 'emergencyIntensity':
+ _$JmaForecastIntensityEnumMap[instance.emergencyIntensity]!,
+ 'silentIntensity':
+ _$JmaForecastIntensityEnumMap[instance.silentIntensity]!,
+ 'isMain': instance.isMain,
+ };
diff --git a/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_notifier.dart b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_notifier.dart
new file mode 100644
index 000000000..48009a431
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_notifier.dart
@@ -0,0 +1,144 @@
+import 'dart:convert';
+
+import 'package:eqapi_types/eqapi_types.dart';
+import 'package:eqmonitor/feature/settings/features/notification_local_settings/data/notification_local_settings_model.dart';
+import 'package:notification_setting_types/notification_payload.pbenum.dart'
+ as pb_enum;
+import 'package:notification_setting_types/notification_settings.pb.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared_preference_app_group/shared_preference_app_group.dart';
+
+part 'notification_local_settings_notifier.g.dart';
+
+@Riverpod(keepAlive: true)
+class NotificationLocalSettingsNotifier
+ extends _$NotificationLocalSettingsNotifier {
+ @override
+ Future build() async {
+ final value =
+ await SharedPreferenceAppGroup.getString('notification_settings');
+ if (value == null) {
+ return const NotificationLocalSettingsModel();
+ }
+ // base64でdecode
+ final buffer = base64Decode(value);
+ final savedState = NotificationSettings.fromBuffer(buffer);
+ return NotificationLocalSettingsModel(
+ earthquake: EarthquakeSettings(
+ emergencyIntensity:
+ savedState.earthquakeSettings.emergencyIntensity.jmaIntensity,
+ silentIntensity:
+ savedState.earthquakeSettings.silentIntensity.jmaIntensity,
+ regions: savedState.earthquakeSettings.regions
+ .map(
+ (e) => Region(
+ code: e.code,
+ name: e.name,
+ emergencyIntensity: e.emergencyIntensity.jmaIntensity,
+ silentIntensity: e.silentIntensity.jmaIntensity,
+ isMain: e.isMain,
+ ),
+ )
+ .toList(),
+ ),
+ eew: EewSettings(
+ emergencyIntensity:
+ savedState.eewSettings.emergencyIntensity.jmaIntensity,
+ silentIntensity: savedState.eewSettings.silentIntensity.jmaIntensity,
+ regions: savedState.eewSettings.regions
+ .map(
+ (e) => Region(
+ code: e.code,
+ name: e.name,
+ emergencyIntensity: e.emergencyIntensity.jmaIntensity,
+ silentIntensity: e.silentIntensity.jmaIntensity,
+ isMain: e.isMain,
+ ),
+ )
+ .toList(),
+ ),
+ );
+ }
+
+ Future save(NotificationLocalSettingsModel state) async {
+ final pb = NotificationSettings(
+ earthquakeSettings: NotificationSettings_EarthquakeSettings(
+ emergencyIntensity: state.earthquake.emergencyIntensity?.toPb,
+ silentIntensity: state.earthquake.silentIntensity?.toPb,
+ regions: state.earthquake.regions
+ .map(
+ (e) => NotificationSettings_EarthquakeSettings_Region(
+ code: e.code,
+ name: e.name,
+ emergencyIntensity: e.emergencyIntensity.toPb,
+ silentIntensity: e.silentIntensity.toPb,
+ isMain: e.isMain,
+ ),
+ )
+ .toList(),
+ ),
+ eewSettings: NotificationSettings_EewSettings(
+ emergencyIntensity: state.eew.emergencyIntensity?.toPb,
+ silentIntensity: state.eew.silentIntensity?.toPb,
+ regions: state.eew.regions
+ .map(
+ (e) => NotificationSettings_EewSettings_Region(
+ code: e.code,
+ name: e.name,
+ emergencyIntensity: e.emergencyIntensity.toPb,
+ silentIntensity: e.silentIntensity.toPb,
+ isMain: e.isMain,
+ ),
+ )
+ .toList(),
+ ),
+ );
+ final buffer = pb.writeToBuffer();
+ // base64でencode
+ final value = base64Encode(buffer);
+ await SharedPreferenceAppGroup.setString('notification_settings', value);
+ }
+}
+
+extension PbEnumEx on pb_enum.JmaIntensity {
+ JmaForecastIntensity get jmaIntensity => switch (this) {
+ pb_enum.JmaIntensity.JMA_INTENSITY_0 => JmaForecastIntensity.zero,
+ pb_enum.JmaIntensity.JMA_INTENSITY_1 => JmaForecastIntensity.one,
+ pb_enum.JmaIntensity.JMA_INTENSITY_2 => JmaForecastIntensity.two,
+ pb_enum.JmaIntensity.JMA_INTENSITY_3 => JmaForecastIntensity.three,
+ pb_enum.JmaIntensity.JMA_INTENSITY_4 => JmaForecastIntensity.four,
+ pb_enum.JmaIntensity.JMA_INTENSITY_5_MINUS =>
+ JmaForecastIntensity.fiveLower,
+ pb_enum.JmaIntensity.JMA_INTENSITY_5_PLUS =>
+ JmaForecastIntensity.fiveUpper,
+ pb_enum.JmaIntensity.JMA_INTENSITY_6_MINUS =>
+ JmaForecastIntensity.sixLower,
+ pb_enum.JmaIntensity.JMA_INTENSITY_6_PLUS =>
+ JmaForecastIntensity.sixUpper,
+ pb_enum.JmaIntensity.JMA_INTENSITY_7 => JmaForecastIntensity.seven,
+ pb_enum.JmaIntensity.JMA_INTENSITY_UNSPECIFIED =>
+ JmaForecastIntensity.unknown,
+ pb_enum.JmaIntensity() => throw UnimplementedError(),
+ };
+}
+
+extension JmaIntensity on JmaForecastIntensity {
+ pb_enum.JmaIntensity get toPb => switch (this) {
+ JmaForecastIntensity.zero => pb_enum.JmaIntensity.JMA_INTENSITY_0,
+ JmaForecastIntensity.one => pb_enum.JmaIntensity.JMA_INTENSITY_1,
+ JmaForecastIntensity.two => pb_enum.JmaIntensity.JMA_INTENSITY_2,
+ JmaForecastIntensity.three => pb_enum.JmaIntensity.JMA_INTENSITY_3,
+ JmaForecastIntensity.four => pb_enum.JmaIntensity.JMA_INTENSITY_4,
+ JmaForecastIntensity.fiveLower =>
+ pb_enum.JmaIntensity.JMA_INTENSITY_5_MINUS,
+ JmaForecastIntensity.fiveUpper =>
+ pb_enum.JmaIntensity.JMA_INTENSITY_5_PLUS,
+ JmaForecastIntensity.sixLower =>
+ pb_enum.JmaIntensity.JMA_INTENSITY_6_MINUS,
+ JmaForecastIntensity.sixUpper =>
+ pb_enum.JmaIntensity.JMA_INTENSITY_6_PLUS,
+ JmaForecastIntensity.seven => pb_enum.JmaIntensity.JMA_INTENSITY_7,
+ JmaForecastIntensity.unknown =>
+ pb_enum.JmaIntensity.JMA_INTENSITY_UNSPECIFIED,
+ };
+}
diff --git a/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_notifier.g.dart b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_notifier.g.dart
new file mode 100644
index 000000000..f5c7b1daf
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_local_settings/data/notification_local_settings_notifier.g.dart
@@ -0,0 +1,30 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// ignore_for_file: type=lint, duplicate_ignore
+
+part of 'notification_local_settings_notifier.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$notificationLocalSettingsNotifierHash() =>
+ r'7a81c66a60719bd428a39ec75b436274673bbf6c';
+
+/// See also [NotificationLocalSettingsNotifier].
+@ProviderFor(NotificationLocalSettingsNotifier)
+final notificationLocalSettingsNotifierProvider = AsyncNotifierProvider<
+ NotificationLocalSettingsNotifier, NotificationLocalSettingsModel>.internal(
+ NotificationLocalSettingsNotifier.new,
+ name: r'notificationLocalSettingsNotifierProvider',
+ debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$notificationLocalSettingsNotifierHash,
+ dependencies: null,
+ allTransitiveDependencies: null,
+);
+
+typedef _$NotificationLocalSettingsNotifier
+ = AsyncNotifier;
+// 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/settings/features/notification_local_settings/ui/notification_local_settings_page.dart b/app/lib/feature/settings/features/notification_local_settings/ui/notification_local_settings_page.dart
new file mode 100644
index 000000000..9d6e0f01e
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_local_settings/ui/notification_local_settings_page.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+
+class NotificationLocalSettingsPage extends StatelessWidget {
+ const NotificationLocalSettingsPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text('通知音・表示設定'),
+ ),
+ body: const _Body(),
+ );
+ }
+}
+
+class _Body extends ConsumerWidget {
+ const _Body();
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ return Container();
+ }
+}
diff --git a/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.dart b/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.dart
new file mode 100644
index 000000000..4515317e5
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.dart
@@ -0,0 +1,75 @@
+import 'package:eqapi_types/eqapi_types.dart';
+import 'package:eqapi_types/lib.dart';
+import 'package:eqapi_types/model/components/core/core.dart';
+import 'package:freezed_annotation/freezed_annotation.dart';
+
+part 'notification_remote_settings_state.freezed.dart';
+part 'notification_remote_settings_state.g.dart';
+
+@freezed
+class NotificationRemoteSettingsState with _$NotificationRemoteSettingsState {
+ const factory NotificationRemoteSettingsState({
+ required NotificationRemoteSettingsEew eew,
+ required NotificationRemoteSettingsEarthquake earthquake,
+ }) = _NotificationRemoteSettingsState;
+
+ factory NotificationRemoteSettingsState.fromJson(Map json) =>
+ _$NotificationRemoteSettingsStateFromJson(json);
+}
+
+@freezed
+class NotificationRemoteSettingsEew with _$NotificationRemoteSettingsEew {
+ const factory NotificationRemoteSettingsEew({
+ required JmaForecastIntensity? global,
+ required List regions,
+ }) = _NotificationRemoteSettingsEew;
+
+ factory NotificationRemoteSettingsEew.fromJson(
+ Map json,
+ ) =>
+ _$NotificationRemoteSettingsEewFromJson(json);
+}
+
+@freezed
+class NotificationRemoteSettingsEewRegion
+ with _$NotificationRemoteSettingsEewRegion {
+ const factory NotificationRemoteSettingsEewRegion({
+ required int regionId,
+ required JmaForecastIntensity minJmaIntensity,
+ required String name,
+ }) = _NotificationRemoteSettingsEewRegion;
+
+ factory NotificationRemoteSettingsEewRegion.fromJson(
+ Map json,
+ ) =>
+ _$NotificationRemoteSettingsEewRegionFromJson(json);
+}
+
+@freezed
+class NotificationRemoteSettingsEarthquake
+ with _$NotificationRemoteSettingsEarthquake {
+ const factory NotificationRemoteSettingsEarthquake({
+ required JmaForecastIntensity? global,
+ required List regions,
+ }) = _NotificationRemoteSettingsEarthquake;
+
+ factory NotificationRemoteSettingsEarthquake.fromJson(
+ Map json,
+ ) =>
+ _$NotificationRemoteSettingsEarthquakeFromJson(json);
+}
+
+@freezed
+class NotificationRemoteSettingsEarthquakeRegion
+ with _$NotificationRemoteSettingsEarthquakeRegion {
+ const factory NotificationRemoteSettingsEarthquakeRegion({
+ required int regionId,
+ required JmaForecastIntensity minJmaIntensity,
+ required String name,
+ }) = _NotificationRemoteSettingsEarthquakeRegion;
+
+ factory NotificationRemoteSettingsEarthquakeRegion.fromJson(
+ Map json,
+ ) =>
+ _$NotificationRemoteSettingsEarthquakeRegionFromJson(json);
+}
diff --git a/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.freezed.dart b/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.freezed.dart
new file mode 100644
index 000000000..9e580bb9c
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.freezed.dart
@@ -0,0 +1,971 @@
+// coverage:ignore-file
+// GENERATED CODE - DO NOT MODIFY BY HAND
+// ignore_for_file: type=lint
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
+
+part of 'notification_remote_settings_state.dart';
+
+// **************************************************************************
+// FreezedGenerator
+// **************************************************************************
+
+T _$identity(T value) => value;
+
+final _privateConstructorUsedError = UnsupportedError(
+ 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
+
+NotificationRemoteSettingsState _$NotificationRemoteSettingsStateFromJson(
+ Map json) {
+ return _NotificationRemoteSettingsState.fromJson(json);
+}
+
+/// @nodoc
+mixin _$NotificationRemoteSettingsState {
+ NotificationRemoteSettingsEew get eew => throw _privateConstructorUsedError;
+ NotificationRemoteSettingsEarthquake get earthquake =>
+ throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $NotificationRemoteSettingsStateCopyWith
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $NotificationRemoteSettingsStateCopyWith<$Res> {
+ factory $NotificationRemoteSettingsStateCopyWith(
+ NotificationRemoteSettingsState value,
+ $Res Function(NotificationRemoteSettingsState) then) =
+ _$NotificationRemoteSettingsStateCopyWithImpl<$Res,
+ NotificationRemoteSettingsState>;
+ @useResult
+ $Res call(
+ {NotificationRemoteSettingsEew eew,
+ NotificationRemoteSettingsEarthquake earthquake});
+
+ $NotificationRemoteSettingsEewCopyWith<$Res> get eew;
+ $NotificationRemoteSettingsEarthquakeCopyWith<$Res> get earthquake;
+}
+
+/// @nodoc
+class _$NotificationRemoteSettingsStateCopyWithImpl<$Res,
+ $Val extends NotificationRemoteSettingsState>
+ implements $NotificationRemoteSettingsStateCopyWith<$Res> {
+ _$NotificationRemoteSettingsStateCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? eew = null,
+ Object? earthquake = null,
+ }) {
+ return _then(_value.copyWith(
+ eew: null == eew
+ ? _value.eew
+ : eew // ignore: cast_nullable_to_non_nullable
+ as NotificationRemoteSettingsEew,
+ earthquake: null == earthquake
+ ? _value.earthquake
+ : earthquake // ignore: cast_nullable_to_non_nullable
+ as NotificationRemoteSettingsEarthquake,
+ ) as $Val);
+ }
+
+ @override
+ @pragma('vm:prefer-inline')
+ $NotificationRemoteSettingsEewCopyWith<$Res> get eew {
+ return $NotificationRemoteSettingsEewCopyWith<$Res>(_value.eew, (value) {
+ return _then(_value.copyWith(eew: value) as $Val);
+ });
+ }
+
+ @override
+ @pragma('vm:prefer-inline')
+ $NotificationRemoteSettingsEarthquakeCopyWith<$Res> get earthquake {
+ return $NotificationRemoteSettingsEarthquakeCopyWith<$Res>(
+ _value.earthquake, (value) {
+ return _then(_value.copyWith(earthquake: value) as $Val);
+ });
+ }
+}
+
+/// @nodoc
+abstract class _$$NotificationRemoteSettingsStateImplCopyWith<$Res>
+ implements $NotificationRemoteSettingsStateCopyWith<$Res> {
+ factory _$$NotificationRemoteSettingsStateImplCopyWith(
+ _$NotificationRemoteSettingsStateImpl value,
+ $Res Function(_$NotificationRemoteSettingsStateImpl) then) =
+ __$$NotificationRemoteSettingsStateImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call(
+ {NotificationRemoteSettingsEew eew,
+ NotificationRemoteSettingsEarthquake earthquake});
+
+ @override
+ $NotificationRemoteSettingsEewCopyWith<$Res> get eew;
+ @override
+ $NotificationRemoteSettingsEarthquakeCopyWith<$Res> get earthquake;
+}
+
+/// @nodoc
+class __$$NotificationRemoteSettingsStateImplCopyWithImpl<$Res>
+ extends _$NotificationRemoteSettingsStateCopyWithImpl<$Res,
+ _$NotificationRemoteSettingsStateImpl>
+ implements _$$NotificationRemoteSettingsStateImplCopyWith<$Res> {
+ __$$NotificationRemoteSettingsStateImplCopyWithImpl(
+ _$NotificationRemoteSettingsStateImpl _value,
+ $Res Function(_$NotificationRemoteSettingsStateImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? eew = null,
+ Object? earthquake = null,
+ }) {
+ return _then(_$NotificationRemoteSettingsStateImpl(
+ eew: null == eew
+ ? _value.eew
+ : eew // ignore: cast_nullable_to_non_nullable
+ as NotificationRemoteSettingsEew,
+ earthquake: null == earthquake
+ ? _value.earthquake
+ : earthquake // ignore: cast_nullable_to_non_nullable
+ as NotificationRemoteSettingsEarthquake,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$NotificationRemoteSettingsStateImpl
+ implements _NotificationRemoteSettingsState {
+ const _$NotificationRemoteSettingsStateImpl(
+ {required this.eew, required this.earthquake});
+
+ factory _$NotificationRemoteSettingsStateImpl.fromJson(
+ Map json) =>
+ _$$NotificationRemoteSettingsStateImplFromJson(json);
+
+ @override
+ final NotificationRemoteSettingsEew eew;
+ @override
+ final NotificationRemoteSettingsEarthquake earthquake;
+
+ @override
+ String toString() {
+ return 'NotificationRemoteSettingsState(eew: $eew, earthquake: $earthquake)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$NotificationRemoteSettingsStateImpl &&
+ (identical(other.eew, eew) || other.eew == eew) &&
+ (identical(other.earthquake, earthquake) ||
+ other.earthquake == earthquake));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(runtimeType, eew, earthquake);
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$NotificationRemoteSettingsStateImplCopyWith<
+ _$NotificationRemoteSettingsStateImpl>
+ get copyWith => __$$NotificationRemoteSettingsStateImplCopyWithImpl<
+ _$NotificationRemoteSettingsStateImpl>(this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$NotificationRemoteSettingsStateImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _NotificationRemoteSettingsState
+ implements NotificationRemoteSettingsState {
+ const factory _NotificationRemoteSettingsState(
+ {required final NotificationRemoteSettingsEew eew,
+ required final NotificationRemoteSettingsEarthquake earthquake}) =
+ _$NotificationRemoteSettingsStateImpl;
+
+ factory _NotificationRemoteSettingsState.fromJson(Map json) =
+ _$NotificationRemoteSettingsStateImpl.fromJson;
+
+ @override
+ NotificationRemoteSettingsEew get eew;
+ @override
+ NotificationRemoteSettingsEarthquake get earthquake;
+ @override
+ @JsonKey(ignore: true)
+ _$$NotificationRemoteSettingsStateImplCopyWith<
+ _$NotificationRemoteSettingsStateImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+NotificationRemoteSettingsEew _$NotificationRemoteSettingsEewFromJson(
+ Map json) {
+ return _NotificationRemoteSettingsEew.fromJson(json);
+}
+
+/// @nodoc
+mixin _$NotificationRemoteSettingsEew {
+ JmaForecastIntensity? get global => throw _privateConstructorUsedError;
+ List get regions =>
+ throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $NotificationRemoteSettingsEewCopyWith
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $NotificationRemoteSettingsEewCopyWith<$Res> {
+ factory $NotificationRemoteSettingsEewCopyWith(
+ NotificationRemoteSettingsEew value,
+ $Res Function(NotificationRemoteSettingsEew) then) =
+ _$NotificationRemoteSettingsEewCopyWithImpl<$Res,
+ NotificationRemoteSettingsEew>;
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? global,
+ List regions});
+}
+
+/// @nodoc
+class _$NotificationRemoteSettingsEewCopyWithImpl<$Res,
+ $Val extends NotificationRemoteSettingsEew>
+ implements $NotificationRemoteSettingsEewCopyWith<$Res> {
+ _$NotificationRemoteSettingsEewCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? global = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_value.copyWith(
+ global: freezed == global
+ ? _value.global
+ : global // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value.regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ) as $Val);
+ }
+}
+
+/// @nodoc
+abstract class _$$NotificationRemoteSettingsEewImplCopyWith<$Res>
+ implements $NotificationRemoteSettingsEewCopyWith<$Res> {
+ factory _$$NotificationRemoteSettingsEewImplCopyWith(
+ _$NotificationRemoteSettingsEewImpl value,
+ $Res Function(_$NotificationRemoteSettingsEewImpl) then) =
+ __$$NotificationRemoteSettingsEewImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? global,
+ List regions});
+}
+
+/// @nodoc
+class __$$NotificationRemoteSettingsEewImplCopyWithImpl<$Res>
+ extends _$NotificationRemoteSettingsEewCopyWithImpl<$Res,
+ _$NotificationRemoteSettingsEewImpl>
+ implements _$$NotificationRemoteSettingsEewImplCopyWith<$Res> {
+ __$$NotificationRemoteSettingsEewImplCopyWithImpl(
+ _$NotificationRemoteSettingsEewImpl _value,
+ $Res Function(_$NotificationRemoteSettingsEewImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? global = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_$NotificationRemoteSettingsEewImpl(
+ global: freezed == global
+ ? _value.global
+ : global // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value._regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$NotificationRemoteSettingsEewImpl
+ implements _NotificationRemoteSettingsEew {
+ const _$NotificationRemoteSettingsEewImpl(
+ {required this.global,
+ required final List regions})
+ : _regions = regions;
+
+ factory _$NotificationRemoteSettingsEewImpl.fromJson(
+ Map json) =>
+ _$$NotificationRemoteSettingsEewImplFromJson(json);
+
+ @override
+ final JmaForecastIntensity? global;
+ final List _regions;
+ @override
+ List get regions {
+ if (_regions is EqualUnmodifiableListView) return _regions;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_regions);
+ }
+
+ @override
+ String toString() {
+ return 'NotificationRemoteSettingsEew(global: $global, regions: $regions)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$NotificationRemoteSettingsEewImpl &&
+ (identical(other.global, global) || other.global == global) &&
+ const DeepCollectionEquality().equals(other._regions, _regions));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(
+ runtimeType, global, const DeepCollectionEquality().hash(_regions));
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$NotificationRemoteSettingsEewImplCopyWith<
+ _$NotificationRemoteSettingsEewImpl>
+ get copyWith => __$$NotificationRemoteSettingsEewImplCopyWithImpl<
+ _$NotificationRemoteSettingsEewImpl>(this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$NotificationRemoteSettingsEewImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _NotificationRemoteSettingsEew
+ implements NotificationRemoteSettingsEew {
+ const factory _NotificationRemoteSettingsEew(
+ {required final JmaForecastIntensity? global,
+ required final List regions}) =
+ _$NotificationRemoteSettingsEewImpl;
+
+ factory _NotificationRemoteSettingsEew.fromJson(Map json) =
+ _$NotificationRemoteSettingsEewImpl.fromJson;
+
+ @override
+ JmaForecastIntensity? get global;
+ @override
+ List get regions;
+ @override
+ @JsonKey(ignore: true)
+ _$$NotificationRemoteSettingsEewImplCopyWith<
+ _$NotificationRemoteSettingsEewImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+NotificationRemoteSettingsEewRegion
+ _$NotificationRemoteSettingsEewRegionFromJson(Map json) {
+ return _NotificationRemoteSettingsEewRegion.fromJson(json);
+}
+
+/// @nodoc
+mixin _$NotificationRemoteSettingsEewRegion {
+ int get regionId => throw _privateConstructorUsedError;
+ JmaForecastIntensity get minJmaIntensity =>
+ throw _privateConstructorUsedError;
+ String get name => throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $NotificationRemoteSettingsEewRegionCopyWith<
+ NotificationRemoteSettingsEewRegion>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $NotificationRemoteSettingsEewRegionCopyWith<$Res> {
+ factory $NotificationRemoteSettingsEewRegionCopyWith(
+ NotificationRemoteSettingsEewRegion value,
+ $Res Function(NotificationRemoteSettingsEewRegion) then) =
+ _$NotificationRemoteSettingsEewRegionCopyWithImpl<$Res,
+ NotificationRemoteSettingsEewRegion>;
+ @useResult
+ $Res call({int regionId, JmaForecastIntensity minJmaIntensity, String name});
+}
+
+/// @nodoc
+class _$NotificationRemoteSettingsEewRegionCopyWithImpl<$Res,
+ $Val extends NotificationRemoteSettingsEewRegion>
+ implements $NotificationRemoteSettingsEewRegionCopyWith<$Res> {
+ _$NotificationRemoteSettingsEewRegionCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? regionId = null,
+ Object? minJmaIntensity = null,
+ Object? name = null,
+ }) {
+ return _then(_value.copyWith(
+ regionId: null == regionId
+ ? _value.regionId
+ : regionId // ignore: cast_nullable_to_non_nullable
+ as int,
+ minJmaIntensity: null == minJmaIntensity
+ ? _value.minJmaIntensity
+ : minJmaIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ name: null == name
+ ? _value.name
+ : name // ignore: cast_nullable_to_non_nullable
+ as String,
+ ) as $Val);
+ }
+}
+
+/// @nodoc
+abstract class _$$NotificationRemoteSettingsEewRegionImplCopyWith<$Res>
+ implements $NotificationRemoteSettingsEewRegionCopyWith<$Res> {
+ factory _$$NotificationRemoteSettingsEewRegionImplCopyWith(
+ _$NotificationRemoteSettingsEewRegionImpl value,
+ $Res Function(_$NotificationRemoteSettingsEewRegionImpl) then) =
+ __$$NotificationRemoteSettingsEewRegionImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call({int regionId, JmaForecastIntensity minJmaIntensity, String name});
+}
+
+/// @nodoc
+class __$$NotificationRemoteSettingsEewRegionImplCopyWithImpl<$Res>
+ extends _$NotificationRemoteSettingsEewRegionCopyWithImpl<$Res,
+ _$NotificationRemoteSettingsEewRegionImpl>
+ implements _$$NotificationRemoteSettingsEewRegionImplCopyWith<$Res> {
+ __$$NotificationRemoteSettingsEewRegionImplCopyWithImpl(
+ _$NotificationRemoteSettingsEewRegionImpl _value,
+ $Res Function(_$NotificationRemoteSettingsEewRegionImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? regionId = null,
+ Object? minJmaIntensity = null,
+ Object? name = null,
+ }) {
+ return _then(_$NotificationRemoteSettingsEewRegionImpl(
+ regionId: null == regionId
+ ? _value.regionId
+ : regionId // ignore: cast_nullable_to_non_nullable
+ as int,
+ minJmaIntensity: null == minJmaIntensity
+ ? _value.minJmaIntensity
+ : minJmaIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ name: null == name
+ ? _value.name
+ : name // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$NotificationRemoteSettingsEewRegionImpl
+ implements _NotificationRemoteSettingsEewRegion {
+ const _$NotificationRemoteSettingsEewRegionImpl(
+ {required this.regionId,
+ required this.minJmaIntensity,
+ required this.name});
+
+ factory _$NotificationRemoteSettingsEewRegionImpl.fromJson(
+ Map json) =>
+ _$$NotificationRemoteSettingsEewRegionImplFromJson(json);
+
+ @override
+ final int regionId;
+ @override
+ final JmaForecastIntensity minJmaIntensity;
+ @override
+ final String name;
+
+ @override
+ String toString() {
+ return 'NotificationRemoteSettingsEewRegion(regionId: $regionId, minJmaIntensity: $minJmaIntensity, name: $name)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$NotificationRemoteSettingsEewRegionImpl &&
+ (identical(other.regionId, regionId) ||
+ other.regionId == regionId) &&
+ (identical(other.minJmaIntensity, minJmaIntensity) ||
+ other.minJmaIntensity == minJmaIntensity) &&
+ (identical(other.name, name) || other.name == name));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(runtimeType, regionId, minJmaIntensity, name);
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$NotificationRemoteSettingsEewRegionImplCopyWith<
+ _$NotificationRemoteSettingsEewRegionImpl>
+ get copyWith => __$$NotificationRemoteSettingsEewRegionImplCopyWithImpl<
+ _$NotificationRemoteSettingsEewRegionImpl>(this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$NotificationRemoteSettingsEewRegionImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _NotificationRemoteSettingsEewRegion
+ implements NotificationRemoteSettingsEewRegion {
+ const factory _NotificationRemoteSettingsEewRegion(
+ {required final int regionId,
+ required final JmaForecastIntensity minJmaIntensity,
+ required final String name}) = _$NotificationRemoteSettingsEewRegionImpl;
+
+ factory _NotificationRemoteSettingsEewRegion.fromJson(
+ Map json) =
+ _$NotificationRemoteSettingsEewRegionImpl.fromJson;
+
+ @override
+ int get regionId;
+ @override
+ JmaForecastIntensity get minJmaIntensity;
+ @override
+ String get name;
+ @override
+ @JsonKey(ignore: true)
+ _$$NotificationRemoteSettingsEewRegionImplCopyWith<
+ _$NotificationRemoteSettingsEewRegionImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+NotificationRemoteSettingsEarthquake
+ _$NotificationRemoteSettingsEarthquakeFromJson(Map json) {
+ return _NotificationRemoteSettingsEarthquake.fromJson(json);
+}
+
+/// @nodoc
+mixin _$NotificationRemoteSettingsEarthquake {
+ JmaForecastIntensity? get global => throw _privateConstructorUsedError;
+ List get regions =>
+ throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $NotificationRemoteSettingsEarthquakeCopyWith<
+ NotificationRemoteSettingsEarthquake>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $NotificationRemoteSettingsEarthquakeCopyWith<$Res> {
+ factory $NotificationRemoteSettingsEarthquakeCopyWith(
+ NotificationRemoteSettingsEarthquake value,
+ $Res Function(NotificationRemoteSettingsEarthquake) then) =
+ _$NotificationRemoteSettingsEarthquakeCopyWithImpl<$Res,
+ NotificationRemoteSettingsEarthquake>;
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? global,
+ List regions});
+}
+
+/// @nodoc
+class _$NotificationRemoteSettingsEarthquakeCopyWithImpl<$Res,
+ $Val extends NotificationRemoteSettingsEarthquake>
+ implements $NotificationRemoteSettingsEarthquakeCopyWith<$Res> {
+ _$NotificationRemoteSettingsEarthquakeCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? global = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_value.copyWith(
+ global: freezed == global
+ ? _value.global
+ : global // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value.regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ) as $Val);
+ }
+}
+
+/// @nodoc
+abstract class _$$NotificationRemoteSettingsEarthquakeImplCopyWith<$Res>
+ implements $NotificationRemoteSettingsEarthquakeCopyWith<$Res> {
+ factory _$$NotificationRemoteSettingsEarthquakeImplCopyWith(
+ _$NotificationRemoteSettingsEarthquakeImpl value,
+ $Res Function(_$NotificationRemoteSettingsEarthquakeImpl) then) =
+ __$$NotificationRemoteSettingsEarthquakeImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call(
+ {JmaForecastIntensity? global,
+ List regions});
+}
+
+/// @nodoc
+class __$$NotificationRemoteSettingsEarthquakeImplCopyWithImpl<$Res>
+ extends _$NotificationRemoteSettingsEarthquakeCopyWithImpl<$Res,
+ _$NotificationRemoteSettingsEarthquakeImpl>
+ implements _$$NotificationRemoteSettingsEarthquakeImplCopyWith<$Res> {
+ __$$NotificationRemoteSettingsEarthquakeImplCopyWithImpl(
+ _$NotificationRemoteSettingsEarthquakeImpl _value,
+ $Res Function(_$NotificationRemoteSettingsEarthquakeImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? global = freezed,
+ Object? regions = null,
+ }) {
+ return _then(_$NotificationRemoteSettingsEarthquakeImpl(
+ global: freezed == global
+ ? _value.global
+ : global // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity?,
+ regions: null == regions
+ ? _value._regions
+ : regions // ignore: cast_nullable_to_non_nullable
+ as List,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$NotificationRemoteSettingsEarthquakeImpl
+ implements _NotificationRemoteSettingsEarthquake {
+ const _$NotificationRemoteSettingsEarthquakeImpl(
+ {required this.global,
+ required final List regions})
+ : _regions = regions;
+
+ factory _$NotificationRemoteSettingsEarthquakeImpl.fromJson(
+ Map json) =>
+ _$$NotificationRemoteSettingsEarthquakeImplFromJson(json);
+
+ @override
+ final JmaForecastIntensity? global;
+ final List _regions;
+ @override
+ List get regions {
+ if (_regions is EqualUnmodifiableListView) return _regions;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_regions);
+ }
+
+ @override
+ String toString() {
+ return 'NotificationRemoteSettingsEarthquake(global: $global, regions: $regions)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$NotificationRemoteSettingsEarthquakeImpl &&
+ (identical(other.global, global) || other.global == global) &&
+ const DeepCollectionEquality().equals(other._regions, _regions));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(
+ runtimeType, global, const DeepCollectionEquality().hash(_regions));
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$NotificationRemoteSettingsEarthquakeImplCopyWith<
+ _$NotificationRemoteSettingsEarthquakeImpl>
+ get copyWith => __$$NotificationRemoteSettingsEarthquakeImplCopyWithImpl<
+ _$NotificationRemoteSettingsEarthquakeImpl>(this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$NotificationRemoteSettingsEarthquakeImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _NotificationRemoteSettingsEarthquake
+ implements NotificationRemoteSettingsEarthquake {
+ const factory _NotificationRemoteSettingsEarthquake(
+ {required final JmaForecastIntensity? global,
+ required final List
+ regions}) = _$NotificationRemoteSettingsEarthquakeImpl;
+
+ factory _NotificationRemoteSettingsEarthquake.fromJson(
+ Map json) =
+ _$NotificationRemoteSettingsEarthquakeImpl.fromJson;
+
+ @override
+ JmaForecastIntensity? get global;
+ @override
+ List get regions;
+ @override
+ @JsonKey(ignore: true)
+ _$$NotificationRemoteSettingsEarthquakeImplCopyWith<
+ _$NotificationRemoteSettingsEarthquakeImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+NotificationRemoteSettingsEarthquakeRegion
+ _$NotificationRemoteSettingsEarthquakeRegionFromJson(
+ Map json) {
+ return _NotificationRemoteSettingsEarthquakeRegion.fromJson(json);
+}
+
+/// @nodoc
+mixin _$NotificationRemoteSettingsEarthquakeRegion {
+ int get regionId => throw _privateConstructorUsedError;
+ JmaForecastIntensity get minJmaIntensity =>
+ throw _privateConstructorUsedError;
+ String get name => throw _privateConstructorUsedError;
+
+ Map toJson() => throw _privateConstructorUsedError;
+ @JsonKey(ignore: true)
+ $NotificationRemoteSettingsEarthquakeRegionCopyWith<
+ NotificationRemoteSettingsEarthquakeRegion>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $NotificationRemoteSettingsEarthquakeRegionCopyWith<$Res> {
+ factory $NotificationRemoteSettingsEarthquakeRegionCopyWith(
+ NotificationRemoteSettingsEarthquakeRegion value,
+ $Res Function(NotificationRemoteSettingsEarthquakeRegion) then) =
+ _$NotificationRemoteSettingsEarthquakeRegionCopyWithImpl<$Res,
+ NotificationRemoteSettingsEarthquakeRegion>;
+ @useResult
+ $Res call({int regionId, JmaForecastIntensity minJmaIntensity, String name});
+}
+
+/// @nodoc
+class _$NotificationRemoteSettingsEarthquakeRegionCopyWithImpl<$Res,
+ $Val extends NotificationRemoteSettingsEarthquakeRegion>
+ implements $NotificationRemoteSettingsEarthquakeRegionCopyWith<$Res> {
+ _$NotificationRemoteSettingsEarthquakeRegionCopyWithImpl(
+ this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? regionId = null,
+ Object? minJmaIntensity = null,
+ Object? name = null,
+ }) {
+ return _then(_value.copyWith(
+ regionId: null == regionId
+ ? _value.regionId
+ : regionId // ignore: cast_nullable_to_non_nullable
+ as int,
+ minJmaIntensity: null == minJmaIntensity
+ ? _value.minJmaIntensity
+ : minJmaIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ name: null == name
+ ? _value.name
+ : name // ignore: cast_nullable_to_non_nullable
+ as String,
+ ) as $Val);
+ }
+}
+
+/// @nodoc
+abstract class _$$NotificationRemoteSettingsEarthquakeRegionImplCopyWith<$Res>
+ implements $NotificationRemoteSettingsEarthquakeRegionCopyWith<$Res> {
+ factory _$$NotificationRemoteSettingsEarthquakeRegionImplCopyWith(
+ _$NotificationRemoteSettingsEarthquakeRegionImpl value,
+ $Res Function(_$NotificationRemoteSettingsEarthquakeRegionImpl)
+ then) =
+ __$$NotificationRemoteSettingsEarthquakeRegionImplCopyWithImpl<$Res>;
+ @override
+ @useResult
+ $Res call({int regionId, JmaForecastIntensity minJmaIntensity, String name});
+}
+
+/// @nodoc
+class __$$NotificationRemoteSettingsEarthquakeRegionImplCopyWithImpl<$Res>
+ extends _$NotificationRemoteSettingsEarthquakeRegionCopyWithImpl<$Res,
+ _$NotificationRemoteSettingsEarthquakeRegionImpl>
+ implements _$$NotificationRemoteSettingsEarthquakeRegionImplCopyWith<$Res> {
+ __$$NotificationRemoteSettingsEarthquakeRegionImplCopyWithImpl(
+ _$NotificationRemoteSettingsEarthquakeRegionImpl _value,
+ $Res Function(_$NotificationRemoteSettingsEarthquakeRegionImpl) _then)
+ : super(_value, _then);
+
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? regionId = null,
+ Object? minJmaIntensity = null,
+ Object? name = null,
+ }) {
+ return _then(_$NotificationRemoteSettingsEarthquakeRegionImpl(
+ regionId: null == regionId
+ ? _value.regionId
+ : regionId // ignore: cast_nullable_to_non_nullable
+ as int,
+ minJmaIntensity: null == minJmaIntensity
+ ? _value.minJmaIntensity
+ : minJmaIntensity // ignore: cast_nullable_to_non_nullable
+ as JmaForecastIntensity,
+ name: null == name
+ ? _value.name
+ : name // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$NotificationRemoteSettingsEarthquakeRegionImpl
+ implements _NotificationRemoteSettingsEarthquakeRegion {
+ const _$NotificationRemoteSettingsEarthquakeRegionImpl(
+ {required this.regionId,
+ required this.minJmaIntensity,
+ required this.name});
+
+ factory _$NotificationRemoteSettingsEarthquakeRegionImpl.fromJson(
+ Map json) =>
+ _$$NotificationRemoteSettingsEarthquakeRegionImplFromJson(json);
+
+ @override
+ final int regionId;
+ @override
+ final JmaForecastIntensity minJmaIntensity;
+ @override
+ final String name;
+
+ @override
+ String toString() {
+ return 'NotificationRemoteSettingsEarthquakeRegion(regionId: $regionId, minJmaIntensity: $minJmaIntensity, name: $name)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$NotificationRemoteSettingsEarthquakeRegionImpl &&
+ (identical(other.regionId, regionId) ||
+ other.regionId == regionId) &&
+ (identical(other.minJmaIntensity, minJmaIntensity) ||
+ other.minJmaIntensity == minJmaIntensity) &&
+ (identical(other.name, name) || other.name == name));
+ }
+
+ @JsonKey(ignore: true)
+ @override
+ int get hashCode => Object.hash(runtimeType, regionId, minJmaIntensity, name);
+
+ @JsonKey(ignore: true)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$NotificationRemoteSettingsEarthquakeRegionImplCopyWith<
+ _$NotificationRemoteSettingsEarthquakeRegionImpl>
+ get copyWith =>
+ __$$NotificationRemoteSettingsEarthquakeRegionImplCopyWithImpl<
+ _$NotificationRemoteSettingsEarthquakeRegionImpl>(
+ this, _$identity);
+
+ @override
+ Map toJson() {
+ return _$$NotificationRemoteSettingsEarthquakeRegionImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _NotificationRemoteSettingsEarthquakeRegion
+ implements NotificationRemoteSettingsEarthquakeRegion {
+ const factory _NotificationRemoteSettingsEarthquakeRegion(
+ {required final int regionId,
+ required final JmaForecastIntensity minJmaIntensity,
+ required final String name}) =
+ _$NotificationRemoteSettingsEarthquakeRegionImpl;
+
+ factory _NotificationRemoteSettingsEarthquakeRegion.fromJson(
+ Map json) =
+ _$NotificationRemoteSettingsEarthquakeRegionImpl.fromJson;
+
+ @override
+ int get regionId;
+ @override
+ JmaForecastIntensity get minJmaIntensity;
+ @override
+ String get name;
+ @override
+ @JsonKey(ignore: true)
+ _$$NotificationRemoteSettingsEarthquakeRegionImplCopyWith<
+ _$NotificationRemoteSettingsEarthquakeRegionImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
diff --git a/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.g.dart b/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.g.dart
new file mode 100644
index 000000000..35dfa3d79
--- /dev/null
+++ b/app/lib/feature/settings/features/notification_remote_settings/data/model/notification_remote_settings_state.g.dart
@@ -0,0 +1,158 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+// ignore_for_file: type=lint, duplicate_ignore
+
+part of 'notification_remote_settings_state.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+_$NotificationRemoteSettingsStateImpl
+ _$$NotificationRemoteSettingsStateImplFromJson(Map json) =>
+ $checkedCreate(
+ r'_$NotificationRemoteSettingsStateImpl',
+ json,
+ ($checkedConvert) {
+ final val = _$NotificationRemoteSettingsStateImpl(
+ eew: $checkedConvert(
+ 'eew',
+ (v) => NotificationRemoteSettingsEew.fromJson(
+ v as Map