Put it all together - Private chat - (Unreal Engine module)
Connect the UI with private chat
In this tutorial, you will connect your implementation in PrivateChatSubsystem_Starter
to the private chat widget.
-
Open the
PrivateChatWidget_Starter
CPP file and start with connecting the UI to send private chat messages. Replace theSendPrivateChatMessage()
code with the following code:void UPrivateChatWidget_Starter::SendPrivateChatMessage(const FText& MessageText)
{
if (!PrivateChatSubsystem)
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot send private chat message. Private Chat subsystem is not valid."));
return;
}
if (!ensure(GetOwningPlayer()))
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot send private chat message. PlayerController is not valid."));
return;
}
const ULocalPlayer* LocalPlayer = GetOwningPlayer()->GetLocalPlayer();
if (!ensure(LocalPlayer))
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot send private chat message. LocalPlayer is not valid."));
return;
}
// Send private private chat message.
PrivateChatSubsystem->SendPrivateChatMessage(
LocalPlayer->GetPreferredUniqueNetId().GetUniqueNetId(),
PrivateChatRecipientUserId,
MessageText.ToString());
} -
Replace the
GetLastPrivateChatMessages()
function with the code below to get and display the chat message history:void UPrivateChatWidget_Starter::GetLastPrivateChatMessages() const
{
if (!PrivateChatSubsystem)
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot get last private chat messages. Private Chat subsystem is not valid."));
return;
}
if (!ensure(GetOwningPlayer()))
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot get last private chat messages. PlayerController is not valid."));
return;
}
const ULocalPlayer* LocalPlayer = GetOwningPlayer()->GetLocalPlayer();
if (!ensure(LocalPlayer))
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot get last private chat messages. LocalPlayer is not valid."));
return;
}
// Get chat room id.
const FString ChatRoomId = PrivateChatSubsystem->GetPrivateChatRoomId(
LocalPlayer->GetPreferredUniqueNetId().GetUniqueNetId(),
PrivateChatRecipientUserId);
// Abort if room id was not found.
if (ChatRoomId.IsEmpty())
{
W_Chat->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Empty, NO_CHAT_MESSAGE);
return;
}
// Get last private chat messages.
TArray<TSharedRef<FChatMessage>> OutMessages;
if (PrivateChatSubsystem->GetLastPrivateChatMessages(
LocalPlayer->GetPreferredUniqueNetId().GetUniqueNetId(),
ChatRoomId,
W_Chat->GetMaxChatHistory(),
OutMessages))
{
// Abort if last messages is empty.
if (OutMessages.IsEmpty())
{
W_Chat->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Empty, NO_CHAT_MESSAGE);
return;
}
// Display last chat messages.
Algo::Reverse(OutMessages);
for (const TSharedRef<FChatMessage>& Message : OutMessages)
{
AppendChatMessage(Message.Get());
}
}
// Show error message if failed.
else
{
W_Chat->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Error, FAILED_TO_LOAD_CHAT_MESSAGE);
}
} -
Next, replace the
AppendChatMessage()
function with the code below to append the chat message to be displayed with additional safeguards:void UPrivateChatWidget_Starter::AppendChatMessage(const FChatMessage& Message) const
{
if (!PrivateChatSubsystem)
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot append a private chat message to display. Private Chat subsystem is not valid."));
return;
}
if (!ensure(GetOwningPlayer()))
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot append a private chat message to display. PlayerController is not valid."));
return;
}
const ULocalPlayer* LocalPlayer = GetOwningPlayer()->GetLocalPlayer();
if (!ensure(LocalPlayer))
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot append a private chat message to display. LocalPlayer is not valid."));
return;
}
const FUniqueNetIdAccelByteUserRef SenderABId = StaticCastSharedRef<const FUniqueNetIdAccelByteUser>(Message.GetUserId());
if (!SenderABId.Get().IsValid())
{
UE_LOG_PRIVATECHAT(Warning, TEXT("Cannot append a private chat message to display. Sender User Id is invalid."));
return;
}
// Construct chat message.
UChatData* ChatData = NewObject<UChatData>();
ChatData->Message = Message.GetBody();
ChatData->bIsSenderLocal = PrivateChatSubsystem->IsMessageFromLocalUser(LocalPlayer->GetPreferredUniqueNetId().GetUniqueNetId(), Message);
// If the sender doesn't have display name, then use the default display name.
ChatData->Sender = Message.GetNickname();
if (ChatData->Sender.IsEmpty() || SenderABId.Get().GetAccelByteId().Equals(ChatData->Sender))
{
ChatData->Sender = UTutorialModuleOnlineUtility::GetUserDefaultDisplayName(Message.GetUserId().Get());
}
// Display chat message.
W_Chat->AppendChatMessage(ChatData);
} -
Now, complete the code by binding the chat events with the widget. To do this, replace the pre-defined
NativeOnActivated()
function with the following code:void UPrivateChatWidget_Starter::NativeOnActivated()
{
Super::NativeOnActivated();
// Reset chat widget
W_Chat->ClearChatMessages();
W_Chat->ClearInput();
// Setup widget
W_Chat->OnSubmitDelegates.AddUObject(this, &ThisClass::SendPrivateChatMessage);
Btn_Back->OnClicked().AddUObject(this, &ThisClass::DeactivateWidget);
if (PrivateChatSubsystem)
{
PrivateChatSubsystem->GetOnSendPrivateChatCompleteDelegates()->AddUObject(this, &ThisClass::OnSendPrivateChatComplete);
PrivateChatSubsystem->GetOnPrivateChatMessageReceivedDelegates()->AddUObject(this, &ThisClass::OnPrivateChatMessageReceived);
}
// Display default state.
GetLastPrivateChatMessages();
} -
Finally, unbind those events when the widget is closed. To this, replace the pre-defined
NativeOnDeactivated()
function with the following code:void UPrivateChatWidget_Starter::NativeOnDeactivated()
{
PrivateChatRecipientUserId = nullptr;
// Cleanup widget
W_Chat->OnSubmitDelegates.RemoveAll(this);
Btn_Back->OnClicked().RemoveAll(this);
// Unbind chat events.
if (PrivateChatSubsystem)
{
PrivateChatSubsystem->GetOnSendPrivateChatCompleteDelegates()->RemoveAll(this);
PrivateChatSubsystem->GetOnPrivateChatMessageReceivedDelegates()->RemoveAll(this);
}
Super::NativeOnDeactivated();
}
Resources
- The files used in this tutorial section are available in the Byte Wars GitHub repository.