@@ -14,6 +14,7 @@ import {
14
14
escapeQuotationMarks ,
15
15
formatDate ,
16
16
getHighlightLocation ,
17
+ HighlightType ,
17
18
loadArticles ,
18
19
loadDeletedArticleSlugs ,
19
20
PageType ,
@@ -45,6 +46,7 @@ interface Settings {
45
46
highlightTemplate : string
46
47
loading : boolean
47
48
syncJobId : number
49
+ endpoint : string
48
50
}
49
51
50
52
const siteNameFromUrl = ( originalArticleUrl : string ) : string => {
@@ -95,6 +97,7 @@ const fetchOmnivore = async (inBackground = false) => {
95
97
highlightTemplate,
96
98
graph,
97
99
loading,
100
+ endpoint,
98
101
} = logseq . settings as Settings
99
102
// prevent multiple fetches
100
103
if ( loading ) {
@@ -180,7 +183,8 @@ const fetchOmnivore = async (inBackground = false) => {
180
183
parseDateTime ( syncAt ) . toISO ( ) ,
181
184
getQueryFromFilter ( filter , customQuery ) ,
182
185
true ,
183
- 'markdown'
186
+ 'markdown' ,
187
+ endpoint
184
188
)
185
189
186
190
const articleBatch : IBatchBlock [ ] = [ ]
@@ -194,8 +198,11 @@ const fetchOmnivore = async (inBackground = false) => {
194
198
const datePublished = article . publishedAt
195
199
? formatDate ( new Date ( article . publishedAt ) , preferredDateFormat )
196
200
: undefined
201
+ const note = article . highlights ?. find (
202
+ ( h ) => h . type === HighlightType . Note
203
+ )
197
204
// Build content string based on template
198
- const articleView = {
205
+ const articleVariables = {
199
206
title : article . title ,
200
207
omnivoreUrl : `https://omnivore.app/me/${ article . slug } ` ,
201
208
siteName,
@@ -205,12 +212,15 @@ const fetchOmnivore = async (inBackground = false) => {
205
212
dateSaved,
206
213
content : article . content ,
207
214
datePublished,
215
+ note : note ?. annotation ,
208
216
}
209
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
210
- const content = render ( articleTemplate , articleView )
217
+ // filter out notes and redactions
218
+ const highlights = article . highlights ?. filter (
219
+ ( h ) => h . type === HighlightType . Highlight
220
+ )
211
221
// sort highlights by location if selected in options
212
- highlightOrder === HighlightOrder . LOCATION &&
213
- article . highlights ?. sort ( ( a , b ) => {
222
+ if ( highlightOrder === HighlightOrder . LOCATION ) {
223
+ highlights ?. sort ( ( a , b ) => {
214
224
try {
215
225
if ( article . pageType === PageType . File ) {
216
226
// sort by location in file
@@ -225,12 +235,13 @@ const fetchOmnivore = async (inBackground = false) => {
225
235
return compareHighlightsInFile ( a , b )
226
236
}
227
237
} )
228
- const highlightBatch : ( IBatchBlock & { id : string } ) [ ] =
229
- article . highlights ?. map ( ( it ) => {
238
+ }
239
+ const highlightBatch : IBatchBlock [ ] =
240
+ highlights ?. map ( ( it ) => {
230
241
// Build content string based on template
231
242
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
232
243
const content = render ( highlightTemplate , {
233
- ...articleView ,
244
+ ...articleVariables ,
234
245
text : it . quote ,
235
246
labels : it . labels ,
236
247
highlightUrl : `https://omnivore.app/me/${ article . slug } #${ it . id } ` ,
@@ -245,7 +256,9 @@ const fetchOmnivore = async (inBackground = false) => {
245
256
return {
246
257
content,
247
258
children : noteChild ? [ noteChild ] : undefined ,
248
- id : it . id ,
259
+ properties : {
260
+ id : it . id ,
261
+ } ,
249
262
}
250
263
} ) || [ ]
251
264
@@ -265,45 +278,48 @@ const fetchOmnivore = async (inBackground = false) => {
265
278
[(clojure.string/includes? ?c "${ article . slug } ")]]`
266
279
)
267
280
) . flat ( )
281
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
282
+ const articleContent = render ( articleTemplate , articleVariables )
268
283
if ( existingBlocks . length > 0 ) {
269
284
isNewArticle = false
270
285
const existingBlock = existingBlocks [ 0 ]
271
286
// update the first existing block
272
- if ( existingBlock . content !== content ) {
273
- await logseq . Editor . updateBlock ( existingBlock . uuid , content )
287
+ if ( existingBlock . content !== articleContent ) {
288
+ await logseq . Editor . updateBlock ( existingBlock . uuid , articleContent )
274
289
}
275
290
// delete the rest of the existing blocks
276
291
await deleteBlocks ( existingBlocks . slice ( 1 ) )
277
- if ( highlightBatch . length > 0 ) {
278
- // append highlights to existing block
279
- for ( const highlight of highlightBatch ) {
280
- const existingHighlights = (
281
- await logseq . DB . datascriptQuery < BlockEntity [ ] > (
282
- `[:find (pull ?b [*])
292
+ // append highlights to existing block
293
+ for ( const highlight of highlightBatch ) {
294
+ const existingHighlights = (
295
+ await logseq . DB . datascriptQuery < BlockEntity [ ] > (
296
+ `[:find (pull ?b [*])
283
297
:where
284
298
[?b :block/parent ?p]
285
299
[?p :block/uuid ?u]
286
300
[(str ?u) ?s]
287
301
[(= ?s "${ existingBlock . uuid } ")]
288
302
[?b :block/content ?c]
289
- [(clojure.string/includes? ?c "${ highlight . id } ")]]`
290
- )
291
- ) . flat ( )
292
- if ( existingHighlights . length > 0 ) {
293
- const existingHighlight = existingHighlights [ 0 ]
294
- // update existing highlight if content is different
295
- existingHighlight . content !== highlight . content &&
296
- ( await logseq . Editor . updateBlock (
297
- existingHighlight . uuid ,
298
- highlight . content
299
- ) )
300
-
301
- // checking notes
302
- const noteChild = highlight . children ?. [ 0 ]
303
- if ( noteChild ) {
304
- const existingNotes = (
305
- await logseq . DB . datascriptQuery < BlockEntity [ ] > (
306
- `[:find (pull ?b [*])
303
+ [(clojure.string/includes? ?c "${
304
+ highlight . properties ?. id as string
305
+ } ")]]`
306
+ )
307
+ ) . flat ( )
308
+ if ( existingHighlights . length > 0 ) {
309
+ const existingHighlight = existingHighlights [ 0 ]
310
+ // update existing highlight if content is different
311
+ existingHighlight . content !== highlight . content &&
312
+ ( await logseq . Editor . updateBlock (
313
+ existingHighlight . uuid ,
314
+ highlight . content
315
+ ) )
316
+
317
+ // checking notes
318
+ const noteChild = highlight . children ?. [ 0 ]
319
+ if ( noteChild ) {
320
+ const existingNotes = (
321
+ await logseq . DB . datascriptQuery < BlockEntity [ ] > (
322
+ `[:find (pull ?b [*])
307
323
:where
308
324
[?b :block/parent ?p]
309
325
[?p :block/uuid ?u]
@@ -313,32 +329,31 @@ const fetchOmnivore = async (inBackground = false) => {
313
329
[(= ?c "${ escapeQuotationMarks (
314
330
noteChild . content
315
331
) } ")]]`
316
- )
317
- ) . flat ( )
318
- if ( existingNotes . length == 0 ) {
319
- // append new note
320
- await logseq . Editor . insertBlock (
321
- existingHighlight . uuid ,
322
- noteChild . content ,
323
- { sibling : false }
324
- )
325
- }
332
+ )
333
+ ) . flat ( )
334
+ if ( existingNotes . length == 0 ) {
335
+ // append new note
336
+ await logseq . Editor . insertBlock (
337
+ existingHighlight . uuid ,
338
+ noteChild . content ,
339
+ { sibling : false }
340
+ )
326
341
}
327
- } else {
328
- // append new highlight
329
- await logseq . Editor . insertBatchBlock (
330
- existingBlock . uuid ,
331
- highlight ,
332
- { sibling : false }
333
- )
334
342
}
343
+ } else {
344
+ // append new highlight
345
+ await logseq . Editor . insertBatchBlock (
346
+ existingBlock . uuid ,
347
+ highlight ,
348
+ { sibling : false }
349
+ )
335
350
}
336
351
}
337
352
}
338
353
339
354
isNewArticle &&
340
355
articleBatch . unshift ( {
341
- content,
356
+ content : articleContent ,
342
357
children : highlightBatch ,
343
358
} )
344
359
}
@@ -360,7 +375,8 @@ const fetchOmnivore = async (inBackground = false) => {
360
375
apiKey ,
361
376
after ,
362
377
size ,
363
- parseDateTime ( syncAt ) . toISO ( )
378
+ parseDateTime ( syncAt ) . toISO ( ) ,
379
+ endpoint
364
380
)
365
381
366
382
for ( const slug of deletedArticleSlugs ) {
@@ -517,7 +533,7 @@ const main = async (baseInfo: LSPluginBaseInfo) => {
517
533
type : 'string' ,
518
534
title : 'Enter the template to use for new articles' ,
519
535
description :
520
- 'Enter the template to use for new articles. Required variables are: {{{ title}}}, {{{ omnivoreUrl}}} . Optional variables are: {{{ siteName}}}, {{{ originalUrl}}}, {{{ author}}}, {{{ labels}}}, {{{ dateSaved}}}, {{{ datePublished}}} ' ,
536
+ 'We use {{ mustache }} template: http://mustache.github.io/mustache.5.html. Required variables are: title, omnivoreUrl. Optional variables are: siteName, originalUrl, author, labels, dateSaved, datePublished, note ' ,
521
537
default : `[{{{title}}}]({{{omnivoreUrl}}})
522
538
collapsed:: true
523
539
site:: {{#siteName}}[{{{siteName}}}]{{/siteName}}({{{originalUrl}}})
@@ -538,10 +554,17 @@ date-published:: {{{datePublished}}}
538
554
type : 'string' ,
539
555
title : 'Enter the template to use for new highlights' ,
540
556
description :
541
- 'Enter the template to use for new highlights. Required variables are: {{{ text}}}, {{{ highlightUrl}}} . Optional variables are {{{ dateHighlighted}}} . You can also use the variables in the article template.' ,
557
+ 'We use {{ mustache }} template: http://mustache.github.io/mustache.5.html. Required variables are: text, highlightUrl. Optional variables are dateHighlighted. You can also use the variables in the article template.' ,
542
558
default : `> {{{text}}} [⤴️]({{{highlightUrl}}}) {{#labels}} #[[{{{name}}}]] {{/labels}}` ,
543
559
inputAs : 'textarea' ,
544
560
} ,
561
+ {
562
+ key : 'endpoint' ,
563
+ type : 'string' ,
564
+ title : 'API Endpoint' ,
565
+ description : "Enter the Omnivore server's API endpoint" ,
566
+ default : 'https://api-prod.omnivore.app/api/graphql' ,
567
+ } ,
545
568
]
546
569
logseq . useSettingsSchema ( settingsSchema )
547
570
0 commit comments