added loading screen; improvements

This commit is contained in:
Myzel394 2022-08-16 18:55:44 +02:00
parent 3441938e11
commit 6492a75185
4 changed files with 205 additions and 44 deletions

View File

@ -1,80 +1,42 @@
import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:share_location/constants/apis.dart';
import 'package:share_location/screens/calendar_screen.dart';
import 'package:share_location/screens/grant_permission_screen.dart';
import 'package:share_location/screens/login_screen.dart';
import 'package:share_location/screens/main_screen.dart';
import 'package:share_location/screens/server_loading_screen.dart';
import 'package:share_location/screens/timeline_screen.dart';
import 'package:share_location/screens/welcome_screen.dart';
import 'package:share_location/utils/auth_required.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'managers/global_values_manager.dart';
import 'managers/startup_page_manager.dart';
import 'models/memories.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Supabase.initialize(
url: SUPABASE_API_URL,
anonKey: SUPABASE_API_KEY,
debug: kDebugMode,
);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
GlobalValuesManager.setCameras(await availableCameras());
final initialPage = await StartupPageManager.getPage();
runApp(MyApp(initialPage: initialPage));
runApp(MyApp());
}
class MyApp extends StatefulWidget {
final String initialPage;
const MyApp({
Key? key,
required this.initialPage,
}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends AuthRequiredState<MyApp> {
class _MyAppState extends State<MyApp> {
final memories = Memories();
@override
void initState() {
super.initState();
memories.addListener(() {
setState(() {
});
}, ['isInitializing']);
}
@override
void onAuthenticated(Session session) {
memories.initialize();
}
@override
Widget build(BuildContext context) {
if (memories.isInitializing) {
return SizedBox();
}
return ChangeNotifierProvider.value(
value: memories,
child: MaterialApp(
@ -102,8 +64,9 @@ class _MyAppState extends AuthRequiredState<MyApp> {
TimelineScreen.ID: (context) => const TimelineScreen(),
GrantPermissionScreen.ID: (context) => const GrantPermissionScreen(),
CalendarScreen.ID: (context) => const CalendarScreen(),
ServerLoadingScreen.ID: (context) => const ServerLoadingScreen(),
},
initialRoute: widget.initialPage,
initialRoute: ServerLoadingScreen.ID,
),
);
}

View File

@ -248,8 +248,16 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
backgroundColor: Colors.black,
bottomSheet: () {
if (isLoading) {
return const Center(
child: CircularProgressIndicator(),
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
SizedBox(height: MEDIUM_SPACE),
Text('Loading camera'),
],
),
);
}

View File

@ -0,0 +1,95 @@
import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:share_location/constants/apis.dart';
import 'package:share_location/constants/spacing.dart';
import 'package:share_location/managers/global_values_manager.dart';
import 'package:share_location/models/memories.dart';
import 'package:share_location/widgets/dot_animation.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'main_screen.dart';
import 'welcome_screen.dart';
class ServerLoadingScreen extends StatefulWidget {
static const ID = 'server_loading';
const ServerLoadingScreen({Key? key}) : super(key: key);
@override
State<ServerLoadingScreen> createState() => _ServerLoadingScreenState();
}
class _ServerLoadingScreenState extends State<ServerLoadingScreen> {
@override
void initState() {
super.initState();
load();
}
Future<void> load() async {
GlobalValuesManager.setCameras(await availableCameras());
await Supabase.initialize(
url: SUPABASE_API_URL,
anonKey: SUPABASE_API_KEY,
debug: kDebugMode,
);
final memories = context.read<Memories>();
final session = Supabase.instance.client.auth.session();
if (session != null) {
memories.initialize().then((_) {
Navigator.pushReplacementNamed(context, MainScreen.ID);
});
} else {
Navigator.pushReplacementNamed(context, WelcomeScreen.ID);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const <Widget>[
Icon(Icons.cloud, size: 60),
SizedBox(height: SMALL_SPACE),
DotAnimation(
initialFadeInDelay: Duration.zero,
fadeInDuration: Duration(seconds: 1),
fadeOutDuration: Duration(seconds: 1),
fadeInDelay: Duration(seconds: 6),
fadeOutDelay: Duration.zero,
),
DotAnimation(
initialFadeInDelay: Duration(seconds: 2),
fadeInDuration: Duration(seconds: 1),
fadeOutDuration: Duration(seconds: 1),
fadeInDelay: Duration(seconds: 6),
fadeOutDelay: Duration.zero,
),
DotAnimation(
initialFadeInDelay: Duration(seconds: 4),
fadeInDuration: Duration(seconds: 1),
fadeOutDuration: Duration(seconds: 1),
fadeInDelay: Duration(seconds: 6),
fadeOutDelay: Duration.zero,
),
SizedBox(height: SMALL_SPACE),
Icon(Icons.smartphone, size: 60),
SizedBox(height: LARGE_SPACE),
Text(
'We are loading your data',
),
],
),
),
);
}
}

View File

@ -0,0 +1,95 @@
import 'dart:async';
import 'package:flutter/material.dart';
class DotAnimation extends StatefulWidget {
final Duration fadeInDuration;
final Duration fadeOutDuration;
final Duration fadeInDelay;
final Duration fadeOutDelay;
final Duration? initialFadeInDelay;
final Curve curve;
const DotAnimation({
Key? key,
this.fadeInDuration = const Duration(seconds: 2),
this.fadeOutDuration = const Duration(seconds: 2),
this.curve = Curves.easeOut,
this.fadeInDelay = const Duration(seconds: 1),
this.fadeOutDelay = const Duration(seconds: 1),
this.initialFadeInDelay,
}) : super(key: key);
@override
State<DotAnimation> createState() => _DotAnimationState();
}
class _DotAnimationState extends State<DotAnimation> {
Timer? _timer;
bool animateIn = false;
Duration get initialFadeInDelay =>
widget.initialFadeInDelay ?? widget.fadeInDelay;
@override
void initState() {
super.initState();
_timer = Timer(initialFadeInDelay, () {
setState(() {
animateIn = true;
});
});
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedScale(
duration: animateIn ? widget.fadeInDuration : widget.fadeOutDuration,
scale: animateIn ? 1 : .4,
curve: widget.curve,
onEnd: () {
if (animateIn) {
// Animate out
_timer = Timer(widget.fadeOutDelay, () {
if (mounted) {
return;
}
setState(() {
animateIn = false;
});
});
} else {
// Animate in
_timer = Timer(widget.fadeInDelay, () {
if (mounted) {
return;
}
setState(() {
animateIn = true;
});
});
}
},
child: AnimatedOpacity(
opacity: animateIn ? 1 : .4,
duration: animateIn ? widget.fadeInDuration : widget.fadeOutDuration,
curve: widget.curve,
child: const Icon(
Icons.circle,
size: 30,
color: Colors.white,
),
),
);
}
}