website: add SimpleX Network News channel preview (#7087)

* website: add SimpleX Network News channel preview

* send relay domain/capability to channel owner on profile update

* add channel ID

* add top offset parameter

* allow overscroll

* better scroll

* improve

* fix promoted communities

* use path for channel renderer without host

* fix

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
Evgeny @ SimpleX Chat
2026-06-17 19:06:24 +01:00
committed by GitHub
co-authored by Evgeny Poberezkin
parent bcd980127d
commit 8dd888295d
8 changed files with 65 additions and 18 deletions
+1 -11
View File
@@ -4918,17 +4918,7 @@ runRelayGroupLinkChecks user = do
else void $ withStore' $ \db -> updateRelayOwnStatusFromTo db gInfo RSActive RSInactive
_ -> pure ()
_ -> pure ()
sendRelayCapIfNeeded cxt gInfo
sendRelayCapIfNeeded cxt gInfo = do
ChatConfig {webPreviewConfig} <- asks config
let currentWebDomain = (\WebPreviewConfig {webDomain} -> webDomain) <$> webPreviewConfig
sentWebDomain <- withStore' (`getRelaySentWebDomain` gInfo)
when (currentWebDomain /= sentWebDomain) $ do
owners <- withStore' $ \db -> getGroupOwners db cxt user gInfo
let capableOwners = filter (\m -> memberCurrent m && m `supportsVersion` relayWebCapVersion) owners
unless (null capableOwners) $ do
void $ sendGroupMessage' user gInfo capableOwners (XGrpRelayCap RelayCapabilities {webDomain = currentWebDomain})
withStore' $ \db -> updateRelaySentWebDomain db gInfo currentWebDomain
sendRelayCapIfNeeded user gInfo
checkRelayInactiveGroups = do
cxt <- chatStoreCxt
ttl <- asks (relayInactiveTTL . config)
+16
View File
@@ -2126,6 +2126,22 @@ sendGroupMessage' user gInfo members chatMsgEvent =
((Right msg) :| [], _) -> pure msg
_ -> throwChatError $ CEInternalError "sendGroupMessage': expected 1 message"
-- Relay advertises its current web preview capability to channel owners.
-- Idempotent: sends only when the configured web domain differs from what was last sent, and only to
-- owners whose recorded chat version supports relayWebCapVersion (older apps can't parse XGrpRelayCap).
sendRelayCapIfNeeded :: User -> GroupInfo -> CM ()
sendRelayCapIfNeeded user gInfo = do
ChatConfig {webPreviewConfig} <- asks config
let currentWebDomain = (\WebPreviewConfig {webDomain} -> webDomain) <$> webPreviewConfig
sentWebDomain <- withStore' (`getRelaySentWebDomain` gInfo)
when (currentWebDomain /= sentWebDomain) $ do
cxt <- chatStoreCxt
owners <- withStore' $ \db -> getGroupOwners db cxt user gInfo
let capableOwners = filter (\m -> memberCurrent m && m `supportsVersion` relayWebCapVersion) owners
unless (null capableOwners) $ do
void $ sendGroupMessage' user gInfo capableOwners (XGrpRelayCap RelayCapabilities {webDomain = currentWebDomain})
withStore' $ \db -> updateRelaySentWebDomain db gInfo currentWebDomain
sendGroupMessages :: MsgEncodingI e => User -> GroupInfo -> Maybe GroupChatScope -> ShowGroupAsSender -> [GroupMember] -> NonEmpty (ChatMsgEvent e) -> CM (NonEmpty (Either ChatError SndMessage), GroupSndResult)
sendGroupMessages user gInfo scope asGroup members events = do
-- TODO [knocking] send current profile to pending member after approval?
+2
View File
@@ -3323,6 +3323,8 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage =
unless (useRelays' g'') $
void $ forkIO $ void $ setGroupLinkData' NRMBackground user g''
Just _ -> updateGroupPrefs_ msgSigned g m $ fromMaybe defaultBusinessGroupPrefs $ groupPreferences p'
-- relay advertises its web capability now that the owner's version is known (bumped by saveGroupRcvMsg)
when (isRelay (membership g)) $ sendRelayCapIfNeeded user g
pure $ Just DJSGroup {jobSpec = DJDeliveryJob {includePending = True}}
xGrpPrefs :: GroupInfo -> GroupMember -> GroupPreferences -> RcvMessage -> CM (Maybe DeliveryJobScope)
+1 -1
View File
@@ -148,7 +148,7 @@
</svg>
</button>
{% if ('blog' not in page.url) and ('about' not in page.url) and ('donate' not in page.url) and ('privacy' not in page.url) and ('directory' not in page.url) and ('credits' not in page.url) and ('file' not in page.url) and ('links' not in page.url) %}
{% if ('blog' not in page.url) and ('about' not in page.url) and ('donate' not in page.url) and ('privacy' not in page.url) and ('directory' not in page.url) and ('credits' not in page.url) and ('file' not in page.url) and ('links' not in page.url) and ('news' not in page.url) %}
<div class="nav-link flag-container">
<a href="javascript:void(0);">
{% for language in languages.languages %}
+2 -1
View File
@@ -41,7 +41,8 @@ active_blog: true
<section class="py-10 px-5 mt-[66px]" id="blog-list">
<div class="container">
<h1 class="text-[38px] text-center font-bold mb-9">Latest news</h1>
<h1 class="text-[38px] text-center font-bold mb-2">Latest news</h1>
<p class="text-right mb-9"><a class="text-primary-light dark:text-[#70F0F9] text-sm font-medium tracking-[0.03em]" href="/news">Open SimpleX Network News channel</a></p>
{% for blog in collections.blogs %}
{% if not(blog.data.draft) %}
+26 -3
View File
@@ -94,6 +94,15 @@ const STYLE = `
text-overflow: ellipsis;
}
.simplex-preview-container .simplex-preview-header-name {
background: none;
-webkit-background-clip: border-box;
background-clip: border-box;
color: var(--sp-text);
-webkit-text-fill-color: var(--sp-text);
text-fill-color: var(--sp-text);
}
.simplex-preview-header-description {
font-size: 13px;
color: var(--sp-text-secondary);
@@ -492,16 +501,18 @@ const STYLE = `
min-width: 0;
max-width: 640px;
overflow-y: auto;
overscroll-behavior: contain;
position: relative;
}
.simplex-preview-info {
overflow-y: auto;
overscroll-behavior: contain;
background: var(--sp-bg);
}
.simplex-preview-scroll-lock {
overflow: hidden;
}
.simplex-preview-info-close {
display: none;
}
@@ -696,12 +707,13 @@ const STYLE = `
.simplex-preview-info {
display: none;
position: fixed;
top: 0;
top: var(--sp-top-offset, 0px);
left: 0;
right: 0;
bottom: 0;
z-index: 100;
padding: 16px;
overscroll-behavior: contain;
}
.simplex-preview-info.open {
display: block;
@@ -786,6 +798,13 @@ function initChannelPreview(container) {
if (container.dataset.darkBackground) {
container.style.setProperty('--sp-dark-bg', container.dataset.darkBackground);
}
const topOffset = parseInt(container.dataset.topOffset || '0', 10);
if (topOffset > 0) {
container.style.setProperty('--sp-top-offset', topOffset + 'px');
container.style.marginTop = topOffset + 'px';
container.style.height = 'calc(100vh - ' + topOffset + 'px)';
container.style.height = 'calc(100dvh - ' + topOffset + 'px)';
}
container.innerHTML = '<p class="simplex-preview-empty">Loading channel...</p>';
fetchPreview(relayScheme, relayDomains, channelLink, channelId).then(data => {
@@ -885,12 +904,16 @@ function render(container, data, channelLink, showAppBadges) {
if (window.innerWidth < 1000) {
info.classList.add('open');
main.style.overflow = 'hidden';
document.documentElement.classList.add('simplex-preview-scroll-lock');
document.body.classList.add('simplex-preview-scroll-lock');
}
});
closeBtn.addEventListener('click', () => {
info.classList.remove('open');
main.style.overflow = '';
document.documentElement.classList.remove('simplex-preview-scroll-lock');
document.body.classList.remove('simplex-preview-scroll-lock');
});
setupSecretToggles(container);
+1 -2
View File
@@ -1,5 +1,3 @@
#include "simplex-lib.jsc"
const simplexDirectoryDataURL = 'https://directory.simplex.chat/data/';
// const simplexDirectoryDataURL = 'http://localhost:8080/directory-data/';
@@ -7,6 +5,7 @@ const simplexDirectoryDataURL = 'https://directory.simplex.chat/data/';
const simplexUsersGroup = 'SimpleX users group';
(function() {
#include "simplex-lib.jsc"
if (!document.location.pathname.startsWith('/directory')) return;
let allEntries = [];
+16
View File
@@ -0,0 +1,16 @@
---
layout: layouts/main.html
title: "SimpleX Network News"
description: "The news about SimpleX Network technology, governance and anything related to its development."
templateEngineOverride: njk
---
<div data-simplex-channel-preview
data-channel-link="https://smp18.simplex.im/c#grcfG3ulVI4Sh6ow33qBsmSk7uEy3gRSl2KkJ5ER6tA"
data-channel-id="8Ge2ASVRkbDhdJc05ZgSSnZmSjw3UMUaQW_QttI0j_w="
data-relay-domains="relay1.simplex.chat,relay2.simplex.chat"
data-app-download-buttons="off"
data-color-scheme="site"
data-top-offset="54"
></div>
<script src="/js/channel-preview.js"></script>