clean_pin 1.0.0
clean_pin: ^1.0.0 copied to clipboard
A tiny, UI-free PIN code logic controller for Flutter/Dart apps.
example/lib/main.dart
import 'dart:async';
import 'package:clean_pin_example/apple_lock_pin_code/apple_lock_pin_code.dart';
import 'package:clean_pin_example/bolid_product_pin_code/bolid_pin_code.dart';
import 'package:clean_pin_example/bolid_product_pin_code/styles/keyboard_style.dart';
import 'package:clean_pin_example/bolid_product_pin_code/styles/pin_number_style.dart';
import 'package:clean_pin_example/bolid_product_pin_code/widgets/keyboard_button.dart';
import 'manage_types/bloc_managment.dart';
import 'manage_types/ordinary_managment.dart';
import 'manage_types/riverpod_managment.dart';
import 'package:flutter/material.dart';
import 'package:clean_pin/clean_pin.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:local_auth/local_auth.dart' as la;
void main() {
runApp(const ProviderScope(child: PinDemoApp()));
}
/// Реализация шлюза биометрии через local_auth
class LocalAuthGateway implements BiometricGateway {
final _auth = la.LocalAuthentication();
@override
Future<BiometricStatus> status() async {
final can =
await _auth.canCheckBiometrics || await _auth.isDeviceSupported();
final typesRaw = await _auth.getAvailableBiometrics();
final types = typesRaw.map((t) {
switch (t) {
case la.BiometricType.face:
return BiometricType.face;
case la.BiometricType.fingerprint:
return BiometricType.fingerprint;
case la.BiometricType.iris:
return BiometricType.iris;
default:
return BiometricType.unknown;
}
}).toList();
return BiometricStatus(
canAuthenticate: can && types.isNotEmpty, types: types);
}
@override
Future<bool> authenticate(
{required String reason, bool stickyAuth = false}) async {
try {
final ok = await _auth.authenticate(
localizedReason: reason,
options: la.AuthenticationOptions(
biometricOnly: true,
stickyAuth: stickyAuth,
useErrorDialogs: true,
sensitiveTransaction: true,
),
);
return ok;
} catch (_) {
return false;
}
}
}
class PinDemoApp extends StatelessWidget {
const PinDemoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PIN Logic Demo',
theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.indigo),
home: const HomeTabs(),
);
}
}
class HomeTabs extends StatelessWidget {
const HomeTabs({super.key});
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 5,
child: Scaffold(
appBar: AppBar(
title: const Text('clean_pin'),
bottom: const TabBar(tabs: [
Tab(text: 'Vanilla'),
Tab(text: 'Riverpod'),
Tab(text: 'BLoC'),
Tab(text: 'Bolid PC'),
Tab(text: 'IOs PC'),
]),
),
body: TabBarView(
children: [
const VanillaScreen(),
const RiverpodScreen(),
const BlocScreen(),
BolidPinCode(
pinLen: 4,
onAuth: (pin) async {
await Future.delayed(Duration(milliseconds: 125));
return false;
},
leftSideButton: KeyboardButton(
child: Text(
"Exit",
style: TextStyle(
color: Colors.grey.shade500,
fontSize: 16,
fontFamily: 'CupertinoSystemText'),
),
),
rightSideButton: KeyboardButton(
onPressed: () {},
child: Icon(Icons.face),
),
pinCodeDecorations: PinCodeDecorations(
keyboardStyle: KeyboardStyle(
keyboardButtonStyle: KeyboardButtonStyle(
numberStyle:
TextStyle(color: Colors.grey.shade700, fontSize: 36)),
)),
),
const IOSLockPinScreen()
],
),
),
);
}
}
Future<bool> fakeServerValidator(String pin) async {
await Future.delayed(const Duration(milliseconds: 4000));
return pin == '1234';
}