generated from tpl/obsidian-sample-plugin
Add Create Book from Clipboard Command
This commit is contained in:
parent
2f89a703d3
commit
9213e1ef0d
|
|
@ -0,0 +1,36 @@
|
|||
import { Notice } from "obsidian";
|
||||
import { Command } from "./Command";
|
||||
import { bookSchema, type Book } from "@src/types";
|
||||
|
||||
|
||||
export class CreateBookFromClipboardCommand extends Command {
|
||||
constructor(
|
||||
private readonly createEntry: (book: Book) => void | PromiseLike<void>
|
||||
) {
|
||||
super(
|
||||
"create-book-from-clipboard",
|
||||
"Create Book from Clipboard"
|
||||
);
|
||||
}
|
||||
|
||||
async callback() {
|
||||
const data = await navigator.clipboard.readText();
|
||||
const { data: book, success, error } = await bookSchema.safeParseAsync(JSON.parse(data));
|
||||
|
||||
if (!success) {
|
||||
console.error(error.message);
|
||||
new Notice("There is not a valid book in the clipboard. Check console for details");
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await this.createEntry(book);
|
||||
} catch (error) {
|
||||
console.error("Failed to create book:", error);
|
||||
new Notice("Failed to create book. Check console for details.");
|
||||
return;
|
||||
}
|
||||
|
||||
new Notice("Book created from clipboard data.");
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ import {
|
|||
import { CoverImageDownloaderService } from "./services/CoverImageDownloaderService";
|
||||
import { ImageCompressorService } from "./services/ImageCompressorService";
|
||||
import type { Book, BookMetadata, ReadingState } from "./types";
|
||||
import { CreateBookFromClipboardCommand } from "@commands/CreateBookFromClipboardCommand";
|
||||
|
||||
export default class BookTrackerPlugin extends Plugin {
|
||||
public settings: BookTrackerPluginSettings;
|
||||
|
|
@ -86,6 +87,7 @@ export default class BookTrackerPlugin extends Plugin {
|
|||
this.readingLog
|
||||
)
|
||||
);
|
||||
this.addCommand(new CreateBookFromClipboardCommand(this.createEntry.bind(this)))
|
||||
this.addCommand(
|
||||
new CreateBookFromGoodreadsUrlCommand(
|
||||
this.goodreads,
|
||||
|
|
|
|||
45
src/types.ts
45
src/types.ts
|
|
@ -2,30 +2,47 @@ import moment from "@external/moment";
|
|||
import { STATUS_IN_PROGRESS, STATUS_READ, STATUS_TO_BE_READ } from "./const";
|
||||
import z from "zod/v4";
|
||||
|
||||
export const authorSchema = z.object({
|
||||
name: z.string()
|
||||
.transform(val => val.replace(/\s{2,}/g, ' ')),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export interface Author {
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const seriesSchema = z.object({
|
||||
title: z.string(),
|
||||
position: z.number().or(z.nan()),
|
||||
})
|
||||
|
||||
export interface Series {
|
||||
title: string;
|
||||
position: number;
|
||||
}
|
||||
|
||||
export interface Book {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
description: string;
|
||||
authors: Author[];
|
||||
series: Series | null;
|
||||
publisher: string;
|
||||
publishedAt: Date;
|
||||
genres: string[];
|
||||
coverImageUrl: string;
|
||||
pageCount: number;
|
||||
isbn: string;
|
||||
isbn13: string;
|
||||
}
|
||||
export const bookSchema = z.object({
|
||||
title: z.string(),
|
||||
subtitle: z.string(),
|
||||
description: z.string(),
|
||||
authors: z.array(authorSchema),
|
||||
series: seriesSchema.nullable(),
|
||||
publisher: z.string(),
|
||||
publishedAt: z.date(),
|
||||
genres: z.array(z.string()),
|
||||
coverImageUrl: z.url(),
|
||||
pageCount: z.number().min(0),
|
||||
isbn: z.string()
|
||||
.transform(val => val.replace(/-+/g, ''))
|
||||
.pipe(z.string().length(10)),
|
||||
isbn13: z.string()
|
||||
.transform(val => val.replace(/-+/g, ''))
|
||||
.pipe(z.string().length(10)),
|
||||
});
|
||||
|
||||
export type Book = z.infer<typeof bookSchema>;
|
||||
|
||||
export type ToBeReadState = typeof STATUS_TO_BE_READ;
|
||||
export type InProgressState = typeof STATUS_IN_PROGRESS;
|
||||
|
|
|
|||
Loading…
Reference in New Issue