Slide 1

Slide 1 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 2022/12/14
 toranoana.deno #10 
 
 虎の穴ラボ
 奥谷 一陽
 Fresh(Deno)で 画像投稿サイトを作ってみよう! with Cloudflare x Tora Viewer


Slide 2

Slide 2 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 自己紹介
 奥谷 一陽
 所属:虎の穴ラボ株式会社
 担当:Fantiaなど新規事業系の開発
 興味:TypeScript、Deno
 おすすめコンテンツ:
   『暴太郎戦隊ドンブラザーズ』
   『STAR WARS 小説 』
 
 Twitter:@okutann88


Slide 3

Slide 3 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. Fresh 使ってますか?


Slide 4

Slide 4 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. さっと作って、
 Deno Deployに上げるのもカンタン


Slide 5

Slide 5 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. ですが、あえてFreshを使って
 ちょっと込み入ったことをしてみました


Slide 6

Slide 6 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. Freshで 画像投稿をやろう
 - Freshをベースに開発する
 - 機能
 - 画像のアップロード
 - 画像の一覧表示
 - 画像の詳細表示
 これらを実装する方針
 
 


Slide 7

Slide 7 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. イメージが湧きにくいと思うので、先にできたものを
 - Freshをベースに開発する
 - 機能
 - 画像のアップロード
 - 画像の一覧表示
 - 画像の詳細表示
 これらを実装する方針
 
 


Slide 8

Slide 8 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. イメージが湧きにくいと思うので、先にできたものを
 - Freshをベースに開発する
 - 機能
 - 画像のアップロード
 - 画像の一覧表示
 - 画像の詳細表示
 これらを実装する方針
 
 


Slide 9

Slide 9 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/サービス
 - Deno
 - Fresh 
 - Cloudflare
 - Tora Viewer


Slide 10

Slide 10 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術サービス
 - Deno
 - Fresh 
 - Cloudflare
 - Tora Viewer ?


Slide 11

Slide 11 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. Tora Viewer
 https://www.npmjs.com/package/@toralab/tora-viewer

Slide 12

Slide 12 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. Tora Viewer
 - 漫画、写真集など画像一覧を閲覧できるビューアー
 - 虎の穴ラボ発のOSSです
 - Freshでも使えます。
 // import_map.json { "imports": { "$fresh/": "https://deno.land/x/[email protected]/", "preact": "https://esm.sh/[email protected]", "preact/": "https://esm.sh/[email protected]/", "preact-render-to-string": "https://esm.sh/*[email protected]", "@preact/signals": "https://esm.sh/*@preact/[email protected]", "@preact/signals-core": "https://esm.sh/*@preact/[email protected]", "twind": "https://esm.sh/[email protected]", "twind/": "https://esm.sh/[email protected]/", "dotenv/": "https://deno.land/[email protected]/dotenv/", "huid/": "https://deno.land/x/[email protected]/", "tora-viewer": "https://esm.sh/v99/@toralab/[email protected]/es2022/tora-viewer.js", "body-scroll-lock": "https://esm.sh/body-scroll-lock", "simple-dropzone": "https://esm.sh/simple-dropzone" }

Slide 13

Slide 13 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 全体構成
 deno cli APPサーバー 画像 アップロード ・ダウンロード ページアクセス 画像ID登録 APIサーバー DB

Slide 14

Slide 14 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. その他追加導入しているモジュール
 - huid:文字列のハッシュをつくるのに使用
 - body-scroll-lock:ビューアーを開いたときのスクロールロック
 - simple-dropzone:画像ドラッグ&ドロップ操作用
 body-scroll-lock と simple-dropzone は、esm.sh経由での導入
 


Slide 15

Slide 15 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. ソースコード
 // routes/index.tsx import Uploader from "../islands/Uploader.tsx"; import Images from "../islands/Images.tsx"; export default function Home() { return (
); }

Slide 16

Slide 16 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. ソースコード
 // app/islands/Uploader.tsx (前半) import { JSX } from "preact"; import { useEffect, useRef } from "preact/hooks"; import { mode } from "../util/signal.ts"; import { SimpleDropzone } from "simple-dropzone"; import UploaderIcon from "../components/UpLoadIcon.tsx"; export default function Uploader(_props: JSX.HTMLAttributes) { const inputRef = useRef(null); const dropzoneRef = useRef(null); const upload = async (file: File) => { if (!inputRef.current) return; const result = await fetch("/api/get_temp_post_url"); const resultJson = await result.json(); const formData = new FormData(); formData.append("file", file); const uploadResult = await fetch(resultJson.url, { method: "POST", body: formData, }); const uploadedResultJson = await uploadResult.json(); await fetch("/api/image_updated", { method: "POST", body: JSON.stringify(uploadedResultJson), }); inputRef.current.value = ""; mode.value = 1; };

Slide 17

Slide 17 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. ソースコード
 // app/islands/Uploader.tsx (後半) useEffect(() => { const dropCtrl = new SimpleDropzone(dropzoneRef.current, inputRef.current); dropCtrl.on("drop", ({ files }: { files: Map }) => { for (const [_key, value] of files) { upload(value); } }); }, []); return (
Drop or Select
); }

Slide 18

Slide 18 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. ソースコード
 // app/islands/Images.tsx (tora-viewer部分抜粋) import toraViewer from "tora-viewer"; export default function Images(_props: JSX.HTMLAttributes) { const openViewer = (index: number) => { const viewer = toraViewer( originalImages.map((image: Image, index: number) => { return { url: image.url, thumbnailUrl: miniImages[index].url }; }), { pageStyle: "normal"}, ); viewer.goTo(index); const originDispose = viewer.dispose; const boundDispose = originDispose.bind(viewer); const newDispose = () => { clearAllBodyScrollLocks(); boundDispose(); }; viewer.dispose = newDispose; }; return (
{!miniImages ? "" : miniImages.map((image: Image, index: number) => (
openViewer(index)} />
))}
); }

Slide 19

Slide 19 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. esm.sh 小ネタ
 開発中のこと
 - esm.sh経由で Tora Viewer を読み込むと、どうも毎回ビルドをしているような動 きをしていて動きが遅かった
 
 
 - ビルド結果を直接インポートするようにすると改善
 
 
 同じように、esm.shから読み込みが遅いものは同じ対応ができるかも
 "https://esm.sh/v99/@toralab/[email protected]/es2022/tora-viewer.js" "https://esm.sh/@toralab/tora-viewer"

Slide 20

Slide 20 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. まとめ
 - Fresh x Cloudflare x Tora Viewer で画像投稿サイトを作ってみました。
 - ユーザー認証、ローディングアニメーションなど拡張すれば、
 画像投稿サイトとして十分使えそうです。
 - 今回の実装は islands2つだけを使ったサイトでした。
 islandsを使いこなせるといろんなことができます。


Slide 21

Slide 21 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. お知らせ
 今回取り扱った 画像投稿サイトの実装の詳細な解説が入ったブログが明日公開
 省略した箇所の解説も入ってますので、ご期待ください!!


Slide 22

Slide 22 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. ありがとうございました