SHA256
Channels UI + read/unread + unique views + style polish
This commit is contained in:
@@ -756,6 +756,17 @@ export class AuthService {
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async markChannelMessagesSeen({ login, channel, messages }) {
|
||||
const cleanLogin = String(login || '').trim();
|
||||
const refs = Array.isArray(messages) ? messages : [];
|
||||
const payload = { channel, messages: refs };
|
||||
if (cleanLogin) payload.login = cleanLogin;
|
||||
|
||||
const response = await this.ws.request('MarkChannelMessagesSeen', payload);
|
||||
if (response.status !== 200) throw opError('MarkChannelMessagesSeen', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async addBlockSigned({ login, storagePwd, msgType, msgSubType, msgVersion = 1, bodyBytes }) {
|
||||
const cleanLogin = (login || '').trim();
|
||||
if (!cleanLogin) throw new Error('Missing login for AddBlock');
|
||||
|
||||
@@ -168,3 +168,55 @@ export function normalizeChannelDescription(value) {
|
||||
if (chars.length <= 200) return text;
|
||||
return chars.slice(0, 200).join('');
|
||||
}
|
||||
|
||||
function fallbackCopyText(text) {
|
||||
const ta = document.createElement('textarea');
|
||||
ta.value = String(text || '');
|
||||
ta.setAttribute('readonly', 'readonly');
|
||||
ta.style.position = 'fixed';
|
||||
ta.style.opacity = '0';
|
||||
ta.style.pointerEvents = 'none';
|
||||
document.body.append(ta);
|
||||
ta.focus();
|
||||
ta.select();
|
||||
const ok = document.execCommand('copy');
|
||||
ta.remove();
|
||||
return !!ok;
|
||||
}
|
||||
|
||||
export async function shareOrCopyLink({ title = '', text = '', url = '' }) {
|
||||
const link = String(url || '').trim();
|
||||
if (!link) {
|
||||
throw new Error('Ссылка для передачи не подготовлена.');
|
||||
}
|
||||
|
||||
const payload = { title: String(title || '').trim(), text: String(text || '').trim(), url: link };
|
||||
|
||||
if (navigator?.share) {
|
||||
try {
|
||||
await navigator.share(payload);
|
||||
return 'shared';
|
||||
} catch (error) {
|
||||
if (error?.name === 'AbortError') return 'cancelled';
|
||||
// fallback to copy path
|
||||
}
|
||||
}
|
||||
|
||||
if (navigator?.clipboard?.writeText) {
|
||||
await navigator.clipboard.writeText(link);
|
||||
return 'copied';
|
||||
}
|
||||
|
||||
if (fallbackCopyText(link)) {
|
||||
return 'copied';
|
||||
}
|
||||
|
||||
throw new Error('Не удалось передать ссылку.');
|
||||
}
|
||||
|
||||
export async function longPressFeel(el, delayMs = 130) {
|
||||
const node = el instanceof Element ? el : null;
|
||||
if (node) node.classList.add('is-long-press');
|
||||
await new Promise((resolve) => setTimeout(resolve, Math.max(60, Number(delayMs) || 130)));
|
||||
if (node) node.classList.remove('is-long-press');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user