Skip to content

Raw map

Use SeatLayerView and SeatLayerController from Flutter 0.7.2 when your application intentionally owns every buyer control and hold transition.

Updated View as Markdown

SeatLayerView is the low-level Flutter map. It remains source-compatible with the original 0.2.x surface inside seatlayer: 0.7.2.

Choose it only when your app will own confirmation, cart, hold timing, validation messages, test-mode disclosure, required attribution, recovery, and checkout. If you want a different arrangement without reimplementing those rules, use SeatLayerPickerScope instead.

Create and own the controller

raw_seat_map.dartdart
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:seatlayer/seatlayer.dart';

class RawSeatMap extends StatefulWidget {
  const RawSeatMap({super.key});

  @override
  State<RawSeatMap> createState() => _RawSeatMapState();
}

class _RawSeatMapState extends State<RawSeatMap> {
  final controller = SeatLayerController();
  StreamSubscription<void>? holdExpired;

  @override
  void initState() {
    super.initState();
    holdExpired = controller.onHoldExpired.listen((_) {
      returnBuyerToSelection();
    });
  }

  @override
  void dispose() {
    holdExpired?.cancel();
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SeatLayerView(
      controller: controller,
      configuration: SeatLayerConfiguration(
        event: 'ev_your_event_key',
        publicKey: 'pk_test_your_public_key',
        currency: 'USD',
      ),
      onReady: (info) => debugPrint('SeatLayer mode: ${info.mode.raw}'),
      onLoadError: showLoadError,
    );
  }
}

The controller and configuration are required. Keep one controller for the mounted view lifecycle, and give the map a definite height or full-screen parent.

For gated inventory, replace publicKey with the renewable provider:

final configuration = SeatLayerConfiguration(
  event: 'ev_private',
  buyerAccessTokenProvider: (request) =>
      buyerBackend.mintSeatLayerAccess(request.reason),
);

Your backend creates the native buyer-access session through buyer access sessions, returns only its short-lived token to the authenticated app, and treats SDK access details as opaque. It never exposes a SeatLayer secret.

Configuration map

Concern SeatLayerConfiguration fields
Identity and access event, publicKey, buyerAccessToken, buyerAccessTokenProvider
Selection policy maxSelection, selectedObjects, selectableObjects, numberOfPlacesToSelect, selectionValidators
Presentation locale, messages, currency, colorblindSafe, initialView, showsWebSeatTooltip
Operations commandTimeout, handshakeTimeout, hostInfo

See the complete tagged constructor and field documentation for types, defaults, and validation.

Common command groups

This table is a task-oriented map, not a substitute for the complete tagged API.

Group SeatLayerController methods
Read getSelection, getSelectionValidity, getCurrentHold, getGAAreas, getFloors, getViewMode
Select selectObjects, deselectObjects, clearSelection, selectCategories, deselectCategories, setSelectableObjects, setMaxSelection, setSeatTier
Hold hold, resumeHold, extendHold, release, releaseLabels, bestAvailable, holdGA
Access refreshAccess
Map setFloor, setColorblindSafe, setViewMode, zoomIn, zoomOut, zoomToFit
Session destroy, dispose

Use the tagged SeatLayerController source for exact parameters, return types, and every method in 0.7.2. Feature controls should also respect reported capability state; a public method does not prove a particular Event supports the operation.

Commands return Futures and throw SeatLayerError at the awaited call site.

try {
  final hold = await controller.hold();
  if (hold != null) {
    await checkoutBackend.begin(holdId: hold.holdId);
  }
} on SeatLayerError catch (error) {
  showInventoryMessage(error.code, error.message);
}

Typed streams

Important streams include onReady, onSelectionChanged, onSelectionValidityChanged, onHold, onHoldRestored, onHoldExpired, onBuyerAccessExpired, onBuyerAccessUnavailable, onSelectedObjectsUnavailable, onGAClick, onSeatHover, onError, and onUnknownEvent.

Subscribe once, retain each StreamSubscription, and cancel it from dispose. Unknown future enum values and events remain inspectable rather than crashing an older application.

Stream Payload and host responsibility
onSelectionChanged Full current List<SelectedSeat>; replace local selection rather than appending
onSelectionValidityChanged SelectionValidity; enable host confirmation only when the configured rules are satisfied
onHold, onHoldRestored, onHoldExpired Authoritative hold changes; expiry carries no reusable local hold
onBuyerAccessExpired, onBuyerAccessUnavailable Refresh outcome or access refusal; never silently widen private inventory
onSelectedObjectsUnavailable Labels and reason for inventory that must be removed from host UI
onError, onUnknownEvent Typed operational failure or forward-compatible raw event for diagnostics

Raw-map responsibilities

The complete picker normally owns these behaviors. A raw integration must provide them explicitly:

  • selection confirmation and validation feedback;
  • general-admission quantity and tier selection;
  • test-mode disclosure and required attribution;
  • hold countdown, server-authoritative expiry, resume, and release;
  • background/foreground reconciliation;
  • unavailable-inventory recovery;
  • gesture-safe overlays and accessible controls;
  • back-navigation behavior; and
  • secure checkout handoff.

Do not duplicate venue behavior by forwarding touch coordinates or placing the map inside another pan/zoom surface. Use typed commands and let the canvas own its gestures.

Security boundary

HoldResult contains a display-oriented view of a temporary hold. Send only holdId plus your own order context to your backend. The backend inspects the hold, calculates the authoritative price, takes payment, and reuses the same bookingRef for retries.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close