SHA256
Добавил гостевой режим, единые shine-ссылки и пометку о нестабильности мнений
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { navigate } from '../router.js';
|
||||
|
||||
function escapeHtml(text) {
|
||||
return String(text || '')
|
||||
.replaceAll('&', '&')
|
||||
.replaceAll('<', '<')
|
||||
.replaceAll('>', '>')
|
||||
.replaceAll('"', '"')
|
||||
.replaceAll("'", ''');
|
||||
}
|
||||
|
||||
export function openAuthRequiredModal({
|
||||
title = 'Нужен вход',
|
||||
text = 'Эта часть доступна после входа в систему.',
|
||||
startRoute = 'start-view',
|
||||
} = {}) {
|
||||
const root = document.getElementById('modal-root');
|
||||
if (!(root instanceof HTMLElement)) {
|
||||
window.alert(`${title}\n\n${text}`);
|
||||
return;
|
||||
}
|
||||
root.innerHTML = `
|
||||
<div class="modal" id="auth-required-modal">
|
||||
<div class="modal-card stack">
|
||||
<h3 class="modal-title">${escapeHtml(title)}</h3>
|
||||
<p class="meta-muted" style="white-space: pre-wrap; line-height: 1.45;">${escapeHtml(text)}</p>
|
||||
<div class="form-actions-grid">
|
||||
<button class="secondary-btn" type="button" id="auth-required-close">Закрыть</button>
|
||||
<button class="primary-btn" type="button" id="auth-required-start">На старт</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const close = () => { root.innerHTML = ''; };
|
||||
root.querySelector('#auth-required-close')?.addEventListener('click', close);
|
||||
root.querySelector('#auth-required-start')?.addEventListener('click', () => {
|
||||
close();
|
||||
navigate(startRoute);
|
||||
});
|
||||
root.querySelector('#auth-required-modal')?.addEventListener('click', (event) => {
|
||||
if (event.target?.id === 'auth-required-modal') close();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
function encodeRoutePart(value = '') {
|
||||
return encodeURIComponent(String(value || '').trim());
|
||||
}
|
||||
|
||||
function decodeRoutePart(value = '') {
|
||||
try {
|
||||
return decodeURIComponent(String(value || ''));
|
||||
} catch {
|
||||
return String(value || '');
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeLogin(value = '') {
|
||||
return String(value || '').trim().replace(/^@+/, '');
|
||||
}
|
||||
|
||||
export function extractLoginFromBlockchainName(value = '') {
|
||||
const raw = String(value || '').trim();
|
||||
const match = raw.match(/^(.+)-\d+$/);
|
||||
if (!match) return normalizeLogin(raw);
|
||||
return normalizeLogin(String(match[1] || ''));
|
||||
}
|
||||
|
||||
export function makeProfileRoute(login = '') {
|
||||
const clean = normalizeLogin(login);
|
||||
return clean ? `shine.${encodeRoutePart(clean)}` : 'profile-view';
|
||||
}
|
||||
|
||||
export function makeProfileLinksRoute(login = '') {
|
||||
const clean = normalizeLogin(login);
|
||||
return clean ? `shine.${encodeRoutePart(clean)}/links` : 'network-view/keep-history';
|
||||
}
|
||||
|
||||
export function makeProfileChannelsRoute(login = '', scope = 'all') {
|
||||
const clean = normalizeLogin(login);
|
||||
if (!clean) return 'channels-list/feed';
|
||||
const normalizedScope = String(scope || '').trim().toLowerCase();
|
||||
if (normalizedScope === 'owned') return `shine.${encodeRoutePart(clean)}/channels/owned`;
|
||||
if (normalizedScope === 'following') return `shine.${encodeRoutePart(clean)}/channels/following`;
|
||||
return `shine.${encodeRoutePart(clean)}/channels`;
|
||||
}
|
||||
|
||||
export function makeShineChannelRoute({ ownerLogin = '', ownerBlockchainName = '', channelName = '', messageBlockNumber = '' }) {
|
||||
const cleanOwnerLogin = normalizeLogin(ownerLogin) || extractLoginFromBlockchainName(ownerBlockchainName);
|
||||
const ownerBch = String(ownerBlockchainName || '').trim();
|
||||
const chName = String(channelName || '').trim();
|
||||
const msgNo = String(messageBlockNumber || '').trim();
|
||||
if (!cleanOwnerLogin || !ownerBch || !chName) return '';
|
||||
if (msgNo) return `shine.${encodeRoutePart(cleanOwnerLogin)}/channel/${encodeRoutePart(ownerBch)}/${encodeRoutePart(chName)}/${encodeRoutePart(msgNo)}`;
|
||||
return `shine.${encodeRoutePart(cleanOwnerLogin)}/channel/${encodeRoutePart(ownerBch)}/${encodeRoutePart(chName)}`;
|
||||
}
|
||||
|
||||
export function makeShineMessageRoute({ ownerLogin = '', messageBlockchainName = '', messageBlockNumber = '' }) {
|
||||
const cleanOwnerLogin = normalizeLogin(ownerLogin);
|
||||
const msgBch = String(messageBlockchainName || '').trim();
|
||||
const msgNo = String(messageBlockNumber || '').trim();
|
||||
if (!cleanOwnerLogin || !msgBch || !msgNo) return '';
|
||||
return `shine.${encodeRoutePart(cleanOwnerLogin)}/msg/${encodeRoutePart(msgBch)}/${encodeRoutePart(msgNo)}`;
|
||||
}
|
||||
|
||||
export function parseShineRootSegment(segment = '') {
|
||||
const raw = String(segment || '').trim();
|
||||
if (!raw.toLowerCase().startsWith('shine.')) return '';
|
||||
return normalizeLogin(decodeRoutePart(raw.slice('shine.'.length)));
|
||||
}
|
||||
@@ -47,7 +47,23 @@ function toToggleMap(snapshot) {
|
||||
}
|
||||
|
||||
function readArray(payload, key) {
|
||||
const value = payload?.[key];
|
||||
const aliases = {
|
||||
outKnownPersons: ['outKnownPersons', 'outKnownPerson', 'out_known_persons'],
|
||||
inKnownPersons: ['inKnownPersons', 'inKnownPerson', 'in_known_persons'],
|
||||
outShineConfirmed: ['outShineConfirmed', 'outShineConfident', 'out_shine_confirmed'],
|
||||
inShineConfirmed: ['inShineConfirmed', 'inShineConfident', 'in_shine_confirmed'],
|
||||
outShineSeen: ['outShineSeen', 'out_shine_seen'],
|
||||
inShineSeen: ['inShineSeen', 'in_shine_seen'],
|
||||
};
|
||||
const keys = aliases[key] || [key];
|
||||
let value = null;
|
||||
for (const oneKey of keys) {
|
||||
const candidate = payload?.[oneKey];
|
||||
if (Array.isArray(candidate)) {
|
||||
value = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Array.isArray(value) ? uniqueLogins(value) : null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user