join_stories_flutter 1.0.0 copy "join_stories_flutter: ^1.0.0" to clipboard
join_stories_flutter: ^1.0.0 copied to clipboard

JOIN Stories Flutter SDK - Monolithic plugin for JOIN Stories

JOIN Stories Flutter Plugin #

A Flutter plugin to integrate JOIN Stories widgets and standalone player in Flutter apps.

🚀 Features #

  • Bubble, Card List, Card Grid widgets
  • Unified standalone player API (JOINStories.startPlayer)
  • Centralized event routing (triggers, player, analytics)
  • Refresh support via controllers (Bubble/Card)
  • Custom fonts on Android and iOS
  • iOS and Android support

Compatibility #

  • Flutter: 3.0.0+
  • Dart SDK: 2.17.0+
  • iOS: 12.0+
  • Android: API 21+

See COMPATIBILITY.md and COMPATIBILITY_SUMMARY.md for details.

Installation #

Add to your app’s pubspec.yaml:

dependencies:
  join_stories_flutter: ^0.0.1

iOS #

  • Set platform to 12.0+ in ios/Podfile:
platform :ios, '12.0'
  • Then run in ios/: pod repo update && pod install

Android #

  • No special setup required.

Initialization #

import 'package:join_stories_flutter/join_stories_flutter.dart';

await JOINStories.initialize(teamId: 'your-team-id');

// optional if provided by JOIN
await JOINStories.initialize(teamId: 'your-team-id', apiKey: 'your-api-key');

Widgets #

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

class MyStoriesPage extends StatefulWidget {
  const MyStoriesPage({super.key});
  @override
  State<MyStoriesPage> createState() => _MyStoriesPageState();
}

class _MyStoriesPageState extends State<MyStoriesPage> {
  final BubbleController _bubbleCtrl = BubbleController();
  final CardController _cardListCtrl = CardController();
  final CardController _cardGridCtrl = CardController();

  Future<void> _pullToRefresh() async {
    await _bubbleCtrl.refresh();
    await _cardListCtrl.refresh();
    await _cardGridCtrl.refresh();
  }

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: _pullToRefresh,
      child: ListView(
        children: [
          BubbleWidget(
            alias: 'bubble-alias',
            controller: _bubbleCtrl,
            configuration: const BubbleConfiguration(
              showLabel: true,
              labelFontSize: 14,
              fontName: 'Avenir',
              // player customization available here as well
            ),
            onTriggerFetchSuccess: (count) {},
            onTriggerFetchEmpty: () {},
            onTriggerFetchError: (msg) {},
            onPlayerFetchSuccess: () {},
            onPlayerLoaded: () {},
            onPlayerFetchError: (msg) {},
            onPlayerDismissed: (type) {}, // 'auto' | 'manual'
            onContentLinkClick: (link) {},
            onAnalyticsEvent: (name, payload) {},
          ),
          CardListWidget(
            alias: 'card-list-alias',
            controller: _cardListCtrl,
            configuration: const CardConfiguration(
              showLabel: true,
              cardRadius: 12,
            ),
          ),
          CardGridWidget(
            alias: 'card-grid-alias',
            controller: _cardGridCtrl,
            configuration: const CardConfiguration(
              numberOfColumns: 2,
              cardSize: 150,
            ),
          ),
        ],
      ),
    );
  }
}

Standalone Player #

Single unified method (customization + callbacks):

await JOINStories.startPlayer(
  'widget-alias',
  standaloneOrigin: 'top', // 'top'|'topLeft'|'topRight'|'bottom'|'bottomLeft'|'bottomRight'
  playerBackgroundColor: 0xFF2C3E50,
  playerVerticalAnchor: 'center',
  playerHorizontalMargins: 20.0,
  playerCornerRadius: 12.0,
  playerProgressBarDefaultColor: 0xFF7F8C8D,
  playerProgressBarFillColor: 0xFF3498DB,
  playerProgressBarThickness: 4.0,
  playerProgressBarRadius: 8.0,
  onPlayerFetchSuccess: () {},
  onPlayerLoaded: () {},
  onPlayerFetchError: (msg) {},
  onPlayerDismissed: (type) {},
  onContentLinkClick: (link) {},
  onAnalyticsEvent: (eventName, payload) {},
);

Analytics & Identification #

await JOINStories.setTrackingUserId('user_123');
await JOINStories.sendConversion('purchase', 'ecommerce');
await JOINStories.setSegmentationKey('premium_user');

All analytics events are routed to Flutter via:

onAnalyticsEvent(String eventName, Map<String, dynamic> payload)

Note (iOS widgets): until per-widget IDs are available, analytics include viewId: -1 (global). The plugin broadcasts to mounted widgets so callbacks still fire.

Custom Fonts #

JOIN widgets are native views. Make the font available on both Flutter and native sides.

Flutter #

Add fonts under assets/fonts/ and declare in pubspec.yaml:

flutter:
  uses-material-design: true
  fonts:
    - family: Parisienne
      fonts:
        - asset: assets/fonts/Parisienne-Regular.ttf

Optional global theme:

MaterialApp(theme: ThemeData(fontFamily: 'Parisienne'))

iOS #

  • Copy the font into ios/Runner/Fonts/Parisienne-Regular.ttf (Target Membership: Runner)
  • Add in ios/Runner/Info.plist under UIAppFonts:
<string>Fonts/Parisienne-Regular.ttf</string>
  • Use the exact PostScript name in JOIN configs: fontName: 'Parisienne-Regular'

Android #

  • Either put the font under android/app/src/main/res/font/ or keep it in Flutter assets.
  • Pass the same fontName as iOS; the bridge will try assets first, then res/font, then system font.

Refresh Widgets #

Recommended: use controllers and call refresh() (see example above).

Advanced: call the API directly if you have a viewId:

await JOINStories.refreshWidget(viewId: someViewId, type: 'bubble'); // or 'card'

Example #

See the example/ directory for a complete example application.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

0
likes
140
points
157
downloads

Publisher

unverified uploader

Weekly Downloads

JOIN Stories Flutter SDK - Monolithic plugin for JOIN Stories

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on join_stories_flutter

Packages that implement join_stories_flutter