Skip to content

Implement mirror check#482

Open
johnnycrich wants to merge 6 commits into
stagingfrom
jr/feat/mirror-check
Open

Implement mirror check#482
johnnycrich wants to merge 6 commits into
stagingfrom
jr/feat/mirror-check

Conversation

@johnnycrich

@johnnycrich johnnycrich commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

What is in this PR?

Introduces a basic "mirror check" feature to ensure users verify their camera and microphone settings before joining a meeting. The changes also enhance error handling and user feedback during device setup.

Changes in the codebase

  • Integrated the mirror check status into MediaDeviceService for runtime access. (media_device_service.dart)
  • Updated MediaSettingsWidget to support a mirror check mode, including a new introductory message, modified save button behavior, and logic to mark the mirror check as complete. (media_settings_widget.dart)
  • Improved device selection and preview logic, and clarified the distinction between device selection and streaming state in the UI. (media_settings_widget.dart)
  • Improves the distinction between device readiness and actual audio/video streaming. Added explicit flags (audioIsStreaming, videoIsStreaming) to track whether audio/video is actually being sent, separate from device enablement. Updated all relevant logic and toggles to use these flags. (agora_room.dart, conference_room.dart).
  • Modified audio/video enablement logic to only allow streaming if the mirror check has been completed, preventing premature streaming. (conference_room.dart)
  • Added a local storage flag (array) in SharedPreferencesService to track if the user has completed the mirror check per event.
  • Improved error handling and logging throughout device setup and streaming toggles to assist with debugging and ensure user state is reset correctly on failure. (media_settings_widget.dart, conference_room.dart)
  • Only show the grid of participants if mirror check is complete. (video_flutter_meeting.dart)

Testing this PR

  • Create a new event and enter it. For now, use hosted.
  • initially, you should not see any other participants in the meeting, whether or not they have a A/V enabled.
  • You should see a pop-up stating "Audiovisual Settings", with dropdowns for both camera and audio devices. When video device changes, the preview should reflect that.
  • Click save and close.
  • Note that any other participants now appear, and your mic and camera are still off.
  • Verify that after turning them on your camera and microphone use your desired devices.
  • Access the AV settings panel as normal and verify that changing devices still works as intended.
  • Refresh the event and note that you do not see the mirror check again, and that your devices now turn on by default.
  • Try the above steps again with both a hostless and livestream event. You should not see the mirror check in those events before you enter a breakout room.

PR Checklist

  • Where applicable, I have added localization (l10n) entries to my feature for user-facing text.
  • For new Cloud Functions, I have added the function to function-mapping.json.

AI tools used (if applicable):
Copilot assisted in drafting this PR.

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 2afeff8):

https://gen-hls-bkc-7627--pr482-jr-feat-mirror-check-hfijea56.web.app

(expires Fri, 26 Jun 2026 16:06:51 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: eed668cca81618d491d024574a8f8a6003deaa8d

@johnnycrich johnnycrich changed the title Jr/feat/mirror check Implement mirror check Jun 11, 2026
@johnnycrich johnnycrich linked an issue Jun 12, 2026 that may be closed by this pull request
@johnnycrich johnnycrich added the enhancement New feature or request label Jun 12, 2026
@johnnycrich johnnycrich marked this pull request as ready for review June 12, 2026 14:14
Copilot AI review requested due to automatic review settings June 12, 2026 14:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements a per-event “mirror check” flow that forces users to review/select camera & microphone devices before they can stream A/V or see other participants in a meeting. This is integrated into meeting connection, UI controls, participant rendering, and persisted locally so the mirror check is only shown once per event.

Changes:

  • Added mirror-check completion persistence via SharedPreferencesService and used it to gate A/V streaming and participant visibility.
  • Updated meeting UI to distinguish “device enabled” vs “actually streaming” and updated toggles/participant rendering accordingly.
  • Refreshed the media settings dialog UI/copy and device-save logic, including new l10n keys.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
client/lib/l10n/app_en.arb Adds mirror-check related strings; currently introduces a duplicate key issue (and).
client/lib/l10n/app_es.arb Adds mirror-check related strings; currently introduces a duplicate key issue (and).
client/lib/l10n/app_zh.arb Adds mirror-check related strings; currently introduces a duplicate key issue (and).
client/lib/l10n/app_zh_Hant_TW.arb Adds mirror-check related strings (Traditional Chinese).
client/lib/core/widgets/media_settings_widget.dart Updates A/V settings dialog UI and save behavior for mirror-check mode; contains a critical rollback bug and dead state.
client/lib/core/utils/media_device_service.dart Minor formatting-only change.
client/lib/core/data/services/shared_preferences_service.dart Adds per-event mirror-check completion tracking APIs.
client/lib/features/events/features/live_meeting/features/video/data/providers/agora_room.dart Introduces separate “is streaming” flags for local participant A/V state.
client/lib/features/events/features/live_meeting/features/video/data/providers/conference_room.dart Gates A/V streaming on mirror-check completion; shows mirror-check dialog on connect; introduces unused imports and state-semantic mismatch.
client/lib/features/events/features/live_meeting/features/video/presentation/widgets/control_bar.dart Updates controls to use streaming flags and (partially) gate toggles based on mirror-check completion; video toggle gating and messaging need fixes.
client/lib/features/events/features/live_meeting/features/video/presentation/widgets/participant_widget.dart Uses streaming flags for local audio state and hides video view until mirror check is complete.
client/lib/features/events/features/live_meeting/features/video/presentation/views/video_flutter_meeting.dart Hides participant grid until mirror check is complete (but only for one layout branch).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread client/lib/l10n/app_en.arb
Comment thread client/lib/l10n/app_es.arb
Comment thread client/lib/l10n/app_zh.arb
Comment thread client/lib/core/widgets/media_settings_widget.dart
Comment thread client/lib/core/widgets/media_settings_widget.dart Outdated
Comment on lines 426 to +432
child: Container(
padding: const EdgeInsets.all(8),
alignment: Alignment.center,
child: ParticipantGridLayout(),
// Only show the grid if mirror check is complete for this event
child: sharedPreferencesService.hasMirrorCheckCompletedForEvent(widget.liveMeetingProvider.eventProvider.eventId)
? ParticipantGridLayout()
: const SizedBox.shrink(),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultStageView is currently not exposed as an option to be changed, so the grid view is always Brady Bunch.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

client/lib/features/events/features/live_meeting/features/video/data/providers/conference_room.dart:382

  • On camera permission denial, the code sets videoTrackEnabled = false but leaves videoIsStreaming unchanged and does not update shouldStartLocalVideoOn. Since the UI now uses videoIsStreaming (and the provider uses shouldStartLocalVideoOn) for state, this can leave the UI/provider out of sync after a failed enable attempt.
    if (updatedEnabledValue) {
      final permissionStatus = await Permission.camera.request();
      if (permissionStatus.isDenied || permissionStatus.isPermanentlyDenied) {
        if (!context.mounted) return;
        await showAlert(
          context,
          'Error enabling camera. Please ensure you have granted permission.',
        );
        _room?.localParticipant?.videoTrackEnabled = false;
        return;

Comment on lines +389 to 400
try {
if (sharedPreferencesService.hasMirrorCheckCompletedForEvent(liveMeetingProvider.eventProvider.eventId)) {
await _room!.localParticipant!.enableVideo(
setEnabled: updatedEnabledValue,
);
}
if (updateProvider) {
liveMeetingProvider.shouldStartLocalVideoOn = updatedEnabledValue;
}
} catch (e) {
loggingService.log('Error toggling video: $e');
}
Comment on lines +435 to 459
try {
final audioEnableFutures = [
if (sharedPreferencesService.hasMirrorCheckCompletedForEvent(liveMeetingProvider.eventProvider.eventId))
_room!.localParticipant!.enableAudio(
setEnabled: updatedEnabledValue,
),
if ((liveMeetingProvider
.eventProvider.selfParticipant?.muteOverride ??
false) &&
updatedEnabledValue)
firestoreLiveMeetingService.updateParticipantMuteOverride(
event: liveMeetingProvider.eventProvider.event,
participantId: userService.currentUserId!,
muteOverride: false,
),
];

await Future.wait(audioEnableFutures);

if (updateProvider) {
liveMeetingProvider.shouldStartLocalAudioOn = updatedEnabledValue;
}
} catch (e) {
loggingService.log('Error toggling audio: $e');
}
Comment on lines +422 to 423
_room?.localParticipant?.audioIsStreaming = false;
return;
Comment on lines +463 to +465
setState(() {
isLoadingCameraChange = false;
});
Comment on lines +533 to +537
return MediaSettingsWidget(
conferenceRoom: this,
shouldShowVideoPreview: liveMeetingProvider.videoDefaultOn,
isMirrorCheck: true,
);
Comment on lines +173 to +177
return videoEnabled
? AgoraVideoView(
controller: videoViewController!,
)
: SizedBox.shrink();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Mirror Check

2 participants