commit stash
parent
2ef9151258
commit
7f0f9009ec
|
@ -0,0 +1,22 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:location/location.dart';
|
||||
import 'package:unit2/sevices/sos/sos_service.dart';
|
||||
|
||||
part 'sos_event.dart';
|
||||
part 'sos_state.dart';
|
||||
|
||||
class SosBloc extends Bloc<SosEvent, SosState> {
|
||||
SosBloc() : super(SosInitial()) {
|
||||
LocationData? locationData;
|
||||
on<LoadUserLocation>((event, emit)async {
|
||||
emit(LoadingState());
|
||||
|
||||
LocationData? newLocationData =
|
||||
await SosService.instance.getUserLocation();
|
||||
locationData = newLocationData;
|
||||
// User location Loaded and there is no mobile numbers in cache
|
||||
emit(UserLocationLoaded(locationData: locationData!));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
part of 'sos_bloc.dart';
|
||||
|
||||
abstract class SosEvent extends Equatable {
|
||||
const SosEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class LoadUserLocation extends SosEvent {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
part of 'sos_bloc.dart';
|
||||
|
||||
abstract class SosState extends Equatable {
|
||||
const SosState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class SosInitial extends SosState {}
|
||||
|
||||
class UserLocationLoaded extends SosState {
|
||||
final LocationData locationData;
|
||||
const UserLocationLoaded({required this.locationData});
|
||||
@override
|
||||
List<Object> get props => [locationData];
|
||||
}
|
||||
class ErrorState extends SosState{
|
||||
final String message;
|
||||
const ErrorState({required this.message});
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
class LoadingState extends SosState{
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:unit2/screens/sos/components/request_sos.dart';
|
||||
import 'package:unit2/theme-data.dart/text-styles.dart';
|
||||
import 'package:unit2/utils/screen_info.dart';
|
||||
import '../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../theme-data.dart/colors.dart';
|
||||
import '../../../theme-data.dart/form-style.dart';
|
||||
import '../../../utils/global.dart';
|
||||
import '../../../utils/text_container.dart';
|
||||
import '../../../utils/validators.dart';
|
||||
import '../../../widgets/wave.dart';
|
||||
|
||||
class AddMobile extends StatelessWidget {
|
||||
AddMobile({super.key});
|
||||
final _formKey = GlobalKey<FormBuilderState>();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
return true;
|
||||
},
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Add contact info"),
|
||||
centerTitle: true,
|
||||
backgroundColor: primary,
|
||||
elevation: 0,
|
||||
),
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: screenHeight * .90,
|
||||
child: Stack(
|
||||
children: [
|
||||
Wave(height: blockSizeVertical * 8),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: WaveReverse(height: blockSizeVertical * 8)),
|
||||
Container(
|
||||
height: screenHeight,
|
||||
padding: isMobile()
|
||||
? const EdgeInsets.symmetric(horizontal: 24)
|
||||
: const EdgeInsets.symmetric(horizontal: 60),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: isMobile()
|
||||
? screenHeight * .12
|
||||
: screenHeight * .20),
|
||||
SvgPicture.asset(
|
||||
'assets/svgs/add_mobile.svg',
|
||||
height: isMobile()
|
||||
? blockSizeVertical * 22
|
||||
: blockSizeVertical * 30,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Text(addMobile, style: titleTextStyle()),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(addMobileCaption,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.caption),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
FormBuilder(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
// Mobile number 1
|
||||
FormBuilderTextField(
|
||||
name: 'mobile1',
|
||||
validator: mobileNumberValidator,
|
||||
maxLength: 11,
|
||||
decoration:
|
||||
normalTextFieldStyle(mobile1, "+63")),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
FormBuilderTextField(
|
||||
name: 'mobile2',
|
||||
maxLength: 11,
|
||||
decoration:
|
||||
normalTextFieldStyle(mobile2, "+63")),
|
||||
|
||||
SizedBox(
|
||||
height: isMobile()
|
||||
? blockSizeVertical * 3
|
||||
: blockSizeHorizontal * 5),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: screenHeight * .06,
|
||||
child: ElevatedButton(
|
||||
style: secondaryBtnStyle(second,
|
||||
Colors.transparent, Colors.white54),
|
||||
child: const Text(
|
||||
submit,
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!
|
||||
.saveAndValidate()) {
|
||||
|
||||
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context){
|
||||
return RequestSOS();
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
// }
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
))
|
||||
]),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/container.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:fluttericon/font_awesome5_icons.dart';
|
||||
import 'package:fluttericon/typicons_icons.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:unit2/screens/sos/components/mobile.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/utils/text_container.dart';
|
||||
|
||||
import '../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../theme-data.dart/form-style.dart';
|
||||
import '../../../utils/global.dart';
|
||||
|
||||
class RequestSOS extends StatefulWidget {
|
||||
const RequestSOS({super.key});
|
||||
|
||||
@override
|
||||
State<RequestSOS> createState() => _RequestSOSState();
|
||||
}
|
||||
|
||||
class _RequestSOSState extends State<RequestSOS> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: const Text(sOSTitle),
|
||||
backgroundColor: second,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
height: screenHeight * .84,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 2,
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/svgs/request_sos.svg',
|
||||
height: blockSizeVertical * 22,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
),
|
||||
Mobile(
|
||||
title: "09661548775",
|
||||
subtitle: mobile1,
|
||||
onPressed: () {}),
|
||||
const Divider(),
|
||||
Mobile(
|
||||
title: "09661548775",
|
||||
subtitle: mobile2,
|
||||
onPressed: () {}),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(
|
||||
Typicons.location,
|
||||
color: second,
|
||||
),
|
||||
title: Text("Latitude/Longitude"),
|
||||
subtitle: Text(
|
||||
currentLocation,
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
),
|
||||
FormBuilderTextField(
|
||||
name: "message",
|
||||
validator: FormBuilderValidators.compose([
|
||||
FormBuilderValidators.required(
|
||||
errorText: messageRequired)
|
||||
]),
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
maxLines: 5,
|
||||
decoration: normalTextFieldStyle("", sosMessage),
|
||||
),
|
||||
const Expanded(
|
||||
child: SizedBox(),
|
||||
),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: screenHeight * .06,
|
||||
child: ElevatedButton(
|
||||
style: secondaryBtnStyle(
|
||||
second, Colors.transparent, Colors.white54),
|
||||
child: const Text(
|
||||
submit,
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
onPressed: () {
|
||||
// if (_formKey.currentState.validate()) {
|
||||
// _formKey.currentState.save();
|
||||
// BlocProvider.of<UserBloc>(context)
|
||||
// .add(UserWebLogin(
|
||||
// password: password,
|
||||
// username: username));
|
||||
// }
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
import 'package:animate_do/animate_do.dart';
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:unit2/theme-data.dart/btn-style.dart';
|
||||
import 'package:unit2/utils/text_container.dart';
|
||||
import '../../../theme-data.dart/colors.dart';
|
||||
import '../../../utils/global.dart';
|
||||
|
||||
class SOSreceived extends StatelessWidget {
|
||||
final Function onpressed;
|
||||
const SOSreceived({required Key key, required this.onpressed})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 35),
|
||||
height: screenHeight,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
child: SizedBox(
|
||||
width: screenWidth,
|
||||
height: screenHeight / 2,
|
||||
child: Opacity(
|
||||
opacity: .2,
|
||||
child: Image.asset(
|
||||
"assets/emergency.png",
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
)),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 6,
|
||||
),
|
||||
Bounce(
|
||||
from: 20,
|
||||
infinite: true,
|
||||
delay: const Duration(milliseconds: 800),
|
||||
child: Stack(
|
||||
alignment: AlignmentDirectional.topCenter,
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 20),
|
||||
child: CircleAvatar(
|
||||
radius: blockSizeVertical * 8,
|
||||
backgroundColor: second,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 25),
|
||||
child: SvgPicture.asset(
|
||||
'assets/sos.svg',
|
||||
height: blockSizeHorizontal * 17,
|
||||
color: Colors.white,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
alignment: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: blockSizeVertical * 3,
|
||||
child: const SpinKitPulse(
|
||||
color: primary,
|
||||
size: 120,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SlideInUp(
|
||||
from: 50,
|
||||
child: AutoSizeText(
|
||||
sosReceived,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.displayMedium!.copyWith(
|
||||
fontSize: 40,
|
||||
color: third,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
SlideInUp(
|
||||
from: 50,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(15))),
|
||||
child: AutoSizeText(
|
||||
sOSReceivedMessage,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.caption!.copyWith(
|
||||
fontSize: 16,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
),
|
||||
Expanded(child: Container()),
|
||||
SlideInUp(
|
||||
child: SizedBox(
|
||||
height: 50,
|
||||
width: 200,
|
||||
child: TextButton(
|
||||
style: mainBtnStyle(second, Colors.transparent, second),
|
||||
onPressed: () {},
|
||||
child: const Text(cancelRequest,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
)),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/src/widgets/placeholder.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:unit2/bloc/sos/sos_bloc.dart';
|
||||
import 'package:unit2/screens/sos/components/add_mobile.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
|
||||
class SosScreen extends StatefulWidget {
|
||||
const SosScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SosScreen> createState() => _SosScreenState();
|
||||
}
|
||||
|
||||
class _SosScreenState extends State<SosScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBar(
|
||||
title: const Text("SOS"),
|
||||
centerTitle: true,
|
||||
backgroundColor: primary,
|
||||
),
|
||||
body: ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
backgroundColor: Colors.black87,
|
||||
indicatorWidget: const SpinKitFadingCircle(color: Colors.white),
|
||||
child: BlocConsumer<SosBloc,SosState>(
|
||||
listener: (context, state) {
|
||||
//// user location loaded
|
||||
if (state is UserLocationLoaded) {
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (BuildContext context) {
|
||||
return AddMobile();
|
||||
}));
|
||||
}
|
||||
////loading state
|
||||
if (state is LoadingState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is ErrorState) {}
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -317,7 +317,7 @@ class _UniT2LoginState extends State<UniT2Login> {
|
|||
Colors.transparent,
|
||||
Colors.white38),
|
||||
onPressed: () {
|
||||
|
||||
Navigator.pushNamed(context, '/sos');
|
||||
},
|
||||
label: const Text(
|
||||
requestSOS,
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import 'package:intl/intl.dart';
|
||||
import 'package:location/location.dart';
|
||||
|
||||
class SosService{
|
||||
static final SosService _instance = SosService();
|
||||
static SosService get instance => _instance;
|
||||
DateFormat todayFormat = DateFormat("yMdHms");
|
||||
Future<LocationData?> getUserLocation() async {
|
||||
Location location = Location();
|
||||
LocationData? locationData;
|
||||
bool serviceEnabled = false;
|
||||
PermissionStatus permissionGranted;
|
||||
serviceEnabled = await location.serviceEnabled();
|
||||
if (!serviceEnabled) {
|
||||
serviceEnabled = await location.requestService();
|
||||
if (!serviceEnabled) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
permissionGranted = await location.hasPermission();
|
||||
if (permissionGranted == PermissionStatus.denied) {
|
||||
permissionGranted = await location.requestPermission();
|
||||
if (permissionGranted != PermissionStatus.granted) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
LocationData newLocationData = await location.getLocation();
|
||||
locationData = newLocationData;
|
||||
return locationData;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/sos/sos_bloc.dart';
|
||||
import 'package:unit2/screens/sos/index.dart';
|
||||
import 'package:unit2/screens/unit2/homepage.dart/components/menu.dart';
|
||||
import 'package:unit2/screens/unit2/login/login.dart';
|
||||
import 'package:unit2/utils/global_context.dart';
|
||||
|
@ -34,13 +36,21 @@ class AppRouter {
|
|||
return const QRLogin();
|
||||
});
|
||||
case '/profile':
|
||||
ProfileArguments arguments = routeSettings.arguments as ProfileArguments;
|
||||
ProfileArguments arguments =
|
||||
routeSettings.arguments as ProfileArguments;
|
||||
BlocProvider.of<ProfileBloc>(
|
||||
NavigationService.navigatorKey.currentContext!)
|
||||
.add(LoadProfile(token: arguments.token, userID: arguments.userID));
|
||||
return MaterialPageRoute(builder: (_) {
|
||||
return const ProfileInfo();
|
||||
});
|
||||
case '/sos':
|
||||
return MaterialPageRoute(builder: (BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => SosBloc()..add(LoadUserLocation()),
|
||||
child: const SosScreen(),
|
||||
);
|
||||
});
|
||||
default:
|
||||
return MaterialPageRoute(builder: (context) {
|
||||
return Container();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue