koishi-plugin-kkk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/LICENSE +674 -0
- package/README.md +98 -0
- package/assets/web/assets/CronEditor-CYgFpX-g.js +1 -0
- package/assets/web/assets/DesktopLayout-iI43ij11.js +1 -0
- package/assets/web/assets/MobileLayout-CziU8MCR.js +1 -0
- package/assets/web/assets/ThemeSwitch-DFohhwd9.js +1 -0
- package/assets/web/assets/index-BRROK0vh.js +47 -0
- package/assets/web/assets/index-Dj-StEiS.css +2 -0
- package/assets/web/assets/separator-CxcFlCzz.js +1 -0
- package/assets/web/favicon.svg +1 -0
- package/assets/web/icons.svg +24 -0
- package/assets/web/index.html +15 -0
- package/assets/webui.html +115 -0
- package/client/index.ts +63 -0
- package/config/default_config/app.yaml +64 -0
- package/config/default_config/bilibili.yaml +116 -0
- package/config/default_config/config.json +157 -0
- package/config/default_config/cookies.yaml +11 -0
- package/config/default_config/douyin.yaml +99 -0
- package/config/default_config/kuaishou.yaml +8 -0
- package/config/default_config/pushlist.yaml +37 -0
- package/config/default_config/request.yaml +22 -0
- package/config/default_config/upload.yaml +50 -0
- package/config/default_config/xiaohongshu.yaml +23 -0
- package/dist/index.js +1 -0
- package/lib/compat/axios.js +23 -0
- package/lib/compat/cron.js +77 -0
- package/lib/compat/esm.js +15 -0
- package/lib/compat/express.js +23 -0
- package/lib/compat/heroui.js +12 -0
- package/lib/compat/lodash.js +33 -0
- package/lib/compat/logger.js +118 -0
- package/lib/compat/node-karin.js +1053 -0
- package/lib/compat/phosphor-icons.js +27 -0
- package/lib/compat/qqcard.js +256 -0
- package/lib/compat/root.js +44 -0
- package/lib/compat/runtime.js +87 -0
- package/lib/compat/segment.js +167 -0
- package/lib/compat/sqlite3.js +117 -0
- package/lib/compat/start.js +7 -0
- package/lib/compat/syncConfig.js +65 -0
- package/lib/compat/template-react.js +30 -0
- package/lib/compat/text.js +65 -0
- package/lib/compat/yaml.js +13 -0
- package/lib/configBridge.js +91 -0
- package/lib/index.js +775 -0
- package/lib/karin/app.js +34 -0
- package/lib/karin/apps/__ready.js +9 -0
- package/lib/karin/apps/admin.js +136 -0
- package/lib/karin/apps/help.js +233 -0
- package/lib/karin/apps/push.js +291 -0
- package/lib/karin/apps/qrlogin.js +176 -0
- package/lib/karin/apps/statistics.js +209 -0
- package/lib/karin/apps/testPush.js +247 -0
- package/lib/karin/apps/tools.js +473 -0
- package/lib/karin/apps/update.js +252 -0
- package/lib/karin/index.js +37 -0
- package/lib/karin/module/db/bilibili.js +831 -0
- package/lib/karin/module/db/douyin.js +918 -0
- package/lib/karin/module/db/index.js +165 -0
- package/lib/karin/module/db/migration.js +199 -0
- package/lib/karin/module/db/statistics.js +559 -0
- package/lib/karin/module/index.js +94 -0
- package/lib/karin/module/server/constants/routes.js +48 -0
- package/lib/karin/module/server/controllers/bots.js +230 -0
- package/lib/karin/module/server/controllers/config.js +75 -0
- package/lib/karin/module/server/controllers/video.js +208 -0
- package/lib/karin/module/server/index.js +26 -0
- package/lib/karin/module/server/middlewares/auth.js +133 -0
- package/lib/karin/module/server/routes/amagi.js +57 -0
- package/lib/karin/module/server/routes/api.js +40 -0
- package/lib/karin/module/server/routes/index.js +97 -0
- package/lib/karin/module/server/routes/ssr.js +16 -0
- package/lib/karin/module/server/routes/static.js +43 -0
- package/lib/karin/module/utils/Base.js +403 -0
- package/lib/karin/module/utils/CardParser.js +487 -0
- package/lib/karin/module/utils/Common.js +418 -0
- package/lib/karin/module/utils/Config.js +434 -0
- package/lib/karin/module/utils/EmojiReaction.js +242 -0
- package/lib/karin/module/utils/ErrorHandler/handler.js +114 -0
- package/lib/karin/module/utils/ErrorHandler/index.js +55 -0
- package/lib/karin/module/utils/ErrorHandler/render.js +182 -0
- package/lib/karin/module/utils/ErrorHandler/sender.js +206 -0
- package/lib/karin/module/utils/ErrorHandler/strategy.js +41 -0
- package/lib/karin/module/utils/ErrorHandler/types.js +2 -0
- package/lib/karin/module/utils/ErrorHandler/utils.js +108 -0
- package/lib/karin/module/utils/FFmpeg.js +298 -0
- package/lib/karin/module/utils/ImageHelper.js +91 -0
- package/lib/karin/module/utils/ImageSlice.js +429 -0
- package/lib/karin/module/utils/MotionPhoto.js +250 -0
- package/lib/karin/module/utils/Network/Downloader.js +413 -0
- package/lib/karin/module/utils/Network/ImageDownloader.js +250 -0
- package/lib/karin/module/utils/Network/Network.js +332 -0
- package/lib/karin/module/utils/Network/ThrottleStream.js +71 -0
- package/lib/karin/module/utils/Network/constants.js +129 -0
- package/lib/karin/module/utils/Network/helpers.js +174 -0
- package/lib/karin/module/utils/Network/index.js +34 -0
- package/lib/karin/module/utils/Network/types.js +12 -0
- package/lib/karin/module/utils/Networks.js +17 -0
- package/lib/karin/module/utils/ParseLock.js +34 -0
- package/lib/karin/module/utils/ParseOverride.js +88 -0
- package/lib/karin/module/utils/QqCardResolve.js +114 -0
- package/lib/karin/module/utils/QqPanel.js +879 -0
- package/lib/karin/module/utils/Render/coverTheme.js +256 -0
- package/lib/karin/module/utils/Render/index.js +582 -0
- package/lib/karin/module/utils/amagiClient.js +338 -0
- package/lib/karin/module/utils/avatar.js +201 -0
- package/lib/karin/module/utils/bot.js +141 -0
- package/lib/karin/module/utils/build-metadata.js +50 -0
- package/lib/karin/module/utils/changelog.js +166 -0
- package/lib/karin/module/utils/index.js +26 -0
- package/lib/karin/module/utils/loginSession.js +259 -0
- package/lib/karin/module/utils/parseTip.js +93 -0
- package/lib/karin/module/utils/runtime-report.js +140 -0
- package/lib/karin/module/utils/semver.js +72 -0
- package/lib/karin/module/utils/statisticsAggregate.js +415 -0
- package/lib/karin/platform/bilibili/bilibili.js +1805 -0
- package/lib/karin/platform/bilibili/comments.js +294 -0
- package/lib/karin/platform/bilibili/danmaku.js +555 -0
- package/lib/karin/platform/bilibili/dynamic-text.js +827 -0
- package/lib/karin/platform/bilibili/genParams.js +37 -0
- package/lib/karin/platform/bilibili/getID.js +159 -0
- package/lib/karin/platform/bilibili/index.js +24 -0
- package/lib/karin/platform/bilibili/live-status.js +40 -0
- package/lib/karin/platform/bilibili/login.js +132 -0
- package/lib/karin/platform/bilibili/push.js +1397 -0
- package/lib/karin/platform/bilibili/riskControl.js +133 -0
- package/lib/karin/platform/bilibili/search.js +299 -0
- package/lib/karin/platform/common/danmaku-types.js +12 -0
- package/lib/karin/platform/douyin/comments.js +310 -0
- package/lib/karin/platform/douyin/danmaku.js +893 -0
- package/lib/karin/platform/douyin/douyin.js +1145 -0
- package/lib/karin/platform/douyin/getID.js +94 -0
- package/lib/karin/platform/douyin/index.js +24 -0
- package/lib/karin/platform/douyin/login.js +230 -0
- package/lib/karin/platform/douyin/push/favorite.js +75 -0
- package/lib/karin/platform/douyin/push/index.js +21 -0
- package/lib/karin/platform/douyin/push/live.js +69 -0
- package/lib/karin/platform/douyin/push/post.js +60 -0
- package/lib/karin/platform/douyin/push/recommend.js +74 -0
- package/lib/karin/platform/douyin/push/render.js +621 -0
- package/lib/karin/platform/douyin/push/types.js +2 -0
- package/lib/karin/platform/douyin/push.js +1128 -0
- package/lib/karin/platform/douyin/types.js +13 -0
- package/lib/karin/platform/douyin/videoQuality.js +222 -0
- package/lib/karin/platform/douyin/workType.js +182 -0
- package/lib/karin/platform/index.js +20 -0
- package/lib/karin/platform/kuaishou/comments.js +91 -0
- package/lib/karin/platform/kuaishou/getID.js +43 -0
- package/lib/karin/platform/kuaishou/getdata.js +41 -0
- package/lib/karin/platform/kuaishou/index.js +20 -0
- package/lib/karin/platform/kuaishou/kuaishou.js +122 -0
- package/lib/karin/platform/xiaohongshu/comments.js +162 -0
- package/lib/karin/platform/xiaohongshu/getID.js +129 -0
- package/lib/karin/platform/xiaohongshu/index.js +18 -0
- package/lib/karin/platform/xiaohongshu/xiaohongshu.js +643 -0
- package/lib/karin/root.js +73 -0
- package/lib/karin/setup.js +99 -0
- package/lib/karin/types/config/amagi.js +2 -0
- package/lib/karin/types/config/app.js +2 -0
- package/lib/karin/types/config/bilibili.js +2 -0
- package/lib/karin/types/config/cookies.js +2 -0
- package/lib/karin/types/config/douyin.js +2 -0
- package/lib/karin/types/config/index.js +2 -0
- package/lib/karin/types/config/kuaishou.js +2 -0
- package/lib/karin/types/config/pushlist.js +2 -0
- package/lib/karin/types/config/request.js +2 -0
- package/lib/karin/types/config/upload.js +2 -0
- package/lib/karin/types/config/xiaohongshu.js +2 -0
- package/lib/karin/types/datatypes.js +2 -0
- package/lib/karin/types/index.js +18 -0
- package/lib/karin/types/netrorks/NetworksConfigType.js +2 -0
- package/lib/karin/types/netrorks/index.js +17 -0
- package/lib/karin/web.config.js +49 -0
- package/lib/ktr/registry.js +82 -0
- package/lib/ktr/template/_preview/components/PreviewInfoCard.js +10 -0
- package/lib/ktr/template/_preview/components/PreviewLayout.js +10 -0
- package/lib/ktr/template/_preview/components/PreviewVideoCard.js +8 -0
- package/lib/ktr/template/_preview/render.js +142 -0
- package/lib/ktr/template/_preview/types.js +2 -0
- package/lib/ktr/template/_preview/utils/status.js +31 -0
- package/lib/ktr/template/_preview/utils/time.js +12 -0
- package/lib/ktr/template/bilibili/bangumi/components/bangumi.js +127 -0
- package/lib/ktr/template/bilibili/bangumi/components/types.js +2 -0
- package/lib/ktr/template/bilibili/bangumi/index.js +12 -0
- package/lib/ktr/template/bilibili/comment/components/Comment.js +193 -0
- package/lib/ktr/template/bilibili/comment/components/types.js +2 -0
- package/lib/ktr/template/bilibili/comment/index.js +10 -0
- package/lib/ktr/template/bilibili/components/Icons.js +66 -0
- package/lib/ktr/template/bilibili/components/shared.js +93 -0
- package/lib/ktr/template/bilibili/components/types.js +2 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/DYNAMIC_TYPE_ARTICLE.js +66 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/types.js +2 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/index.js +10 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/DYNAMIC_TYPE_AV.js +87 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/types.js +2 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/index.js +10 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/DYNAMIC_TYPE_DRAW.js +93 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/types.js +2 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/index.js +10 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/DYNAMIC_TYPE_FORWARD.js +132 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/types.js +2 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/index.js +10 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/DYNAMIC_TYPE_LIVE_RCMD.js +84 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/types.js +2 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/index.js +10 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/DYNAMIC_TYPE_WORD.js +38 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/types.js +2 -0
- package/lib/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/index.js +10 -0
- package/lib/ktr/template/bilibili/dynamic/components/AdditionalCard.js +59 -0
- package/lib/ktr/template/bilibili/dynamic/components/CommonComponents.js +30 -0
- package/lib/ktr/template/bilibili/dynamic/types.js +2 -0
- package/lib/ktr/template/bilibili/qrcodeImg/components/qrcodeImg.js +48 -0
- package/lib/ktr/template/bilibili/qrcodeImg/components/types.js +3 -0
- package/lib/ktr/template/bilibili/qrcodeImg/index.js +10 -0
- package/lib/ktr/template/bilibili/userlist/components/UserList.js +53 -0
- package/lib/ktr/template/bilibili/userlist/components/types.js +3 -0
- package/lib/ktr/template/bilibili/userlist/index.js +13 -0
- package/lib/ktr/template/bilibili/videoInfo/components/types.js +2 -0
- package/lib/ktr/template/bilibili/videoInfo/components/videoInfo.js +62 -0
- package/lib/ktr/template/bilibili/videoInfo/index.js +10 -0
- package/lib/ktr/template/components/AmbientCover.js +36 -0
- package/lib/ktr/template/components/DefaultLayout.js +33 -0
- package/lib/ktr/template/components/GlowImage.js +276 -0
- package/lib/ktr/template/components/QRCodeWithAvatar.js +34 -0
- package/lib/ktr/template/components/RolldownLogo.js +6 -0
- package/lib/ktr/template/components/ViteLogo.js +6 -0
- package/lib/ktr/template/components/iconRegistry.js +173 -0
- package/lib/ktr/template/douyin/article-work/components/ArticleWork.js +99 -0
- package/lib/ktr/template/douyin/article-work/components/types.js +3 -0
- package/lib/ktr/template/douyin/article-work/index.js +10 -0
- package/lib/ktr/template/douyin/comment/components/Comment.js +189 -0
- package/lib/ktr/template/douyin/comment/components/types.js +2 -0
- package/lib/ktr/template/douyin/comment/index.js +10 -0
- package/lib/ktr/template/douyin/components/Icons.js +29 -0
- package/lib/ktr/template/douyin/components/types.js +3 -0
- package/lib/ktr/template/douyin/dynamic/components/Dynamic.js +90 -0
- package/lib/ktr/template/douyin/dynamic/components/types.js +3 -0
- package/lib/ktr/template/douyin/dynamic/index.js +10 -0
- package/lib/ktr/template/douyin/favorite-list/components/FavoriteList.js +30 -0
- package/lib/ktr/template/douyin/favorite-list/components/types.js +3 -0
- package/lib/ktr/template/douyin/favorite-list/index.js +10 -0
- package/lib/ktr/template/douyin/image-work/components/ImageWork.js +136 -0
- package/lib/ktr/template/douyin/image-work/components/types.js +2 -0
- package/lib/ktr/template/douyin/image-work/index.js +10 -0
- package/lib/ktr/template/douyin/live/components/Live.js +51 -0
- package/lib/ktr/template/douyin/live/components/types.js +3 -0
- package/lib/ktr/template/douyin/live/index.js +10 -0
- package/lib/ktr/template/douyin/musicinfo/components/MusicInfo.js +60 -0
- package/lib/ktr/template/douyin/musicinfo/components/types.js +3 -0
- package/lib/ktr/template/douyin/musicinfo/index.js +10 -0
- package/lib/ktr/template/douyin/qrcodeImg/components/qrcodeImg.js +39 -0
- package/lib/ktr/template/douyin/qrcodeImg/components/types.js +3 -0
- package/lib/ktr/template/douyin/qrcodeImg/index.js +9 -0
- package/lib/ktr/template/douyin/recommend-list/components/RecommendList.js +30 -0
- package/lib/ktr/template/douyin/recommend-list/components/types.js +3 -0
- package/lib/ktr/template/douyin/recommend-list/index.js +10 -0
- package/lib/ktr/template/douyin/user_profile/components/UserVideoList.js +54 -0
- package/lib/ktr/template/douyin/user_profile/components/types.js +3 -0
- package/lib/ktr/template/douyin/user_profile/index.js +9 -0
- package/lib/ktr/template/douyin/userlist/components/UserList.js +50 -0
- package/lib/ktr/template/douyin/userlist/components/types.js +3 -0
- package/lib/ktr/template/douyin/userlist/index.js +13 -0
- package/lib/ktr/template/douyin/video-work/components/VideoWork.js +127 -0
- package/lib/ktr/template/douyin/video-work/components/types.js +2 -0
- package/lib/ktr/template/douyin/video-work/index.js +10 -0
- package/lib/ktr/template/kuaishou/comment/components/Comment.js +88 -0
- package/lib/ktr/template/kuaishou/comment/components/types.js +2 -0
- package/lib/ktr/template/kuaishou/comment/index.js +10 -0
- package/lib/ktr/template/other/changelog/components/changelog.js +117 -0
- package/lib/ktr/template/other/changelog/components/types.js +3 -0
- package/lib/ktr/template/other/changelog/index.js +9 -0
- package/lib/ktr/template/other/handlerError/components/errorTitles.js +227 -0
- package/lib/ktr/template/other/handlerError/components/handlerError.js +392 -0
- package/lib/ktr/template/other/handlerError/components/stackHighlight.js +109 -0
- package/lib/ktr/template/other/handlerError/components/types.js +2 -0
- package/lib/ktr/template/other/handlerError/index.js +9 -0
- package/lib/ktr/template/other/help/components/Help.js +79 -0
- package/lib/ktr/template/other/help/components/types.js +3 -0
- package/lib/ktr/template/other/help/index.js +12 -0
- package/lib/ktr/template/other/live-photo-tip/components/LivePhotoTip.js +80 -0
- package/lib/ktr/template/other/live-photo-tip/components/types.js +3 -0
- package/lib/ktr/template/other/live-photo-tip/index.js +9 -0
- package/lib/ktr/template/other/qrlogin/components/qrlogin.js +58 -0
- package/lib/ktr/template/other/qrlogin/components/types.js +3 -0
- package/lib/ktr/template/other/qrlogin/index.js +9 -0
- package/lib/ktr/template/other/runtime/components/runtime.js +101 -0
- package/lib/ktr/template/other/runtime/components/types.js +3 -0
- package/lib/ktr/template/other/runtime/index.js +9 -0
- package/lib/ktr/template/other/version_warning/components/VersionWarning.js +38 -0
- package/lib/ktr/template/other/version_warning/components/types.js +3 -0
- package/lib/ktr/template/other/version_warning/index.js +9 -0
- package/lib/ktr/template/statistics/components/BoxplotGuide.js +17 -0
- package/lib/ktr/template/statistics/components/ChartCard.js +15 -0
- package/lib/ktr/template/statistics/components/KpiCard.js +14 -0
- package/lib/ktr/template/statistics/components/PlatformTable.js +20 -0
- package/lib/ktr/template/statistics/components/RankList.js +61 -0
- package/lib/ktr/template/statistics/components/SSRChart.js +22 -0
- package/lib/ktr/template/statistics/components/chartPresets.js +630 -0
- package/lib/ktr/template/statistics/components/chartTheme.js +226 -0
- package/lib/ktr/template/statistics/components/format.js +38 -0
- package/lib/ktr/template/statistics/components/types.js +9 -0
- package/lib/ktr/template/statistics/global/components/GlobalStatistics.js +246 -0
- package/lib/ktr/template/statistics/global/components/types.js +3 -0
- package/lib/ktr/template/statistics/global/index.js +9 -0
- package/lib/ktr/template/statistics/group/components/GroupStatistics.js +181 -0
- package/lib/ktr/template/statistics/group/components/types.js +3 -0
- package/lib/ktr/template/statistics/group/index.js +9 -0
- package/lib/ktr/template/types/ctx.js +2 -0
- package/lib/ktr/template/xiaohongshu/comment/components/Comment.js +99 -0
- package/lib/ktr/template/xiaohongshu/comment/components/types.js +3 -0
- package/lib/ktr/template/xiaohongshu/comment/index.js +9 -0
- package/lib/ktr/template/xiaohongshu/noteInfo/components/noteInfo.js +93 -0
- package/lib/ktr/template/xiaohongshu/noteInfo/components/types.js +2 -0
- package/lib/ktr/template/xiaohongshu/noteInfo/index.js +9 -0
- package/lib/ktr/utils/QRCodeAvatar.js +99 -0
- package/lib/ktr/utils/QRcode.js +56 -0
- package/lib/ktr/utils/avatarProxy.js +45 -0
- package/lib/ktr/utils/cn.js +11 -0
- package/lib/ktr/utils/theme.js +12 -0
- package/lib/qqFields.json +75 -0
- package/lib/qqOptions.js +44 -0
- package/lib/richtext/index.js +25 -0
- package/lib/richtext/parse/index.js +232 -0
- package/lib/richtext/react/cn.js +11 -0
- package/lib/richtext/react/index.js +221 -0
- package/lib/richtext/types.js +2 -0
- package/lib/schema.js +352 -0
- package/lib/webui.js +341 -0
- package/package.json +88 -0
- package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_BV.svg +1 -0
- package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_GOODS.svg +1 -0
- package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_LOTTERY.svg +1 -0
- package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_VIEW_PICTURE.svg +1 -0
- package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_VOTE.svg +1 -0
- package/resources/image/bilibili/RICH_TEXT_NODE_TYPE/RICH_TEXT_NODE_TYPE_WEB.svg +1 -0
- package/resources/image/bilibili/bilibili-dark.png +0 -0
- package/resources/image/bilibili/bilibili-light.png +0 -0
- package/resources/image/bilibili/bilibili.png +0 -0
- package/resources/image/bilibili/id-dark.svg +1 -0
- package/resources/image/bilibili/id-light.svg +1 -0
- package/resources/image/bilibili/level/lv0.svg +1 -0
- package/resources/image/bilibili/level/lv1.svg +1 -0
- package/resources/image/bilibili/level/lv2.svg +1 -0
- package/resources/image/bilibili/level/lv3.svg +1 -0
- package/resources/image/bilibili/level/lv4.svg +1 -0
- package/resources/image/bilibili/level/lv5.svg +1 -0
- package/resources/image/bilibili/level/lv6.svg +1 -0
- package/resources/image/bilibili/level/lv7.svg +1 -0
- package/resources/image/bilibili/like-dark.svg +6 -0
- package/resources/image/bilibili/like-light.svg +6 -0
- package/resources/image/bilibili/play.svg +28 -0
- package/resources/image/bilibili/res-local1.png +0 -0
- package/resources/image/bilibili/up_pb.svg +1 -0
- package/resources/image/bilibili//347/233/264/346/222/255/344/270/255.png +0 -0
- package/resources/image/douyin/douyin.png +0 -0
- package/resources/image/douyin/dylogo-dark.svg +23 -0
- package/resources/image/douyin/dylogo-light.svg +38 -0
- package/resources/image/douyin/search-dark.svg +1 -0
- package/resources/image/douyin/search-light.svg +3 -0
- package/resources/image/douyin//346/212/226/351/237/263-/347/233/264/346/222/255/344/270/255.png +0 -0
- package/resources/image/frame-logo.png +0 -0
- package/resources/image/kuaishou/logo.png +0 -0
- package/resources/image/other/handlerError/Milky.png +0 -0
- package/resources/image/other/handlerError/chronocat.svg +43 -0
- package/resources/image/other/handlerError/conwechat.webp +0 -0
- package/resources/image/other/handlerError/gocq-http.webp +0 -0
- package/resources/image/other/handlerError/lagrange.webp +0 -0
- package/resources/image/other/handlerError/llonebot.webp +0 -0
- package/resources/image/other/handlerError/napcat.webp +0 -0
- package/resources/image/other/handlerError/onebot.png +0 -0
- package/resources/image/other/handlerError/satori.png +0 -0
- package/resources/image/xiaohongshu/logo.png +0 -0
- package/resources/template/style.css +23708 -0
- package/resources/vite.svg +130 -0
- package/scripts/build.mjs +129 -0
- package/scripts/check-schema.cjs +55 -0
- package/scripts/deploy.mjs +78 -0
- package/scripts/make-demo-placeholders.mjs +112 -0
- package/scripts/patch-deps.mjs +46 -0
- package/scripts/patch-webui.mjs +112 -0
- package/scripts/smoke-commands.cjs +39 -0
- package/scripts/smoke-config.cjs +122 -0
- package/scripts/smoke-douyin.cjs +170 -0
- package/scripts/smoke-koishi-commands.cjs +210 -0
- package/scripts/smoke-login.cjs +110 -0
- package/scripts/smoke-parse.cjs +54 -0
- package/scripts/smoke-push-mock.cjs +114 -0
- package/scripts/smoke-push.cjs +104 -0
- package/scripts/smoke-qq.cjs +147 -0
- package/scripts/smoke-qqcard.cjs +108 -0
- package/scripts/smoke-qqpanel.cjs +205 -0
- package/scripts/smoke-render.cjs +106 -0
- package/scripts/smoke-server.cjs +94 -0
- package/src/compat/axios.ts +5 -0
- package/src/compat/cron.ts +86 -0
- package/src/compat/esm.ts +13 -0
- package/src/compat/express.ts +5 -0
- package/src/compat/heroui.tsx +53 -0
- package/src/compat/lodash.ts +32 -0
- package/src/compat/logger.ts +121 -0
- package/src/compat/node-karin.ts +1064 -0
- package/src/compat/phosphor-icons.tsx +25 -0
- package/src/compat/qqcard.ts +251 -0
- package/src/compat/root.ts +44 -0
- package/src/compat/runtime.ts +120 -0
- package/src/compat/segment.ts +161 -0
- package/src/compat/sqlite3.ts +123 -0
- package/src/compat/start.ts +3 -0
- package/src/compat/syncConfig.ts +64 -0
- package/src/compat/template-react.ts +54 -0
- package/src/compat/text.ts +58 -0
- package/src/compat/yaml.ts +6 -0
- package/src/configBridge.ts +94 -0
- package/src/index.ts +769 -0
- package/src/karin/app.ts +1 -0
- package/src/karin/apps/__ready.ts +14 -0
- package/src/karin/apps/admin.ts +127 -0
- package/src/karin/apps/help.ts +228 -0
- package/src/karin/apps/push.ts +327 -0
- package/src/karin/apps/qrlogin.ts +160 -0
- package/src/karin/apps/statistics.ts +203 -0
- package/src/karin/apps/testPush.ts +226 -0
- package/src/karin/apps/tools.ts +510 -0
- package/src/karin/apps/update.ts +239 -0
- package/src/karin/index.ts +9 -0
- package/src/karin/module/db/bilibili.ts +1089 -0
- package/src/karin/module/db/douyin.ts +1218 -0
- package/src/karin/module/db/index.ts +159 -0
- package/src/karin/module/db/migration.ts +249 -0
- package/src/karin/module/db/statistics.ts +817 -0
- package/src/karin/module/index.ts +37 -0
- package/src/karin/module/server/constants/routes.ts +53 -0
- package/src/karin/module/server/controllers/bots.ts +289 -0
- package/src/karin/module/server/controllers/config.ts +85 -0
- package/src/karin/module/server/controllers/video.ts +212 -0
- package/src/karin/module/server/index.ts +11 -0
- package/src/karin/module/server/middlewares/auth.ts +147 -0
- package/src/karin/module/server/routes/amagi.ts +57 -0
- package/src/karin/module/server/routes/api.ts +42 -0
- package/src/karin/module/server/routes/index.ts +68 -0
- package/src/karin/module/server/routes/ssr.ts +14 -0
- package/src/karin/module/server/routes/static.ts +43 -0
- package/src/karin/module/utils/Base.ts +497 -0
- package/src/karin/module/utils/CardParser.ts +503 -0
- package/src/karin/module/utils/Common.ts +448 -0
- package/src/karin/module/utils/Config.ts +443 -0
- package/src/karin/module/utils/EmojiReaction.ts +268 -0
- package/src/karin/module/utils/ErrorHandler/handler.ts +124 -0
- package/src/karin/module/utils/ErrorHandler/index.ts +48 -0
- package/src/karin/module/utils/ErrorHandler/render.ts +180 -0
- package/src/karin/module/utils/ErrorHandler/sender.ts +192 -0
- package/src/karin/module/utils/ErrorHandler/strategy.ts +41 -0
- package/src/karin/module/utils/ErrorHandler/types.ts +122 -0
- package/src/karin/module/utils/ErrorHandler/utils.ts +108 -0
- package/src/karin/module/utils/FFmpeg.ts +357 -0
- package/src/karin/module/utils/ImageHelper.ts +90 -0
- package/src/karin/module/utils/ImageSlice.ts +383 -0
- package/src/karin/module/utils/MotionPhoto.ts +297 -0
- package/src/karin/module/utils/Network/Downloader.ts +481 -0
- package/src/karin/module/utils/Network/ImageDownloader.ts +291 -0
- package/src/karin/module/utils/Network/Network.ts +344 -0
- package/src/karin/module/utils/Network/ThrottleStream.ts +76 -0
- package/src/karin/module/utils/Network/constants.ts +135 -0
- package/src/karin/module/utils/Network/helpers.ts +183 -0
- package/src/karin/module/utils/Network/index.ts +28 -0
- package/src/karin/module/utils/Network/types.ts +46 -0
- package/src/karin/module/utils/Networks.ts +20 -0
- package/src/karin/module/utils/ParseLock.ts +33 -0
- package/src/karin/module/utils/ParseOverride.ts +128 -0
- package/src/karin/module/utils/QqCardResolve.ts +116 -0
- package/src/karin/module/utils/QqPanel.ts +880 -0
- package/src/karin/module/utils/Render/coverTheme.ts +294 -0
- package/src/karin/module/utils/Render/index.ts +574 -0
- package/src/karin/module/utils/amagiClient.ts +368 -0
- package/src/karin/module/utils/avatar.ts +220 -0
- package/src/karin/module/utils/bot.ts +115 -0
- package/src/karin/module/utils/build-metadata.ts +60 -0
- package/src/karin/module/utils/changelog.ts +175 -0
- package/src/karin/module/utils/index.ts +10 -0
- package/src/karin/module/utils/loginSession.ts +291 -0
- package/src/karin/module/utils/parseTip.ts +59 -0
- package/src/karin/module/utils/runtime-report.ts +142 -0
- package/src/karin/module/utils/semver.ts +60 -0
- package/src/karin/module/utils/statisticsAggregate.ts +507 -0
- package/src/karin/platform/bilibili/bilibili.ts +2004 -0
- package/src/karin/platform/bilibili/comments.ts +397 -0
- package/src/karin/platform/bilibili/danmaku.ts +653 -0
- package/src/karin/platform/bilibili/dynamic-text.ts +926 -0
- package/src/karin/platform/bilibili/genParams.ts +30 -0
- package/src/karin/platform/bilibili/getID.ts +163 -0
- package/src/karin/platform/bilibili/index.ts +8 -0
- package/src/karin/platform/bilibili/live-status.ts +36 -0
- package/src/karin/platform/bilibili/login.ts +130 -0
- package/src/karin/platform/bilibili/push.ts +1615 -0
- package/src/karin/platform/bilibili/riskControl.ts +114 -0
- package/src/karin/platform/bilibili/search.ts +305 -0
- package/src/karin/platform/common/danmaku-types.ts +18 -0
- package/src/karin/platform/douyin/comments.ts +404 -0
- package/src/karin/platform/douyin/danmaku.ts +1187 -0
- package/src/karin/platform/douyin/douyin.ts +1244 -0
- package/src/karin/platform/douyin/getID.ts +101 -0
- package/src/karin/platform/douyin/index.ts +8 -0
- package/src/karin/platform/douyin/login.ts +251 -0
- package/src/karin/platform/douyin/push/favorite.ts +97 -0
- package/src/karin/platform/douyin/push/index.ts +5 -0
- package/src/karin/platform/douyin/push/live.ts +86 -0
- package/src/karin/platform/douyin/push/post.ts +75 -0
- package/src/karin/platform/douyin/push/recommend.ts +96 -0
- package/src/karin/platform/douyin/push/render.ts +768 -0
- package/src/karin/platform/douyin/push/types.ts +41 -0
- package/src/karin/platform/douyin/push.ts +1241 -0
- package/src/karin/platform/douyin/types.ts +151 -0
- package/src/karin/platform/douyin/videoQuality.ts +234 -0
- package/src/karin/platform/douyin/workType.ts +238 -0
- package/src/karin/platform/index.ts +4 -0
- package/src/karin/platform/kuaishou/comments.ts +114 -0
- package/src/karin/platform/kuaishou/getID.ts +48 -0
- package/src/karin/platform/kuaishou/getdata.ts +78 -0
- package/src/karin/platform/kuaishou/index.ts +4 -0
- package/src/karin/platform/kuaishou/kuaishou.ts +130 -0
- package/src/karin/platform/xiaohongshu/comments.ts +227 -0
- package/src/karin/platform/xiaohongshu/getID.ts +127 -0
- package/src/karin/platform/xiaohongshu/index.ts +2 -0
- package/src/karin/platform/xiaohongshu/xiaohongshu.ts +733 -0
- package/src/karin/root.ts +78 -0
- package/src/karin/setup.ts +77 -0
- package/src/karin/types/config/amagi.ts +46 -0
- package/src/karin/types/config/app.ts +129 -0
- package/src/karin/types/config/bilibili.ts +121 -0
- package/src/karin/types/config/cookies.ts +11 -0
- package/src/karin/types/config/douyin.ts +93 -0
- package/src/karin/types/config/index.ts +41 -0
- package/src/karin/types/config/kuaishou.ts +10 -0
- package/src/karin/types/config/pushlist.ts +55 -0
- package/src/karin/types/config/request.ts +27 -0
- package/src/karin/types/config/upload.ts +49 -0
- package/src/karin/types/config/xiaohongshu.ts +24 -0
- package/src/karin/types/datatypes.ts +42 -0
- package/src/karin/types/index.ts +4 -0
- package/src/karin/types/netrorks/NetworksConfigType.ts +61 -0
- package/src/karin/types/netrorks/index.ts +1 -0
- package/src/karin/web.config.ts +48 -0
- package/src/ktr/registry.ts +55 -0
- package/src/ktr/template/_preview/components/PreviewInfoCard.tsx +33 -0
- package/src/ktr/template/_preview/components/PreviewLayout.tsx +65 -0
- package/src/ktr/template/_preview/components/PreviewVideoCard.tsx +22 -0
- package/src/ktr/template/_preview/render.ts +158 -0
- package/src/ktr/template/_preview/types.ts +15 -0
- package/src/ktr/template/_preview/utils/status.ts +29 -0
- package/src/ktr/template/_preview/utils/time.ts +8 -0
- package/src/ktr/template/bilibili/bangumi/components/bangumi.tsx +462 -0
- package/src/ktr/template/bilibili/bangumi/components/types.ts +36 -0
- package/src/ktr/template/bilibili/bangumi/index.tsx +9 -0
- package/src/ktr/template/bilibili/comment/components/Comment.tsx +657 -0
- package/src/ktr/template/bilibili/comment/components/types.ts +26 -0
- package/src/ktr/template/bilibili/comment/index.tsx +11 -0
- package/src/ktr/template/bilibili/components/Icons.tsx +209 -0
- package/src/ktr/template/bilibili/components/shared.tsx +162 -0
- package/src/ktr/template/bilibili/components/types.ts +388 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/DYNAMIC_TYPE_ARTICLE.tsx +251 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/components/types.ts +67 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_ARTICLE/index.tsx +12 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/DYNAMIC_TYPE_AV.tsx +238 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/components/types.ts +39 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_AV/index.tsx +12 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/DYNAMIC_TYPE_DRAW.tsx +205 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/components/types.ts +20 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_DRAW/index.tsx +11 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/DYNAMIC_TYPE_FORWARD.tsx +348 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/components/types.ts +16 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_FORWARD/index.tsx +12 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/DYNAMIC_TYPE_LIVE_RCMD.tsx +264 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/components/types.ts +32 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_LIVE_RCMD/index.tsx +12 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/DYNAMIC_TYPE_WORD.tsx +68 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/components/types.ts +14 -0
- package/src/ktr/template/bilibili/dynamic/DYNAMIC_TYPE_WORD/index.tsx +12 -0
- package/src/ktr/template/bilibili/dynamic/components/AdditionalCard.tsx +165 -0
- package/src/ktr/template/bilibili/dynamic/components/CommonComponents.tsx +142 -0
- package/src/ktr/template/bilibili/dynamic/types.ts +382 -0
- package/src/ktr/template/bilibili/qrcodeImg/components/qrcodeImg.tsx +179 -0
- package/src/ktr/template/bilibili/qrcodeImg/components/types.ts +9 -0
- package/src/ktr/template/bilibili/qrcodeImg/index.tsx +12 -0
- package/src/ktr/template/bilibili/userlist/components/UserList.tsx +246 -0
- package/src/ktr/template/bilibili/userlist/components/types.ts +35 -0
- package/src/ktr/template/bilibili/userlist/index.tsx +11 -0
- package/src/ktr/template/bilibili/videoInfo/components/types.ts +28 -0
- package/src/ktr/template/bilibili/videoInfo/components/videoInfo.tsx +217 -0
- package/src/ktr/template/bilibili/videoInfo/index.tsx +12 -0
- package/src/ktr/template/components/AmbientCover.tsx +50 -0
- package/src/ktr/template/components/DefaultLayout.tsx +166 -0
- package/src/ktr/template/components/GlowImage.tsx +572 -0
- package/src/ktr/template/components/QRCodeWithAvatar.tsx +52 -0
- package/src/ktr/template/components/RolldownLogo.tsx +110 -0
- package/src/ktr/template/components/ViteLogo.tsx +134 -0
- package/src/ktr/template/components/iconRegistry.ts +294 -0
- package/src/ktr/template/douyin/article-work/components/ArticleWork.tsx +301 -0
- package/src/ktr/template/douyin/article-work/components/types.ts +53 -0
- package/src/ktr/template/douyin/article-work/index.tsx +12 -0
- package/src/ktr/template/douyin/comment/components/Comment.tsx +612 -0
- package/src/ktr/template/douyin/comment/components/types.ts +85 -0
- package/src/ktr/template/douyin/comment/index.tsx +11 -0
- package/src/ktr/template/douyin/components/Icons.tsx +75 -0
- package/src/ktr/template/douyin/components/types.ts +83 -0
- package/src/ktr/template/douyin/dynamic/components/Dynamic.tsx +283 -0
- package/src/ktr/template/douyin/dynamic/components/types.ts +46 -0
- package/src/ktr/template/douyin/dynamic/index.tsx +11 -0
- package/src/ktr/template/douyin/favorite-list/components/FavoriteList.tsx +201 -0
- package/src/ktr/template/douyin/favorite-list/components/types.ts +38 -0
- package/src/ktr/template/douyin/favorite-list/index.tsx +12 -0
- package/src/ktr/template/douyin/image-work/components/ImageWork.tsx +437 -0
- package/src/ktr/template/douyin/image-work/components/types.ts +78 -0
- package/src/ktr/template/douyin/image-work/index.tsx +11 -0
- package/src/ktr/template/douyin/live/components/Live.tsx +229 -0
- package/src/ktr/template/douyin/live/components/types.ts +47 -0
- package/src/ktr/template/douyin/live/index.tsx +11 -0
- package/src/ktr/template/douyin/musicinfo/components/MusicInfo.tsx +187 -0
- package/src/ktr/template/douyin/musicinfo/components/types.ts +31 -0
- package/src/ktr/template/douyin/musicinfo/index.tsx +11 -0
- package/src/ktr/template/douyin/qrcodeImg/components/qrcodeImg.tsx +170 -0
- package/src/ktr/template/douyin/qrcodeImg/components/types.ts +9 -0
- package/src/ktr/template/douyin/qrcodeImg/index.tsx +9 -0
- package/src/ktr/template/douyin/recommend-list/components/RecommendList.tsx +201 -0
- package/src/ktr/template/douyin/recommend-list/components/types.ts +37 -0
- package/src/ktr/template/douyin/recommend-list/index.tsx +12 -0
- package/src/ktr/template/douyin/user_profile/components/UserVideoList.tsx +225 -0
- package/src/ktr/template/douyin/user_profile/components/types.ts +71 -0
- package/src/ktr/template/douyin/user_profile/index.tsx +9 -0
- package/src/ktr/template/douyin/userlist/components/UserList.tsx +229 -0
- package/src/ktr/template/douyin/userlist/components/types.ts +35 -0
- package/src/ktr/template/douyin/userlist/index.tsx +11 -0
- package/src/ktr/template/douyin/video-work/components/VideoWork.tsx +398 -0
- package/src/ktr/template/douyin/video-work/components/types.ts +80 -0
- package/src/ktr/template/douyin/video-work/index.tsx +11 -0
- package/src/ktr/template/font.css +6071 -0
- package/src/ktr/template/global.d.ts +69 -0
- package/src/ktr/template/kuaishou/comment/components/Comment.tsx +207 -0
- package/src/ktr/template/kuaishou/comment/components/types.ts +47 -0
- package/src/ktr/template/kuaishou/comment/index.tsx +11 -0
- package/src/ktr/template/other/changelog/components/changelog.tsx +411 -0
- package/src/ktr/template/other/changelog/components/types.ts +21 -0
- package/src/ktr/template/other/changelog/index.tsx +9 -0
- package/src/ktr/template/other/handlerError/components/errorTitles.ts +224 -0
- package/src/ktr/template/other/handlerError/components/handlerError.tsx +1076 -0
- package/src/ktr/template/other/handlerError/components/stackHighlight.ts +127 -0
- package/src/ktr/template/other/handlerError/components/types.ts +124 -0
- package/src/ktr/template/other/handlerError/index.tsx +9 -0
- package/src/ktr/template/other/help/components/Help.tsx +249 -0
- package/src/ktr/template/other/help/components/types.ts +47 -0
- package/src/ktr/template/other/help/index.tsx +9 -0
- package/src/ktr/template/other/live-photo-tip/components/LivePhotoTip.tsx +295 -0
- package/src/ktr/template/other/live-photo-tip/components/types.ts +8 -0
- package/src/ktr/template/other/live-photo-tip/index.tsx +9 -0
- package/src/ktr/template/other/qrlogin/components/qrlogin.tsx +295 -0
- package/src/ktr/template/other/qrlogin/components/types.ts +11 -0
- package/src/ktr/template/other/qrlogin/index.tsx +9 -0
- package/src/ktr/template/other/runtime/components/runtime.tsx +347 -0
- package/src/ktr/template/other/runtime/components/types.ts +75 -0
- package/src/ktr/template/other/runtime/index.tsx +9 -0
- package/src/ktr/template/other/version_warning/components/VersionWarning.tsx +392 -0
- package/src/ktr/template/other/version_warning/components/types.ts +8 -0
- package/src/ktr/template/other/version_warning/index.tsx +9 -0
- package/src/ktr/template/statistics/components/BoxplotGuide.tsx +57 -0
- package/src/ktr/template/statistics/components/ChartCard.tsx +40 -0
- package/src/ktr/template/statistics/components/KpiCard.tsx +39 -0
- package/src/ktr/template/statistics/components/PlatformTable.tsx +83 -0
- package/src/ktr/template/statistics/components/RankList.tsx +127 -0
- package/src/ktr/template/statistics/components/SSRChart.tsx +41 -0
- package/src/ktr/template/statistics/components/chartPresets.ts +700 -0
- package/src/ktr/template/statistics/components/chartTheme.ts +234 -0
- package/src/ktr/template/statistics/components/format.ts +33 -0
- package/src/ktr/template/statistics/components/types.ts +92 -0
- package/src/ktr/template/statistics/global/components/GlobalStatistics.tsx +597 -0
- package/src/ktr/template/statistics/global/components/types.ts +138 -0
- package/src/ktr/template/statistics/global/index.tsx +9 -0
- package/src/ktr/template/statistics/group/components/GroupStatistics.tsx +468 -0
- package/src/ktr/template/statistics/group/components/types.ts +113 -0
- package/src/ktr/template/statistics/group/index.tsx +9 -0
- package/src/ktr/template/style.css +65 -0
- package/src/ktr/template/types/ctx.ts +42 -0
- package/src/ktr/template/xiaohongshu/comment/components/Comment.tsx +264 -0
- package/src/ktr/template/xiaohongshu/comment/components/types.ts +119 -0
- package/src/ktr/template/xiaohongshu/comment/index.tsx +9 -0
- package/src/ktr/template/xiaohongshu/noteInfo/components/noteInfo.tsx +271 -0
- package/src/ktr/template/xiaohongshu/noteInfo/components/types.ts +66 -0
- package/src/ktr/template/xiaohongshu/noteInfo/index.tsx +9 -0
- package/src/ktr/utils/QRCodeAvatar.ts +102 -0
- package/src/ktr/utils/QRcode.ts +65 -0
- package/src/ktr/utils/avatarProxy.ts +42 -0
- package/src/ktr/utils/cn.ts +6 -0
- package/src/ktr/utils/theme.ts +10 -0
- package/src/qqFields.json +75 -0
- package/src/qqOptions.ts +64 -0
- package/src/richtext/index.ts +9 -0
- package/src/richtext/parse/index.ts +271 -0
- package/src/richtext/react/cn.ts +6 -0
- package/src/richtext/react/index.tsx +582 -0
- package/src/richtext/types.ts +320 -0
- package/src/schema.ts +372 -0
- package/src/webui.ts +352 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
import React, { type CSSProperties, type ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
import type { RichTextDocument, RichTextInlineStyle, RichTextNode, RichTextRenderOptions } from '../types'
|
|
4
|
+
import { cn } from './cn'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 限制图片来源协议。
|
|
8
|
+
*
|
|
9
|
+
* React 会自动转义文本和属性,但不会替我们判断 URL 协议是否安全,所以这里仍然做白名单。
|
|
10
|
+
*/
|
|
11
|
+
const sanitizeImageSource = (value: string): string | null => {
|
|
12
|
+
const normalized = value.trim()
|
|
13
|
+
if (!normalized) {
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (/^https?:\/\//i.test(normalized)) {
|
|
18
|
+
return normalized
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (/^data:image\/(?:png|jpe?g|gif|webp|avif);base64,[a-z0-9+/=]+$/i.test(normalized)) {
|
|
22
|
+
return normalized
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 富文本表情的默认排版。
|
|
30
|
+
*
|
|
31
|
+
* 这些规则属于 richtext 节点的渲染语义,不应该散落在各个平台模板里:
|
|
32
|
+
* - 表情跟随当前文字大小缩放;
|
|
33
|
+
* - 作为行内内容参与排版;
|
|
34
|
+
* - 不撑破行高,也不突破当前文本块宽度。
|
|
35
|
+
*/
|
|
36
|
+
const getRichTextEmojiStyle = (scale: number = 1): CSSProperties => ({
|
|
37
|
+
display: 'inline-block',
|
|
38
|
+
height: `${1.5 * scale}em`,
|
|
39
|
+
width: 'auto',
|
|
40
|
+
verticalAlign: scale > 1 ? 'text-bottom' : 'middle',
|
|
41
|
+
lineHeight: 1
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
/** 统一的搜索图标,避免 template 每次都自己重复拼 JSX。 */
|
|
45
|
+
const SearchKeywordIcon = ({ className }: { className?: string }) => {
|
|
46
|
+
return (
|
|
47
|
+
<span
|
|
48
|
+
aria-hidden
|
|
49
|
+
className={className}
|
|
50
|
+
style={{
|
|
51
|
+
display: 'inline-flex',
|
|
52
|
+
verticalAlign: 'super',
|
|
53
|
+
marginLeft: '0.08em',
|
|
54
|
+
lineHeight: 1
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
<svg
|
|
58
|
+
viewBox="0 0 24 24"
|
|
59
|
+
width="0.72em"
|
|
60
|
+
height="0.72em"
|
|
61
|
+
fill="none"
|
|
62
|
+
stroke="currentColor"
|
|
63
|
+
strokeWidth={2}
|
|
64
|
+
strokeLinecap="round"
|
|
65
|
+
strokeLinejoin="round"
|
|
66
|
+
>
|
|
67
|
+
<circle cx="11" cy="11" r="7" />
|
|
68
|
+
<path d="m20 20-3.5-3.5" />
|
|
69
|
+
</svg>
|
|
70
|
+
</span>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** 话题图标 */
|
|
75
|
+
const TopicIcon = ({ className }: { className?: string }) => (
|
|
76
|
+
<svg className={cn(className, 'inline-block w-16 mb-4 mr-4 align-middle')} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
|
77
|
+
<path
|
|
78
|
+
d="M5.1911266666666664 0.9880383333333334C4.908345 1.1859883333333332 4.839576666666666 1.5756933333333332 5.0375266666666665 1.8584683333333332L6.109626666666665 3.3900216666666663C6.307576666666667 3.6728033333333334 6.697288333333333 3.7415716666666663 6.980041666666667 3.5436216666666667C7.26285 3.345673333333333 7.3316 2.955966666666666 7.133666666666667 2.6731916666666664L6.061558333333332 1.1416383333333333C5.863613333333333 0.8588566666666666 5.473901666666667 0.7900883333333333 5.1911266666666664 0.9880383333333334z"
|
|
79
|
+
fill="currentColor"
|
|
80
|
+
></path>
|
|
81
|
+
<path
|
|
82
|
+
d="M10.808908333333331 0.9880316666666666C10.52615 0.7900883333333333 10.136408333333332 0.8588566666666666 9.938466666666667 1.1416383333333333L8.866399999999999 2.6731916666666664C8.668458333333334 2.9559716666666667 8.737216666666665 3.345678333333333 9.020024999999999 3.543628333333333C9.302775 3.7415716666666663 9.692466666666666 3.6728033333333334 9.890458333333333 3.3900216666666663L10.962533333333333 1.8584683333333332C11.160466666666665 1.5756883333333334 11.091716666666665 1.1859816666666667 10.808908333333331 0.9880316666666666z"
|
|
83
|
+
fill="currentColor"
|
|
84
|
+
></path>
|
|
85
|
+
<path
|
|
86
|
+
d="M8.388033333333333 8.2152L8.548749999999998 7.036716666666667L7.611974999999999 7.036716666666667L7.45125 8.2152L8.388033333333333 8.2152z"
|
|
87
|
+
fill="currentColor"
|
|
88
|
+
></path>
|
|
89
|
+
<path
|
|
90
|
+
d="M8 2.559733333333333C6.498214999999999 2.559733333333333 5.16768 2.6184066666666665 4.195425 2.678813333333333C2.923148333333333 2.75786 1.9012316666666664 3.7431133333333335 1.8069283333333335 5.026566666666666C1.7538833333333335 5.748475 1.7082533333333334 6.652113333333333 1.7082533333333334 7.626266666666666C1.7082533333333334 8.604275 1.75425 9.504349999999999 1.8075966666666665 10.219908333333333C1.9018333333333333 11.483925 2.899678333333333 12.460316666666666 4.154273333333333 12.551708333333332C5.104525 12.620916666666668 6.4048050000000005 12.688916666666666 7.876416666666666 12.692558333333332C8.379624999999999 13.169883333333333 9.433408333333333 14.084808333333331 10.662975 14.643741666666665C11.005616666666665 14.799541666666666 11.427091666666666 14.859316666666667 11.735999999999999 14.576575C12.039016666666665 14.299274999999998 12.024899999999999 13.881124999999999 11.919241666666666 13.523958333333333C11.811016666666664 13.158316666666666 11.757858333333333 12.821666666666667 11.73155 12.559758333333335C13.013916666666667 12.468349999999997 14.093808333333332 11.543458333333334 14.192449999999997 10.220175C14.245791666666666 9.504874999999998 14.291733333333333 8.604875 14.291733333333333 7.626266666666666C14.291733333333333 6.6514999999999995 14.246125 5.74798 14.193108333333331 5.026299999999999C14.098808333333332 3.7429283333333334 13.076958333333332 2.757873333333333 11.804816666666664 2.6788266666666662C10.832533333333332 2.6184133333333333 9.501883333333334 2.559733333333333 8 2.559733333333333zM6.536343333333332 10.730624999999998C6.226251666666666 10.688316666666665 6.009155 10.402649999999998 6.0514399999999995 10.092558333333333L6.152898333333334 9.348533333333332L5.457055 9.348533333333332C5.144096666666666 9.348533333333332 4.890388333333333 9.094850000000001 4.890388333333333 8.781866666666666C4.890388333333333 8.468933333333332 5.144096666666666 8.2152 5.457055 8.2152L6.307441666666667 8.2152L6.468145 7.036716666666667L5.457055 7.036716666666667C5.144096666666666 7.036716666666667 4.890388333333333 6.783036666666668 4.890388333333333 6.470073333333333C4.890388333333333 6.15711 5.144096666666666 5.903406666666666 5.457055 5.903406666666666L6.6226883333333335 5.903406666666666L6.744933333333333 5.006731666666666C6.787241666666667 4.6966399999999995 7.0729083333333325 4.479536666666666 7.383 4.521823333333333C7.693091666666666 4.564108333333333 7.910191666666667 4.849765 7.867875 5.159858333333333L7.766483333333333 5.903406666666666L8.703325 5.903406666666666L8.825558333333333 5.006731666666666C8.867866666666666 4.6966399999999995 9.153533333333332 4.479536666666666 9.463625 4.521823333333333C9.773716666666667 4.564108333333333 9.990816666666666 4.849765 9.948508333333333 5.159858333333333L9.847116666666667 5.903406666666666L10.542933333333332 5.903406666666666C10.855858333333332 5.903406666666666 11.1096 6.15711 11.1096 6.470073333333333C11.1096 6.783036666666668 10.855858333333332 7.036716666666667 10.542933333333332 7.036716666666667L9.692599999999999 7.036716666666667L9.531875 8.2152L10.542933333333332 8.2152C10.855858333333332 8.2152 11.1096 8.468933333333332 11.1096 8.781866666666666C11.1096 9.094850000000001 10.855858333333332 9.348533333333332 10.542933333333332 9.348533333333332L9.377308333333332 9.348533333333332L9.255008333333333 10.245691666666666C9.212691666666666 10.555783333333332 8.927033333333332 10.772874999999999 8.616941666666666 10.730624999999998C8.306849999999999 10.688316666666665 8.089749999999999 10.402649999999998 8.132058333333333 10.092558333333333L8.233516666666667 9.348533333333332L7.296741666666667 9.348533333333332L7.1743749999999995 10.245691666666666C7.132066666666667 10.555783333333332 6.846406666666667 10.772874999999999 6.536343333333332 10.730624999999998z"
|
|
91
|
+
fill="currentColor"
|
|
92
|
+
></path>
|
|
93
|
+
</svg>
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
/** 抽奖图标 */
|
|
97
|
+
const LotteryIcon = ({ className }: { className?: string }) => (
|
|
98
|
+
<svg className={cn(className, 'inline-block w-16 h-auto mb-4 mr-2 align-middle')} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
|
|
99
|
+
<path
|
|
100
|
+
d="M3.3749775 8.758875C3.6856424999999997 8.758875 3.9374775 9.0106875 3.9374775 9.321375L3.9374775 13.821375C3.9374775 14.3095125 4.33323 14.70525 4.821405 14.70525L13.178550000000001 14.70525C13.666725 14.70525 14.0625 14.3095125 14.0625 13.821375L14.0625 9.321375C14.0625 9.0106875 14.3143125 8.758875 14.625 8.758875C14.93565 8.758875 15.1875 9.0106875 15.1875 9.321375L15.1875 13.821375C15.1875 14.930850000000001 14.2880625 15.83025 13.178550000000001 15.83025L4.821405 15.83025C3.7119074999999997 15.83025 2.8124775 14.930850000000001 2.8124775 13.821375L2.8124775 9.321375C2.8124775 9.0106875 3.0643199999999995 8.758875 3.3749775 8.758875z"
|
|
101
|
+
fill="currentColor"
|
|
102
|
+
></path>
|
|
103
|
+
<path
|
|
104
|
+
d="M2.1696225 6.5892824999999995C2.1696225 5.746065 2.8531875 5.0625 3.696405 5.0625L14.303550000000001 5.0625C15.146774999999998 5.0625 15.830324999999998 5.746065 15.830324999999998 6.5892824999999995L15.830324999999998 8.025825000000001C15.830324999999998 8.768025 15.288825000000001 9.4204875 14.518125000000001 9.4986C13.5663 9.5950875 11.7789375 9.723225 9 9.723225C6.221047499999999 9.723225 4.433669999999999 9.5950875 3.4818525000000005 9.4986C2.711145 9.4204875 2.1696225 8.768025 2.1696225 8.025825000000001L2.1696225 6.5892824999999995zM3.696405 6.1875C3.4745099999999995 6.1875 3.2946225 6.3673875 3.2946225 6.5892824999999995L3.2946225 8.025825000000001C3.2946225 8.221725000000001 3.423675 8.3619375 3.5952824999999997 8.3793375C4.50612 8.4716625 6.255472500000001 8.598225 9 8.598225C11.744512499999999 8.598225 13.493850000000002 8.4716625 14.40465 8.3793375C14.5762875 8.3619375 14.705324999999998 8.221725000000001 14.705324999999998 8.025825000000001L14.705324999999998 6.5892824999999995C14.705324999999998 6.3673875 14.525437499999999 6.1875 14.303550000000001 6.1875L3.696405 6.1875z"
|
|
105
|
+
fill="currentColor"
|
|
106
|
+
></path>
|
|
107
|
+
<path
|
|
108
|
+
d="M4.9017675 4.0179075C4.9017675 2.8196475 5.873145 1.84827 7.071405 1.84827C8.2696875 1.84827 9.241050000000001 2.8196475 9.241050000000001 4.0179075L9.241050000000001 6.187552499999999L7.071405 6.187552499999999C5.873145 6.187552499999999 4.9017675 5.2161675 4.9017675 4.0179075zM7.071405 2.9732700000000003C6.494467500000001 2.9732700000000003 6.0267675 3.44097 6.0267675 4.0179075C6.0267675 4.5948525 6.494467500000001 5.0625525 7.071405 5.0625525L8.116050000000001 5.0625525L8.116050000000001 4.0179075C8.116050000000001 3.44097 7.648350000000001 2.9732700000000003 7.071405 2.9732700000000003z"
|
|
109
|
+
fill="currentColor"
|
|
110
|
+
></path>
|
|
111
|
+
<path
|
|
112
|
+
d="M8.758875 4.0179075C8.758875 2.8196475 9.730274999999999 1.84827 10.928550000000001 1.84827C12.126825 1.84827 13.098225000000001 2.8196475 13.098225000000001 4.0179075C13.098225000000001 5.2161675 12.126825 6.187552499999999 10.928550000000001 6.187552499999999L8.758875 6.187552499999999L8.758875 4.0179075zM10.928550000000001 2.9732700000000003C10.3516125 2.9732700000000003 9.883875 3.44097 9.883875 4.0179075L9.883875 5.0625525L10.928550000000001 5.0625525C11.505487500000001 5.0625525 11.973225 4.5948525 11.973225 4.0179075C11.973225 3.44097 11.505487500000001 2.9732700000000003 10.928550000000001 2.9732700000000003z"
|
|
113
|
+
fill="currentColor"
|
|
114
|
+
></path>
|
|
115
|
+
<path
|
|
116
|
+
d="M9 4.2588525C9.310649999999999 4.2588525 9.5625 4.5106874999999995 9.5625 4.8213525L9.5625 14.78565C9.5625 15.0963 9.310649999999999 15.34815 9 15.34815C8.6893125 15.34815 8.4375 15.0963 8.4375 14.78565L8.4375 4.8213525C8.4375 4.5106874999999995 8.6893125 4.2588525 9 4.2588525z"
|
|
117
|
+
fill="currentColor"
|
|
118
|
+
></path>
|
|
119
|
+
</svg>
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
/** 网页链接图标 */
|
|
123
|
+
const WebLinkIcon = ({ className }: { className?: string }) => (
|
|
124
|
+
<svg className={cn(className, 'inline-block w-14 mb-3 mr-2 align-middle')} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
|
|
125
|
+
<path
|
|
126
|
+
d="M8.614275 6.87951C8.7490125 6.6030750000000005 9.082275 6.4881975 9.358725 6.622927499999999C9.806437500000001 6.7862849999999995 10.2297 7.0488 10.590599999999998 7.409677499999999C12.12825 8.9473875 12.12825 11.440462499999999 10.590599999999998 12.978150000000001L8.734425 14.834325C7.196745 16.3720125 4.7036549999999995 16.3720125 3.1659675 14.834325C1.6282725 13.296637500000001 1.6282725 10.803525 3.1659675 9.2658375L4.5079125 7.923900000000001C4.7275875 7.704224999999999 5.08374 7.704224999999999 5.303415 7.923900000000001C5.5230825 8.143575 5.5230825 8.499712500000001 5.303415 8.7193875L3.9614625 10.061325C2.8631100000000003 11.1597 2.8631100000000003 12.940462499999999 3.9614625 14.0388375C5.0598 15.137175 6.840585 15.137175 7.9389375 14.0388375L9.795075 12.1826625C10.89345 11.084325 10.89345 9.303525 9.795075 8.205187500000001C9.5242125 7.9342875 9.206475 7.7408175 8.8708125 7.623959999999999C8.5944 7.4892375 8.479537500000001 7.155944999999999 8.614275 6.87951z"
|
|
127
|
+
fill="currentColor"
|
|
128
|
+
></path>
|
|
129
|
+
<path
|
|
130
|
+
d="M14.0377875 3.9623775C12.93945 2.8640250000000003 11.1586875 2.8640250000000003 10.0603125 3.9623775L8.204175 5.81853C7.1058225 6.9168825 7.1058225 8.697637499999999 8.204175 9.7960125C8.4579 10.049737499999999 8.753325 10.234425 9.065775 10.3508625C9.338925 10.492275 9.4457625 10.828275 9.304387499999999 11.1013875C9.162975 11.3745375 8.826975 11.481375 8.553862500000001 11.34C8.138175 11.1783 7.745744999999999 10.928550000000001 7.4086725 10.5915C5.870985 9.0538125 5.870985 6.560722499999999 7.4086725 5.023035L9.264825 3.1668825C10.802512499999999 1.6291875 13.2955875 1.6291875 14.833312500000002 3.1668825C16.371 4.70457 16.371 7.197660000000001 14.833312500000002 8.735325L13.549425 10.0192125C13.329787500000002 10.23885 12.973650000000001 10.23885 12.7539375 10.0192125C12.534299999999998 9.7995 12.534299999999998 9.443362500000001 12.7539375 9.2236875L14.0377875 7.939837499999999C15.136125 6.8415 15.136125 5.0607225 14.0377875 3.9623775z"
|
|
131
|
+
fill="currentColor"
|
|
132
|
+
></path>
|
|
133
|
+
</svg>
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
/** 站内图文链接图标 */
|
|
137
|
+
const OpusLinkIcon = ({ className }: { className?: string }) => (
|
|
138
|
+
<svg className={cn(className, 'inline-block w-16 h-auto mb-2 mr-2 align-middle')} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
|
139
|
+
<path
|
|
140
|
+
d="M10 3.124591666666667C8.164908333333335 3.124591666666667 6.791808333333333 3.15845 5.811916666666667 3.1982166666666667C5.002533333333334 3.231058333333334 4.375 3.8969416666666667 4.375 4.743841666666667L4.375 15.12575C4.375 16.01275 5.067016666666667 16.737333333333336 5.943891666666667 16.773000000000003C7.195191666666667 16.823833333333337 8.756833333333335 16.874583333333334 10 16.874583333333334C11.243166666666667 16.874583333333334 12.804833333333335 16.823833333333337 14.056125 16.773000000000003C14.932958333333335 16.737333333333336 15.625 16.01275 15.625 15.12575L15.625 4.743841666666667C15.625 3.8969416666666667 14.997458333333332 3.231058333333334 14.188083333333335 3.1982166666666667C13.208208333333333 3.15845 11.835125 3.124591666666667 10 3.124591666666667zM5.7612250000000005 1.9492416666666668C6.759566666666667 1.908725 8.149641666666668 1.8745916666666667 10 1.8745916666666667C11.850375 1.8745916666666667 13.240458333333335 1.908725 14.238791666666666 1.9492416666666668C15.754791666666668 2.010766666666667 16.875 3.263466666666667 16.875 4.743841666666667L16.875 15.12575C16.875 16.673958333333335 15.663166666666667 17.958708333333334 14.106874999999999 18.021958333333334C12.851916666666668 18.072958333333336 11.269541666666667 18.124583333333334 10 18.124583333333334C8.730458333333333 18.124583333333334 7.148116666666668 18.072958333333336 5.893133333333334 18.021958333333334C4.336833333333334 17.958708333333334 3.125 16.673958333333335 3.125 15.12575L3.125 4.743841666666667C3.125 3.263475 4.245233333333334 2.010766666666667 5.7612250000000005 1.9492416666666668z"
|
|
141
|
+
fill="currentColor"
|
|
142
|
+
></path>
|
|
143
|
+
<path
|
|
144
|
+
d="M6.385416666666667 6.2491666666666665C6.385416666666667 5.921250000000001 6.65125 5.655416666666667 6.979166666666667 5.655416666666667L9.479166666666668 5.655416666666667C9.807083333333333 5.655416666666667 10.072916666666668 5.921250000000001 10.072916666666668 6.2491666666666665C10.072916666666668 6.577091666666667 9.807083333333333 6.842908333333333 9.479166666666668 6.842908333333333L6.979166666666667 6.842908333333333C6.65125 6.842908333333333 6.385416666666667 6.577091666666667 6.385416666666667 6.2491666666666665z"
|
|
145
|
+
fill="currentColor"
|
|
146
|
+
></path>
|
|
147
|
+
<path
|
|
148
|
+
d="M6.28125 8.749166666666667C6.28125 8.421258333333334 6.547083333333333 8.155408333333334 6.875 8.155408333333334L13.125 8.155408333333334C13.452916666666667 8.155408333333334 13.71875 8.421258333333334 13.71875 8.749166666666667C13.71875 9.077083333333334 13.452916666666667 9.342916666666666 13.125 9.342916666666666L6.875 9.342916666666666C6.547083333333333 9.342916666666666 6.28125 9.077083333333334 6.28125 8.749166666666667z"
|
|
149
|
+
fill="currentColor"
|
|
150
|
+
></path>
|
|
151
|
+
<path
|
|
152
|
+
d="M6.28125 11.249166666666667C6.28125 10.92125 6.547083333333333 10.655416666666667 6.875 10.655416666666667L13.125 10.655416666666667C13.452916666666667 10.655416666666667 13.71875 10.92125 13.71875 11.249166666666667C13.71875 11.577083333333334 13.452916666666667 11.842916666666666 13.125 11.842916666666666L6.875 11.842916666666666C6.547083333333333 11.842916666666666 6.28125 11.577083333333334 6.28125 11.249166666666667z"
|
|
153
|
+
fill="currentColor"
|
|
154
|
+
></path>
|
|
155
|
+
<path
|
|
156
|
+
d="M6.28125 13.749166666666666C6.28125 13.42125 6.547083333333333 13.155416666666667 6.875 13.155416666666667L11.458333333333334 13.155416666666667C11.78625 13.155416666666667 12.052083333333334 13.42125 12.052083333333334 13.749166666666666C12.052083333333334 14.077083333333333 11.78625 14.342916666666667 11.458333333333334 14.342916666666667L6.875 14.342916666666667C6.547083333333333 14.342916666666667 6.28125 14.077083333333333 6.28125 13.749166666666666z"
|
|
157
|
+
fill="currentColor"
|
|
158
|
+
></path>
|
|
159
|
+
</svg>
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
/** 投票图标 */
|
|
163
|
+
const VoteIcon = ({ className }: { className?: string }) => (
|
|
164
|
+
<svg className={cn(className, 'inline-block w-20 mb-2 align-middle')} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
|
|
165
|
+
<path
|
|
166
|
+
d="M1.5 10.688324999999999C1.5 9.6528 2.3394675 8.813324999999999 3.375 8.813324999999999L4.125 8.813324999999999C5.1605324999999995 8.813324999999999 6 9.6528 6 10.688324999999999L6 13.313325C6 14.348849999999999 5.1605324999999995 15.188325 4.125 15.188325L3.375 15.188325C2.3394675 15.188325 1.5 14.348849999999999 1.5 13.313325L1.5 10.688324999999999zM3.375 9.938324999999999C2.96079 9.938324999999999 2.625 10.2741 2.625 10.688324999999999L2.625 13.313325C2.625 13.72755 2.96079 14.063325 3.375 14.063325L4.125 14.063325C4.5392175 14.063325 4.875 13.72755 4.875 13.313325L4.875 10.688324999999999C4.875 10.2741 4.5392175 9.938324999999999 4.125 9.938324999999999L3.375 9.938324999999999z"
|
|
167
|
+
fill="currentColor"
|
|
168
|
+
></path>
|
|
169
|
+
<path
|
|
170
|
+
d="M6.75 4.313235000000001C6.75 3.2777024999999997 7.589482500000001 2.438235 8.625 2.438235L9.375 2.438235C10.410525 2.438235 11.25 3.2777024999999997 11.25 4.313235000000001L11.25 13.31325C11.25 14.348775 10.410525 15.18825 9.375 15.18825L8.625 15.18825C7.589482500000001 15.18825 6.75 14.348775 6.75 13.31325L6.75 4.313235000000001zM8.625 3.563235C8.210775 3.563235 7.875 3.8990175000000002 7.875 4.313235000000001L7.875 13.31325C7.875 13.727437499999999 8.210775 14.06325 8.625 14.06325L9.375 14.06325C9.789225 14.06325 10.125 13.727437499999999 10.125 13.31325L10.125 4.313235000000001C10.125 3.8990175000000002 9.789225 3.563235 9.375 3.563235L8.625 3.563235z"
|
|
171
|
+
fill="currentColor"
|
|
172
|
+
></path>
|
|
173
|
+
<path
|
|
174
|
+
d="M12 8.25075C12 7.2152025 12.839475 6.375735000000001 13.875 6.375735000000001L14.625 6.375735000000001C15.660525 6.375735000000001 16.5 7.2152025 16.5 8.25075L16.5 13.31325C16.5 14.348775 15.660525 15.18825 14.625 15.18825L13.875 15.18825C12.839475 15.18825 12 14.348775 12 13.31325L12 8.25075zM13.875 7.500742499999999C13.460775000000002 7.500742499999999 13.125 7.836525 13.125 8.25075L13.125 13.31325C13.125 13.727437499999999 13.460775000000002 14.06325 13.875 14.06325L14.625 14.06325C15.039224999999998 14.06325 15.375 13.727437499999999 15.375 13.31325L15.375 8.25075C15.375 7.836525 15.039224999999998 7.500742499999999 14.625 7.500742499999999L13.875 7.500742499999999z"
|
|
175
|
+
fill="currentColor"
|
|
176
|
+
></path>
|
|
177
|
+
</svg>
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
/** 查看图片图标 */
|
|
181
|
+
const ViewPictureIcon = ({ className }: { className?: string }) => (
|
|
182
|
+
<svg
|
|
183
|
+
className={cn(className, 'inline-block w-20 align-middle')}
|
|
184
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
185
|
+
viewBox="0 0 22 22"
|
|
186
|
+
width="22"
|
|
187
|
+
height="22"
|
|
188
|
+
>
|
|
189
|
+
<path
|
|
190
|
+
d="M7.791666666666666 7.733060333333333C7.253044666666666 7.733060333333333 6.816416666666667 8.169688333333333 6.816416666666667 8.708310333333333C6.816416666666667 9.246946 7.253044666666666 9.683544999999999 7.791666666666666 9.683544999999999C8.330281000000001 9.683544999999999 8.766916666666667 9.246946 8.766916666666667 8.708310333333333C8.766916666666667 8.169688333333333 8.330281000000001 7.733060333333333 7.791666666666666 7.733060333333333zM5.558583333333333 8.708310333333333C5.558583333333333 7.475007999999999 6.558372 6.4752193333333325 7.791666666666666 6.4752193333333325C9.024961333333332 6.4752193333333325 10.02475 7.475007999999999 10.02475 8.708310333333333C10.02475 9.941568333333333 9.024961333333332 10.941378333333333 7.791666666666666 10.941378333333333C6.558372 10.941378333333333 5.558583333333333 9.941568333333333 5.558583333333333 8.708310333333333z"
|
|
191
|
+
fill="currentColor"
|
|
192
|
+
/>
|
|
193
|
+
<path
|
|
194
|
+
d="M11 4.543596666666667C8.690401666666668 4.543596666666667 6.673815333333333 4.661083166666667 5.250284333333333 4.776523999999999C4.243521333333333 4.858162833333334 3.4624053333333333 5.627683666666666 3.37265 6.626020666666667C3.268142166666667 7.788485666666666 3.170833333333333 9.321563333333334 3.170833333333333 10.9978C3.170833333333333 12.673983333333332 3.268142166666667 14.207033333333332 3.37265 15.369535C3.4624053333333333 16.36785666666667 4.243521333333333 17.137388333333334 5.250284333333333 17.219013333333333C6.673816833333333 17.334481666666665 8.690401666666668 17.451966666666664 11 17.451966666666664C13.309854999999999 17.451966666666664 15.326548333333335 17.33439 16.750163333333333 17.218959999999996C17.756758333333334 17.137349999999998 18.5377 16.36804 18.627441666666666 15.36994C18.731925 14.207988333333333 18.829166666666666 12.675175 18.829166666666666 10.9978C18.829166666666666 9.320333333333332 18.731925 7.787542999999999 18.627441666666666 6.6255715C18.5377 5.627479 17.756758333333334 4.858190333333333 16.750163333333333 4.776553C15.326548333333335 4.661109166666666 13.309854999999999 4.543596666666667 11 4.543596666666667zM5.145209166666667 3.480780333333333C6.5952265 3.3631968333333333 8.647761666666666 3.2435966666666665 11 3.2435966666666665C13.352495000000001 3.2435966666666665 15.405159999999999 3.3632151666666665 16.855203333333332 3.4808078333333334C18.484758333333332 3.6129723333333335 19.775116666666666 4.873037 19.922241666666665 6.509160333333334C20.02923333333333 7.6992561666666655 20.129166666666666 9.272141666666666 20.129166666666666 10.9978C20.129166666666666 12.723366666666667 20.02923333333333 14.296258333333332 19.922241666666665 15.486381666666665C19.775116666666666 17.12246833333333 18.484758333333332 18.382566666666666 16.855203333333332 18.514723333333333C15.405159999999999 18.63231 13.352495000000001 18.751966666666664 11 18.751966666666664C8.647761666666666 18.751966666666664 6.5952265 18.63231 5.145209166666667 18.514761666666665C3.515391333333333 18.382566666666666 2.224978166666667 17.122193333333332 2.0778760000000003 15.485923333333332C1.970837 14.295341666666666 1.8708333333333333 12.722213333333332 1.8708333333333333 10.9978C1.8708333333333333 9.273295 1.970837 7.700146833333332 2.0778760000000003 6.509618666666666C2.224978166666667 4.8733365 3.515391333333333 3.6129448333333336 5.145209166666667 3.480780333333333z"
|
|
195
|
+
fill="currentColor"
|
|
196
|
+
/>
|
|
197
|
+
<path
|
|
198
|
+
d="M14.586553333333333 12.397246666666668C14.19608 12.006681666666665 13.562881666666666 12.006681666666665 13.172316666666665 12.397208333333333L11.288666666666668 14.280896666666665C10.517069999999999 15.052493333333333 9.265836666666667 15.052218333333332 8.494585500000001 14.280124999999998C8.166277166666667 13.951508333333333 7.633659333333334 13.951363333333331 7.305149499999999 14.279834999999999L5.922092833333333 15.66269C5.6682380000000006 15.91648833333333 5.256674833333333 15.91648833333333 5.002853666666667 15.662636666666666C4.7490248333333325 15.4088 4.749050833333333 14.99722 5.002907166666666 14.743368333333333L6.385979166666666 13.360513333333333C7.222356166666667 12.524223333333333 8.578404666666666 12.524628333333332 9.414303333333333 13.361376666666667C9.677975 13.6253 10.105658333333334 13.625445 10.369436666666665 13.361666666666666L12.253033333333333 11.477978333333331C13.151301666666665 10.57971 14.607698333333333 10.579763333333334 15.505913333333332 11.478108333333331L16.99718 12.969611666666665C17.250978333333336 13.223448333333334 17.25094 13.63499 16.997049999999998 13.888841666666666C16.743198333333332 14.142639999999998 16.331671666666665 14.142639999999998 16.07782 13.88875L14.586553333333333 12.397246666666668z"
|
|
199
|
+
fill="currentColor"
|
|
200
|
+
/>
|
|
201
|
+
</svg>
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* 渲染带行内样式的文本节点。
|
|
206
|
+
*/
|
|
207
|
+
const renderStyledText = (text: string, style: RichTextInlineStyle | undefined, index: number | string): ReactNode => {
|
|
208
|
+
if (!style) {
|
|
209
|
+
return <span key={`text-${index}`}>{text}</span>
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const classNames: string[] = []
|
|
213
|
+
if (style.bold) classNames.push('font-bold')
|
|
214
|
+
if (style.italic) classNames.push('italic')
|
|
215
|
+
if (style.strike) classNames.push('line-through')
|
|
216
|
+
|
|
217
|
+
const inlineStyle: CSSProperties = {}
|
|
218
|
+
if (style.color) {
|
|
219
|
+
inlineStyle.color = style.color
|
|
220
|
+
}
|
|
221
|
+
if (style.fontSize) {
|
|
222
|
+
inlineStyle.fontSize = style.fontSize
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (style.link) {
|
|
226
|
+
return (
|
|
227
|
+
<a
|
|
228
|
+
key={`text-${index}`}
|
|
229
|
+
href={style.link}
|
|
230
|
+
className={classNames.join(' ') || undefined}
|
|
231
|
+
style={inlineStyle}
|
|
232
|
+
target="_blank"
|
|
233
|
+
rel="noopener noreferrer"
|
|
234
|
+
data-richtext-node="text"
|
|
235
|
+
>
|
|
236
|
+
{text}
|
|
237
|
+
</a>
|
|
238
|
+
)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (classNames.length === 0 && Object.keys(inlineStyle).length === 0) {
|
|
242
|
+
return <span key={`text-${index}`}>{text}</span>
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<span key={`text-${index}`} className={classNames.join(' ') || undefined} style={inlineStyle} data-richtext-node="text">
|
|
247
|
+
{text}
|
|
248
|
+
</span>
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* 将单个富文本节点渲染成 React 节点。
|
|
254
|
+
*
|
|
255
|
+
* 这里的设计重点是"只在 template 侧落地 UI 语义":
|
|
256
|
+
* - `core` 不需要依赖 React,也不用承担 JSX/SSR 运行时边界。
|
|
257
|
+
* - React 负责文本与属性转义,我们只补上图片协议白名单。
|
|
258
|
+
*/
|
|
259
|
+
const renderNodeToReact = (node: RichTextNode, index: number, options: RichTextRenderOptions): ReactNode => {
|
|
260
|
+
switch (node.type) {
|
|
261
|
+
case 'text': {
|
|
262
|
+
const text = node.text
|
|
263
|
+
const urlRegex = /https?:\/\/[-\w._~:/?#[\]@!$&'()*+,;=%]+/g
|
|
264
|
+
if (!urlRegex.test(text)) {
|
|
265
|
+
return renderStyledText(text, node.style, index)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const parts: ReactNode[] = []
|
|
269
|
+
let lastIndex = 0
|
|
270
|
+
let match: RegExpExecArray | null
|
|
271
|
+
urlRegex.lastIndex = 0
|
|
272
|
+
while ((match = urlRegex.exec(text)) !== null) {
|
|
273
|
+
if (match.index > lastIndex) {
|
|
274
|
+
parts.push(renderStyledText(text.slice(lastIndex, match.index), node.style, `${index}-pre-${match.index}`))
|
|
275
|
+
}
|
|
276
|
+
parts.push(
|
|
277
|
+
<span key={`url-${index}-${match.index}`} className="break-all">
|
|
278
|
+
{renderStyledText(match[0], node.style, `${index}-url-${match.index}`)}
|
|
279
|
+
</span>
|
|
280
|
+
)
|
|
281
|
+
lastIndex = match.index + match[0].length
|
|
282
|
+
}
|
|
283
|
+
if (lastIndex < text.length) {
|
|
284
|
+
parts.push(renderStyledText(text.slice(lastIndex), node.style, `${index}-post`))
|
|
285
|
+
}
|
|
286
|
+
return <React.Fragment key={`text-fragment-${index}`}>{parts}</React.Fragment>
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
case 'lineBreak':
|
|
290
|
+
return <br key={`br-${index}`} />
|
|
291
|
+
|
|
292
|
+
case 'mention':
|
|
293
|
+
return (
|
|
294
|
+
<span key={`mention-${index}`} className={options.mention?.className} data-richtext-node="mention" data-user-id={node.userId}>
|
|
295
|
+
{node.text}
|
|
296
|
+
</span>
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
case 'searchKeyword':
|
|
300
|
+
return (
|
|
301
|
+
<span
|
|
302
|
+
key={`search-${index}`}
|
|
303
|
+
className={options.searchKeyword?.className}
|
|
304
|
+
data-richtext-node="searchKeyword"
|
|
305
|
+
data-search-query-id={node.queryId}
|
|
306
|
+
>
|
|
307
|
+
<span>{node.text}</span>
|
|
308
|
+
<SearchKeywordIcon className={options.searchKeyword?.iconClassName} />
|
|
309
|
+
</span>
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
case 'emoji': {
|
|
313
|
+
const safeSrc = sanitizeImageSource(node.src)
|
|
314
|
+
if (!safeSrc) {
|
|
315
|
+
return node.name
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
<img
|
|
320
|
+
key={`emoji-${index}`}
|
|
321
|
+
className="mx-1"
|
|
322
|
+
src={safeSrc}
|
|
323
|
+
alt={node.name}
|
|
324
|
+
style={getRichTextEmojiStyle(node.scale)}
|
|
325
|
+
referrerPolicy="no-referrer"
|
|
326
|
+
crossOrigin="anonymous"
|
|
327
|
+
data-richtext-node="emoji"
|
|
328
|
+
/>
|
|
329
|
+
)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
case 'topic':
|
|
333
|
+
return (
|
|
334
|
+
<span key={`topic-${index}`} className={options.topic?.className} data-richtext-node="topic">
|
|
335
|
+
<span
|
|
336
|
+
style={
|
|
337
|
+
options.iconScale && options.iconScale !== 1
|
|
338
|
+
? { transform: `scale(${options.iconScale})`, transformOrigin: 'left center', display: 'inline-block' }
|
|
339
|
+
: undefined
|
|
340
|
+
}
|
|
341
|
+
>
|
|
342
|
+
<TopicIcon />
|
|
343
|
+
</span>
|
|
344
|
+
{node.text}
|
|
345
|
+
</span>
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
case 'hashtag':
|
|
349
|
+
return (
|
|
350
|
+
<span key={`hashtag-${index}`} className={options.hashtag?.className} data-richtext-node="hashtag">
|
|
351
|
+
{node.text}
|
|
352
|
+
</span>
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
case 'at':
|
|
356
|
+
return (
|
|
357
|
+
<span key={`at-${index}`} className={options.at?.className} data-richtext-node="at" data-user-id={node.userId}>
|
|
358
|
+
{node.text}
|
|
359
|
+
</span>
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
case 'lottery':
|
|
363
|
+
return (
|
|
364
|
+
<span key={`lottery-${index}`} className={options.lottery?.className} data-richtext-node="lottery">
|
|
365
|
+
<span
|
|
366
|
+
style={
|
|
367
|
+
options.iconScale && options.iconScale !== 1
|
|
368
|
+
? { transform: `scale(${options.iconScale})`, transformOrigin: 'left center', display: 'inline-block' }
|
|
369
|
+
: undefined
|
|
370
|
+
}
|
|
371
|
+
>
|
|
372
|
+
<LotteryIcon />
|
|
373
|
+
</span>
|
|
374
|
+
{node.text}
|
|
375
|
+
</span>
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
case 'webLink':
|
|
379
|
+
return (
|
|
380
|
+
<a
|
|
381
|
+
key={`weblink-${index}`}
|
|
382
|
+
className={cn(options.webLink?.className, 'break-all')}
|
|
383
|
+
href={node.jumpUrl}
|
|
384
|
+
target="_blank"
|
|
385
|
+
rel="noopener noreferrer"
|
|
386
|
+
data-richtext-node="webLink"
|
|
387
|
+
>
|
|
388
|
+
<span
|
|
389
|
+
style={
|
|
390
|
+
options.iconScale && options.iconScale !== 1
|
|
391
|
+
? { transform: `scale(${options.iconScale})`, transformOrigin: 'left center', display: 'inline-block' }
|
|
392
|
+
: undefined
|
|
393
|
+
}
|
|
394
|
+
>
|
|
395
|
+
<WebLinkIcon />
|
|
396
|
+
</span>
|
|
397
|
+
{node.text}
|
|
398
|
+
</a>
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
case 'opusLink':
|
|
402
|
+
return (
|
|
403
|
+
<span key={`opuslink-${index}`} className={options.opusLink?.className} data-richtext-node="opusLink" data-url={node.url}>
|
|
404
|
+
<span
|
|
405
|
+
style={
|
|
406
|
+
options.iconScale && options.iconScale !== 1
|
|
407
|
+
? { transform: `scale(${options.iconScale})`, transformOrigin: 'left center', display: 'inline-block' }
|
|
408
|
+
: undefined
|
|
409
|
+
}
|
|
410
|
+
>
|
|
411
|
+
<OpusLinkIcon />
|
|
412
|
+
</span>
|
|
413
|
+
{node.text}
|
|
414
|
+
</span>
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
case 'vote':
|
|
418
|
+
return (
|
|
419
|
+
<span key={`vote-${index}`} className={options.vote?.className} data-richtext-node="vote">
|
|
420
|
+
<span
|
|
421
|
+
style={
|
|
422
|
+
options.iconScale && options.iconScale !== 1
|
|
423
|
+
? { transform: `scale(${options.iconScale})`, transformOrigin: 'left center', display: 'inline-block' }
|
|
424
|
+
: undefined
|
|
425
|
+
}
|
|
426
|
+
>
|
|
427
|
+
<VoteIcon />
|
|
428
|
+
</span>
|
|
429
|
+
{node.text}
|
|
430
|
+
</span>
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
case 'viewPicture':
|
|
434
|
+
return (
|
|
435
|
+
<span key={`viewpicture-${index}`} className={options.viewPicture?.className} data-richtext-node="viewPicture">
|
|
436
|
+
<span
|
|
437
|
+
style={
|
|
438
|
+
options.iconScale && options.iconScale !== 1
|
|
439
|
+
? { transform: `scale(${options.iconScale})`, transformOrigin: 'left center', display: 'inline-block' }
|
|
440
|
+
: undefined
|
|
441
|
+
}
|
|
442
|
+
>
|
|
443
|
+
<ViewPictureIcon />
|
|
444
|
+
</span>
|
|
445
|
+
{node.text}
|
|
446
|
+
</span>
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
case 'heading': {
|
|
450
|
+
const HeadingTag = `h${node.level}` as keyof React.JSX.IntrinsicElements
|
|
451
|
+
const sizeClass =
|
|
452
|
+
node.level === 1
|
|
453
|
+
? 'text-[64px]'
|
|
454
|
+
: node.level === 2
|
|
455
|
+
? 'text-[58px]'
|
|
456
|
+
: node.level === 3
|
|
457
|
+
? 'text-[52px]'
|
|
458
|
+
: node.level === 4
|
|
459
|
+
? 'text-[48px]'
|
|
460
|
+
: node.level === 5
|
|
461
|
+
? 'text-[44px]'
|
|
462
|
+
: 'text-[40px]'
|
|
463
|
+
return (
|
|
464
|
+
<HeadingTag
|
|
465
|
+
key={`heading-${index}`}
|
|
466
|
+
className={`${sizeClass} font-bold my-10`}
|
|
467
|
+
data-richtext-node="heading"
|
|
468
|
+
data-heading-level={node.level}
|
|
469
|
+
>
|
|
470
|
+
{node.nodes.map((child, childIndex) => renderNodeToReact(child, childIndex, options))}
|
|
471
|
+
</HeadingTag>
|
|
472
|
+
)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
case 'paragraph':
|
|
476
|
+
return (
|
|
477
|
+
<p key={`paragraph-${index}`} data-richtext-node="paragraph">
|
|
478
|
+
{node.nodes.map((child, childIndex) => renderNodeToReact(child, childIndex, options))}
|
|
479
|
+
</p>
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
case 'image': {
|
|
483
|
+
const safeSrc = sanitizeImageSource(node.src)
|
|
484
|
+
if (!safeSrc) {
|
|
485
|
+
return null
|
|
486
|
+
}
|
|
487
|
+
return (
|
|
488
|
+
<div key={`image-${index}`} data-richtext-node="image">
|
|
489
|
+
<img className="rounded-4xl" src={safeSrc} alt={node.alt || ''} referrerPolicy="no-referrer" crossOrigin="anonymous" />
|
|
490
|
+
{node.caption && <div className="mt-6 text-center text-[36px] text-foreground/60 select-text">{node.caption}</div>}
|
|
491
|
+
</div>
|
|
492
|
+
)
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
case 'horizontalRule':
|
|
496
|
+
return <div key={`hr-${index}`} className="my-16 w-full h-px bg-border" data-richtext-node="horizontalRule" />
|
|
497
|
+
|
|
498
|
+
case 'blockquote':
|
|
499
|
+
return (
|
|
500
|
+
<blockquote key={`blockquote-${index}`} data-richtext-node="blockquote">
|
|
501
|
+
{node.nodes.map((child, childIndex) => renderNodeToReact(child, childIndex, options))}
|
|
502
|
+
</blockquote>
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
case 'list': {
|
|
506
|
+
const ListTag = node.ordered ? 'ol' : 'ul'
|
|
507
|
+
return (
|
|
508
|
+
<ListTag key={`list-${index}`} data-richtext-node="list" data-list-ordered={node.ordered}>
|
|
509
|
+
{node.items.map((item, itemIndex) => renderNodeToReact(item, itemIndex, options))}
|
|
510
|
+
</ListTag>
|
|
511
|
+
)
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
case 'listItem':
|
|
515
|
+
return (
|
|
516
|
+
<li key={`listitem-${index}`} data-richtext-node="listItem">
|
|
517
|
+
{node.nodes.map((child, childIndex) => renderNodeToReact(child, childIndex, options))}
|
|
518
|
+
</li>
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
case 'codeBlock': {
|
|
522
|
+
const lines = node.content.split('\n')
|
|
523
|
+
const showLang = node.language && node.language !== 'plaintext'
|
|
524
|
+
return (
|
|
525
|
+
<div
|
|
526
|
+
key={`codeblock-${index}`}
|
|
527
|
+
className={cn('bg-surface rounded-4xl my-8 border border-border', options.codeBlock?.className)}
|
|
528
|
+
data-richtext-node="codeBlock"
|
|
529
|
+
data-language={node.language}
|
|
530
|
+
>
|
|
531
|
+
{showLang && (
|
|
532
|
+
<div className="px-12 py-6 text-[36px] font-medium text-muted border-b border-border" data-richtext-code-lang>
|
|
533
|
+
{node.language}
|
|
534
|
+
</div>
|
|
535
|
+
)}
|
|
536
|
+
<div className="py-8 pl-4 pr-12" data-richtext-code-body>
|
|
537
|
+
{lines.map((line, lineIndex) => (
|
|
538
|
+
<div key={`line-${lineIndex}`} className="flex gap-16 leading-[1.8]" data-richtext-code-line>
|
|
539
|
+
<span className="shrink-0 w-12 text-right text-[30px] text-muted select-none font-mono" data-richtext-code-lineno>
|
|
540
|
+
{lineIndex + 1}
|
|
541
|
+
</span>
|
|
542
|
+
<code className="font-mono text-[34px] whitespace-pre-wrap break-all text-foreground" data-richtext-code-content>
|
|
543
|
+
{line || ' '}
|
|
544
|
+
</code>
|
|
545
|
+
</div>
|
|
546
|
+
))}
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
)
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
case 'linkCard':
|
|
553
|
+
return (
|
|
554
|
+
<a
|
|
555
|
+
key={`linkcard-${index}`}
|
|
556
|
+
className={options.linkCard?.className}
|
|
557
|
+
href={node.url}
|
|
558
|
+
target="_blank"
|
|
559
|
+
rel="noopener noreferrer"
|
|
560
|
+
data-richtext-node="linkCard"
|
|
561
|
+
data-card-type={node.cardType}
|
|
562
|
+
>
|
|
563
|
+
{node.title}
|
|
564
|
+
</a>
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
default:
|
|
568
|
+
return null
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* 将富文本文档渲染成 React 节点。
|
|
574
|
+
*
|
|
575
|
+
* 这是 React 模板的首选渲染方式:
|
|
576
|
+
* - 不经过 HTML 字符串;
|
|
577
|
+
* - 不需要 `dangerouslySetInnerHTML`;
|
|
578
|
+
* - 更适合 SSR,因为传输边界仍然是纯 JSON。
|
|
579
|
+
*/
|
|
580
|
+
export const renderRichTextToReact = (document: RichTextDocument, options: RichTextRenderOptions = {}): ReactNode => {
|
|
581
|
+
return <>{document.nodes.map((node, index) => renderNodeToReact(node, index, options))}</>
|
|
582
|
+
}
|