init
This commit is contained in:
64
app/lib/services/api_service.dart
Normal file
64
app/lib/services/api_service.dart
Normal file
@@ -0,0 +1,64 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../models/sms_message.dart';
|
||||
|
||||
class ApiService {
|
||||
String _baseUrl = '';
|
||||
String? _token;
|
||||
|
||||
void configure(String baseUrl, String token) {
|
||||
_baseUrl = baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl;
|
||||
_token = token;
|
||||
}
|
||||
|
||||
Map<String, String> get _headers => {
|
||||
'Content-Type': 'application/json',
|
||||
if (_token != null) 'Authorization': 'Bearer $_token',
|
||||
};
|
||||
|
||||
Future<String> login(String username, String password) async {
|
||||
final res = await http.post(
|
||||
Uri.parse('$_baseUrl/api/auth/login'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'username': username, 'password': password}),
|
||||
);
|
||||
if (res.statusCode != 200) throw Exception(_error(res));
|
||||
return jsonDecode(res.body)['token'];
|
||||
}
|
||||
|
||||
Future<String> register(String username, String password) async {
|
||||
final res = await http.post(
|
||||
Uri.parse('$_baseUrl/api/auth/register'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'username': username, 'password': password}),
|
||||
);
|
||||
if (res.statusCode != 201) throw Exception(_error(res));
|
||||
return jsonDecode(res.body)['token'];
|
||||
}
|
||||
|
||||
Future<int> uploadSms(List<SmsMessage> messages) async {
|
||||
final res = await http.post(
|
||||
Uri.parse('$_baseUrl/api/sms/upload'),
|
||||
headers: _headers,
|
||||
body: jsonEncode(messages.map((m) => m.toJson()).toList()),
|
||||
);
|
||||
if (res.statusCode != 200) throw Exception(_error(res));
|
||||
return jsonDecode(res.body)['uploaded'];
|
||||
}
|
||||
|
||||
Future<void> registerDevice(String deviceName) async {
|
||||
await http.post(
|
||||
Uri.parse('$_baseUrl/api/devices/register'),
|
||||
headers: _headers,
|
||||
body: jsonEncode({'device_name': deviceName}),
|
||||
);
|
||||
}
|
||||
|
||||
String _error(http.Response res) {
|
||||
try {
|
||||
return jsonDecode(res.body)['error'] ?? 'Request failed';
|
||||
} catch (_) {
|
||||
return 'Request failed (${res.statusCode})';
|
||||
}
|
||||
}
|
||||
}
|
||||
43
app/lib/services/settings_service.dart
Normal file
43
app/lib/services/settings_service.dart
Normal file
@@ -0,0 +1,43 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class SettingsService {
|
||||
static const _keyServerUrl = 'server_url';
|
||||
static const _keyToken = 'token';
|
||||
static const _keyAutoUpload = 'auto_upload';
|
||||
|
||||
static const _keyUploaded = 'uploaded_keys';
|
||||
|
||||
final SharedPreferences _prefs;
|
||||
|
||||
SettingsService(this._prefs);
|
||||
|
||||
String? get serverUrl => _prefs.getString(_keyServerUrl);
|
||||
Future<bool> setServerUrl(String v) => _prefs.setString(_keyServerUrl, v);
|
||||
|
||||
String? get token => _prefs.getString(_keyToken);
|
||||
Future<bool> setToken(String v) => _prefs.setString(_keyToken, v);
|
||||
|
||||
bool get autoUpload => _prefs.getBool(_keyAutoUpload) ?? false;
|
||||
Future<bool> setAutoUpload(bool v) => _prefs.setBool(_keyAutoUpload, v);
|
||||
|
||||
bool get isConfigured => serverUrl != null && token != null;
|
||||
|
||||
Set<String> getUploadedKeys() => _prefs.getStringList(_keyUploaded)?.toSet() ?? <String>{};
|
||||
|
||||
Future<bool> addUploadedKey(String key) {
|
||||
final keys = _prefs.getStringList(_keyUploaded) ?? [];
|
||||
keys.add(key);
|
||||
return _prefs.setStringList(_keyUploaded, keys);
|
||||
}
|
||||
|
||||
Future<bool> addUploadedKeys(List<String> newKeys) {
|
||||
final keys = _prefs.getStringList(_keyUploaded) ?? [];
|
||||
keys.addAll(newKeys);
|
||||
return _prefs.setStringList(_keyUploaded, keys);
|
||||
}
|
||||
|
||||
static Future<SettingsService> init() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return SettingsService(prefs);
|
||||
}
|
||||
}
|
||||
36
app/lib/services/sms_reader_service.dart
Normal file
36
app/lib/services/sms_reader_service.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
import 'dart:async';
|
||||
import 'package:sms_maintained/sms_maintained.dart';
|
||||
import '../models/sms_message.dart';
|
||||
|
||||
class SmsReaderService {
|
||||
Future<List<SmsMessage>> queryAllSms() async {
|
||||
final messages = <SmsMessage>[];
|
||||
final all = await SmsQuery().querySms(
|
||||
kinds: [SmsQueryKind.Inbox, SmsQueryKind.Sent],
|
||||
);
|
||||
for (final s in all) {
|
||||
messages.add(SmsMessage(
|
||||
phoneNumber: s.address ?? '',
|
||||
contactName: s.sender ?? s.address,
|
||||
content: s.body ?? '',
|
||||
type: s.kind == SmsQueryKind.Sent ? 'sent' : 'received',
|
||||
smsDate: DateTime.fromMillisecondsSinceEpoch(s.date!).toUtc().toIso8601String(),
|
||||
));
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
Stream<SmsMessage> listenToIncoming() {
|
||||
final controller = StreamController<SmsMessage>.broadcast();
|
||||
SmsReceiver().onSmsReceived!.listen((SmsMessage sms) {
|
||||
controller.add(SmsMessage(
|
||||
phoneNumber: sms.address ?? '',
|
||||
contactName: sms.sender ?? sms.address,
|
||||
content: sms.body ?? '',
|
||||
type: 'received',
|
||||
smsDate: DateTime.now().toUtc().toIso8601String(),
|
||||
));
|
||||
});
|
||||
return controller.stream;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user