Skip to content

Instantly share code, notes, and snippets.

@jaggzh
Last active June 10, 2020 21:18
Show Gist options
  • Save jaggzh/8b94065620867b7f84b208fdb504f282 to your computer and use it in GitHub Desktop.
Save jaggzh/8b94065620867b7f84b208fdb504f282 to your computer and use it in GitHub Desktop.
class Cfg {
static final apiUrl = 'https://www.this-is-my-backend-api-site.com/api';
static final urlAuth = apiUrl+'/auth';
}
//import 'dart:async';
import 'package:flutter/rendering.dart';
//import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
//import '../models/user.dart';
//import '../util/login_form_validator.dart';
import '../ui/bb_convex.dart';
class ScreenHome extends StatefulWidget {
@override
_ScreenHomeState createState() => _ScreenHomeState();
}
class _ScreenHomeState extends State<ScreenHome> {
final formKey = GlobalKey<FormState>();
final scaffoldKey = GlobalKey<ScaffoldState>();
// var _context;
Widget build(BuildContext context) {
// _context = context;
return Stack(children: [
Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
colors: [
//const Color(0xFF3366FF),
//const Color(0xFF00CCFF),
const Color(0xFFc0CCFF),
const Color(0xFF5366cF),
],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.2, .5),
//begin: Alignment.topLeft,
//end: Alignment(0.8, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
),
Scaffold(
key: scaffoldKey,
extendBodyBehindAppBar: false,
//backgroundColor: Colors.white,
backgroundColor: Colors.transparent,
appBar: AppBar(
title: Text(
'Le\'App',
style: TextStyle(color: Colors.white70),
),
elevation: 0.0,
backgroundColor: Colors.transparent,
flexibleSpace: Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
colors: [
////const Color(0xFF3366FF), const Color(0xFF00CCFF),
//const Color(0xf05346FF), const Color(0x005346FF),
const Color(0x20ffffff), const Color(0x00ffffff),
],
begin: const FractionalOffset(.6, 1 - (-0.2)),
end: const FractionalOffset(1 - 0.475, 1 - 1.1),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
),
automaticallyImplyLeading: false,
leading: null,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.account_circle),
onPressed: () => Navigator.of(context).pop(null),
),
],
),
body: Stack(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: SingleChildScrollView(
child: Center(child: Text("You are here"))),
),
],
),
bottomNavigationBar: BBar(),
)
]);
}
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class HttpSession extends ChangeNotifier {
Map<String, String> headers = {};
//HttpSession() => {};
Future<Map> get(String url) async {
http.Response response = await http.get(url, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
Future<Map> post(String url, dynamic data) async {
http.Response response = await http.post(url, body: data, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
void updateCookie(http.Response response) {
String rawCookie = response.headers['set-cookie'];
if (rawCookie != null) {
int index = rawCookie.indexOf(';');
headers['cookie'] =
(index == -1) ? rawCookie : rawCookie.substring(0, index);
}
}
}
/*
static InheritedHttpSession of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<InheritedHttpSession>();
}
@override
bool updateShouldNotify(HttpSession old) => session != old.session;}
bool updateShouldNotify(HttpSession old) => session != old.session;}
class InheritedHttpSession extends InheritedWidget {
HttpSession session = HttpSession();
static InheritedHttpSession of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<InheritedHttpSession>();
}
@override
bool updateShouldNotify(HttpSession session) => session != old.session;
}
*/
//import 'dart:async';
import 'package:flutter/rendering.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import '../models/user.dart';
import '../util/login_form_validator.dart';
class OffsiteUserChangeListener extends StatelessWidget {
final scaffoldKey;
final user;
const OffsiteUserChangeListener({
Key key,
this.scaffoldKey,
this.user,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// Haven't tried logging in yet. Also, we might not even have build()'ed
if (user.loginState == LoginState.loggedIn) {
// We handled this ourselves. This is just a reminder for me
} else if (user.loginState == LoginState.success) {
user.loginState = LoginState.loggedIn;
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.pushReplacementNamed(context, '/home');
});
} else if (user.loginState == LoginState.inProgress) {
return Stack(children: [
Positioned.fill(child: Container(color: Color.fromRGBO(255, 255, 255, .7))),
//Opacity( opacity:1.0,
Center(child: CircularProgressIndicator()),
]);
} else if (user.loginState == LoginState.failed) {
final snackbar = SnackBar(
content: Text("Couldn't log in: ${user.loginMsg}"),
);
WidgetsBinding.instance.addPostFrameCallback((_) {
Scaffold.of(context).showSnackBar(snackbar);
});
}
return Offstage(child: Container(width:0, height:0)); // Dummy so we exist.
}
}
class ScreenLogin extends StatefulWidget {
@override
_ScreenLoginState createState() => _ScreenLoginState();
}
class _ScreenLoginState extends State<ScreenLogin> {
final formKey = GlobalKey<FormState>();
final scaffoldKey = GlobalKey<ScaffoldState>();
String _userid; // For the form fields.
String _pw;
var _context;
void _submitCommand() {
final form = formKey.currentState;
var _user = Provider.of<User>(_context, listen:false);
if (form.validate()) {
form.save(); // userid & pw passed val rules and are in _userid & _pw fields
_user.loginUnknownID(id: _userid, pw: _pw); //_loginCommand();
}
}
@override
Widget build(BuildContext context) {
_context = context;
return Scaffold(
key: scaffoldKey,
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Login'),
),
body:
Stack(children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: SingleChildScrollView(
child: Form(
key: formKey,
child: Column(
children: <Widget>[
GestureDetector(
onTap: () { Navigator.pop(context); },
child: Hero(
tag: 'splash_img',
child: Image.asset('lib/assets/videos/0128.png', width: 150, height: 150,
),
),
),
TextFormField(
initialValue: "Username",
decoration: InputDecoration(labelText: 'Username / Email'),
validator: (val) => !ValidatorUsernameOrEmail.validate(val) ? 'Invalid Username or Email.' : null,
onSaved: (val) => _userid = val,
),
TextFormField(
initialValue: "Password",
decoration: InputDecoration(labelText: 'Password'),
validator: (val) => val.length < 4 ? 'Password too short..' : null,
onSaved: (val) => _pw = val,
obscureText: true,
),
RaisedButton(
onPressed: _submitCommand,
child: Text('Sign in'),
),
],
),
),
),
),
Consumer<User>(
builder: (context, user, child) => OffsiteUserChangeListener(
scaffoldKey: scaffoldKey,
user: user,
),
),
],)
);
}
}
import 'package:flutter/foundation.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'models/user.dart';
import 'screens/splash.dart';
import 'screens/login.dart';
import 'screens/home.dart';
import 'util/http_session.dart';
void main() => runApp(AppMain());
class Session extends InheritedWidget {
final HttpSession httpSession = HttpSession();
Session(child): super(child: child);
@override
bool updateShouldNotify(Session old) =>
httpSession != old.httpSession;
}
class AppMain extends StatefulWidget {
AppMain({Key key}) : super(key: key);
@override
_AppMainState createState() => _AppMainState();
}
class _AppMainState extends State<AppMain> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => User(),
//return MultiProvider(
// providers: [
// Provider<User>(create: (_) => User()),
// Provider<HttpSession>(create: (_) => HttpSession()),
//],
child: Session(MaterialApp(
title: 'Named Routes Demo',
initialRoute: '/',
routes: {
'/': (context) => ScreenSplash(),
'/login': (context) => ScreenLogin(),
'/home': (context) => ScreenHome(),
},
)),
);
}
}
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import '../util/common.dart';
class ScreenSplash extends StatefulWidget {
@override
_ScreenSplashState createState() => _ScreenSplashState();
}
class _ScreenSplashState extends State<ScreenSplash> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
ScreenState _screenState = ScreenState.here;
// bool _haveLeftScreen = false;
//bool _userHasInteracted = false; // used for web video, so we get an interaction
// in and then can play audio.
@override
void initState() {
super.initState();
_controller = VideoPlayerController.asset(
'lib/assets/videos/vid.mp4',
);
_initializeVideoPlayerFuture = _controller.initialize();
super.initState();
if (kIsWeb) _controller.setVolume(0.0); // needed for autovideo play
_controller.play();
_controller.addListener(() async {
if (!_controller.value.isPlaying) {
if (_screenState != ScreenState.here) {
//_controller.dispose();
} else {
//_haveLeftScreen = true;
_screenState = ScreenState.left;
await Navigator.pushNamed(context, '/login');
_screenState = ScreenState.returned;
//_haveLeftScreen = false;
_controller.setVolume(1.0);
}
}
});
/* ..setVolume(1.0)..initialize()..play();
.then((_) {
// Ensure the first frame is shown after the
// video is initialized, even before the
// play button has been pressed.
setState(() {});
}); */
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(),
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Veedios'),
backgroundColor: Colors.black87,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () async {
//_userHasInteracted = true;
_controller.setVolume(1.0);
if (!_controller.value.isPlaying) {
_controller.seekTo(Duration(seconds: 0));
_controller.play();
} else {
//_controller.pause();
//_haveLeftScreen = true;
_screenState = ScreenState.left;
await Navigator.pushNamed(context, '/login');
_screenState = ScreenState.returned;
//_haveLeftScreen = false;
}
},
child: IgnorePointer(
ignoring: true,
child: Stack(children: <Widget>[
// Image.asset(
// 'lib/assets/video/0019.png',
// width: 100,
// height: 100,
// ),
Padding(
padding: const EdgeInsets.all(72.0),
child: Hero(
tag: 'splash_img',
//child: Image.asset('lib/assets/videos/0128.png',),
child: VideoPlayer(_controller),
),
),
/* Hero(
tag: 'splash_img',
child: Image.asset('lib/assets/video/vid.png'),
), */
])),
));
} else {
return Center(child: CircularProgressIndicator());
}
})
]),
/*
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
*/
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
import 'package:flutter/foundation.dart';
import '../util/cfg.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
import '../util/http_session.dart';
import 'package:provider/provider.dart';
//import 'dart:io';
enum LoginState {
pre,
inProgress,
failed,
success, // when login succeeds
loggedIn, // callers of sign in should set this themselves
// once they've detected the success.
}
class User extends ChangeNotifier {
String id;
String username;
String pw;
String token;
LoginState loginState = LoginState.pre;
String loginMsg;
LoginResponse loginResponse;
void loginUnknownID({ // Not sure if username or email yet...
@required id,
@required pw,
}) async {
assert(id != null && pw != null,
'We need a username or email and a password.');
this.id = id; // No login yet. Just pretend
this.pw = pw;
loginState = LoginState.inProgress;
notifyListeners(); // But pretend slowly \/ \/ \/
loginResponse = await userGetLoginResponse(id: id, pw: pw);
if (loginResponse.success == 1) {
this.username = loginResponse.username;
this.token = loginResponse.token;
this.loginState = LoginState.success;
this.pw = null;
} else {
this.loginMsg = loginResponse.msg ?? "Unknown login error";
this.loginState = LoginState.failed;
}
//await Future.delayed(const Duration(seconds: 2), () {});
notifyListeners();
}
}
Future<LoginResponse> userGetLoginResponse({id, pw}) async {
LoginResponse loginResponse;
var http = Provider.of<HttpSession>(_context, listen:false);
final response = await http.get(
Cfg.urlAuth,
headers: {
'Authorization': "Basic $id:$pw"
//HttpHeaders.authorizationHeader: "$id:$pw"
},
);
if (response.statusCode == 200) {
final responseJson = json.decode(response.body);
loginResponse = LoginResponse.fromJsonIsSuccess(responseJson);
} else {
loginResponse = LoginResponse.bad(404);
}
return loginResponse;
}
class LoginResponse {
final String username;
final String token;
final String msg;
final int success;
final int statusCode;
LoginResponse({this.username, this.token,
this.success, this.msg, this.statusCode});
factory LoginResponse.fromJsonIsSuccess(Map<String, dynamic> json) {
if (json.containsKey('username') &&
json.containsKey('token') &&
json.containsKey('success')) {
return LoginResponse(
username: json['username'],
token: json['token'],
success: json['success'],
msg: json['msg'] ?? "",
statusCode: 200,
);
} else {
return LoginResponse(
username: "",
token: "",
success: 0,
msg: json['msg'] ?? "Unknown error. We're sorry too.",
statusCode: 200,
);
}
}
factory LoginResponse.bad(int code) {
return LoginResponse(
username: "",
token: "",
success: 0,
msg: "HTTP error ($code)",
statusCode: code,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment