diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index b3ad3fa..240d9ad 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -11,27 +11,13 @@
-
-
-
-
-
-
-
-
-
-
_baseUrl;
- static void setBaseUrl(String url) {
+ static void setBaseUrl(String url){
_baseUrl = url.endsWith('/') ? url.substring(0, url.length - 1) : url;
}
diff --git a/lib/main.dart b/lib/main.dart
index 6e35cb2..fb7aedc 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -12,6 +12,7 @@ import 'services/settings_service.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final settings = SettingsService();
+ await settings.initialize();
ApiConfig.setBaseUrl(settings.baseUrl);
final bgGeo = BackgroundGeoService();
await bgGeo.init();
diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart
index a25f5fc..826bbab 100644
--- a/lib/screens/login_screen.dart
+++ b/lib/screens/login_screen.dart
@@ -30,13 +30,18 @@ class _LoginScreenState extends State
_tabController.addListener(() {
setState(() {});
});
- final settings = context.read();
- _serverUrlController.text = settings.baseUrl;
- _loginController.text = settings.login ?? "";
- _passwordController.text = settings.pwd ?? "";
- if (settings.login != null && settings.pwd != null) {
- savedAuth = true;
- }
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ final settings = context.read();
+ _serverUrlController.text = settings.baseUrl;
+ _loginController.text = settings.login ?? "";
+ _passwordController.text = settings.pwd ?? "";
+ if (settings.login != null && settings.pwd != null) {
+ savedAuth = true;
+ final authProvider = context.read();
+ login(settings.login!, settings.pwd!, authProvider);
+ Navigator.of(context).pushReplacementNamed('/map');
+ }
+ });
}
@override
@@ -53,15 +58,6 @@ class _LoginScreenState extends State
Widget build(BuildContext context) {
final authProvider = context.watch();
final settings = context.read();
- if (savedAuth) {
- login(
- _loginController.text,
- _passwordController.text,
- context,
- authProvider,
- settings,
- );
- }
return Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
@@ -77,7 +73,7 @@ class _LoginScreenState extends State
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
- 'Family Safety',
+ 'Авторизация',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 32,
@@ -174,11 +170,13 @@ class _LoginScreenState extends State
}
}
if (_tabController.index == 0) {
+ print("Login...");
try {
await authProvider.login(
_loginController.text,
_passwordController.text,
);
+ settings.saveAuth(_loginController.text, _passwordController.text);
if (!context.mounted) return;
Navigator.of(
context,
@@ -233,15 +231,10 @@ class _LoginScreenState extends State
Future login(
String login,
String pwd,
- BuildContext ctx,
AuthProvider authProvider,
- SettingsService settings,
) async {
try {
await authProvider.login(login, pwd);
- settings.saveAuth(login, pwd);
- if (!ctx.mounted) return;
- Navigator.of(ctx).pushReplacementNamed('/map');
} catch (e) {
// Error is handled by provider
}
diff --git a/lib/screens/map_screen.dart b/lib/screens/map_screen.dart
index 0cbcb9e..1db6aa2 100644
--- a/lib/screens/map_screen.dart
+++ b/lib/screens/map_screen.dart
@@ -1,4 +1,5 @@
import 'dart:async';
+import 'package:GeoShare/services/settings_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_map/flutter_map.dart';
@@ -27,7 +28,7 @@ class _MapScreenState extends State {
@override
void initState() {
super.initState();
- _initLocationAndShare();
+ //_initLocationAndShare();
}
@override
@@ -93,7 +94,7 @@ class _MapScreenState extends State {
_geoTimer = Timer.periodic(
const Duration(seconds: 30),
- (_) => _updateGeolocation(),
+ (_) => _updateGeolocation(),
);
} catch (_) {
setState(() => _loading = false);
@@ -150,21 +151,22 @@ class _MapScreenState extends State {
showModalBottomSheet(
context: context,
isScrollControlled: true,
- builder: (context) => _WatchMenu(
- token: authProvider.token,
- onAdd: (shareId) async {
- await shareProvider.addTracking(shareId, authProvider.token);
- if (shareProvider.trackedPeople.length == 1) {
- shareProvider.startTrackingPolling(authProvider.token);
- }
- },
- onRemove: (shareId) {
- shareProvider.removeTracking(shareId);
- if (shareProvider.trackedPeople.isEmpty) {
- shareProvider.stopAllTracking();
- }
- },
- ),
+ builder: (context) =>
+ _WatchMenu(
+ token: authProvider.token,
+ onAdd: (shareId) async {
+ await shareProvider.addTracking(shareId, authProvider.token);
+ if (shareProvider.trackedPeople.length == 1) {
+ shareProvider.startTrackingPolling(authProvider.token);
+ }
+ },
+ onRemove: (shareId) {
+ shareProvider.removeTracking(shareId);
+ if (shareProvider.trackedPeople.isEmpty) {
+ shareProvider.stopAllTracking();
+ }
+ },
+ ),
);
}
@@ -207,6 +209,7 @@ class _MapScreenState extends State {
final authProvider = context.watch();
final _ = context.watch();
final shareProvider = context.watch();
+ final settings = context.read();
if (_loading) {
return Scaffold(body: const Center(child: CircularProgressIndicator()));
@@ -215,7 +218,8 @@ class _MapScreenState extends State {
return Scaffold(
appBar: AppBar(
title: Text(
- 'Family Safety Map\n${_center.latitude.toStringAsFixed(4)}, ${_center.longitude.toStringAsFixed(4)}',
+ 'Карта\n${_center.latitude.toStringAsFixed(4)}, ${_center
+ .longitude.toStringAsFixed(4)}',
textAlign: TextAlign.center,
),
actions: [
@@ -223,7 +227,10 @@ class _MapScreenState extends State {
icon: const Icon(Icons.refresh),
onPressed: _updateGeolocation,
),
- IconButton(icon: const Icon(Icons.share), onPressed: _copyShareLink),
+ IconButton(icon: const Icon(Icons.share), onPressed: () {
+ _initLocationAndShare();
+ _copyShareLink();
+ }),
IconButton(
icon: const Icon(Icons.visibility),
onPressed: _openWatchMenu,
@@ -236,6 +243,7 @@ class _MapScreenState extends State {
await bgGeo.stop();
bgGeo.dispose();
authProvider.logout();
+ settings.logOut();
Navigator.of(context).pushReplacementNamed('/');
},
),
@@ -287,7 +295,10 @@ class _WatchMenuState extends State<_WatchMenu> {
return Padding(
padding: EdgeInsets.only(
- bottom: MediaQuery.of(context).viewInsets.bottom,
+ bottom: MediaQuery
+ .of(context)
+ .viewInsets
+ .bottom,
),
child: Container(
constraints: const BoxConstraints(maxHeight: 400),
@@ -297,7 +308,10 @@ class _WatchMenuState extends State<_WatchMenu> {
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.surfaceContainerHighest,
+ color: Theme
+ .of(context)
+ .colorScheme
+ .surfaceContainerHighest,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(16),
),
@@ -354,8 +368,9 @@ class _WatchMenuState extends State<_WatchMenu> {
title: Text(person.name),
subtitle: hasPosition
? Text(
- '${person.position!['y'].toStringAsFixed(4)}, ${person.position!['x'].toStringAsFixed(4)}',
- )
+ '${person.position!['y'].toStringAsFixed(4)}, ${person
+ .position!['x'].toStringAsFixed(4)}',
+ )
: const Text('Нет данных'),
trailing: IconButton(
icon: const Icon(Icons.close, color: Colors.red),
@@ -368,7 +383,10 @@ class _WatchMenuState extends State<_WatchMenu> {
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.surfaceContainerHighest,
+ color: Theme
+ .of(context)
+ .colorScheme
+ .surfaceContainerHighest,
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(16),
),
@@ -387,7 +405,9 @@ class _WatchMenuState extends State<_WatchMenu> {
),
),
onSubmitted: (value) {
- if (value.trim().isNotEmpty) {
+ if (value
+ .trim()
+ .isNotEmpty) {
widget.onAdd(value.trim());
_controller.clear();
}
@@ -397,7 +417,9 @@ class _WatchMenuState extends State<_WatchMenu> {
const SizedBox(width: 8),
ElevatedButton(
onPressed: () {
- if (_controller.text.trim().isNotEmpty) {
+ if (_controller.text
+ .trim()
+ .isNotEmpty) {
widget.onAdd(_controller.text.trim());
_controller.clear();
}
diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart
index 36025dd..a6e4ab7 100644
--- a/lib/services/auth_service.dart
+++ b/lib/services/auth_service.dart
@@ -8,6 +8,7 @@ class AuthService {
AuthService({http.Client? client}) : _client = client ?? http.Client();
Future login(String login, String password) async {
+ print(ApiConfig.loginUrl);
final response = await _client.post(
Uri.parse(ApiConfig.loginUrl),
headers: {'Content-Type': 'application/json'},
@@ -17,6 +18,8 @@ class AuthService {
if (response.statusCode == 200) {
return response.body;
} else {
+ print(response.statusCode);
+ print(response.body);
throw Exception('Invalid credentials');
}
}
diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart
index bbc8401..1b06d87 100644
--- a/lib/services/settings_service.dart
+++ b/lib/services/settings_service.dart
@@ -1,7 +1,6 @@
import 'package:shared_preferences/shared_preferences.dart';
class SettingsService {
- SettingsService(){initialize();}
static const String _baseUrlKey = 'server_base_url';
static const String _defaultBaseUrl =
'https://family-safety.onrender.com/api';
@@ -13,6 +12,7 @@ class SettingsService {
String get baseUrl => _baseUrl;
String? login;
String? pwd;
+ bool loggedIn=false;
Future initialize() async {
if (_initialized) return;
@@ -34,7 +34,14 @@ class SettingsService {
pwd = pass;
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_loginKey, user);
- await prefs.setString(_loginKey, user);
+ await prefs.setString(_pwdKey, pass);
+ }
+ Future logOut() async {
+ final prefs = await SharedPreferences.getInstance();
+ login = null;
+ pwd = null;
+ await prefs.remove(_loginKey);
+ await prefs.remove(_pwdKey);
}
void resetToDefault() {
diff --git a/pubspec.yaml b/pubspec.yaml
index 9596379..62e2464 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
-name: family_safety_frontend
-description: "A new Flutter project."
+name: GeoShare
+description: "GeoShare"
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev