From 3552e05e4c342eec0ec10e32706717eef8a61c1276a8b3c4d59e486fa512e37e Mon Sep 17 00:00:00 2001
From: AidarKC
Date: Sun, 9 Aug 2026 21:26:08 +0400
Subject: [PATCH] =?UTF-8?q?UI:=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?=
=?UTF-8?q?=D1=82=D1=8C=20=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=20=D0=BA=D0=B0?=
=?UTF-8?q?=D0=BD=D0=B0=D0=BB=D0=B0=20=D0=B8=20=D1=82=D1=80=D0=B5=D0=B4?=
=?UTF-8?q?=D0=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
VERSION.properties | 2 +-
shine-UI/js/pages/channel-thread-view.js | 27 ++++++++++---
shine-UI/js/pages/channel-view.js | 41 +++++++++++++------
shine-UI/js/services/auth-service.js | 5 ++-
shine-UI/styles/components.css | 50 +++++++++++++++++++++---
5 files changed, 99 insertions(+), 26 deletions(-)
diff --git a/VERSION.properties b/VERSION.properties
index 230d9d6f..2e486484 100644
--- a/VERSION.properties
+++ b/VERSION.properties
@@ -1,2 +1,2 @@
-client.version=1.5.8
+client.version=1.5.9
server.version=1.4.7
diff --git a/shine-UI/js/pages/channel-thread-view.js b/shine-UI/js/pages/channel-thread-view.js
index 65a62d97..d179abce 100644
--- a/shine-UI/js/pages/channel-thread-view.js
+++ b/shine-UI/js/pages/channel-thread-view.js
@@ -209,6 +209,24 @@ function resolveChannelDisplayName(channelSelector) {
return `${found.channel?.ownerLogin || 'неизвестно'}/${found.channel?.channelName || 'канал'}`;
}
+function resolveChannelHeadingFromNode(node) {
+ const info = node?.channelInfo;
+ const ownerBch = String(info?.ownerBlockchainName || '').trim();
+ const rootBlockNumber = Number(info?.channelRoot?.blockNumber);
+ if (!ownerBch || !Number.isFinite(rootBlockNumber) || rootBlockNumber < 0) return '';
+ if (rootBlockNumber === 0) return 'История пользователя';
+
+ const label = resolveChannelDisplayName({
+ ownerBlockchainName: ownerBch,
+ channelRootBlockNumber: rootBlockNumber,
+ channelRootBlockHash: '0',
+ });
+ const slashIndex = label.indexOf('/');
+ const channelName = slashIndex >= 0 ? label.slice(slashIndex + 1).trim() : label.trim();
+ if (!channelName) return 'Сообщение в канале';
+ return `Сообщение в канале ${channelName}`;
+}
+
function extractChannelContextFromThreadPayload(payload) {
const focusInfo = payload?.focus?.channelInfo;
if (focusInfo?.ownerBlockchainName && focusInfo?.channelRoot?.blockNumber != null) {
@@ -706,7 +724,7 @@ function renderNodeCard(node, heading, handlers, localNumber) {
const isOwnMessage = String(node?.authorLogin || '').trim().toLowerCase() === String(state.session.login || '').trim().toLowerCase();
const isChannelPost = Number(node?.channelInfo?.channelRoot?.blockNumber) >= 0;
const msgSubType = Number(node?.msgSubType || 0);
- const repostTarget = msgSubType === 30 ? buildRepostTargetFromNode(node) : null;
+ const repostTarget = msgSubType === 50 ? buildRepostTargetFromNode(node) : null;
const parsedText = parseMessageAttachments(text);
const headingText = String(heading || '').trim();
@@ -1326,12 +1344,9 @@ export function render({ navigate, route }) {
if (ancestors.length) {
ancestorsWrap = document.createElement('div');
ancestorsWrap.className = 'stack thread-block thread-block--ancestors';
- const title = document.createElement('h3');
- title.className = 'section-title';
- title.textContent = 'История выше (на что это ответ)';
- ancestorsWrap.append(title);
ancestors.forEach((node, index) => {
- ancestorsWrap.append(renderNodeCard(node, `Предок ${index + 1}`, handlers, nextNumber()));
+ const heading = index === 0 ? resolveChannelHeadingFromNode(node) : '';
+ ancestorsWrap.append(renderNodeCard(node, heading, handlers, nextNumber()));
});
}
diff --git a/shine-UI/js/pages/channel-view.js b/shine-UI/js/pages/channel-view.js
index 1c64a2d0..11c7d6cb 100644
--- a/shine-UI/js/pages/channel-view.js
+++ b/shine-UI/js/pages/channel-view.js
@@ -37,6 +37,7 @@ import { buildArweaveDataUrl } from '../services/arweave-file-service.js';
export const pageMeta = { id: 'channel-view', title: 'Канал' };
const CHANNEL_TYPE_STORIES = 0;
const CHANNEL_TYPE_PERSONAL = 100;
+const MSG_SUBTYPE_TEXT_REPOST = 50;
const pendingReactionActions = new Set();
const pendingScrollByRoute = new Map();
@@ -303,7 +304,19 @@ function createChannelAvatarElement(channel, size = 72) {
return wrap;
}
-function openChannelMetaDetailsModal({ title = 'Данные канала', channel = {}, canEdit = false, onEdit = null } = {}) {
+function openChannelMetaDetailsModal({
+ title = 'Данные канала',
+ channel = {},
+ canEdit = false,
+ onEdit = null,
+ changedAtMs = 0,
+} = {}) {
+ const avatarState = String(channel.avaAr || '').trim()
+ ? 'Установлен'
+ : 'Не установлен';
+ const changedAtLabel = changedAtMs
+ ? new Date(Number(changedAtMs)).toLocaleString('ru-RU')
+ : '—';
const root = document.getElementById('modal-root');
root.innerHTML = `
${escapeHtml(channel.displayTitle || channel.displayName || channel.name)}
- - + @@ -337,6 +355,7 @@ function openAboutChannelModal(channel, options = {}) { channel, canEdit: options.canEdit === true, onEdit: options.onEdit, + changedAtMs: Number(channel?.metaUpdatedAtMs || 0), }); } @@ -1181,15 +1200,14 @@ function renderChannelMetaEventCard(event) { const card = document.createElement('article'); card.className = 'card channel-system-event-card'; const label = event.kind === 'created' - ? `Создан канал ${event.title || event.name || ''}`.trim() - : 'Изменён профиль канала'; + ? 'Создан канал' + : 'Изменено описание канала'; card.innerHTML = ` - ${escapeHtml(label)} - ${escapeHtml(event.timestampMs ? new Date(event.timestampMs).toLocaleString('ru-RU') : '')} + ${escapeHtml(label)} `; card.addEventListener('click', () => { openChannelMetaDetailsModal({ - title: event.kind === 'created' ? 'Канал создан' : 'Профиль канала изменён', + title: label, channel: { name: event.name, displayTitle: event.title, @@ -1199,6 +1217,7 @@ function renderChannelMetaEventCard(event) { avaSize: event.avaSize, ownerName: event.ownerName, }, + changedAtMs: event.timestampMs, }); }); return card; @@ -1377,7 +1396,7 @@ function renderPostCard(post, { }); actions.append(shareButton); - if (post.msgSubType === 30 && post.targetRef?.blockchainName && Number.isFinite(post.targetRef?.blockNumber) && post.targetRef?.blockHash) { + if (post.msgSubType === MSG_SUBTYPE_TEXT_REPOST && post.targetRef?.blockchainName && Number.isFinite(post.targetRef?.blockNumber) && post.targetRef?.blockHash) { const originalBtn = document.createElement('button'); originalBtn.type = 'button'; originalBtn.className = 'channel-action-item'; @@ -1797,7 +1816,7 @@ export function render({ navigate, route }) { channelHeaderButton.onclick = (event) => { animatePress(event.currentTarget); openAboutChannelModal(apiData.channel, { - canEdit: apiData?.isOwnChannel === true, + canEdit: apiData?.isOwnChannel === true && !isStoriesChannel(apiData?.channel), onEdit: () => openEditChannelModal({ channel: apiData.channel, onSave: onEditChannelMeta, diff --git a/shine-UI/js/services/auth-service.js b/shine-UI/js/services/auth-service.js index 432147ce..0179c39d 100644 --- a/shine-UI/js/services/auth-service.js +++ b/shine-UI/js/services/auth-service.js @@ -53,8 +53,9 @@ const MSG_SUBTYPE_TEXT_POST = 10; const MSG_SUBTYPE_TEXT_EDIT_POST = 11; const MSG_SUBTYPE_TEXT_REPLY = 20; const MSG_SUBTYPE_TEXT_EDIT_REPLY = 21; -const MSG_SUBTYPE_TEXT_REPOST = 30; -const MSG_SUBTYPE_TEXT_CHANNEL_META = 70; +const MSG_SUBTYPE_TEXT_RATING = 30; +const MSG_SUBTYPE_TEXT_REPOST = 50; +const MSG_SUBTYPE_TEXT_CHANNEL_META = 90; const MSG_SUBTYPE_REACTION_LIKE = 1; const MSG_SUBTYPE_REACTION_UNLIKE = 2; const MSG_SUBTYPE_CONNECTION_FOLLOW = 30; diff --git a/shine-UI/styles/components.css b/shine-UI/styles/components.css index ff3f690b..9ef777e4 100644 --- a/shine-UI/styles/components.css +++ b/shine-UI/styles/components.css @@ -3939,6 +3939,12 @@ textarea.input { gap: 10px; } +.channels-screen--channel .channel-feed { + gap: 2px; + margin-left: -7px; + margin-right: -7px; +} + .channels-screen .channel-message-card { gap: 14px; padding: 20px; @@ -3950,6 +3956,10 @@ textarea.input { box-shadow: 0 0 60px rgba(80, 60, 180, 0.15); } +.channels-screen--channel .channel-message-card { + margin-bottom: 6px; +} + .channel-message-top { display: flex; align-items: center; @@ -4037,19 +4047,41 @@ textarea.input { .channel-system-event-card { display: flex; align-items: center; - justify-content: space-between; + justify-content: center; gap: 10px; - padding: 9px 11px; + width: fit-content; + max-width: min(88%, 460px); + margin: 0 auto 4px; + padding: 8px 16px; border-color: rgba(255, 210, 130, 0.22); - background: rgba(89, 67, 31, 0.22); + border-radius: 999px; + background: rgba(89, 67, 31, 0.26); color: rgba(255, 235, 188, 0.92); cursor: pointer; + text-align: center; } -.channel-system-event-card small { - flex: 0 0 auto; +.channel-system-event-card__label { + display: block; + font-size: 13px; + line-height: 1.2; +} + +.channel-meta-details-grid { + display: grid; + grid-template-columns: minmax(96px, 120px) 1fr; + gap: 10px 14px; + align-items: start; + color: rgba(255, 255, 255, 0.92); +} + +.channel-meta-details-grid > span:nth-child(odd) { color: rgba(255, 255, 255, 0.48); - font-size: 11px; +} + +.channel-meta-details-grid code { + color: rgba(255, 214, 117, 0.92); + word-break: break-word; } .channel-profile-card { @@ -5331,6 +5363,7 @@ textarea.input { } #about-channel-modal.modal, +#edit-channel-modal.modal, #reply-modal.modal, #channel-message-modal.modal, #channel-edit-description-modal.modal, @@ -5342,6 +5375,7 @@ textarea.input { } #about-channel-modal .modal-card, +#edit-channel-modal .modal-card, #reply-modal .modal-card, #channel-message-modal .modal-card, #channel-edit-description-modal .modal-card, @@ -5356,6 +5390,7 @@ textarea.input { } #about-channel-modal .modal-title, +#edit-channel-modal .modal-title, #reply-modal .modal-title, #channel-message-modal .modal-title, #channel-edit-description-modal .modal-title, @@ -5368,6 +5403,7 @@ textarea.input { } #about-channel-modal .input, +#edit-channel-modal .input, #reply-modal .input, #channel-message-modal .input, #channel-edit-description-modal .input, @@ -5390,6 +5426,7 @@ textarea.input { } #about-channel-modal .secondary-btn, +#edit-channel-modal .secondary-btn, #reply-modal .secondary-btn, #channel-message-modal .secondary-btn, #channel-edit-description-modal .secondary-btn, @@ -5403,6 +5440,7 @@ textarea.input { } #about-channel-modal .primary-btn, +#edit-channel-modal .primary-btn, #reply-modal .primary-btn, #channel-message-modal .primary-btn, #channel-edit-description-modal .primary-btn,