js_notifications 0.0.3 copy "js_notifications: ^0.0.3" to clipboard
js_notifications: ^0.0.3 copied to clipboard

An extended NotificationsAPI for Dart Web notifications.

example/lib/main.dart

import 'dart:async';
//ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:js_notifications/interop/interop.dart';
import 'package:js_notifications/js_notifications_web.dart';
import 'package:js_notifications/platform_interface/js_notifications_platform_interface.dart';
import 'package:stop_watch_timer/stop_watch_timer.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _jsNotificationsPlugin = JsNotificationsPlatform.instance;
  final stopWatchTimer = StopWatchTimer();
  StreamSubscription<int>? _stopWatchTimerListener;
  final _boldTextStyle = const TextStyle(fontWeight: FontWeight.bold);
  bool _stopwatchSilent = false;

  static const _notificationTagStopwatch = "stopwatch";
  static const _notificationActionStopwatchStart = "stopwatch_start";
  static const _notificationActionStopwatchPause = "stopwatch_pause";
  static const _notificationActionStopwatchStop = "stopwatch_stop";

  static const _notificationActionStopwatchSilent = "stopwatch_silent";
  static const _notificationActionStopwatchHeadsUp = "stopwatch_headsup";

  static const _notificationActionDismiss = "dismiss";

  @override
  void initState() {
    super.initState();
    _jsNotificationsPlugin.actionStream.listen((event) {
      switch (event.action) {
        case "unexpected":
          {
            _sendBasicNotification("I know, neither did they.");
            break;
          }
        case _notificationActionDismiss:
          {
            if (event.tag == "inquisition") {
              _sendBasicNotification("Wey, you're next...");
            }
            break;
          }
        case "general_kenobi":
          {
            _sendGrievousConversation();
            break;
          }
        case "confused":
          {
            _sendBasicNotification("Go watch Star Wars, now!",
                tag: "star_wars_channel");
            break;
          }
        case "kill_him":
          {
            _sendBasicNotification("Good good, now go watch Star Wars!",
                tag: "star_wars_channel");
            break;
          }
        case "watch_star_wars":
          {
            _sendBasicNotification("Sure, click here to watch it.",
                tag: "rick_roll");
            break;
          }

        case _notificationActionStopwatchStart:
          {
            _startTimerNotification();
            break;
          }

        case _notificationActionStopwatchPause:
          {
            _pauseTimerNotification();
            _onSecondTimerTick();
            break;
          }

        case _notificationActionStopwatchStop:
          {
            _stopTimerNotification();
            _onSecondTimerTick();
            break;
          }

        case _notificationActionStopwatchSilent:
          {
            setState(() {
              _stopwatchSilent = true;
            });
            break;
          }

        case _notificationActionStopwatchHeadsUp:
          {
            setState(() {
              _stopwatchSilent = false;
            });
            break;
          }

        default:
          {
            if (event.tag == "rick_roll") {
              openNewWindow("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
            } else if (event.tag == "star_wars_channel") {
              openNewWindow("https://www.youtube.com/@StarWars");
            }
          }
      }
    });
    _jsNotificationsPlugin.dismissStream.listen((event) {
      switch (event.tag) {
        case "data-notification":
          {
            _sendBasicNotification("Dismissed data notification", tag: "");
            break;
          }
        case "grievous":
          {
            _sendBasicNotification(
                "My disappointment is immeasurable and my day is ruined.",
                tag: "ruined");
            break;
          }
      }
    });
  }

  void _onSecondTimerTick() {
    final formattedCallTime = StopWatchTimer.getDisplayTime(
        stopWatchTimer.rawTime.value,
        milliSecond: false);
    if (kDebugMode) {
      print("Timer: $formattedCallTime");
    }
    _jsNotificationsPlugin.showNotification(
      "Timer",
      body: formattedCallTime,
      tag: _notificationTagStopwatch,
      requireInteraction: !_stopwatchSilent,
      timestamp: DateTime.now().millisecondsSinceEpoch,
      icon: "icons/call.png",
      silent: _stopwatchSilent,
      actions: [
        if (stopWatchTimer.isRunning) ...[
          const JSNotificationAction(
              action: _notificationActionStopwatchPause, title: "Pause"),
          const JSNotificationAction(
              action: _notificationActionStopwatchStop, title: "Stop"),
        ] else ...[
          const JSNotificationAction(
              action: _notificationActionStopwatchStart, title: "Start"),
          const JSNotificationAction(
              action: _notificationActionDismiss, title: "Dismiss"),
        ],
        if (_stopwatchSilent)
          const JSNotificationAction(
              action: _notificationActionStopwatchHeadsUp, title: "Heads Up")
        else
          const JSNotificationAction(
              action: _notificationActionStopwatchSilent, title: "Silence"),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Column(
              children: [
                Text("Test Notification", style: _boldTextStyle),
                const SizedBox(height: 8),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        _sendBasicNotification("Test Notification",
                            tag: "test");
                      },
                      child: const Text("Test Notification"),
                    ),
                    const SizedBox(width: 4),
                    ElevatedButton(
                      onPressed: () {
                        _dismissBasicNotification();
                      },
                      child: const Text("Dismiss Test Notification"),
                    ),
                  ],
                ),
                const SizedBox(height: 24),
                Text("Data Notification", style: _boldTextStyle),
                const SizedBox(height: 8),
                ElevatedButton(
                  onPressed: () {
                    _sendDataNotification();
                  },
                  child: const Text("Data Notification"),
                ),
                const SizedBox(height: 24),
                Text("Custom Notifications", style: _boldTextStyle),
                const SizedBox(height: 8),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        _sendSpanishInquisition();
                      },
                      child: const Text("Expect the unexpected."),
                    ),
                    const SizedBox(width: 4),
                    ElevatedButton(
                      onPressed: () {
                        _sendGrievous();
                      },
                      child: const Text("Star Wars"),
                    ),
                  ],
                ),
              ],
            ),
            const SizedBox(height: 24),
            Column(
              children: [
                // Control timer notification
                Text("Timer Notification", style: _boldTextStyle),
                const SizedBox(height: 4),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        _startTimerNotification();
                      },
                      child: const Icon(Icons.play_arrow),
                    ),
                    const SizedBox(width: 8),
                    ElevatedButton(
                      onPressed: () {
                        _pauseTimerNotification();
                      },
                      child: const Icon(Icons.pause),
                    ),
                    const SizedBox(width: 8),
                    ElevatedButton(
                      onPressed: () {
                        _stopTimerNotification();
                      },
                      child: const Icon(Icons.stop),
                    )
                  ],
                ),
              ],
            ),
            const SizedBox(height: 8),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    _showTimerNotification();
                  },
                  child: const Text("Show Timer Notification"),
                ),
                const SizedBox(width: 8),
                ElevatedButton(
                  onPressed: () {
                    _hideTimerNotification();
                  },
                  child: const Text("Hide Timer Notification"),
                ),
              ],
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () {
                _clearAllNotifications();
              },
              child: const Text("Clear All"),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _sendDataNotification(
      {String? id, String? title, String? body, Map<String, dynamic>? data}) {
    final id0 = id ?? "data-notification";
    final title0 = title ?? "Data Notification";
    final body0 = body ?? "A notification with some data too";
    final data0 = {
      "string": "string",
      "1": 1,
      "false": false,
      "1.1": 1.1,
      'c': 'c',
      '[]': [],
      '{}': {},
      if (data != null) ...data,
    };

    return _jsNotificationsPlugin.showNotification(title0,
        body: body0, data: data0, tag: id0);
  }

  Future<void> _sendBasicNotification(String title, {String? tag}) {
    return _jsNotificationsPlugin.showNotification(title, tag: tag);
  }

  Future<void> _dismissBasicNotification() {
    return _jsNotificationsPlugin.dismissNotification(id: "test");
  }

  Future<void> _sendSpanishInquisition() {
    return _jsNotificationsPlugin.showNotification(
      "Oh no!",
      body:
          "Subverted expectations result in expected unexpected expectations. Anyway, check the icon...",
      tag: "inquisition",
      icon: "https://pbs.twimg.com/media/CtCG_f4WcAAJY-1.jpg",
      actions: [
        const JSNotificationAction(action: "dismiss", title: "Whatever"),
        const JSNotificationAction(
            action: "unexpected", title: "Didn't expect that"),
      ],
      requireInteraction: true,
    );
  }

  Future<void> _sendGrievous() {
    return _jsNotificationsPlugin.showNotification(
      "Obiwan Kenobi",
      tag: "grievous",
      body: "Hello there. How do you respond?",
      icon:
          "https://www.liveabout.com/thmb/F5lfgFptU9DNTDCT-xNEtot0lQ0=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/EP2-IA-60435_R_8x10-56a83bea3df78cf7729d314a.jpg",
      actions: [
        const JSNotificationAction(
            action: "general_kenobi", title: "General Kenobi"),
        const JSNotificationAction(action: "confused", title: "I'm confused"),
      ],
      requireInteraction: true,
    );
  }

  Future<void> _sendGrievousConversation() {
    return _jsNotificationsPlugin.showNotification(
      "Grievous",
      tag: "grievous_2",
      body: "You acknowledge he is a bold one. What do you do?",
      icon:
          "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQvS2A_Sb7z7dXcrPVscT0FeCdFO7IM88U2vg&s",
      actions: [
        const JSNotificationAction(action: "kill_him", title: "Kill Him"),
        const JSNotificationAction(
            action: "watch_star_wars", title: "Watch Star Wars"),
      ],
      requireInteraction: true,
    );
  }

  void _clearAllNotifications() {
    _jsNotificationsPlugin.clearNotifications();
  }

  void openNewWindow(String url) {
    html.window.open(url, "", 'noopener,noreferrer');
  }

  Future<void> _showTimerNotification() {
    return _jsNotificationsPlugin.showNotification(
      "Timer",
      tag: _notificationTagStopwatch,
      actions: [
        const JSNotificationAction(title: "Start", action: "stopwatch_start"),
        const JSNotificationAction(title: "Dismiss", action: "dismiss"),
      ],
      requireInteraction: true,
    );
  }

  void _startTimerNotification() {
    _stopWatchTimerListener ??=
        stopWatchTimer.secondTime.listen((_) => _onSecondTimerTick());
    _stopwatchSilent = false;
    stopWatchTimer.onStartTimer();
  }

  void _pauseTimerNotification() {
    stopWatchTimer.onStopTimer();
  }

  void _stopTimerNotification() {
    stopWatchTimer.onResetTimer();
  }

  void _hideTimerNotification() {
    stopWatchTimer.onStopTimer();
    _jsNotificationsPlugin.dismissNotification(id: _notificationTagStopwatch);
  }
}
0
likes
0
points
233
downloads

Publisher

verified publisherearthbase.io

Weekly Downloads

An extended NotificationsAPI for Dart Web notifications.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface, simple_print, uuid, web

More

Packages that depend on js_notifications