Skip to content

Commit

Permalink
Merge pull request #978 from npocccties/gh-977
Browse files Browse the repository at this point in the history
feat: Deep Linking でのブック提供
  • Loading branch information
kou029w authored Jul 18, 2023
2 parents ce1ef1d + 0cf1bf8 commit 891d411
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 90 deletions.
6 changes: 3 additions & 3 deletions pages/book/edit/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Placeholder from "$templates/Placeholder";
import BookNotFoundProblem from "$templates/BookNotFoundProblem";
import { destroyBook, updateBook, useBook } from "$utils/book";
import { pagesPath } from "$utils/$path";
import useBookLinkHandler from "$utils/useBookLinkHandler";
import useBookLinkingHandlers from "$utils/useBookLinkingHandlers";
import useAuthorsHandler from "$utils/useAuthorsHandler";

export type Query = {
Expand All @@ -23,7 +23,7 @@ function Edit({ bookId, context }: Query) {
const { session, isContentEditable } = useSessionAtom();
const { book, error } = useBook(bookId, isContentEditable);
const router = useRouter();
const handleBookLink = useBookLinkHandler();
const { onBookLinking } = useBookLinkingHandlers();
const { handleAuthorsUpdate, handleAuthorSubmit } = useAuthorsHandler(
book && { type: "book", ...book }
);
Expand All @@ -43,7 +43,7 @@ function Edit({ bookId, context }: Query) {
...props
}: BookPropsWithSubmitOptions) {
await updateBook({ id: bookId, ...props });
if (submitWithLink) await handleBookLink({ id: bookId });
if (submitWithLink) await onBookLinking({ id: bookId });
return back();
}
async function handleDelete({ id }: Pick<BookSchema, "id">) {
Expand Down
30 changes: 3 additions & 27 deletions pages/books/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,8 @@ import BookPreviewDialog from "$organisms/BookPreviewDialog";
import useBooks from "$utils/useBooks";
import useLinkedBook from "$utils/useLinkedBook";
import { pagesPath } from "$utils/$path";
import {
updateLtiResourceLink,
destroyLtiResourceLink,
} from "$utils/ltiResourceLink";
import getLtiResourceLink from "$utils/getLtiResourceLink";
import useDialogProps from "$utils/useDialogProps";
import { useSearchAtom } from "$store/search";
import { revalidateContents } from "utils/useContents";
import useBookLinkingHandlers from "$utils/useBookLinkingHandlers";

const Books = (
props: Omit<
Expand All @@ -26,14 +20,13 @@ const Books = (

function Index() {
const router = useRouter();
const { session, isContentEditable } = useSessionAtom();
const { isContentEditable } = useSessionAtom();
const { linkedBook } = useLinkedBook();
const {
data: previewContent,
dispatch: onContentPreviewClick,
...dialogProps
} = useDialogProps<ContentSchema>();
const { query } = useSearchAtom();
const onContentEditClick = (book: Pick<ContentSchema, "id" | "authors">) => {
const action = isContentEditable(book) ? "edit" : "generate";
return router.push(
Expand All @@ -52,24 +45,7 @@ function Index() {
pagesPath.books.import.$url({ query: { context: "books" } })
);
};
const onContentLinkClick = async (
content: ContentSchema,
checked: boolean
) => {
const book = content as BookSchema;
const ltiResourceLink = getLtiResourceLink(session);
if (ltiResourceLink == null) return;
const bookId = book.id;
if (checked) {
await updateLtiResourceLink({ ...ltiResourceLink, bookId });
} else {
const link = book.ltiResourceLinks.find(
({ consumerId }) => consumerId === session?.oauthClient.id
);
if (link) await destroyLtiResourceLink(link);
}
await revalidateContents(query);
};
const { onBookLinking: onContentLinkClick } = useBookLinkingHandlers();
const handleLinkedBookClick = (book: Pick<BookSchema, "id">) =>
router.push(pagesPath.book.$url({ query: { bookId: book.id } }));
const handlers = {
Expand Down
10 changes: 6 additions & 4 deletions server/services/ltiDeepLinking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { outdent } from "outdent";
import authUser from "$server/auth/authUser";
import authInstructor from "$server/auth/authInstructor";
import type { FromSchema, JSONSchema } from "json-schema-to-ts";
import bookExists from "$server/utils/book/bookExists";
import findBook from "$server/utils/book/findBook";
import { FRONTEND_ORIGIN } from "$server/utils/env";
import { createPrivateKey } from "$server/utils/ltiv1p3/jwk";
import findClient from "$server/utils/ltiv1p3/findClient";
Expand Down Expand Up @@ -60,9 +60,9 @@ export async function index(req: FastifyRequest<{ Querystring: Query }>) {

if (!privateKey) return { status: 403 };

const found = await bookExists(req.query.book_id);
const book = await findBook(req.query.book_id, req.session.user.id);

if (!found) return { status: 404 };
if (!book) return { status: 404 };

const jwt = await getDlResponseJwt(client, {
privateKey,
Expand All @@ -71,9 +71,11 @@ export async function index(req: FastifyRequest<{ Querystring: Query }>) {
contentItems: [
{
type: "ltiResourceLink",
title: book.name,
text: book.description,
url: `${
FRONTEND_ORIGIN || `${req.protocol}://${req.hostname}`
}/book?bookId=${found.id}`,
}/book?bookId=${book.id}`,
},
],
});
Expand Down
32 changes: 0 additions & 32 deletions utils/getLtiResourceLink.ts

This file was deleted.

20 changes: 0 additions & 20 deletions utils/useBookLinkHandler.ts

This file was deleted.

92 changes: 92 additions & 0 deletions utils/useBookLinkingHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useCallback, useMemo } from "react";
import { useRouter } from "next/router";
import type { ContentSchema } from "$server/models/content";
import type { BookSchema } from "$server/models/book";
import type { SessionSchema } from "$server/models/session";
import type { LtiResourceLinkSchema } from "$server/models/ltiResourceLink";
import { useSessionAtom } from "$store/session";
import { useSearchAtom } from "$store/search";
import {
destroyLtiResourceLink,
updateLtiResourceLink,
} from "$utils/ltiResourceLink";
import { revalidateContents } from "./useContents";
import { pagesPath } from "./$path";

/**
* セッションのltiResourceLinkRequestからltiResourceLinkを作成
* @param session セッション
* @return creatorIdとbookIdを除いたLTIリソースリンク
*/
function getLtiResourceLink(
session?: SessionSchema
): Omit<LtiResourceLinkSchema, "creatorId" | "bookId"> | undefined {
if (session == null) return;
if (session.ltiResourceLinkRequest?.id == null) return;

const ltiResourceLink = {
consumerId: session.oauthClient.id,
id: session.ltiResourceLinkRequest.id,
title: session.ltiResourceLinkRequest.title ?? "",
contextId: session.ltiContext.id,
contextTitle: session.ltiContext.title ?? "",
contextLabel: session.ltiContext.label ?? "",
};

return ltiResourceLink;
}

function useBookLinkingHandlers() {
const router = useRouter();
const { session } = useSessionAtom();
const ltiResourceLink = useMemo(() => getLtiResourceLink(session), [session]);
const { query } = useSearchAtom();

const update = useCallback(
async (
bookId: BookSchema["id"],
ltiResourceLink?: Omit<LtiResourceLinkSchema, "creatorId" | "bookId">
) => {
if (session?.ltiMessageType === "LtiDeepLinkingRequest") {
await router.push(pagesPath.book.linking.$url({ query: { bookId } }));
return;
}

if (ltiResourceLink) {
await updateLtiResourceLink({ ...ltiResourceLink, bookId });
return;
}
},
[router, session]
);

const destroy = useCallback(
async (
ltiResourceLink?: Omit<LtiResourceLinkSchema, "creatorId" | "bookId">
) => {
if (ltiResourceLink == null) return;

await destroyLtiResourceLink(ltiResourceLink);
},
[]
);

const onBookLinking = useCallback(
async (content: Pick<BookSchema, "id"> | ContentSchema, linking = true) => {
if ("type" in content && content.type !== "book") return;

if (linking) {
await update(content.id, ltiResourceLink);
} else {
await destroy(ltiResourceLink);
}

await revalidateContents(query);
},
[update, destroy, ltiResourceLink, query]
);

return { onBookLinking };
}

export default useBookLinkingHandlers;
8 changes: 4 additions & 4 deletions utils/useBookNewHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { BookSchema } from "$server/models/book";
import type { BookPropsWithSubmitOptions } from "$types/bookPropsWithSubmitOptions";
import { pagesPath } from "./$path";
import { createBook } from "./book";
import useBookLinkHandler from "./useBookLinkHandler";
import useBookLinkingHandlers from "./useBookLinkingHandlers";
import useAuthorsHandler from "$utils/useAuthorsHandler";
import { updateBookAuthors } from "./bookAuthors";

Expand All @@ -13,7 +13,7 @@ function useBookNewHandlers(
bookId?: BookSchema["id"]
) {
const router = useRouter();
const handleBookLink = useBookLinkHandler();
const { onBookLinking } = useBookLinkingHandlers();
const { handleAuthorsUpdate, handleAuthorSubmit } = useAuthorsHandler();
const handleSubmit = useCallback(
async ({
Expand All @@ -32,7 +32,7 @@ function useBookNewHandlers(
...authors,
],
});
if (submitWithLink) await handleBookLink({ id: book.id });
if (submitWithLink) await onBookLinking({ id: book.id });
await router.replace(
pagesPath.book.edit.$url({
query: {
Expand All @@ -42,7 +42,7 @@ function useBookNewHandlers(
})
);
},
[router, context, handleBookLink]
[router, context, onBookLinking]
);
const handleCancel = useCallback(() => {
switch (context) {
Expand Down

0 comments on commit 891d411

Please sign in to comment.