Skip to content
Merged

canary #7162

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,12 @@ android {
dimension "environment"
applicationId "me.tinykitten.trainlcd.dev"
versionNameSuffix "-dev"
versionCode 100000833
versionCode 100000835
versionName "10.17.0"
}
prod {
dimension "environment"
versionCode 100000833
versionCode 100000835
versionName "10.17.0"
}
// ストア配信する dev (Canary) と applicationId を分けた、ローカル検証専用のフレーバー。
Expand All @@ -186,7 +186,7 @@ android {
dimension "environment"
applicationId "me.tinykitten.trainlcd.local"
versionNameSuffix "-local"
versionCode 100000833
versionCode 100000835
versionName "10.17.0"
}
}
Expand Down
6 changes: 3 additions & 3 deletions android/wearable/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ android {
dimension = "environment"
applicationIdSuffix = ".dev"
versionNameSuffix = "-dev"
versionCode = 100000834
versionCode = 100000836
versionName = "10.17.0"
}
create("prod") {
dimension = "environment"
versionCode = 100000834
versionCode = 100000836
versionName = "10.17.0"
}
// :app の local フレーバーと対になるローカル検証専用フレーバー。Wear の Data Layer は
Expand All @@ -100,7 +100,7 @@ android {
dimension = "environment"
applicationIdSuffix = ".local"
versionNameSuffix = "-local"
versionCode = 100000834
versionCode = 100000836
versionName = "10.17.0"
}
}
Expand Down
4 changes: 2 additions & 2 deletions app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default {
userInterfaceStyle: 'automatic',
// Expo SDK 57 の各モジュール(expo / expo-modules-core ほか)は podspec で iOS 16.4 以上を要求する
deploymentTarget: '16.4',
buildNumber: '2946',
buildNumber: '2947',
scheme: IS_DEV ? 'CanaryTrainLCD' : 'ProdTrainLCD',
bundleIdentifier: IS_DEV
? 'me.tinykitten.trainlcd.dev'
Expand All @@ -78,7 +78,7 @@ export default {
? 'me.tinykitten.trainlcd.dev'
: 'me.tinykitten.trainlcd',
permissions: [],
versionCode: 100000833,
versionCode: 100000835,
},
owner: 'trainlcd',
experiments: {
Expand Down
6 changes: 6 additions & 0 deletions docs/location-simulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ npm run gpx:generate -- \
ごとの速度を実ダイヤで較正した到着時間推定から出る。アプリのオートモード
(`useSimulationMode`) も同じ見込みで走るので、GPX・オートモード・ETA の時間がそろう。

オートモードがこの見込みで走るのは、Worker の `/config/remote` が
`auto_mode_estimated_enabled: true` を配信しているときだけ。`false`・未配信・取得失敗の
ときは、`model` を渡さない従来の値 (`Legacy`) で区間の最高速度を出して走る。値は Worker の
KV `config:remote` に入れる。`true` でも StationAPI が `model` を知らずにエラーを返したときは、
`Legacy` に戻して走る。

- 停車駅から次の停車駅までの時間は「次の停車駅の到着 − この駅の出発」。推定では停まるが
GPX では通過する駅 (平日運転の駅を休日に走る、`--skip` など) は、その駅の停車時間を
走行から引く。
Expand Down
36 changes: 18 additions & 18 deletions ios/TrainLCD.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2562,7 +2562,7 @@
CODE_SIGN_ENTITLEMENTS = ProdTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Prod/Info.plist;
Expand Down Expand Up @@ -2602,7 +2602,7 @@
CODE_SIGN_ENTITLEMENTS = ProdTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Prod/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = TrainLCD;
Expand Down Expand Up @@ -2661,7 +2661,7 @@
CODE_SIGN_ENTITLEMENTS = TrainLCD/trainlcd.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand Down Expand Up @@ -2768,7 +2768,7 @@
CODE_SIGN_ENTITLEMENTS = TrainLCD/trainlcd.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand Down Expand Up @@ -2849,7 +2849,7 @@
CODE_SIGN_ENTITLEMENTS = CanaryTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Dev/Info.plist;
Expand Down Expand Up @@ -2889,7 +2889,7 @@
CODE_SIGN_ENTITLEMENTS = CanaryTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Dev/Info.plist;
Expand Down Expand Up @@ -3101,7 +3101,7 @@
CODE_SIGN_ENTITLEMENTS = RideSessionActivity/CanaryRideSessionActivity.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3153,7 +3153,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3204,7 +3204,7 @@
CODE_SIGN_ENTITLEMENTS = WatchWidget/ProdWatchWidget.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3262,7 +3262,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3313,7 +3313,7 @@
CODE_SIGN_ENTITLEMENTS = WatchWidget/CanaryWatchWidget.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3370,7 +3370,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3419,7 +3419,7 @@
CODE_SIGN_ENTITLEMENTS = RideSessionActivity/ProdRideSessionActivity.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3471,7 +3471,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3690,7 +3690,7 @@
CODE_SIGN_ENTITLEMENTS = ProdAppClip/ProdAppClip.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down Expand Up @@ -3746,7 +3746,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down Expand Up @@ -3796,7 +3796,7 @@
CODE_SIGN_ENTITLEMENTS = CanaryAppClip/CanaryAppClip.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down Expand Up @@ -3854,7 +3854,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2946;
CURRENT_PROJECT_VERSION = 2947;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down
11 changes: 11 additions & 0 deletions src/hooks/useAutoModeEstimatedEnabled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useSyncExternalStore } from 'react';
import {
isAutoModeEstimatedEnabled,
subscribeRemoteConfig,
} from '~/lib/remoteConfig';

// オートモードの走らせ方(auto_mode_estimated_enabled)のリアクティブ版。
// setupRemoteConfig は起動時に非同期で完了するため、同期読みだけではコールドスタート時の
// キャッシュ更新に追従できない。useAIAgentFeatureEnabled と同じくキャッシュ更新を購読する。
export const useAutoModeEstimatedEnabled = (): boolean =>
useSyncExternalStore(subscribeRemoteConfig, isAutoModeEstimatedEnabled);
74 changes: 74 additions & 0 deletions src/hooks/useSimulationMode.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
StopCondition,
} from '~/@types/graphql';
import { YAMANOTE_LINE_ID } from '~/constants';
import { useAutoModeEstimatedEnabled } from '~/hooks/useAutoModeEstimatedEnabled';
import * as useCurrentTrainTypeModule from '~/hooks/useCurrentTrainType';
import { useGraphQLQuery } from '~/hooks/useGraphQLQuery';
import { useLoopLine } from '~/hooks/useLoopLine';
Expand Down Expand Up @@ -61,6 +62,12 @@ jest.mock('~/store/atoms/location', () => ({
locationAtom: { toString: () => 'locationAtom' },
}));

// オートモードの走らせ方のフラグ(auto_mode_estimated_enabled)。各テストの既定は
// 到着時間推定の見込みで走る側(true)で、従来の値で走る側は個別に false にする
jest.mock('~/hooks/useAutoModeEstimatedEnabled', () => ({
useAutoModeEstimatedEnabled: jest.fn(() => true),
}));

jest.mock('~/hooks/useLoopLine', () => ({
useLoopLine: jest.fn(() => ({
isLoopLine: false,
Expand Down Expand Up @@ -258,6 +265,7 @@ describe('useSimulationMode', () => {
// 各テストは非ループ線を前提とする。ループ線テストで上書きした実装が
// 後続テストへ漏れないよう毎回明示的にリセットする。
(useLoopLine as jest.Mock).mockReturnValue({ isLoopLine: false });
(useAutoModeEstimatedEnabled as jest.Mock).mockReturnValue(true);

jest
.spyOn(useCurrentTrainTypeModule, 'useCurrentTrainType')
Expand Down Expand Up @@ -1805,6 +1813,72 @@ describe('useSimulationMode', () => {
);
});

it('auto_mode_estimated_enabled が false なら、model: Estimated を引かずに従来の値で走る', () => {
(useAutoModeEstimatedEnabled as jest.Mock).mockReturnValue(false);
const stations = timedStations();
setupAtomMocks(
{ station: stations[0], stations, selectedDirection: 'INBOUND' },
{ autoModeEnabled: true }
);
// 従来の問い合わせは見込みのフィールドを選ばないので、区間の最高速度だけが返る
mockTrainRoute(stations, { accel: 0.7, decel: 0.9 });
const generateSpy = jest.spyOn(
trainSpeedModule,
'generateTrainSpeedProfile'
);

renderHook(() => useSimulationMode(), {
wrapper: ({ children }) => <Provider>{children}</Provider>,
});

expect(useGraphQLQuery).toHaveBeenCalledWith(
GET_ESTIMATED_TRAIN_ROUTE,
expect.objectContaining({ skip: true })
);
expect(useGraphQLQuery).toHaveBeenCalledWith(
GET_TRAIN_ROUTE,
expect.objectContaining({ skip: false })
);
// 見込みではなく区間の最高速度で速度プロファイルを作る
expect(generateSpy).toHaveBeenCalledWith(
expect.objectContaining({ maxSpeed: 30 })
);
});

it('auto_mode_estimated_enabled が false なら、乗換経路も従来の問い合わせで引く', () => {
(useAutoModeEstimatedEnabled as jest.Mock).mockReturnValue(false);
const withTrainType = (station: Station, groupId: number): Station => ({
...station,
trainType: { groupId } as Station['trainType'],
});
const stations = [
withTrainType(mockStation(9930138, 9930138, 35.76, 139.63, 99301), 7),
withTrainType(mockStation(9930128, 1130208, 35.69, 139.7, 99301), 7),
withTrainType(mockStation(1132104, 1130208, 35.69, 139.7, 11321), 170),
withTrainType(
mockStation(1132103, 1130205, 35.658, 139.701, 11321),
170
),
];
setupAtomMocks(
{ station: stations[0], stations, selectedDirection: 'INBOUND' },
{ autoModeEnabled: true }
);

renderHook(() => useSimulationMode(), {
wrapper: ({ children }) => <Provider>{children}</Provider>,
});

expect(useGraphQLQuery).toHaveBeenCalledWith(
GET_ESTIMATED_CONNECTED_TRAIN_ROUTE,
expect.objectContaining({ skip: true })
);
expect(useGraphQLQuery).toHaveBeenCalledWith(
GET_CONNECTED_TRAIN_ROUTE,
expect.objectContaining({ skip: false })
);
});

it('model: Estimated の問い合わせがエラーなら、従来の問い合わせの値で走る', () => {
const stations = timedStations();
setupAtomMocks(
Expand Down
Loading
Loading