Уточнить уведомления и карточку звонка

This commit is contained in:
AidarKC
2026-08-09 20:54:52 +04:00
parent c511910b8f
commit ffd01814b0
5 changed files with 75 additions and 29 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
client.version=1.5.5 client.version=1.5.6
server.version=1.4.7 server.version=1.4.7
+3 -2
View File
@@ -1211,13 +1211,14 @@ async function init() {
if (added && isIncomingForCurrent && !payload.backlog) { if (added && isIncomingForCurrent && !payload.backlog) {
const parsedText = parseDmTechBlocks(text); const parsedText = parseDmTechBlocks(text);
const displayText = String(parsedText.displayText || ''); const displayText = String(parsedText.displayText || '');
const suppressHiddenNotification = parsedText.callSummary?.status === 'completed';
if (document.visibilityState === 'visible') { if (document.visibilityState === 'visible') {
void playDmSignal({ extended: false }); void playDmSignal({ extended: false });
} else if (Notification.permission === 'granted') { } else if (Notification.permission === 'granted' && !suppressHiddenNotification) {
try { try {
void notifyHiddenIncomingMessage(fromLogin, displayText || ''); void notifyHiddenIncomingMessage(fromLogin, displayText || '');
} catch {} } catch {}
} else { } else if (!suppressHiddenNotification) {
void playDmSignal({ extended: true }); void playDmSignal({ extended: true });
} }
} }
+27 -13
View File
@@ -440,12 +440,12 @@ function buildCallStatusText(callSummary) {
return `Длительность: ${formatCallDurationCompact(callSummary.durationSec)}`; return `Длительность: ${formatCallDurationCompact(callSummary.durationSec)}`;
} }
const reason = String(callSummary.reason || '').trim().toLowerCase(); const reason = String(callSummary.reason || '').trim().toLowerCase();
if (reason === 'offline') return 'Не дозвонился: абонент не в сети'; if (reason === 'offline') return 'Абонент не в сети';
if (reason === 'no_answer') return 'Не дозвонился: нет ответа'; if (reason === 'no_answer') return 'Нет ответа';
if (reason === 'connect_failed') return 'Не дозвонился: не удалось установить соединение'; if (reason === 'connect_failed') return 'Не удалось установить соединение';
if (reason === 'busy') return 'Не дозвонился: абонент занят'; if (reason === 'busy') return 'Абонент занят';
if (reason === 'declined') return 'Не дозвонился: звонок отклонён'; if (reason === 'declined') return 'Звонок отклонён';
return 'Не дозвонился'; return 'Звонок не завершён';
} }
function resolveEffectiveReadState(messages, msg) { function resolveEffectiveReadState(messages, msg) {
@@ -594,20 +594,34 @@ function renderLog(list, chatId, { onOpenActions, markAsRead = true, scrollMode
const callIcon = document.createElement('span'); const callIcon = document.createElement('span');
callIcon.className = 'bubble-call-icon'; callIcon.className = 'bubble-call-icon';
callIcon.textContent = '☎'; callIcon.classList.add(msg?.from === 'out' ? 'bubble-call-icon--outgoing' : 'bubble-call-icon--incoming');
const callIconPhone = document.createElement('span');
callIconPhone.className = 'bubble-call-icon-phone';
callIconPhone.textContent = '✆';
const callIconArrow = document.createElement('span');
callIconArrow.className = 'bubble-call-icon-arrow';
callIconArrow.textContent = msg?.from === 'out' ? '↑' : '↓';
callIcon.append(callIconPhone, callIconArrow);
const callTitle = document.createElement('span'); const callTitle = document.createElement('span');
callTitle.className = 'bubble-call-title'; callTitle.className = 'bubble-call-title';
callTitle.textContent = msg?.from === 'out' ? 'Исходящий звонок' : 'Входящий звонок'; callTitle.textContent = 'Звонок';
callHead.append(callIcon, callTitle); const callMetaLine = document.createElement('span');
callMetaLine.className = 'bubble-call-line';
const callMetaLine = document.createElement('div'); callMetaLine.classList.add(
callMetaLine.className = 'bubble-call-line bubble-call-line--muted'; parsedText.callSummary.status === 'completed'
? 'bubble-call-line--success'
: 'bubble-call-line--plain',
);
const callStatus = buildCallStatusText(parsedText.callSummary); const callStatus = buildCallStatusText(parsedText.callSummary);
callMetaLine.textContent = callStatus; callMetaLine.textContent = callStatus;
callCard.append(callHead, callMetaLine); callHead.append(callIcon, callTitle, callMetaLine);
callCard.append(callHead);
bubble.append(callCard); bubble.append(callCard);
} }
+6 -6
View File
@@ -47,12 +47,12 @@ function buildCallDisplayText(callSummary) {
return `Звонок: ${formatCallDuration(callSummary.durationSec)}`; return `Звонок: ${formatCallDuration(callSummary.durationSec)}`;
} }
const reason = String(callSummary.reason || '').trim().toLowerCase(); const reason = String(callSummary.reason || '').trim().toLowerCase();
if (reason === 'offline') return 'Звонил, но недозвонился: абонент не в сети'; if (reason === 'offline') return 'Абонент не в сети';
if (reason === 'no_answer') return 'Звонил, но недозвонился: нет ответа'; if (reason === 'no_answer') return 'Нет ответа';
if (reason === 'connect_failed') return 'Звонил, но недозвонился: не удалось установить соединение'; if (reason === 'connect_failed') return 'Не удалось установить соединение';
if (reason === 'busy') return 'Звонил, но недозвонился: абонент занят'; if (reason === 'busy') return 'Абонент занят';
if (reason === 'declined') return 'Звонил, но недозвонился: звонок отклонён'; if (reason === 'declined') return 'Звонок отклонён';
return 'Звонил, но недозвонился'; return 'Звонок не завершён';
} }
export function sanitizeUserDmTextForSend(rawText = '') { export function sanitizeUserDmTextForSend(rawText = '') {
+38 -7
View File
@@ -1763,7 +1763,6 @@
.bubble-call-card { .bubble-call-card {
display: grid; display: grid;
gap: 4px;
min-width: min(280px, 72vw); min-width: min(280px, 72vw);
} }
@@ -1771,11 +1770,14 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
flex-wrap: wrap;
} }
.bubble-call-icon { .bubble-call-icon {
display: inline-grid; position: relative;
place-items: center; display: inline-flex;
align-items: center;
justify-content: center;
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 999px; border-radius: 999px;
@@ -1783,22 +1785,51 @@
border: 1px solid rgba(123, 191, 255, 0.28); border: 1px solid rgba(123, 191, 255, 0.28);
color: #d9ecff; color: #d9ecff;
font-size: 15px; font-size: 15px;
flex: 0 0 auto;
}
.bubble-call-icon-phone {
font-size: 15px;
line-height: 1;
transform: translateX(-1px);
}
.bubble-call-icon-arrow {
position: absolute;
right: 4px;
bottom: 3px;
font-size: 10px;
line-height: 1;
font-weight: 700;
}
.bubble-call-icon--incoming .bubble-call-icon-arrow {
color: rgba(167, 225, 255, 0.98);
}
.bubble-call-icon--outgoing .bubble-call-icon-arrow {
color: rgba(255, 214, 132, 0.98);
} }
.bubble-call-title { .bubble-call-title {
font-size: 14px; font-size: 14px;
font-weight: 700; font-weight: 700;
color: #eef6ff; color: #eef6ff;
line-height: 1.2;
} }
.bubble-call-line { .bubble-call-line {
font-size: 12px; font-size: 12px;
line-height: 1.35; line-height: 1.2;
color: rgba(230, 240, 255, 0.94); margin-left: 2px;
} }
.bubble-call-line--muted { .bubble-call-line--success {
color: rgba(188, 207, 238, 0.78); color: #7ee19e;
}
.bubble-call-line--plain {
color: rgba(230, 240, 255, 0.94);
} }
.chat-input { .chat-input {