ui: Migrate [AddContactPage] to Bloc
This commit is contained in:
parent
7a999d40d8
commit
489ef364c1
@ -139,6 +139,19 @@ files:
|
|||||||
removed:
|
removed:
|
||||||
type: List<String>
|
type: List<String>
|
||||||
default: "[]"
|
default: "[]"
|
||||||
|
# Triggered by the service in response to an [AddContactCommand].
|
||||||
|
- name: AddContactResultEvent
|
||||||
|
extends:
|
||||||
|
- BackgroundEvent
|
||||||
|
implements:
|
||||||
|
- JsonImplementation
|
||||||
|
attributes:
|
||||||
|
conversation:
|
||||||
|
type: Conversation?
|
||||||
|
deserialise: true
|
||||||
|
# Indicate if the conversation is new (true) or modified (false).
|
||||||
|
# Does not mean anything unless conversation != null.
|
||||||
|
added: bool
|
||||||
generate_builder: true
|
generate_builder: true
|
||||||
builder_name: "Event"
|
builder_name: "Event"
|
||||||
builder_baseclass: "BackgroundEvent"
|
builder_baseclass: "BackgroundEvent"
|
||||||
@ -229,6 +242,13 @@ files:
|
|||||||
preferences:
|
preferences:
|
||||||
type: PreferencesState
|
type: PreferencesState
|
||||||
deserialise: true
|
deserialise: true
|
||||||
|
- name: AddContactCommand
|
||||||
|
extends:
|
||||||
|
- BackgroundCommand
|
||||||
|
implements:
|
||||||
|
- JsonImplementation
|
||||||
|
attributes:
|
||||||
|
jid: String
|
||||||
generate_builder: true
|
generate_builder: true
|
||||||
# get${builder_Name}FromJson
|
# get${builder_Name}FromJson
|
||||||
builder_name: "Command"
|
builder_name: "Command"
|
||||||
|
@ -4,8 +4,8 @@ import "package:moxxyv2/ui/constants.dart";
|
|||||||
import "package:moxxyv2/ui/pages/register/register.dart";
|
import "package:moxxyv2/ui/pages/register/register.dart";
|
||||||
import "package:moxxyv2/ui/pages/postregister/postregister.dart";
|
import "package:moxxyv2/ui/pages/postregister/postregister.dart";
|
||||||
import "package:moxxyv2/ui/pages/sendfiles.dart";
|
import "package:moxxyv2/ui/pages/sendfiles.dart";
|
||||||
import "package:moxxyv2/ui/pages/addcontact/addcontact.dart";
|
|
||||||
*/
|
*/
|
||||||
|
import "package:moxxyv2/ui/pages/addcontact/addcontact.dart";
|
||||||
import "package:moxxyv2/ui/pages/settings/debugging.dart";
|
import "package:moxxyv2/ui/pages/settings/debugging.dart";
|
||||||
import "package:moxxyv2/ui/pages/settings/privacy.dart";
|
import "package:moxxyv2/ui/pages/settings/privacy.dart";
|
||||||
import "package:moxxyv2/ui/pages/settings/network.dart";
|
import "package:moxxyv2/ui/pages/settings/network.dart";
|
||||||
@ -29,6 +29,7 @@ import "package:moxxyv2/ui/bloc/conversation_bloc.dart";
|
|||||||
import "package:moxxyv2/ui/bloc/blocklist_bloc.dart";
|
import "package:moxxyv2/ui/bloc/blocklist_bloc.dart";
|
||||||
import "package:moxxyv2/ui/bloc/profile_bloc.dart";
|
import "package:moxxyv2/ui/bloc/profile_bloc.dart";
|
||||||
import "package:moxxyv2/ui/bloc/preferences_bloc.dart";
|
import "package:moxxyv2/ui/bloc/preferences_bloc.dart";
|
||||||
|
import "package:moxxyv2/ui/bloc/addcontact_bloc.dart";
|
||||||
import "package:moxxyv2/ui/service/download.dart";
|
import "package:moxxyv2/ui/service/download.dart";
|
||||||
import "package:moxxyv2/service/service.dart";
|
import "package:moxxyv2/service/service.dart";
|
||||||
import "package:moxxyv2/shared/commands.dart";
|
import "package:moxxyv2/shared/commands.dart";
|
||||||
@ -62,6 +63,7 @@ void setupBlocs(GlobalKey<NavigatorState> navKey) {
|
|||||||
GetIt.I.registerSingleton<BlocklistBloc>(BlocklistBloc());
|
GetIt.I.registerSingleton<BlocklistBloc>(BlocklistBloc());
|
||||||
GetIt.I.registerSingleton<ProfileBloc>(ProfileBloc());
|
GetIt.I.registerSingleton<ProfileBloc>(ProfileBloc());
|
||||||
GetIt.I.registerSingleton<PreferencesBloc>(PreferencesBloc());
|
GetIt.I.registerSingleton<PreferencesBloc>(PreferencesBloc());
|
||||||
|
GetIt.I.registerSingleton<AddContactBloc>(AddContactBloc());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Replace all Column(children: [ Padding(), Padding, ...]) with a
|
// TODO: Replace all Column(children: [ Padding(), Padding, ...]) with a
|
||||||
@ -104,6 +106,9 @@ void main() async {
|
|||||||
),
|
),
|
||||||
BlocProvider<PreferencesBloc>(
|
BlocProvider<PreferencesBloc>(
|
||||||
create: (_) => GetIt.I.get<PreferencesBloc>()
|
create: (_) => GetIt.I.get<PreferencesBloc>()
|
||||||
|
),
|
||||||
|
BlocProvider<AddContactBloc>(
|
||||||
|
create: (_) => GetIt.I.get<AddContactBloc>()
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
child: MyApp(navKey)
|
child: MyApp(navKey)
|
||||||
@ -235,11 +240,11 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
|||||||
networkRoute: (context) => const NetworkPage(),
|
networkRoute: (context) => const NetworkPage(),
|
||||||
privacyRoute: (context) => const PrivacyPage(),
|
privacyRoute: (context) => const PrivacyPage(),
|
||||||
debuggingRoute: (context) => DebuggingPage(),
|
debuggingRoute: (context) => DebuggingPage(),
|
||||||
|
addContactRoute: (context) => AddContactPage(),
|
||||||
/*
|
/*
|
||||||
registrationRoute: (context) => RegistrationPage(),
|
registrationRoute: (context) => RegistrationPage(),
|
||||||
postRegistrationRoute: (context) => const PostRegistrationPage(),
|
postRegistrationRoute: (context) => const PostRegistrationPage(),
|
||||||
sendFilesRoute: (context) => SendFilesPage(),
|
sendFilesRoute: (context) => SendFilesPage(),
|
||||||
addContactRoute: (context) => AddContactPage(),
|
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
home: Splashscreen()
|
home: Splashscreen()
|
||||||
|
@ -7,6 +7,7 @@ import "package:moxxyv2/service/preferences.dart";
|
|||||||
import "package:moxxyv2/service/roster.dart";
|
import "package:moxxyv2/service/roster.dart";
|
||||||
import "package:moxxyv2/service/database.dart";
|
import "package:moxxyv2/service/database.dart";
|
||||||
import "package:moxxyv2/service/blocking.dart";
|
import "package:moxxyv2/service/blocking.dart";
|
||||||
|
import "package:moxxyv2/service/avatars.dart";
|
||||||
import "package:moxxyv2/xmpp/connection.dart";
|
import "package:moxxyv2/xmpp/connection.dart";
|
||||||
import "package:moxxyv2/xmpp/settings.dart";
|
import "package:moxxyv2/xmpp/settings.dart";
|
||||||
import "package:moxxyv2/xmpp/jid.dart";
|
import "package:moxxyv2/xmpp/jid.dart";
|
||||||
@ -207,3 +208,47 @@ Future<void> performSetPreferences(BaseEvent c, { dynamic extra }) async {
|
|||||||
final command = c as SetPreferencesCommand;
|
final command = c as SetPreferencesCommand;
|
||||||
GetIt.I.get<PreferencesService>().modifyPreferences((_) => command.preferences);
|
GetIt.I.get<PreferencesService>().modifyPreferences((_) => command.preferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> performAddContact(BaseEvent c, { dynamic extra }) async {
|
||||||
|
final command = c as AddContactCommand;
|
||||||
|
final id = extra as String;
|
||||||
|
|
||||||
|
final jid = command.jid;
|
||||||
|
final roster = GetIt.I.get<RosterService>();
|
||||||
|
if (await roster.isInRoster(jid)) {
|
||||||
|
sendEvent(AddContactResultEvent(conversation: null, added: false), id: id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final db = GetIt.I.get<DatabaseService>();
|
||||||
|
final conversation = await db.getConversationByJid(jid);
|
||||||
|
if (conversation != null) {
|
||||||
|
final c = await db.updateConversation(id: conversation.id, open: true);
|
||||||
|
|
||||||
|
sendEvent(
|
||||||
|
AddContactResultEvent(conversation: c, added: false),
|
||||||
|
id: id
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
final c = await db.addConversationFromData(
|
||||||
|
jid.split("@")[0],
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
jid,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
[],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
sendEvent(
|
||||||
|
AddContactResultEvent(conversation: c, added: true),
|
||||||
|
id: id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
roster.addToRosterWrapper("", jid, jid.split("@")[0]);
|
||||||
|
|
||||||
|
// Try to figure out an avatar
|
||||||
|
await GetIt.I.get<AvatarService>().subscribeJid(jid);
|
||||||
|
GetIt.I.get<AvatarService>().fetchAndUpdateAvatarForJid(jid);
|
||||||
|
}
|
||||||
|
@ -106,6 +106,20 @@ JidFormatError validateJid(String jid) {
|
|||||||
return JidFormatError.none;
|
return JidFormatError.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an error string if [jid] is not a valid JID. Returns null if everything
|
||||||
|
/// appears okay.
|
||||||
|
String? validateJidString(String jid) {
|
||||||
|
switch (validateJid(jid)) {
|
||||||
|
case JidFormatError.empty: return "XMPP-Address cannot be empty";
|
||||||
|
case JidFormatError.noSeparator:
|
||||||
|
case JidFormatError.tooManySeparators: return "XMPP-Address must contain exactly one @";
|
||||||
|
// TODO: Find a better text
|
||||||
|
case JidFormatError.noDomain: return "A domain must follow the @";
|
||||||
|
case JidFormatError.noLocalpart: return "Your username must preceed the @";
|
||||||
|
case JidFormatError.none: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the first element in [items] which is non null.
|
/// Returns the first element in [items] which is non null.
|
||||||
/// Returns null if they all are null.
|
/// Returns null if they all are null.
|
||||||
T? firstNotNull<T>(List<T?> items) {
|
T? firstNotNull<T>(List<T?> items) {
|
||||||
|
66
lib/ui/bloc/addcontact_bloc.dart
Normal file
66
lib/ui/bloc/addcontact_bloc.dart
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import "package:moxxyv2/shared/commands.dart";
|
||||||
|
import "package:moxxyv2/shared/events.dart";
|
||||||
|
import "package:moxxyv2/shared/helpers.dart";
|
||||||
|
import "package:moxxyv2/shared/backgroundsender.dart";
|
||||||
|
import "package:moxxyv2/ui/bloc/conversations_bloc.dart";
|
||||||
|
import "package:moxxyv2/ui/bloc/conversation_bloc.dart";
|
||||||
|
|
||||||
|
import "package:get_it/get_it.dart";
|
||||||
|
import "package:bloc/bloc.dart";
|
||||||
|
import "package:freezed_annotation/freezed_annotation.dart";
|
||||||
|
|
||||||
|
part "addcontact_state.dart";
|
||||||
|
part "addcontact_event.dart";
|
||||||
|
part "addcontact_bloc.freezed.dart";
|
||||||
|
|
||||||
|
class AddContactBloc extends Bloc<AddContactEvent, AddContactState> {
|
||||||
|
AddContactBloc() : super(AddContactState()) {
|
||||||
|
on<AddedContactEvent>(_onContactAdded);
|
||||||
|
on<JidChangedEvent>(_onJidChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onContactAdded(AddedContactEvent event, Emitter<AddContactState> emit) async {
|
||||||
|
// TODO: Remove once we can disable the custom buttom
|
||||||
|
if (state.working) return;
|
||||||
|
|
||||||
|
final validation = validateJidString(state.jid);
|
||||||
|
if (validation != null) {
|
||||||
|
emit(state.copyWith(jidError: validation));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
working: true,
|
||||||
|
jidError: null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await GetIt.I.get<BackgroundServiceDataSender>().sendData(
|
||||||
|
AddContactCommand(
|
||||||
|
jid: state.jid
|
||||||
|
)
|
||||||
|
) as AddContactResultEvent;
|
||||||
|
|
||||||
|
if (result.conversation != null) {
|
||||||
|
if (result.added) {
|
||||||
|
GetIt.I.get<ConversationsBloc>().add(ConversationsAddedEvent(result.conversation!));
|
||||||
|
} else {
|
||||||
|
GetIt.I.get<ConversationsBloc>().add(ConversationsUpdatedEvent(result.conversation!));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetIt.I.get<ConversationBloc>().add(
|
||||||
|
RequestedConversationEvent(
|
||||||
|
result.conversation!.jid,
|
||||||
|
result.conversation!.title,
|
||||||
|
result.conversation!.avatarUrl,
|
||||||
|
removeUntilConversations: true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onJidChanged(JidChangedEvent event, Emitter<AddContactState> emit) async {
|
||||||
|
emit(state.copyWith(jid: event.jid));
|
||||||
|
}
|
||||||
|
}
|
13
lib/ui/bloc/addcontact_event.dart
Normal file
13
lib/ui/bloc/addcontact_event.dart
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
part of "addcontact_bloc.dart";
|
||||||
|
|
||||||
|
abstract class AddContactEvent {}
|
||||||
|
|
||||||
|
/// Triggered when a new contact has been added by the UI
|
||||||
|
class AddedContactEvent extends AddContactEvent {}
|
||||||
|
|
||||||
|
/// Triggered by the UI when the JID input field is changed
|
||||||
|
class JidChangedEvent extends AddContactEvent {
|
||||||
|
final String jid;
|
||||||
|
|
||||||
|
JidChangedEvent(this.jid);
|
||||||
|
}
|
10
lib/ui/bloc/addcontact_state.dart
Normal file
10
lib/ui/bloc/addcontact_state.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
part of "addcontact_bloc.dart";
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class AddContactState with _$AddContactState {
|
||||||
|
factory AddContactState({
|
||||||
|
@Default("") String jid,
|
||||||
|
@Default(null) String? jidError,
|
||||||
|
@Default(false) bool working
|
||||||
|
}) = _AddContactState;
|
||||||
|
}
|
@ -11,6 +11,7 @@ import "package:moxxyv2/ui/bloc/conversations_bloc.dart";
|
|||||||
import "package:get_it/get_it.dart";
|
import "package:get_it/get_it.dart";
|
||||||
import "package:bloc/bloc.dart";
|
import "package:bloc/bloc.dart";
|
||||||
import "package:freezed_annotation/freezed_annotation.dart";
|
import "package:freezed_annotation/freezed_annotation.dart";
|
||||||
|
import "package:flutter/widgets.dart";
|
||||||
|
|
||||||
part "conversation_state.dart";
|
part "conversation_state.dart";
|
||||||
part "conversation_event.dart";
|
part "conversation_event.dart";
|
||||||
@ -47,11 +48,18 @@ class ConversationBloc extends Bloc<ConversationEvent, ConversationState> {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
GetIt.I.get<NavigationBloc>().add(
|
final navEvent = event.removeUntilConversations ? (
|
||||||
|
PushedNamedAndRemoveUntilEvent(
|
||||||
|
const NavigationDestination(conversationRoute),
|
||||||
|
ModalRoute.withName(conversationsRoute)
|
||||||
|
)
|
||||||
|
) : (
|
||||||
PushedNamedEvent(
|
PushedNamedEvent(
|
||||||
const NavigationDestination(conversationRoute)
|
const NavigationDestination(conversationRoute)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
GetIt.I.get<NavigationBloc>().add(navEvent);
|
||||||
|
|
||||||
final result = await GetIt.I.get<BackgroundServiceDataSender>().sendData(
|
final result = await GetIt.I.get<BackgroundServiceDataSender>().sendData(
|
||||||
GetMessagesForJidCommand(
|
GetMessagesForJidCommand(
|
||||||
|
@ -28,8 +28,16 @@ class RequestedConversationEvent extends ConversationEvent {
|
|||||||
final String jid;
|
final String jid;
|
||||||
final String title;
|
final String title;
|
||||||
final String avatarUrl;
|
final String avatarUrl;
|
||||||
|
final bool removeUntilConversations;
|
||||||
|
|
||||||
RequestedConversationEvent(this.jid, this.title, this.avatarUrl);
|
RequestedConversationEvent(
|
||||||
|
this.jid,
|
||||||
|
this.title,
|
||||||
|
this.avatarUrl,
|
||||||
|
{
|
||||||
|
this.removeUntilConversations = false
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Triggered by the UI when a message is quoted
|
/// Triggered by the UI when a message is quoted
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import "package:moxxyv2/shared/events.dart";
|
|
||||||
import "package:moxxyv2/shared/backgroundsender.dart";
|
|
||||||
import "package:moxxyv2/shared/models/conversation.dart";
|
import "package:moxxyv2/shared/models/conversation.dart";
|
||||||
|
|
||||||
import "package:bloc/bloc.dart";
|
import "package:bloc/bloc.dart";
|
||||||
|
@ -14,20 +14,6 @@ part "login_state.dart";
|
|||||||
part "login_event.dart";
|
part "login_event.dart";
|
||||||
part "login_bloc.freezed.dart";
|
part "login_bloc.freezed.dart";
|
||||||
|
|
||||||
/// Returns an error string if [jid] is not a valid JID. Returns null if everything
|
|
||||||
/// appears okay.
|
|
||||||
String? _validateJid(String jid) {
|
|
||||||
switch (validateJid(jid)) {
|
|
||||||
case JidFormatError.empty: return "XMPP-Address cannot be empty";
|
|
||||||
case JidFormatError.noSeparator:
|
|
||||||
case JidFormatError.tooManySeparators: return "XMPP-Address must contain exactly one @";
|
|
||||||
// TODO: Find a better text
|
|
||||||
case JidFormatError.noDomain: return "A domain must follow the @";
|
|
||||||
case JidFormatError.noLocalpart: return "Your username must preceed the @";
|
|
||||||
case JidFormatError.none: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
||||||
LoginBloc() : super(LoginState()) {
|
LoginBloc() : super(LoginState()) {
|
||||||
on<LoginJidChangedEvent>(_onJidChanged);
|
on<LoginJidChangedEvent>(_onJidChanged);
|
||||||
@ -49,7 +35,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onSubmitted(LoginSubmittedEvent event, Emitter<LoginState> emit) async {
|
Future<void> _onSubmitted(LoginSubmittedEvent event, Emitter<LoginState> emit) async {
|
||||||
final jidValidity = _validateJid(state.jid);
|
final jidValidity = validateJidString(state.jid);
|
||||||
if (jidValidity != null) {
|
if (jidValidity != null) {
|
||||||
return emit(
|
return emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
@ -4,14 +4,12 @@ import "package:moxxyv2/shared/helpers.dart";
|
|||||||
import "package:moxxyv2/shared/models/roster.dart";
|
import "package:moxxyv2/shared/models/roster.dart";
|
||||||
import "package:moxxyv2/shared/models/conversation.dart";
|
import "package:moxxyv2/shared/models/conversation.dart";
|
||||||
import "package:moxxyv2/shared/backgroundsender.dart";
|
import "package:moxxyv2/shared/backgroundsender.dart";
|
||||||
import "package:moxxyv2/ui/constants.dart";
|
|
||||||
import "package:moxxyv2/ui/bloc/conversations_bloc.dart";
|
import "package:moxxyv2/ui/bloc/conversations_bloc.dart";
|
||||||
import "package:moxxyv2/ui/bloc/navigation_bloc.dart";
|
import "package:moxxyv2/ui/bloc/conversation_bloc.dart";
|
||||||
|
|
||||||
import "package:bloc/bloc.dart";
|
import "package:bloc/bloc.dart";
|
||||||
import "package:freezed_annotation/freezed_annotation.dart";
|
import "package:freezed_annotation/freezed_annotation.dart";
|
||||||
import "package:get_it/get_it.dart";
|
import "package:get_it/get_it.dart";
|
||||||
import "package:flutter/widgets.dart";
|
|
||||||
|
|
||||||
part "newconversation_state.dart";
|
part "newconversation_state.dart";
|
||||||
part "newconversation_event.dart";
|
part "newconversation_event.dart";
|
||||||
@ -38,14 +36,12 @@ class NewConversationBloc extends Bloc<NewConversationEvent, NewConversationStat
|
|||||||
|
|
||||||
// Guard against an unneccessary roundtrip
|
// Guard against an unneccessary roundtrip
|
||||||
if (listContains(conversations.state.conversations, (Conversation c) => c.jid == event.jid)) {
|
if (listContains(conversations.state.conversations, (Conversation c) => c.jid == event.jid)) {
|
||||||
// TODO: Use the [ConversationBloc]
|
GetIt.I.get<ConversationBloc>().add(
|
||||||
GetIt.I.get<NavigationBloc>().add(
|
RequestedConversationEvent(
|
||||||
PushedNamedAndRemoveUntilEvent(
|
event.jid,
|
||||||
NavigationDestination(
|
event.title,
|
||||||
conversationRoute,
|
event.avatarUrl,
|
||||||
//arguments: ConversationPageArguments(event.jid)
|
removeUntilConversations: true
|
||||||
),
|
|
||||||
ModalRoute.withName(conversationsRoute)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -68,20 +64,17 @@ class NewConversationBloc extends Bloc<NewConversationEvent, NewConversationStat
|
|||||||
conversations.add(ConversationsAddedEvent(result.conversation));
|
conversations.add(ConversationsAddedEvent(result.conversation));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use the [ConversationBloc]
|
GetIt.I.get<ConversationBloc>().add(
|
||||||
GetIt.I.get<NavigationBloc>().add(
|
RequestedConversationEvent(
|
||||||
PushedNamedAndRemoveUntilEvent(
|
event.jid,
|
||||||
NavigationDestination(
|
event.title,
|
||||||
conversationRoute,
|
event.avatarUrl,
|
||||||
//arguments: ConversationPageArguments(event.jid)
|
removeUntilConversations: true
|
||||||
),
|
|
||||||
ModalRoute.withName(conversationsRoute)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onRosterItemRemoved(NewConversationRosterItemRemovedEvent event, Emitter<NewConversationState> emit) async {
|
Future<void> _onRosterItemRemoved(NewConversationRosterItemRemovedEvent event, Emitter<NewConversationState> emit) async {
|
||||||
// TODO
|
|
||||||
return emit(
|
return emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
roster: state.roster.where(
|
roster: state.roster.where(
|
||||||
|
@ -1,52 +1,25 @@
|
|||||||
/*
|
import "package:moxxyv2/ui/constants.dart";
|
||||||
|
import "package:moxxyv2/ui/helpers.dart";
|
||||||
import "package:moxxyv2/ui/widgets/topbar.dart";
|
import "package:moxxyv2/ui/widgets/topbar.dart";
|
||||||
import "package:moxxyv2/ui/widgets/textfield.dart";
|
import "package:moxxyv2/ui/widgets/textfield.dart";
|
||||||
import "package:moxxyv2/ui/widgets/button.dart";
|
import "package:moxxyv2/ui/widgets/button.dart";
|
||||||
import "package:moxxyv2/ui/constants.dart";
|
import "package:moxxyv2/ui/bloc/addcontact_bloc.dart";
|
||||||
import "package:moxxyv2/ui/helpers.dart";
|
|
||||||
import "package:moxxyv2/ui/redux/state.dart";
|
|
||||||
import "package:moxxyv2/ui/redux/addcontact/actions.dart";
|
|
||||||
|
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_redux/flutter_redux.dart";
|
import "package:flutter_bloc/flutter_bloc.dart";
|
||||||
|
|
||||||
class _AddContactPageViewModel {
|
|
||||||
final bool doingWork;
|
|
||||||
final String? errorText;
|
|
||||||
final void Function(String jid) addContact;
|
|
||||||
final void Function() resetErrors;
|
|
||||||
|
|
||||||
const _AddContactPageViewModel({ required this.addContact, required this.doingWork, required this.resetErrors, this.errorText });
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Reset the errorText using WillPopScope
|
|
||||||
class AddContactPage extends StatelessWidget {
|
class AddContactPage extends StatelessWidget {
|
||||||
final TextEditingController _controller;
|
const AddContactPage({ Key? key }) : super(key: key);
|
||||||
|
|
||||||
AddContactPage({ Key? key }) : _controller = TextEditingController(), super(key: key);
|
|
||||||
|
|
||||||
void _addToRoster(BuildContext context, _AddContactPageViewModel viewModel) {
|
|
||||||
if (_controller.text.isEmpty) return;
|
|
||||||
|
|
||||||
viewModel.resetErrors();
|
|
||||||
viewModel.addContact(_controller.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StoreConnector<MoxxyState, _AddContactPageViewModel>(
|
return BlocBuilder<AddContactBloc, AddContactState>(
|
||||||
converter: (store) => _AddContactPageViewModel(
|
builder: (context, state) => Scaffold(
|
||||||
doingWork: store.state.globalState.doingWork,
|
|
||||||
errorText: store.state.addContactErrorText,
|
|
||||||
addContact: (jid) => store.dispatch(AddContactAction(jid: jid)),
|
|
||||||
resetErrors: () => store.dispatch(AddContactSetErrorLogin())
|
|
||||||
),
|
|
||||||
builder: (context, viewModel) => Scaffold(
|
|
||||||
appBar: BorderlessTopbar.simple(title: "Add new contact"),
|
appBar: BorderlessTopbar.simple(title: "Add new contact"),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: viewModel.doingWork,
|
visible: state.working,
|
||||||
child: const LinearProgressIndicator(value: null)
|
child: const LinearProgressIndicator(value: null)
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -54,11 +27,14 @@ class AddContactPage extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: paddingVeryLarge).add(const EdgeInsets.only(top: 8.0)),
|
padding: const EdgeInsets.symmetric(horizontal: paddingVeryLarge).add(const EdgeInsets.only(top: 8.0)),
|
||||||
child: CustomTextField(
|
child: CustomTextField(
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
controller: _controller,
|
|
||||||
labelText: "XMPP-Address",
|
labelText: "XMPP-Address",
|
||||||
|
onChanged: (value) => context.read<AddContactBloc>().add(
|
||||||
|
JidChangedEvent(value)
|
||||||
|
),
|
||||||
|
enabled: !state.working,
|
||||||
cornerRadius: textfieldRadiusRegular,
|
cornerRadius: textfieldRadiusRegular,
|
||||||
contentPadding: const EdgeInsets.only(top: 4.0, bottom: 4.0, left: 8.0, right: 8.0),
|
contentPadding: const EdgeInsets.only(top: 4.0, bottom: 4.0, left: 8.0, right: 8.0),
|
||||||
errorText: viewModel.errorText,
|
errorText: state.jidError,
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: const Icon(Icons.qr_code),
|
icon: const Icon(Icons.qr_code),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -84,7 +60,7 @@ class AddContactPage extends StatelessWidget {
|
|||||||
color: Colors.purple,
|
color: Colors.purple,
|
||||||
child: const Text("Add to contacts"),
|
child: const Text("Add to contacts"),
|
||||||
cornerRadius: 32.0,
|
cornerRadius: 32.0,
|
||||||
onTap: () => _addToRoster(context, viewModel)
|
onTap: () => context.read<AddContactBloc>().add(AddedContactEvent())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -96,4 +72,3 @@ class AddContactPage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user