diff --git a/android/app/build.gradle b/android/app/build.gradle index 9dd78f5404..56d2103c6a 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -141,12 +141,12 @@ android { dimension "environment" applicationId "me.tinykitten.trainlcd.dev" versionNameSuffix "-dev" - versionCode 100000427 + versionCode 100000428 versionName "10.5.1" } prod { dimension "environment" - versionCode 100000427 + versionCode 100000428 versionName "10.5.1" } } diff --git a/app.config.ts b/app.config.ts index e118e670a4..fae510d7f2 100644 --- a/app.config.ts +++ b/app.config.ts @@ -53,7 +53,7 @@ export default ({ config }: ConfigContext) => ({ }, }, ios: { - buildNumber: '2640', + buildNumber: '2641', bundleIdentifier: process.env.EAS_BUILD_PROFILE === 'production' ? 'me.tinykitten.trainlcd' @@ -70,7 +70,7 @@ export default ({ config }: ConfigContext) => ({ ? 'me.tinykitten.trainlcd' : 'me.tinykitten.trainlcd.dev', permissions: [], - versionCode: 100000427, + versionCode: 100000428, }, owner: 'trainlcd', }); diff --git a/functions/package-lock.json b/functions/package-lock.json index 259f0f80ac..44ddb7f26e 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -1914,9 +1914,10 @@ } }, "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz", + "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==", + "license": "MIT", "engines": { "node": ">= 10" } @@ -2466,22 +2467,23 @@ } }, "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "license": "MIT", "dependencies": { - "bytes": "3.1.2", + "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", "type-is": "~1.6.18", - "unpipe": "1.0.0" + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8", @@ -2492,14 +2494,45 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/body-parser/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -2597,6 +2630,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2799,6 +2833,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3249,14 +3284,14 @@ } }, "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "~1.20.3", + "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", @@ -3275,7 +3310,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "~6.14.0", + "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", @@ -3315,21 +3350,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/express/node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4037,6 +4057,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5134,6 +5155,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5679,11 +5701,12 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -5701,19 +5724,49 @@ } }, "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/raw-body/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -5849,7 +5902,8 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/semver": { "version": "7.7.0", @@ -6449,6 +6503,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" diff --git a/ios/TrainLCD.xcodeproj/project.pbxproj b/ios/TrainLCD.xcodeproj/project.pbxproj index ad84639f30..0cb3eb4e5d 100644 --- a/ios/TrainLCD.xcodeproj/project.pbxproj +++ b/ios/TrainLCD.xcodeproj/project.pbxproj @@ -2419,7 +2419,7 @@ CODE_SIGN_ENTITLEMENTS = ProdTrainLCD.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = E6R2G33Z36; INFOPLIST_FILE = TrainLCD/Schemes/Prod/Info.plist; @@ -2458,7 +2458,7 @@ CODE_SIGN_ENTITLEMENTS = ProdTrainLCD.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEVELOPMENT_TEAM = E6R2G33Z36; INFOPLIST_FILE = TrainLCD/Schemes/Prod/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = TrainLCD; @@ -2517,7 +2517,7 @@ CODE_SIGN_ENTITLEMENTS = TrainLCD/trainlcd.entitlements; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -2623,7 +2623,7 @@ CODE_SIGN_ENTITLEMENTS = TrainLCD/trainlcd.entitlements; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -2702,7 +2702,7 @@ CODE_SIGN_ENTITLEMENTS = CanaryTrainLCD.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = E6R2G33Z36; INFOPLIST_FILE = TrainLCD/Schemes/Dev/Info.plist; @@ -2741,7 +2741,7 @@ CODE_SIGN_ENTITLEMENTS = CanaryTrainLCD.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = E6R2G33Z36; INFOPLIST_FILE = TrainLCD/Schemes/Dev/Info.plist; @@ -2952,7 +2952,7 @@ CODE_SIGN_ENTITLEMENTS = RideSessionActivity/CanaryRideSessionActivity.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = E6R2G33Z36; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -3003,7 +3003,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = E6R2G33Z36; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -3054,7 +3054,7 @@ CODE_SIGN_ENTITLEMENTS = WatchWidget/ProdWatchWidget.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -3112,7 +3112,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -3163,7 +3163,7 @@ CODE_SIGN_ENTITLEMENTS = WatchWidget/CanaryWatchWidget.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -3220,7 +3220,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -3268,7 +3268,7 @@ CODE_SIGN_ENTITLEMENTS = RideSessionActivity/ProdRideSessionActivity.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = E6R2G33Z36; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -3319,7 +3319,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = E6R2G33Z36; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -3538,7 +3538,7 @@ CODE_SIGN_ENTITLEMENTS = ProdAppClip/ProdAppClip.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -3594,7 +3594,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -3644,7 +3644,7 @@ CODE_SIGN_ENTITLEMENTS = CanaryAppClip/CanaryAppClip.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -3702,7 +3702,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2640; + CURRENT_PROJECT_VERSION = 2641; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = E6R2G33Z36; ENABLE_USER_SCRIPT_SANDBOXING = NO; diff --git a/jest.setup.js b/jest.setup.js index bd6593e3f4..9fe6b9a836 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -26,6 +26,7 @@ jest.mock("~/hooks", () => ({ useNumbering: jest.fn(() => []), useClock: jest.fn(() => []), useInterval: jest.fn(() => null), + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), })); jest.mock("react-native-reanimated", () => { diff --git a/src/components/DevOverlay.test.tsx b/src/components/DevOverlay.test.tsx index df222590b7..fe6656c688 100644 --- a/src/components/DevOverlay.test.tsx +++ b/src/components/DevOverlay.test.tsx @@ -26,6 +26,7 @@ jest.mock('expo-application', () => ({ // Mock hooks jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useDistanceToNextStation: jest.fn(), useNextStation: jest.fn(), })); diff --git a/src/components/DevOverlay.tsx b/src/components/DevOverlay.tsx index a4aff49015..6140e278c0 100644 --- a/src/components/DevOverlay.tsx +++ b/src/components/DevOverlay.tsx @@ -10,11 +10,14 @@ import { StyleSheet, Text, type TextStyle, - useWindowDimensions, View, type ViewStyle, } from 'react-native'; -import { useDistanceToNextStation, useNextStation } from '~/hooks'; +import { + useDistanceToNextStation, + useLandscapeWindowDimensions, + useNextStation, +} from '~/hooks'; import { useTelemetryEnabled } from '~/hooks/useTelemetryEnabled'; import { backgroundLocationTrackingAtom, @@ -357,7 +360,7 @@ const DevOverlay: React.FC = () => { .filter(Boolean) .join(' / '); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const [basePosition, setBasePosition] = useState({ x: 0, y: 0 }); const isLandscape = dim.width > dim.height; const panelWidth = isLandscape diff --git a/src/components/Header.test.tsx b/src/components/Header.test.tsx index 22bf6dfd8f..b9546edec3 100644 --- a/src/components/Header.test.tsx +++ b/src/components/Header.test.tsx @@ -13,6 +13,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useHeaderCommonData: () => mockUseHeaderCommonData(), })); diff --git a/src/components/HeaderE231.test.tsx b/src/components/HeaderE231.test.tsx index e9cb4433dc..491a6f78e5 100644 --- a/src/components/HeaderE231.test.tsx +++ b/src/components/HeaderE231.test.tsx @@ -10,6 +10,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(() => ({ id: 1, name: 'Test', color: '#FFD400' })), useClock: jest.fn(() => ['12', '34']), useInterval: jest.fn(), diff --git a/src/components/HeaderEast/HeaderEast.test.tsx b/src/components/HeaderEast/HeaderEast.test.tsx index 4d7ef2c0bd..f762dec904 100644 --- a/src/components/HeaderEast/HeaderEast.test.tsx +++ b/src/components/HeaderEast/HeaderEast.test.tsx @@ -53,6 +53,7 @@ jest.mock('~/store/atoms/tuning', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => ({ id: 1, name: 'Test Station', diff --git a/src/components/HeaderEast/HeaderEast.tsx b/src/components/HeaderEast/HeaderEast.tsx index d4cba8f085..6ad21b9734 100644 --- a/src/components/HeaderEast/HeaderEast.tsx +++ b/src/components/HeaderEast/HeaderEast.tsx @@ -1,14 +1,8 @@ import { LinearGradient } from 'expo-linear-gradient'; import React from 'react'; -import { - Animated as RNAnimated, - StyleSheet, - Text, - useWindowDimensions, - View, -} from 'react-native'; +import { Animated as RNAnimated, StyleSheet, Text, View } from 'react-native'; import { MARK_SHAPE, STATION_NAME_FONT_SIZE } from '../../constants'; -import { useHeaderAnimation } from '../../hooks'; +import { useHeaderAnimation, useLandscapeWindowDimensions } from '../../hooks'; import isTablet from '../../utils/isTablet'; import { RFValue } from '../../utils/rfValue'; import { calcStationNameMinScale } from '../../utils/stationNameScale'; @@ -125,7 +119,7 @@ const HeaderEast: React.FC = ({ config, ...props }) => { isJapaneseState, }); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const stationNameColor = config.stationNameColor ?? config.textColor; diff --git a/src/components/HeaderJRKyushu.test.tsx b/src/components/HeaderJRKyushu.test.tsx index 472bc21776..410c66df57 100644 --- a/src/components/HeaderJRKyushu.test.tsx +++ b/src/components/HeaderJRKyushu.test.tsx @@ -76,6 +76,7 @@ const mockNextStation = { }; jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => mockStation), useCurrentLine: jest.fn(() => mockLine), useNextStation: jest.fn(() => mockNextStation), diff --git a/src/components/HeaderJRWest.test.tsx b/src/components/HeaderJRWest.test.tsx index b67d6724c6..b8077977fc 100644 --- a/src/components/HeaderJRWest.test.tsx +++ b/src/components/HeaderJRWest.test.tsx @@ -59,6 +59,7 @@ const mockNextStation = { }; jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => mockStation), useCurrentLine: jest.fn(() => mockLine), useNextStation: jest.fn(() => mockNextStation), diff --git a/src/components/HeaderLED.test.tsx b/src/components/HeaderLED.test.tsx index 9997166d05..9095e32ea6 100644 --- a/src/components/HeaderLED.test.tsx +++ b/src/components/HeaderLED.test.tsx @@ -41,6 +41,7 @@ const mockNextStation = { }; jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => mockStation), useNextStation: jest.fn(() => mockNextStation), useIsNextLastStop: jest.fn(() => false), diff --git a/src/components/HeaderLED.tsx b/src/components/HeaderLED.tsx index 52ea7c24ba..425d20d375 100644 --- a/src/components/HeaderLED.tsx +++ b/src/components/HeaderLED.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useState } from 'react'; -import { StyleSheet, useWindowDimensions, View } from 'react-native'; -import { useNumbering } from '~/hooks'; +import { StyleSheet, View } from 'react-native'; +import { useLandscapeWindowDimensions, useNumbering } from '~/hooks'; import { LED_THEME_BG_COLOR, STATION_NAME_FONT_SIZE } from '../constants'; import { translate } from '../translation'; import type { CommonHeaderProps } from './Header.types'; @@ -61,7 +61,7 @@ const HeaderLED: React.FC = (props) => { // HeaderLEDは現在駅と次駅両方のナンバリングが必要 const [nextStationNumber] = useNumbering(); const [currentStationNumber] = useNumbering(true); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const [stateText, setStateText] = useState(''); const [stationText, setStationText] = useState(station?.name ?? ''); diff --git a/src/components/HeaderOdakyu.test.tsx b/src/components/HeaderOdakyu.test.tsx index 0f172ae89d..b505f5fe5c 100644 --- a/src/components/HeaderOdakyu.test.tsx +++ b/src/components/HeaderOdakyu.test.tsx @@ -50,6 +50,7 @@ jest.mock('~/store/atoms/tuning', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => ({ id: 1, name: 'Test' })), useCurrentLine: jest.fn(() => ({ id: 1, name: 'Test', color: '#FF0000' })), useNextStation: jest.fn(() => ({ id: 2, name: 'Next' })), diff --git a/src/components/HeaderSaikyo.test.tsx b/src/components/HeaderSaikyo.test.tsx index e4634e42f4..ca52cb1ca7 100644 --- a/src/components/HeaderSaikyo.test.tsx +++ b/src/components/HeaderSaikyo.test.tsx @@ -77,6 +77,7 @@ const mockNextStation = { }; jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => mockStation), useCurrentLine: jest.fn(() => mockLine), useNextStation: jest.fn(() => mockNextStation), diff --git a/src/components/HeaderTY.test.tsx b/src/components/HeaderTY.test.tsx index 272d1dd0bd..335b7d82cb 100644 --- a/src/components/HeaderTY.test.tsx +++ b/src/components/HeaderTY.test.tsx @@ -73,6 +73,7 @@ const mockNextStation = { }; jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => mockStation), useCurrentLine: jest.fn(() => mockLine), useNextStation: jest.fn(() => mockNextStation), diff --git a/src/components/HeaderTokyoMetro.test.tsx b/src/components/HeaderTokyoMetro.test.tsx index 0f95e90df6..783715bd06 100644 --- a/src/components/HeaderTokyoMetro.test.tsx +++ b/src/components/HeaderTokyoMetro.test.tsx @@ -73,6 +73,7 @@ const mockNextStation = { }; jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(() => mockStation), useCurrentLine: jest.fn(() => mockLine), useNextStation: jest.fn(() => mockNextStation), diff --git a/src/components/LineBoard.test.tsx b/src/components/LineBoard.test.tsx index b542f89a89..c9cf5684ee 100644 --- a/src/components/LineBoard.test.tsx +++ b/src/components/LineBoard.test.tsx @@ -12,6 +12,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentStation: jest.fn(), })); diff --git a/src/components/LineBoard/shared/components/StationName.tsx b/src/components/LineBoard/shared/components/StationName.tsx index d87c9689d4..e5b2983c9c 100644 --- a/src/components/LineBoard/shared/components/StationName.tsx +++ b/src/components/LineBoard/shared/components/StationName.tsx @@ -1,11 +1,7 @@ import React, { useMemo } from 'react'; -import { - type StyleProp, - type TextStyle, - useWindowDimensions, - View, -} from 'react-native'; +import { type StyleProp, type TextStyle, View } from 'react-native'; import type { Station } from '~/@types/graphql'; +import { useLandscapeWindowDimensions } from '~/hooks'; import getStationNameR from '~/utils/getStationNameR'; import isTablet from '~/utils/isTablet'; import Typography from '../../../Typography'; @@ -35,7 +31,7 @@ export const StationName: React.FC = React.memo( () => station.name?.split('') ?? [], [station.name] ); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const horizontalAdditionalStyle = useMemo( () => ({ diff --git a/src/components/LineBoardE231.tsx b/src/components/LineBoardE231.tsx index a00007cba9..e6648a9858 100644 --- a/src/components/LineBoardE231.tsx +++ b/src/components/LineBoardE231.tsx @@ -1,8 +1,12 @@ import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo } from 'react'; -import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native'; +import { Platform, StyleSheet, View } from 'react-native'; import type { Line, Station } from '~/@types/graphql'; -import { useCurrentLine, useTransferLinesFromStation } from '~/hooks'; +import { + useCurrentLine, + useLandscapeWindowDimensions, + useTransferLinesFromStation, +} from '~/hooks'; import { useScale } from '~/hooks/useScale'; import { isEnAtom } from '~/store/selectors/isEn'; import { RFValue } from '~/utils/rfValue'; @@ -158,7 +162,7 @@ const StationNameCell: React.FC = ({ hasTerminus, }: StationNameCellProps) => { const isEn = useAtomValue(isEnAtom); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const { widthScale } = useScale(); const { left: barLeft, width: barWidth } = useBarStyles({ index }); @@ -300,7 +304,7 @@ const LineBoardE231: React.FC = ({ }: Props) => { const { selectedLine } = useAtomValue(lineState); const currentLine = useCurrentLine(); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const line = useMemo( () => currentLine || selectedLine, diff --git a/src/components/LineBoardEast.test.tsx b/src/components/LineBoardEast.test.tsx index 39e573f96e..e60fcc1ec0 100644 --- a/src/components/LineBoardEast.test.tsx +++ b/src/components/LineBoardEast.test.tsx @@ -11,6 +11,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(), useInterval: jest.fn(), useTransferLinesFromStation: jest.fn(() => []), diff --git a/src/components/LineBoardEast.tsx b/src/components/LineBoardEast.tsx index 3c3fc88521..b22faf325d 100644 --- a/src/components/LineBoardEast.tsx +++ b/src/components/LineBoardEast.tsx @@ -1,11 +1,12 @@ import { LinearGradient } from 'expo-linear-gradient'; import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo, useState } from 'react'; -import { StyleSheet, useWindowDimensions, View } from 'react-native'; +import { StyleSheet, View } from 'react-native'; import type { Line, Station } from '~/@types/graphql'; import { useCurrentLine, useInterval, + useLandscapeWindowDimensions, useTransferLinesFromStation, } from '~/hooks'; import { useAfterNextStation } from '~/hooks/useAfterNextStation'; @@ -333,7 +334,7 @@ const StationNameCell: React.FC = ({ const additionalChevronStyle = useChevronPosition(index, arrived, passed); const includesLongStationName = useIncludesLongStationName(stations); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const hasDrawableNumbering = useMemo( () => @@ -478,7 +479,7 @@ const LineBoardEast: React.FC = ({ const nextStation = useNextStation(); const afterNextStation = useAfterNextStation(); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const line = useMemo( () => currentLine || selectedLine, diff --git a/src/components/LineBoardJO.test.tsx b/src/components/LineBoardJO.test.tsx index 252423c870..31a13cc674 100644 --- a/src/components/LineBoardJO.test.tsx +++ b/src/components/LineBoardJO.test.tsx @@ -11,6 +11,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(), useCurrentStation: jest.fn(), useIsPassing: jest.fn(() => false), diff --git a/src/components/LineBoardJO.tsx b/src/components/LineBoardJO.tsx index 75d95c5e8b..ee9ed5da76 100644 --- a/src/components/LineBoardJO.tsx +++ b/src/components/LineBoardJO.tsx @@ -1,11 +1,12 @@ import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo } from 'react'; -import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native'; +import { Platform, StyleSheet, View } from 'react-native'; import type { Station, StationNumber } from '~/@types/graphql'; import { useCurrentLine, useCurrentStation, useIsPassing, + useLandscapeWindowDimensions, useStationNumberIndexFunc, useTransferLinesFromStation, } from '~/hooks'; @@ -34,7 +35,7 @@ interface Props { } const useBarWidth = () => { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); return isTablet ? (dim.width - 120) / 8 : (dim.width - 96) / 7.835; }; @@ -129,7 +130,7 @@ const StationNameCell: React.FC = ({ () => stationInLoop.stationNumbers?.[stationNumberIndex], [stationInLoop.stationNumbers, stationNumberIndex] ); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const additionalPadLineMarksContainerStyle = useMemo(() => { // rootWestJOのbottomがAndroidでは'30%'、iPadでは'40%'のため、 diff --git a/src/components/LineBoardJRKyushu.test.tsx b/src/components/LineBoardJRKyushu.test.tsx index f4963d5b2f..aec4281d3a 100644 --- a/src/components/LineBoardJRKyushu.test.tsx +++ b/src/components/LineBoardJRKyushu.test.tsx @@ -11,6 +11,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(), useInterval: jest.fn(), useTransferLinesFromStation: jest.fn(() => []), diff --git a/src/components/LineBoardJRKyushu.tsx b/src/components/LineBoardJRKyushu.tsx index ff3ce20ff2..b16c1ce59a 100644 --- a/src/components/LineBoardJRKyushu.tsx +++ b/src/components/LineBoardJRKyushu.tsx @@ -1,11 +1,12 @@ import { LinearGradient } from 'expo-linear-gradient'; import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo, useState } from 'react'; -import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native'; +import { Platform, StyleSheet, View } from 'react-native'; import type { Line, Station } from '~/@types/graphql'; import { useCurrentLine, useInterval, + useLandscapeWindowDimensions, useTransferLinesFromStation, } from '~/hooks'; import { useScale } from '~/hooks/useScale'; @@ -252,7 +253,7 @@ const StationNameCell: React.FC = ({ hasTerminus, chevronColor, }: StationNameCellProps) => { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const { currentStationIndex, arrived, @@ -393,7 +394,7 @@ const LineBoardJRKyushu: React.FC = ({ const [chevronColor, setChevronColor] = useState<'BLUE' | 'BLACK'>('BLACK'); const { selectedLine } = useAtomValue(lineState); const currentLine = useCurrentLine(); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const padCount = Math.max(0, 8 - stations.length); const totalStations = stations.length + padCount; diff --git a/src/components/LineBoardLED.test.tsx b/src/components/LineBoardLED.test.tsx index ab008bf110..b17832497f 100644 --- a/src/components/LineBoardLED.test.tsx +++ b/src/components/LineBoardLED.test.tsx @@ -12,6 +12,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useAfterNextStation: jest.fn(), useBounds: jest.fn(() => ({ directionalStops: [] })), useCurrentLine: jest.fn(), diff --git a/src/components/LineBoardSaikyo.test.tsx b/src/components/LineBoardSaikyo.test.tsx index ff3604187a..c5bf6953d6 100644 --- a/src/components/LineBoardSaikyo.test.tsx +++ b/src/components/LineBoardSaikyo.test.tsx @@ -11,6 +11,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(), useInterval: jest.fn(), useTransferLinesFromStation: jest.fn(() => []), diff --git a/src/components/LineBoardSaikyo.tsx b/src/components/LineBoardSaikyo.tsx index fd843f73d1..9651371231 100644 --- a/src/components/LineBoardSaikyo.tsx +++ b/src/components/LineBoardSaikyo.tsx @@ -1,11 +1,12 @@ import { LinearGradient } from 'expo-linear-gradient'; import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo, useState } from 'react'; -import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native'; +import { Platform, StyleSheet, View } from 'react-native'; import type { Line, Station } from '~/@types/graphql'; import { useCurrentLine, useInterval, + useLandscapeWindowDimensions, useTransferLinesFromStation, } from '~/hooks'; import { useScale } from '~/hooks/useScale'; @@ -208,7 +209,7 @@ const StationNameCell: React.FC = ({ chevronColor, }: StationNameCellProps) => { const isEn = useAtomValue(isEnAtom); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const { widthScale } = useScale(); const { left: barLeft, width: barWidth } = useBarStyles({ index }); @@ -301,7 +302,7 @@ const LineBoardSaikyo: React.FC = ({ const [chevronColor, setChevronColor] = useState<'RED' | 'WHITE'>('RED'); const { selectedLine } = useAtomValue(lineState); const currentLine = useCurrentLine(); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const line = useMemo( () => currentLine || selectedLine, diff --git a/src/components/LineBoardToei.test.tsx b/src/components/LineBoardToei.test.tsx index 86560b4ab6..d9cc23aee5 100644 --- a/src/components/LineBoardToei.test.tsx +++ b/src/components/LineBoardToei.test.tsx @@ -11,6 +11,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(), useInterval: jest.fn(), useStationNumberIndexFunc: jest.fn(() => jest.fn(() => 0)), diff --git a/src/components/LineBoardToei.tsx b/src/components/LineBoardToei.tsx index fd8b67deae..ae2b3aaa90 100644 --- a/src/components/LineBoardToei.tsx +++ b/src/components/LineBoardToei.tsx @@ -1,11 +1,12 @@ import { LinearGradient } from 'expo-linear-gradient'; import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo, useState } from 'react'; -import { StyleSheet, useWindowDimensions, View } from 'react-native'; +import { StyleSheet, View } from 'react-native'; import type { Line, Station, StationNumber } from '~/@types/graphql'; import { useCurrentLine, useInterval, + useLandscapeWindowDimensions, useStationNumberIndexFunc, useTransferLinesFromStation, } from '~/hooks'; @@ -92,7 +93,7 @@ const StationNameToeiBase: React.FC = ({ hasNumbering, }) => { const stationNameR = useMemo(() => getStationNameR(station), [station]); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const horizontalAdditionalStyle = useMemo(() => { if (!hasNumbering) { @@ -367,7 +368,7 @@ const StationNameCell: React.FC = ({ const additionalChevronStyle = useChevronPosition(index, arrived, passed); const includesLongStationName = useIncludesLongStationName(stations); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const getStationNumberIndex = useStationNumberIndexFunc(); const stationNumberIndex = useMemo( () => getStationNumberIndex(currentStation ?? undefined), @@ -497,7 +498,7 @@ const LineBoardToei: React.FC = ({ const { selectedLine } = useAtomValue(lineState); const currentLine = useCurrentLine(); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const line = useMemo( () => currentLine || selectedLine, diff --git a/src/components/LineBoardWest.test.tsx b/src/components/LineBoardWest.test.tsx index 919aedb27e..a635a34b23 100644 --- a/src/components/LineBoardWest.test.tsx +++ b/src/components/LineBoardWest.test.tsx @@ -11,6 +11,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(), useCurrentStation: jest.fn(), useHasPassStationInRegion: jest.fn(() => false), diff --git a/src/components/LineBoardWest.tsx b/src/components/LineBoardWest.tsx index 1e83d1d442..655d26ae99 100644 --- a/src/components/LineBoardWest.tsx +++ b/src/components/LineBoardWest.tsx @@ -1,17 +1,13 @@ import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo } from 'react'; -import { - type StyleProp, - type TextStyle, - useWindowDimensions, - View, -} from 'react-native'; +import { type StyleProp, type TextStyle, View } from 'react-native'; import type { Line, Station, StationNumber } from '~/@types/graphql'; import { useCurrentLine, useCurrentStation, useHasPassStationInRegion, useIsPassing, + useLandscapeWindowDimensions, useNextStation, usePreviousStation, useStationNumberIndexFunc, @@ -37,7 +33,7 @@ interface Props { } const useBarWidth = () => { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); return useMemo( () => (isTablet ? (dim.width - 72) / 8 : (dim.width - 48) / 8), [dim.width] @@ -314,7 +310,7 @@ const StationNameCell: React.FC = ({ }: StationNameCellProps) => { const { stations: allStations } = useAtomValue(stationState); const isEn = useAtomValue(isEnAtom); - const { width: windowWidth } = useWindowDimensions(); + const { width: windowWidth } = useLandscapeWindowDimensions(); const transferLines = useTransferLinesFromStation(station, { omitJR: true, @@ -416,7 +412,7 @@ const LineBoardWest: React.FC = ({ stations, lineColors }: Props) => { const { selectedLine } = useAtomValue(lineState); const { arrived, approaching } = useAtomValue(stationState); const barWidth = useBarWidth(); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const isPassing = useIsPassing(); const currentLine = useCurrentLine(); diff --git a/src/components/LineBoardYamanotePad.test.tsx b/src/components/LineBoardYamanotePad.test.tsx index dcfa2ed24a..bc843cea12 100644 --- a/src/components/LineBoardYamanotePad.test.tsx +++ b/src/components/LineBoardYamanotePad.test.tsx @@ -11,6 +11,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(), useCurrentTrainType: jest.fn(() => null), useGetLineMark: jest.fn(() => jest.fn(() => null)), diff --git a/src/components/Marquee.tsx b/src/components/Marquee.tsx index 2f757f7464..5d5abecb6a 100644 --- a/src/components/Marquee.tsx +++ b/src/components/Marquee.tsx @@ -12,10 +12,10 @@ import { ScrollView, type StyleProp, StyleSheet, - useWindowDimensions, type View, type ViewStyle, } from 'react-native'; +import { useLandscapeWindowDimensions } from '~/hooks'; type Props = { children: React.ReactElement; @@ -28,7 +28,7 @@ const styles = StyleSheet.create({ const PIXELS_PER_SECOND = 400; const Marquee = ({ children }: Props) => { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const wrapperViewRef = useRef(null); const offsetX = useRef(new Animated.Value(dim.width)).current; diff --git a/src/components/PadArch.tsx b/src/components/PadArch.tsx index d013722abc..99ef8c4301 100644 --- a/src/components/PadArch.tsx +++ b/src/components/PadArch.tsx @@ -1,14 +1,9 @@ import { darken } from 'polished'; import React, { useCallback, useEffect, useMemo, useRef } from 'react'; -import { - Animated, - Easing, - StyleSheet, - useWindowDimensions, - View, -} from 'react-native'; +import { Animated, Easing, StyleSheet, View } from 'react-native'; import { Path, Svg } from 'react-native-svg'; import type { Line, LineNested, Station } from '~/@types/graphql'; +import { useLandscapeWindowDimensions } from '~/hooks'; import { isBusLine } from '~/utils/line'; import { MANY_LINES_THRESHOLD, @@ -411,7 +406,8 @@ const PadArch: React.FC = ({ trainTypeLines, isEn, }: Props) => { - const { width: windowWidth, height: windowHeight } = useWindowDimensions(); + const { width: windowWidth, height: windowHeight } = + useLandscapeWindowDimensions(); // Animated.Value(RN Animated API — Reanimated 4.2 の mapper バグ回避) const bgScale = useRef(new Animated.Value(0.95)).current; diff --git a/src/components/Permitted.tsx b/src/components/Permitted.tsx index c94d0af36b..e340111d19 100644 --- a/src/components/Permitted.tsx +++ b/src/components/Permitted.tsx @@ -4,7 +4,6 @@ import { StackActions, useNavigation } from '@react-navigation/native'; import { File } from 'expo-file-system'; import * as Haptics from 'expo-haptics'; import { addScreenshotListener } from 'expo-screen-capture'; -import * as ScreenOrientation from 'expo-screen-orientation'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import React, { useCallback, @@ -217,7 +216,6 @@ const PermittedLayout: React.FC = ({ children }: Props) => { const base64 = await file.base64(); setScreenShotBase64(base64); setReportModalShow(true); - await ScreenOrientation.unlockAsync(); } catch (err) { captureError(err); } @@ -258,11 +256,7 @@ const PermittedLayout: React.FC = ({ children }: Props) => { url: urlString, type: 'image/png', }; - await ScreenOrientation.unlockAsync().catch(console.error); await Share.open(options).catch(console.warn); - await ScreenOrientation.lockAsync( - ScreenOrientation.OrientationLock.LANDSCAPE - ).catch(console.error); } catch (err) { captureError(err); } @@ -554,10 +548,6 @@ const PermittedLayout: React.FC = ({ children }: Props) => { const handleNewReportModalClose = useCallback(() => { setScreenShotBase64(''); setReportModalShow(false); - - ScreenOrientation.lockAsync( - ScreenOrientation.OrientationLock.LANDSCAPE - ).catch(console.error); }, [setReportModalShow]); const handleReportSend = useCallback( diff --git a/src/components/SelectBoundModal.render.test.tsx b/src/components/SelectBoundModal.render.test.tsx index 78f39486aa..62064898ac 100644 --- a/src/components/SelectBoundModal.render.test.tsx +++ b/src/components/SelectBoundModal.render.test.tsx @@ -17,6 +17,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useBounds: jest.fn(() => ({ bounds: [[{ id: 1, groupId: 1 }], [{ id: 2, groupId: 2 }]], })), diff --git a/src/components/TrainTypeBox.tsx b/src/components/TrainTypeBox.tsx index 7bb82146c7..f7d3b2a545 100644 --- a/src/components/TrainTypeBox.tsx +++ b/src/components/TrainTypeBox.tsx @@ -12,13 +12,13 @@ import { Platform, Animated as RNAnimated, StyleSheet, - useWindowDimensions, View, } from 'react-native'; import type { TrainType } from '~/@types/graphql'; import { FONTS, parenthesisRegexp } from '../constants'; import { useCurrentLine, + useLandscapeWindowDimensions, useLazyPrevious, useNextTrainType, usePrevious, @@ -97,7 +97,7 @@ const TrainTypeBox: React.FC = ({ const fontSizeScale = Math.max(fontSizeScaleRaw, 0.1); const [fadeOutFinished, setFadeOutFinished] = useState(false); - const { width: windowWidth } = useWindowDimensions(); + const { width: windowWidth } = useLandscapeWindowDimensions(); const { headerState } = useAtomValue(navigationState); const { headerTransitionDelay } = useAtomValue(tuningState); const theme = useAtomValue(themeAtom); diff --git a/src/components/TrainTypeBoxE231.test.tsx b/src/components/TrainTypeBoxE231.test.tsx index f73e40a0be..ccdb35829d 100644 --- a/src/components/TrainTypeBoxE231.test.tsx +++ b/src/components/TrainTypeBoxE231.test.tsx @@ -41,6 +41,7 @@ jest.mock('jotai', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(() => ({ id: 1, nameShort: 'テスト', diff --git a/src/components/TransfersYamanote.tsx b/src/components/TransfersYamanote.tsx index 38e9de6f2f..904b696ad3 100644 --- a/src/components/TransfersYamanote.tsx +++ b/src/components/TransfersYamanote.tsx @@ -4,13 +4,16 @@ import { Platform, StyleSheet, TouchableOpacity, - useWindowDimensions, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import type { Line, Station } from '~/@types/graphql'; import { NUMBERING_ICON_SIZE, parenthesisRegexp } from '../constants'; -import { useGetLineMark, useTransferLines } from '../hooks'; +import { + useGetLineMark, + useLandscapeWindowDimensions, + useTransferLines, +} from '../hooks'; import { translate } from '../translation'; import isTablet from '../utils/isTablet'; import { RFValue } from '../utils/rfValue'; @@ -66,7 +69,7 @@ const styles = StyleSheet.create({ const TransfersYamanote: React.FC = ({ onPress, station }: Props) => { const getLineMarkFunc = useGetLineMark(); const lines = useTransferLines(); - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const flexBasis = useMemo(() => dim.width / 3, [dim.width]); diff --git a/src/components/TypeChangeNotify.test.tsx b/src/components/TypeChangeNotify.test.tsx index 537e3769d2..3d8730e6f8 100644 --- a/src/components/TypeChangeNotify.test.tsx +++ b/src/components/TypeChangeNotify.test.tsx @@ -28,6 +28,7 @@ jest.mock('expo-linear-gradient', () => ({ })); jest.mock('~/hooks', () => ({ + useLandscapeWindowDimensions: jest.fn(() => ({ width: 812, height: 375 })), useCurrentLine: jest.fn(() => ({ id: 1, nameShort: 'テスト線', diff --git a/src/components/TypeChangeNotify.tsx b/src/components/TypeChangeNotify.tsx index 5f2a1f1485..e2fb92ee84 100644 --- a/src/components/TypeChangeNotify.tsx +++ b/src/components/TypeChangeNotify.tsx @@ -1,7 +1,7 @@ import { LinearGradient } from 'expo-linear-gradient'; import { useAtomValue } from 'jotai'; import React, { useCallback, useMemo } from 'react'; -import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native'; +import { Platform, StyleSheet, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { type Line, StopCondition, type TrainType } from '~/@types/graphql'; import { parenthesisRegexp } from '~/constants'; @@ -9,6 +9,7 @@ import { useCurrentLine, useCurrentStation, useCurrentTrainType, + useLandscapeWindowDimensions, useNextTrainType, } from '~/hooks'; import { RFValue } from '~/utils/rfValue'; @@ -174,7 +175,7 @@ const styles = StyleSheet.create({ }); const useBarWidth = () => { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); return Math.max(0, dim.width / 2 - edgeOffset); }; @@ -206,7 +207,7 @@ const EastBars = React.memo(function EastBars({ getBarGradient?: ColorGradientFn; getBoxGradient?: ColorGradientFn; }) { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const barWidth = useBarWidth(); const rightBarWidth = Math.max(0, barWidth - barTerminalWidth); @@ -445,7 +446,7 @@ const OdakyuBars = React.memo(function OdakyuBars({ trainType: TrainType; nextTrainType: TrainType; }) { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const barWidth = useBarWidth(); const rightBarWidth = Math.max(0, barWidth - odakyuTerminalWidth); @@ -714,7 +715,7 @@ const SaikyoBars = React.memo(function SaikyoBars({ trainType: TrainType; nextTrainType: TrainType; }) { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const barWidth = useBarWidth(); const rightBarWidth = Math.max(0, barWidth - barTerminalWidth); @@ -938,7 +939,7 @@ const JOBars = React.memo(function JOBars({ trainType: TrainType; nextTrainType: TrainType; }) { - const dim = useWindowDimensions(); + const dim = useLandscapeWindowDimensions(); const barWidth = useBarWidth(); const rightBarWidth = Math.max(0, barWidth - barTerminalWidth); diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 4ae4d7d3d7..c127ef357b 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -37,10 +37,10 @@ export { useIsNextLastStop } from './useIsNextLastStop'; export { useIsPassing } from './useIsPassing'; export { useIsTerminus } from './useIsTerminus'; export { useKeepAwake } from './useKeepAwake'; +export { useLandscapeWindowDimensions } from './useLandscapeWindowDimensions'; export { useLazyPrevious } from './useLazyPrevious'; export { useLineSelection } from './useLineSelection'; export { useLocationPermissionsGranted } from './useLocationPermissionsGranted'; -export { useLockLandscapeOnActive } from './useLockLandscapeOnActive'; export { useLoopLine } from './useLoopLine'; export { useLoopLineBound } from './useLoopLineBound'; export { useNearestStation } from './useNearestStation'; diff --git a/src/hooks/useLandscapeWindowDimensions.ts b/src/hooks/useLandscapeWindowDimensions.ts new file mode 100644 index 0000000000..19347cb447 --- /dev/null +++ b/src/hooks/useLandscapeWindowDimensions.ts @@ -0,0 +1,13 @@ +import { useWindowDimensions } from 'react-native'; + +// Main 画面は常に横長レイアウト前提だが、端末側の回転ロック ON 等で物理的に +// portrait のままだと useWindowDimensions が縦寸を返してしまい、Main 配下の +// レイアウトが画面いっぱいに広がらない。長辺を width / 短辺を height として返す +// ことで、Main.tsx 側の 90deg 回転ラッパーと矛盾しないサイズを子に渡す。 +export const useLandscapeWindowDimensions = () => { + const { width, height } = useWindowDimensions(); + return { + width: Math.max(width, height), + height: Math.min(width, height), + }; +}; diff --git a/src/hooks/useLockLandscapeOnActive.test.tsx b/src/hooks/useLockLandscapeOnActive.test.tsx deleted file mode 100644 index 451bfab01f..0000000000 --- a/src/hooks/useLockLandscapeOnActive.test.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { act, render } from '@testing-library/react-native'; -import * as ScreenOrientation from 'expo-screen-orientation'; -import { createStore, Provider } from 'jotai'; -import type React from 'react'; -import { AppState, Text } from 'react-native'; -import reportModalVisibleAtom from '~/store/atoms/reportModal'; -import { useLockLandscapeOnActive } from './useLockLandscapeOnActive'; - -jest.mock('expo-screen-orientation', () => ({ - __esModule: true, - lockAsync: jest.fn().mockResolvedValue(undefined), - OrientationLock: { - LANDSCAPE: 'LANDSCAPE', - }, -})); - -const mockAddEventListener = jest.fn(); -const mockRemove = jest.fn(); - -jest.spyOn(AppState, 'addEventListener').mockImplementation((_, handler) => { - mockAddEventListener(handler); - return { remove: mockRemove }; -}); - -const TestComponent: React.FC = () => { - useLockLandscapeOnActive(); - return Test; -}; - -describe('useLockLandscapeOnActive', () => { - let store: ReturnType; - - beforeEach(() => { - store = createStore(); - jest.clearAllMocks(); - }); - - it('reportModalが表示されていない時、AppStateがactiveになるとlockAsyncが呼ばれる', () => { - store.set(reportModalVisibleAtom, false); - - render( - - - - ); - - expect(mockAddEventListener).toHaveBeenCalled(); - const handler = mockAddEventListener.mock.calls[0][0]; - - act(() => { - handler('active'); - }); - - expect(ScreenOrientation.lockAsync).toHaveBeenCalledWith( - ScreenOrientation.OrientationLock.LANDSCAPE - ); - }); - - it('reportModalが表示されている時、AppStateがactiveになってもlockAsyncが呼ばれない', () => { - store.set(reportModalVisibleAtom, true); - - render( - - - - ); - - expect(mockAddEventListener).toHaveBeenCalled(); - const handler = mockAddEventListener.mock.calls[0][0]; - - act(() => { - handler('active'); - }); - - expect(ScreenOrientation.lockAsync).not.toHaveBeenCalled(); - }); - - it('AppStateがactive以外の場合はlockAsyncが呼ばれない', () => { - store.set(reportModalVisibleAtom, false); - - render( - - - - ); - - const handler = mockAddEventListener.mock.calls[0][0]; - - act(() => { - handler('background'); - }); - - expect(ScreenOrientation.lockAsync).not.toHaveBeenCalled(); - }); - - it('アンマウント時にリスナーが削除される', () => { - const { unmount } = render( - - - - ); - - expect(AppState.addEventListener).toHaveBeenCalled(); - - unmount(); - - expect(mockRemove).toHaveBeenCalled(); - }); - - it('reportModalVisibleAtomが変更されるとリスナーが再登録される', () => { - store.set(reportModalVisibleAtom, false); - - const { rerender } = render( - - - - ); - - expect(mockAddEventListener).toHaveBeenCalledTimes(1); - - act(() => { - store.set(reportModalVisibleAtom, true); - }); - - rerender( - - - - ); - - // 依存配列が変更されたのでリスナーが再登録される - expect(mockRemove).toHaveBeenCalled(); - }); -}); diff --git a/src/hooks/useLockLandscapeOnActive.ts b/src/hooks/useLockLandscapeOnActive.ts deleted file mode 100644 index 2abe64df1c..0000000000 --- a/src/hooks/useLockLandscapeOnActive.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as ScreenOrientation from 'expo-screen-orientation'; -import { useAtomValue } from 'jotai'; -import { useEffect } from 'react'; -import { AppState } from 'react-native'; -import reportModalVisibleAtom from '~/store/atoms/reportModal'; - -export const useLockLandscapeOnActive = () => { - const isReportModalVisible = useAtomValue(reportModalVisibleAtom); - - useEffect(() => { - const sub = AppState.addEventListener('change', (state) => { - if (state === 'active' && !isReportModalVisible) { - ScreenOrientation.lockAsync( - ScreenOrientation.OrientationLock.LANDSCAPE - ).catch(console.warn); - } - }); - - return () => sub.remove(); - }, [isReportModalVisible]); -}; diff --git a/src/hooks/useQuickActions.ts b/src/hooks/useQuickActions.ts index 320e0ce056..66025cf1a9 100644 --- a/src/hooks/useQuickActions.ts +++ b/src/hooks/useQuickActions.ts @@ -1,6 +1,5 @@ import { CommonActions } from '@react-navigation/native'; import * as QuickActions from 'expo-quick-actions'; -import * as ScreenOrientation from 'expo-screen-orientation'; import { useAtomValue, useSetAtom } from 'jotai'; import { useEffect } from 'react'; import { Platform } from 'react-native'; @@ -19,8 +18,6 @@ const navigateToSelectLine = () => { return false; } - ScreenOrientation.unlockAsync().catch(console.error); - navigationRef.dispatch( CommonActions.reset({ index: 0, diff --git a/src/hooks/useScale.ts b/src/hooks/useScale.ts index 1dcafaa42e..86692043a9 100644 --- a/src/hooks/useScale.ts +++ b/src/hooks/useScale.ts @@ -1,11 +1,12 @@ import { useCallback } from 'react'; -import { PixelRatio, useWindowDimensions } from 'react-native'; +import { PixelRatio } from 'react-native'; +import { useLandscapeWindowDimensions } from './useLandscapeWindowDimensions'; const standardWidth = 375.0; const standardHeight = 667.0; export const useScale = () => { - const { width: myWidth, height: myHeight } = useWindowDimensions(); + const { width: myWidth, height: myHeight } = useLandscapeWindowDimensions(); const widthScale = useCallback( (dimension: number): number => diff --git a/src/screens/Main.tsx b/src/screens/Main.tsx index de27ecefd6..e1a37c216f 100644 --- a/src/screens/Main.tsx +++ b/src/screens/Main.tsx @@ -1,7 +1,6 @@ import { useLazyQuery } from '@apollo/client/react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import * as Location from 'expo-location'; -import * as ScreenOrientation from 'expo-screen-orientation'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import React, { useCallback, @@ -10,7 +9,16 @@ import React, { useRef, useState, } from 'react'; -import { Alert, Linking, Platform, Pressable, StyleSheet } from 'react-native'; +import { + Alert, + Linking, + Platform, + Pressable, + StyleSheet, + useWindowDimensions, + View, + type ViewStyle, +} from 'react-native'; import { isClip } from 'react-native-app-clip'; import { LineType, @@ -29,7 +37,6 @@ import { useCurrentTrainType, useFirstStop, useKeepAwake, - useLockLandscapeOnActive, useLoopLine, useNextStation, useRefreshLeftStations, @@ -95,7 +102,6 @@ type GetStationTrainTypesVariables = { }; const MainScreen: React.FC = () => { - const [isRotated, setIsRotated] = useState(false); const [isSelectBoundModalOpen, setIsSelectBoundModalOpen] = useState(false); const theme = useAtomValue(themeAtom); @@ -114,9 +120,26 @@ const MainScreen: React.FC = () => { const trainType = useCurrentTrainType(); const nextStation = useNextStation(); + const { width: windowWidth, height: windowHeight } = useWindowDimensions(); + + // OS 側で orientation lock せず、物理的に portrait のときはコンテンツ側を 90deg + // 回転して横長レイアウトを維持する。端末の回転ロック ON でも横表示を保てる。 + const landscapeKeepStyle = useMemo(() => { + if (windowHeight <= windowWidth) { + return StyleSheet.absoluteFillObject; + } + return { + position: 'absolute', + top: (windowHeight - windowWidth) / 2, + left: (windowWidth - windowHeight) / 2, + width: windowHeight, + height: windowWidth, + transform: [{ rotate: '90deg' }], + }; + }, [windowWidth, windowHeight]); + useSimulationMode(); useFirstStop(true); - useLockLandscapeOnActive(); useTelemetrySender(true); useConsoleTelemetry(); @@ -155,9 +178,6 @@ const MainScreen: React.FC = () => { const handleCloseSelectBoundModal = useCallback(() => { setIsSelectBoundModalOpen(false); - ScreenOrientation.lockAsync( - ScreenOrientation.OrientationLock.LANDSCAPE - ).catch(console.error); }, []); const handleTrainTypeSelect = useCallback( @@ -249,30 +269,6 @@ const MainScreen: React.FC = () => { }, [selectedDirection]); useEffect(() => { - const lockOrientationAsync = async () => { - try { - await ScreenOrientation.lockAsync( - ScreenOrientation.OrientationLock.LANDSCAPE - ); - } catch (_e) { - // ignore and proceed - } finally { - // fail-open to avoid blocking UI even if locking fails - setIsRotated(true); - } - }; - lockOrientationAsync(); - return () => { - ScreenOrientation.unlockAsync().catch(console.error); - }; - }, []); - - useEffect(() => { - // 横画面になるのを待たないと2回スクリーンロックがかかる - if (!isRotated) { - return; - } - if ( stationsFromCurrentStation.some( (s) => s.line?.lineType === LineType.Subway @@ -306,16 +302,11 @@ const MainScreen: React.FC = () => { alertAsync(); } - }, [stationsFromCurrentStation, isRotated]); + }, [stationsFromCurrentStation]); const isHoliday = useMemo(() => getIsHoliday(new Date()), []); useEffect(() => { - // 横画面になるのを待たないと2回スクリーンロックがかかる - if (!isRotated) { - return; - } - const alertAsync = async () => { // 土休日通過 const holidayNoticeDismissed = await AsyncStorage.getItem( @@ -396,7 +387,7 @@ const MainScreen: React.FC = () => { } }; alertAsync(); - }, [stationsFromCurrentStation, isHoliday, isRotated]); + }, [stationsFromCurrentStation, isHoliday]); const transferLines = useTransferLines(); @@ -455,11 +446,6 @@ const MainScreen: React.FC = () => { }, []); useEffect(() => { - // 横画面になるのを待たないと2回スクリーンロックがかかる - if (!isRotated) { - return; - } - const f = async (): Promise => { const warningDismissed = await AsyncStorage.getItem( ASYNC_STORAGE_KEYS.ALWAYS_PERMISSION_NOT_GRANTED_WARNING_DISMISSED @@ -549,7 +535,7 @@ const MainScreen: React.FC = () => { } }; f(); - }, [isRotated]); + }, []); const changeOperatingLine = useCallback( async (selectedStation: Station) => { @@ -558,8 +544,6 @@ const MainScreen: React.FC = () => { return; } - await ScreenOrientation.unlockAsync().catch(console.error); - setIsSelectBoundModalOpen(true); const { data } = await fetchStationsByLineId({ @@ -668,31 +652,31 @@ const MainScreen: React.FC = () => { } }, [bottomState, handleTransferPress, hasTerminus, theme, transferStation]); - if (!isRotated) { - return null; - } - if (isLEDTheme) { return ( - <> +
- + ); } return ( <> - -
- {inner} - + + +
+ {inner} + + + {isDevApp && devOverlayEnabled && } + { null } /> - - {isDevApp && devOverlayEnabled && } ); }; diff --git a/src/screens/SelectLineScreen.render.test.tsx b/src/screens/SelectLineScreen.render.test.tsx index ec7a4f8cd5..134b91cfa8 100644 --- a/src/screens/SelectLineScreen.render.test.tsx +++ b/src/screens/SelectLineScreen.render.test.tsx @@ -39,7 +39,6 @@ jest.mock('~/lib/gql', () => ({ })); jest.mock('expo-screen-orientation', () => ({ - unlockAsync: jest.fn().mockResolvedValue(undefined), Orientation: { PORTRAIT_UP: 1, PORTRAIT_DOWN: 2, @@ -587,14 +586,5 @@ describe('SelectLineScreen', () => { expect(useStationsCache).toHaveBeenCalledWith(null); }); - - it('ScreenOrientation.unlockAsync が呼ばれる', () => { - setupDefaults(); - - render(); - - const ScreenOrientation = require('expo-screen-orientation'); - expect(ScreenOrientation.unlockAsync).toHaveBeenCalled(); - }); }); }); diff --git a/src/screens/SelectLineScreen.tsx b/src/screens/SelectLineScreen.tsx index 78d56e3da5..4783c1ee19 100644 --- a/src/screens/SelectLineScreen.tsx +++ b/src/screens/SelectLineScreen.tsx @@ -1,4 +1,3 @@ -import * as ScreenOrientation from 'expo-screen-orientation'; import { Orientation } from 'expo-screen-orientation'; import { useAtom, useAtomValue } from 'jotai'; import React, { @@ -142,11 +141,6 @@ const SelectLineScreen = () => { setNavigationState, ]); - // --- 画面回転ロック解除 --- - useEffect(() => { - ScreenOrientation.unlockAsync().catch(console.error); - }, []); - // --- RefreshControl tintColor ワークアラウンド --- const [refreshTintColor, setRefreshTintColor] = useState< string | undefined