Merge remote-tracking branch 'origin/master' into WIP#feat#heartbeat-manager
commit
7cca6f3740
|
@ -2,5 +2,5 @@
|
|||
|
||||
final String baseUrlCore = "http://localhost/core";
|
||||
final String baseUrlSignaling = "http://localhost/signal";
|
||||
final String baseUrlLogin = "http://localhost/login";
|
||||
final String baseUrlLogin = "http://localhost:1837";
|
||||
final String globalUserId = "u-fb91825f564a3cc110f11836fedea6f4";
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
import "dart:async";
|
||||
import "package:http/http.dart" as http;
|
||||
import "dart:io";
|
||||
import "dart:convert";
|
||||
|
||||
import "../models/user_model.dart";
|
||||
import "../services/cache_http.dart";
|
||||
import "../services/login_manager.dart";
|
||||
import "../../settings.dart";
|
||||
|
||||
class ContactApiProvider {
|
||||
CacheHttp cache = CacheHttp();
|
||||
LoginManager loginManager = LoginManager();
|
||||
|
||||
Future<List<User>> fetchContacts() async {
|
||||
final jwt = await loginManager.getToken();
|
||||
|
||||
try {
|
||||
final responseBody =
|
||||
await this.cache.fetch("$baseUrlCore/user/$globalUserId/contact/");
|
||||
await this.cache.fetch("$baseUrlCore/user/contact", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
return jsonDecode(responseBody)
|
||||
.map<User>((user) => User.fromJson(user))
|
||||
.toList();
|
||||
|
@ -21,7 +29,14 @@ class ContactApiProvider {
|
|||
}
|
||||
}
|
||||
|
||||
void createContact(User user) async =>
|
||||
await http.post("$baseUrlCore/user/contact",
|
||||
headers: {"Content-Type": "application/json"}, body: user.toJson);
|
||||
void createContact(User user) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
|
||||
await http.post("$baseUrlCore/user/contact",
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
},
|
||||
body: user.toJson);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,47 @@
|
|||
import "dart:async";
|
||||
import "package:http/http.dart" as http;
|
||||
import "dart:io";
|
||||
import "dart:convert";
|
||||
|
||||
import "../models/conversation_model.dart";
|
||||
import "../models/user_model.dart";
|
||||
|
||||
import "../services/cache_http.dart";
|
||||
|
||||
import "../services/login_manager.dart";
|
||||
import "../../settings.dart";
|
||||
|
||||
class ConversationApiProvider {
|
||||
CacheHttp cache = CacheHttp();
|
||||
LoginManager loginManager = LoginManager();
|
||||
|
||||
Future<Conversation> createConversation(String title) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
final response = await http.post("$baseUrlCore/user/conversation",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
},
|
||||
body: jsonEncode({"title": title}));
|
||||
|
||||
return Conversation.fromJson(jsonDecode(response.body));
|
||||
}
|
||||
|
||||
void deleteConversation(String id) async =>
|
||||
await http.delete("$baseUrlCore/user/conversation/$id");
|
||||
void deleteConversation(String id) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
await http.delete("$baseUrlCore/user/conversation/$id", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<Conversation>> fetchConversations() async {
|
||||
final jwt = await loginManager.getToken();
|
||||
print("jwt: ${jwt}");
|
||||
try {
|
||||
final responseBody = await this
|
||||
.cache
|
||||
.fetch("$baseUrlCore/user/$globalUserId/conversation/");
|
||||
final responseBody =
|
||||
await this.cache.fetch("$baseUrlCore/user/conversation", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
return jsonDecode(responseBody)
|
||||
.map<Conversation>(
|
||||
(conversation) => Conversation.fromJson(conversation))
|
||||
|
@ -38,9 +52,14 @@ class ConversationApiProvider {
|
|||
}
|
||||
|
||||
Future<Conversation> fetchConversation(String id) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
try {
|
||||
final responseBody =
|
||||
await this.cache.fetch("$baseUrlCore/user/conversation/$id");
|
||||
final responseBody = await this
|
||||
.cache
|
||||
.fetch("$baseUrlCore/user/conversation/$id", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
return Conversation.fromJson(jsonDecode(responseBody));
|
||||
} catch (e) {
|
||||
throw e;
|
||||
|
@ -48,10 +67,14 @@ class ConversationApiProvider {
|
|||
}
|
||||
|
||||
Future<List<User>> fetchConversationMembers(String id) async {
|
||||
final jwt = await loginManager.getToken();
|
||||
try {
|
||||
final responseBody = await this
|
||||
.cache
|
||||
.fetch("$baseUrlCore/user/$globalUserId/conversation/$id/member/");
|
||||
.fetch("$baseUrlCore/user/conversation/$id/member", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
return jsonDecode(responseBody)
|
||||
.map<User>((user) => User.fromJson(user))
|
||||
.toList();
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import "dart:async";
|
||||
import "package:http/http.dart" as http;
|
||||
import "dart:convert";
|
||||
|
||||
import "../models/user_model.dart";
|
||||
import "dart:io";
|
||||
|
||||
import "../../settings.dart";
|
||||
|
||||
class LoginApiProvider {
|
||||
Future<String> initAuthentication(User user) async {
|
||||
Future<String> initAuthentication(String phoneNumber) async {
|
||||
final response = await http.post("$baseUrlLogin/init",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: jsonEncode({"phone_number": user.phoneNumber}));
|
||||
headers: {HttpHeaders.contentTypeHeader: "application/json"},
|
||||
body: jsonEncode({"phone_number": phoneNumber}));
|
||||
if (response.statusCode == 400 || response.statusCode == 500) {
|
||||
throw response.statusCode;
|
||||
}
|
||||
|
@ -19,9 +18,11 @@ class LoginApiProvider {
|
|||
|
||||
Future<String> verifyOtp(String otp, String nonce, String clientid) async {
|
||||
final response = await http.post("$baseUrlLogin/verify",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
headers: {HttpHeaders.contentTypeHeader: "application/json"},
|
||||
body: jsonEncode({"code": otp, "nonce": nonce, "clientid": clientid}));
|
||||
if (response.statusCode == 400 || response.statusCode == 404 || response.statusCode == 500) {
|
||||
if (response.statusCode == 400 ||
|
||||
response.statusCode == 404 ||
|
||||
response.statusCode == 500) {
|
||||
throw response.statusCode;
|
||||
}
|
||||
return response.body;
|
||||
|
@ -29,7 +30,7 @@ class LoginApiProvider {
|
|||
|
||||
Future<String> loginTest(String userId, String clientId) async {
|
||||
final response = await http.post("$baseUrlLogin/login",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
headers: {HttpHeaders.contentTypeHeader: "application/json"},
|
||||
body: jsonEncode({"userid": userId, "clientid": clientId}));
|
||||
|
||||
return response.body;
|
||||
|
|
|
@ -1,26 +1,38 @@
|
|||
import "dart:async";
|
||||
import "dart:convert";
|
||||
import "dart:io";
|
||||
import "package:http/http.dart" as http;
|
||||
|
||||
import "../models/user_model.dart";
|
||||
import "../services/cache_http.dart";
|
||||
import "../services/login_manager.dart";
|
||||
import "../../settings.dart";
|
||||
|
||||
class UserApiProvider {
|
||||
CacheHttp cache;
|
||||
CacheHttp cache = CacheHttp();
|
||||
LoginManager loginManager = LoginManager();
|
||||
|
||||
Future<User> createUser(User user) async {
|
||||
// Prob need to add the headers
|
||||
final jwt = loginManager.getToken();
|
||||
final response = await http.post("$baseUrlCore/user",
|
||||
headers: {"Content-Type": "application/json"}, body: user.toJson());
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
},
|
||||
body: user.toJson());
|
||||
|
||||
return User.fromJson(jsonDecode(response.body));
|
||||
}
|
||||
|
||||
Future<User> fetchUserByPhone(String phoneNumber) async {
|
||||
final jwt = loginManager.getToken();
|
||||
try {
|
||||
final responseBody =
|
||||
await this.cache.fetch("$baseUrlCore/user?phone_number=$phoneNumber");
|
||||
final responseBody = await this
|
||||
.cache
|
||||
.fetch("$baseUrlCore/user?phone_number=$phoneNumber", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
return User.fromJson(jsonDecode(responseBody));
|
||||
} catch (e) {
|
||||
throw e;
|
||||
|
@ -28,8 +40,13 @@ class UserApiProvider {
|
|||
}
|
||||
|
||||
Future<User> fetchUserById(String id) async {
|
||||
final jwt = loginManager.getToken();
|
||||
try {
|
||||
final responseBody = await this.cache.fetch("$baseUrlCore/user/id/$id");
|
||||
final responseBody =
|
||||
await this.cache.fetch("$baseUrlCore/user/id/$id", headers: {
|
||||
HttpHeaders.contentTypeHeader: "application/json",
|
||||
HttpHeaders.authorizationHeader: "Bearer $jwt"
|
||||
});
|
||||
return User.fromJson(jsonDecode(responseBody));
|
||||
} catch (e) {
|
||||
throw e;
|
||||
|
|
|
@ -29,13 +29,14 @@ class CacheHttp {
|
|||
}
|
||||
|
||||
// Returns raw response body
|
||||
Future<String> fetch(String url, {bool update = false}) async {
|
||||
Future<String> fetch(String url,
|
||||
{bool update = false, Map<String, String> headers = const {}}) async {
|
||||
if (!this.hasInit) {
|
||||
this.hasInit = true;
|
||||
await this.init();
|
||||
}
|
||||
try {
|
||||
final response = await http.get(url);
|
||||
final response = await http.get(url, headers: headers);
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
// Unsuccessful response, use cache
|
||||
final body = await this.getCache(url);
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
import "../resources/login_api_provider.dart";
|
||||
import "../models/user_model.dart";
|
||||
import "../resources/user_api_provider.dart";
|
||||
import "../../settings.dart";
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class LoginManager {
|
||||
final loginApiProvider = LoginApiProvider();
|
||||
User user;
|
||||
String clientid;
|
||||
String nonce;
|
||||
|
||||
LoginManager(User user, String clientid) {
|
||||
this.user = user;
|
||||
this.clientid = clientid;
|
||||
this.nonce = "";
|
||||
}
|
||||
|
||||
// Returns JWT, blank string if nothing is found
|
||||
Future<String> getToken() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
@ -23,23 +18,35 @@ class LoginManager {
|
|||
}
|
||||
|
||||
// Throws error status code if it occurs
|
||||
Future<void> initAuthentication(User user) async {
|
||||
Future<void> initAuthentication(String phoneNumber) async {
|
||||
try {
|
||||
final nonce = await loginApiProvider.initAuthentication(user);
|
||||
final nonce = await loginApiProvider.initAuthentication(phoneNumber);
|
||||
this.nonce = nonce;
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Throws error status code if it occurs, otherwise returns jwt
|
||||
Future<String> processOTP(String otp) async {
|
||||
Future<String> processOtp(String otp) async {
|
||||
try {
|
||||
final jwt = await loginApiProvider.verifyOtp(otp, this.nonce, this.clientid);
|
||||
final jwt =
|
||||
await loginApiProvider.verifyOtp(otp, this.nonce, this.clientid);
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString("token", jwt);
|
||||
return jwt;
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> loginTest() async {
|
||||
try {
|
||||
final jwt = await loginApiProvider.loginTest(globalUserId, "1");
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString("token", jwt);
|
||||
return jwt;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import "package:flutter/material.dart";
|
||||
import "package:flutter_svg/flutter_svg.dart";
|
||||
|
||||
import "../../services/login_manager.dart";
|
||||
import "./widgets/welcome_page.dart";
|
||||
import "./widgets/login_page.dart";
|
||||
import "./widgets/otp_page.dart";
|
||||
|
||||
class Welcome extends StatelessWidget {
|
||||
final String logo = "assets/logo.png";
|
||||
final LoginManager loginManager = LoginManager();
|
||||
final Map<String, String> user = {};
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -42,10 +44,13 @@ class Welcome extends StatelessWidget {
|
|||
builder = (BuildContext _) => WelcomePage();
|
||||
break;
|
||||
case "welcome/login":
|
||||
builder = (BuildContext _) => LoginPage();
|
||||
builder = (BuildContext _) =>
|
||||
LoginPage(loginManager: loginManager);
|
||||
break;
|
||||
case "welcome/otp":
|
||||
builder = (BuildContext _) => OtpPage(buttonCallback: () {
|
||||
builder = (BuildContext _) =>
|
||||
OtpPage(buttonCallback: (String otp) async {
|
||||
// loginManager.processOtp(otp); disabled for testing
|
||||
Navigator.of(context).pushNamed("/home");
|
||||
});
|
||||
break;
|
||||
|
|
|
@ -2,10 +2,27 @@ import "package:flutter/material.dart";
|
|||
import "package:flutter_svg/flutter_svg.dart";
|
||||
|
||||
import "../../widgets/text_button.dart";
|
||||
import "../../../services/login_manager.dart";
|
||||
import "phone_input.dart";
|
||||
|
||||
class LoginPage extends StatelessWidget {
|
||||
class LoginPage extends StatefulWidget {
|
||||
final LoginManager loginManager;
|
||||
|
||||
LoginPage({@required this.loginManager});
|
||||
|
||||
@override
|
||||
_LoginPageState createState() => _LoginPageState();
|
||||
}
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
final String phoneSvg = "assets/phoneno.svg";
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -30,13 +47,16 @@ class LoginPage extends StatelessWidget {
|
|||
.title
|
||||
.copyWith(fontWeight: FontWeight.w400)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20.0), child: PhoneInput()),
|
||||
padding: EdgeInsets.only(top: 20.0),
|
||||
child: PhoneInput(controller: controller)),
|
||||
]),
|
||||
Spacer(),
|
||||
TextButton(
|
||||
text: "Continue",
|
||||
onClickCallback: () =>
|
||||
Navigator.pushNamed(context, 'welcome/otp')),
|
||||
onClickCallback: () {
|
||||
widget.loginManager.loginTest();
|
||||
Navigator.pushNamed(context, 'welcome/otp');
|
||||
}),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,21 @@ import "package:flutter_svg/flutter_svg.dart";
|
|||
import "../../widgets/text_button.dart";
|
||||
|
||||
// Callback types
|
||||
typedef void ButtonCallback();
|
||||
typedef void ButtonCallback(String otp);
|
||||
|
||||
class OtpPage extends StatelessWidget {
|
||||
final String phoneSvg = "assets/authenticate.svg";
|
||||
class OtpPage extends StatefulWidget {
|
||||
final ButtonCallback buttonCallback;
|
||||
|
||||
OtpPage({@required this.buttonCallback});
|
||||
|
||||
@override
|
||||
_OtpPageState createState() => _OtpPageState();
|
||||
}
|
||||
|
||||
class _OtpPageState extends State<OtpPage> {
|
||||
final String phoneSvg = "assets/authenticate.svg";
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
|
@ -39,6 +46,7 @@ class OtpPage extends StatelessWidget {
|
|||
padding: EdgeInsets.only(top: 20.0),
|
||||
child: Center(
|
||||
child: PinCodeTextField(
|
||||
controller: controller,
|
||||
highlight: true,
|
||||
highlightColor: Colors.white,
|
||||
/*hideCharacter: true,*/
|
||||
|
@ -52,7 +60,9 @@ class OtpPage extends StatelessWidget {
|
|||
Theme.of(context).accentTextTheme.display3))),
|
||||
]),
|
||||
Spacer(),
|
||||
TextButton(text: "Done", onClickCallback: () => buttonCallback()),
|
||||
TextButton(
|
||||
text: "Done",
|
||||
onClickCallback: () => widget.buttonCallback(controller.text)),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import "package:flutter/material.dart";
|
||||
|
||||
class PhoneInput extends StatelessWidget {
|
||||
final TextEditingController controller;
|
||||
|
||||
PhoneInput({@required this.controller});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipRRect(
|
||||
|
@ -21,6 +25,7 @@ class PhoneInput extends StatelessWidget {
|
|||
)),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
autocorrect: false,
|
||||
cursorWidth: 2.0,
|
||||
cursorColor: Colors.white,
|
||||
|
|
Loading…
Reference in New Issue