mirror of
https://github.com/Ujwal223/FocusGram.git
synced 2026-07-02 01:25:33 +02:00
172 lines
6.0 KiB
Dart
172 lines
6.0 KiB
Dart
import 'dart:math';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:hive/hive.dart';
|
|
|
|
/// Outcome of a Bait Me activation.
|
|
enum BaitOutcome {
|
|
/// Opens your ad website and resets the reels session.
|
|
openAdSiteAndReset,
|
|
|
|
/// Adds 10 minutes to the session credit balance.
|
|
addTenMinutes,
|
|
|
|
/// Opens an external ad URL and ends the session.
|
|
openExternalAdAndEnd,
|
|
|
|
/// Randomly reduces session time (1-5 min).
|
|
reduceSessionTime,
|
|
|
|
/// Increases cooldown by 10 min.
|
|
increaseCooldown,
|
|
|
|
/// Ends the current reel session.
|
|
endReelSession,
|
|
|
|
/// Ends the current app session.
|
|
endAppSession,
|
|
}
|
|
|
|
/// Weighted random outcome engine for the Bait Me button.
|
|
class BaitEngine extends ChangeNotifier {
|
|
static const String _boxName = 'bait_engine';
|
|
|
|
late Box _box;
|
|
final Random _random = Random();
|
|
|
|
// ── Hardcoded ad URLs ──────────────────────────────────────
|
|
String _adWebsiteUrl =
|
|
'https://www.effectivecpmnetwork.com/qbwsaqj5?key=e547ad0035c9e857ba0ee18506a45f13';
|
|
String _externalAdUrl =
|
|
'https://www.effectivecpmnetwork.com/qbwsaqj5?key=e547ad0035c9e857ba0ee18506a45f13';
|
|
|
|
// ── Cooldown ───────────────────────────────────────────────
|
|
static const int _cooldownMinutes = 30;
|
|
DateTime? _lastActivation;
|
|
|
|
// ── Callbacks ──────────────────────────────────────────────
|
|
void Function(int minutes)? onAddMinutes;
|
|
void Function()? onResetSession;
|
|
void Function()? onEndReelSession;
|
|
void Function()? onEndAppSession;
|
|
void Function(String url)? onOpenUrl;
|
|
void Function(int minutes)? onReduceSessionTime;
|
|
void Function(int minutes)? onIncreaseCooldown;
|
|
|
|
// ── Getters ────────────────────────────────────────────────
|
|
String get adWebsiteUrl => _adWebsiteUrl;
|
|
String get externalAdUrl => _externalAdUrl;
|
|
|
|
bool get isOnCooldown {
|
|
if (_lastActivation == null) return false;
|
|
return DateTime.now().difference(_lastActivation!).inMinutes <
|
|
_cooldownMinutes;
|
|
}
|
|
|
|
int get cooldownRemainingMinutes {
|
|
if (_lastActivation == null) return 0;
|
|
final elapsed = DateTime.now().difference(_lastActivation!).inMinutes;
|
|
return (_cooldownMinutes - elapsed).clamp(0, _cooldownMinutes);
|
|
}
|
|
|
|
// ─── Init ───────────────────────────────────────────────────
|
|
Future<void> init() async {
|
|
_box = await Hive.openBox(_boxName);
|
|
final lastMs = _box.get('last_activation_ms', defaultValue: 0) as int;
|
|
if (lastMs > 0) {
|
|
_lastActivation = DateTime.fromMillisecondsSinceEpoch(lastMs);
|
|
}
|
|
}
|
|
|
|
// ─── Activation ─────────────────────────────────────────────
|
|
BaitOutcome roll() {
|
|
final r = _random.nextInt(100);
|
|
// 30% open ad site + reset (permanent — always happens when rolled)
|
|
// 20% add 10 min
|
|
// 15% reduce session time
|
|
// 15% increase cooldown
|
|
// 10% end reel session
|
|
// 10% end app session
|
|
if (r < 30) return BaitOutcome.openAdSiteAndReset;
|
|
if (r < 50) return BaitOutcome.addTenMinutes;
|
|
if (r < 65) return BaitOutcome.reduceSessionTime;
|
|
if (r < 80) return BaitOutcome.increaseCooldown;
|
|
if (r < 90) return BaitOutcome.endReelSession;
|
|
return BaitOutcome.endAppSession;
|
|
}
|
|
|
|
Future<BaitOutcome> activate() async {
|
|
final outcome = roll();
|
|
_lastActivation = DateTime.now();
|
|
await _box.put(
|
|
'last_activation_ms', _lastActivation!.millisecondsSinceEpoch);
|
|
|
|
notifyListeners();
|
|
switch (outcome) {
|
|
case BaitOutcome.openAdSiteAndReset:
|
|
onResetSession?.call();
|
|
onOpenUrl?.call(_adWebsiteUrl);
|
|
break;
|
|
case BaitOutcome.addTenMinutes:
|
|
onAddMinutes?.call(10);
|
|
break;
|
|
case BaitOutcome.openExternalAdAndEnd:
|
|
onOpenUrl?.call(_externalAdUrl);
|
|
onResetSession?.call();
|
|
break;
|
|
case BaitOutcome.reduceSessionTime:
|
|
final min = 1 + _random.nextInt(5); // 1-5 min
|
|
onReduceSessionTime?.call(min);
|
|
break;
|
|
case BaitOutcome.increaseCooldown:
|
|
onIncreaseCooldown?.call(10);
|
|
break;
|
|
case BaitOutcome.endReelSession:
|
|
onEndReelSession?.call();
|
|
break;
|
|
case BaitOutcome.endAppSession:
|
|
onEndAppSession?.call();
|
|
break;
|
|
}
|
|
return outcome;
|
|
}
|
|
|
|
static String outcomeLabel(BaitOutcome o) {
|
|
switch (o) {
|
|
case BaitOutcome.openAdSiteAndReset:
|
|
return '💸 Session Reset!';
|
|
case BaitOutcome.addTenMinutes:
|
|
return '⏰ +10 Minutes!';
|
|
case BaitOutcome.openExternalAdAndEnd:
|
|
return '🚫 Session Ended!';
|
|
case BaitOutcome.reduceSessionTime:
|
|
return '⏳ Time Deducted!';
|
|
case BaitOutcome.increaseCooldown:
|
|
return '🧊 Cooldown Increased!';
|
|
case BaitOutcome.endReelSession:
|
|
return '🎬 Reel Session Ended!';
|
|
case BaitOutcome.endAppSession:
|
|
return '📱 App Session Ended!';
|
|
}
|
|
}
|
|
|
|
static String outcomeSubtext(BaitOutcome o) {
|
|
switch (o) {
|
|
case BaitOutcome.openAdSiteAndReset:
|
|
return 'All session credits have been reset. Better luck next time.';
|
|
case BaitOutcome.addTenMinutes:
|
|
return 'You earned 10 extra minutes. Use them wisely!';
|
|
case BaitOutcome.openExternalAdAndEnd:
|
|
return 'Session forcefully ended. Time for a break.';
|
|
case BaitOutcome.reduceSessionTime:
|
|
return 'The Bait Me took some time away!';
|
|
case BaitOutcome.increaseCooldown:
|
|
return 'Cooldown period extended by 10 minutes.';
|
|
case BaitOutcome.endReelSession:
|
|
return 'Your reel session has been cut short.';
|
|
case BaitOutcome.endAppSession:
|
|
return 'Your Instagram session has been ended.';
|
|
}
|
|
}
|
|
}
|