Conversation
* style: set background color for expansion panels * docs: add TODOs explaining the dark mode background override
…911) * feat: add theme override capabilities to ThemedScaffold Introduces ContentThemeOverride to allow forcing light or dark modes on the scaffold or its body independently. - Add ContentThemeOverride enum (auto, light, dark). - Add contentThemeOverride and ignoreAppBarOverride parameters. - Implement _resolveThemeOverride to dynamically generate theme data. - Update build logic to conditionally wrap the scaffold or body in a Theme widget. - Refactor background decoration logic for better readability. * refactor: replace Scaffold with ThemedScaffold across main feature screens * chore: add theme override configurations and documentation to page configs * feat: add theme override configuration for pages * feat(theme): implement comprehensive screen theming and override system Overhauls the screen styling architecture to support dynamic background styles and explicit theme mode overrides (Light/Dark) across all main features. - Implement ThemeOverrideConfig to manage theme mode forcing and AppBar synchronization. - Introduce screen-specific styles (Contacts, Embedded, Favorites, Conversations, Recents) with background and theme override support. - Refactor ThemedScaffold to use applyToAppBar (positive logic) for better readability and predictable theme propagation. - Add StyleFactories for all migrated screens to map declarative JSON configurations to UI styles. - Update BottomMenuTab models to include theme override data for tab-level consistency. - Standardize MainAppBar behavior to handle complex backgrounds (gradients/images) by dynamically adjusting transparency and elevation. * chore(theme): synchronize theme override keys and visibility in page configs * fix: prevent content overlap with AppBar on complex backgrounds * docs: align applyToAppBar documentation and default behavior
* fix: fixed formatting on about screen Transferred core url after version and divided app information and device information. * refactor: optimize layout and decompose widgets * feat: add documentation and enrich appInfo output in AppMetadataProvider --------- Co-authored-by: Dmytro Serdun <d.serdun@webtrit.com>
Added collate method with no case option when sorting contacts
…upport (#914) * refactor: update dark theme configuration and enable mode support * feat: implement supported features schema and unify theme mode * feat: apply forced theme mode from FeatureAccess configuration * refactor: swap page and widget theme configurations to correct files
* refactor: rename ThemeModeConfig.auto to ThemeModeConfig.system * refactor: replace custom ContentThemeOverride with standard ThemeMode * refactor: rename toContentThemeOverride to toThemeMode * fix: correctly handle nullable contentThemeOverride
…rides (#916) * refactor: rename ThemeModeConfig.auto to ThemeModeConfig.system * refactor: replace custom ContentThemeOverride with standard ThemeMode * refactor: use ThemeProvider for theme overrides Replaces the manual theme generation logic in ThemedScaffold with direct retrieval from ThemeProvider. This ensures that when a theme mode is forced (Light/Dark), the resulting ThemeData includes all custom extensions and component styles defined in the app.
* style: remove temporary background color overrides in MediaSettingsScreen * fix: wrap active thumbnail in Card for overlay support The active call thumbnail is rendered inside an overlay, which is detached from the main Scaffold tree. Without a Material ancestor, the widget lacks theme context and elevation. This change wraps the content in a Card to ensure proper Material styling and shadows when displayed as a floating thumbnail. * refactor(settings): use theme colors for microphone warning
* refactor(app): implement safe teardown sequence for user logout Introduces a dedicated `Teardown` application lifecycle state to ensure safe resource cleanup. - Add `AppLifecycleStatus` to `AppBloc` to manage authentication states. - Create `TeardownScreen` to hold the UI context while the `MainShell` unmounts. - Implement `UserSessionCleanupResolver` to centralize repository and database clearing. - Remove `onLogout` callback from `SessionRepository` and `main.dart`. - Refactor `AppRouter` guards to handle the new teardown navigation flow. * refactor: implement best-effort strategy for user session cleanup * refactor: rename AppLogined to AppLoggedIn and refine logout documentation * feat(autoprovision): pass system info when logging in via autoprovision * refactor: implement memory-first session strategy and remove reactive streams * fix: promote SessionRepository to a singleton in bootstrap * refactor: implement intent-based logout orchestration in AppBloc * style: optimize event instantiation and refine code comments * style: reorder members in AppEvent classes * feat: localize TeardownScreen progress text * feat: explicitly handle storage cleanup during session updates * refactor: refine teardown screen navigation guard * docs: refine _saveSession documentation to match delegation pattern
* feat: add ButtonStyle and Geometry configuration models * feat: implement configurable ButtonStyle for LoginSwitchScreen * chore: add configurable SegmentedButton styling for login switch * feat: add disabled state colors to ButtonStyleConfig * feat: support disabled states and improve border side resolution in button styles * refactor: migrate primary elevated button to ButtonStyleConfig
…ead badges (#924) * refactor: replace custom tab buttons with standard TabBar and add unread badges * refactor: remove redundant TabButtonsBar widget * refactor: optimize tab selection logic and state updates
* fix(theme): propagate defaultFontFamily to theme factories Updated theme style factories and configuration extensions to accept and apply a `defaultFontFamily`. This ensures consistent font rendering across the app by explicitly passing the font family derived from the global TextTheme into custom component styles. - Added `defaultFontFamily` parameter to `TextStyleConfig.toTextStyle` and related style conversion methods. - Modified `ThemeStyleFactoryProvider` to initialize a `defaultTextTheme` and pass its font family to various screen and widget factories. - Refactored multiple factories (Keypad, CallScreen, Login, Settings, etc.) to support the new font propagation logic. - Replaced redundant `createTextTheme()` calls with a cached `defaultTextTheme`. * refactor: improve initials text style mapping and reduce log verbosity
* refactor: move ActionPadWidgetConfig from widget to page configuration * refactor: add defaultVerticalAlignment to TextButtonsTable * refactor(keypad): transition Actionpad to semantic button styling Redesign Actionpad styling logic to move away from function-specific identifiers toward semantic roles. This decoupling allows for more flexible UI configurations and cleaner style inheritance. * fix: correct button style merging and disabled states in ActionPad
* refactor: remove hardcoded timeouts in PeerConnectionManager * refactor: increase RtpTrafficMonitor check interval to 15s Update the default monitorCheckInterval from 2s to 15s to optimize log storage and prevent quota exhaustion. This adjustment reduces log volume by approximately 85% while maintaining sufficient granularity for monitoring network quality trends.
…930) * refactor: consolidate remote config service implementations * refactor: enhance remote config service and caching logic * refactor: move remote config service to services directory * refactor: rename FirebaseRemoteConfigService to CachedRemoteConfigService * feat: add remote config update stream support * feat: integrate remote config overrides into FeatureAccess * refactor: implement Snapshot pattern for RemoteConfigService * refactor: update RemoteConfigService architecture and snapshot handling * refactor: improve FeatureAccess reactivity and StreamUtils robustness * refactor: add disposal guards to CachedRemoteConfigService and clean up redundant comments * refactor: introduce FeatureAccessStreamFactory and decouple stream logic from RootApp * refactor: update FeatureAccess architecture with specialized factories and rxdart integration * refactor: ensure deterministic equality in CoreSupportImpl by sorting flags
…ronization (#931) * feat: implement dynamic RTP monitoring configuration - Added MonitoringConfig model and MonitoringMapper to handle monitor intervals. - Updated PeerConnectionManager to support runtime configuration updates. - Introduced CallConfigSynchronizer to reactively update CallBloc when FeatureAccess changes. - Added 'monitorConfig' to SupportedFeature for static app configuration. - Integrated Remote Config override for monitor check interval via 'feature_monitor_check_interval_sec'. - Enabled voicemail settings by default in app.config.json. * fix: align app.config.json key with SupportedMonitorConfig model - Rename 'checkInterval' to 'checkIntervalSec' in app.config.json. - Fixes an issue where the static monitor configuration was ignored due to a naming mismatch with the generated SupportedMonitorConfig model. - Ensures the default 15-second interval is correctly read from the assets. * fix(data): add monitoringConfig to FeatureAccess Equatable props * fix(data): validate remote config monitor interval to prevent zero or negative values * fix(call): allow disabling RTP monitor via zero interval * test(data): verify monitor interval remote overrides and refactor validation * docs: fix parameter name in SupportedFeature.monitorConfig doc comment * fix: allow zero interval to propagate for RTP monitor disablement * test(call): add unit tests for RtpTrafficMonitor - Verified that checkInterval <= 0 successfully acts as a kill switch, preventing timer initialization and native calls. - Verified that a valid positive interval correctly triggers periodic WebRTC stats fetching. - Verified that monitoring automatically stops when RTCPeerConnection enters a closed state. - Covered edge cases for zero and negative durations to ensure stability against invalid configurations.
…ng (#932) * feat: add reboot dialog Added dialog for user to reboot user when timeout error on starting a call if it is Xiaomi phone * refactor: replace AppMetadataProvider with DeviceInfo in DiagnosticService * refactor: inject DeviceInfo into DiagnosticService in AppShell * feat: include Huawei in emergency reboot diagnostic logic * chore: update system error dialog localizations * refactor(diagnostic): improve error handling and decouple UI logic * refactor: simplify system error dialog and unify diagnostic launchers * refactor: unify diagnostic flow and streamline reporting * chore: remove trailing periods from system error dialog titles --------- Co-authored-by: Alex Maudza <o.maudza@webtrit.com>
…ry saving (#933) * refactor: add controller to HistoryAutocompleteField for manual history saving - Implement HistoryAutocompleteController to allow manual triggers for saving input to history. - Convert LoginCoreUrlAssignScreen to a StatefulWidget to manage the controller lifecycle. - Update HistoryAutocompleteField to support the new controller and internal logic extraction. - Refactor callbacks into private methods and simplify widget building logic. * fix: avoid redundant history saving in HistoryAutocompleteField
…ures (#934) Refactor feature configuration by introducing systemNotifications and sipPresence as variants of SupportedFeature. This change initiates the transition away from legacy flat properties in AppConfigMain.
…ion (WT-1401) (#1193) * fix(call): skip ICE restart for calls without initialized PeerConnection _onConnectivityResultChanged called retrieve() unconditionally for all active calls. For calls still in pre-PC states (outgoingConnectingToSignaling, incomingInitializingMedia, etc.) the completer was never completed, causing retrieve() to block for 5 s then throw TimeoutException — breaking the entire handler loop and silently skipping ICE restart for all subsequent calls. Adds hasPeerConnectionReady getter to CallProcessingStatus covering the states where complete() is guaranteed to have been called (outgoingOfferSent, outgoingRinging, connected, disconnecting). The guard skips retrieve() for calls that have no PC yet while preserving the TimeoutException signal for calls that should have a PC but don't. Fixes: WT-1401 (secondary bug) * fix(call): log skipped ICE restart when PC not ready * test(call): add unit tests for CallProcessingStatus.hasPeerConnectionReady * fix(call): remove disconnecting from hasPeerConnectionReady, add status to ICE restart log
…o prevent native eviction (#1196) * fix(WT-1398): detach pooled track from stream before dispose On iOS and Android, streamDispose iterates the stream's track list and removes each track from the native localTracks registry. When a pooled audio/video track is shared between the main call and a consultation call, disposing the consultation call's local stream evicts the track from localTracks — even though the main call still holds a reference. The next consultation attempt calls addTrack() on the same pooled track object, which fails with "Track is nil" / "track is null" because the track is no longer in localTracks. Fix: in release(), call removeTrack() on the pooled track before stream.dispose() when references > 1. mediaStreamRemoveTrack removes the track from the stream's own audioTracks/videoTracks list without touching localTracks, so streamDispose no longer sees it and does not evict it from the registry. Confirmed by reading the native plugin source: - iOS: FlutterWebRTCPlugin.m streamDispose / mediaStreamRemoveTrack - Android: MethodCallHandlerImpl.java streamDispose / mediaStreamRemoveTrack * test(user-media-builder): stub removeTrack and add detach verification Adds missing removeTrack stub to _TestMediaStreamFactory so the new _detachIfStillPooled path does not fail with a null return from the mock. Adds a test verifying that pooled tracks are detached from a stream before dispose when another borrower still holds a reference, and that the last borrower skips detach (tracks are stopped and disposed anyway).
…ions (#1200) * fix(signaling): ignore late server ACK for already-timed-out transactions When a signaling transaction times out the client removes it from the _transactions map and tears down the call. If the server responds after the timeout (observed up to 63 s under network congestion), the missing map entry previously triggered _onError(WebtritSignalingTransactionUnavailableException) which emitted a false-positive SignalingConnectionFailed and caused an unnecessary reconnect while other calls may still be in progress. Replace the error path with a warning-level log so a late ACK is a no-op. * refactor(signaling): remove WebtritSignalingTransactionUnavailableException Class became dead code after late-ACK handling was changed to log a warning instead of calling _onError. Remove the class, its hub codec encode/decode branches, the constant, and all test references.
…tification (#1203) * fix(wt-1416): show caller number instead of Unknown in missed call notification When IncomingCallEvent is missing (race condition where push isolate connects after the event has passed through the hub), the caller number now falls back to _metadata.handle.value from FCM push metadata instead of the hardcoded 'unknown' string. The missed-call notification display name resolution now also falls back to the caller phone number when neither signaling nor push metadata provide a display name. * fix(wt-1416): replace unknown string fallback with empty string Use empty string instead of hardcoded 'unknown' as final fallback for caller number, allowing isNotEmpty check to handle all cases cleanly. * refactor(wt-1416): simplify _getDisplayNameForMissedCall with firstWhere
* fix(signaling): align hub execute timeout with full retry cycle
_executeTimeout in SignalingHubClient was set to 15 s ("slightly longer
than the 10 s transaction timeout") but did not account for
SignalingRequestQueue retrying a timed-out transaction up to
defaultMaxRetryCount times. The hub timeout fired mid-retry, causing the
main isolate to receive a TimeoutException while the background isolate
was still working, which triggered a false wasAccepted==false → Decline.
Fix: derive _executeTimeout dynamically from the actual retry budget —
transactionTimeout × (maxRetryCount + 1) + 5 s overhead (45 s with
defaults). The hub timeout now only fires when the background isolate
stops responding entirely (hub death), which is the intended behaviour.
Hub death detection via ping/pong remains unchanged as a parallel guard.
Add SignalingRequestQueue.defaultMaxRetryCount constant so both sides
reference the same source of truth without hardcoding.
* test(signaling): add coverage for hub execute timeout alignment
- hub_client_integration_test: new 'execute timeout alignment' group with 4
tests proving that _executeTimeout must cover the full retry cycle
(transactionTimeout × (maxRetryCount + 1)); fixes const → final for
Duration arithmetic expressions
- signaling_request_queue_test: add 3 tests for defaultMaxRetryCount
constant value, default constructor usage, and custom override
* refactor(signaling): address PR review comments
- add explicit int type to SignalingRequestQueue.defaultMaxRetryCount
- clarify test comment: fake client delays directly, no real retry happens
…1205) CallController now requires ConnectivityService; mocked it in tests. Timeout path now emits GeneralUnableToCallNotification, not NoInternetConnectionNotification.
…1403) (#1206) * fix(signaling): reset _errorHandled when new client connects (WT-1403) When _onError fired for clientA, _errorHandled was left true after clientB successfully connected. ClientB's subsequent disconnect was silently suppressed, preventing any reconnect from being triggered. Adds regression tests covering both the with-stale-disconnect and direct error→reconnect→disconnect scenarios. * fix(signaling): close stale-callback guard hole and add ghost-state detection (WT-1403) Bug #2 — _activeClientId token replaces the old _client != null guard in SignalingModuleImpl. The previous guard passed stale callbacks when _client was already null (e.g. a late _wsOnDone after _onError had cleared _client), delivering spurious SignalingDisconnected(delay=null) that silenced the reconnect loop. The new per-client Object token is cleared in both _onError and _onDisconnect, so any late callback from the same or a prior client is discarded regardless of _client's current value. Bug #3 — ghost-state detection in WebtritSignalingService.execute(). When the main-isolate believes it is connected (_isConnected=true) but the FGS hub is actually disconnected, execute() now receives NotConnectedException instead of a generic StateError. The exception is encoded through the isolate codec (signaling_hub_codec) and caught in a catchError chain; on detection _isConnected is reset to false and connect() is called to trigger recovery. Tests: 8 new tests for Bug #2 (4 BUG + 4 after-fix) and 5 new tests for Bug #3 (ghost-state reset, reconnect trigger, rethrow, normal path, non-NCE). * fix(signaling): fix null-aware operator and local variable naming lint warnings * refactor(signaling-tests): address reviewer feedback — merge duplicate helpers and rename BUG→regression prefix - Extract buildModuleWith/buildModuleWith2 local functions into a single top-level _buildModuleFromClients helper to remove duplication - Rename test prefix 'BUG:' → 'regression:' for clarity: regression tests reproduce the bug scenario and are expected to fail on unfixed code, not assert buggy behavior - Update library docstring to match the new naming convention
#1207) * fix(call): show missed call notification on Android when call ends via signaling When the app is alive and an incoming call is never answered, the HangupEvent arrives through the signaling path in CallBloc, which only logged the call and reported end to callkeep — no OS notification was posted. The push isolate path already handled this correctly via localPushRepository.displayPush. Added localPushRepository dep to CallBloc and _showMissedCallNotification helper. Notification is guarded to Android only since iOS handles missed calls via CallKit. * feat: add AppLocalPush.missedCall factory to centralise missed call notification construction Both push isolate and CallBloc were constructing the same AppLocalPush payload manually with duplicated callId.hashCode, title string, and payload keys. Moved the construction into a named factory so callers pass only callId and callerName. * fix(call): suppress missed call notification when declined on another device When code == declineCall the call was actively rejected by another registered device, so posting a missed call notification is misleading. Guard the notification behind code != declineCall.
Adds missing error codes to handleError switch so users see actionable messages instead of silent failures: - incorrect_credentials → "Incorrect username or password" - user_not_found → "User not found" - unconfigured_bundle_id, validation_error, parameters_apply_issue, empty_email — previously handled only in deprecated LoginErrorNotification Adds 7 new notification classes and 2 new l10n keys (EN/UK/IT). Fixes: WT-1417
…#1209) ConnectivityResult.vpn was falling through to the default case and returning NetworkStatus.none, causing the app to show "waiting network" and skip signaling reconnect when VPN was active.
* fix(wt-1417): debounce ICE restart on connectivity change to allow interface init * refactor(wt-1417): extract debounce-per-key logic into reusable DebounceMap utility - Add DebounceMap<K> to lib/utils/ — cancel+reschedule timer per key, dispose all on teardown - Replace raw Map<String, Timer> + Timer in CallBloc with DebounceMap<String> - Cover DebounceMap with 8 unit tests using fake_async * refactor(wt-1417): address review — dispatch internal event from ICE restart timer - Add _IceRestartTriggered event; timer now calls add() instead of doing async work directly - _onIceRestartTriggered handles retrieve+restartIce inside the BLoC event loop - Cancel pending ICE restart on call teardown in __onResetStateEventCompleteCall - Fix debounce_map.dart export position in utils.dart (alphabetical order)
) * fix(wt-1428): show user not found notification on OTP sign-in 404 Convert 404 from otp-create endpoint to UserNotFoundException in the API client, then handle it explicitly in LoginCubit.handleError to show LoginUserNotFoundNotification instead of logging as unexpected error. * fix(wt-1428): fix log style and add test for 404 UserNotFoundException Align warning log to use string interpolation consistent with existing handleError style. Add unit test for createSessionOtp 404 → UserNotFoundException.
…tation error handler (#1213)
…425, WT-1404, WT-5471) (#1214)
* fix: safe renegotiate - pc ready guard * fix: _safeRenegotiate move pc retrieve on top to avoid other guards inconsistency after retrieve await * fix: skip remote updating if disconnecting
…uting (#1216) * feat(call): introduce CallMediaManager for centralized audio/video routing Replaces scattered direct audio plugin calls in CallBloc with a single CallMediaManager facade that encapsulates both webtrit_callkeep and flutter_webrtc audio APIs. Key changes: - CallMediaManager: single coordinator for all audio routing decisions (device selection, iOS session lifecycle, video-triggered speaker logic) - CallAudioDevice moved from call_state.dart (part file) to models/call_audio_device.dart to resolve circular import - Android: earpiece-first preferredOutputOrder set at app init via AndroidNativeAudioManagement.setAndroidAudioConfiguration, fixing speaker auto-activation on cold-start voice calls - onVideoEnabled/onVideoDisabled: symmetric speaker↔earpiece routing on both platforms when camera is toggled mid-call - _handleVideoStateTransitions in onChange: reacts to mid-call video flag transitions (prevCall != null guard prevents firing on initial call creation before PhoneConnection exists) - _onVideoStreamReady helper: called after getUserMedia completes for initial video calls, when AudioSwitch and PhoneConnection are both ready * chore: update pubspec.lock to pick up flutter-webrtc preferredOutputOrder (#8) * refactor(call): call mediaManager directly instead of reactive onChange detection * fix(call): route speaker via AudioSwitch in onVideoEnabled/Disabled * fix(call): route all Android audio device changes through AudioSwitch in setDevice * refactor(call): extract reusable _enableSpeaker/_disableSpeaker helpers in CallMediaManager * refactor(call): remove duplicate comment in CallMediaManager speaker helpers * fix(lint): add curly braces to if statements in CallMediaManager * refactor(call): move CallMediaManager from services/ to utils/ * chore: restore network_security_config.xml to match develop Remove local dev IP (192.168.0.9) committed by mistake; file now matches develop exactly. * chore: remove auto-generated assets.dart committed by mistake * refactor(call): inline lifecycle mediaManager calls, remove wrapper methods _onFirstCallStarted/_onLastCallEnded were thin wrappers with no logic of their own. * refactor(call): move lifecycle logging into CallMediaManager, remove bloc logs * refactor(call): remove redundant platform guards in CallMediaManager lifecycle methods * refactor(call): replace lifecycle methods with direct commands in CallMediaManager * refactor(call): make enableSpeaker/disableSpeaker public, remove resetSpeaker wrapper * refactor(call): merge enableSpeaker/disableSpeaker into single setSpeaker method * refactor(call): move setUseManualAudio to _configure, remove onCallStarted * revert(call): revert instance fields for static-only classes, keep static calls * docs(call): restore doc comments lost during CallMediaManager refactor * fix(call): address reviewer issues in CallMediaManager - Add Platform.isAndroid guard to clearCommunicationDevice - Fix double setSpeakerphoneOn(false) on iOS in onVideoDisabled - Route Android non-speaker setDevice through setSpeaker for consistency - Add catchError logging to fire-and-forget audio session callbacks - Remove navigation comment from call_state.dart * fix(call): address second round of reviewer issues - Replace byName with exhaustive switch in fromCallkeep/toCallkeep - Make setSpeaker/setDevice properly async with await - Fix double Telecom call in Android non-speaker setDevice path - Fix fire-and-forget audio session callbacks with unawaited+try/catch - Rename mediaManager to _mediaManager (encapsulation) * docs(call): update CallMediaManager class doc to reflect current responsibilities * docs(call): document AudioSwitch activation constraint in onVideoEnabled
* fix: pass actual device ID to Telecom when switching audio on Android setSpeaker() was creating an anonymous CallAudioDevice (id=null) and passing it to Callkeep.setAudioDevice(), causing "Cannot set audio device: null device id" on every speaker switch during a call. setDevice() Android speaker branch now calls both Helper.setSpeakerphoneOn and _callkeep.setAudioDevice with the real device (preserving its UUID). Same fix applied to onVideoEnabled/onVideoDisabled which had the same null-id pattern via setSpeaker(callId, ...). setSpeaker() is now WebRTC-only (no Telecom call) since all live-call routing goes through setDevice or the video helpers with the actual device. * fix: revert Telecom routing from video helpers, use AudioSwitch only onVideoEnabled/onVideoDisabled called _callkeep.setAudioDevice which competed with AudioSwitch and prevented the speaker from switching on Android when the user enabled video on an established audio call. Video-triggered audio routing goes through AudioSwitch (setSpeakerphoneOn) only — the same path used before PR #1216. Telecom routing via setAudioDevice is reserved for explicit user-triggered device changes in setDevice(). * fix: restore Telecom routing in onVideoEnabled/onVideoDisabled Log confirms AudioSwitch alone is insufficient: Telecom holds earpiece routing (uid 1000) and overrides setSpeakerphoneOn(true) from the app (uid 11391). Both APIs must be called to switch to speaker on video enable. Restores _callkeep.setAudioDevice with the actual device ID from availableAudioDevices, which was the missing piece to update the Telecom route and let the app win the audio routing conflict. * fix(call): skip speaker auto-enable for incoming video calls Only route audio to speaker in _onVideoStreamReady when the call direction is outgoing. Incoming video calls do not initiate video — auto-enabling speaker on answer is unexpected for the user. * fix(call): explicitly set VideoChat mode on iOS when video is enabled With setUseManualAudio(true) active, WebRTC does not auto-switch the AVAudioSession mode. onVideoEnabled now mirrors the reverse of onVideoDisabled: sets AppleAudioMode.videoChat then calls setSpeakerphoneOn(true). * fix(call): enable speaker for all video calls, not just outgoing Speaker auto-enable on video applies to both incoming and outgoing video calls. Reverts the outgoing-only direction guard added earlier. * fix(call): update setSpeaker docstring and add warning on missing earpiece device - Clarify that setSpeaker is also used for live iOS routing in setDevice (iOS has no Telecom layer, so Helper.setSpeakerphoneOn is sufficient there) - Add logger.warning in onVideoDisabled when earpieceDevice is null on Android so a silent Telecom-skip is observable in field logs
#1226) RenegotiationHandler.handle now calls getSenders() and getReceivers() before createOffer to determine anyoneHasVideo, but the affected tests did not stub these methods — causing a TypeError that short-circuited execution before the verify assertions could pass.
Update flutter-webrtc resolved ref and webtrit_callkeep version to 1.0.1+0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 1.15.1
Changes since 1.15.0