diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart index e3ed2aa0a..c758844d3 100644 --- a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart +++ b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart @@ -227,6 +227,9 @@ class MeetingStore extends ChangeNotifier int currentScreenSharePage = 0; + ///This stores whether whiteboard or screenshare is in full screen mode + bool isScreenshareWhiteboardFullScreen = false; + ///PeerList iterators ///This is a map with key as role and value as the iterator for that role Map peerListIterators = {}; @@ -1752,7 +1755,11 @@ class MeetingStore extends ChangeNotifier int peerIndex = peerTracks.indexWhere( (element) => element.uid == peer.peerId + track.trackId); if (peerIndex != -1) { - if ((screenShareCount - 1) == currentScreenSharePage) { + + ///This is done to handle the case when the screen share is stopped + ///and the user is on the last page of the screen share + ///we need to move the user to the previous page + if (((screenShareCount - 1) == currentScreenSharePage) && currentScreenSharePage > 0) { currentScreenSharePage--; } screenShareCount--; diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/peer_tile.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/peer_tile.dart index b1e9ee187..87cf00ff2 100644 --- a/packages/hms_room_kit/lib/src/widgets/common_widgets/peer_tile.dart +++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/peer_tile.dart @@ -2,17 +2,14 @@ import 'dart:developer'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:focus_detector_v2/focus_detector_v2.dart'; import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:provider/provider.dart'; // Project imports import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart'; -import 'package:hms_room_kit/src/meeting/meeting_store.dart'; import 'package:hms_room_kit/src/widgets/peer_widgets/local_peer_more_option.dart'; import 'package:hms_room_kit/src/widgets/peer_widgets/name_and_network.dart'; -import 'package:hms_room_kit/src/widgets/peer_widgets/screen_share_tile_name.dart'; import 'package:hms_room_kit/src/model/peer_track_node.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/degrade_tile.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/video_view.dart'; @@ -21,6 +18,7 @@ import 'package:hms_room_kit/src/widgets/peer_widgets/brb_tag.dart'; import 'package:hms_room_kit/src/widgets/peer_widgets/hand_raise.dart'; import 'package:hms_room_kit/src/widgets/peer_widgets/more_option.dart'; import 'package:hms_room_kit/src/widgets/peer_widgets/rtc_stats_view.dart'; +import 'package:hms_room_kit/src/widgets/whiteboard_screenshare/screenshare_tile.dart'; ///This widget is used to render the peer tile ///It contains following parameters @@ -132,256 +130,14 @@ class _PeerTileState extends State { child: LayoutBuilder( builder: (context, BoxConstraints constraints) { return Container( - decoration: BoxDecoration( - border: Border.all( - color: HMSThemeColors.surfaceDim, width: 1.0), - color: Colors.transparent, - borderRadius: - const BorderRadius.all(Radius.circular(10))), - key: key, - child: Stack( - children: [ - VideoView( - uid: context.read().uid, - scaleType: widget.scaleType, - ), - Positioned( - top: 5, - right: 5, - child: GestureDetector( - ///This is to show the screenshare in full screen - onTap: () { - showGeneralDialog( - context: context, - transitionBuilder: (dialogContext, - animation, - secondaryAnimation, - value) { - if (mounted) { - ///Setting the screenshare context - ///in the meeting store to store the current context - ///so that we can pop the dialog from the meeting store when screenshare is stopped - context - .read() - .screenshareContext = - dialogContext; - } - - ///Here we check whether the full screen screenshare is mounted or not - return context.mounted - ? Transform.scale( - scale: animation.value, - child: Opacity( - opacity: animation.value, - child: ListenableProvider - .value( - value: context.read< - PeerTrackNode>(), - child: Scaffold( - body: SafeArea( - child: Container( - color: HMSThemeColors - .backgroundDim, - height: - MediaQuery.of( - context) - .size - .height, - width: - MediaQuery.of( - context) - .size - .width, - child: Stack( - children: [ - InteractiveViewer( - child: - ListenableProvider - .value( - value: context - .read< - MeetingStore>(), - child: - VideoView( - uid: context - .read< - PeerTrackNode>() - .uid, - scaleType: - widget - .scaleType, - ), - ), - ), - Positioned( - top: 5, - right: 5, - child: - GestureDetector( - onTap: - () { - Navigator.pop( - dialogContext); - context - .read() - .screenshareContext = null; - }, - child: - Container( - height: - 40, - width: - 40, - decoration: BoxDecoration( - color: - HMSThemeColors.backgroundDim.withAlpha(64), - borderRadius: BorderRadius.circular(8)), - child: - Center( - child: - SvgPicture.asset( - "packages/hms_room_kit/lib/src/assets/icons/minimize.svg", - height: - 16, - width: - 16, - semanticsLabel: - "minimize_label", - colorFilter: - ColorFilter.mode(HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn), - ), - ), - ), - )), - Positioned( - //Bottom left - bottom: 5, - left: 5, - child: - Container( - decoration: BoxDecoration( - color: HMSThemeColors - .backgroundDim - .withOpacity( - 0.64), - borderRadius: - BorderRadius.circular(8)), - child: - Center( - child: - Padding( - padding: const EdgeInsets - .only( - left: - 8.0, - right: - 4, - top: - 4, - bottom: - 4), - child: - Row( - mainAxisSize: - MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - SvgPicture.asset( - "packages/hms_room_kit/lib/src/assets/icons/screen_share.svg", - height: 20, - width: 20, - colorFilter: ColorFilter.mode(HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn), - ), - const SizedBox( - width: 6, - ), - ScreenshareTileName(maxWidth: constraints.maxWidth) - ], - ), - ), - ), - ), - ), - ], - ), - ), - ), - ), - )), - ) - : Container(); - }, - pageBuilder: - (ctx, animation, secondaryAnimation) { - return Container(); - }); - }, - child: Container( - height: 40, - width: 40, - decoration: BoxDecoration( - color: HMSThemeColors.backgroundDim - .withAlpha(64), - borderRadius: BorderRadius.circular(8)), - child: Center( - child: SvgPicture.asset( - "packages/hms_room_kit/lib/src/assets/icons/maximize.svg", - height: 16, - width: 16, - semanticsLabel: "maximize_label", - colorFilter: ColorFilter.mode( - HMSThemeColors.onSurfaceHighEmphasis, - BlendMode.srcIn), - ), - ), - ), - )), - Positioned( - //Bottom left - bottom: 5, - left: 5, - child: Container( - decoration: BoxDecoration( - color: HMSThemeColors.backgroundDim - .withOpacity(0.64), - borderRadius: BorderRadius.circular(8)), - child: Center( - child: Padding( - padding: const EdgeInsets.only( - left: 8.0, right: 4, top: 4, bottom: 4), - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - "packages/hms_room_kit/lib/src/assets/icons/screen_share.svg", - height: 20, - width: 20, - colorFilter: ColorFilter.mode( - HMSThemeColors - .onSurfaceHighEmphasis, - BlendMode.srcIn), - ), - const SizedBox( - width: 6, - ), - ScreenshareTileName( - maxWidth: constraints.maxWidth) - ], - ), - ), - ), - ), - ), - const RTCStatsView(isLocal: false), - ], - ), - ); + decoration: BoxDecoration( + border: Border.all( + color: HMSThemeColors.surfaceDim, width: 1.0), + color: Colors.transparent, + borderRadius: + const BorderRadius.all(Radius.circular(10))), + key: key, + child: const ScreenshareTile()); }), ); }), diff --git a/packages/hms_room_kit/lib/src/widgets/grid_layouts/screen_share_grid_layout.dart b/packages/hms_room_kit/lib/src/widgets/grid_layouts/screen_share_grid_layout.dart index dd68dca23..60840098f 100644 --- a/packages/hms_room_kit/lib/src/widgets/grid_layouts/screen_share_grid_layout.dart +++ b/packages/hms_room_kit/lib/src/widgets/grid_layouts/screen_share_grid_layout.dart @@ -67,7 +67,7 @@ class _ScreenshareGridLayoutState extends State { if (widget.screenshareCount > 0) Expanded( child: PageView.builder( - physics: const PageScrollPhysics(), + physics: isFullScreen? const NeverScrollableScrollPhysics() :const PageScrollPhysics(), allowImplicitScrolling: true, itemCount: widget.screenshareCount, onPageChanged: (newPage) { @@ -92,7 +92,7 @@ class _ScreenshareGridLayoutState extends State { ///The number of dots is equal to [number of screens being shared] ///The active dot is the current page ///The inactive dots are the pages other than the current page - if (widget.screenshareCount > 1) + if (!isFullScreen && widget.screenshareCount > 1) Padding( padding: const EdgeInsets.only(top: 8.0), child: Selector( diff --git a/packages/hms_room_kit/lib/src/widgets/meeting_modes/custom_one_to_one_grid.dart b/packages/hms_room_kit/lib/src/widgets/meeting_modes/custom_one_to_one_grid.dart index 7e46cfc04..6712ba43d 100644 --- a/packages/hms_room_kit/lib/src/widgets/meeting_modes/custom_one_to_one_grid.dart +++ b/packages/hms_room_kit/lib/src/widgets/meeting_modes/custom_one_to_one_grid.dart @@ -54,7 +54,7 @@ class _CustomOneToOneGridState extends State { int pageCount = (numberOfPeers ~/ 6) + (numberOfPeers % 6 == 0 ? 0 : 1); - var screenshareStore = WhiteboardScreenshareStore(); + var screenshareStore = WhiteboardScreenshareStore(meetingStore: context.read()); ///If the remote peer is sharing screen then we render the [ScreenshareGridLayout] with inset tile ///Else we render the normal layout with inset tile diff --git a/packages/hms_room_kit/lib/src/widgets/whiteboard_screenshare/screenshare_tile.dart b/packages/hms_room_kit/lib/src/widgets/whiteboard_screenshare/screenshare_tile.dart new file mode 100644 index 000000000..5c2d06a17 --- /dev/null +++ b/packages/hms_room_kit/lib/src/widgets/whiteboard_screenshare/screenshare_tile.dart @@ -0,0 +1,105 @@ +library; + +///Package imports +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:hmssdk_flutter/hmssdk_flutter.dart'; +import 'package:provider/provider.dart'; + +///Project imports +import 'package:hms_room_kit/hms_room_kit.dart'; +import 'package:hms_room_kit/src/model/peer_track_node.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/video_view.dart'; +import 'package:hms_room_kit/src/widgets/peer_widgets/rtc_stats_view.dart'; +import 'package:hms_room_kit/src/widgets/peer_widgets/screen_share_tile_name.dart'; +import 'package:hms_room_kit/src/widgets/whiteboard_screenshare/whiteboard_screenshare_store.dart'; + +///[ScreenshareTile] is a widget that is used to render the screenshare tile +///It is used to render the screenshare of the peer +class ScreenshareTile extends StatelessWidget { + + const ScreenshareTile({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + VideoView( + uid: context.read().uid, + scaleType: ScaleType.SCALE_ASPECT_FIT, + ), + Positioned( + top: 5, + right: 5, + child: GestureDetector( + onTap: () { + context.read().toggleFullScreen(); + }, + child: Container( + height: 40, + width: 40, + decoration: BoxDecoration( + color: HMSThemeColors.backgroundDim.withAlpha(64), + borderRadius: BorderRadius.circular(8)), + child: Center( + child: Selector( + selector: (_, whiteboardScreenshareStore) => + whiteboardScreenshareStore.isFullScreen, + builder: (_, isFullScreen, __) { + return SvgPicture.asset( + "packages/hms_room_kit/lib/src/assets/icons/${isFullScreen ? "minimize" : "maximize"}.svg", + height: 16, + width: 16, + semanticsLabel: "maximize_label", + colorFilter: ColorFilter.mode( + HMSThemeColors.onSurfaceHighEmphasis, + BlendMode.srcIn), + ); + }), + ), + ), + )), + Positioned( + //Bottom left + bottom: 5, + left: 5, + child: Container( + decoration: BoxDecoration( + color: HMSThemeColors.backgroundDim.withOpacity(0.64), + borderRadius: BorderRadius.circular(8)), + child: Center( + child: Padding( + padding: const EdgeInsets.only( + left: 8.0, right: 4, top: 4, bottom: 4), + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + "packages/hms_room_kit/lib/src/assets/icons/screen_share.svg", + height: 20, + width: 20, + colorFilter: ColorFilter.mode( + HMSThemeColors.onSurfaceHighEmphasis, + BlendMode.srcIn), + ), + const SizedBox( + width: 6, + ), + LayoutBuilder( + builder: (context, BoxConstraints constraints) { + return ScreenshareTileName( + maxWidth: constraints.maxWidth); + }) + ], + ), + ), + ), + ), + ), + const RTCStatsView(isLocal: false), + ], + ); + } +} diff --git a/packages/hms_room_kit/lib/src/widgets/whiteboard_screenshare/whiteboard_screenshare_store.dart b/packages/hms_room_kit/lib/src/widgets/whiteboard_screenshare/whiteboard_screenshare_store.dart index 2e3663fd0..42919623f 100644 --- a/packages/hms_room_kit/lib/src/widgets/whiteboard_screenshare/whiteboard_screenshare_store.dart +++ b/packages/hms_room_kit/lib/src/widgets/whiteboard_screenshare/whiteboard_screenshare_store.dart @@ -2,13 +2,20 @@ library; ///Package imports import 'package:flutter/material.dart'; +import 'package:hms_room_kit/src/meeting/meeting_store.dart'; ///[WhiteboardScreenshareStore] is a store that stores the state of the whiteboard screenshare class WhiteboardScreenshareStore extends ChangeNotifier { + MeetingStore meetingStore; bool isFullScreen = false; + WhiteboardScreenshareStore({required this.meetingStore}) { + isFullScreen = meetingStore.isScreenshareWhiteboardFullScreen; + } + void toggleFullScreen() { isFullScreen = !isFullScreen; + meetingStore.isScreenshareWhiteboardFullScreen = isFullScreen; notifyListeners(); } }