Files
FocusGram-Android/lib/utils/discipline_challenge.dart
Ujwal 7bb472d212 What's new
- Reordered Settings Page.
- Added "Click to Unblur" for posts.
- Added Persistent Notification
- Improved Grayscale Scheduling.
and more.
2026-03-04 10:48:14 +05:45

642 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_windowmanager_plus/flutter_windowmanager_plus.dart';
class DisciplineChallenge {
static const List<String> _words = [
'discipline',
'focus',
'growth',
'mindful',
'purpose',
'control',
'strength',
'clarity',
'vision',
'action',
'habit',
'success',
'power',
'balance',
'wisdom',
'patience',
'intent',
'choice',
'calm',
'peace',
'truth',
'grit',
'work',
'time',
'life',
'soul',
'mind',
'body',
'heart',
'will',
'hope',
'love',
'kind',
'help',
'give',
'take',
'stay',
'move',
'jump',
'run',
'walk',
'talk',
'sing',
'play',
'read',
'write',
'draw',
'cook',
'bake',
'farm',
'fish',
'hunt',
'grow',
'learn',
'teach',
'lead',
'follow',
'build',
'fix',
'save',
'spend',
'win',
'lose',
'try',
'fail',
'rise',
'fall',
'start',
'stop',
'wait',
'now',
'here',
'slow',
'fast',
'high',
'low',
'deep',
'wide',
'long',
'short',
'big',
'small',
'old',
'new',
'good',
'bad',
'real',
'fake',
'pure',
'dark',
'light',
'fire',
'water',
'earth',
'air',
'wind',
'storm',
'sun',
'moon',
'star',
'sky',
'road',
'path',
'gate',
'door',
'room',
'house',
'home',
'city',
'town',
'land',
'sea',
'ocean',
'lake',
'river',
'wood',
'tree',
'leaf',
'root',
'seed',
'fruit',
'food',
'bread',
'cake',
'milk',
'wine',
'beer',
'salt',
'gold',
'iron',
'rock',
'sand',
'dust',
'bone',
'blood',
'skin',
'hair',
'eyes',
'ears',
'nose',
'mouth',
'hand',
'foot',
'wing',
'tail',
'bird',
'cat',
'dog',
'bear',
'wolf',
'lion',
'deer',
'horse',
'cow',
'pig',
'sheep',
'goat',
'bee',
'ant',
'fly',
'worm',
'snake',
'frog',
'turtle',
'crab',
'whale',
'shark',
'dolphin',
'eagle',
'hawk',
'owl',
'swan',
'duck',
'goose',
'rose',
'lily',
'pine',
'oak',
'fern',
'moss',
'weed',
'grass',
'corn',
'rice',
'bean',
'pea',
'nut',
'oil',
'honey',
'wax',
'silk',
'wool',
'flax',
'hemp',
'paper',
'ink',
'pen',
'book',
'lamp',
'bed',
'chair',
'desk',
'wall',
'roof',
'step',
'mile',
'inch',
'yard',
'hour',
'day',
'week',
'month',
'year',
'age',
'past',
'next',
'death',
'birth',
'name',
'word',
'song',
'poem',
'story',
'myth',
'fact',
'law',
'rule',
'king',
'queen',
'lord',
'lady',
'man',
'woman',
'child',
'youth',
'elder',
'friend',
'foe',
'guest',
'host',
'war',
'fight',
'deal',
'buy',
'sell',
'pay',
'debt',
'cost',
'coin',
'cash',
'bank',
'shop',
'mall',
'mill',
'port',
'ship',
'boat',
'car',
'bus',
'bike',
'train',
'plane',
'street',
'hill',
'peak',
'cave',
'well',
'bridge',
'tower',
'fort',
'camp',
'tent',
'ash',
'smoke',
'coal',
'log',
'branch',
'stick',
'tool',
'hammer',
'nail',
'saw',
'knife',
'fork',
'spoon',
'bowl',
'cup',
'plate',
'pot',
'pan',
'stove',
'oven',
'sink',
'bath',
'soap',
'towel',
'comb',
'brush',
'mirror',
'clock',
'watch',
'ring',
'belt',
'boot',
'shoe',
'sock',
'hat',
'coat',
'shirt',
'pant',
'dress',
'skirt',
'bag',
'box',
'case',
'lock',
'key',
'bell',
'horn',
'drum',
'pipe',
'lute',
'harp',
'flute',
'reed',
'cord',
'rope',
'knot',
'net',
'hook',
'line',
'bait',
'trap',
'plow',
'hoe',
'rake',
'spade',
'crop',
'wheat',
'oats',
'rye',
'zinc',
'lead',
'copper',
'tin',
'silver',
'stone',
'clay',
'mud',
'rain',
'snow',
'hail',
'mist',
'fog',
'cloud',
'dawn',
'dusk',
'noon',
'night',
'ghost',
'angel',
'devil',
'god',
'fate',
'doom',
'fear',
'joy',
'woe',
'pain',
'care',
'hate',
'rage',
'lust',
'greed',
'pride',
'envy',
'sloth',
'wrath',
'holy',
'sin',
'hell',
'heaven',
'void',
'space',
'form',
'idea',
'thought',
'dot',
'circle',
'square',
'point',
'edge',
'flow',
'wave',
'tide',
'shore',
'bank',
'cliff',
'vale',
'meadow',
'field',
'plain',
'desert',
'forest',
'jungle',
'swamp',
'marsh',
'glade',
'grove',
'peak',
'ridge',
'slope',
'track',
'trail',
'lane',
'path',
'alley',
'court',
'plaza',
'park',
'bridge',
'tunnel',
'arch',
'dome',
'spire',
'tower',
'wall',
'fence',
'gate',
'stair',
'floor',
'beam',
'pole',
'mast',
'sail',
'deck',
'hull',
'keel',
'oar',
'helm',
'anchor',
'net',
'rope',
'knot',
'line',
'hook',
'bait',
'trap',
'net',
'spear',
'bow',
'arrow',
'sword',
'shield',
'armor',
'helm',
'boot',
'glove',
'cloak',
'scarf',
'belt',
'ujwal',
'ring',
'gem',
'jewel',
'pearl',
'gold',
'silver',
'bronze',
'iron',
'steel',
'brass',
'glass',
'stone',
'brick',
'tile',
'wood',
'clay',
'wax',
'ink',
'paint',
'dye',
'glue',
'oil',
'coal',
'gas',
'steam',
'heat',
'cold',
'ice',
'frost',
'thaw',
'melt',
'burn',
'glow',
'shine',
'beam',
'ray',
'spark',
'flash',
'flare',
'blast',
'shock',
'wave',
'pulse',
'beat',
'rhythm',
'tone',
'note',
'tune',
'song',
];
/// Shows the word challenge dialog. Returns true if successful.
static Future<bool> show(BuildContext context, {int count = 15}) async {
final list = List<String>.from(_words)..shuffle();
final challenge = list.take(count).join(' ');
final controller = TextEditingController();
// Prevent screenshots on Android
try {
await FlutterWindowManagerPlus.addFlags(
FlutterWindowManagerPlus.FLAG_SECURE,
);
} catch (_) {}
if (!context.mounted) return false;
final result = await showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (ctx) => AlertDialog(
backgroundColor: const Color(0xFF1A1A1A),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
title: const Row(
children: [
Icon(Icons.psychology, color: Colors.blue, size: 24),
SizedBox(width: 10),
Text(
'Discipline Challenge',
style: TextStyle(color: Colors.white, fontSize: 18),
),
],
),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'FocusGram is currently blocked to help you stay focused. Type the following sequence exactly to proceed:',
style: TextStyle(color: Colors.white70, fontSize: 14),
),
const SizedBox(height: 16),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.blue.withValues(alpha: 0.3)),
),
child: Text(
challenge,
style: const TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
fontSize: 14,
height: 1.5,
),
),
),
const SizedBox(height: 16),
TextField(
controller: controller,
autofocus: true,
enableInteractiveSelection:
false, // Prevents copy/paste/selection
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: 'Type here...',
hintStyle: const TextStyle(color: Colors.white24),
filled: true,
fillColor: Colors.white.withValues(alpha: 0.05),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide.none,
),
),
),
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx, false),
child: const Text(
'Cancel',
style: TextStyle(color: Colors.white38),
),
),
ElevatedButton(
onPressed: () {
if (controller.text.trim() == challenge) {
Navigator.pop(ctx, true);
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Incorrect sequence. Please try again.'),
backgroundColor: Colors.redAccent,
),
);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: const Text('Confirm'),
),
],
),
);
// Re-enable screenshots
try {
await FlutterWindowManagerPlus.clearFlags(
FlutterWindowManagerPlus.FLAG_SECURE,
);
} catch (_) {}
return result ?? false;
}
}