Skip to content

Embedded Clips#

StorytellerEmbeddedClipsView lets you place the native Storyteller clips experience inline within your Flutter UI while keeping full control of layout, scrolling, and lifecycle.

Basic usage#

class InlineClips extends StatelessWidget {
  const InlineClips({super.key});

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 420,
      child: StorytellerEmbeddedClipsView(
        collectionId: 'featured-highlights',
        shouldPlay: true,
        topLevelBack: false,
        onDataLoadStarted: () => debugPrint('Loading clips...'),
        onDataLoadComplete: (result) {
          debugPrint('Loaded ${result.dataCount} clips');
        },
      ),
    );
  }
}

Key parameters:

  • collectionId (required) – the Storyteller collection to play.
  • clipId – start playback at a specific clip.
  • initialCategory – open the embedded UI within a category.
  • shouldPlay – autoplay behaviour (defaults to true).
  • topLevelBack – whether to expose a back button for nested navigation.
  • theme – apply a StorytellerTheme override.
  • context – attach analytics context metadata.
  • topInset / bottomInset – provide safe area values in logical pixels. Available on Android only.

For a production-ready configuration (including safe-area handling and controller-driven playback), review the Showcase MomentsScreen.

React to embedded callbacks#

Three callbacks surface native lifecycle events:

  • onDataLoadStarted() – when Storyteller begins loading collection data.
  • onDataLoadComplete(StorytellerEmbeddedClipsLoadResult result) – includes status and counts; inspect result.error when result.success is false.
  • onUserActivityOccurred(Map<String, dynamic> payload) – emits the same payloads you see on the global onUserActivityOccurred stream, scoped to this embedded instance.

Control playback programmatically#

Attach a StorytellerEmbeddedClipsController to pause/resume playback, reload data, or propagate inset changes after creation.

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

  @override
  State<ControllableEmbeddedClips> createState() =>
      _ControllableEmbeddedClipsState();
}

class _ControllableEmbeddedClipsState
    extends State<ControllableEmbeddedClips> {
  final _controller = StorytellerEmbeddedClipsController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: StorytellerEmbeddedClipsView(
            collectionId: 'live-stream',
            controller: _controller,
            shouldPlay: false,
          ),
        ),
        FilledButton(
          onPressed: () async {
            await _controller.setShouldPlay(true);
          },
          child: const Text('Play clips'),
        ),
      ],
    );
  }
}

Available controller actions:

  • reloadData() – refreshes the native data source.
  • goBack() / canGoBack() – traverse nested embedded navigation.
  • setShouldPlay(bool) – toggle playback.
  • updateInsets({int top, int bottom}) – sync safe areas when your layout changes.

Calls made before the platform view is created are ignored (the embedded clips controller does not queue commands). Prefer invoking controller methods after the widget is on screen (for example, after the first frame) or in response to user interaction.