mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
feat(mobile): show build number with version in settings (#7697)
Mobile Settings now identifies the installed build as e.g. `v0.16.0 (432)` rather than just `v0.16.0`. If the platform supplies no build number, the footer keeps the existing version-only display. | Before | After | | --- | --- | | Marketing version only | Version and native build number | |  |  | --------- Signed-off-by: Tom Brow <tomb@block.xyz>
This commit is contained in:
@@ -1523,7 +1523,7 @@ mod tests {
|
||||
conn_id: Uuid::new_v4(),
|
||||
tenant: tenant.clone(),
|
||||
remote_addr: "127.0.0.1:1234".parse().unwrap(),
|
||||
auth_state: RwLock::new(crate::connection::AuthState::Authenticated(
|
||||
auth_state: std::sync::Mutex::new(crate::connection::AuthState::Authenticated(
|
||||
buzz_auth::AuthContext {
|
||||
pubkey: keys.public_key(),
|
||||
scopes: vec![],
|
||||
@@ -1668,7 +1668,7 @@ mod tests {
|
||||
conn_id: Uuid::new_v4(),
|
||||
tenant: tenant.clone(),
|
||||
remote_addr: "127.0.0.1:1234".parse().unwrap(),
|
||||
auth_state: RwLock::new(crate::connection::AuthState::Authenticated(
|
||||
auth_state: std::sync::Mutex::new(crate::connection::AuthState::Authenticated(
|
||||
buzz_auth::AuthContext {
|
||||
pubkey: keys.public_key(),
|
||||
scopes: vec![],
|
||||
|
||||
@@ -225,7 +225,10 @@ class SettingsPage extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
if (packageInfo.hasData)
|
||||
_VersionFooter(version: packageInfo.data!.version),
|
||||
_VersionFooter(
|
||||
version: packageInfo.data!.version,
|
||||
buildNumber: packageInfo.data!.buildNumber,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -233,9 +236,10 @@ class SettingsPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
class _VersionFooter extends StatelessWidget {
|
||||
const _VersionFooter({required this.version});
|
||||
const _VersionFooter({required this.version, required this.buildNumber});
|
||||
|
||||
final String version;
|
||||
final String buildNumber;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -245,7 +249,7 @@ class _VersionFooter extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(bottom: Grid.xs, top: Grid.xxs),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'v$version',
|
||||
buildNumber.isEmpty ? 'v$version' : 'v$version ($buildNumber)',
|
||||
style: context.textTheme.bodySmall?.copyWith(
|
||||
color: context.colors.onSurfaceVariant.withValues(alpha: 0.6),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:buzz/features/settings/settings_page.dart';
|
||||
import 'package:buzz/shared/community/community_membership_provider.dart';
|
||||
import 'package:buzz/shared/theme/theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('settings remains usable while package metadata loads', (
|
||||
tester,
|
||||
) async {
|
||||
final metadata = Completer<Map<String, String>>();
|
||||
const channel = MethodChannel('dev.fluttercommunity.plus/package_info');
|
||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
|
||||
channel,
|
||||
(_) => metadata.future,
|
||||
);
|
||||
addTearDown(
|
||||
() => tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
|
||||
channel,
|
||||
null,
|
||||
),
|
||||
);
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
savedPrefsProvider.overrideWithValue(prefs),
|
||||
currentCommunityRoleProvider.overrideWithValue(
|
||||
const AsyncData<CommunityMemberRole?>(CommunityMemberRole.admin),
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
theme: AppTheme.light(),
|
||||
builder: (context, child) => MediaQuery(
|
||||
data: MediaQuery.of(
|
||||
context,
|
||||
).copyWith(textScaler: TextScaler.linear(2)),
|
||||
child: child!,
|
||||
),
|
||||
home: SettingsPage(
|
||||
profileHeader: const SizedBox.shrink(),
|
||||
invitePageBuilder: (_) => const SizedBox.shrink(),
|
||||
identityRecoveryPageBuilder: (_) => const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.text('Invite to community'), findsOneWidget);
|
||||
|
||||
expect(find.text('v0.16.0 (432)'), findsNothing);
|
||||
expect(find.byTooltip('Close settings'), findsOneWidget);
|
||||
metadata.complete({
|
||||
'appName': 'Buzz',
|
||||
'packageName': 'xyz.block.buzz',
|
||||
'version': '0.16.0',
|
||||
'buildNumber': '432',
|
||||
'buildSignature': '',
|
||||
});
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('v0.16.0 (432)'), findsOneWidget);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
}
|
||||
@@ -11,9 +11,71 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
PackageInfo.setMockInitialValues(
|
||||
appName: 'Buzz',
|
||||
packageName: 'xyz.block.buzz',
|
||||
version: '0.16.0',
|
||||
buildNumber: '432',
|
||||
buildSignature: '',
|
||||
);
|
||||
});
|
||||
|
||||
for (final buildNumber in ['432', '', '2147483647']) {
|
||||
testWidgets('shows version with build number "$buildNumber"', (
|
||||
tester,
|
||||
) async {
|
||||
tester.view.physicalSize = const Size(320, 700);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
PackageInfo.setMockInitialValues(
|
||||
appName: 'Buzz',
|
||||
packageName: 'xyz.block.buzz',
|
||||
version: '0.16.0',
|
||||
buildNumber: buildNumber,
|
||||
buildSignature: '',
|
||||
);
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
savedPrefsProvider.overrideWithValue(prefs),
|
||||
currentCommunityRoleProvider.overrideWithValue(
|
||||
const AsyncData<CommunityMemberRole?>(CommunityMemberRole.admin),
|
||||
),
|
||||
],
|
||||
child: MaterialApp(
|
||||
theme: AppTheme.light(),
|
||||
builder: (context, child) => MediaQuery(
|
||||
data: MediaQuery.of(
|
||||
context,
|
||||
).copyWith(textScaler: TextScaler.linear(2)),
|
||||
child: child!,
|
||||
),
|
||||
home: SettingsPage(
|
||||
profileHeader: const SizedBox.shrink(),
|
||||
invitePageBuilder: (_) => const SizedBox.shrink(),
|
||||
identityRecoveryPageBuilder: (_) => const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.text('Invite to community'), findsOneWidget);
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
find.text(buildNumber.isEmpty ? 'v0.16.0' : 'v0.16.0 ($buildNumber)'),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
}
|
||||
|
||||
testWidgets('shows the persisted per-community push opt-in on iOS', (
|
||||
tester,
|
||||
) async {
|
||||
|
||||
Reference in New Issue
Block a user