mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-19 07:35:26 +02:00
improvements for iOS; bugfixes for loading screen
This commit is contained in:
parent
e58462c313
commit
909d4f8d89
@ -1,5 +1,7 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- Alamofire (5.6.2)
|
- Alamofire (5.6.2)
|
||||||
|
- apple_maps_flutter (0.0.1):
|
||||||
|
- Flutter
|
||||||
- camera_avfoundation (0.0.1):
|
- camera_avfoundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
@ -32,6 +34,7 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
- apple_maps_flutter (from `.symlinks/plugins/apple_maps_flutter/ios`)
|
||||||
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
|
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_osm_plugin (from `.symlinks/plugins/flutter_osm_plugin/ios`)
|
- flutter_osm_plugin (from `.symlinks/plugins/flutter_osm_plugin/ios`)
|
||||||
@ -53,6 +56,8 @@ SPEC REPOS:
|
|||||||
- Toast
|
- Toast
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
|
apple_maps_flutter:
|
||||||
|
:path: ".symlinks/plugins/apple_maps_flutter/ios"
|
||||||
camera_avfoundation:
|
camera_avfoundation:
|
||||||
:path: ".symlinks/plugins/camera_avfoundation/ios"
|
:path: ".symlinks/plugins/camera_avfoundation/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
@ -80,6 +85,7 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
Alamofire: d368e1ff8a298e6dde360e35a3e68e6c610e7204
|
Alamofire: d368e1ff8a298e6dde360e35a3e68e6c610e7204
|
||||||
|
apple_maps_flutter: c59725efea39e13e703cde52a1d2b14866ad68a8
|
||||||
camera_avfoundation: 07c77549ea54ad95d8581be86617c094a46280d9
|
camera_avfoundation: 07c77549ea54ad95d8581be86617c094a46280d9
|
||||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||||
flutter_osm_plugin: f06ae1e854af57270c61ae27bdb8a386cfd4afa5
|
flutter_osm_plugin: f06ae1e854af57270c61ae27bdb8a386cfd4afa5
|
||||||
|
@ -52,7 +52,7 @@ class _MyAppState extends State<MyApp> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> watchAuthenticationStatus() async {
|
Future<void> watchAuthenticationStatus() async {
|
||||||
await GlobalValuesManager.watchForInitialization();
|
await GlobalValuesManager.waitForInitialization();
|
||||||
|
|
||||||
Supabase.instance.client.auth.onAuthStateChange((event, session) {
|
Supabase.instance.client.auth.onAuthStateChange((event, session) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -1,33 +1,17 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
|
||||||
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
|
|
||||||
import 'package:quid_faciam_hodie/screens/main_screen.dart';
|
|
||||||
import 'package:quid_faciam_hodie/screens/welcome_screen.dart';
|
|
||||||
import 'package:supabase/supabase.dart';
|
import 'package:supabase/supabase.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
|
||||||
class AuthState<T extends StatefulWidget> extends SupabaseAuthState<T> {
|
class AuthState<T extends StatefulWidget> extends SupabaseAuthState<T> {
|
||||||
@override
|
@override
|
||||||
void onUnauthenticated() {
|
void onUnauthenticated() {}
|
||||||
if (mounted) {
|
|
||||||
Navigator.of(context)
|
|
||||||
.pushNamedAndRemoveUntil(WelcomeScreen.ID, (route) => false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onAuthenticated(Session session) {
|
void onAuthenticated(Session session) {}
|
||||||
if (mounted) {
|
|
||||||
Navigator.of(context)
|
|
||||||
.pushNamedAndRemoveUntil(MainScreen.ID, (route) => false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onPasswordRecovery(Session session) {}
|
void onPasswordRecovery(Session session) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onErrorAuthenticating(String message) {
|
void onErrorAuthenticating(String message) {}
|
||||||
if (isMaterial(context)) context.showErrorSnackBar(message: message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ final supabase = Supabase.instance.client;
|
|||||||
|
|
||||||
class FileManager {
|
class FileManager {
|
||||||
static Future<Memory> getMemoryMetadata(final String id) async {
|
static Future<Memory> getMemoryMetadata(final String id) async {
|
||||||
await GlobalValuesManager.watchForInitialization();
|
await GlobalValuesManager.waitForInitialization();
|
||||||
|
|
||||||
final response = await supabase
|
final response = await supabase
|
||||||
.from('memories')
|
.from('memories')
|
||||||
@ -38,7 +38,7 @@ class FileManager {
|
|||||||
final File file, {
|
final File file, {
|
||||||
LocationData? locationData,
|
LocationData? locationData,
|
||||||
}) async {
|
}) async {
|
||||||
await GlobalValuesManager.watchForInitialization();
|
await GlobalValuesManager.waitForInitialization();
|
||||||
|
|
||||||
final basename = uuid.v4();
|
final basename = uuid.v4();
|
||||||
final extension = file.path.split('.').last;
|
final extension = file.path.split('.').last;
|
||||||
@ -108,7 +108,7 @@ class FileManager {
|
|||||||
final bool disableDownloadCache = false,
|
final bool disableDownloadCache = false,
|
||||||
final bool disableFileCache = false,
|
final bool disableFileCache = false,
|
||||||
}) async {
|
}) async {
|
||||||
await GlobalValuesManager.watchForInitialization();
|
await GlobalValuesManager.waitForInitialization();
|
||||||
|
|
||||||
final tempDirectory = await getTemporaryDirectory();
|
final tempDirectory = await getTemporaryDirectory();
|
||||||
final filename = '${tempDirectory.path}/$path';
|
final filename = '${tempDirectory.path}/$path';
|
||||||
@ -129,7 +129,7 @@ class FileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> deleteFile(final String path) async {
|
static Future<void> deleteFile(final String path) async {
|
||||||
await GlobalValuesManager.watchForInitialization();
|
await GlobalValuesManager.waitForInitialization();
|
||||||
|
|
||||||
final response =
|
final response =
|
||||||
await supabase.from('memories').delete().eq('location', path).execute();
|
await supabase.from('memories').delete().eq('location', path).execute();
|
||||||
|
@ -52,7 +52,7 @@ class GlobalValuesManager {
|
|||||||
_initializeSettings();
|
_initializeSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> watchForInitialization() async {
|
static Future<void> waitForInitialization() async {
|
||||||
// Server initialization
|
// Server initialization
|
||||||
if (_serverInitializationFuture == null) {
|
if (_serverInitializationFuture == null) {
|
||||||
if (_isServerInitialized) {
|
if (_isServerInitialized) {
|
||||||
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:quid_faciam_hodie/constants/apis.dart';
|
||||||
|
|
||||||
class PhotoManager {
|
class PhotoManager {
|
||||||
static const MAX_PHOTOS_PER_PAGE = 80;
|
static const MAX_PHOTOS_PER_PAGE = 80;
|
||||||
@ -10,7 +11,12 @@ class PhotoManager {
|
|||||||
static Future<String> getRandomPhoto(final String query) async {
|
static Future<String> getRandomPhoto(final String query) async {
|
||||||
final url =
|
final url =
|
||||||
'https://api.pexels.com/v1/search?query=$query&per_page=$MAX_PHOTOS_PER_PAGE&orientation=portait';
|
'https://api.pexels.com/v1/search?query=$query&per_page=$MAX_PHOTOS_PER_PAGE&orientation=portait';
|
||||||
final response = await http.get(Uri.parse(url));
|
final response = await http.get(
|
||||||
|
Uri.parse(url),
|
||||||
|
headers: {
|
||||||
|
'Authorization': PEXELS_API_KEY,
|
||||||
|
},
|
||||||
|
);
|
||||||
final data = jsonDecode(response.body);
|
final data = jsonDecode(response.body);
|
||||||
final photoIndex = Random().nextInt(data['per_page']);
|
final photoIndex = Random().nextInt(data['per_page']);
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class Memories extends PropertyChangeNotifier<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadInitialData() async {
|
Future<void> _loadInitialData() async {
|
||||||
await GlobalValuesManager.watchForInitialization();
|
await GlobalValuesManager.waitForInitialization();
|
||||||
|
|
||||||
final response = await supabase
|
final response = await supabase
|
||||||
.from('memories')
|
.from('memories')
|
||||||
|
@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
import 'package:quid_faciam_hodie/screens/login_screen.dart';
|
|
||||||
import 'package:quid_faciam_hodie/screens/server_loading_screen.dart';
|
|
||||||
|
|
||||||
import 'grant_permission_screen/permissions_required_page.dart';
|
import 'grant_permission_screen/permissions_required_page.dart';
|
||||||
|
|
||||||
@ -25,14 +23,7 @@ class GrantPermissionScreen extends StatelessWidget {
|
|||||||
child: Center(
|
child: Center(
|
||||||
child: PermissionsRequiredPage(
|
child: PermissionsRequiredPage(
|
||||||
onPermissionsGranted: () {
|
onPermissionsGranted: () {
|
||||||
Navigator.push(
|
Navigator.pop(context);
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => const ServerLoadingScreen(
|
|
||||||
nextScreen: LoginScreen.ID,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -118,7 +118,7 @@ class _PermissionsRequiredPageState extends State<PermissionsRequiredPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: MEDIUM_SPACE),
|
const SizedBox(height: SMALL_SPACE),
|
||||||
PlatformTextButton(
|
PlatformTextButton(
|
||||||
onPressed: hasGrantedMicrophonePermission
|
onPressed: hasGrantedMicrophonePermission
|
||||||
? null
|
? null
|
||||||
@ -142,6 +142,7 @@ class _PermissionsRequiredPageState extends State<PermissionsRequiredPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: SMALL_SPACE),
|
||||||
PlatformTextButton(
|
PlatformTextButton(
|
||||||
onPressed: hasGrantedLocationPermission
|
onPressed: hasGrantedLocationPermission
|
||||||
? null
|
? null
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
|
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
|
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
||||||
@ -10,6 +9,8 @@ import 'package:quid_faciam_hodie/utils/lookup_address.dart';
|
|||||||
import 'package:quid_faciam_hodie/utils/theme.dart';
|
import 'package:quid_faciam_hodie/utils/theme.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/key_value_info.dart';
|
import 'package:quid_faciam_hodie/widgets/key_value_info.dart';
|
||||||
|
import 'package:quid_faciam_hodie/widgets/platform_widgets/memory_cupertino_maps.dart';
|
||||||
|
import 'package:quid_faciam_hodie/widgets/platform_widgets/memory_material_maps.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/sheet_indicator.dart';
|
import 'package:quid_faciam_hodie/widgets/sheet_indicator.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
@ -26,7 +27,6 @@ class MemoryMapScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MemoryMapScreenState extends State<MemoryMapScreen> with Loadable {
|
class _MemoryMapScreenState extends State<MemoryMapScreen> with Loadable {
|
||||||
late final MapController controller;
|
|
||||||
String? address;
|
String? address;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -34,13 +34,6 @@ class _MemoryMapScreenState extends State<MemoryMapScreen> with Loadable {
|
|||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
callWithLoading(fetchAddress);
|
callWithLoading(fetchAddress);
|
||||||
|
|
||||||
controller = MapController(
|
|
||||||
initPosition: GeoPoint(
|
|
||||||
latitude: widget.location.latitude,
|
|
||||||
longitude: widget.location.longitude,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> fetchAddress() async {
|
Future<void> fetchAddress() async {
|
||||||
@ -60,34 +53,6 @@ class _MemoryMapScreenState extends State<MemoryMapScreen> with Loadable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCircle() => controller.drawCircle(
|
|
||||||
CircleOSM(
|
|
||||||
key: 'accuracy',
|
|
||||||
color: Colors.blue,
|
|
||||||
centerPoint: GeoPoint(
|
|
||||||
latitude: widget.location.latitude,
|
|
||||||
longitude: widget.location.longitude,
|
|
||||||
),
|
|
||||||
radius: widget.location.accuracy,
|
|
||||||
strokeWidth: 4,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
List<StaticPositionGeoPoint> get staticPoints => [
|
|
||||||
StaticPositionGeoPoint(
|
|
||||||
'position',
|
|
||||||
const MarkerIcon(
|
|
||||||
icon: Icon(Icons.location_on, size: 150, color: Colors.blue),
|
|
||||||
),
|
|
||||||
[
|
|
||||||
GeoPoint(
|
|
||||||
latitude: widget.location.latitude,
|
|
||||||
longitude: widget.location.longitude,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
];
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final localizations = AppLocalizations.of(context)!;
|
final localizations = AppLocalizations.of(context)!;
|
||||||
@ -99,15 +64,14 @@ class _MemoryMapScreenState extends State<MemoryMapScreen> with Loadable {
|
|||||||
),
|
),
|
||||||
body: ExpandableBottomSheet(
|
body: ExpandableBottomSheet(
|
||||||
enableToggle: true,
|
enableToggle: true,
|
||||||
background: OSMFlutter(
|
background: isMaterial(context)
|
||||||
controller: controller,
|
? MemoryMaterialMaps(
|
||||||
initZoom: 13,
|
location: widget.location,
|
||||||
stepZoom: 1.0,
|
initialZoom: 13,
|
||||||
trackMyPosition: true,
|
)
|
||||||
staticPoints: staticPoints,
|
: MemoryCupertinoMaps(
|
||||||
onMapIsReady: (_) {
|
location: widget.location,
|
||||||
drawCircle();
|
initialZoom: 13,
|
||||||
},
|
|
||||||
),
|
),
|
||||||
persistentHeader: Container(
|
persistentHeader: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
|
@ -6,6 +6,7 @@ import 'package:quid_faciam_hodie/constants/spacing.dart';
|
|||||||
import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
|
import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
|
||||||
import 'package:quid_faciam_hodie/models/memories.dart';
|
import 'package:quid_faciam_hodie/models/memories.dart';
|
||||||
import 'package:quid_faciam_hodie/screens/grant_permission_screen.dart';
|
import 'package:quid_faciam_hodie/screens/grant_permission_screen.dart';
|
||||||
|
import 'package:quid_faciam_hodie/screens/login_screen.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
|
||||||
import 'empty_screen.dart';
|
import 'empty_screen.dart';
|
||||||
@ -36,23 +37,32 @@ class _ServerLoadingScreenState extends State<ServerLoadingScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
if (!(await GlobalValuesManager.hasGrantedPermissions())) {
|
while (!(await GlobalValuesManager.hasGrantedPermissions())) {
|
||||||
Navigator.pushReplacementNamed(
|
await Navigator.pushNamed(
|
||||||
context,
|
context,
|
||||||
GrantPermissionScreen.ID,
|
GrantPermissionScreen.ID,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await GlobalValuesManager.watchForInitialization();
|
await GlobalValuesManager.waitForInitialization();
|
||||||
|
|
||||||
final memories = context.read<Memories>();
|
final memories = context.read<Memories>();
|
||||||
final session = Supabase.instance.client.auth.session();
|
final session = Supabase.instance.client.auth.session();
|
||||||
|
|
||||||
|
if (session == null && widget.nextScreen == LoginScreen.ID) {
|
||||||
|
Navigator.pushReplacementNamed(
|
||||||
|
context,
|
||||||
|
LoginScreen.ID,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
Navigator.pushReplacementNamed(
|
Navigator.pushReplacementNamed(
|
||||||
context,
|
context,
|
||||||
WelcomeScreen.ID,
|
WelcomeScreen.ID,
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (!memories.isInitialized) {
|
if (!memories.isInitialized) {
|
||||||
await memories.initialize();
|
await memories.initialize();
|
||||||
@ -67,17 +77,20 @@ class _ServerLoadingScreenState extends State<ServerLoadingScreen> {
|
|||||||
context,
|
context,
|
||||||
MainScreen.ID,
|
MainScreen.ID,
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (memories.memories.isEmpty) {
|
if (memories.memories.isEmpty) {
|
||||||
Navigator.pushReplacementNamed(
|
Navigator.pushReplacementNamed(
|
||||||
context,
|
context,
|
||||||
EmptyScreen.ID,
|
EmptyScreen.ID,
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
Navigator.pushReplacementNamed(
|
Navigator.pushReplacementNamed(
|
||||||
context,
|
context,
|
||||||
widget.nextScreen!,
|
widget.nextScreen!,
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
||||||
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
|
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
|
||||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
|
||||||
import 'package:quid_faciam_hodie/constants/values.dart';
|
|
||||||
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
|
||||||
import 'package:quid_faciam_hodie/screens/memory_map_screen.dart';
|
|
||||||
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
|
||||||
|
|
||||||
class MemoryLocationView extends StatefulWidget {
|
|
||||||
final MemoryLocation location;
|
|
||||||
|
|
||||||
const MemoryLocationView({
|
|
||||||
Key? key,
|
|
||||||
required this.location,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MemoryLocationView> createState() => _MemoryLocationViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MemoryLocationViewState extends State<MemoryLocationView> {
|
|
||||||
late final MapController controller;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
controller = MapController(
|
|
||||||
initPosition: GeoPoint(
|
|
||||||
latitude: widget.location.latitude,
|
|
||||||
longitude: widget.location.longitude,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
controller.dispose();
|
|
||||||
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawCircle() => controller.drawCircle(
|
|
||||||
CircleOSM(
|
|
||||||
key: 'accuracy',
|
|
||||||
color: Colors.blue,
|
|
||||||
centerPoint: GeoPoint(
|
|
||||||
latitude: widget.location.latitude,
|
|
||||||
longitude: widget.location.longitude,
|
|
||||||
),
|
|
||||||
radius: widget.location.accuracy,
|
|
||||||
strokeWidth: 4,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
List<StaticPositionGeoPoint> get staticPoints {
|
|
||||||
if (widget.location.accuracy <= ACCURACY_IN_METERS_FOR_PINPOINT) {
|
|
||||||
return [
|
|
||||||
StaticPositionGeoPoint(
|
|
||||||
'position',
|
|
||||||
const MarkerIcon(
|
|
||||||
icon: Icon(Icons.location_on, size: 150, color: Colors.blue),
|
|
||||||
),
|
|
||||||
[
|
|
||||||
GeoPoint(
|
|
||||||
latitude: widget.location.latitude,
|
|
||||||
longitude: widget.location.longitude,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final localizations = AppLocalizations.of(context)!;
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: <Widget>[
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 400,
|
|
||||||
child: GestureDetector(
|
|
||||||
// Avoid panning, map is view-only
|
|
||||||
onDoubleTap: () {},
|
|
||||||
child: OSMFlutter(
|
|
||||||
controller: controller,
|
|
||||||
initZoom: 14,
|
|
||||||
minZoomLevel: 14,
|
|
||||||
maxZoomLevel: 14,
|
|
||||||
staticPoints: staticPoints,
|
|
||||||
onMapIsReady: (_) {
|
|
||||||
drawCircle();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: MEDIUM_SPACE),
|
|
||||||
PlatformTextButton(
|
|
||||||
child: IconButtonChild(
|
|
||||||
icon: Icon(context.platformIcons.fullscreen),
|
|
||||||
label: Text(localizations.memorySheetViewMoreDetails),
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
await Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (_) => MemoryMapScreen(
|
|
||||||
location: widget.location,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!mounted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: MEDIUM_SPACE),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,12 +10,15 @@ import 'package:quid_faciam_hodie/enums.dart';
|
|||||||
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
|
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
|
||||||
import 'package:quid_faciam_hodie/foreign_types/memory.dart';
|
import 'package:quid_faciam_hodie/foreign_types/memory.dart';
|
||||||
import 'package:quid_faciam_hodie/managers/file_manager.dart';
|
import 'package:quid_faciam_hodie/managers/file_manager.dart';
|
||||||
|
import 'package:quid_faciam_hodie/screens/memory_map_screen.dart';
|
||||||
import 'package:quid_faciam_hodie/utils/loadable.dart';
|
import 'package:quid_faciam_hodie/utils/loadable.dart';
|
||||||
import 'package:quid_faciam_hodie/utils/theme.dart';
|
import 'package:quid_faciam_hodie/utils/theme.dart';
|
||||||
|
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
||||||
|
import 'package:quid_faciam_hodie/widgets/platform_widgets/memory_cupertino_maps.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/sheet_indicator.dart';
|
import 'package:quid_faciam_hodie/widgets/sheet_indicator.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
|
||||||
import 'memory_location_view.dart';
|
import '../../widgets/platform_widgets/memory_material_maps.dart';
|
||||||
|
|
||||||
class MemorySheet extends StatefulWidget {
|
class MemorySheet extends StatefulWidget {
|
||||||
final Memory memory;
|
final Memory memory;
|
||||||
@ -250,8 +253,51 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
|
|||||||
: Container(
|
: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
child: MemoryLocationView(
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 400,
|
||||||
|
child: GestureDetector(
|
||||||
|
// Avoid panning, map is view-only
|
||||||
|
onDoubleTap: () {},
|
||||||
|
child: PlatformWidget(
|
||||||
|
material: (_, __) => MemoryMaterialMaps(
|
||||||
location: widget.memory.location!,
|
location: widget.memory.location!,
|
||||||
|
initialZoom: 14,
|
||||||
|
),
|
||||||
|
cupertino: (_, __) => MemoryCupertinoMaps(
|
||||||
|
location: widget.memory.location!,
|
||||||
|
initialZoom: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: MEDIUM_SPACE),
|
||||||
|
PlatformTextButton(
|
||||||
|
child: IconButtonChild(
|
||||||
|
icon: Icon(context.platformIcons.fullscreen),
|
||||||
|
label: Text(localizations.memorySheetViewMoreDetails),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => MemoryMapScreen(
|
||||||
|
location: widget.memory.location!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: MEDIUM_SPACE),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
import 'package:quid_faciam_hodie/screens/grant_permission_screen.dart';
|
import 'package:quid_faciam_hodie/screens/login_screen.dart';
|
||||||
|
import 'package:quid_faciam_hodie/screens/server_loading_screen.dart';
|
||||||
import 'package:quid_faciam_hodie/screens/welcome_screen/crabs/logo.dart';
|
import 'package:quid_faciam_hodie/screens/welcome_screen/crabs/logo.dart';
|
||||||
import 'package:quid_faciam_hodie/utils/theme.dart';
|
import 'package:quid_faciam_hodie/utils/theme.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
||||||
@ -38,9 +39,13 @@ class GetStartedPage extends StatelessWidget {
|
|||||||
label: Text(localizations.welcomeScreenStartButtonTitle),
|
label: Text(localizations.welcomeScreenStartButtonTitle),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pushNamed(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
GrantPermissionScreen.ID,
|
MaterialPageRoute(
|
||||||
|
builder: (_) => const ServerLoadingScreen(
|
||||||
|
nextScreen: LoginScreen.ID,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/values.dart';
|
import 'package:quid_faciam_hodie/constants/values.dart';
|
||||||
import 'package:quid_faciam_hodie/managers/photo_manager.dart';
|
import 'package:quid_faciam_hodie/managers/photo_manager.dart';
|
||||||
@ -15,7 +16,7 @@ class PhotoSwitching extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PhotoSwitchingState extends State<PhotoSwitching> with Loadable {
|
class _PhotoSwitchingState extends State<PhotoSwitching> with Loadable {
|
||||||
late String photoURL;
|
String photoURL = '';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -41,7 +42,9 @@ class _PhotoSwitchingState extends State<PhotoSwitching> with Loadable {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return Center(
|
||||||
|
child: PlatformCircularProgressIndicator(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
|
62
lib/widgets/platform_widgets/memory_cupertino_maps.dart
Normal file
62
lib/widgets/platform_widgets/memory_cupertino_maps.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:apple_maps_flutter/apple_maps_flutter.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
||||||
|
|
||||||
|
class MemoryCupertinoMaps extends StatefulWidget {
|
||||||
|
final MemoryLocation location;
|
||||||
|
final bool lockZoom;
|
||||||
|
final double initialZoom;
|
||||||
|
|
||||||
|
const MemoryCupertinoMaps({
|
||||||
|
Key? key,
|
||||||
|
required this.location,
|
||||||
|
required this.initialZoom,
|
||||||
|
this.lockZoom = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MemoryCupertinoMaps> createState() => _MemoryCupertinoMapsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MemoryCupertinoMapsState extends State<MemoryCupertinoMaps> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AppleMap(
|
||||||
|
minMaxZoomPreference: MinMaxZoomPreference(
|
||||||
|
widget.lockZoom ? widget.initialZoom : 1,
|
||||||
|
widget.lockZoom ? widget.initialZoom : 20,
|
||||||
|
),
|
||||||
|
circles: {
|
||||||
|
Circle(
|
||||||
|
circleId: CircleId('accuracy'),
|
||||||
|
center: LatLng(
|
||||||
|
widget.location.latitude,
|
||||||
|
widget.location.longitude,
|
||||||
|
),
|
||||||
|
radius: widget.location.accuracy,
|
||||||
|
strokeWidth: 1,
|
||||||
|
fillColor: Colors.blue.withOpacity(.2),
|
||||||
|
strokeColor: Colors.blue,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
annotations: {
|
||||||
|
Annotation(
|
||||||
|
annotationId: AnnotationId('position'),
|
||||||
|
position: LatLng(
|
||||||
|
widget.location.latitude,
|
||||||
|
widget.location.longitude,
|
||||||
|
),
|
||||||
|
icon: BitmapDescriptor.defaultAnnotation,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
initialCameraPosition: CameraPosition(
|
||||||
|
target: LatLng(
|
||||||
|
widget.location.latitude,
|
||||||
|
widget.location.longitude,
|
||||||
|
),
|
||||||
|
zoom: 14,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
84
lib/widgets/platform_widgets/memory_material_maps.dart
Normal file
84
lib/widgets/platform_widgets/memory_material_maps.dart
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
|
||||||
|
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
||||||
|
|
||||||
|
class MemoryMaterialMaps extends StatefulWidget {
|
||||||
|
final MemoryLocation location;
|
||||||
|
final bool lockZoom;
|
||||||
|
final double initialZoom;
|
||||||
|
|
||||||
|
const MemoryMaterialMaps({
|
||||||
|
Key? key,
|
||||||
|
required this.location,
|
||||||
|
required this.initialZoom,
|
||||||
|
this.lockZoom = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MemoryMaterialMaps> createState() => _MemoryMaterialMapsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MemoryMaterialMapsState extends State<MemoryMaterialMaps> {
|
||||||
|
late final MapController controller;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
controller = MapController(
|
||||||
|
initPosition: GeoPoint(
|
||||||
|
latitude: widget.location.latitude,
|
||||||
|
longitude: widget.location.longitude,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller.dispose();
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawCircle() => controller.drawCircle(
|
||||||
|
CircleOSM(
|
||||||
|
key: 'accuracy',
|
||||||
|
color: Colors.blue,
|
||||||
|
centerPoint: GeoPoint(
|
||||||
|
latitude: widget.location.latitude,
|
||||||
|
longitude: widget.location.longitude,
|
||||||
|
),
|
||||||
|
radius: widget.location.accuracy,
|
||||||
|
strokeWidth: 4,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
List<StaticPositionGeoPoint> get staticPoints => [
|
||||||
|
StaticPositionGeoPoint(
|
||||||
|
'position',
|
||||||
|
const MarkerIcon(
|
||||||
|
icon: Icon(Icons.location_on, size: 150, color: Colors.blue),
|
||||||
|
),
|
||||||
|
[
|
||||||
|
GeoPoint(
|
||||||
|
latitude: widget.location.latitude,
|
||||||
|
longitude: widget.location.longitude,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return OSMFlutter(
|
||||||
|
controller: controller,
|
||||||
|
initZoom: widget.initialZoom,
|
||||||
|
maxZoomLevel: widget.lockZoom ? widget.initialZoom : 19,
|
||||||
|
minZoomLevel: widget.lockZoom ? widget.initialZoom : 2,
|
||||||
|
staticPoints: staticPoints,
|
||||||
|
onMapIsReady: (_) {
|
||||||
|
drawCircle();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:quid_faciam_hodie/utils/theme.dart';
|
||||||
|
|
||||||
class SheetIndicator extends StatelessWidget {
|
class SheetIndicator extends StatelessWidget {
|
||||||
const SheetIndicator({Key? key}) : super(key: key);
|
const SheetIndicator({Key? key}) : super(key: key);
|
||||||
@ -9,7 +10,7 @@ class SheetIndicator extends StatelessWidget {
|
|||||||
width: 100,
|
width: 100,
|
||||||
height: 5,
|
height: 5,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white24,
|
color: getBodyTextColor(context).withOpacity(.2),
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
apple_maps_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: apple_maps_flutter
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -62,6 +62,7 @@ dependencies:
|
|||||||
flutter_exif_plugin: ^1.1.0
|
flutter_exif_plugin: ^1.1.0
|
||||||
flutter_osm_plugin: ^0.39.0
|
flutter_osm_plugin: ^0.39.0
|
||||||
url_launcher: ^6.1.5
|
url_launcher: ^6.1.5
|
||||||
|
apple_maps_flutter: ^1.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user