From ffd01814b06bd5f9f523631e4a27517bded0c37ea3f292389efcaca71e4684f2 Mon Sep 17 00:00:00 2001 From: AidarKC Date: Sun, 9 Aug 2026 20:54:52 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A3=D1=82=D0=BE=D1=87=D0=BD=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D1=83=D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B8=20=D0=BA=D0=B0=D1=80=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BA=D1=83=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION.properties | 2 +- shine-UI/js/app.js | 5 +-- shine-UI/js/pages/chat-view.js | 40 +++++++++++++++-------- shine-UI/js/services/dm-tech-blocks.js | 12 +++---- shine-UI/styles/components.css | 45 ++++++++++++++++++++++---- 5 files changed, 75 insertions(+), 29 deletions(-) diff --git a/VERSION.properties b/VERSION.properties index 4bc97b5c..e6ac240d 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.5.5 +client.version=1.5.6 server.version=1.4.7 diff --git a/shine-UI/js/app.js b/shine-UI/js/app.js index fe92aee7..70366603 100644 --- a/shine-UI/js/app.js +++ b/shine-UI/js/app.js @@ -1211,13 +1211,14 @@ async function init() { if (added && isIncomingForCurrent && !payload.backlog) { const parsedText = parseDmTechBlocks(text); const displayText = String(parsedText.displayText || ''); + const suppressHiddenNotification = parsedText.callSummary?.status === 'completed'; if (document.visibilityState === 'visible') { void playDmSignal({ extended: false }); - } else if (Notification.permission === 'granted') { + } else if (Notification.permission === 'granted' && !suppressHiddenNotification) { try { void notifyHiddenIncomingMessage(fromLogin, displayText || ''); } catch {} - } else { + } else if (!suppressHiddenNotification) { void playDmSignal({ extended: true }); } } diff --git a/shine-UI/js/pages/chat-view.js b/shine-UI/js/pages/chat-view.js index 9fbbe469..2e49d714 100644 --- a/shine-UI/js/pages/chat-view.js +++ b/shine-UI/js/pages/chat-view.js @@ -440,12 +440,12 @@ function buildCallStatusText(callSummary) { return `Длительность: ${formatCallDurationCompact(callSummary.durationSec)}`; } const reason = String(callSummary.reason || '').trim().toLowerCase(); - if (reason === 'offline') return 'Не дозвонился: абонент не в сети'; - if (reason === 'no_answer') return 'Не дозвонился: нет ответа'; - if (reason === 'connect_failed') return 'Не дозвонился: не удалось установить соединение'; - if (reason === 'busy') return 'Не дозвонился: абонент занят'; - if (reason === 'declined') return 'Не дозвонился: звонок отклонён'; - return 'Не дозвонился'; + if (reason === 'offline') return 'Абонент не в сети'; + if (reason === 'no_answer') return 'Нет ответа'; + if (reason === 'connect_failed') return 'Не удалось установить соединение'; + if (reason === 'busy') return 'Абонент занят'; + if (reason === 'declined') return 'Звонок отклонён'; + return 'Звонок не завершён'; } function resolveEffectiveReadState(messages, msg) { @@ -594,20 +594,34 @@ function renderLog(list, chatId, { onOpenActions, markAsRead = true, scrollMode const callIcon = document.createElement('span'); 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'); callTitle.className = 'bubble-call-title'; - callTitle.textContent = msg?.from === 'out' ? 'Исходящий звонок' : 'Входящий звонок'; + callTitle.textContent = 'Звонок'; - callHead.append(callIcon, callTitle); - - const callMetaLine = document.createElement('div'); - callMetaLine.className = 'bubble-call-line bubble-call-line--muted'; + const callMetaLine = document.createElement('span'); + callMetaLine.className = 'bubble-call-line'; + callMetaLine.classList.add( + parsedText.callSummary.status === 'completed' + ? 'bubble-call-line--success' + : 'bubble-call-line--plain', + ); const callStatus = buildCallStatusText(parsedText.callSummary); callMetaLine.textContent = callStatus; - callCard.append(callHead, callMetaLine); + callHead.append(callIcon, callTitle, callMetaLine); + callCard.append(callHead); bubble.append(callCard); } diff --git a/shine-UI/js/services/dm-tech-blocks.js b/shine-UI/js/services/dm-tech-blocks.js index 841a2351..2ba76fe3 100644 --- a/shine-UI/js/services/dm-tech-blocks.js +++ b/shine-UI/js/services/dm-tech-blocks.js @@ -47,12 +47,12 @@ function buildCallDisplayText(callSummary) { return `Звонок: ${formatCallDuration(callSummary.durationSec)}`; } const reason = String(callSummary.reason || '').trim().toLowerCase(); - if (reason === 'offline') return 'Звонил, но недозвонился: абонент не в сети'; - if (reason === 'no_answer') return 'Звонил, но недозвонился: нет ответа'; - if (reason === 'connect_failed') return 'Звонил, но недозвонился: не удалось установить соединение'; - if (reason === 'busy') return 'Звонил, но недозвонился: абонент занят'; - if (reason === 'declined') return 'Звонил, но недозвонился: звонок отклонён'; - return 'Звонил, но недозвонился'; + if (reason === 'offline') return 'Абонент не в сети'; + if (reason === 'no_answer') return 'Нет ответа'; + if (reason === 'connect_failed') return 'Не удалось установить соединение'; + if (reason === 'busy') return 'Абонент занят'; + if (reason === 'declined') return 'Звонок отклонён'; + return 'Звонок не завершён'; } export function sanitizeUserDmTextForSend(rawText = '') { diff --git a/shine-UI/styles/components.css b/shine-UI/styles/components.css index f7b74f9e..f1fcb93d 100644 --- a/shine-UI/styles/components.css +++ b/shine-UI/styles/components.css @@ -1763,7 +1763,6 @@ .bubble-call-card { display: grid; - gap: 4px; min-width: min(280px, 72vw); } @@ -1771,11 +1770,14 @@ display: inline-flex; align-items: center; gap: 8px; + flex-wrap: wrap; } .bubble-call-icon { - display: inline-grid; - place-items: center; + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; width: 28px; height: 28px; border-radius: 999px; @@ -1783,22 +1785,51 @@ border: 1px solid rgba(123, 191, 255, 0.28); color: #d9ecff; 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 { font-size: 14px; font-weight: 700; color: #eef6ff; + line-height: 1.2; } .bubble-call-line { font-size: 12px; - line-height: 1.35; - color: rgba(230, 240, 255, 0.94); + line-height: 1.2; + margin-left: 2px; } -.bubble-call-line--muted { - color: rgba(188, 207, 238, 0.78); +.bubble-call-line--success { + color: #7ee19e; +} + +.bubble-call-line--plain { + color: rgba(230, 240, 255, 0.94); } .chat-input {