101 lines
2.6 KiB
Dart
101 lines
2.6 KiB
Dart
|
import 'dart:convert';
|
||
|
import 'dart:io';
|
||
|
|
||
|
import 'package:http/http.dart' as http;
|
||
|
import 'package:signature/signature.dart';
|
||
|
|
||
|
class TimedPoint {
|
||
|
final DateTime time;
|
||
|
final Point point;
|
||
|
|
||
|
const TimedPoint({
|
||
|
required this.time,
|
||
|
required this.point,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
class HandwritingRequest {
|
||
|
final double appVersion;
|
||
|
final String apiLevel;
|
||
|
String? device;
|
||
|
final int inputType;
|
||
|
final String options;
|
||
|
final int writingAreaWidth;
|
||
|
final int writingAreaHeight;
|
||
|
final String preContext;
|
||
|
final int maxNumResults;
|
||
|
final int maxCompletions;
|
||
|
final String language;
|
||
|
final List<List<TimedPoint>> ink;
|
||
|
|
||
|
HandwritingRequest({
|
||
|
this.appVersion = 0.4,
|
||
|
this.apiLevel = '537.36',
|
||
|
this.device,
|
||
|
this.inputType = 0,
|
||
|
this.options = 'enable_pre_space',
|
||
|
required this.writingAreaWidth,
|
||
|
required this.writingAreaHeight,
|
||
|
this.preContext = '',
|
||
|
this.maxNumResults = 10,
|
||
|
this.maxCompletions = 0,
|
||
|
this.language = 'ja',
|
||
|
required this.ink,
|
||
|
});
|
||
|
|
||
|
List<List<dynamic>> get formattedInk => ink
|
||
|
.map(
|
||
|
(stroke) => [
|
||
|
stroke.map((tp) => tp.point.offset.dx).toList(),
|
||
|
stroke.map((tp) => tp.point.offset.dy).toList(),
|
||
|
stroke
|
||
|
.map((tp) => tp.time.difference(stroke.first.time).inMilliseconds)
|
||
|
.toList(),
|
||
|
],
|
||
|
)
|
||
|
.toList();
|
||
|
|
||
|
Map<String, Object?> toJson() => {
|
||
|
'app_version': appVersion,
|
||
|
'api_level': apiLevel,
|
||
|
'device': device,
|
||
|
'input_type': inputType,
|
||
|
'options': options,
|
||
|
'requests': [
|
||
|
{
|
||
|
'writing_guide': {
|
||
|
'writing_area_width': writingAreaWidth,
|
||
|
'writing_area_height': writingAreaHeight
|
||
|
},
|
||
|
'pre_context': preContext,
|
||
|
'max_num_results': maxNumResults,
|
||
|
'max_completions': maxCompletions,
|
||
|
'language': language,
|
||
|
'ink': formattedInk,
|
||
|
}
|
||
|
]
|
||
|
};
|
||
|
|
||
|
Future<List<String>> fetch() async {
|
||
|
device ??= HttpClient().userAgent;
|
||
|
final response = await http.post(
|
||
|
Uri.parse(
|
||
|
'https://inputtools.google.com/request?itc=ja-t-i0-handwrit&app=translate',
|
||
|
),
|
||
|
headers: <String, String>{
|
||
|
'Content-Type': 'application/json; charset=UTF-8',
|
||
|
},
|
||
|
body: jsonEncode(this),
|
||
|
);
|
||
|
|
||
|
final List<dynamic> json = jsonDecode(response.body);
|
||
|
// TODO: add a more detailed error.
|
||
|
if (response.statusCode != 200 || json[0] != 'SUCCESS') throw Error();
|
||
|
|
||
|
return (((json[1] as List<dynamic>)[0] as List<dynamic>)[1]
|
||
|
as List<dynamic>)
|
||
|
.map((e) => e as String)
|
||
|
.toList();
|
||
|
}
|
||
|
}
|