diff --git a/lib/core/config/app_config.dart b/lib/core/config/app_config.dart index a75bc96..98baefc 100644 --- a/lib/core/config/app_config.dart +++ b/lib/core/config/app_config.dart @@ -11,11 +11,10 @@ import 'package:flutter/foundation.dart'; class AppConfig { const AppConfig._(); - /// 真机默认使用的开发机局域网地址。 + /// 开发调试默认服务地址,当前直接指向公网。 /// - /// 这个地址跟着电脑所在的网络走,换网络后要用 - /// `ipconfig getifaddr en0` 重新确认。默认值只改这一行。 - static const String devHostBaseUrl = 'http://192.168.31.187:8081'; + /// 需要切换局域网联调时只改这一行,地址不要带结尾斜杠。 + static const String devHostBaseUrl = 'http://39.162.50.99:8081'; /// 本机后端地址:通过 `adb reverse tcp:8081 tcp:8081` 映射到开发机, /// 探测可达时 App 直连本机服务;不可达时回落到公网地址。 @@ -38,7 +37,7 @@ class AppConfig { static const List _probeCandidates = [ lanBaseUrl, devHostBaseUrl, - publicBaseUrl, + if (devHostBaseUrl != publicBaseUrl) publicBaseUrl, ]; /// Build-time server URL supplied through `--dart-define=API_BASE_URL`. diff --git a/lib/core/widgets/app_bottom_nav.dart b/lib/core/widgets/app_bottom_nav.dart index 8905618..9081ebb 100644 --- a/lib/core/widgets/app_bottom_nav.dart +++ b/lib/core/widgets/app_bottom_nav.dart @@ -43,37 +43,35 @@ class AppBottomNav extends StatelessWidget { @override Widget build(BuildContext context) { + final bar = Container( + key: barKey, + height: AppDimens.navHeight, + decoration: BoxDecoration( + color: dark ? Colors.black : backgroundColor.withValues(alpha: 0.95), + border: Border( + top: BorderSide(color: dark ? Colors.white12 : AppColors.border), + ), + ), + child: Row( + children: [ + for (final item in items) + _NavDestination( + item: item, + unselectedColor: dark ? Colors.white70 : AppColors.navUnselected, + ), + ], + ), + ); + if (dark) { + return ColoredBox( + color: Colors.black, + child: SafeArea(top: false, child: bar), + ); + } return ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), - child: SafeArea( - top: false, - child: Container( - key: barKey, - height: AppDimens.navHeight, - decoration: BoxDecoration( - color: dark - ? const Color(0xE6000000) - : backgroundColor.withValues(alpha: 0.95), - border: Border( - top: BorderSide( - color: dark ? Colors.white12 : AppColors.border, - ), - ), - ), - child: Row( - children: [ - for (final item in items) - _NavDestination( - item: item, - unselectedColor: dark - ? Colors.white70 - : AppColors.navUnselected, - ), - ], - ), - ), - ), + child: SafeArea(top: false, child: bar), ), ); } diff --git a/test/config/server_endpoint_test.dart b/test/config/server_endpoint_test.dart index 2348717..524eede 100644 --- a/test/config/server_endpoint_test.dart +++ b/test/config/server_endpoint_test.dart @@ -62,8 +62,8 @@ void main() { ); }); - test('should_use_the_configured_lan_address_for_device_default', () { - expect(AppConfig.devHostBaseUrl, 'http://192.168.31.187:8081'); + test('should_use_the_configured_public_address_for_device_default', () { + expect(AppConfig.devHostBaseUrl, 'http://39.162.50.99:8081'); }); test('should_skip_probe_when_compiled_override_is_set', () async { @@ -111,11 +111,7 @@ void main() { }, ); - expect(attempts, [ - AppConfig.lanBaseUrl, - AppConfig.devHostBaseUrl, - AppConfig.publicBaseUrl, - ]); + expect(attempts, [AppConfig.lanBaseUrl, AppConfig.devHostBaseUrl]); expect(AppConfig.apiBaseUrl, AppConfig.publicBaseUrl); }); @@ -133,7 +129,7 @@ void main() { attempts.add(baseUrl); active++; if (active > maxActive) maxActive = active; - if (active == 3) allStarted.complete(); + if (active == 2) allStarted.complete(); await allStarted.future; active--; return baseUrl == AppConfig.lanBaseUrl || @@ -143,17 +139,13 @@ void main() { await probing.timeout(const Duration(seconds: 1)); - expect(attempts, [ - AppConfig.lanBaseUrl, - AppConfig.devHostBaseUrl, - AppConfig.publicBaseUrl, - ]); - expect(maxActive, 3); + expect(attempts, [AppConfig.lanBaseUrl, AppConfig.devHostBaseUrl]); + expect(maxActive, 2); expect(AppConfig.apiBaseUrl, AppConfig.lanBaseUrl); }, ); - test('should_probe_loopback_dev_host_then_public_in_order', () async { + test('should_probe_loopback_then_public_in_order', () async { final attempts = []; await AppConfig.probeAndApplyBaseUrl( @@ -164,11 +156,7 @@ void main() { }, ); - expect(attempts, [ - AppConfig.lanBaseUrl, - AppConfig.devHostBaseUrl, - AppConfig.publicBaseUrl, - ]); + expect(attempts, [AppConfig.lanBaseUrl, AppConfig.devHostBaseUrl]); expect(AppConfig.apiBaseUrl, AppConfig.publicBaseUrl); }); @@ -183,11 +171,7 @@ void main() { }, ); - expect(attempts, [ - AppConfig.lanBaseUrl, - AppConfig.devHostBaseUrl, - AppConfig.publicBaseUrl, - ]); + expect(attempts, [AppConfig.lanBaseUrl, AppConfig.devHostBaseUrl]); expect(AppConfig.apiBaseUrl, AppConfig.devHostBaseUrl); }); @@ -203,12 +187,7 @@ void main() { }, ); - expect(attempts, [ - custom, - AppConfig.lanBaseUrl, - AppConfig.devHostBaseUrl, - AppConfig.publicBaseUrl, - ]); + expect(attempts, [custom, AppConfig.lanBaseUrl, AppConfig.devHostBaseUrl]); expect(AppConfig.apiBaseUrl, custom); }); diff --git a/test/home/app_bottom_nav_test.dart b/test/home/app_bottom_nav_test.dart index df8a59e..f019a17 100644 --- a/test/home/app_bottom_nav_test.dart +++ b/test/home/app_bottom_nav_test.dart @@ -82,4 +82,68 @@ void main() { await tester.tap(find.byKey(const Key('tab-theater'))); expect(theaterTaps, 1); }); + + testWidgets('should_fill_dark_bottom_safe_area_with_black_background', ( + tester, + ) async { + const barKey = Key('dark-nav-bar'); + await tester.pumpWidget( + MaterialApp( + home: MediaQuery( + data: const MediaQueryData(padding: EdgeInsets.only(bottom: 34)), + child: Scaffold( + bottomNavigationBar: AppBottomNav( + dark: true, + barKey: barKey, + items: [ + AppBottomNavItem( + tabKey: const Key('tab-home'), + icon: Icons.movie_outlined, + selectedIcon: Icons.movie_rounded, + label: 'Home', + selected: true, + onTap: () {}, + ), + AppBottomNavItem( + tabKey: const Key('tab-theater'), + icon: Icons.explore_outlined, + selectedIcon: Icons.explore_rounded, + label: 'Theater', + onTap: () {}, + ), + AppBottomNavItem( + tabKey: const Key('tab-create'), + icon: Icons.add_box_outlined, + selectedIcon: Icons.add_box_rounded, + label: 'Create', + onTap: () {}, + ), + AppBottomNavItem( + tabKey: const Key('tab-mine'), + icon: Icons.person_outline_rounded, + selectedIcon: Icons.person_rounded, + label: 'Me', + onTap: () {}, + ), + ], + ), + ), + ), + ), + ); + + expect( + tester.getSize(find.byType(AppBottomNav)).height, + AppDimens.navHeight + 34, + ); + expect(tester.getSize(find.byKey(barKey)).height, AppDimens.navHeight); + + final coloredBox = tester.widget( + find.descendant( + of: find.byType(AppBottomNav), + matching: find.byType(ColoredBox), + ), + ); + expect(coloredBox.color, Colors.black); + }); } diff --git a/test/home/home_nav_ui_test.dart b/test/home/home_nav_ui_test.dart index 763eb84..1b61ce0 100644 --- a/test/home/home_nav_ui_test.dart +++ b/test/home/home_nav_ui_test.dart @@ -53,7 +53,7 @@ void main() { final decoration = bar.decoration as BoxDecoration; final border = decoration.border as Border; // 首页 feed 用深色导航。 - expect(decoration.color, const Color(0xE6000000)); + expect(decoration.color, Colors.black); expect(border.top.color, Colors.white12); expect( tester