Обновить список каналов и кнопку сообщения

This commit is contained in:
AidarKC
2026-06-24 14:59:08 +04:00
parent 77f5759d60
commit f9a15ab192
7 changed files with 146 additions and 188 deletions
+41 -42
View File
@@ -27,6 +27,7 @@ import {
} from '../services/shine-routes.js';
export const pageMeta = { id: 'channel-view', title: 'Канал' };
const CHANNEL_TYPE_STORIES = 0;
const CHANNEL_TYPE_PERSONAL = 100;
const pendingReactionActions = new Set();
@@ -226,6 +227,12 @@ function latestVersionText(versions) {
return '';
}
function isStoriesChannel(channel = null) {
const typeCode = Number(channel?.channelTypeCode ?? channel?.channel?.channelTypeCode ?? 1);
const name = String(channel?.channelName || channel?.channel?.channelName || '').trim().toLowerCase();
return typeCode === CHANNEL_TYPE_STORIES || name === 'stories';
}
function resolveMessageText(message) {
return firstNonEmptyText(
message?.text,
@@ -363,10 +370,11 @@ function openRepostModal({ navigate, channels = [], onSubmit }) {
const root = document.getElementById('modal-root');
const options = (Array.isArray(channels) ? channels : [])
.filter((item) => item?.selector?.ownerBlockchainName && Number.isFinite(Number(item?.selector?.channelRootBlockNumber)))
.filter((item) => !isStoriesChannel(item))
.map((item, index) => {
const owner = String(item?.ownerLogin || '').trim();
const name = String(item?.channelName || '').trim();
const label = `${owner || 'my'} / ${name || 'stories'}`;
const label = `${owner || 'my'}/${name || 'channel'}`;
return `<option value="${index}">${label}</option>`;
})
.join('');
@@ -451,9 +459,6 @@ function openAddMessageModal({ channelName, onSubmit, navigate }) {
<h3 class="modal-title">Новое сообщение в канале</h3>
<p class="meta-muted">${channelName}</p>
<textarea id="channel-message-text" class="input" rows="6" maxlength="2000" placeholder="Текст сообщения"></textarea>
<div class="row wrap-row">
<button class="ghost-btn" id="channel-message-voice" type="button">🎤 Голосом</button>
</div>
<div class="meta-muted inline-error" id="channel-message-error"></div>
<div class="form-actions-grid">
<button class="secondary-btn" id="channel-message-cancel" type="button">Отмена</button>
@@ -480,15 +485,6 @@ function openAddMessageModal({ channelName, onSubmit, navigate }) {
};
root.querySelector('#channel-message-cancel')?.addEventListener('click', close);
root.querySelector('#channel-message-voice')?.addEventListener('click', async () => {
await openSpeechInputModal({
navigate,
onTextReady: (text) => {
const prev = String(textEl?.value || '').trim();
if (textEl) textEl.value = prev ? `${prev} ${text}` : text;
},
});
});
submitEl?.addEventListener('click', async () => {
if (inFlight) return;
@@ -735,6 +731,9 @@ async function loadFromApi(route, channelId) {
const ownerLogin = String(payload.channel?.ownerLogin || '').trim();
const channelName = String(payload.channel?.channelName || '').trim();
const channelTypeCode = Number(payload.channel?.channelTypeCode ?? 1);
if (channelTypeCode === CHANNEL_TYPE_STORIES) {
throw new Error('Канал stories скрыт из пользовательского интерфейса.');
}
const canResolveReverse = (
channelTypeCode === CHANNEL_TYPE_PERSONAL
&& !!currentLogin
@@ -1085,6 +1084,15 @@ function renderBody(screen, navigate, routeKey, channelData, handlers) {
actionButton.className = 'destructive-btn channel-main-action';
actionButton.textContent = 'Подписаться на канал';
const addMessageButton = document.createElement('button');
addMessageButton.type = 'button';
addMessageButton.className = 'primary-btn channel-main-action channel-main-action--compose';
addMessageButton.textContent = 'Добавить сообщение';
addMessageButton.addEventListener('click', (event) => {
animatePress(event.currentTarget);
handlers.onAddMessage();
});
const feed = document.createElement('div');
feed.className = 'stack channel-feed';
const postsByKey = new Map();
@@ -1124,8 +1132,8 @@ function renderBody(screen, navigate, routeKey, channelData, handlers) {
backButton.addEventListener('click', () => navigate('channels-list'));
if (channelData.isOwnChannel) {
screen.append(feed);
} else if (!channelData.isSubscribed) {
screen.append(feed, addMessageButton);
} else if (!channelData.isSubscribed && !isStoriesChannel(channelData.channel)) {
screen.append(actionButton, feed, backButton);
} else {
screen.append(feed, backButton);
@@ -1257,10 +1265,12 @@ export function render({ navigate, route }) {
return {
ownerLogin: String(row?.channel?.ownerLogin || '').trim(),
channelName: String(row?.channel?.channelName || '').trim(),
channelTypeCode: Number(row?.channel?.channelTypeCode ?? 1),
selector,
};
})
.filter(Boolean);
.filter(Boolean)
.filter((item) => !isStoriesChannel(item));
};
const isSameChannelSelector = (a, b) => (
@@ -1359,7 +1369,7 @@ export function render({ navigate, route }) {
try {
const apiData = await loadFromApi(route, channelId);
activeSelector = apiData?.selector || null;
const channelRouteLabel = `Канал: ${apiData?.channel?.ownerName || 'owner'}/${apiData?.channel?.name || 'channel'}`;
const channelRouteLabel = `Канал: ${apiData?.channel?.ownerName || 'owner'} / ${apiData?.channel?.name || 'channel'}`;
const ownChannelLabel = `Ваш канал: ${apiData?.channel?.name || 'channel'}`;
if (channelHeaderButton) {
channelHeaderButton.textContent = apiData?.isOwnChannel ? ownChannelLabel : channelRouteLabel;
@@ -1369,33 +1379,22 @@ export function render({ navigate, route }) {
openAboutChannelModal(apiData.channel);
};
}
if (apiData?.isOwnChannel) {
const headerActions = header.querySelector('.header-actions');
if (headerActions) {
const addBtn = document.createElement('button');
addBtn.type = 'button';
addBtn.className = 'icon-btn channel-header-add-btn';
addBtn.textContent = 'Добавить сообщение';
addBtn.addEventListener('click', (event) => {
animatePress(event.currentTarget);
openAddMessageModal({
channelName: apiData?.channel?.name || '',
navigate,
onSubmit: async (bodyText) => {
try {
await onAddPost(bodyText);
showStatus('');
} catch (error) {
throw new Error(toUserMessage(error, 'Не удалось добавить сообщение.'));
}
},
});
});
headerActions.append(addBtn);
}
}
skeleton.remove();
cleanupSeenTracking = renderBody(screen, navigate, routeKey, apiData, {
onAddMessage: () => {
openAddMessageModal({
channelName: apiData?.channel?.name || '',
navigate,
onSubmit: async (bodyText) => {
try {
await onAddPost(bodyText);
showStatus('');
} catch (error) {
throw new Error(toUserMessage(error, 'Не удалось добавить сообщение.'));
}
},
});
},
onToggleLike: async (messageRef, action) => {
try {
await onToggleLike(messageRef, action);