core: render web previews for channels (#7029)

* plan: web previews for channels

* types for recipient side to support channel web previews and domain names

* fix

* migrations

* update schema and api types

* update schema

* rename migrations

* core: render channel preview data

* core: render channel preview data in relays

* website: use cpp to inject JS functions

* JSC files

* remove directory.js

* channel preview renderer

* Revert "cli: fix redraw slowness (#6735)"

This reverts commit b801d77c74.

* sample channel page

* default avatar

* rename options

* better layout

* layout

* images

* some fixes

* tails

* markdown colors

* image sizes

* reactions

* fix reactions

* fewer avatars

* forward icon

* command to change group access parameters

* view public group access changes in CLI

* media metadata color

* ios: group web access ui

* update ui

* add init

* kotlin, labels

* update page

* update relay base URL

* fix

* ios update channel web page info

* update kotlin layout

* use cards

* update layout

* use domains for relay data, path is fixed

* update embed code

* fix bots api

* include only history items and senders

* update preview JS/HTML

* show different error if link is different

* remove stale json files

* better layout

* layout fixes

* improve layout

* improve layout

* update embed code

* web cta

* better layout

* buttons

* layout

* paddings

* desktop cta

* desktop cta

* cta layout

* fonts

* paddings

* paddings

* more paddings

* copy link

* read more

* hide avatar and placeholder when all messages are from channel

* color scheme

* fix color

* improve

* layout

* welcome message

* dark mode colors

* padding

* font size

* overscroll

* font

* logo on button

* better join

* buttons

* refactor

* another logo

* text

* desktop button

* button text

* center

* fix svg

* padding

* smaller gap

* render channel on any message changes etc

* fixes

* atomic file updates, escape attributes

* fix tests

* more tests

* more efficient rendering

* improve security

* sanitize links, include mentioned members

* schema

* fixes

* improve rendering

* fix showing correct subscribers count

* fix member names

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny
2026-06-16 14:36:55 +01:00
committed by GitHub
co-authored by Evgeny @ SimpleX Chat
parent 43904dd0dc
commit adb3fb8cb2
42 changed files with 3234 additions and 175 deletions
+41
View File
@@ -39,6 +39,7 @@ import Data.Char (ord)
import Data.Int (Int64)
import Data.List.NonEmpty (NonEmpty)
import Data.Map.Strict (Map)
import Data.Set (Set)
import qualified Data.Map.Strict as M
import Data.Maybe (fromMaybe)
import Data.String
@@ -162,6 +163,7 @@ data ChatConfig = ChatConfig
ciExpirationInterval :: Int64, -- microseconds
deliveryWorkerDelay :: Int64, -- microseconds
deliveryBucketSize :: Int,
webPreviewConfig :: Maybe WebPreviewConfig,
channelSubscriberRole :: GroupMemberRole, -- TODO [relays] starting role should be communicated in protocol from owner to relays
relayChecksInterval :: NominalDiffTime,
relayInactiveTTL :: NominalDiffTime,
@@ -173,6 +175,43 @@ data ChatConfig = ChatConfig
chatHooks :: ChatHooks
}
data WebPreviewConfig = WebPreviewConfig
{ webDomain :: Text,
webJsonDir :: FilePath,
webCorsFile :: Maybe FilePath,
webUpdateInterval :: Int, -- seconds
webPreviewItemCount :: Int
}
data PublishableGroup = PublishableGroup
{ pgFileName :: FilePath,
pgCorsEntry :: Maybe (Text, CorsOrigin)
}
data CorsOrigin = CorsAny | CorsOrigins [Text]
deriving (Show)
data WebPreviewState = WebPreviewState
{ publishableGroupIds :: TVar (Map Int64 PublishableGroup),
priorityRender :: TQueue Int64,
filesToRemove :: TQueue FilePath,
corsNeeded :: TVar Bool,
routinePending :: TVar (Set Int64),
wakeSignal :: TMVar (),
webPreviewWorkerAsync :: TVar (Maybe (Async ()))
}
newWebPreviewState :: IO WebPreviewState
newWebPreviewState = do
publishableGroupIds <- newTVarIO mempty
priorityRender <- newTQueueIO
filesToRemove <- newTQueueIO
corsNeeded <- newTVarIO False
routinePending <- newTVarIO mempty
wakeSignal <- newEmptyTMVarIO
webPreviewWorkerAsync <- newTVarIO Nothing
pure WebPreviewState {publishableGroupIds, priorityRender, filesToRemove, corsNeeded, routinePending, wakeSignal, webPreviewWorkerAsync}
-- | Builds the read-only context threaded through store functions from chat config.
-- The single construction point, so new store-wide config (e.g. server keys) is added in one place.
mkStoreCxt :: ChatConfig -> StoreCxt
@@ -266,6 +305,7 @@ data ChatController = ChatController
deliveryJobWorkers :: TMap DeliveryWorkerKey Worker,
relayRequestWorkers :: TMap Int Worker, -- single global worker with key 1 is used to fit into existing worker management framework
relayGroupLinkChecksAsync :: TVar (Maybe (Async ())),
webPreviewState :: Maybe WebPreviewState,
chatRelayTests :: TMap ConnId RelayTest,
expireCIThreads :: TMap UserId (Maybe (Async ())),
expireCIFlags :: TMap UserId Bool,
@@ -555,6 +595,7 @@ data ChatCommand
| ShowGroupProfile GroupName
| UpdateGroupDescription GroupName (Maybe Text)
| ShowGroupDescription GroupName
| SetPublicGroupAccess GroupName PublicGroupAccess
| CreateGroupLink GroupName GroupMemberRole
| GroupLinkMemberRole GroupName GroupMemberRole
| DeleteGroupLink GroupName