Skip to content

Commit dc2921e

Browse files
xftp-server: embed file download widget in XFTP server web page (#1733)
* xftp-server: embed file download widget in XFTP server web page When a URL has a hash fragment (>50 chars), the server page shows the file download UI instead of the server info page. Embeds xftp-web assets (JS, CSS, crypto worker) and protocol overlay with matching website content. Overlay renders below the server navbar. * xftp-server: fix overlay scroll lock, remove extra margin, fix dark SVG * xftp-server: move file transfer widget to standalone /file page * web: collapse all repeated Nothing sections in render section_ only collapsed the first occurrence of a section when content was Nothing, leaving subsequent sections with the same label intact. This caused SMP server pages to show raw <x-xftpConfig> tags. * xftp-server: update bundled css/js * xftp-server: move file.html to xftp-server, rename xftp bundle dir * web: remove unused server-info wrapper div * refactor * fix --------- Co-authored-by: Evgeny <evgeny@poberezkin.com>
1 parent 5a32e72 commit dc2921e

File tree

11 files changed

+13564
-5
lines changed

11 files changed

+13564
-5
lines changed

apps/common/Web/static/index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@
105105
class="text-[16px] leading-[26px] tracking-[0.01em] nav-link-text text-black dark:text-white before:bg-black dark:before:bg-white">Server
106106
information</span></a>
107107
</li>
108+
<x-xftpConfig>
109+
<li class="nav-link relative"><a href="/file"
110+
class="flex items-center justify-between gap-2 lg:py-5 whitespace-nowrap"><span
111+
class="text-[16px] leading-[26px] tracking-[0.01em] nav-link-text text-black dark:text-white before:bg-black dark:before:bg-white">File
112+
transfer</span></a>
113+
</li>
114+
</x-xftpConfig>
108115
</ul><a target="_blank" href="https://github.com/simplex-chat/simplex-chat#help-us-with-donations"
109116
class="whitespace-nowrap flex items-center gap-1 self-center text-white dark:text-black text-[16px] font-medium tracking-[0.02em] rounded-[34px] bg-primary-light dark:bg-primary-dark py-3 lg:py-2 px-20 lg:px-5 mb-16 lg:mb-0">Donate</a>
110117
</div>

apps/xftp-server/XFTPWeb.hs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
{-# LANGUAGE NamedFieldPuns #-}
22
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE TemplateHaskell #-}
34

45
module XFTPWeb
56
( xftpGenerateSite,
67
xftpServerInformation,
78
) where
89

10+
import Control.Monad (forM_)
11+
import qualified Data.ByteString.Char8 as B
912
import Data.ByteString (ByteString)
13+
import Data.FileEmbed (embedDir, embedFile)
1014
import Data.Maybe (isJust)
1115
import Data.String (fromString)
1216
import Web.Embedded (embeddedContent)
@@ -18,15 +22,41 @@ import Simplex.Messaging.Server.Main (simplexmqSource)
1822
import qualified Simplex.Messaging.Server.Web as Web
1923
import Simplex.Messaging.Server.Web (render, serverInfoSubsts, timedTTLText)
2024
import Simplex.Messaging.Transport.Client (TransportHost (..))
25+
import System.Directory (createDirectoryIfMissing)
26+
import System.FilePath ((</>))
27+
28+
xftpWebContent :: [(FilePath, ByteString)]
29+
xftpWebContent = $(embedDir "apps/xftp-server/static/xftp-web-bundle/")
30+
31+
xftpMediaContent :: [(FilePath, ByteString)]
32+
xftpMediaContent = $(embedDir "apps/xftp-server/static/media/")
33+
34+
xftpFilePageHtml :: ByteString
35+
xftpFilePageHtml = $(embedFile "apps/xftp-server/static/file.html")
2136

2237
xftpGenerateSite :: XFTPServerConfig -> Maybe ServerPublicInfo -> Maybe TransportHost -> FilePath -> IO ()
23-
xftpGenerateSite cfg info onionHost path =
24-
Web.generateSite embeddedContent (xftpServerInformation cfg info onionHost) [] path
38+
xftpGenerateSite cfg info onionHost path = do
39+
let substs = xftpSubsts cfg info onionHost
40+
Web.generateSite embeddedContent (render (Web.indexHtml embeddedContent) substs) [] path
41+
let xftpDir = path </> "xftp-web-bundle"
42+
mediaDir = path </> "media"
43+
fileDir = path </> "file"
44+
filePage xftpDir xftpWebContent
45+
filePage mediaDir xftpMediaContent
46+
createDirectoryIfMissing True fileDir
47+
B.writeFile (fileDir </> "index.html") $ render xftpFilePageHtml substs
48+
where
49+
filePage dir content_ = do
50+
createDirectoryIfMissing True dir
51+
forM_ content_ $ \(fp, content) -> B.writeFile (dir </> fp) content
2552

2653
xftpServerInformation :: XFTPServerConfig -> Maybe ServerPublicInfo -> Maybe TransportHost -> ByteString
27-
xftpServerInformation XFTPServerConfig {fileExpiration, logStatsInterval, allowNewFiles, newFileBasicAuth} information onionHost = render (Web.indexHtml embeddedContent) substs
54+
xftpServerInformation cfg info onionHost = render (Web.indexHtml embeddedContent) (xftpSubsts cfg info onionHost)
55+
56+
xftpSubsts :: XFTPServerConfig -> Maybe ServerPublicInfo -> Maybe TransportHost -> [(ByteString, Maybe ByteString)]
57+
xftpSubsts XFTPServerConfig {fileExpiration, logStatsInterval, allowNewFiles, newFileBasicAuth} information onionHost =
58+
[("smpConfig", Nothing), ("xftpConfig", Just "y")] <> substConfig <> serverInfoSubsts simplexmqSource information <> [("onionHost", strEncode <$> onionHost), ("iniFileName", Just "file-server.ini")]
2859
where
29-
substs = [("smpConfig", Nothing), ("xftpConfig", Just "y")] <> substConfig <> serverInfoSubsts simplexmqSource information <> [("onionHost", strEncode <$> onionHost), ("iniFileName", Just "file-server.ini")]
3060
substConfig =
3161
[ ("fileExpiration", Just $ maybe "Never" (fromString . timedTTLText . ttl) fileExpiration),
3262
("statsEnabled", Just . yesNo $ isJust logStatsInterval),

0 commit comments

Comments
 (0)