-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
api updates; popup menu on toggle addon menu; add mode to tap on note to fetch children recursively BREAKING CHANGE: api: add ReturnBody_Toc; mediaList -> mediaMap; add bookMap for ReturnBody_Note and ReturnBody_Toc ...
- Loading branch information
Showing
12 changed files
with
470 additions
and
195 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
type Undefined<T> = { [P in keyof T]: P extends undefined ? T[P] : never }; | ||
|
||
type FilterFlags<Base, Condition> = { | ||
[Key in keyof Base]: Base[Key] extends Condition ? Key : never; | ||
}; | ||
|
||
type AllowedNames<Base, Condition> = FilterFlags<Base, Condition>[keyof Base]; | ||
|
||
type SubType<Base, Condition> = Pick<Base, AllowedNames<Base, Condition>>; | ||
|
||
export type OptionalKeys<T> = Exclude< | ||
keyof T, | ||
NonNullable<keyof SubType<Undefined<T>, never>> | ||
>; | ||
export type RequiredKeys<T> = NonNullable<keyof SubType<Undefined<T>, never>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,110 @@ | ||
import { excerptPic_video, MbBook } from "@alx-plugins/marginnote"; | ||
import { excerptPic_video, MbBook, MbBookNote } from "@alx-plugins/marginnote"; | ||
|
||
import PopupRecorder from "./PopupRecorder"; | ||
import { item, MNMark, node, ReturnBody, selection } from "./return"; | ||
import { scanObject } from "./tools"; | ||
|
||
const process = (node: node, rec: PopupRecorder, book?: MbBook): ReturnBody => { | ||
const currentBook = book ? scanObject(book) : undefined; | ||
|
||
const getLastAndSendTime = ( | ||
data: node, | ||
): { sendTime: ReturnBody["sendTime"]; last: ReturnBody["last"] } => { | ||
const last = rec.last; | ||
rec.push(data); | ||
const sendTime = (rec.last as Exclude<item, null>).addTime; | ||
return { last, sendTime }; | ||
}; | ||
import { | ||
Data, | ||
MNMark, | ||
ReturnBody, | ||
ReturnBody_Note, | ||
ReturnBody_Sel, | ||
ReturnBody_Toc, | ||
Selection, | ||
} from "./return"; | ||
import { scanNote, scanObject, scanToc } from "./scan"; | ||
import { copy, showHUD } from "./tools"; | ||
import getText from "./translate"; | ||
|
||
if (isSel(node)) { | ||
const data = node; | ||
const { last, sendTime } = getLastAndSendTime(data); | ||
const mediaList = null; | ||
return { type: "sel", sendTime, currentBook, mediaList, data, last }; | ||
} else { | ||
const data = scanObject(node, 2); | ||
const { last, sendTime } = getLastAndSendTime(data); | ||
const videoId = (data.excerptPic as excerptPic_video)?.video; | ||
const mediaList = []; | ||
const mediaIds = node.mediaList?.split("-").filter((id) => id !== videoId); | ||
if (mediaIds && mediaIds.length > 1) { | ||
for (const id of mediaIds) { | ||
if (!id) continue; // escape empty string | ||
const mediaData = Database.sharedInstance() | ||
.getMediaByHash(id) | ||
?.base64Encoding(); | ||
// only export png, cannot find way to process stroke properly for now | ||
if (mediaData && mediaData.startsWith("iVBORw0K")) | ||
mediaList.push({ id, data: mediaData }); | ||
} | ||
} | ||
return { type: "note", sendTime, currentBook, mediaList, data, last }; | ||
} | ||
const getBook = (docMd5: string | undefined): MbBook | null => { | ||
const bookObj = | ||
docMd5 && typeof docMd5 === "string" | ||
? Database.sharedInstance().getDocumentById(docMd5) | ||
: null; | ||
return bookObj ? scanObject(bookObj) : null; | ||
}; | ||
|
||
const MNMark: MNMark = "<!--MN-->\n"; | ||
const stringify = (obj: any): string => { | ||
return MNMark + JSON.stringify(obj); | ||
}; | ||
|
||
const getLastAndSendTime = ( | ||
data: Data, | ||
): { sendTime: ReturnBody["sendTime"]; last: ReturnBody["last"] } => { | ||
const rec = self.recorder as PopupRecorder, | ||
last = rec.last; | ||
return { last, sendTime: rec.push(data) }; | ||
}; | ||
|
||
export const handleSel = (sel: Selection): void => { | ||
const { last, sendTime } = getLastAndSendTime(sel); | ||
const returns: ReturnBody_Sel = { | ||
type: "sel", | ||
sendTime, | ||
data: sel, | ||
last, | ||
}; | ||
copy(stringify(returns)); | ||
}; | ||
|
||
export const stringify = <T extends node>( | ||
node: T, | ||
rec: PopupRecorder, | ||
currentBook?: MbBook, | ||
): string => { | ||
return MNMark + JSON.stringify(process(node, rec, currentBook)); | ||
const arrToObj = <V>( | ||
arr: string[], | ||
cvt: (id: string) => V | null, | ||
): Record<string, V> => | ||
arr.reduce((obj, id) => { | ||
const val = cvt(id); | ||
if (val) obj[id] = val; | ||
return obj; | ||
}, {} as any) as Record<string, V>; | ||
|
||
export const handleNote = (note: MbBookNote): void => { | ||
const [data, bookMd5s] = scanNote(note, 2), | ||
{ last, sendTime } = getLastAndSendTime(data), | ||
bookMap = arrToObj(bookMd5s, (id) => getBook(id)); | ||
|
||
const videoId = (data.excerptPic as excerptPic_video)?.video, | ||
mediaIds = note.mediaList?.split("-").filter((id) => id !== videoId), | ||
mediaMap = | ||
mediaIds && mediaIds.length > 0 | ||
? arrToObj(mediaIds, (id) => { | ||
const mediaData = Database.sharedInstance() | ||
.getMediaByHash(id) | ||
?.base64Encoding(); | ||
return mediaData && mediaData.startsWith("iVBORw0K") | ||
? mediaData | ||
: null; | ||
}) | ||
: {}; | ||
|
||
const returns: ReturnBody_Note = { | ||
type: "note", | ||
sendTime, | ||
bookMap, | ||
mediaMap, | ||
data, | ||
last, | ||
}; | ||
copy(stringify(returns)); | ||
}; | ||
|
||
const isSel = (node: node): node is selection => | ||
typeof (node as selection).sel === "string"; | ||
export const handleToc = (note: MbBookNote): void => { | ||
// if (note.parentNote) return; | ||
const result = scanToc(note); | ||
if (typeof result !== "string") { | ||
const [data, bookMd5s] = result, | ||
{ last, sendTime } = getLastAndSendTime(data), | ||
bookMap = arrToObj(bookMd5s, (id) => getBook(id)); | ||
const returns: ReturnBody_Toc = { | ||
type: "toc", | ||
sendTime, | ||
bookMap, | ||
data, | ||
last, | ||
}; | ||
copy(stringify(returns)); | ||
showHUD(getText("hint_toc_success") + note.noteTitle); | ||
} else showHUD(result); | ||
}; | ||
|
||
const MNMark: MNMark = "<!--MN-->\n"; | ||
|
||
const isSel = (node: Data): node is Selection => | ||
typeof (node as Selection).sel === "string"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,52 @@ | ||
import { MbBook, MbBookNote } from "@alx-plugins/marginnote"; | ||
|
||
export type selection = { sel: string }; | ||
export type inHistory = selection | MbBookNote | null; | ||
export type Selection = { sel: string; book?: MbBook }; | ||
export type inHistory = Data | null; | ||
export type time = number | null; | ||
export type item = { | ||
data: Exclude<inHistory, null>; | ||
addTime: Exclude<time, null>; | ||
} | null; | ||
|
||
export type node = selection | MbBookNote; | ||
export type Data = Selection | MbBookNote | Toc; | ||
export type DataType = "sel" | "note" | "toc"; | ||
|
||
export type MNMark = "<!--MN-->\n"; | ||
|
||
type Media = { | ||
id: string; | ||
/** encoded in base64 */ | ||
data: string; | ||
}; | ||
|
||
type ReturnBody_Basic = { | ||
type: "sel" | "note"; | ||
type: DataType; | ||
sendTime: ReturnType<typeof Date.now>; | ||
currentBook?: MbBook; | ||
mediaList: Media[] | null; | ||
data: node; | ||
data: Data; | ||
last: item | null; | ||
}; | ||
|
||
export type ReturnBody = ReturnBody_Note | ReturnBody_Sel; | ||
|
||
export interface ReturnBody_Sel extends ReturnBody_Basic { | ||
type: "sel"; | ||
data: selection; | ||
mediaList: null; | ||
data: Selection; | ||
book?: MbBook; | ||
} | ||
|
||
export interface ReturnBody_Note extends ReturnBody_Basic { | ||
type: "note"; | ||
data: MbBookNote; | ||
mediaList: Array<{ id: string; data: string }>; | ||
/** id - base64(png) pair */ | ||
mediaMap: Record<string, string>; | ||
bookMap: Record<string, MbBook>; | ||
} | ||
|
||
export interface ReturnBody_Toc extends ReturnBody_Basic { | ||
type: "toc"; | ||
data: Toc; | ||
bookMap: Record<string, MbBook>; | ||
} | ||
export interface Toc { | ||
noteTitle: string; | ||
noteId: string; | ||
docMd5?: string; | ||
startPage?: number; | ||
endPage?: number; | ||
|
||
childNotes: Toc[]; | ||
} |
Oops, something went wrong.