1
+ import 'dart:math' ;
2
+
1
3
import 'package:flutter/gestures.dart' ;
2
4
import 'package:flutter/material.dart' ;
3
5
import 'package:typetypego/config/config.dart' ;
@@ -69,7 +71,7 @@ class TextInputBox extends StatelessWidget {
69
71
}
70
72
71
73
/// The text field displayed in the [TextInputBox] .
72
- class TextInputBoxTextField extends StatelessWidget {
74
+ class TextInputBoxTextField extends StatefulWidget {
73
75
final TextEditingController ? controller;
74
76
final FocusNode focusNode;
75
77
final GlobalKey formKey;
@@ -81,15 +83,75 @@ class TextInputBoxTextField extends StatelessWidget {
81
83
required this .formKey,
82
84
required this .maxWordLength});
83
85
86
+ @override
87
+ _TextInputBoxTextFieldState createState () => _TextInputBoxTextFieldState ();
88
+ }
89
+
90
+ class _TextInputBoxTextFieldState extends State <TextInputBoxTextField > {
91
+ String _value = "" ;
92
+ String _difficulty = "VERY EASY" ;
93
+
94
+ /// Calculates the difficulty of the [value] and updates [_value] and [_difficulty] accordingly.
95
+ void _updateDifficulty (String value) {
96
+ setState (() {
97
+ final String trimmedValue = value.trim ();
98
+ _value = trimmedValue;
99
+
100
+ // Set the difficuly text to "VERY EASY" is the textbox is empty.
101
+ if (trimmedValue.isEmpty)
102
+ _difficulty = "VERY EASY" ;
103
+
104
+ // True if the textbox is not empty.
105
+ else {
106
+ // Create a list of all the easy characters.
107
+ final List <String > easyCharacters =
108
+ "abcdefghijklmnopqrstuvwxyz" .split ("" )..addAll ([" " , "\n " ]);
109
+
110
+ double difficultyPoints = 0 ;
111
+
112
+ // Loop through the text in the textbox.
113
+ trimmedValue.split ("" ).forEach ((String element) {
114
+ // True if the character is not easy.
115
+ if (! easyCharacters.contains (element)) {
116
+ // Add 0.25 to difficultPoints if the character is a capital letter.
117
+ if (easyCharacters.contains (element.toLowerCase ()))
118
+ difficultyPoints += 0.25 ;
119
+ // Add 0.5 to difficultPoints if the character is a number.
120
+ else if (double .tryParse (element) != null )
121
+ difficultyPoints += 0.5 ;
122
+ // Add 1 to difficultPoints if the character is a anything else, e.g. !, :, #,...
123
+ else
124
+ difficultyPoints++ ;
125
+ }
126
+ });
127
+
128
+ // Calculate the difficulty by dividing the points by the square root of the length of text.
129
+ final double difficulty = difficultyPoints / sqrt (trimmedValue.length);
130
+
131
+ // Update the difficuly text according to the calculated difficulty.
132
+ if (difficultyPoints < 0.75 )
133
+ _difficulty = "VERY EASY" ;
134
+ else if (difficulty < 1 )
135
+ _difficulty = "EASY" ;
136
+ else if (difficulty < 1.25 )
137
+ _difficulty = "MEDIUM" ;
138
+ else if (difficulty < 1.5 )
139
+ _difficulty = "HARD" ;
140
+ else
141
+ _difficulty = "VERY HARD" ;
142
+ }
143
+ });
144
+ }
145
+
84
146
@override
85
147
Widget build (BuildContext context) {
86
148
return Form (
87
- key: formKey,
149
+ key: widget. formKey,
88
150
child: SizedBox (
89
151
height: 200 ,
90
152
child: TextFormField (
91
- controller: controller,
92
- focusNode: focusNode,
153
+ controller: widget. controller,
154
+ focusNode: widget. focusNode,
93
155
validator: (value) {
94
156
final String trimmedValue = value! .trim ();
95
157
// True if the text field is empty.
@@ -104,11 +166,12 @@ class TextInputBoxTextField extends StatelessWidget {
104
166
.reduce ((value, element) =>
105
167
value.length > element.length ? value : element)
106
168
.length >
107
- maxWordLength) {
169
+ widget. maxWordLength) {
108
170
return 'A word is too long (try making your window bigger)' ;
109
171
}
110
172
return null ;
111
173
},
174
+ onChanged: _updateDifficulty,
112
175
maxLines: null ,
113
176
minLines: null ,
114
177
expands: true ,
@@ -123,6 +186,7 @@ class TextInputBoxTextField extends StatelessWidget {
123
186
color: Palette .blueGrey.withOpacity (0.5 ), fontSize: 16 ),
124
187
errorStyle: TextStyle (color: Palette .red, fontSize: 16 ),
125
188
counterStyle: TextStyle (color: Palette .blueGrey, fontSize: 16 ),
189
+ counterText: "Difficulty: $_difficulty - ${_value .length }/1000" ,
126
190
border: OutlineInputBorder (
127
191
borderRadius: BorderRadius .circular (Config .borderRadius)),
128
192
errorBorder: OutlineInputBorder (
0 commit comments