feat: integration with follow

This commit is contained in:
Stephen Zhou 2024-09-13 08:37:01 +08:00
parent 7b223590a4
commit 47d09468fc
No known key found for this signature in database
8 changed files with 178 additions and 129 deletions

View File

@ -93,7 +93,6 @@
"isomorphic-dompurify": "2.11.0",
"js-yaml": "4.1.0",
"jsdom": "24.0.0",
"jsonfeed-to-rss": "3.0.8",
"katex": "0.16.10",
"langchain": "0.1.37",
"lottie-react": "2.4.0",
@ -141,6 +140,7 @@
"remark-parse": "11.0.0",
"remark-rehype": "11.1.0",
"remove-markdown": "0.5.0",
"rss": "^1.2.2",
"rss-parser": "3.13.0",
"serialize-javascript": "6.0.2",
"server-only": "0.0.1",
@ -176,6 +176,7 @@
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@types/remove-markdown": "^0.3.4",
"@types/rss": "^0.0.32",
"@types/serialize-javascript": "5.0.4",
"@types/sortablejs": "1.15.8",
"autoprefixer": "10.4.19",
@ -184,8 +185,8 @@
"eslint-config-next": "14.2.3",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-react": "7.34.1",
"eslint-plugin-tailwindcss": "3.17.0",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-tailwindcss": "3.17.0",
"eslint-plugin-unused-imports": "3.2.0",
"husky": "9.0.11",
"lint-staged": "15.2.4",
@ -219,4 +220,4 @@
"tailwindcss-variable-colors@0.0.2": "patches/tailwindcss-variable-colors@0.0.2.patch"
}
}
}
}

View File

@ -206,9 +206,6 @@ importers:
jsdom:
specifier: 24.0.0
version: 24.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)
jsonfeed-to-rss:
specifier: 3.0.8
version: 3.0.8
katex:
specifier: 0.16.10
version: 0.16.10
@ -350,6 +347,9 @@ importers:
remove-markdown:
specifier: 0.5.0
version: 0.5.0
rss:
specifier: ^1.2.2
version: 1.2.2
rss-parser:
specifier: 3.13.0
version: 3.13.0
@ -450,6 +450,9 @@ importers:
'@types/remove-markdown':
specifier: ^0.3.4
version: 0.3.4
'@types/rss':
specifier: ^0.0.32
version: 0.0.32
'@types/serialize-javascript':
specifier: 5.0.4
version: 5.0.4
@ -665,9 +668,6 @@ packages:
'@braintree/sanitize-url@6.0.4':
resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==}
'@bret/truthy@1.0.1':
resolution: {integrity: sha512-mFVhqy/yrh+BZwzqQQptGcTq5SJ+T0uhWQ/hmBkU0RFV3YN2UkcDhxvAzUuMDibOi6s66YM01BUGAi1y/92QGw==}
'@codemirror/autocomplete@6.16.0':
resolution: {integrity: sha512-P/LeCTtZHRTCU4xQsa89vSKWecYv1ZqwzOd5topheGRf+qtacFgBeIMQi3eL8Kt/BUNvxUWkx+5qP2jlGoARrg==}
peerDependencies:
@ -2124,9 +2124,6 @@ packages:
'@tanstack/virtual-core@3.5.0':
resolution: {integrity: sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==}
'@textlint/ast-node-types@13.4.1':
resolution: {integrity: sha512-qrZyhCh8Ekk6nwArx3BROybm9BnX6vF7VcZbijetV/OM3yfS4rTYhoMWISmhVEP2H2re0CtWEyMl/XF+WdvVLQ==}
'@tianfeng98/hls.js@1.0.2':
resolution: {integrity: sha512-IHSLEBxlAllx5oecRfCvzsd23yuBuiSU2BmrNKDBwAf4dLjYcZW8TASG5i+SZg/rFyzXm4OWrLJKwPgwvSg5uA==}
@ -2223,6 +2220,9 @@ packages:
'@types/retry@0.12.0':
resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
'@types/rss@0.0.32':
resolution: {integrity: sha512-2oKNqKyUY4RSdvl5eZR1n2Q9yvw3XTe3mQHsFPn9alaNBxfPnbXBtGP8R0SV8pK1PrVnLul0zx7izbm5/gF5Qw==}
'@types/serialize-javascript@5.0.4':
resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==}
@ -2491,9 +2491,6 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
add-zero@1.0.0:
resolution: {integrity: sha512-WpPiUgy7h9Kd7NY0aTuhfx7vjub3XYbZCq1W2e/LMvUsEmYK/hz8xgFDmd0GnKpk44HXFwIFu1hEOivc+MzJ0Q==}
aes-js@3.1.2:
resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==}
@ -2735,9 +2732,6 @@ packages:
borsh@0.7.0:
resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==}
boundary@2.0.0:
resolution: {integrity: sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==}
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
@ -2873,10 +2867,6 @@ packages:
classnames@2.5.1:
resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==}
clean-deep@3.4.0:
resolution: {integrity: sha512-Lo78NV5ItJL/jl+B5w0BycAisaieJGXK1qYi/9m4SjR8zbqmrUtO7Yhro40wEShGmmxs/aJLI/A+jNhdkXK8mw==}
engines: {node: '>=4'}
clear-module@4.1.2:
resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==}
engines: {node: '>=8'}
@ -3715,9 +3705,6 @@ packages:
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
engines: {node: '>=16.17'}
existy@1.0.1:
resolution: {integrity: sha512-YeYTp9rIyoArnYubrTXHUOpuxwSdlQEctcw9zUgViSof/uJE+LlsiZb9BpIrCqLRcjiCCeF5cxX3wcfKZMqVzg==}
expand-template@2.0.3:
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
engines: {node: '>=6'}
@ -4545,9 +4532,6 @@ packages:
engines: {node: '>=6'}
hasBin: true
jsonfeed-to-rss@3.0.8:
resolution: {integrity: sha512-KW5qhFGZxGyrT+oaAfS/xxiVindm406x0L6rsQLwG4nXSB4tcXebwXmXuUvg7FDfBniBTB8HgDRUTgZ67BE2rQ==}
jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
@ -4834,27 +4818,15 @@ packages:
lodash.defaults@4.2.0:
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
lodash.get@4.4.2:
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
lodash.isarguments@3.1.0:
resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==}
lodash.isempty@4.4.0:
resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==}
lodash.isequal@4.5.0:
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash.transform@4.6.0:
resolution: {integrity: sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
@ -5146,10 +5118,18 @@ packages:
resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
engines: {node: '>=8.6'}
mime-db@1.25.0:
resolution: {integrity: sha512-5k547tI4Cy+Lddr/hdjNbBEWBwSl8EBc5aSdKvedav8DReADgWJzcYiktaRIw3GtGC1jjwldXtTzvqJZmtvC7w==}
engines: {node: '>= 0.6'}
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
mime-types@2.1.13:
resolution: {integrity: sha512-ryBDp1Z/6X90UvjUK3RksH0IBPM137T7cmg4OgD5wQBojlAiUwuok0QeELkim/72EtcYuNlmbkrcGuxj3Kl0YQ==}
engines: {node: '>= 0.6'}
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
@ -5621,9 +5601,6 @@ packages:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
podcast-categories@2.0.0:
resolution: {integrity: sha512-WcntiTmj4ERPwaevHeR59Lc6yk37YVwksflBaCu7/J2ChjPA02J703rZMVq4gnoa+XHFHqpjK+qSc8Fv6N62EA==}
possible-typed-array-names@1.0.0:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
@ -6145,6 +6122,9 @@ packages:
rss-parser@3.13.0:
resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==}
rss@1.2.2:
resolution: {integrity: sha512-xUhRTgslHeCBeHAqaWSbOYTydN2f0tAzNXvzh3stjz7QDhQMzdgHf3pfgNIngeytQflrFPfy6axHilTETr6gDg==}
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
@ -6208,9 +6188,6 @@ packages:
engines: {node: '>=10'}
hasBin: true
sentence-splitter@5.0.0:
resolution: {integrity: sha512-9Mvf7L8vwpPzkH0/HtXzCbmVkyj4aQXdeG7h8ighRvO0hvcZEy2OUEjeIlnM/z4EX4vBacEfpESC65Oa2rWOig==}
serialize-javascript@6.0.2:
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
@ -6415,12 +6392,6 @@ packages:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
striptags@3.2.0:
resolution: {integrity: sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==}
structured-source@4.0.0:
resolution: {integrity: sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==}
style-mod@4.1.2:
resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
@ -6581,17 +6552,9 @@ packages:
resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
engines: {node: '>=18'}
trim-left@1.0.1:
resolution: {integrity: sha512-quyxKUsLsY7+lgue8TQ6R8C4kwTe5No3/fvliPNTZd8CIK1KXFaIw+Z7SwAWiWUF5Ge5j7ppbjml3EKa02uPWA==}
engines: {node: '>=0.10.0'}
trim-lines@3.0.1:
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
trim-right@1.0.1:
resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==}
engines: {node: '>=0.10.0'}
trough@2.2.0:
resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
@ -7089,14 +7052,13 @@ packages:
resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==}
engines: {node: '>=4.0.0'}
xml@1.0.1:
resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==}
xmlbuilder@11.0.1:
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
engines: {node: '>=4.0'}
xmlbuilder@15.1.1:
resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==}
engines: {node: '>=8.0'}
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
@ -7353,10 +7315,6 @@ snapshots:
'@braintree/sanitize-url@6.0.4': {}
'@bret/truthy@1.0.1':
dependencies:
existy: 1.0.1
'@codemirror/autocomplete@6.16.0(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.3)(@lezer/common@1.2.1)':
dependencies:
'@codemirror/language': 6.10.1
@ -9069,8 +9027,6 @@ snapshots:
'@tanstack/virtual-core@3.5.0': {}
'@textlint/ast-node-types@13.4.1': {}
'@tianfeng98/hls.js@1.0.2': {}
'@types/async-lock@1.4.2': {}
@ -9165,6 +9121,8 @@ snapshots:
'@types/retry@0.12.0': {}
'@types/rss@0.0.32': {}
'@types/serialize-javascript@5.0.4': {}
'@types/shimmer@1.0.5': {}
@ -9747,8 +9705,6 @@ snapshots:
acorn@8.11.3: {}
add-zero@1.0.0: {}
aes-js@3.1.2: {}
agent-base@7.1.1:
@ -10041,8 +9997,6 @@ snapshots:
bs58: 4.0.1
text-encoding-utf-8: 1.0.2
boundary@2.0.0: {}
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
@ -10190,12 +10144,6 @@ snapshots:
classnames@2.5.1: {}
clean-deep@3.4.0:
dependencies:
lodash.isempty: 4.4.0
lodash.isplainobject: 4.0.6
lodash.transform: 4.6.0
clear-module@4.1.2:
dependencies:
parent-module: 2.0.0
@ -11226,8 +11174,6 @@ snapshots:
signal-exit: 4.1.0
strip-final-newline: 3.0.0
existy@1.0.1: {}
expand-template@2.0.3: {}
exponential-backoff@3.1.1: {}
@ -12159,21 +12105,6 @@ snapshots:
json5@2.2.3: {}
jsonfeed-to-rss@3.0.8:
dependencies:
'@bret/truthy': 1.0.1
add-zero: 1.0.0
clean-deep: 3.4.0
existy: 1.0.1
lodash.get: 4.4.2
lodash.merge: 4.6.2
podcast-categories: 2.0.0
sentence-splitter: 5.0.0
striptags: 3.2.0
trim-left: 1.0.1
trim-right: 1.0.1
xmlbuilder: 15.1.1
jsonfile@6.1.0:
dependencies:
universalify: 2.0.1
@ -12426,20 +12357,12 @@ snapshots:
lodash.defaults@4.2.0: {}
lodash.get@4.4.2: {}
lodash.isarguments@3.1.0: {}
lodash.isempty@4.4.0: {}
lodash.isequal@4.5.0: {}
lodash.isplainobject@4.0.6: {}
lodash.merge@4.6.2: {}
lodash.transform@4.6.0: {}
lodash@4.17.21: {}
log-update@6.0.0:
@ -13106,8 +13029,14 @@ snapshots:
braces: 3.0.3
picomatch: 2.3.1
mime-db@1.25.0: {}
mime-db@1.52.0: {}
mime-types@2.1.13:
dependencies:
mime-db: 1.25.0
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
@ -13575,8 +13504,6 @@ snapshots:
pngjs@5.0.0: {}
podcast-categories@2.0.0: {}
possible-typed-array-names@1.0.0: {}
postcss-import@15.1.0(postcss@8.4.38):
@ -14197,6 +14124,11 @@ snapshots:
entities: 2.2.0
xml2js: 0.5.0
rss@1.2.2:
dependencies:
mime-types: 2.1.13
xml: 1.0.1
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
@ -14254,11 +14186,6 @@ snapshots:
semver@7.6.2: {}
sentence-splitter@5.0.0:
dependencies:
'@textlint/ast-node-types': 13.4.1
structured-source: 4.0.0
serialize-javascript@6.0.2:
dependencies:
randombytes: 2.1.0
@ -14483,12 +14410,6 @@ snapshots:
strip-json-comments@3.1.1: {}
striptags@3.2.0: {}
structured-source@4.0.0:
dependencies:
boundary: 2.0.0
style-mod@4.1.2: {}
style-to-object@1.0.6:
@ -14663,12 +14584,8 @@ snapshots:
dependencies:
punycode: 2.3.1
trim-left@1.0.1: {}
trim-lines@3.0.1: {}
trim-right@1.0.1: {}
trough@2.2.0: {}
ts-api-utils@1.3.0(typescript@5.4.5):
@ -15210,9 +15127,9 @@ snapshots:
sax: 1.3.0
xmlbuilder: 11.0.1
xmlbuilder@11.0.1: {}
xml@1.0.1: {}
xmlbuilder@15.1.1: {}
xmlbuilder@11.0.1: {}
xmlchars@2.2.0: {}

View File

@ -36,6 +36,8 @@ export default function SiteSettingsGeneralPage() {
uh: "",
code_theme_light: "",
code_theme_dark: "",
follow_feed_id: undefined,
follow_user_id: undefined,
} as {
icon?: string
banner?: {
@ -51,6 +53,8 @@ export default function SiteSettingsGeneralPage() {
uh: string
code_theme_light: string
code_theme_dark: string
follow_feed_id?: string
follow_user_id?: string
},
})
@ -70,6 +74,10 @@ export default function SiteSettingsGeneralPage() {
light: values.code_theme_light,
dark: values.code_theme_dark,
},
follow: {
feed_id: values.follow_feed_id,
user_id: values.follow_user_id,
},
})
})
@ -126,6 +134,16 @@ export default function SiteSettingsGeneralPage() {
site.data.metadata?.content?.code_theme?.dark ||
"github-dark-default",
)
!form.getValues("follow_feed_id") &&
form.setValue(
"follow_feed_id",
site.data.metadata?.content?.follow?.feed_id,
)
!form.getValues("follow_user_id") &&
form.setValue(
"follow_user_id",
site.data.metadata?.content?.follow?.user_id,
)
}
}, [site.data, form])
@ -248,6 +266,21 @@ export default function SiteSettingsGeneralPage() {
{...form.register("code_theme_dark")}
/>
</div>
<div className="mt-5 flex gap-6 items-center">
<p className="text-lg font-bold">Follow</p>
<div className="flex gap-3">
<Input
label="Feed ID"
id="follow_feed_id"
{...form.register("follow_feed_id")}
/>
<Input
label="User ID"
id="follow_user_id"
{...form.register("follow_user_id")}
/>
</div>
</div>
<div className="mt-5">
<Input
id="ga"

View File

@ -1,3 +1,5 @@
import RSS from "rss"
import { SITE_URL } from "~/lib/env"
import { getSiteLink } from "~/lib/helpers"
import { NextServerResponse } from "~/lib/server-helper"
@ -38,6 +40,10 @@ export async function GET(
subdomain: site?.handle || "",
domain: site?.metadata?.content?.custom_domain,
})
const followFeedId = site?.metadata?.content?.follow?.feed_id
const followUserId = site?.metadata?.content?.follow?.user_id
const data = {
version: "https://jsonfeed.org/version/1",
title: site?.metadata?.content?.site_name || site?.metadata?.content?.name,
@ -57,6 +63,14 @@ export async function GET(
},
},
}),
...(followFeedId && followUserId
? {
follow_challenge: {
feed_id: followFeedId,
user_id: followUserId,
},
}
: {}),
items: pages.list?.map((page) => ({
id: page.characterId + "-" + page.noteId,
title: page.metadata?.content?.title || "Untitled",
@ -84,13 +98,84 @@ export async function GET(
})),
}
const feed = new RSS({
title:
site?.metadata?.content?.site_name ||
site?.metadata?.content?.name ||
"Untitled",
description: site?.metadata?.content?.bio,
image_url: site?.metadata?.content?.avatars?.[0],
site_url: link,
feed_url: `${link}/feed`,
custom_namespaces: {
itunes: "http://www.itunes.com/dtds/podcast-1.0.dtd",
},
custom_elements: [
...(hasAudio
? [
{ "itunes:image": site?.metadata?.content?.avatars?.[0] },
{
"itunes:author":
site?.metadata?.content?.site_name ||
site?.metadata?.content?.name,
},
{ "itunes:summary": site?.metadata?.content?.bio },
{
"itunes:owner": [
{
"itunes:email": email,
},
{
"itunes:name": site?.metadata?.content?.name,
},
],
},
]
: []),
...(followFeedId && followUserId
? [
{
follow_challenge: [
{ feedId: followFeedId },
{ userId: followUserId },
],
},
,
]
: []),
],
})
pages.list.forEach((page) => {
feed.item({
guid: page.characterId + "-" + page.noteId,
title: page.metadata?.content?.title || "Untitled",
description: page.metadata?.content?.summary,
custom_elements: [
{
"content:encoded": page.metadata?.content?.contentHTML,
},
],
url: `${SITE_URL}/api/redirection?characterId=${page.characterId}&noteId=${page.noteId}`,
date: new Date(page.metadata?.content?.date_published),
categories: page.metadata?.content?.tags,
author: site?.metadata?.content?.name,
enclosure: hasAudio
? {
url: page.metadata?.content?.audio,
type: "audio/mpeg",
}
: undefined,
})
})
const format =
new URLSearchParams(request.url.split("?")[1]).get("format") === "json"
? "json"
: "xml"
const res = new NextServerResponse()
return res.status(200).rss(data, format)
return res.status(200).rss(format === "json" ? data : feed.xml(), format)
}
export const dynamic = "force-dynamic"

View File

@ -277,6 +277,13 @@ export const expandCrossbellCharacter = async (site: CharacterEntity) => {
dark: "github-dark-default",
}
expandedCharacter.metadata.content.follow =
JSON.parse(
(expandedCharacter.metadata?.content?.attributes?.find(
(a: any) => a.trait_type === "xlog_follow",
)?.value as string) || "null",
) || undefined
const getArribute = (outputKey: string, typeKey: string) => {
;(expandedCharacter.metadata.content as any)[outputKey] =
expandedCharacter.metadata?.content?.attributes?.find(

View File

@ -1,6 +1,3 @@
// @ts-ignore
import jsonfeedToRSS from "jsonfeed-to-rss"
export const getQuery = (req: Request) => {
const url = new URL(req.url)
const searchParams = url.searchParams
@ -69,7 +66,7 @@ export class NextServerResponse {
rss(data: any, format = "json") {
if (format === "xml") {
return new Response(jsonfeedToRSS(data), {
return new Response(data, {
status: this.#status,
headers: {
"Content-Type": "application/xml; charset=utf-8",

View File

@ -132,6 +132,10 @@ export type ExpandedCharacter = CharacterEntity & {
light?: BundledTheme
dark?: BundledTheme
}
follow?: {
feed_id?: string
user_id?: string
}
}
}
}

View File

@ -152,6 +152,10 @@ export function useUpdateSite() {
light?: string
dark?: string
}
follow?: {
feed_id?: string
user_id?: string
}
}) => {
if (!input.characterId) {
throw new Error("characterId are required")
@ -222,6 +226,7 @@ export function useUpdateSite() {
}
setAttribute("navigation", "navigation", true)
setAttribute("code_theme", "code_theme", true)
setAttribute("follow", "follow", true)
setAttribute("css", "css")
setAttribute("ga", "ga")
setAttribute("ua", "ua")