eksplicit mapping af envs
Some checks failed
Backend CI / test (push) Has been cancelled
Flutter CI / analyze-and-test (push) Has been cancelled

This commit is contained in:
Henrik Jess Nielsen
2026-05-12 18:21:25 +02:00
parent b7a435f8b9
commit 99e9b509a0
67 changed files with 8060 additions and 9 deletions

View File

@@ -0,0 +1,43 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:sighej/models/match_result.dart';
const _baseUrl = String.fromEnvironment('API_URL', defaultValue: 'http://10.0.2.2:8000');
/// Registers the user's profile with the backend session store.
Future<void> registerSession(
String bleToken,
List<String> interests, {
String name = '',
String tagline = '',
}) async {
final response = await http.post(
Uri.parse('$_baseUrl/session'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'ble_token': bleToken,
'interests': interests,
if (name.isNotEmpty) 'name': name,
if (tagline.isNotEmpty) 'tagline': tagline,
}),
);
if (response.statusCode != 200) {
throw Exception('Failed to register session: ${response.statusCode}');
}
}
/// Reports a detected BLE token to the backend and returns the match result.
/// Returns null if the backend returns a non-200 status (soft failure).
Future<MatchResult?> reportMatch(String ownToken, String detectedToken) async {
try {
final response = await http.post(
Uri.parse('$_baseUrl/match'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'own_token': ownToken, 'detected_token': detectedToken}),
);
if (response.statusCode != 200) return null;
return MatchResult.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} catch (_) {
return null;
}
}

View File

@@ -0,0 +1,89 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/foundation.dart';
import 'package:uuid/uuid.dart';
/// Persists the user's profile (nickname, tagline, interests) and ephemeral BLE
/// token locally. No data is ever sent without explicit user consent (toggle).
class SessionStore extends ChangeNotifier {
static const _interestsKey = 'interests';
static const _tokenKey = 'ble_token';
static const _nameKey = 'profile_name';
static const _taglineKey = 'profile_tagline';
static const _profileDoneKey = 'profile_done';
List<String> _interests = [];
String _bleToken = '';
String _name = '';
String _tagline = '';
bool _profileDone = false;
List<String> get interests => List.unmodifiable(_interests);
String get bleToken => _bleToken;
String get name => _name;
String get tagline => _tagline;
/// True once the user has completed profile setup at least once.
bool get hasProfile => _profileDone;
/// Display name — falls back to "Anonym" if not set.
String get displayName => _name.isNotEmpty ? _name : 'Anonym';
SessionStore() {
_load();
}
Future<void> _load() async {
final prefs = await SharedPreferences.getInstance();
_interests = prefs.getStringList(_interestsKey) ?? [];
_bleToken = prefs.getString(_tokenKey) ?? _newToken(prefs);
_name = prefs.getString(_nameKey) ?? '';
_tagline = prefs.getString(_taglineKey) ?? '';
_profileDone = prefs.getBool(_profileDoneKey) ?? false;
notifyListeners();
}
String _newToken(SharedPreferences prefs) {
final token = const Uuid().v4();
prefs.setString(_tokenKey, token);
return token;
}
/// Saves the full profile in one call. Marks profile as complete.
Future<void> saveProfile({
required String name,
required String tagline,
required List<String> interests,
}) async {
final prefs = await SharedPreferences.getInstance();
await Future.wait([
prefs.setString(_nameKey, name),
prefs.setString(_taglineKey, tagline),
prefs.setStringList(_interestsKey, interests),
prefs.setBool(_profileDoneKey, true),
]);
_name = name;
_tagline = tagline;
_interests = interests;
_profileDone = true;
notifyListeners();
}
/// Reset ephemeral identity — fresh BLE token, clears profile.
Future<void> reset() async {
final prefs = await SharedPreferences.getInstance();
await Future.wait([
prefs.remove(_interestsKey),
prefs.remove(_nameKey),
prefs.remove(_taglineKey),
prefs.remove(_profileDoneKey),
]);
_interests = [];
_name = '';
_tagline = '';
_profileDone = false;
_bleToken = _newToken(prefs);
notifyListeners();
}
}