UI: DM список метаданных и Enter/Ctrl+Enter в чате
This commit is contained in:
parent
c6d310184b
commit
8325cbec84
@ -0,0 +1,24 @@
|
||||
# Личные сообщения: правая мета-колонка и Enter/Ctrl+Enter
|
||||
|
||||
- Краткое описание:
|
||||
- В списке `Личные сообщения` обновлена правая колонка карточки диалога:
|
||||
- сверху отображается бейдж количества непрочитанных (если есть);
|
||||
- снизу маленьким шрифтом отображается дата/время последнего сообщения;
|
||||
- если сообщений нет, вместо времени отображается `-`.
|
||||
- В экране чата нижний блок ввода закреплён (sticky) и остаётся на месте при прокрутке.
|
||||
- В поле ввода чата изменено поведение клавиш:
|
||||
- `Enter` отправляет сообщение;
|
||||
- `Ctrl+Enter` добавляет перенос строки и не отправляет сообщение.
|
||||
|
||||
- Что проверять:
|
||||
- В карточках диалогов справа корректно показываются непрочитанные/время/прочерк.
|
||||
- В чате нижний блок ввода не уезжает при прокрутке истории.
|
||||
- `Enter` отправляет сообщение из textarea.
|
||||
- `Ctrl+Enter` вставляет новую строку в textarea.
|
||||
|
||||
- Ожидаемый результат:
|
||||
- Список диалогов показывает полезную мета-информацию в стабильном формате.
|
||||
- Ввод сообщений в чате работает в привычной схеме Enter/многострочность.
|
||||
|
||||
- Статус:
|
||||
- `pending`
|
||||
@ -1,2 +1,2 @@
|
||||
client.version=1.2.71
|
||||
server.version=1.2.65
|
||||
client.version=1.2.72
|
||||
server.version=1.2.66
|
||||
|
||||
@ -416,6 +416,16 @@ export function render({ navigate, route }) {
|
||||
const input = form.elements.message;
|
||||
autoResizeComposer(input);
|
||||
input?.addEventListener('input', () => autoResizeComposer(input));
|
||||
input?.addEventListener('keydown', async (event) => {
|
||||
if (event.key !== 'Enter') return;
|
||||
if (event.ctrlKey) return;
|
||||
event.preventDefault();
|
||||
const text = String(input.value || '').trim();
|
||||
if (!text) return;
|
||||
input.value = '';
|
||||
autoResizeComposer(input);
|
||||
await sendTextMessage(text);
|
||||
});
|
||||
|
||||
form.querySelector('#chat-voice-input')?.addEventListener('click', async () => {
|
||||
await openSpeechInputModal({
|
||||
|
||||
@ -11,6 +11,17 @@ import { loadCurrentRelations } from '../services/user-connections.js';
|
||||
|
||||
export const pageMeta = { id: 'messages-list', title: 'Личные сообщения' };
|
||||
|
||||
function formatChatRowTime(ts) {
|
||||
const value = Number(ts || 0);
|
||||
if (!Number.isFinite(value) || value <= 0) return '-';
|
||||
return new Intl.DateTimeFormat('ru-RU', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
}).format(new Date(value));
|
||||
}
|
||||
|
||||
export function render({ navigate }) {
|
||||
const screen = document.createElement('section');
|
||||
screen.className = 'stack dm-screen dm-list-screen';
|
||||
@ -38,9 +49,9 @@ export function render({ navigate }) {
|
||||
</div>
|
||||
<p class="meta-muted" style="margin-top:4px;">${item.lastMessage}</p>
|
||||
</div>
|
||||
<div style="display:grid; justify-items:end; gap:6px;">
|
||||
<span class="meta-muted">${item.time}</span>
|
||||
<div class="dm-row-meta-col">
|
||||
${item.unread ? `<span class="unread">${item.unread}</span>` : '<span></span>'}
|
||||
<span class="meta-muted dm-row-time">${item.time}</span>
|
||||
</div>
|
||||
`;
|
||||
row.addEventListener('click', () => navigate(`chat-view/${encodeURIComponent(item.id)}`));
|
||||
@ -59,12 +70,13 @@ export function render({ navigate }) {
|
||||
const chat = getChatMessages(login);
|
||||
const lastChat = chat[chat.length - 1];
|
||||
const unread = chat.filter((m) => m?.from === 'in' && m?.unread).length;
|
||||
const lastTimeMs = Number(lastChat?.createdAtMs || 0);
|
||||
return {
|
||||
id: login,
|
||||
initials: (login[0] || '?').toUpperCase(),
|
||||
name: preview?.name || login,
|
||||
lastMessage: lastChat?.text || preview?.lastMessage || 'Диалог пока пуст.',
|
||||
time: preview?.time || '—',
|
||||
time: formatChatRowTime(lastTimeMs),
|
||||
unread,
|
||||
notInContacts: false,
|
||||
};
|
||||
@ -81,12 +93,13 @@ export function render({ navigate }) {
|
||||
const chat = getChatMessages(login);
|
||||
const lastChat = chat[chat.length - 1];
|
||||
const unread = chat.filter((m) => m?.from === 'in' && m?.unread).length;
|
||||
const lastTimeMs = Number(lastChat?.createdAtMs || 0);
|
||||
return {
|
||||
id: login,
|
||||
initials: (login[0] || '?').toUpperCase(),
|
||||
name: login,
|
||||
lastMessage: lastChat?.text || 'Диалог пока пуст.',
|
||||
time: 'сейчас',
|
||||
time: formatChatRowTime(lastTimeMs),
|
||||
unread,
|
||||
notInContacts: true,
|
||||
};
|
||||
|
||||
@ -3427,6 +3427,19 @@ textarea.input {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.32);
|
||||
}
|
||||
|
||||
.dm-row-meta-col {
|
||||
display: grid;
|
||||
justify-items: end;
|
||||
align-content: start;
|
||||
gap: 6px;
|
||||
min-width: 64px;
|
||||
}
|
||||
|
||||
.dm-row-time {
|
||||
font-size: 11px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.dm-chat-wrap {
|
||||
gap: 12px;
|
||||
}
|
||||
@ -3465,6 +3478,14 @@ textarea.input {
|
||||
gap: 10px;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: end;
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
padding: 10px;
|
||||
border-top: 1px solid rgba(212, 175, 55, 0.22);
|
||||
background: rgba(8, 12, 20, 0.9);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.dm-voice-btn {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user