bingo 1.0.1
bingo: ^1.0.1 copied to clipboard
A high-performance, synchronous state storage engine for Flutter with built-in caching and type-safe object registration.
import 'package:flutter/material.dart';
import 'package:bingo/bingo.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Bingo.setup();
// Mapping the User factory for Bingo's deep casting logic
Bingo.register<User>((json) => User.fromJson(json));
runApp(const BingoExampleApp());
}
class BingoExampleApp extends StatelessWidget {
const BingoExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: const Color(0xFF0D1117),
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.cyanAccent,
brightness: Brightness.dark,
),
),
home: const BingoDashboard(),
);
}
}
class BingoDashboard extends StatefulWidget {
const BingoDashboard({super.key});
@override
State<BingoDashboard> createState() => _BingoDashboardState();
}
class _BingoDashboardState extends State<BingoDashboard> {
final List<String> _logs = ["👾 Bingo Console Active"];
// Controllers for User Object Input
final _uIdCtrl = TextEditingController();
final _uNameCtrl = TextEditingController();
final _uEmailCtrl = TextEditingController();
final _uKeyCtrl = TextEditingController();
// Controllers for Retrieval & Deletion
final _queryCtrl = TextEditingController();
final _deleteCtrl = TextEditingController();
dynamic _queryResult;
String _resultType = "None";
void _log(String msg) =>
setState(() => _logs.insert(0, "[${DateTime.now().second}s] $msg"));
void _fetchData() {
final key = _queryCtrl.text.trim();
if (key.isEmpty) {
setState(() {
_queryResult = null;
_resultType = "None";
});
return;
}
// Attempting to call as User first, fallback to dynamic
dynamic result;
try {
result = Bingo.call<User>(key);
} catch (_) {
result = Bingo.call<dynamic>(key);
}
setState(() {
_queryResult = result;
_resultType = result?.runtimeType.toString() ?? "Null";
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
"B I N G O",
style: TextStyle(letterSpacing: 4, fontWeight: FontWeight.bold),
),
elevation: 0,
centerTitle: true,
foregroundColor: Colors.cyanAccent,
backgroundColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
children: [
// 1. USER GENERATOR (Now the main entry point)
_sectionHeader("USER GENERATOR"),
_glassContainer(
child: Column(
children: [
TextField(
controller: _uKeyCtrl,
decoration: const InputDecoration(
labelText: "Storage Key (Unique)",
prefixIcon: Icon(Icons.key, size: 18),
),
),
const SizedBox(height: 10),
Row(
children: [
Expanded(
child: TextField(
controller: _uIdCtrl,
decoration: const InputDecoration(
labelText: "User ID",
),
),
),
const SizedBox(width: 10),
Expanded(
child: TextField(
controller: _uNameCtrl,
decoration: const InputDecoration(labelText: "Name"),
),
),
],
),
TextField(
controller: _uEmailCtrl,
decoration: const InputDecoration(
labelText: "Email Address",
),
),
const SizedBox(height: 20),
_neonButton(
text: "GENERATE & MARK USER",
onTap: () {
if (_uKeyCtrl.text.isEmpty) {
_log("⚠️ Error: Storage Key is required.");
return;
}
final user = User(
id: _uIdCtrl.text,
name: _uNameCtrl.text,
email: _uEmailCtrl.text,
);
Bingo.mark(_uKeyCtrl.text, user);
_log(
"👤 User '${user.name}' marked at key '${_uKeyCtrl.text}'",
);
_uKeyCtrl.clear();
_uIdCtrl.clear();
_uNameCtrl.clear();
_uEmailCtrl.clear();
setState(() {});
},
),
],
),
),
const SizedBox(height: 25),
// 2. RETRIEVAL MODULE
_sectionHeader("USER DATA RETRIEVAL"),
_glassContainer(
child: Column(
children: [
TextField(
controller: _queryCtrl,
onChanged: (_) => _fetchData(),
decoration: const InputDecoration(
labelText: "Enter Key to Fetch",
prefixIcon: Icon(Icons.search),
),
),
const SizedBox(height: 15),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"TYPE: $_resultType",
style: const TextStyle(
color: Colors.cyanAccent,
fontSize: 10,
),
),
const Divider(color: Colors.white10),
Text(
_queryResult?.toString() ?? "No record found",
style: TextStyle(
fontSize: 13,
color: _queryResult == null
? Colors.grey
: Colors.white,
fontFamily: 'monospace',
),
),
],
),
),
],
),
),
const SizedBox(height: 25),
// 3. DESTRUCTION MODULE (Delete & Clear)
_sectionHeader("DESTRUCTION MODULE"),
_glassContainer(
child: Column(
children: [
TextField(
controller: _deleteCtrl,
decoration: const InputDecoration(
labelText: "Key to Erase",
prefixIcon: Icon(
Icons.delete_outline,
color: Colors.redAccent,
),
),
),
const SizedBox(height: 15),
Row(
children: [
Expanded(
child: _neonButton(
text: "ERASE KEY",
color: Colors.redAccent,
onTap: () {
if (_deleteCtrl.text.isNotEmpty) {
Bingo.erase(_deleteCtrl.text);
_log("🗑️ Erased key: ${_deleteCtrl.text}");
_deleteCtrl.clear();
_fetchData(); // Update retrieval if current key was deleted
}
},
),
),
const SizedBox(width: 12),
Expanded(
child: _neonButton(
text: "CLEAR ALL",
color: Colors.orangeAccent,
onTap: () {
Bingo.clear();
_log("☢️ DATABASE WIPED");
_fetchData();
setState(() {});
},
),
),
],
),
],
),
),
const SizedBox(height: 25),
// 4. LOGS
_sectionHeader("SYSTEM LOGS"),
Container(
height: 120,
width: double.infinity,
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.white10),
),
child: ListView.builder(
itemCount: _logs.length,
itemBuilder: (context, i) => Text(
_logs[i],
style: const TextStyle(
color: Colors.greenAccent,
fontFamily: 'monospace',
fontSize: 11,
),
),
),
),
],
),
),
);
}
// --- REUSABLE UI BUILDERS ---
Widget _sectionHeader(String title) {
return Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 8, left: 4),
child: Text(
title,
style: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.bold,
color: Colors.grey,
letterSpacing: 1.5,
),
),
),
);
}
Widget _glassContainer({required Widget child}) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.cyanAccent.withAlpha(40)),
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.cyan.withAlpha(15), Colors.transparent],
),
),
padding: const EdgeInsets.all(16),
child: child,
);
}
Widget _neonButton({
required String text,
required VoidCallback onTap,
Color color = Colors.cyanAccent,
}) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(999),
child: Container(
padding: const EdgeInsets.all(12),
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: color.withAlpha(80)),
borderRadius: BorderRadius.circular(999),
gradient: LinearGradient(
colors: [color.withAlpha(60), Colors.transparent],
),
),
child: Text(
text,
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.bold,
color: color,
),
),
),
);
}
}
class User {
final String id, name, email;
User({required this.id, required this.name, required this.email});
factory User.fromJson(Map<String, dynamic> json) =>
User(id: json['id'], name: json['name'], email: json['email']);
Map<String, dynamic> toJson() => {'id': id, 'name': name, 'email': email};
@override
String toString() => "User(ID: $id, Name: $name, Email: $email)";
}