Skip to content

Commit

Permalink
Merge pull request #30 from readwiseio/migrate-settings-books-map-to-…
Browse files Browse the repository at this point in the history
…use-ids

feat: Improve settings to avoid naming conflict
  • Loading branch information
brunojm authored Jul 4, 2023
2 parents dd22367 + 6545c42 commit c8fdfec
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 37 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"license": "MIT",
"dependencies": {
"@logseq/libs": "^0.0.14",
"@logseq/libs": "^0.0.15",
"date-fns": "^2.28.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 71 additions & 31 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ function escapeDash(inputString: string): string {
}
}

async function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

function getLogseqClientID() {
let clientId = window.localStorage.getItem('rw-LogseqClientId')
if (clientId) {
Expand Down Expand Up @@ -109,16 +113,6 @@ function processBlockContent(content: string, preferredDateFormat: string) {
}
}

function escapeBlocks(blocks: Array<IBatchBlock>) {
return blocks.map(b => {
const content = escapeDash(b.content)
if (b.children !== undefined) {
b.children = escapeBlocks(b.children)
}
return {...b, content}
})
}

function convertReadwiseToIBatchBlock(preferredDateFormat: string, obj: ReadwiseBlock) {
// we ignore the first one (which we can consider as the block title)
const block: IBatchBlock = {
Expand All @@ -145,38 +139,78 @@ async function createPage(title: string, blocks: Array<IBatchBlock>) {
before: false,
isPageBlock: true
})
await logseq.Editor.insertBatchBlock(firstBlock!.uuid, escapeBlocks(blocks.slice(1)), {sibling: true})
return true
await logseq.Editor.insertBatchBlock(firstBlock!.uuid, blocks.slice(1), {sibling: true})
return page
} else if (pageBlocksTree !== null && pageBlocksTree.length === 1) {
// createFirstBlock: false creates a block to title if the name contains invalid characters
const _first = pageBlocksTree[0]
await logseq.Editor.updateBlock(_first!.uuid, _first.content + "\n" + blocks[0].content)
await logseq.Editor.insertBatchBlock(_first!.uuid, escapeBlocks(blocks.slice(1)), {sibling: true})
return true
await logseq.Editor.insertBatchBlock(_first!.uuid, blocks.slice(1), {sibling: true})
return page
}
logseq.App.showMsg(`Error creating "${title}", page not created`, "warning")
return false
}


async function updatePage(page: PageEntity, blocks: Array<IBatchBlock>) {
const pageBlocksTree = await logseq.Editor.getPageBlocksTree(page.originalName)
const pageBlocksTree = await logseq.Editor.getPageBlocksTree(page.uuid)
// uuid isn't working: https://github.com/logseq/logseq/issues/4920
await new Promise(r => setTimeout(r, 500))
if (pageBlocksTree.length === 0) {
const firstBlock = await logseq.Editor.insertBlock(page!.originalName, blocks[0].content, {
const firstBlock = await logseq.Editor.insertBlock(page!.uuid, blocks[0].content, {
before: false,
isPageBlock: true
})
await logseq.Editor.insertBatchBlock(firstBlock!.uuid, escapeBlocks(blocks.slice(1)), {sibling: true})
await logseq.Editor.insertBatchBlock(firstBlock!.uuid, blocks.slice(1), {sibling: true})
} else if (pageBlocksTree.length > 0) {
const _last = pageBlocksTree[pageBlocksTree.length - 1]
await logseq.Editor.insertBatchBlock(_last!.uuid, escapeBlocks(blocks), {sibling: true})
await logseq.Editor.insertBatchBlock(_last!.uuid, blocks, {sibling: true})
} else {
logseq.App.showMsg(`Error updating "${page.originalName}", page not loaded`, "error")
}
}

function checkAndMigrateBooksIDsMap() {
// check booksIDsMap format and migrate old format
console.log("Readwise Official plugin: checking booksIDsMap format")
if (logseq.settings!.booksIDsMap) {
const booksIDsMap = logseq.settings!.booksIDsMap
const newBooksIDsMap = logseq.settings!.newBooksIDsMap
let isOldFormat = false
if (Object.keys(booksIDsMap).length < Object.keys(newBooksIDsMap).length) {
isOldFormat = true
}
if (isOldFormat) {
console.log("Readwise Official plugin: migrating booksIDsMap format")
const newBooksIDsMap: any = {}
Promise.all(Object.keys(booksIDsMap).map((bookTitle) => {
return new Promise((resolve) => {
logseq.Editor.getPage(bookTitle).then((page) => {
if (page) {
const bookId = booksIDsMap[bookTitle]
if (bookId) {
console.log(`Readwise Official plugin: migrating book ${bookTitle} (${bookId})`)
newBooksIDsMap[bookId] = page!.uuid
resolve(bookId)
}
}
})
})
})).then(() => {
// @ts-ignore
console.log("Readwise Official plugin: saving new booksIDsMap format (newBooksIDsMap setting)")
logseq.updateSettings({
newBooksIDsMap: newBooksIDsMap
})
})
} else {
console.log("Readwise Official plugin: booksIDsMap format is correct")
}
}

}

function getErrorMessageFromResponse(response: Response) {
if (response && response.status === 409) {
return "Sync in progress initiated by different client"
Expand Down Expand Up @@ -214,6 +248,7 @@ export function clearSettingsComplete() {
lastSyncFailed: false,
lastSavedStatusID: 0,
booksIDsMap: null,
newBooksIDsMap: null,
readwiseAccessToken: null,
isLoadAuto: true,
isResyncDeleted: false,
Expand Down Expand Up @@ -253,11 +288,11 @@ async function refreshBookExport(books: Array<BookToExport>) {
console.log("Readwise Official plugin: fetch failed in refreshBookExport: ", e);
}
if (response && response.ok) {
const booksIDsMap = logseq.settings!.booksIDsMap || {}
const booksIDsMap = logseq.settings!.newBooksIDsMap || {}
const booksIDsMapAsArray = Object.entries(booksIDsMap)
logseq.updateSettings({
// @ts-ignore
booksIDsMap: Object.fromEntries(booksIDsMapAsArray.filter((b) => !(b[1] in bookIds)))
newBooksIDsMap: Object.fromEntries(booksIDsMapAsArray.filter((b) => !(b[0] in bookIds)))
})
}
} else {
Expand Down Expand Up @@ -318,7 +353,7 @@ async function downloadArchive(exportID: number, setNotification?, setIsSyncing?
console.log("Readwise Official plugin: fetch failed in downloadArchive: ", e)
setIsSyncing(false)
}
const booksIDsMap = logseq.settings!.booksIDsMap || {}
const booksIDsMap = logseq.settings!.newBooksIDsMap || {}
const preferredDateFormat = (await logseq.App.getUserConfigs()).preferredDateFormat
if (response && response.ok) {
const responseJSON = await response.json()
Expand All @@ -329,8 +364,11 @@ async function downloadArchive(exportID: number, setNotification?, setIsSyncing?
const bookId = book.userBookExportId
const bookIsUpdate = book.isUpdate
const bookData = book.data
booksIDsMap[bookData.title] = bookId
const page = await logseq.Editor.getPage(bookData.title)
const localId = booksIDsMap[bookId]
let page = null
if (localId) {
page = await logseq.Editor.getPage(localId)
}
// @ts-ignore
if (window.onAnotherGraph) {
setIsSyncing(false)
Expand Down Expand Up @@ -361,8 +399,9 @@ async function downloadArchive(exportID: number, setNotification?, setIsSyncing?
} else {
const convertedNewBook = convertReadwiseToIBatchBlock(preferredDateFormat, bookData)
if (convertedNewBook !== undefined) {
const created = await createPage(bookData.title, convertedNewBook!.children!)
if (created) {
const page = await createPage(bookData.title, convertedNewBook!.children!)
if (page) {
booksIDsMap[bookId] = page.uuid
setNotification(`Creating "${bookData.title}" completed (${index}/${books.length})`)
}
}
Expand All @@ -383,7 +422,7 @@ async function downloadArchive(exportID: number, setNotification?, setIsSyncing?
}
}
logseq.updateSettings({
booksIDsMap: booksIDsMap
newBooksIDsMap: booksIDsMap
})
setIsSyncing(false)
setNotification(null)
Expand Down Expand Up @@ -491,12 +530,12 @@ function resyncDeleted(callback: (() => void)) {
(new Promise(r => setTimeout(r, 2000))).then(() => {
const booksIDsMap = logseq.settings!.booksIDsMap || {}
// @ts-ignore
Promise.all(Object.keys(booksIDsMap).map((bookName) => {
Promise.all(Object.keys(booksIDsMap).map((userBookId) => {
return new Promise((resolve) => {
logseq.Editor.getPage(bookName).then((res) => {
logseq.Editor.getPage(booksIDsMap[userBookId]).then((res) => {
if (res === null) {
resolve(([booksIDsMap[bookName], bookName]))
console.log(`Page '${bookName}' deleted, going to resync.`)
resolve(([booksIDsMap[userBookId], userBookId]))
console.log(`Page UserBook ID: '${userBookId}' deleted, going to resync.`)
} else {
resolve(null)
}
Expand Down Expand Up @@ -620,6 +659,8 @@ function main() {
</React.StrictMode>
)

checkAndMigrateBooksIDsMap()

function createModel() {
return {
async show() {
Expand Down Expand Up @@ -683,7 +724,6 @@ function main() {
})
}


// check current state
if (logseq.settings!.readwiseAccessToken && logseq.settings!.currentSyncStatusID !== 0) {
// the last sync didn't finish correctly (initial phase)
Expand Down

0 comments on commit c8fdfec

Please sign in to comment.