Фикс скрола

This commit is contained in:
Халимов Рустам
2026-03-17 16:33:18 +03:00
parent 408cb446c3
commit e7cdc544d0
2 changed files with 28 additions and 18 deletions

View File

@@ -115,7 +115,6 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
}
const firstUnreadId = activeChat === sessionUnreadRef.current.chatId ? sessionUnreadRef.current.msgId : null;
const lastObservedMessageIdRef = useRef<string | null>(null);
const prevScrollHeightRef = useRef<number>(0);
const initialScrollChatId = useRef<string | null>(null);
// Load muted state
@@ -209,15 +208,6 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
}
}, [activeChat, isLoadingMessages]);
useLayoutEffect(() => {
if (prevScrollHeightRef.current > 0 && messagesContainerRef.current) {
const container = messagesContainerRef.current;
const diff = container.scrollHeight - prevScrollHeightRef.current;
container.scrollTop += diff;
prevScrollHeightRef.current = 0;
}
}, [chatMessages.length]);
// Scroll on new message arrivals
useEffect(() => {
if (chatMessages.length > 0) {
@@ -337,7 +327,6 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
const container = messagesContainerRef.current;
if (container && container.scrollTop < 100 && activeChat && hasMoreMessages[activeChat] && !isLoadingMessages) {
prevScrollHeightRef.current = container.scrollHeight;
useChatStore.getState().loadMessages(activeChat, false, true);
}
};

View File

@@ -130,6 +130,9 @@ const translations = {
klipySuccess: 'Klipy connection successful!',
klipyFailed: 'Klipy Test Failed: ',
apiRequired: 'API Key is required',
customerIdRequired: 'Customer ID is required',
turnGatherFailed: 'Failed to gather candidates. Check credentials or network.',
turnTimeout: 'Timeout gathering candidates.',
},
ru: {
loginTitle: 'Вход администратора',
@@ -215,6 +218,9 @@ const translations = {
klipySuccess: 'Успешное подключение к Klipy!',
klipyFailed: 'Ошибка Klipy: ',
apiRequired: 'API ключ обязателен',
customerIdRequired: 'Customer ID обязателен',
turnGatherFailed: 'Сбор кандидатов не удался. Проверьте данные или сеть.',
turnTimeout: 'Таймаут при сборе кандидатов.',
}
};
@@ -333,12 +339,23 @@ export default function AdminPage() {
let resolved = false;
try {
const pc = new RTCPeerConnection({
iceServers: [{
urls: `turn:${config.turnHost}:${config.turnPort}`,
const turnUrl = `turn:${config.turnHost}:${config.turnPort}`;
const stunUrl = `stun:${config.turnHost}:${config.turnPort}`;
const servers: RTCIceServer[] = [
{ urls: stunUrl }
];
if (config.turnUser) {
servers.push({
urls: [turnUrl, turnUrl + "?transport=tcp"],
username: config.turnUser,
credential: config.turnSecret
}]
credential: config.turnSecret || config.turnUser
});
}
const pc = new RTCPeerConnection({
iceServers: servers
});
pc.addTransceiver('audio');
@@ -349,7 +366,7 @@ export default function AdminPage() {
const timeout = setTimeout(() => {
if (!resolved) {
resolved = true;
reject(new Error("Timeout gathering relay candidates"));
reject(new Error(t.turnTimeout || "Timeout"));
}
}, 10000);
@@ -365,7 +382,7 @@ export default function AdminPage() {
if (!resolved) {
resolved = true;
clearTimeout(timeout);
reject(new Error("Failed to gather candidates. Check credentials or network."));
reject(new Error(t.turnGatherFailed || "Failed to gather candidates."));
}
}
};
@@ -385,6 +402,10 @@ export default function AdminPage() {
showToast(t.apiRequired, 'error');
return;
}
if (!config.klipyCustomerId) {
showToast(t.customerIdRequired || "Customer ID required", 'error');
return;
}
setIsTestingKlipy(true);
try {