Merge branch 'develop' into feature/Sound

# Conflicts:
#	Assets/PerfectWorld/Scene/LoginScene.unity
#	Assets/Prefabs/UI/Music.prefab
#	Assets/Scripts/CECHostPlayer.cs
This commit is contained in:
vuong dinh hoang
2026-04-26 14:09:23 +07:00
26 changed files with 1494 additions and 32 deletions
+28 -3
View File
@@ -3,14 +3,11 @@ using UnityEngine;
using TMPro;
using CSNetwork.GPDataType;
using System.Collections.Generic;
using BrewMonster;
using BrewMonster.Network;
using BrewMonster.Scripts.Chat;
using BrewMonster.Scripts.Chat.EmotionData;
using BrewMonster.Scripts.Managers;
using BrewMonster.UI;
using CSNetwork;
using PerfectWorld.Scripts.Managers;
namespace BrewMonster.Scripts.ChatUI
{
@@ -31,6 +28,9 @@ namespace BrewMonster.Scripts.ChatUI
public TMP_InputField inputField;
public ChatSystemSO chatSystem;
[Header("Typing Preview")]
[SerializeField] private TypingPreviewController typingPreview = new();
[Header("Emoji")]
[Tooltip("SO ánh xạ emotion → TMP sprite tag. Gán EmotionLibrarySpriteMap đã build từ Emotion Atlas Converter.")]
[SerializeField] EmotionLibrarySpriteMap _spriteMap;
@@ -110,6 +110,8 @@ namespace BrewMonster.Scripts.ChatUI
private float m_dwTickFarCry = 0;
private float m_dwTickFarCry2 = 0;
private Vector2 _inputBarBaseAnchoredPos;
private bool _cachedAnchors;
private void Awake()
{
@@ -172,6 +174,14 @@ namespace BrewMonster.Scripts.ChatUI
}
UpdateChatDropdownInteractable();
UpdateTypingPreviewFromInput();
}
private void Update()
{
// Keyboard open/close does not always trigger input value changed,
// so refresh preview gate every frame.
UpdateTypingPreviewFromInput();
}
// =====================================================
@@ -812,6 +822,8 @@ namespace BrewMonster.Scripts.ChatUI
{
inputField.text = "";
}
UpdateTypingPreviewFromInput();
}
private int GetEmotionSetForCurrentChannel()
@@ -877,6 +889,7 @@ namespace BrewMonster.Scripts.ChatUI
if (_syncingWireToDisplay)
{
_lastInputFieldText = newText;
UpdateTypingPreviewFromInput();
return;
}
@@ -884,6 +897,7 @@ namespace BrewMonster.Scripts.ChatUI
{
_lastInputFieldText = newText;
SyncChatWireBodyFromInput();
UpdateTypingPreviewFromInput();
return;
}
@@ -905,11 +919,13 @@ namespace BrewMonster.Scripts.ChatUI
inputField.ForceLabelUpdate();
_lastInputFieldText = fixedText;
SyncChatWireBodyFromInput();
UpdateTypingPreviewFromInput();
return;
}
_lastInputFieldText = newText;
SyncChatWireBodyFromInput();
UpdateTypingPreviewFromInput();
}
/// <summary>
@@ -981,6 +997,15 @@ namespace BrewMonster.Scripts.ChatUI
inputField.ActivateInputField();
}
void UpdateTypingPreviewFromInput()
{
if (inputField == null)
return;
string body = ExtractMessageBodyFromVisual(inputField.text ?? "");
typingPreview?.UpdatePreview(inputField.isFocused, body);
}
/// <summary>
/// C++: GetHostPlayer()->GetPack()->GetItemTotalNum(id) — đếm túi chính.
/// </summary>
+76
View File
@@ -0,0 +1,76 @@
using TMPro;
using UnityEngine;
namespace BrewMonster.Scripts.ChatUI
{
/// <summary>
/// Controls typing preview visibility/content and keyboard-anchored position.
/// Kept standalone so other chat/input UIs can reuse the same behavior.
/// </summary>
[System.Serializable]
public class TypingPreviewController
{
[Tooltip("Root của box xem trước nội dung đang gõ.")]
[SerializeField] private GameObject typingPreviewRoot;
[Tooltip("Text hiển thị nội dung đang gõ realtime.")]
[SerializeField] private TMP_InputField typingPreviewText;
[Tooltip("Rect của preview box để neo theo keyboard.")]
[SerializeField] private RectTransform typingPreviewRect;
[Tooltip("Khoảng cách dọc cộng thêm cho preview box.")]
[SerializeField] private float previewVerticalOffset = 8f;
private Vector2 _baseAnchoredPos;
private bool _cachedAnchor;
public void CacheInitialAnchor()
{
if (_cachedAnchor)
return;
if (typingPreviewRect != null)
_baseAnchoredPos = typingPreviewRect.anchoredPosition;
_cachedAnchor = true;
}
public void ApplyKeyboardOffset(float yOffset)
{
if (typingPreviewRect == null)
return;
CacheInitialAnchor();
var previewPos = _baseAnchoredPos;
previewPos.y += yOffset + previewVerticalOffset;
typingPreviewRect.anchoredPosition = previewPos;
}
public void UpdatePreview(bool isInputFocused, string body)
{
if (typingPreviewRoot == null || typingPreviewText == null)
return;
string previewBody = body ?? string.Empty;
bool keyboardVisible = IsMobileKeyboardVisible();
bool shouldShow = keyboardVisible && isInputFocused;
typingPreviewRoot.SetActive(shouldShow);
if (shouldShow)
typingPreviewText.text = previewBody;
}
bool IsMobileKeyboardVisible()
{
if (!Application.isMobilePlatform)
return false;
return GetVisibleKeyboardHeight() > 0f || TouchScreenKeyboard.visible;
}
float GetVisibleKeyboardHeight()
{
if (!TouchScreenKeyboard.visible)
return 0f;
Rect area = TouchScreenKeyboard.area;
return area.height > 0f ? area.height : 0f;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a9934ac12c563f746a3ba562e3de5bff
+60
View File
@@ -0,0 +1,60 @@
# Typing Preview - Summary
## Muc tieu da thuc hien
- Tach logic `typingPreview` ra class rieng de de tai su dung.
- Lien ket lai logic giua `ChatInputHandler` va `TypingPreviewController`.
- Dieu chinh co che hien/an theo yeu cau mobile keyboard.
## Cac file da cap nhat
- `Assets/Scripts/TypingPreviewController.cs`
- `Assets/Scripts/ChatInputHandler.cs`
## Noi dung da lam
### 1) Tach typing preview thanh class rieng
- Tao class `TypingPreviewController` de quan ly:
- Hien/an preview (`typingPreviewRoot`)
- Cap nhat text preview realtime (`typingPreviewText`)
- Dinh vi preview theo offset keyboard (`typingPreviewRect`, `previewVerticalOffset`)
### 2) Lien ket voi ChatInputHandler
- `ChatInputHandler` giu `SerializeField`:
- `TypingPreviewController typingPreview`
- Moi khi input thay doi text, `ChatInputHandler` lay message body (bo prefix kenh/whisper) roi day sang controller de cap nhat preview.
- Khi clear input, preview duoc cap nhat lai ngay de an dung trang thai.
### 3) Co che mobile keyboard (cap nhat moi nhat)
- Da chuyen logic check keyboard vao thang `TypingPreviewController`:
- `IsMobileKeyboardVisible()`
- `GetVisibleKeyboardHeight()`
- `ChatInputHandler` da bo cac ham keyboard-check khong con dung.
- `ChatInputHandler` chi can goi `typingPreview.UpdatePreview(isFocused, body)`.
- `ChatInputHandler.Update()` van refresh moi frame de bat kip luc keyboard mo/dong.
- Rule hien moi nhat:
- Keyboard mobile vua mo la preview show ngay (neu input dang focus), khong can cho co ky tu.
## Hanh vi hien tai
- Preview chi hien khi:
- Dang o mobile
- Keyboard dang mo
- Input dang focus
- Khong con yeu cau body phai khong rong (show ngay khi keyboard mo).
- Khi tat keyboard, preview an ngay.
- Khi mo lai keyboard, noi dung da go truoc do van con trong input va preview hien lai dung noi dung.
## Emoji tren preview
- Hien tai preview duoc set text truc tiep tu `body`, nen neu `body` co TMP sprite tag thi co the hien emoji.
- Luu y cau hinh component:
- `typingPreviewText` dang de kieu `TMP_InputField` trong `TypingPreviewController`.
- Neu muon on dinh cho muc dich "preview display", nen doi sang `TMP_Text` hoac `TextMeshProUGUI`.
## Ghi chu
- Da kiem tra lint sau cac lan sua, khong phat hien loi lint moi tren cac file da chinh.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 85a85257c23e84e41ba29cbc51455178
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: