@@ -43,6 +43,7 @@ interface Settings {
43
43
pageName : string
44
44
articleTemplate : string
45
45
highlightTemplate : string
46
+ loading : boolean
46
47
}
47
48
48
49
const siteNameFromUrl = ( originalArticleUrl : string ) : string => {
@@ -54,7 +55,6 @@ const siteNameFromUrl = (originalArticleUrl: string): string => {
54
55
}
55
56
56
57
const delay = ( t = 100 ) => new Promise ( ( r ) => setTimeout ( r , t ) )
57
- let loading = false
58
58
59
59
const getQueryFromFilter = ( filter : Filter , customQuery : string ) : string => {
60
60
switch ( filter ) {
@@ -76,9 +76,13 @@ const isValidCurrentGraph = async (): Promise<boolean> => {
76
76
return currentGraph ?. name === settings . graph
77
77
}
78
78
79
- const fetchOmnivore = async ( inBackground = false ) => {
80
- if ( loading ) return
79
+ const deleteBlocks = async ( blocks : BlockEntity [ ] ) => {
80
+ for await ( const block of blocks ) {
81
+ await logseq . Editor . removeBlock ( block . uuid )
82
+ }
83
+ }
81
84
85
+ const fetchOmnivore = async ( inBackground = false ) => {
82
86
const {
83
87
syncAt,
84
88
apiKey,
@@ -89,7 +93,16 @@ const fetchOmnivore = async (inBackground = false) => {
89
93
articleTemplate,
90
94
highlightTemplate,
91
95
graph,
96
+ loading,
92
97
} = logseq . settings as Settings
98
+ // prevent multiple fetches
99
+ if ( loading ) {
100
+ await logseq . UI . showMsg ( 'Omnivore is already syncing' , 'warning' , {
101
+ timeout : 3000 ,
102
+ } )
103
+ return
104
+ }
105
+ logseq . updateSettings ( { loading : true } )
93
106
94
107
if ( ! apiKey ) {
95
108
await logseq . UI . showMsg ( 'Missing Omnivore api key' , 'warning' , {
@@ -119,15 +132,17 @@ const fetchOmnivore = async (inBackground = false) => {
119
132
120
133
await delay ( 300 )
121
134
122
- loading = true
123
135
let targetBlock : BlockEntity | null = null
124
136
const userConfigs = await logseq . App . getUserConfigs ( )
125
137
const preferredDateFormat : string = userConfigs . preferredDateFormat
138
+ const fetchingMsgKey = 'omnivore-fetching'
126
139
127
140
try {
128
141
console . log ( `logseq-omnivore starting sync since: '${ syncAt } ` )
129
-
130
- ! inBackground && ( await logseq . UI . showMsg ( '🚀 Fetching articles ...' ) )
142
+ ! inBackground &&
143
+ ( await logseq . UI . showMsg ( fetchingTitle , 'success' , {
144
+ key : fetchingMsgKey ,
145
+ } ) )
131
146
132
147
let omnivorePage = await logseq . Editor . getPage ( pageName )
133
148
if ( ! omnivorePage ) {
@@ -175,9 +190,11 @@ const fetchOmnivore = async (inBackground = false) => {
175
190
new Date ( article . savedAt ) ,
176
191
preferredDateFormat
177
192
)
193
+ const datePublished = article . publishedAt
194
+ ? formatDate ( new Date ( article . publishedAt ) , preferredDateFormat )
195
+ : undefined
178
196
// Build content string based on template
179
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
180
- const content = render ( articleTemplate , {
197
+ const articleView = {
181
198
title : article . title ,
182
199
omnivoreUrl : `https://omnivore.app/me/${ article . slug } ` ,
183
200
siteName,
@@ -186,8 +203,10 @@ const fetchOmnivore = async (inBackground = false) => {
186
203
labels : article . labels ,
187
204
dateSaved,
188
205
content : article . content ,
189
- } )
190
-
206
+ datePublished,
207
+ }
208
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
209
+ const content = render ( articleTemplate , articleView )
191
210
// sort highlights by location if selected in options
192
211
highlightOrder === HighlightOrder . LOCATION &&
193
212
article . highlights ?. sort ( ( a , b ) => {
@@ -210,6 +229,7 @@ const fetchOmnivore = async (inBackground = false) => {
210
229
// Build content string based on template
211
230
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
212
231
const content = render ( highlightTemplate , {
232
+ ...articleView ,
213
233
text : it . quote ,
214
234
labels : it . labels ,
215
235
highlightUrl : `https://omnivore.app/me/${ article . slug } #${ it . id } ` ,
@@ -247,10 +267,12 @@ const fetchOmnivore = async (inBackground = false) => {
247
267
if ( existingBlocks . length > 0 ) {
248
268
isNewArticle = false
249
269
const existingBlock = existingBlocks [ 0 ]
250
- // update existing block
270
+ // update the first existing block
251
271
if ( existingBlock . content !== content ) {
252
272
await logseq . Editor . updateBlock ( existingBlock . uuid , content )
253
273
}
274
+ // delete the rest of the existing blocks
275
+ await deleteBlocks ( existingBlocks . slice ( 1 ) )
254
276
if ( highlightBatch . length > 0 ) {
255
277
// append highlights to existing block
256
278
for ( const highlight of highlightBatch ) {
@@ -357,21 +379,26 @@ const fetchOmnivore = async (inBackground = false) => {
357
379
) . flat ( )
358
380
359
381
if ( existingBlocks . length > 0 ) {
360
- await logseq . Editor . removeBlock ( existingBlocks [ 0 ] . uuid )
382
+ await deleteBlocks ( existingBlocks )
361
383
}
362
384
}
363
385
}
364
386
365
- ! inBackground && ( await logseq . UI . showMsg ( '🔖 Articles fetched' ) )
387
+ if ( ! inBackground ) {
388
+ logseq . UI . closeMsg ( fetchingMsgKey )
389
+ await logseq . UI . showMsg ( '🔖 Articles fetched' , 'success' , {
390
+ timeout : 2000 ,
391
+ } )
392
+ }
366
393
logseq . updateSettings ( { syncAt : DateTime . local ( ) . toFormat ( DATE_FORMAT ) } )
367
394
} catch ( e ) {
368
395
! inBackground &&
369
- ( await logseq . UI . showMsg ( 'Failed to fetch articles' , 'warning ' ) )
396
+ ( await logseq . UI . showMsg ( 'Failed to fetch articles' , 'error ' ) )
370
397
console . error ( e )
371
398
} finally {
372
- loading = false
373
399
targetBlock &&
374
400
( await logseq . Editor . updateBlock ( targetBlock . uuid , blockTitle ) )
401
+ logseq . updateSettings ( { loading : false } )
375
402
}
376
403
}
377
404
@@ -477,26 +504,29 @@ const main = async (baseInfo: LSPluginBaseInfo) => {
477
504
type : 'string' ,
478
505
title : 'Enter the template to use for new articles' ,
479
506
description :
480
- 'Enter the template to use for new articles. Required variables are: {{{title}}}, {{{omnivoreUrl}}}. Optional variables are: {{{siteName}}}, {{{originalUrl}}}, {{{author}}}, {{{labels}}}, {{{dateSaved}}}' ,
507
+ 'Enter the template to use for new articles. Required variables are: {{{title}}}, {{{omnivoreUrl}}}. Optional variables are: {{{siteName}}}, {{{originalUrl}}}, {{{author}}}, {{{labels}}}, {{{dateSaved}}}, {{{datePublished}}} ' ,
481
508
default : `[{{{title}}}]({{{omnivoreUrl}}})
482
- collapsed:: true
483
- site:: {{#siteName}}[{{{siteName}}}]{{/siteName}}({{{originalUrl}}})
484
- {{#author}}
485
- author:: {{{author}}}
486
- {{/author}}
487
- {{#labels.length}}
488
- labels:: {{#labels}}[[{{{name}}}]]{{/labels}}
489
- {{/labels.length}}
490
- date_saved:: {{{dateSaved}}}` ,
509
+ collapsed:: true
510
+ site:: {{#siteName}}[{{{siteName}}}]{{/siteName}}({{{originalUrl}}})
511
+ {{#author}}
512
+ author:: {{{author}}}
513
+ {{/author}}
514
+ {{#labels.length}}
515
+ labels:: {{#labels}}[[{{{name}}}]]{{/labels}}
516
+ {{/labels.length}}
517
+ date-saved:: {{{dateSaved}}}
518
+ {{#datePublished}}
519
+ date-published:: {{{datePublished}}}
520
+ {{/datePublished}}` ,
491
521
inputAs : 'textarea' ,
492
522
} ,
493
523
{
494
524
key : 'highlightTemplate' ,
495
525
type : 'string' ,
496
526
title : 'Enter the template to use for new highlights' ,
497
527
description :
498
- 'Enter the template to use for new highlights. Required variables are: {{{text}}}, {{{highlightUrl}}}. Optional variables are {{{dateHighlighted}}}' ,
499
- default : `> {{{text}}} [⤴️]({{{highlightUrl}}}) {{#labels}}#[[{{{name}}}]] {{/labels}}` ,
528
+ '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. ' ,
529
+ default : `> {{{text}}} [⤴️]({{{highlightUrl}}}) {{#labels}} #[[{{{name}}}]] {{/labels}}` ,
500
530
inputAs : 'textarea' ,
501
531
} ,
502
532
]
@@ -565,17 +595,18 @@ const main = async (baseInfo: LSPluginBaseInfo) => {
565
595
void ( async ( ) => {
566
596
// reset the last sync time
567
597
logseq . updateSettings ( { syncAt : '' } )
568
- await logseq . UI . showMsg ( 'Omnivore Last Sync reset' )
598
+ await logseq . UI . showMsg ( 'Omnivore Last Sync reset' , 'warning' , {
599
+ timeout : 3000 ,
600
+ } )
569
601
570
602
await fetchOmnivore ( )
571
603
} ) ( )
572
604
}
573
605
)
574
606
575
607
logseq . provideStyle ( `
576
- [data-injected-ui=logseq-omnivore-${ baseInfo . id } ] {
577
- display: flex;
578
- align-items: center;
608
+ div[data-id="${ baseInfo . id } "] div[data-key="articleTemplate"] textarea {
609
+ height: 14rem;
579
610
}
580
611
` )
581
612
0 commit comments