complete ipad orientation and switch recovery

Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
kenny lopez
2026-08-03 14:41:49 +01:00
parent 64a589bd7e
commit b59dc05f23
3 changed files with 116 additions and 5 deletions
+7
View File
@@ -84,5 +84,12 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -7,7 +7,7 @@ class _WideNavigationSidebar extends HookConsumerWidget {
final String? selectedChannelId;
final VoidCallback onProfileSelected;
final bool isCommunitySwitching;
final ValueChanged<String> onCommunitySwitchStart;
final ValueChanged<String?> onCommunitySwitchStart;
final List<_HomeDestination> destinations;
const _WideNavigationSidebar({
@@ -285,7 +285,7 @@ class _WideNavigationSectionLabel extends StatelessWidget {
class _WideNavigationCommunitySwitcher extends HookConsumerWidget {
final VoidCallback onTap;
final ValueChanged<String> onCommunitySwitchStart;
final ValueChanged<String?> onCommunitySwitchStart;
const _WideNavigationCommunitySwitcher({
required this.onTap,
@@ -350,9 +350,19 @@ class _WideNavigationCommunitySwitcher extends HookConsumerWidget {
if (!context.mounted) return;
onCommunitySwitchStart(nextCommunity.id);
unawaited(HapticFeedback.selectionClick());
await ref
.read(communityListProvider.notifier)
.switchCommunity(nextCommunity.id);
try {
await ref
.read(communityListProvider.notifier)
.switchCommunity(nextCommunity.id);
} catch (error) {
debugPrint('[CommunitySwitcher] failed to switch community: $error');
if (!context.mounted) return;
onCommunitySwitchStart(null);
swipeProgress.value = 0;
switchTarget.value = null;
isSwitching.value = false;
return;
}
if (!context.mounted) return;
swipeProgress.value = 0;
switchTarget.value = null;
@@ -658,6 +658,84 @@ void main() {
);
});
testWidgets('a failed community swipe restores the workspace', (
tester,
) async {
tester.view.physicalSize = const Size(1180, 820);
tester.view.devicePixelRatio = 1;
addTearDown(() {
tester.view.resetPhysicalSize();
tester.view.resetDevicePixelRatio();
});
final communityListNotifier = _FailingCommunityListNotifier([
Community(
id: 'alpha',
name: 'Alpha',
relayUrl: 'wss://alpha.example.com',
addedAt: DateTime(2026),
),
Community(
id: 'bravo',
name: 'Bravo',
relayUrl: 'wss://bravo.example.com',
addedAt: DateTime(2026),
),
]);
await tester.pumpWidget(
await buildHome(
communityListNotifier: communityListNotifier,
activeCommunity: communityListNotifier.communities.first,
),
);
await tester.pump();
await tester.pump(const Duration(milliseconds: 1));
Future<void> swipe() async {
final gesture = tester.widget<GestureDetector>(
find.descendant(
of: find.byKey(const Key('wide-navigation-community-icon')),
matching: find.byType(GestureDetector),
),
);
gesture.onVerticalDragStart!(
DragStartDetails(globalPosition: Offset.zero),
);
gesture.onVerticalDragUpdate!(
DragUpdateDetails(
globalPosition: const Offset(0, 40),
delta: const Offset(0, 40),
),
);
await tester.pump();
gesture.onVerticalDragEnd!(DragEndDetails(velocity: Velocity.zero));
await tester.pump();
await tester.pump(const Duration(milliseconds: 120));
await tester.pump();
await tester.pump(const Duration(milliseconds: 120));
await tester.pump();
}
await swipe();
expect(communityListNotifier.switchAttempts, 1);
expect(
tester
.widget<SkeletonShimmer>(
find.ancestor(
of: find.byKey(
const Key('wide-navigation-community-switch-skeleton'),
),
matching: find.byType(SkeletonShimmer),
),
)
.enabled,
isFalse,
);
await swipe();
expect(communityListNotifier.switchAttempts, 2);
});
testWidgets('gives selection haptics only when the tab changes', (
tester,
) async {
@@ -783,3 +861,19 @@ class _FakeCommunityListNotifier extends CommunityListNotifier {
switchedToId = id;
}
}
class _FailingCommunityListNotifier extends CommunityListNotifier {
_FailingCommunityListNotifier(this.communities);
final List<Community> communities;
int switchAttempts = 0;
@override
Future<List<Community>> build() async => communities;
@override
Future<void> switchCommunity(String id) async {
switchAttempts++;
throw Exception('Unable to save active community');
}
}