@@ -5,6 +5,8 @@ import Closer from "../../components/closer"
55import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs"
66import showError from "../../components/error"
77
8+ const requestFrequency = 100
9+
810interface ISuggestionDetails {
911 myFollowersCount : number
1012 folledByMe : boolean
@@ -13,15 +15,21 @@ interface ISuggestionDetails {
1315}
1416
1517const Bsky = ( ) => {
18+ // START: GENERIC STATE
19+ // This kind of state is likely to be used in most applications.
1620 const handleRef = useRef < HTMLInputElement | null > ( null )
1721 const [ searchParams , setSearchParams ] =
1822 typeof window !== "undefined"
1923 ? useSearchParams ( )
2024 : [ new URLSearchParams ( ) , ( ) => { } ]
2125 const [ error , setError ] = useState < React . ReactNode > ( )
26+ // END: GENERIC STATE
27+
28+ // START: APPLICATION STATE
29+ // Reset all of this stuff whenever there is an error
30+ // or whenever the user does something that implies a page refesh.
2231 const [ following , setFollowing ] = useState < string [ ] > ( [ ] )
2332 const [ followingCopy , setMyFollowingCopy ] = useState < string [ ] > ( [ ] )
24- const [ showFollowedByMe , setShowFollowedByMe ] = useState < boolean > ( true )
2533 const [ suggestionCount , setSuggestionCount ] = useState < {
2634 [ key : string ] : number
2735 } > ( { } )
@@ -34,9 +42,22 @@ const Bsky = () => {
3442 const [ suggestionDetailsByScore , setSuggestionDetailsByScore ] = useState <
3543 ISuggestionDetails [ ]
3644 > ( [ ] )
37- const [ showDetailsByScore , setShowDetailsByScore ] = useState < boolean > ( false )
45+ const clearApplicationState = ( ) => {
46+ setFollowing ( [ ] )
47+ setMyFollowingCopy ( [ ] )
48+ setSuggestionCount ( { } )
49+ setSuggestionCountSorted ( [ ] )
50+ setSuggestionDetails ( [ ] )
51+ setSuggestionDetailsByScore ( [ ] )
52+ }
53+ // END: APPLICATION STATE
3854
39- const requestFrequency = 100
55+ // START: UI STATE
56+ // This is similar to the application state,
57+ // different in that it doesn't need to be reset.
58+ const [ showFollowedByMe , setShowFollowedByMe ] = useState < boolean > ( true )
59+ const [ showDetailsByScore , setShowDetailsByScore ] = useState < boolean > ( false )
60+ // END: UI STATE
4061
4162 // Get the "handle" query parameter.
4263 // This should eventually be replaced with a user input field.
@@ -45,22 +66,18 @@ const Bsky = () => {
4566 const myHandle = searchParams . get ( "handle" )
4667
4768 // Get the list of people that I follow.
48- const handleFollowing = async ( ) => {
49- try {
50- const response = await fetch (
51- `${ process . env . GATSBY_API_URL } /bsky/${ myHandle } /following/handles`
52- )
53- if ( ! response . ok ) {
54- throw new Error ( await response . text ( ) )
55- }
56- const data : string [ ] = await response . json ( )
57- // This is done to prevent the same handles from being suggested in the same order.
58- const dataRandomized = [ ...new Set ( data . sort ( ( ) => Math . random ( ) - 0.5 ) ) ]
59- setFollowing ( ( ) => dataRandomized )
60- setMyFollowingCopy ( ( ) => dataRandomized )
61- } catch ( error ) {
62- showError ( setError , error . toString ( ) )
69+ const handleFollowing = async ( handle : string ) => {
70+ const response = await fetch (
71+ `${ process . env . GATSBY_API_URL } /bsky/${ handle } /following/handles`
72+ )
73+ if ( ! response . ok ) {
74+ clearApplicationState ( )
75+ showError ( setError , response )
76+ return
6377 }
78+ const data : string [ ] = await response . json ( )
79+ setFollowing ( ( ) => data )
80+ setMyFollowingCopy ( ( ) => data )
6481 }
6582
6683 // When you have my followers ...
@@ -82,37 +99,35 @@ const Bsky = () => {
8299 // - C: 2
83100 // - D: 1
84101 const handleSuggestionCounts = async ( ) => {
85- try {
86- var myFollowingCopy = [ ...following ]
87- const myFollowingHandle = myFollowingCopy . pop ( )
102+ var myFollowingCopy = [ ...following ]
103+ const myFollowingHandle = myFollowingCopy . pop ( )
104+
105+ // Get for a person that I follow, get a list of the people they follow
106+ const response = await fetch (
107+ `${ process . env . GATSBY_API_URL } /bsky/${ myFollowingHandle } /following/handles`
108+ )
109+ if ( ! response . ok ) {
110+ clearApplicationState ( )
111+ showError ( setError , response )
112+ return
113+ }
114+ const data : string [ ] = await response . json ( )
88115
89- // Get for a person that I follow, get a list of the people they follow
90- const response = await fetch (
91- `${ process . env . GATSBY_API_URL } /bsky/${ myFollowingHandle } /following/handles`
116+ // Generate a "suggestionCount" int for each handle that they follow
117+ // If the handle is already in the suggestions, increment the count.
118+ var suggestionsCopy = { ...suggestionCount }
119+ data . forEach ( ( theirFollowingHandle ) => {
120+ const validHandle = ! [ myHandle , "handle.invalid" , "" ] . includes (
121+ theirFollowingHandle
92122 )
93- if ( ! response . ok ) {
94- throw new Error ( await response . text ( ) )
123+ if ( validHandle ) {
124+ var suggestionCount = suggestionsCopy [ theirFollowingHandle ]
125+ suggestionCount = suggestionCount ? suggestionCount + 1 : 1
126+ suggestionsCopy [ theirFollowingHandle ] = suggestionCount
95127 }
96- const data : string [ ] = await response . json ( )
97-
98- // Generate a "suggestionCount" int for each handle that they follow
99- // If the handle is already in the suggestions, increment the count.
100- var suggestionsCopy = { ...suggestionCount }
101- data . forEach ( ( theirFollowingHandle ) => {
102- const validHandle = ! [ myHandle , "handle.invalid" , "" ] . includes (
103- theirFollowingHandle
104- )
105- if ( validHandle ) {
106- var suggestionCount = suggestionsCopy [ theirFollowingHandle ]
107- suggestionCount = suggestionCount ? suggestionCount + 1 : 1
108- suggestionsCopy [ theirFollowingHandle ] = suggestionCount
109- }
110- } )
111- setSuggestionCount ( ( ) => suggestionsCopy )
112- setFollowing ( ( ) => myFollowingCopy )
113- } catch ( error ) {
114- showError ( setError , error . toString ( ) )
115- }
128+ } )
129+ setSuggestionCount ( ( ) => suggestionsCopy )
130+ setFollowing ( ( ) => myFollowingCopy )
116131 }
117132
118133 // When you have the suggestionomendation counts ...
@@ -170,63 +185,61 @@ const Bsky = () => {
170185 // "Details" here means any profile information required to
171186 // display the suggestion to the user.
172187 const handleSuggestionDetails = async ( ) => {
173- try {
174- const suggestionDetailsCopy = [ ...suggestionDetails ]
175- const suggestionCountSortedCopy = [ ...suggestionCountSorted ]
176- const shiftedItem = suggestionCountSortedCopy . shift ( )
188+ const suggestionDetailsCopy = [ ...suggestionDetails ]
189+ const suggestionCountSortedCopy = [ ...suggestionCountSorted ]
190+ const shiftedItem = suggestionCountSortedCopy . shift ( )
177191
178- if ( ! shiftedItem ) {
179- console . error ( "No handle found to process." )
180- suggestionCountSortedCopy . pop ( )
181- setSuggestionCountSorted ( ( ) => suggestionCountSortedCopy )
182- return
183- }
192+ if ( ! shiftedItem ) {
193+ console . error ( "No handle found to process." )
194+ suggestionCountSortedCopy . pop ( )
195+ setSuggestionCountSorted ( ( ) => suggestionCountSortedCopy )
196+ return
197+ }
184198
185- const [ handle , myFollowers ] = shiftedItem
186- if ( ! handle ) {
187- console . error ( "No handle found to process." )
188- suggestionCountSortedCopy . pop ( )
189- setSuggestionCountSorted ( ( ) => suggestionCountSortedCopy )
190- return
191- }
199+ const [ handle , myFollowers ] = shiftedItem
200+ if ( ! handle ) {
201+ console . error ( "No handle found to process." )
202+ suggestionCountSortedCopy . pop ( )
203+ setSuggestionCountSorted ( ( ) => suggestionCountSortedCopy )
204+ return
205+ }
192206
193- const tooManyDetails = suggestionDetailsCopy . length > 250
194- if ( tooManyDetails ) {
195- console . log ( "Too many details" )
196- setSuggestionCountSorted ( [ ] )
197- return
198- }
207+ const tooManyDetails = suggestionDetailsCopy . length > 250
208+ if ( tooManyDetails ) {
209+ console . log ( "Too many details" )
210+ setSuggestionCountSorted ( [ ] )
211+ return
212+ }
199213
200- const tooFewFollowers = followingCopy . length / 10 > myFollowers
201- if ( tooFewFollowers ) {
202- console . log ( "handle =>" , handle )
203- console . log ( "Too few followers =>" , followingCopy . length , myFollowers )
204- setSuggestionCountSorted ( [ ] )
205- return
206- }
214+ const tooFewFollowers = followingCopy . length / 10 > myFollowers
215+ if ( tooFewFollowers ) {
216+ console . log ( "handle =>" , handle )
217+ console . log ( "Too few followers =>" , followingCopy . length , myFollowers )
218+ setSuggestionCountSorted ( [ ] )
219+ return
220+ }
207221
208- const response = await fetch (
209- `${ process . env . GATSBY_API_URL } /bsky/${ handle } /profile`
210- )
211- if ( ! response . ok ) {
212- throw new Error ( await response . text ( ) )
213- }
214- const data : { [ key : string ] : ProfileViewDetailed } = await response . json ( )
215- const profile : ProfileViewDetailed = Object . values ( data ) [ 0 ]
222+ const response = await fetch (
223+ `${ process . env . GATSBY_API_URL } /bsky/${ handle } /profile`
224+ )
225+ if ( ! response . ok ) {
226+ clearApplicationState ( )
227+ showError ( setError , response )
228+ return
229+ }
230+ const data : { [ key : string ] : ProfileViewDetailed } = await response . json ( )
231+ const profile : ProfileViewDetailed = Object . values ( data ) [ 0 ]
216232
217- suggestionDetailsCopy . push ( {
218- myFollowersCount : myFollowers ,
219- score : myFollowers / ( profile . followersCount ?? 1 ) ,
220- profile : profile ,
221- folledByMe : followingCopy . includes ( profile . handle ) ,
222- } )
233+ suggestionDetailsCopy . push ( {
234+ myFollowersCount : myFollowers ,
235+ score : myFollowers / ( profile . followersCount ?? 1 ) ,
236+ profile : profile ,
237+ folledByMe : followingCopy . includes ( profile . handle ) ,
238+ } )
223239
224- suggestionCountSortedCopy . pop ( )
225- setSuggestionCountSorted ( ( ) => suggestionCountSortedCopy )
226- setSuggestionDetails ( ( ) => suggestionDetailsCopy )
227- } catch ( error ) {
228- showError ( setError , error . toString ( ) )
229- }
240+ suggestionCountSortedCopy . pop ( )
241+ setSuggestionCountSorted ( ( ) => suggestionCountSortedCopy )
242+ setSuggestionDetails ( ( ) => suggestionDetailsCopy )
230243 }
231244
232245 // When you have the suggestionomendation details ...
@@ -380,7 +393,7 @@ const Bsky = () => {
380393 }
381394 onClick = { ( ) => {
382395 setSearchParams ( { handle : handleRef . current ?. value || "" } )
383- handleFollowing ( )
396+ handleFollowing ( handleRef . current ?. value || "" )
384397 } }
385398 >
386399 Suggest!
0 commit comments