Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Commit

Permalink
OT-254 Add Registration Flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Boehrsi committed Jun 28, 2019
1 parent 6653f9e commit 649fcce
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 148 deletions.
1 change: 1 addition & 0 deletions lib/src/assets/json/providers.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
{
"id": "mailbox",
"name": "Mailbox.org",
"register_link": "https://register.mailbox.org/",
"preset": {
"incoming_security": "ssltls",
"incoming_server": "imap.mailbox.org",
Expand Down
6 changes: 3 additions & 3 deletions lib/src/chat/chat_composer_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import 'package:ox_coi/src/utils/security.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:delta_chat_core/delta_chat_core.dart' as Dcc;
import 'package:delta_chat_core/delta_chat_core.dart';

class ChatComposerBloc extends Bloc<ChatComposerEvent, ChatComposerState> {
StreamSubscription<RecordStatus> _recorderSubscription;
Expand Down Expand Up @@ -128,10 +128,10 @@ class ChatComposerBloc extends Bloc<ChatComposerEvent, ChatComposerState> {
int type;
if (pickImage) {
file = await ImagePicker.pickImage(source: ImageSource.camera);
type = Dcc.ChatMsg.typeImage;
type = ChatMsg.typeImage;
} else {
file = await ImagePicker.pickVideo(source: ImageSource.camera);
type = Dcc.ChatMsg.typeVideo;
type = ChatMsg.typeVideo;
}
if (file != null) {
dispatch(StopImageOrVideoRecording(filePath: file.path, type: type));
Expand Down
5 changes: 5 additions & 0 deletions lib/src/chatlist/chat_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ import 'package:ox_coi/src/utils/widgets.dart';
import 'package:ox_coi/src/widgets/search.dart';
import 'package:ox_coi/src/widgets/state_info.dart';

enum ChatListItemType {
chat,
message,
}

class ChatList extends RootChild {
final Navigation navigation = Navigation();

Expand Down
39 changes: 18 additions & 21 deletions lib/src/chatlist/chat_list_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import 'dart:async';
import 'dart:collection';

import 'package:bloc/bloc.dart';
import 'package:delta_chat_core/delta_chat_core.dart';
import 'package:delta_chat_core/delta_chat_core.dart' as Dcc;
import 'package:ox_coi/src/chatlist/chat_list_event_state.dart';
import 'package:ox_coi/src/data/chat_extension.dart';
import 'package:ox_coi/src/data/repository.dart';
Expand All @@ -56,14 +56,11 @@ import 'package:ox_coi/src/utils/date.dart';
import 'package:ox_coi/src/utils/text.dart';
import 'package:rxdart/rxdart.dart';

enum ChatListItemType {
chat,
message,
}
import 'chat_list.dart';

class ChatListBloc extends Bloc<ChatListEvent, ChatListState> {
final Repository<Chat> _chatRepository = RepositoryManager.get(RepositoryType.chat);
final Repository<ChatMsg> _messageListRepository = RepositoryManager.get(RepositoryType.chatMessage, Chat.typeInvite);
final Repository<Dcc.Chat> _chatRepository = RepositoryManager.get(RepositoryType.chat);
final Repository<Dcc.ChatMsg> _messageListRepository = RepositoryManager.get(RepositoryType.chatMessage, Dcc.Chat.typeInvite);
final _messageListBloc = MessageListBloc();
RepositoryMultiEventStreamHandler _repositoryStreamHandler;
String _currentSearch;
Expand Down Expand Up @@ -113,15 +110,15 @@ class ChatListBloc extends Bloc<ChatListEvent, ChatListState> {

void setupChatListListener() {
if (_repositoryStreamHandler == null) {
_repositoryStreamHandler = RepositoryMultiEventStreamHandler(Type.publish, [Event.incomingMsg, Event.msgsChanged], _chatListModified);
_repositoryStreamHandler = RepositoryMultiEventStreamHandler(Type.publish, [Dcc.Event.incomingMsg, Dcc.Event.msgsChanged], _chatListModified);
_chatRepository.addListener(_repositoryStreamHandler);

final messageListObservable = Observable<MessageListState>(_messageListBloc.state);
messageListObservable.listen((state) async {
if (state is MessagesStateSuccess) {
var uniqueInviteMap = LinkedHashMap<int, int>();
await Future.forEach(state.messageIds, (messageId) async {
ChatMsg message = _messageListRepository.get(messageId);
Dcc.ChatMsg message = _messageListRepository.get(messageId);
var contactId = await message.getFromId();
if (!uniqueInviteMap.containsKey(contactId)) {
uniqueInviteMap.putIfAbsent(contactId, () => messageId);
Expand All @@ -145,7 +142,7 @@ class ChatListBloc extends Bloc<ChatListEvent, ChatListState> {
}

Future setupInvites(bool chatListRefreshNeeded) async {
_messageListBloc.dispatch(RequestMessages(chatId: Chat.typeInvite));
_messageListBloc.dispatch(RequestMessages(chatId: Dcc.Chat.typeInvite));
}

ChatListItemWrapper createChatListItemWrapper(List<int> ids, List<int> lastUpdateValues, [List<int> types]) {
Expand All @@ -171,10 +168,10 @@ class ChatListBloc extends Bloc<ChatListEvent, ChatListState> {
} else if (nextInvite >= inviteMessageIds.length) {
nextChat = addChatToResult(ids, getChat(chatIds, nextChat), types, lastUpdateValues, nextChat);
} else {
Chat chat = getChat(chatIds, nextChat);
ChatSummary chatSummary = chat.get(ChatExtension.chatSummary);
Dcc.Chat chat = getChat(chatIds, nextChat);
Dcc.ChatSummary chatSummary = chat.get(ChatExtension.chatSummary);
var chatTimestamp = chatSummary.timestamp;
ChatMsg message = getMessage(inviteMessageIds, nextInvite);
Dcc.ChatMsg message = getMessage(inviteMessageIds, nextInvite);
var inviteTimestamp = await message.getTimestamp();
if (chatTimestamp > inviteTimestamp) {
nextChat = addChatToResult(ids, chat, types, lastUpdateValues, nextChat);
Expand All @@ -191,19 +188,19 @@ class ChatListBloc extends Bloc<ChatListEvent, ChatListState> {
);
}

Chat getChat(List<int> chatIds, int nextChat) => _chatRepository.get(chatIds[nextChat]);
Dcc.Chat getChat(List<int> chatIds, int nextChat) => _chatRepository.get(chatIds[nextChat]);

ChatMsg getMessage(List<int> inviteMessageIds, int nextInvite) => _messageListRepository.get(inviteMessageIds[nextInvite]);
Dcc.ChatMsg getMessage(List<int> inviteMessageIds, int nextInvite) => _messageListRepository.get(inviteMessageIds[nextInvite]);

int addChatToResult(List ids, Chat chat, List types, List lastUpdateValues, int nextChat) {
int addChatToResult(List ids, Dcc.Chat chat, List types, List lastUpdateValues, int nextChat) {
ids.add(chat.id);
types.add(ChatListItemType.chat);
lastUpdateValues.add(chat.lastUpdate);
nextChat++;
return nextChat;
}

int addInviteMessageToResult(List ids, ChatMsg message, List types, List lastUpdateValues, int nextInvite) {
int addInviteMessageToResult(List ids, Dcc.ChatMsg message, List types, List lastUpdateValues, int nextInvite) {
ids.add(message.id);
types.add(ChatListItemType.message);
lastUpdateValues.add(message.lastUpdate);
Expand All @@ -216,15 +213,15 @@ class ChatListBloc extends Bloc<ChatListEvent, ChatListState> {
List<int> chatIds = List();
var lastUpdateValues = List<int>();
if (chatListRefreshNeeded) {
ChatList chatList = ChatList();
var chatList = Dcc.ChatList();
await chatList.setup(_currentSearch);
int chatCount = await chatList.getChatCnt();
Map<int, dynamic> chatSummaries = Map();
for (int i = 0; i < chatCount; i++) {
int chatId = await chatList.getChat(i);
chatIds.add(chatId);
var summaryData = await chatList.getChatSummary(i);
var chatSummary = ChatSummary.fromMethodChannel(summaryData);
var chatSummary = Dcc.ChatSummary.fromMethodChannel(summaryData);
chatSummaries.putIfAbsent(chatId, () => chatSummary);
}
await chatList.tearDown();
Expand Down Expand Up @@ -259,13 +256,13 @@ class ChatListBloc extends Bloc<ChatListEvent, ChatListState> {
}

Future<void> _updateSummaries() async {
ChatList chatList = ChatList();
var chatList = Dcc.ChatList();
await chatList.setup();
int chatCount = await chatList.getChatCnt();
for (int i = 0; i < chatCount; i++) {
int chatId = await chatList.getChat(i);
var summaryData = await chatList.getChatSummary(i);
var chatSummary = ChatSummary.fromMethodChannel(summaryData);
var chatSummary = Dcc.ChatSummary.fromMethodChannel(summaryData);
_chatRepository.get(chatId).set(ChatExtension.chatSummary, chatSummary);
}
await chatList.tearDown();
Expand Down
2 changes: 1 addition & 1 deletion lib/src/chatlist/chat_list_event_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

import 'package:meta/meta.dart';

import 'chat_list_bloc.dart';
import 'chat_list.dart';

abstract class ChatListEvent {}

Expand Down
5 changes: 5 additions & 0 deletions lib/src/l10n/localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ class AppLocalizations {

String get loginErrorDialogTitle => Intl.message('Login failed', name: 'loginErrorDialogTitle');

// Register
String get registerTitle => Intl.message('Register', name: 'registerTitle');

String get registerText => Intl.message('Choose a provider from the list below to create a new account', name: 'registerText');

// Mail
String get mailTitle => Intl.message('Mail', name: 'mailTitle');

Expand Down
128 changes: 61 additions & 67 deletions lib/src/login/login.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class _LoginState extends State<Login> {
super.initState();
var navigation = Navigation();
navigation.current = Navigatable(Type.login);
_loginBloc.dispatch(RequestProviders());
_loginBloc.dispatch(RequestProviders(type: ProviderListType.login));
final loginObservable = new Observable<LoginState>(_loginBloc.state);
loginObservable.listen((state) => handleLoginStateChange(state));
}
Expand Down Expand Up @@ -110,89 +110,83 @@ class _LoginState extends State<Login> {

Widget createWelcomeScreen(){
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: loginHorizontalPadding, right: loginHorizontalPadding, bottom: loginVerticalPadding, top: loginTopPadding),
child: Flex(
direction: Axis.vertical,
padding: EdgeInsets.only(left: loginHorizontalPadding, right: loginHorizontalPadding, bottom: loginVerticalPadding, top: loginTopPadding),
child: Column(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
AppLocalizations.of(context).loginWelcomeText,
style: loginTitleText,
),
Image(
image: AssetImage(AppLocalizations.of(context).appLogoUrl),
height: loginLogoSize,
width: loginLogoSize,
),
Padding(
padding: EdgeInsets.only(bottom: loginVerticalPadding),
child: Text(
AppLocalizations.of(context).loginFirstInformationText,
textAlign: TextAlign.center,
),
),
RaisedButton(
color: accent,
textColor: text,
child: SizedBox(
width: loginButtonWidth,
child: Text(
AppLocalizations.of(context).loginSignInButtonText,
textAlign: TextAlign.center,
),
),
onPressed: _goToProviderList
Text(
AppLocalizations.of(context).loginWelcomeText,
style: loginTitleText,
),
Image(
image: AssetImage(AppLocalizations.of(context).appLogoUrl),
height: loginLogoSize,
width: loginLogoSize,
),
Padding(
padding: EdgeInsets.only(bottom: loginVerticalPadding),
child: Text(
AppLocalizations.of(context).loginFirstInformationText,
textAlign: TextAlign.center,
),
),
RaisedButton(
color: accent,
textColor: text,
child: SizedBox(
width: loginButtonWidth,
child: Text(
AppLocalizations.of(context).loginSignInButtonText,
textAlign: TextAlign.center,
),
Padding(padding: EdgeInsets.all(loginVerticalPadding8dp)),
FlatButton(
//TODO: Add register action
onPressed: null,
),
onPressed: () {
_goToProviderList(ProviderListType.login);
}
),
Padding(padding: EdgeInsets.all(loginVerticalPadding8dp),
child: FlatButton(
child: Text(
AppLocalizations.of(context).loginRegisterButtonText,
AppLocalizations
.of(context)
.loginRegisterButtonText,
style: loginFlatButtonText,
)
),
],
),
onPressed: () {
_goToProviderList(ProviderListType.register);
}
),
),
Align(
heightFactor: loginTermsAndConditionsHeightFactor,
alignment: Alignment.bottomCenter,
child: RichText(
RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: loginTermsAndConditionText,
text: AppLocalizations.of(context).loginTermsConditionPrivacyText,
children: [
UrlTextSpan(
url: null,
text: AppLocalizations.of(context).loginTermsConditionText
),
TextSpan(
text: AppLocalizations.of(context).loginTermsConditionPrivacyAndText
),
UrlTextSpan(
url: null,
text: AppLocalizations.of(context).loginPrivacyDeclarationText
)
]
style: loginTermsAndConditionText,
text: AppLocalizations.of(context).loginTermsConditionPrivacyText,
children: [
UrlTextSpan(
url: null,
text: AppLocalizations.of(context).loginTermsConditionText
),
TextSpan(
text: AppLocalizations.of(context).loginTermsConditionPrivacyAndText
),
UrlTextSpan(
url: null,
text: AppLocalizations.of(context).loginPrivacyDeclarationText
)
]
)
)
)
),
],
),
),
);
}

void _goToProviderList() {
void _goToProviderList(ProviderListType type) {
var navigation = Navigation();
navigation.push(
context,
MaterialPageRoute(
builder: (context) => ProviderList(widget._success)
builder: (context) => ProviderList(type: type, success: widget._success,)
)
);
}
Expand Down
12 changes: 9 additions & 3 deletions lib/src/login/login_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ import 'package:ox_coi/src/login/login_events_state.dart';
import 'package:ox_coi/src/login/providers.dart';
import 'package:ox_coi/src/utils/error.dart';
import 'package:ox_coi/src/utils/core.dart';
import 'package:ox_coi/src/utils/text.dart';
import 'package:rxdart/rxdart.dart';
import 'package:flutter/services.dart' show rootBundle;

import 'login_provider_list.dart';

class LoginBloc extends Bloc<LoginEvent, LoginState> {
DeltaChatCore _core = DeltaChatCore();
Context _context = Context();
Expand All @@ -69,7 +72,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
Stream<LoginState> mapEventToState(LoginState currentState, LoginEvent event) async* {
if(event is RequestProviders){
try{
_loadProviders();
_loadProviders(event.type);
}catch(error){
yield LoginStateFailure(error: error.toString());
}
Expand Down Expand Up @@ -176,12 +179,15 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
dispatch(LoginProgress(0, error));
}

void _loadProviders() async{
void _loadProviders(ProviderListType type) async{
Map<String, dynamic> json = await rootBundle.loadString('lib/src/assets/json/providers.json')
.then((jsonStr) => jsonDecode(jsonStr));

Providers providers = Providers.fromJson(json);
dispatch(ProvidersLoaded(providers: providers.ProvidersList));
if (type == ProviderListType.register) {
providers.providerList.removeWhere((provider) => isNullOrEmpty(provider.registerLink));
}
dispatch(ProvidersLoaded(providers: providers.providerList));
}

_setupConfigWithProvider(ProviderLoginButtonPressed event) async{
Expand Down
Loading

0 comments on commit 649fcce

Please sign in to comment.