fix(watch): corrige applicationId et nettoie la config de build montre

Répare la régression de packaging introduite par le reset/remerge de
develop : l'APK montre était packagée avec com.gametime.app au lieu de
com.gametime.watch (namespace correct mais applicationId hérité du
téléphone), ce qui cassait la détection du bridge. Aligne applicationId
sur com.gametime.watch, nettoie la config de signing partagée sur les
deux modules android/app et watch_app/android/app, et ajuste
use_cases + watch_session_screen en conséquence.

Validé : APK montre release package = com.gametime.watch, même SHA-256
de certificat sur les deux APKs (70cc69e8...45c7815), tests use_cases et
watch_session_screen OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 12:18:48 +02:00
parent 6e110a9fb9
commit 2e40694de4
6 changed files with 192 additions and 60 deletions

View File

@ -1,9 +1,32 @@
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("dev.flutter.flutter-gradle-plugin")
}
val sharedSigningPropertiesFile =
rootProject.projectDir.parentFile.parentFile.resolve("android/key.properties")
val sharedSigningProperties =
Properties().also { properties ->
check(sharedSigningPropertiesFile.isFile) {
"Shared signing config missing: ${sharedSigningPropertiesFile.absolutePath}"
}
sharedSigningPropertiesFile.inputStream().use(properties::load)
}
fun requiredSharedSigningProperty(name: String): String =
sharedSigningProperties.getProperty(name)?.takeIf { it.isNotBlank() }
?: error("Shared signing property '$name' missing in ${sharedSigningPropertiesFile.absolutePath}")
val sharedSigningStoreFile =
sharedSigningPropertiesFile.parentFile.resolve(requiredSharedSigningProperty("storeFile"))
check(sharedSigningStoreFile.isFile) {
"Shared signing keystore missing: ${sharedSigningStoreFile.absolutePath}"
}
android {
namespace = "com.gametime.watch"
compileSdk = flutter.compileSdkVersion
@ -15,16 +38,25 @@ android {
}
defaultConfig {
applicationId = "com.gametime.app"
applicationId = "com.gametime.watch"
minSdk = 30
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
signingConfigs {
create("sharedLocal") {
storeFile = sharedSigningStoreFile
storePassword = requiredSharedSigningProperty("storePassword")
keyAlias = requiredSharedSigningProperty("keyAlias")
keyPassword = requiredSharedSigningProperty("keyPassword")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("debug")
signingConfig = signingConfigs.getByName("sharedLocal")
}
}
}

View File

@ -679,10 +679,6 @@ final class _ActiveContent extends StatelessWidget {
_SmallLabel(dominantLabel),
const SizedBox(height: 2),
_DominantValue(dominantValue),
if (_heartRateLabel(state.sensorSample) case final heartRate?) ...[
const SizedBox(height: 1),
_LiveHeartRateLine(heartRate),
],
if (timer != null) ...[
const SizedBox(height: 3),
_TimerToggleButton(
@ -796,10 +792,6 @@ final class _ManualScoreContent extends StatelessWidget {
? const _PendingDot()
: const SizedBox.shrink(),
),
if (_heartRateLabel(state.sensorSample) case final heartRate?) ...[
const SizedBox(height: 1),
_LiveHeartRateLine(heartRate),
],
const SizedBox(height: 5),
if (timer != null)
_CompactTimerLine(
@ -942,33 +934,6 @@ final class _PendingDot extends StatelessWidget {
}
}
final class _LiveHeartRateLine extends StatelessWidget {
const _LiveHeartRateLine(this.label);
final String label;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.favorite, size: 11, color: Color(0xFFD72638)),
const SizedBox(width: 3),
Text(
label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: const Color(0xFFA7ADBA),
fontSize: 10,
),
),
],
);
}
}
final class _RestContent extends StatelessWidget {
const _RestContent({required this.state, required this.onTogglePause});

View File

@ -212,7 +212,7 @@ void main() {
viewModel.dispose();
});
testWidgets('shows live heart rate on session and telemetry on stats page', (
testWidgets('shows telemetry only on stats page when available', (
tester,
) async {
final client = _FakeNativeWatchBridgeClient();
@ -245,7 +245,7 @@ void main() {
);
await tester.pump();
expect(find.text('142 bpm'), findsOneWidget);
expect(find.text('142 bpm'), findsNothing);
expect(find.byTooltip('Stats'), findsOneWidget);
await tester.drag(
@ -261,6 +261,7 @@ void main() {
expect(find.text('Stats'), findsOneWidget);
expect(find.text('FC'), findsOneWidget);
expect(find.text('142 bpm'), findsOneWidget);
expect(find.text('840 m'), findsOneWidget);
expect(find.text('186 kcal'), findsOneWidget);