Skip to content

Commit

Permalink
TW-1356: fix the avatar not updated when app terminated
Browse files Browse the repository at this point in the history
  • Loading branch information
sherlockvn authored and hoangdat committed May 31, 2024
1 parent e1bdf11 commit 9759166
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 154 deletions.
18 changes: 0 additions & 18 deletions lib/pages/chat_list/chat_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,6 @@ class ChatListController extends State<ChatList>
final ValueNotifier<SelectMode> selectModeNotifier =
ValueNotifier(SelectMode.normal);

final ValueNotifier<Profile> currentProfileNotifier = ValueNotifier(
Profile(userId: ''),
);

final ValueNotifier<List<ConversationSelectionPresentation>>
conversationSelectionNotifier = ValueNotifier([]);

Expand Down Expand Up @@ -748,17 +744,6 @@ class ChatListController extends State<ChatList>
}
}

void _getCurrentProfile(Client client) async {
final profile = await client.getProfileFromUserId(
client.userID!,
getFromRooms: false,
);
Logs().d(
'ChatList::_getCurrentProfile() - currentProfile: $profile',
);
currentProfileNotifier.value = profile;
}

void onClickAvatar() {
context.push('/rooms/profile');
}
Expand All @@ -783,7 +768,6 @@ class ChatListController extends State<ChatList>
);
if (newActiveClient != null && newActiveClient.userID != null) {
setState(() {
_getCurrentProfile(newActiveClient);
_clientStream.add(newActiveClient);
_handleRecovery();
});
Expand All @@ -800,14 +784,12 @@ class ChatListController extends State<ChatList>
scrollController.addListener(_onScroll);
_waitForFirstSync();
_hackyWebRTCFixForWeb();
_getCurrentProfile(activeClient);
// TODO: 28Dec2023 Disable callkeep for util we support audio/video calls
// CallKeepManager().initialize();
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (mounted) {
Matrix.of(context).backgroundPush?.setupPush();
await matrixState.retrievePersistedActiveClient();
_getCurrentProfile(activeClient);
}
});
_checkTorBrowser();
Expand Down
6 changes: 5 additions & 1 deletion lib/pages/chat_list/chat_list_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ class ChatListHeader extends StatelessWidget {
return Column(
children: [
TwakeHeader(
controller: controller,
onClearSelection: controller.onClickClearSelection,
client: controller.activeClient,
selectModeNotifier: controller.selectModeNotifier,
conversationSelectionNotifier:
controller.conversationSelectionNotifier,
onClickAvatar: controller.onClickAvatar,
),
Container(
height: ChatListHeaderStyle.searchBarContainerHeight,
Expand Down
55 changes: 9 additions & 46 deletions lib/pages/multiple_accounts/multiple_accounts_picker.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import 'package:collection/collection.dart';
import 'package:fluffychat/pages/twake_welcome/twake_welcome.dart';
import 'package:fluffychat/presentation/extensions/multiple_accounts/client_profile_extension.dart';
import 'package:fluffychat/presentation/multiple_account/client_profile_presentation.dart';
import 'package:fluffychat/presentation/multiple_account/twake_chat_presentation_account.dart';
import 'package:fluffychat/widgets/layouts/agruments/switch_active_account_body_args.dart';
import 'package:fluffychat/widgets/matrix.dart';
Expand All @@ -17,65 +15,30 @@ typedef OnGoToAccountSettings = void Function(TwakePresentationAccount account);

class MultipleAccountsPickerController {
final BuildContext context;
final List<TwakeChatPresentationAccount> multipleAccounts;

MultipleAccountsPickerController({
required this.context,
required this.multipleAccounts,
});

MatrixState get _matrixState => Matrix.of(context);

Future<List<ClientProfilePresentation?>> _getClientProfiles() async {
final profiles = await Future.wait(
_matrixState.widget.clients.map((client) async {
final profileBundle = await client.fetchOwnProfile();
Logs().d(
'MultipleAccountsPicker::getProfileBundles() - ClientName - ${client.clientName}',
);
Logs().d(
'MultipleAccountsPicker::getProfileBundles() - UserId - ${client.userID}',
);
return ClientProfilePresentation(
profile: profileBundle,
client: client,
);
}),
);

return profiles.toList();
}

Future<List<TwakeChatPresentationAccount>> _getMultipleAccounts(
Client currentActiveClient,
) async {
final profileBundles = await _getClientProfiles();
return profileBundles
.where((clientProfile) => clientProfile != null)
.map(
(clientProfile) => clientProfile!.toTwakeChatPresentationAccount(
currentActiveClient,
),
)
.toList();
}

void showMultipleAccountsPicker(
Client currentActiveClient, {
required VoidCallback onGoToAccountSettings,
}) async {
final multipleAccount = await _getMultipleAccounts(
currentActiveClient,
);
multipleAccount.sort((pre, next) {
multipleAccounts.sort((pre, next) {
return pre.accountActiveStatus.index
.compareTo(next.accountActiveStatus.index);
});
MultipleAccountPicker.showMultipleAccountPicker(
accounts: multipleAccount,
accounts: multipleAccounts,
context: context,
onAddAnotherAccount: _onAddAnotherAccount,
onGoToAccountSettings: onGoToAccountSettings,
onSetAccountAsActive: (account) => _onSetAccountAsActive.call(
multipleAccounts: multipleAccount,
onSetAccountAsActive: (account) => _onSetAccountAsActive(
multipleAccounts: multipleAccounts,
account: account,
),
titleAddAnotherAccount: L10n.of(context)!.addAnotherAccount,
Expand Down Expand Up @@ -113,19 +76,19 @@ class MultipleAccountsPickerController {
)
?.clientAccount;
if (client == null || client == _matrixState.client) return;
_setActiveClient(client);
await _setActiveClient(client);
}

void _onAddAnotherAccount() {
context.go(
context.push(
'/rooms/addaccount',
extra: const TwakeWelcomeArg(
twakeIdType: TwakeWelcomeType.otherAccounts,
),
);
}

void _setActiveClient(Client newClient) async {
Future<void> _setActiveClient(Client newClient) async {
final result = await _matrixState.setActiveClient(newClient);
if (result.isSuccess) {
context.go(
Expand Down
85 changes: 75 additions & 10 deletions lib/pages/settings_dashboard/settings_profile/settings_profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ import 'package:fluffychat/event/twake_inapp_event_types.dart';
import 'package:fluffychat/pages/multiple_accounts/multiple_accounts_picker.dart';
import 'package:fluffychat/pages/settings_dashboard/settings_profile/settings_profile_context_menu_actions.dart';
import 'package:fluffychat/pages/settings_dashboard/settings_profile/settings_profile_state/get_avatar_ui_state.dart';
import 'package:fluffychat/pages/settings_dashboard/settings_profile/settings_profile_state/get_clients_ui_state.dart';
import 'package:fluffychat/pages/settings_dashboard/settings_profile/settings_profile_state/get_profile_ui_state.dart';
import 'package:fluffychat/pages/settings_dashboard/settings_profile/settings_profile_view.dart';
import 'package:fluffychat/presentation/extensions/multiple_accounts/client_profile_extension.dart';
import 'package:fluffychat/presentation/multiple_account/client_profile_presentation.dart';
import 'package:fluffychat/presentation/enum/settings/settings_profile_enum.dart';
import 'package:fluffychat/presentation/extensions/client_extension.dart';
import 'package:fluffychat/presentation/mixins/common_media_picker_mixin.dart';
import 'package:fluffychat/presentation/mixins/single_image_picker_mixin.dart';
import 'package:fluffychat/presentation/multiple_account/twake_chat_presentation_account.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/dialog/twake_dialog.dart';
import 'package:fluffychat/utils/extension/value_notifier_extension.dart';
Expand Down Expand Up @@ -64,15 +68,18 @@ class SettingsProfileController extends State<SettingsProfile>
AssetEntity? assetEntity;
FilePickerResult? filePickerResult;

ValueNotifier<bool> haveMultipleAccountsNotifier = ValueNotifier(false);

final TwakeEventDispatcher twakeEventDispatcher =
getIt.get<TwakeEventDispatcher>();

final ValueNotifier<bool> isEditedProfileNotifier = ValueNotifier(false);

final ValueNotifier<Either<Failure, Success>> settingsProfileUIState =
ValueNotifier<Either<Failure, Success>>(Right(GetAvatarInitialUIState()));

final settingsMultiAccountsUIState = ValueNotifier<Either<Failure, Success>>(
Right(GetClientsInitialUIState()),
);

Client get client => Matrix.of(context).client;

bool get _hasEditedDisplayName =>
Expand Down Expand Up @@ -543,14 +550,71 @@ class SettingsProfileController extends State<SettingsProfile>
}
}

Future<int> get accountsCount async
// FIXME: Change to false after merging TW-1262
=>
(await ClientManager.getClients(initialize: true)).length;
Future<void> _getMultipleAccounts(
Client currentActiveClient,
) async {
try {
settingsMultiAccountsUIState.value = Right(GetClientsLoadingUIState());
final profileBundles = await _getClientProfiles();
final multipleAccounts = profileBundles
.where((clientProfile) => clientProfile != null)
.map(
(clientProfile) => clientProfile!.toTwakeChatPresentationAccount(
currentActiveClient,
),
)
.toList();
settingsMultiAccountsUIState.value = Right(
GetClientsSuccessUIState(
multipleAccounts: multipleAccounts,
),
);
} catch (e) {
Logs().e(
'SettingsProfileController::_getMultipleAccounts() - Error: $e',
);
settingsMultiAccountsUIState.value = Left<Failure, Success>(
GetClientsFailureUIState(
exception: e,
),
);
}
}

Future<List<ClientProfilePresentation?>> _getClientProfiles() async {
try {
final profiles = await Future.wait(
(await ClientManager.getClients()).map((client) async {
final profileBundle = await client.fetchOwnProfile();
Logs().d(
'SettingsProfileController::getProfileBundles() - ClientName - ${client.clientName}',
);
Logs().d(
'SettingsProfileController::getProfileBundles() - UserId - ${client.userID}',
);
return ClientProfilePresentation(
profile: profileBundle,
client: client,
);
}),
);

void onBottomButtonTap() {
MultipleAccountsPickerController(context: context)
.showMultipleAccountsPicker(
return profiles.toList();
} catch (e) {
Logs().e(
'SettingsProfileController::getProfileBundles() - Error: $e',
);
rethrow;
}
}

void onBottomButtonTap({
required List<TwakeChatPresentationAccount> multipleAccounts,
}) {
MultipleAccountsPickerController(
context: context,
multipleAccounts: multipleAccounts,
).showMultipleAccountsPicker(
client,
onGoToAccountSettings: () {
context.go('/rooms/profile');
Expand Down Expand Up @@ -604,7 +668,7 @@ class SettingsProfileController extends State<SettingsProfile>
_handleViewState();
_getCurrentProfile(client);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
haveMultipleAccountsNotifier.value = await accountsCount > 1;
_getMultipleAccounts(client);
});
super.initState();
}
Expand All @@ -616,6 +680,7 @@ class SettingsProfileController extends State<SettingsProfile>
displayNameFocusNode.dispose();
settingsProfileUIState.dispose();
isEditedProfileNotifier.dispose();
settingsMultiAccountsUIState.dispose();
super.dispose();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:fluffychat/app_state/failure.dart';
import 'package:fluffychat/app_state/success.dart';
import 'package:fluffychat/presentation/multiple_account/twake_chat_presentation_account.dart';

class GetClientsInitialUIState extends Success {
@override
List<Object?> get props => [];
}

class GetClientsLoadingUIState extends Success {
@override
List<Object?> get props => [];
}

class GetClientsSuccessUIState extends Success {
final List<TwakeChatPresentationAccount> multipleAccounts;

const GetClientsSuccessUIState({
required this.multipleAccounts,
});

bool get haveMultipleAccounts => multipleAccounts.length > 1;

@override
List<Object?> get props => [multipleAccounts];
}

class GetClientsFailureUIState extends Failure {
final dynamic exception;

const GetClientsFailureUIState({this.exception});

@override
List<Object?> get props => [exception];
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ class SettingsProfileView extends StatelessWidget {
client: controller.client,
settingsProfileUIState: controller.settingsProfileUIState,
onTapAvatar: controller.onTapAvatarInMobile,
onBottomButtonTap: controller.onBottomButtonTap,
haveMultipleAccountsNotifier:
controller.haveMultipleAccountsNotifier,
onTapMultipleAccountsButton: (multipleAccounts) =>
controller.onBottomButtonTap(
multipleAccounts: multipleAccounts,
),
settingsMultiAccountsUIState:
controller.settingsMultiAccountsUIState,
menuChildren: controller.listContextMenuBuilder(context),
menuController: controller.menuController,
settingsProfileOptions: ListView.separated(
Expand Down
Loading

0 comments on commit 9759166

Please sign in to comment.