Pagination class
A stateless widget rendering pagination controls with breakout room access management.
Displays page navigation buttons for switching between main room and breakout rooms in video conferencing. Implements role-based access control (host can visit any room, participants restricted to assigned room), socket-based room switching, and server synchronization via updateHostBreakout events.
Lifecycle & State Management:
- Stateless widget (no internal state)
- Reads current page from options.currentUserPage
- Page changes trigger handlePageChange callback (typically updates parent state + server)
- Access control checks performed in handleClick() before page change
Access Control Logic (in handleClick):
if (breakOutRoomStarted && !breakOutRoomEnded && targetPage != 0) {
  // Calculate which breakout room the page represents
  breakRoomIndex = targetPage - (mainRoomsLength - 1);
  
  // Find user's assigned breakout room
  userBreakoutRoom = breakoutRooms.findIndex(room => room.contains(member));
  
  if (userBreakoutRoom != breakRoomIndex && breakRoomIndex >= 0) {
    // User trying to access non-assigned room
    if (islevel != '2') {
      // Non-host: deny access with alert
      showAlert("You are not part of the breakout room N");
      return;
    } else {
      // Host: allow access, emit updateHostBreakout to server
      handlePageChange(page, breakRoom: breakRoomIndex, inBreakRoom: true);
      socket.emit('updateHostBreakout', newRoom);
    }
  } else {
    // User accessing assigned room or main room
    handlePageChange(page, breakRoom: breakRoomIndex, inBreakRoom: true);
    if (host leaving previous room) socket.emit('updateHostBreakout', -1);
  }
} else {
  // Not in breakout session: allow any page navigation
  handlePageChange(page, breakRoom: 0, inBreakRoom: false);
}
Page Button Rendering Logic:
1. Determine page state:
   - isActive = page == currentUserPage
   - isHomePage = page == 0
   - isLocked = (breakout session active) && (page is breakout room) && (user not member) && (user not host)
   - displayLabel = isHomePage ? star icon : page number or "Room N" or "Room N 🔒"
2. Build baseContent:
   - isHomePage: Icon(Icons.star, color: isActive ? yellow : grey)
   - else: Text(displayLabel, fontSize: 16, fontWeight: bold)
3. Apply pageContentBuilder hook (if provided)
4. Wrap in GestureDetector + Container:
   - onTap: handleClick(page) if !isActive
   - decoration: activeDecoration (blue shadow) or inactiveDecoration (black border)
   - margin: 5px horizontal/vertical
   - constraints: buttonsContainerStyle (if provided)
5. Apply pageButtonBuilder hook (if provided)
Socket Event Emission:
Event: 'updateHostBreakout'
Payload:
  - newRoom: breakRoomIndex (host entering new room)
  - prevRoom: hostNewRoom (host leaving previous room, optional)
  - roomName: roomName (current meeting room name)
Emitted when:
  - Host switches to breakout room (newRoom = breakRoomIndex)
  - Host returns to main room (newRoom = -1, prevRoom = previous breakRoomIndex)
Common Use Cases:
- 
Basic Main Room Pagination: Pagination( options: PaginationOptions( totalPages: 5, // 0 (main) + 1-5 (participant pages) currentUserPage: 0, parameters: parameters, activePageColor: Colors.blue, inactivePageColor: Colors.grey[300], handlePageChange: (options) async { // Switch displayed participants based on page await updateMainGrid(options.page); }, ), )
- 
Breakout Room Navigation (Participant): // Scenario: 4 main pages, 3 breakout rooms; user in room 2 Pagination( options: PaginationOptions( totalPages: 7, // 0-3 (main) + 4-6 (rooms 1-3) currentUserPage: 0, parameters: PaginationParameters( mainRoomsLength: 4, memberRoom: 1, // user in breakout room 2 (0-indexed) breakOutRoomStarted: true, breakOutRoomEnded: false, member: 'john_doe', breakoutRooms: [ [BreakoutParticipant(name: 'alice')], [BreakoutParticipant(name: 'john_doe')], // user's room [BreakoutParticipant(name: 'charlie')], ], islevel: '1', // participant level showAlert: showAlertFunction, ), ), ) // Result: // - Page 0-3: numeric labels (1-3, main room) // - Page 4: "Room 1 🔒" (locked) // - Page 5: "Room 2" (unlocked, user's room) // - Page 6: "Room 3 🔒" (locked) // - Clicking locked room shows alert
- 
Breakout Room Navigation (Host): // Scenario: Host can visit any breakout room Pagination( options: PaginationOptions( totalPages: 7, currentUserPage: 5, // currently in breakout room 2 parameters: PaginationParameters( mainRoomsLength: 4, memberRoom: -1, // host not assigned to any room breakOutRoomStarted: true, breakOutRoomEnded: false, member: 'host_user', breakoutRooms: [[...], [...], [...]], hostNewRoom: 1, // host currently in room 2 (0-indexed) islevel: '2', // host level socket: socketInstance, roomName: 'meeting_room_123', ), ), ) // Result: // - All pages unlocked (no 🔒 symbols) // - Clicking room 1 (page 4): // 1. Emit socket event // 2. Update local state: hostNewRoom = 0 // 3. Switch to room 1 view
Override Integration:
Integrates with MediasfuUICustomOverrides for global styling:
overrides: MediasfuUICustomOverrides(
  paginationOptions: ComponentOverride<PaginationOptions>(
    builder: (existingOptions) => PaginationOptions(
      totalPages: existingOptions.totalPages,
      currentUserPage: existingOptions.currentUserPage,
      parameters: existingOptions.parameters,
      handlePageChange: existingOptions.handlePageChange,
      activePageColor: Colors.deepPurple,
      inactivePageColor: Colors.grey[100],
      backgroundColor: Colors.grey[50]!,
      buttonsContainerStyle: BoxConstraints.tightFor(width: 55, height: 45),
    ),
  ),
),
Responsive Behavior:
- Horizontal mode: maxHeight = paginationHeight, width expands
- Vertical mode: maxWidth = paginationHeight (acts as width), height expands
- ListView.builder creates buttons on demand (efficient for many pages)
- Visibility widget hides entire component when showAspect=false
Performance Notes:
- Stateless widget (no internal state to manage)
- ListView.builder lazily builds page buttons (efficient for large page counts)
- Access control checks only when button clicked (not during render)
- Socket events emitted with ack for reliable delivery
- Builder hooks called during every build (not cached)
Implementation Details:
- Uses ListView.builder for efficient pagination rendering
- Pages list generated via List.generate (0 to totalPages inclusive)
- Active/inactive decorations use BoxShadow for depth effect
- Home page (0) always uses star icon, others use text labels
- Breakout room numbers calculated as: page - (mainRoomsLength - 1)
- Socket emitWithAck ensures server receives updateHostBreakout events
- getUpdatedAllParams() called before access checks to get latest state
Typical Usage Context:
- Video conference main room pagination
- Breakout room navigation with role-based access
- Multi-page participant gallery
- Host-controlled breakout session management
- Room-based content switching with server sync
- Inheritance
- 
    - Object
- DiagnosticableTree
- Widget
- StatelessWidget
- Pagination
 
Constructors
- Pagination({Key? key, required PaginationOptions options})
- 
          
            const
Properties
- hashCode → int
- 
  The hash code for this object.
  no setterinherited
- key → Key?
- 
  Controls how one widget replaces another widget in the tree.
  finalinherited
- options → PaginationOptions
- 
  
  final
- runtimeType → Type
- 
  A representation of the runtime type of the object.
  no setterinherited
Methods
- 
  build(BuildContext context) → Widget 
- 
  Describes the part of the user interface represented by this widget.
  override
- 
  createElement() → StatelessElement 
- 
  Creates a StatelessElement to manage this widget's location in the tree.
  inherited
- 
  debugDescribeChildren() → List< DiagnosticsNode> 
- 
  Returns a list of DiagnosticsNode objects describing this node's
children.
  inherited
- 
  debugFillProperties(DiagnosticPropertiesBuilder properties) → void 
- 
  Add additional properties associated with the node.
  inherited
- 
  handleClick(int page, int offSet) → Future< void> 
- 
  noSuchMethod(Invocation invocation) → dynamic 
- 
  Invoked when a nonexistent method or property is accessed.
  inherited
- 
  toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode 
- 
  Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
  inherited
- 
  toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String 
- 
  A string representation of this object.
  inherited
- 
  toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String 
- 
  Returns a string representation of this node and its descendants.
  inherited
- 
  toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String 
- 
  Returns a one-line detailed description of the object.
  inherited
- 
  toStringShort() → String 
- 
  A short, textual description of this widget.
  inherited
Operators
- 
  operator ==(Object other) → bool 
- 
  The equality operator.
  inherited