flutter_story_kit 0.1.2
flutter_story_kit: ^0.1.2 copied to clipboard
Lightweight Instagram-style Flutter stories: images, videos, YouTube and Facebook embeds, media preload, and tap-to-action callbacks.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_story_kit/flutter_story_kit.dart';
void main() => runApp(const FlutterStoryKitExampleApp());
/// Demo application for the `flutter_story_kit` package by Moatez Zaghdoudi.
class FlutterStoryKitExampleApp extends StatelessWidget {
/// Creates the example app.
const FlutterStoryKitExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'flutter_story_kit example',
theme: ThemeData(colorSchemeSeed: Colors.deepPurple, useMaterial3: true),
home: const _HomePage(),
);
}
}
class _HomePage extends StatefulWidget {
const _HomePage();
@override
State<_HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<_HomePage> {
final _preloader = StoryPreloader();
late final List<Story> _stories = [
Story(
id: 'photo',
title: 'Photos',
thumbnailUrl: 'https://picsum.photos/seed/oui1/200',
media: [
StoryMedia.image(
'https://picsum.photos/seed/oui-story-1/1080/1920',
duration: const Duration(seconds: 5),
),
StoryMedia.image(
'https://picsum.photos/seed/oui-story-2/1080/1920',
duration: const Duration(seconds: 5),
action: const StoryAction(
type: 'link',
url: 'https://flutter.dev',
label: 'Open Flutter',
),
),
],
),
Story(
id: 'youtube',
title: 'YouTube',
thumbnailUrl: YoutubeLink.thumbnailUrl('dQw4w9WgXcQ'),
media: [
StoryMedia.youtube(
'https://youtu.be/dQw4w9WgXcQ',
duration: const Duration(seconds: 12),
),
],
action: const StoryAction(
type: 'weblink',
url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
),
),
];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_preloader.preload(_stories, context: context);
});
}
@override
void dispose() {
unawaited(_preloader.disposeAll());
super.dispose();
}
void _open(int index) {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (_) => StoryViewer(
stories: _stories,
initialIndex: index,
preloader: _preloader,
onSeen: (story) {
setState(() {
final i = _stories.indexWhere((item) => item.id == story.id);
if (i >= 0) _stories[i] = _stories[i].copyWith(seen: true);
});
},
onAction: (story, media, action) async {
final url = action.url;
if (url == null) return;
await showDialog<void>(
context: context,
builder: (ctx) => AlertDialog(
title: Text(action.type),
content: Text(url),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx),
child: const Text('Close'),
),
],
),
);
},
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('flutter_story_kit')),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.fromLTRB(16, 16, 16, 8),
child: Text('Tap a ring. Hold inside the viewer to pause.'),
),
StoryTray(
stories: _stories,
openViewer: false,
onStoryTap: _open,
),
const Spacer(),
const Padding(
padding: EdgeInsets.all(16),
child: Text('Created by Moatez Zaghdoudi'),
),
],
),
);
}
}