@@ -43,7 +43,8 @@ const cleanupDataFields = async (notionResponse) => {
4343 pages,
4444 current_page,
4545 situ,
46- review,
46+ review, // will be deprecated once I fully migrate to reviewed
47+ reviewed,
4748 link,
4849 } = book . properties ;
4950
@@ -56,32 +57,52 @@ const cleanupDataFields = async (notionResponse) => {
5657 }
5758 if ( author . select !== null ) cleanBook . author = author . select . name ;
5859 if ( ISBN . number !== null ) cleanBook . isbn = ISBN . number ;
59- if ( started . date !== null ) cleanBook . started = started . date . start ;
60- if ( finished && finished . date !== null ) {
60+ if ( started ? .date !== null ) cleanBook . started = started . date . start ;
61+ if ( finished ? .date !== null ) {
6162 cleanBook . finished = finished . date . start ;
6263 }
63- if ( publisher && publisher . select !== null ) {
64+ if ( publisher ? .select !== null ) {
6465 cleanBook . publisher = publisher . select . name ;
6566 }
66- if ( pages && pages . number !== null ) {
67+ if ( pages ? .number !== null ) {
6768 cleanBook . pages = pages . number ;
6869 }
69- if ( current_page && current_page . number !== null ) {
70+ if ( current_page ? .number !== null ) {
7071 cleanBook . current_page = current_page . number ;
7172 }
7273
7374 if ( cleanBook . finished ) {
7475 const finalPath = await possiblySaveNewSituImage ( title , finished , situ ) ;
7576 if ( finalPath ) cleanBook . situ = finalPath ;
7677 }
77- if ( review && review . rich_text . length > 0 ) {
78+ if ( review ? .rich_text . length > 0 ) {
7879 // Necessary to stitch rich_text components together like this to preserve any hyperlinks
79- cleanBook . review = review . rich_text . reduce ( ( finalText , current ) => {
80- if ( current . type !== "text" ) return finalText ;
81- if ( current . href === null ) return ( finalText += current . plain_text ) ;
82- return ( finalText += `<a href=\"${ current . href } \">${ current . plain_text } </a>` ) ;
83- } , "" ) ;
80+ cleanBook . review = reduceRichTextToHTMLString ( review . rich_text ) ;
8481 }
82+
83+ /**
84+ * Setting up some more robust review infrastructure here alongside the existing one.
85+ *
86+ * Here's the loose plan:
87+ * 1. If there is no review, but there are blocks, then parse and squish all the blocks together as the review
88+ * 2. Once this is working properly, we can shift the review data from a property to entirely this.
89+ *
90+ * Note that final state is not necessarily easiest implementation for this code, but for my personal workflow.
91+ */
92+
93+ if ( reviewed ?. checkbox === true ) {
94+ const pageBlocks = await notion . blocks . children . list ( {
95+ block_id : book . id ,
96+ page_size : 100 ,
97+ } ) ;
98+ if ( pageBlocks . results . length > 0 ) {
99+ const htmlReview = reduceBlocksToSingleHTMLString ( pageBlocks . results ) ;
100+ if ( htmlReview !== "" ) {
101+ cleanBook . review = htmlReview ;
102+ }
103+ }
104+ }
105+
85106 if ( link && link . url !== null ) cleanBook . link = link . url ;
86107
87108 return cleanBook ;
@@ -90,6 +111,52 @@ const cleanupDataFields = async (notionResponse) => {
90111 return Promise . all ( cleanBooks ) ;
91112} ;
92113
114+ const annotationsWrapper = ( text , annotations ) => {
115+ const applicable = Object . keys ( annotations ) . filter (
116+ ( x ) => annotations [ x ] === true ,
117+ ) ;
118+ if ( applicable . length === 0 ) return text ;
119+
120+ let finalText = text ;
121+ for ( const annotation of applicable ) {
122+ if ( annotation === "bold" ) finalText = `<strong>${ finalText } </strong>` ;
123+ if ( annotation === "italic" ) finalText = `<em>${ finalText } </em>` ;
124+ if ( annotation === "underline" ) finalText = `<u>${ finalText } </u>` ;
125+ if ( annotation === "strikethrough" ) finalText = `<s>${ finalText } </s>` ;
126+ if ( annotation === "code" ) finalText = `<code>${ finalText } </code>` ;
127+ }
128+
129+ return finalText ;
130+ } ;
131+
132+ const reduceRichTextToHTMLString = ( richTextArray ) => {
133+ return richTextArray . reduce ( ( finalText , current ) => {
134+ if ( current . type !== "text" ) return finalText ;
135+ if ( current . href === null ) {
136+ return ( finalText += annotationsWrapper (
137+ current . plain_text ,
138+ current . annotations ,
139+ ) ) ;
140+ }
141+ return ( finalText += `<a href=\"${ current . href } \">${ annotationsWrapper ( current . plain_text , current . annotations ) } </a>` ) ;
142+ } , "" ) ;
143+ } ;
144+
145+ const reduceBlocksToSingleHTMLString = ( blockList ) => {
146+ return blockList . reduce ( ( finalText , currentBlock ) => {
147+ // Only supporting these two types for now
148+ if ( ! [ "paragraph" , "quote" ] . includes ( currentBlock . type ) ) {
149+ return finalText ;
150+ }
151+ if ( currentBlock . type === "paragraph" ) {
152+ return ( finalText += `<p>${ reduceRichTextToHTMLString ( currentBlock . paragraph . rich_text ) } </p>` ) ;
153+ }
154+ if ( currentBlock . type === "quote" ) {
155+ return ( finalText += `<blockquote><p>${ reduceRichTextToHTMLString ( currentBlock . quote . rich_text ) } </p></blockquote>` ) ;
156+ }
157+ } , "" ) ;
158+ } ;
159+
93160const possiblySaveNewSituImage = async ( title , finished , situ ) => {
94161 if ( ! finished || finished . date === null || ! title . title ) {
95162 return ;
0 commit comments