flutter_notify_sphere 1.0.1
flutter_notify_sphere: ^1.0.1 copied to clipboard
Flutter SDK for NotifySphere (notifysphere.net) to monitor push notification delivery confirmations, click tracking, and user subscriptions on Android and iOS.
example/lib/main.dart
import 'dart:math' as math;
import 'dart:math';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_notify_sphere/flutter_notify_sphere.dart';
import 'package:flutter_notify_sphere_example/firebase_options.dart';
@pragma('vm:entry-point')
Future<void> backgroundHandler(RemoteMessage message) async {
debugPrint(
'Background handler calling from application: \n${message.notification?.title}',
);
}
void main() async {
try {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FlutterNotifySphere().initialize(
showForegroundNotification: true,
onForegroundMessage: (msg) {
debugPrint('FOREGROUND: ${msg.data.entries.toString()}');
},
onNotificationClick: (msg) {
debugPrint('CLICKED: ${msg?.data.toString()}');
},
backgroundMessageHandler: backgroundHandler,
);
} catch (e) {
debugPrint("Error in main: $e");
}
runApp(const Sunflower());
}
const int maxSeeds = 160;
class Sunflower extends StatefulWidget {
const Sunflower({super.key});
@override
State<StatefulWidget> createState() {
return _SunflowerState();
}
}
class _SunflowerState extends State<Sunflower> {
int seeds = maxSeeds ~/ 2;
TextEditingController controller = TextEditingController();
Map<String, dynamic> userData = {
"name": "Test User",
"email": "user@example.com",
};
@override
void initState() {
FlutterNotifySphere().registerUser(
userData: userData,
appId: "YOUR_NOTIFYSPHERE_APP_ID", // Replace with your App ID from notifysphere.net
apiKey: "YOUR_NOTIFYSPHERE_API_KEY", // Replace with your API Key from notifysphere.net
onFcmToken: (fcmToken) {
setState(() {
controller.text = " FCM Token: $fcmToken";
});
debugPrint("FCM Token: $fcmToken");
},
onRegistrationComplete: (subscriptionId) {
debugPrint("Registration Complete: $subscriptionId");
},
onError: (e) {
debugPrint("Notify Error: ${e.toString()}");
},
);
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
brightness: Brightness.dark,
appBarTheme: const AppBarTheme(elevation: 2),
),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const Text('Sunflower')),
body: SafeArea(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(child: SunflowerWidget(seeds)),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
child: TextField(
controller: controller,
decoration: const InputDecoration(
labelText: 'Number of seeds',
border: OutlineInputBorder(),
),
),
),
Text('Showing ${seeds.round()} seeds'),
SizedBox(
width: 300,
child: Slider(
min: 1,
max: maxSeeds.toDouble(),
value: seeds.toDouble(),
onChanged: (val) {
setState(() => seeds = val.round());
},
),
),
const SizedBox(height: 20),
],
),
),
),
),
);
}
}
class SunflowerWidget extends StatelessWidget {
static const tau = math.pi * 2;
static const scaleFactor = 1 / 40;
static const size = 600.0;
static final phi = (math.sqrt(5) + 1) / 2;
static final rng = math.Random();
final int seeds;
const SunflowerWidget(this.seeds, {super.key});
@override
Widget build(BuildContext context) {
final seedWidgets = <Widget>[];
for (var i = 0; i < seeds; i++) {
final theta = i * tau / phi;
final r = math.sqrt(i) * scaleFactor;
seedWidgets.add(
AnimatedAlign(
key: ValueKey(i),
duration: Duration(milliseconds: rng.nextInt(500) + 250),
curve: Curves.easeInOut,
alignment: Alignment(r * math.cos(theta), -1 * r * math.sin(theta)),
child: const Dot(true),
),
);
}
for (var j = seeds; j < maxSeeds; j++) {
final x = math.cos(tau * j / (maxSeeds - 1)) * 0.9;
final y = math.sin(tau * j / (maxSeeds - 1)) * 0.9;
seedWidgets.add(
AnimatedAlign(
key: ValueKey(j),
duration: Duration(milliseconds: rng.nextInt(500) + 250),
curve: Curves.easeInOut,
alignment: Alignment(x, y),
child: const Dot(false),
),
);
}
return FittedBox(
fit: BoxFit.contain,
child: SizedBox(
height: size,
width: size,
child: Stack(children: seedWidgets),
),
);
}
}
class Dot extends StatelessWidget {
static const size = 10.0;
static const radius = 5.0;
final bool lit;
const Dot(this.lit, {super.key});
// Generate a random color
// Generate bright colors by ensuring high RGB values
Color _getRandomBrightColor() {
final random = Random();
return Color.fromARGB(
255,
128 + random.nextInt(128), // 128-255
128 + random.nextInt(128), // 128-255
128 + random.nextInt(128), // 128-255
);
}
@override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
color: _getRandomBrightColor(),
borderRadius: BorderRadius.circular(radius),
border: Border.all(color: Colors.tealAccent, width: 0.5),
),
child: const SizedBox(height: size, width: size),
);
}
}