# Circle Story (Flutter)

The `CircleStory` widget is built upon the `VideoFeed` widget, but each story item defaults to a circular shape rather than a rectangular one. Currently, there are eight source types of the circle story:

* Discover
* Channel
* Playlist
* Playlist Group(Only supported on iOS)
* Dynamic Content
* Hashtag Playlist
* SKU
* Single Content

## Integration

```dart
import 'package:fw_flutter_sdk/fw_flutter_sdk.dart';

/// discover
CircleStory(
  height: 200,
  source: VideoFeedSource.discover,
);

/// channel
CircleStory(
  height: 200,
  source: VideoFeedSource.channel,
  channel: "your encoded channel id",
);

/// playlist
CircleStory(
  height: 200,
  source: VideoFeedSource.playlist,
  channel: "your encoded channel id",
  playlist: "your encoded playlist id",
);


/// playlist group
CircleStory(
  height: 200,
  source: VideoFeedSource.playlistGroup,
  playlistGroup: "your encoded playlist group id",
);

/// dynamic content
CircleStory(
  height: 200,
  source: VideoFeedSource.dynamicContent,
  dynamicContentParameters: const {
    '<cohort key>': ['<cohort value1>', '<cohort value2>']
  },
);

/// hashtag playlist
CircleStory(
  height: 200,
  source: VideoFeedSource.hashtagPlaylist,
  channel: "your encoded channel id",
  hashtagFilterExpression: "<hashtag filter expression>",
);

/// sku playlist
CircleStory(
  height: 200,
  source: VideoFeedSource.sku,
  channel: "your encoded channel id",
  productIds: ["prodct_id_1", "prodct_id_2"],
);

/// single content
CircleStory(
  height: 200,
  source: VideoFeedSource.singleContent,
  contentId: "your encoded video or live stream id"
);
```

{% hint style="info" %}
Please refer to the [Encoded IDs](/firework-for-developers/additional-resources/encoded-ids.md) help article to learn about how to find your encoded channel ID, playlist ID, playlist Group ID
{% endhint %}

### Video feed loading result callback

`VideoFeed` widget provides `onVideoFeedLoadFinished` property for setting video feed loading result callback.

```dart
VideoFeed(
  source: VideoFeedSource.discover,
  onVideoFeedLoadFinished: (error) {},
);
```

### Empty callback

`CircleStory` widget provides `onCircleStoryEmpty` property for setting circle story empty callback. The callback is triggered when there are no items in the circle story. For example, you could hide the widget when the callback is triggered. The callback is triggered in the following scenarios:

1. Load successfully but the back end returns an empty list
2. The load failed and the list is empty

```dart
CircleStory(
  source: VideoFeedSource.discover,
  onCircleStoryEmpty: (error) {
    // Hide the widget
  },
);
```

### Force refreshing circle story

```dart
CircleStoryController? _controller;

CircleStory(
  source: VideoFeedSource.discover,
  onCircleStoryCreated: (controller) {
    _controller = controller;
  },
);

//force refreshing circle story
_controller?.refresh();
```

### Enable PiP(Picture in Picture)

Please refer to [Enable PiP(Picture in Picture)](https://docs.firework.com/firework-for-developers/ios-sdk/integration-guide-for-ios-sdk/customization-ios/video-player#enable-pip-picture-in-picture).

### Keep alive when scrolling the widget out of the view box

Generally, if you put the circle story widget as the child of ListView, it will be rebuilt when scrolling the widget out of the view box. You could set `wantKeepAlive` as `true` to make the circle story widget keep alive when scrolling the widget out of the view box.

```dart
CircleStory(
  height: 200,
  source: VideoFeedSource.discover,
  // Keep the widget alive when scrolling the widget out of the view box
  wantKeepAlive: true,
);
```

### onVideoFeedClick

Since `CircleStory` is based on `VideoFeed`, the `onVideoFeedClick` function is also applicable to each circle story item. The callback is triggered when users click the video feed or circle story item. The event type is [VideoFeedClickEvent](https://eng.firework.com/fw_flutter_sdk/v2/fw_flutter_sdk/VideoFeedClickEvent-class.html).

<pre class="language-dart"><code class="lang-dart"><strong>FireworkSDK.getInstance().onVideoFeedClick = (event) {};
</strong></code></pre>

### Circle story configurations

Please refer to [Circle story configurations](/firework-for-developers/flutter-sdk/integration-guide-v2/customization/circle-story-configurations-flutter.md).

### Player configurations

Please refer to [Player configurations (Flutter)](/firework-for-developers/flutter-sdk/integration-guide-v2/customization/player-configurations-flutter.md).

## Reference


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.firework.com/firework-for-developers/flutter-sdk/integration-guide-v2/circle-story.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
