Jisho-Study-Tool/lib/services/handwriting.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();
}
}