bogui/lib/screens/home.dart

279 lines
11 KiB
Dart

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<Bogui> createState() => _BoguiState();
}
class _BoguiState extends ConsumerState<Bogui> {
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: <Widget>[
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('...');
}
},
),
),
]),
);
}
}