182 lines
5.7 KiB
Dart
182 lines
5.7 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:no_screenshot/screenshot_snapshot.dart';
|
|
|
|
import 'no_screenshot_platform_interface.dart';
|
|
|
|
/// Callback type for screenshot and recording events.
|
|
typedef ScreenshotEventCallback = void Function(ScreenshotSnapshot snapshot);
|
|
|
|
/// A class that provides a platform-agnostic way to disable screenshots.
|
|
///
|
|
class NoScreenshot implements NoScreenshotPlatform {
|
|
NoScreenshotPlatform get _instancePlatform => NoScreenshotPlatform.instance;
|
|
NoScreenshot._();
|
|
|
|
@Deprecated(
|
|
"Using this may cause issue\nUse instance directly\ne.g: 'NoScreenshot.instance.screenshotOff()'",
|
|
)
|
|
NoScreenshot();
|
|
|
|
static final NoScreenshot instance = NoScreenshot._();
|
|
|
|
// ── Granular Callbacks (P15) ────────────────────────────────────────
|
|
|
|
/// Called when a screenshot is detected.
|
|
ScreenshotEventCallback? onScreenshotDetected;
|
|
|
|
/// Called when screen recording starts.
|
|
ScreenshotEventCallback? onScreenRecordingStarted;
|
|
|
|
/// Called when screen recording stops.
|
|
ScreenshotEventCallback? onScreenRecordingStopped;
|
|
|
|
StreamSubscription<ScreenshotSnapshot>? _callbackSubscription;
|
|
bool _wasRecording = false;
|
|
|
|
/// Starts dispatching events to [onScreenshotDetected],
|
|
/// [onScreenRecordingStarted], and [onScreenRecordingStopped].
|
|
///
|
|
/// Listens to [screenshotStream] internally. Call [stopCallbacks] or
|
|
/// [removeAllCallbacks] to cancel.
|
|
void startCallbacks() {
|
|
if (_callbackSubscription != null) return;
|
|
_callbackSubscription = screenshotStream.listen(_dispatchCallbacks);
|
|
}
|
|
|
|
/// Stops dispatching events but keeps callback assignments.
|
|
void stopCallbacks() {
|
|
_callbackSubscription?.cancel();
|
|
_callbackSubscription = null;
|
|
}
|
|
|
|
/// Stops dispatching and clears all callback assignments.
|
|
void removeAllCallbacks() {
|
|
stopCallbacks();
|
|
onScreenshotDetected = null;
|
|
onScreenRecordingStarted = null;
|
|
onScreenRecordingStopped = null;
|
|
_wasRecording = false;
|
|
}
|
|
|
|
/// Whether callbacks are currently being dispatched.
|
|
bool get hasActiveCallbacks => _callbackSubscription != null;
|
|
|
|
void _dispatchCallbacks(ScreenshotSnapshot snapshot) {
|
|
if (snapshot.wasScreenshotTaken) {
|
|
onScreenshotDetected?.call(snapshot);
|
|
}
|
|
if (!_wasRecording && snapshot.isScreenRecording) {
|
|
onScreenRecordingStarted?.call(snapshot);
|
|
}
|
|
if (_wasRecording && !snapshot.isScreenRecording) {
|
|
onScreenRecordingStopped?.call(snapshot);
|
|
}
|
|
_wasRecording = snapshot.isScreenRecording;
|
|
}
|
|
|
|
// ── Platform delegation ─────────────────────────────────────────────
|
|
|
|
/// Return `true` if screenshot capabilities has been
|
|
/// successfully disabled or is currently disabled and `false` otherwise.
|
|
/// throw `UnmimplementedError` if not implement
|
|
///
|
|
@override
|
|
Future<bool> screenshotOff() {
|
|
return _instancePlatform.screenshotOff();
|
|
}
|
|
|
|
/// Return `true` if screenshot capabilities has been
|
|
/// successfully enabled or is currently enabled and `false` otherwise.
|
|
/// throw `UnmimplementedError` if not implement
|
|
///
|
|
@override
|
|
Future<bool> screenshotOn() {
|
|
return _instancePlatform.screenshotOn();
|
|
}
|
|
|
|
@override
|
|
Future<bool> toggleScreenshotWithImage() {
|
|
return _instancePlatform.toggleScreenshotWithImage();
|
|
}
|
|
|
|
@override
|
|
Future<bool> toggleScreenshotWithBlur({double blurRadius = 30.0}) {
|
|
return _instancePlatform.toggleScreenshotWithBlur(blurRadius: blurRadius);
|
|
}
|
|
|
|
@override
|
|
Future<bool> toggleScreenshotWithColor({int color = 0xFF000000}) {
|
|
return _instancePlatform.toggleScreenshotWithColor(color: color);
|
|
}
|
|
|
|
/// Always enables image overlay mode (idempotent — safe to call repeatedly).
|
|
@override
|
|
Future<bool> screenshotWithImage() {
|
|
return _instancePlatform.screenshotWithImage();
|
|
}
|
|
|
|
/// Always enables blur overlay mode (idempotent — safe to call repeatedly).
|
|
@override
|
|
Future<bool> screenshotWithBlur({double blurRadius = 30.0}) {
|
|
return _instancePlatform.screenshotWithBlur(blurRadius: blurRadius);
|
|
}
|
|
|
|
/// Always enables color overlay mode (idempotent — safe to call repeatedly).
|
|
@override
|
|
Future<bool> screenshotWithColor({int color = 0xFF000000}) {
|
|
return _instancePlatform.screenshotWithColor(color: color);
|
|
}
|
|
|
|
/// Return `true` if screenshot capabilities has been
|
|
/// successfully toggle from it previous state and `false` if the attempt
|
|
/// to toggle failed.
|
|
/// throw `UnmimplementedError` if not implement
|
|
///
|
|
@override
|
|
Future<bool> toggleScreenshot() {
|
|
return _instancePlatform.toggleScreenshot();
|
|
}
|
|
|
|
/// Stream to screenshot activities [ScreenshotSnapshot]
|
|
///
|
|
@override
|
|
Stream<ScreenshotSnapshot> get screenshotStream {
|
|
return _instancePlatform.screenshotStream;
|
|
}
|
|
|
|
/// Start listening to screenshot activities
|
|
@override
|
|
Future<void> startScreenshotListening() {
|
|
return _instancePlatform.startScreenshotListening();
|
|
}
|
|
|
|
/// Stop listening to screenshot activities
|
|
@override
|
|
Future<void> stopScreenshotListening() {
|
|
return _instancePlatform.stopScreenshotListening();
|
|
}
|
|
|
|
/// Start listening to screen recording activities
|
|
@override
|
|
Future<void> startScreenRecordingListening() {
|
|
return _instancePlatform.startScreenRecordingListening();
|
|
}
|
|
|
|
/// Stop listening to screen recording activities
|
|
@override
|
|
Future<void> stopScreenRecordingListening() {
|
|
return _instancePlatform.stopScreenRecordingListening();
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
return identical(this, other) ||
|
|
other is NoScreenshot &&
|
|
runtimeType == other.runtimeType &&
|
|
_instancePlatform == other._instancePlatform;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => _instancePlatform.hashCode;
|
|
}
|