Skip to content

Commit

Permalink
feat: add Notion Link
Browse files Browse the repository at this point in the history
  • Loading branch information
aalemayhu committed Feb 19, 2024
1 parent 859dff0 commit 70f7aba
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 4 deletions.
7 changes: 7 additions & 0 deletions src/lib/parser/DeckParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ export class DeckParser {

private extractCards(dom: cheerio.Root, toggleList: cheerio.Element[]) {
let cards: Note[] = [];
const pageId = dom('article').attr('id');

toggleList.forEach((t) => {
// We want to perserve the parent's style, so getting the class
Expand Down Expand Up @@ -605,6 +606,12 @@ export class DeckParser {
})();
const note = new Note(front || '', backSide);
note.notionId = parentUL.attr('id');
if (note.notionId && this.settings.addNotionLink) {
const link = this.getLink(pageId, note);
if (link !== null) {
note.back += link;
}
}
if (
(this.settings.isAvocado && this.noteHasAvocado(note)) ||
(this.settings.isCherry && !this.noteHasCherry(note))
Expand Down
3 changes: 3 additions & 0 deletions src/lib/parser/Note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default class Note {

notionId?: string;

notionLink?: string;

constructor(name: string, back: string) {
this.name = name;
this.back = back;
Expand Down Expand Up @@ -50,6 +52,7 @@ export default class Note {
this.answer = clozeCard.answer;
this.media = clozeCard.media;
this.notionId = clozeCard.notionId;
this.notionLink = clozeCard.notionLink;
}

hasRefreshIcon() {
Expand Down
8 changes: 8 additions & 0 deletions src/lib/parser/Settings/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export class Settings {

parentBlockId: string;

readonly addNotionLink: boolean;

constructor(input: { [key: string]: string }) {
this.deckName = input.deckName;
if (this.deckName && !this.deckName.trim()) {
Expand Down Expand Up @@ -92,6 +94,11 @@ export class Settings {
this.useNotionId = input['use-notion-id'] === 'true';
this.parentBlockId = input.parentBlockId;
this.pageEmoji = input['page-emoji'] || 'first_emoji';
this.addNotionLink = input['add-notion-link'] === 'true';
/* Is this really needed? */
if (this.parentBlockId) {
this.addNotionLink = true;
}

this.retrieveTemplates(input);
}
Expand All @@ -108,6 +115,7 @@ export class Settings {

static LoadDefaultOptions(): { [key: string]: string } {
return {
'add-notion-link': 'false',
'use-notion-id': 'true',
all: 'true',
paragraph: 'false',
Expand Down
19 changes: 19 additions & 0 deletions src/services/NotionService/BlockHandler/BlockHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,25 @@ describe('BlockHandler', () => {
expect(flashcards.length).toBe(1);
});

test('Add Notion Link', async () => {
const expected =
'https://www.notion.so/Notion-API-Test-Page-3ce6b147ac8a425f836b51cc21825b85#e5201f35c72240d38e3a5d218e5d80a5';
const flashcards = await loadCards(
{
'add-notion-link': 'true',
parentBlockId: examplId,
},
examplId,
new Workspace(true, 'fs'),
new ParserRules()
);
const card = flashcards.find((f) =>
f.name.includes('1 - This is a basic card')
);
expect(card).toBeTruthy();
expect(card?.notionLink).toBe(expected);
});

test.todo('Maximum One Toggle Per Card');
test.todo('Use All Toggle Lists');
test.todo('Template Options');
Expand Down
40 changes: 36 additions & 4 deletions src/services/NotionService/BlockHandler/BlockHandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isFullBlock } from '@notionhq/client';
import { isFullBlock, isFullPage } from '@notionhq/client';
import {
AudioBlockObjectResponse,
BlockObjectResponse,
Expand All @@ -9,6 +9,7 @@ import {
PageObjectResponse,
} from '@notionhq/client/build/src/api-endpoints';
import axios from 'axios';

import getDeckName from '../../../lib/anki/getDeckname';
import sanitizeTags from '../../../lib/anki/sanitizeTags';
import { sendError } from '../../../lib/error/sendError';
Expand Down Expand Up @@ -37,6 +38,7 @@ import perserveNewlinesIfApplicable from '../helpers/preserveNewlinesIfApplicabl
import { renderBack } from '../helpers/renderBack';
import { toText } from './helpers/deckNameToText';
import getSubDeckName from './helpers/getSubDeckName';
import RenderNotionLink from './RenderNotionLink';

interface Finder {
parentType: string;
Expand Down Expand Up @@ -138,10 +140,20 @@ class BlockHandler {
}
}

__notionLink(
id: string,
notionBaseLink: string | undefined
): string | undefined {
return notionBaseLink
? `${notionBaseLink}#${id.replace(/-/g, '')}`
: undefined;
}

private async getFlashcards(
rules: ParserRules,
flashcardBlocks: GetBlockResponse[],
tags: string[]
tags: string[],
notionBaseLink: string | undefined
): Promise<Note[]> {
let cards = [];
let counter = 0;
Expand Down Expand Up @@ -186,6 +198,10 @@ class BlockHandler {
}

ankiNote.back = back!;
ankiNote.notionLink = this.__notionLink(block.id, notionBaseLink);
if (this.settings.addNotionLink) {
ankiNote.back += RenderNotionLink(ankiNote.notionLink!, this);
}
ankiNote.notionId = this.settings.useNotionId ? block.id : undefined;
ankiNote.media = this.exporter.media;
this.exporter.media = [];
Expand Down Expand Up @@ -291,7 +307,18 @@ class BlockHandler {
});
this.settings.parentBlockId = page.id;

const cards = await this.getFlashcards(rules, cBlocks, tags);
let notionBaseLink =
this.settings.addNotionLink && this.settings.parentBlockId
? isFullPage(page)
? page?.url
: undefined
: undefined;
const cards = await this.getFlashcards(
rules,
cBlocks,
tags,
notionBaseLink
);
const deck = new Deck(
toText(getDeckName(parentName, title)),
Deck.CleanCards(cards),
Expand Down Expand Up @@ -326,7 +353,12 @@ class BlockHandler {
);

this.settings.parentBlockId = sd.id;
const cards = await this.getFlashcards(rules, cBlocks, tags);
const cards = await this.getFlashcards(
rules,
cBlocks,
tags,
undefined
);
let subDeckName = getSubDeckName(sd);

decks.push(
Expand Down
20 changes: 20 additions & 0 deletions src/services/NotionService/BlockHandler/RenderNotionLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ReactDOMServer from 'react-dom/server';
import BlockHandler from './BlockHandler';

const RenderNotionLink = (
link: string,
handler: BlockHandler
): string | null => {
if (handler.settings?.isTextOnlyBack) {
return link;
}
return ReactDOMServer.renderToStaticMarkup(
<div style={{ textAlign: 'center' }}>
<a style={{ textDecoration: 'none', color: 'grey' }} href={link}>
Open in Notion
</a>
</div>
);
};

export default RenderNotionLink;

0 comments on commit 70f7aba

Please sign in to comment.