diff --git a/VERSION.properties b/VERSION.properties index cb23813..d06aa2e 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.2.57 -server.version=1.2.51 +client.version=1.2.58 +server.version=1.2.52 diff --git a/shine-UI/js/pages/channel-thread-view.js b/shine-UI/js/pages/channel-thread-view.js index 7553da3..e5523a1 100644 --- a/shine-UI/js/pages/channel-thread-view.js +++ b/shine-UI/js/pages/channel-thread-view.js @@ -49,6 +49,11 @@ function toSafeInt(value) { return Number.isFinite(parsed) ? parsed : null; } +function looksLikeBlockchainName(value) { + const raw = String(value || '').trim(); + return /^[^-]+-\d+$/.test(raw); +} + function makeReactionActionKey(messageRef) { const login = String(state.session.login || '').trim().toLowerCase(); const blockchainName = String(messageRef?.blockchainName || '').trim(); @@ -581,10 +586,33 @@ export function render({ navigate, route }) { ...(Array.isArray(ownFeed?.followedUsersChannels) ? ownFeed.followedUsersChannels : []), ...(Array.isArray(ownFeed?.followedChannels) ? ownFeed.followedChannels : []), ]; - const channel = allRows.find((item) => ( - String(item?.channel?.ownerBlockchainName || '').trim() === selector.short.ownerBlockchainName - && String(item?.channel?.channelName || '').trim().toLowerCase() === selector.short.channelName.toLowerCase() + const ownerRaw = String(selector.short.ownerBlockchainName || '').trim(); + const ownerNormalized = ownerRaw.toLowerCase(); + const channelNameNormalized = String(selector.short.channelName || '').trim().toLowerCase(); + let channel = allRows.find((item) => ( + String(item?.channel?.ownerBlockchainName || '').trim().toLowerCase() === ownerNormalized + && String(item?.channel?.channelName || '').trim().toLowerCase() === channelNameNormalized )); + if (!channel) { + channel = allRows.find((item) => ( + String(item?.channel?.ownerLogin || '').trim().toLowerCase() === ownerNormalized + && String(item?.channel?.channelName || '').trim().toLowerCase() === channelNameNormalized + )); + } + if (!channel && !looksLikeBlockchainName(ownerRaw)) { + try { + const ownerUser = await authService.getUser(ownerRaw); + const ownerBch = String(ownerUser?.blockchainName || '').trim().toLowerCase(); + if (ownerBch) { + channel = allRows.find((item) => ( + String(item?.channel?.ownerBlockchainName || '').trim().toLowerCase() === ownerBch + && String(item?.channel?.channelName || '').trim().toLowerCase() === channelNameNormalized + )); + } + } catch { + // ignore fallback lookup errors + } + } const ownerBch = String(channel?.channel?.ownerBlockchainName || '').trim(); const rootNo = Number(channel?.channel?.channelRoot?.blockNumber); const rootHash = normalizeRouteHash(channel?.channel?.channelRoot?.blockHash); diff --git a/shine-UI/js/pages/channel-view.js b/shine-UI/js/pages/channel-view.js index 3847521..c082b23 100644 --- a/shine-UI/js/pages/channel-view.js +++ b/shine-UI/js/pages/channel-view.js @@ -55,6 +55,11 @@ function toSafeInt(value) { return Number.isFinite(parsed) ? parsed : null; } +function looksLikeBlockchainName(value) { + const raw = String(value || '').trim(); + return /^[^-]+-\d+$/.test(raw); +} + function makeReactionActionKey(messageRef) { const login = String(state.session.login || '').trim().toLowerCase(); const blockchainName = String(messageRef?.blockchainName || '').trim(); @@ -439,7 +444,7 @@ async function loadFromApi(route, channelId) { && String(item?.channel?.channelName || '').trim().toLowerCase() === selector.channelName.toLowerCase() )); } - if (!channel) { + if (!channel && !looksLikeBlockchainName(routeOwnerRaw)) { try { const ownerUser = await authService.getUser(routeOwnerRaw); const ownerBch = String(ownerUser?.blockchainName || '').trim().toLowerCase(); diff --git a/shine-UI/js/pages/channels-list.js b/shine-UI/js/pages/channels-list.js index 65fae53..f77916d 100644 --- a/shine-UI/js/pages/channels-list.js +++ b/shine-UI/js/pages/channels-list.js @@ -692,7 +692,7 @@ function renderEmptyState(activeTab, navigate) { if (activeTab === 'feed') { text.textContent = 'Нет подписок и найденных каналов.'; } else if (activeTab === 'dialogs') { - text.textContent = 'У вас пока нет персональных каналов.'; + text.textContent = 'Чаты пока не работают.'; } else if (activeTab === 'my') { text.textContent = 'У вас пока нет каналов.'; } else { @@ -1148,6 +1148,10 @@ export function render({ navigate, route }) { tabBtn.type = 'button'; tabBtn.className = `channels-tab-btn${listState.activeTab === tabKey ? ' is-active' : ''}`; tabBtn.textContent = tabLabels[tabKey] || tabKey; + if (tabKey === 'dialogs') { + tabBtn.classList.add('is-disabled'); + tabBtn.title = 'Чаты пока не работают'; + } tabBtn.addEventListener('click', () => { if (listState.activeTab === tabKey) return; listState.activeTab = tabKey; diff --git a/shine-UI/js/services/auth-service.js b/shine-UI/js/services/auth-service.js index 39df3e0..cfef505 100644 --- a/shine-UI/js/services/auth-service.js +++ b/shine-UI/js/services/auth-service.js @@ -1234,10 +1234,15 @@ export class AuthService { const latestMessage = Array.isArray(latestPayload?.messages) ? latestPayload.messages[0] : null; const latestBlockNumber = Number(latestMessage?.messageRef?.blockNumber); const latestBlockHash = normalizeHex32(latestMessage?.messageRef?.blockHash, ''); + const latestVersionsTotal = Number(latestMessage?.versionsTotal); if (Number.isFinite(latestBlockNumber) && latestBlockNumber >= 0 && latestBlockHash) { prevLineNumber = latestBlockNumber; prevLineHashHex = latestBlockHash; - thisLineNumber = latestBlockNumber + 1; + // В line-цепочке thisLineNumber — это номер шага линии, а не глобальный blockNumber. + // Для следующего POST берем шаг после последней известной версии сообщения. + thisLineNumber = Number.isFinite(latestVersionsTotal) && latestVersionsTotal > 0 + ? Math.max(0, latestVersionsTotal) + : 1; } } catch { // fallback to root anchor diff --git a/shine-UI/styles/components.css b/shine-UI/styles/components.css index 65acf78..330bec3 100644 --- a/shine-UI/styles/components.css +++ b/shine-UI/styles/components.css @@ -3545,6 +3545,12 @@ textarea.input { box-shadow: inset 0 1px 0 rgba(255, 238, 197, 0.3); } +.channels-screen--list .channels-tab-btn.is-disabled { + text-decoration: line-through; + text-decoration-thickness: 1.5px; + opacity: 0.72; +} + .toolbar { background: rgba(18, 24, 38, 0.4); backdrop-filter: blur(25px);