import 'package:bogui/global.dart'; import 'package:bogui/riverpods/home.dart'; import 'package:bogui/riverpods/openai.dart'; import 'package:bogui/widgets/parameters_sliders.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:url_launcher/url_launcher.dart'; class Bogui extends ConsumerStatefulWidget { const Bogui({super.key, required this.title}); final String title; @override ConsumerState createState() => _BoguiState(); } class _BoguiState extends ConsumerState { late OpenAI gpt; final promptFocus = FocusNode(); @override void initState() { gpt = OpenAI(); gpt.init(); super.initState(); } _handleValidation() { gpt.completionEasy(ref); promptFocus.requestFocus(); } @override Widget build(BuildContext context) { final scrollController = ScrollController(); screenWidth = MediaQuery.of(context).size.width; screenHight = MediaQuery.of(context).size.height; return Scaffold( appBar: AppBar( leading: Row( children: [ const SizedBox( width: 20, ), InkWell( onTap: () => launchUrl(Uri.parse('https://git.p2p.legal/librezo/bogui')), child: Container( height: 35, decoration: BoxDecoration( boxShadow: [ BoxShadow( color: yellowC.withOpacity(0.4), spreadRadius: 2, blurRadius: 1, offset: const Offset(0, 0), // changes position of shadow ), ], gradient: const RadialGradient( center: Alignment(3, -3), colors: [yellowC, orangeC], radius: 3.4, ), borderRadius: BorderRadius.circular(35), // color: Colors.grey[400], ), child: Image.asset( 'assets/gitea.png', // color: yellowC, scale: 45, ), )), ], ), bottomOpacity: 0.5, backgroundColor: orangeC, title: Center( child: Opacity( opacity: 0.7, child: Text( widget.title, style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w600), ), )), ), body: Stack(children: [ Center( child: SizedBox( width: screenWidth, child: Listener( onPointerSignal: (_) { // if (_ is PointerScrollEvent) { // scrollController.jumpTo( // max( // min( // scrollController.position.maxScrollExtent, // scrollController.offset + _.scrollDelta.dx, // ), // scrollController.position.minScrollExtent, // ), // ); // } }, child: SingleChildScrollView( controller: scrollController, child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Spacer(flex: screenWidth > 800 ? 3 : 2), Column( children: [ IconButton( onPressed: () => ref.read(gpt.prompt).text = '', icon: const Icon(Icons.close), color: Colors.redAccent, ), const SizedBox(height: 120) ], ), Column(children: [ const SizedBox(height: 40), Container( constraints: const BoxConstraints(minWidth: 300, maxWidth: 700), width: screenWidth - 600, child: CallbackShortcuts( bindings: { LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.enter): (() => _handleValidation()), }, child: TextField( autocorrect: false, scrollPhysics: const NeverScrollableScrollPhysics(), focusNode: promptFocus, controller: ref.read(gpt.prompt), autofocus: true, textInputAction: TextInputAction.search, // minLines: 3, maxLines: null, keyboardType: TextInputType.multiline, cursorColor: orangeC, style: const TextStyle( color: Color.fromARGB(255, 223, 223, 223), fontSize: 14, letterSpacing: 0.1, wordSpacing: 0.1, ), decoration: InputDecoration( filled: true, helperText: "Laissez-le autocompléter votre texte plutôt que de lui poser une question...", helperStyle: const TextStyle(fontSize: 10), hintText: "Qu'ils aillent tous se faire recompiler", hintStyle: const TextStyle( color: Color.fromARGB(255, 145, 145, 145), fontWeight: FontWeight.w100, fontSize: 14), // fillColor: Colors.white, prefixIconConstraints: const BoxConstraints( minHeight: 32, ), prefixIcon: const Padding( padding: EdgeInsets.symmetric(horizontal: 17), child: Icon( Icons.agriculture_outlined, color: orangeC, size: 30, )), border: OutlineInputBorder( borderSide: BorderSide( color: Colors.grey[500]!, width: 2), borderRadius: BorderRadius.circular(8)), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.grey[500]!, width: 2.5), borderRadius: BorderRadius.circular(8), ), contentPadding: const EdgeInsets.all(20), ), onSubmitted: (value) => promptFocus.requestFocus(), ), ), ), const SizedBox(height: 40), Opacity( opacity: 0.8, child: SizedBox( width: 200, height: 45, child: ElevatedButton( style: ElevatedButton.styleFrom( shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all( Radius.circular(7), ), ), foregroundColor: Colors.white, elevation: 0, backgroundColor: orangeC.withOpacity(0.9), // foreground ), onPressed: ref.watch(gpt.prompt).text.length > 100000000000 ? null : () { _handleValidation(); }, child: ref.watch(gpt.isLoading) ? const SizedBox( height: 18, width: 18, child: CircularProgressIndicator( color: yellowC, strokeWidth: 4, ), ) : Text( 'Boguer', style: TextStyle( color: const Color.fromARGB( 255, 255, 255, 255) .withOpacity(0.92), fontSize: 19, fontWeight: FontWeight.w500), ), ), ), ), const SizedBox(height: 5), const Text( 'ctrl + entrer', style: TextStyle(fontSize: 11, fontWeight: FontWeight.w100), ), const SizedBox(height: 40), ]), const Spacer(), if (screenWidth > 800) Column( children: [ CustomSlider( parameter: gpt.temperature, nameParameter: 'Température', ), ], ), const Spacer(), ]), ), ), ), ), Positioned( left: 15, top: screenHight - 80, child: FutureBuilder( future: getAppVersion(ref), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return Text( snapshot.data, style: const TextStyle( fontSize: 9, color: Color.fromARGB(255, 216, 216, 216), fontWeight: FontWeight.w100), ); } else { return const Text('...'); } }, ), ), ]), ); } }