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 { CoverImageDownloaderService } from "./services/CoverImageDownloaderService";
|
||||||
import { ImageCompressorService } from "./services/ImageCompressorService";
|
import { ImageCompressorService } from "./services/ImageCompressorService";
|
||||||
import type { Book, BookMetadata, ReadingState } from "./types";
|
import type { Book, BookMetadata, ReadingState } from "./types";
|
||||||
|
import { CreateBookFromClipboardCommand } from "@commands/CreateBookFromClipboardCommand";
|
||||||
|
|
||||||
export default class BookTrackerPlugin extends Plugin {
|
export default class BookTrackerPlugin extends Plugin {
|
||||||
public settings: BookTrackerPluginSettings;
|
public settings: BookTrackerPluginSettings;
|
||||||
|
|
@ -86,6 +87,7 @@ export default class BookTrackerPlugin extends Plugin {
|
||||||
this.readingLog
|
this.readingLog
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
this.addCommand(new CreateBookFromClipboardCommand(this.createEntry.bind(this)))
|
||||||
this.addCommand(
|
this.addCommand(
|
||||||
new CreateBookFromGoodreadsUrlCommand(
|
new CreateBookFromGoodreadsUrlCommand(
|
||||||
this.goodreads,
|
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 { STATUS_IN_PROGRESS, STATUS_READ, STATUS_TO_BE_READ } from "./const";
|
||||||
import z from "zod/v4";
|
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 {
|
export interface Author {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const seriesSchema = z.object({
|
||||||
|
title: z.string(),
|
||||||
|
position: z.number().or(z.nan()),
|
||||||
|
})
|
||||||
|
|
||||||
export interface Series {
|
export interface Series {
|
||||||
title: string;
|
title: string;
|
||||||
position: number;
|
position: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Book {
|
export const bookSchema = z.object({
|
||||||
title: string;
|
title: z.string(),
|
||||||
subtitle: string;
|
subtitle: z.string(),
|
||||||
description: string;
|
description: z.string(),
|
||||||
authors: Author[];
|
authors: z.array(authorSchema),
|
||||||
series: Series | null;
|
series: seriesSchema.nullable(),
|
||||||
publisher: string;
|
publisher: z.string(),
|
||||||
publishedAt: Date;
|
publishedAt: z.date(),
|
||||||
genres: string[];
|
genres: z.array(z.string()),
|
||||||
coverImageUrl: string;
|
coverImageUrl: z.url(),
|
||||||
pageCount: number;
|
pageCount: z.number().min(0),
|
||||||
isbn: string;
|
isbn: z.string()
|
||||||
isbn13: 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 ToBeReadState = typeof STATUS_TO_BE_READ;
|
||||||
export type InProgressState = typeof STATUS_IN_PROGRESS;
|
export type InProgressState = typeof STATUS_IN_PROGRESS;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue