mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {useState, useEffect} from 'react'
2import {ImageModel} from 'state/models/media/image'
3import * as apilib from 'lib/api/index'
4import {getLinkMeta} from 'lib/link-meta/link-meta'
5import {
6 getPostAsQuote,
7 getFeedAsEmbed,
8 getListAsEmbed,
9} from 'lib/link-meta/bsky'
10import {downloadAndResize} from 'lib/media/manip'
11import {
12 isBskyPostUrl,
13 isBskyCustomFeedUrl,
14 isBskyListUrl,
15} from 'lib/strings/url-helpers'
16import {ComposerOpts} from 'state/shell/composer'
17import {POST_IMG_MAX} from 'lib/constants'
18import {logger} from '#/logger'
19import {getAgent} from '#/state/session'
20import {useGetPost} from '#/state/queries/post'
21
22export function useExternalLinkFetch({
23 setQuote,
24}: {
25 setQuote: (opts: ComposerOpts['quote']) => void
26}) {
27 const [extLink, setExtLink] = useState<apilib.ExternalEmbedDraft | undefined>(
28 undefined,
29 )
30 const getPost = useGetPost()
31
32 useEffect(() => {
33 let aborted = false
34 const cleanup = () => {
35 aborted = true
36 }
37 if (!extLink) {
38 return cleanup
39 }
40 if (!extLink.meta) {
41 if (isBskyPostUrl(extLink.uri)) {
42 getPostAsQuote(getPost, extLink.uri).then(
43 newQuote => {
44 if (aborted) {
45 return
46 }
47 setQuote(newQuote)
48 setExtLink(undefined)
49 },
50 err => {
51 logger.error('Failed to fetch post for quote embedding', {
52 error: err.toString(),
53 })
54 setExtLink(undefined)
55 },
56 )
57 } else if (isBskyCustomFeedUrl(extLink.uri)) {
58 getFeedAsEmbed(getAgent(), extLink.uri).then(
59 ({embed, meta}) => {
60 if (aborted) {
61 return
62 }
63 setExtLink({
64 uri: extLink.uri,
65 isLoading: false,
66 meta,
67 embed,
68 })
69 },
70 err => {
71 logger.error('Failed to fetch feed for embedding', {error: err})
72 setExtLink(undefined)
73 },
74 )
75 } else if (isBskyListUrl(extLink.uri)) {
76 getListAsEmbed(getAgent(), extLink.uri).then(
77 ({embed, meta}) => {
78 if (aborted) {
79 return
80 }
81 setExtLink({
82 uri: extLink.uri,
83 isLoading: false,
84 meta,
85 embed,
86 })
87 },
88 err => {
89 logger.error('Failed to fetch list for embedding', {error: err})
90 setExtLink(undefined)
91 },
92 )
93 } else {
94 getLinkMeta(getAgent(), extLink.uri).then(meta => {
95 if (aborted) {
96 return
97 }
98 setExtLink({
99 uri: extLink.uri,
100 isLoading: !!meta.image,
101 meta,
102 })
103 })
104 }
105 return cleanup
106 }
107 if (extLink.isLoading && extLink.meta?.image && !extLink.localThumb) {
108 downloadAndResize({
109 uri: extLink.meta.image,
110 width: POST_IMG_MAX.width,
111 height: POST_IMG_MAX.height,
112 mode: 'contain',
113 maxSize: POST_IMG_MAX.size,
114 timeout: 15e3,
115 })
116 .catch(() => undefined)
117 .then(localThumb => {
118 if (aborted) {
119 return
120 }
121 setExtLink({
122 ...extLink,
123 isLoading: false, // done
124 localThumb: localThumb ? new ImageModel(localThumb) : undefined,
125 })
126 })
127 return cleanup
128 }
129 if (extLink.isLoading) {
130 setExtLink({
131 ...extLink,
132 isLoading: false, // done
133 })
134 }
135 return cleanup
136 }, [extLink, setQuote, getPost])
137
138 return {extLink, setExtLink}
139}