|
| 1 | +--- |
| 2 | +draft: false |
| 3 | +title: <open-heart>❤️</open-heart> |
| 4 | +date: 2025-01-12 |
| 5 | +categories: Tech |
| 6 | +comments: true |
| 7 | +ShowToc: true |
| 8 | +isCJKLanguage: true |
| 9 | +--- |
| 10 | + |
| 11 | +之前在一个[外国开发者 benji 的博客](https://www.benji.dog/articles/interactions-or-reactions/)里发现文章末有个❤️,随手点了下就 Like 上了,感觉很简洁很可爱,遂打开 devtools 看了下, |
| 12 | +发现了这个 `<open-heart>` 元素,具体搜索了一下之后,就想着给自己博客也安上了。 |
| 13 | +记录一下大概过程,给有想要给自己博客或者其他任何地方用上玩玩的人参考。 |
| 14 | + |
| 15 | +基本上需要的东西是: |
| 16 | +- cloudflare worker 提供一个 API 来处理用户的 reaction |
| 17 | +- cloudflare worker KV,一个简单的 key-value storage,用来存储 reaction 数据 |
| 18 | +- 在博客模版里添加 `<open-heart>` 组件进行渲染即可 |
| 19 | + |
| 20 | +## 创建 cloudflare worker |
| 21 | + |
| 22 | +[参考CF Workers 文档](https://developers.cloudflare.com/workers/get-started/guide/),直接用 CLI 最方便。 |
| 23 | + |
| 24 | +```sh |
| 25 | +pnpm create cloudflare@latest <worker-name> |
| 26 | +``` |
| 27 | + |
| 28 | +其中会有让你选择模板,只需要最简单的 Hello World example 就行,语言的话按自己喜好选,我是用 TypeScript。 |
| 29 | + |
| 30 | +这样本地的 worker project 就创建好了。 |
| 31 | +cd 到这个目录后,用 `npm run dev` 就可以用 [wrangler(Cloudflare 开发 CLI 工具)](https://developers.cloudflare.com/workers/wrangler/) 启动一个本地的 worker 了,然后在浏览器里面访问 `http://localhost:8787/` 就可以看到 Hello World!。 |
| 32 | + |
| 33 | +如果不想自己创建维护 worker,也可以直接使用这个 Public API,[https://api.oh.dddddddddzzzz.org/](https://github.com/dddddddddzzzz/api-oh),但数据就也不是在自己的手里了。 |
| 34 | + |
| 35 | + |
| 36 | +## 创建 KV |
| 37 | + |
| 38 | +[参考 CF Workers KV 文档](https://developers.cloudflare.com/kv/get-started/#2-create-a-kv-namespace), |
| 39 | + |
| 40 | +```sh |
| 41 | +npx wrangler kv namespace create <BINDING_NAME> |
| 42 | +``` |
| 43 | +直接在前面创建的 worker 项目目录下创建。 |
| 44 | + |
| 45 | +上面的命令会类似有下面这个提示: |
| 46 | + |
| 47 | +``` |
| 48 | +🌀 Creating namespace with title "open-heart-worker-example-emoji-kv-example" |
| 49 | +✨ Success! |
| 50 | +Add the following to your configuration file in your kv_namespaces array: |
| 51 | +[[kv_namespaces]] |
| 52 | +binding = "emoji_kv_example" |
| 53 | +id = "cb6c56beba9f4e679aa34f0f21e0af31" |
| 54 | +``` |
| 55 | + |
| 56 | +在 worker 项目里会有个 `wrangler.toml` 的配置文件,kv_namespaces 的配置在这个文件里能找到例子。 |
| 57 | +贴上这个 binding name 和 id 的配置就可以了。 |
| 58 | + |
| 59 | + |
| 60 | +## 修改 worker 脚本 |
| 61 | + |
| 62 | +worker 怎么处理数据提供 API 的代码可以直接参考 [OpenHeart Protocol 的 Public API 代码](https://github.com/dddddddddzzzz/api-oh/blob/main/src/worker.js),抄到自己的 worker 项目里的 `src/index.ts` 文件里,改一下 kv namespace 的命名即可。 |
| 63 | + |
| 64 | +具体来说,这个 worker 需要处理两个请求: |
| 65 | +- `GET /<domain>/<uid>`:获取某个 domain 下某个 uid 的 reaction 数据,一般会是这样的 JSON,`{"❤️": 14,"🫀": 12,"🥨": 22}` |
| 66 | +- `POST /<domain>/<uid>`:用户点击某个 emoji 的话,就是用这个来 send,并记录数据 |
| 67 | + |
| 68 | +这个是例子里的处理方式,也可以根据自己需要改。 |
| 69 | + |
| 70 | +改好后,本地启动 worker `npm run dev`,就可以简单用 curl 来测试一下。 |
| 71 | + |
| 72 | +```sh |
| 73 | +$ curl -d '😻' -X POST 'http://localhost:8787/example.com/uid' |
| 74 | +# 按范例的脚本,此处会有个 recorded 信息返回 |
| 75 | +$ curl 'http://localhost:8787/example.com/uid' |
| 76 | +$ {"😻": 1} # 这样就获取了 emoji count |
| 77 | +``` |
| 78 | + |
| 79 | +## 发布 worker |
| 80 | + |
| 81 | +上面的步骤完成后,可以用 `npm run deploy` 将 worker 发布到 Cloudflare 上, |
| 82 | +然后在浏览器里面访问命令行上提示的 worker URL 就可以看到文字提示了。 |
| 83 | + |
| 84 | +## 添加到博客模版 |
| 85 | + |
| 86 | +做好了 worker 的准备,接下来只要参考[组件文档里的例子](https://github.com/dddddddddzzzz/open-heart-element),在博客模版里加上 `<open-heart>` 组件就可以了。 |
| 87 | +以我现在用的 hugo 为例,我在 partials 文件夹里加了个 [`reaction.html`](https://github.com/bambooom/bambooom.github.io/blob/master/themes/PaperMod/layouts/partials/reaction.html)。 |
| 88 | + |
| 89 | +```html |
| 90 | +<!-- emoji 也可以设置成别的,也可以设置不止一个 --> |
| 91 | +<open-heart href="https://<your-worker.url>/<domain>/{{ .Permalink }}" emoji="❤️">❤️</open-heart> |
| 92 | + |
| 93 | +<!-- load web component --> |
| 94 | +<script src="https://unpkg.com/open-heart-element" type="module"></script> |
| 95 | +<!-- when the webcomponent loads, fetch the current counts for that page --> |
| 96 | +<script> |
| 97 | +window.customElements.whenDefined('open-heart').then(() => { |
| 98 | + for (const oh of document.querySelectorAll('open-heart')) { |
| 99 | + oh.getCount() |
| 100 | + } |
| 101 | +}) |
| 102 | +// refresh component after click |
| 103 | +window.addEventListener('open-heart', e => { |
| 104 | + e && e.target && e.target.getCount && e.target.getCount() |
| 105 | +}) |
| 106 | +</script> |
| 107 | +``` |
| 108 | + |
| 109 | +设置好了之后,将这个 partial 放到你想要的地方。比如我放到 [`layouts/_default/single.html`](https://github.com/bambooom/bambooom.github.io/blob/master/themes/PaperMod/layouts/_default/single.html#L56) 里了,在 prev/next navigation 前面的地方。 |
| 110 | + |
| 111 | + |
| 112 | +最后给 `<open-heart>` 加上喜欢的样式就可以了。可以借用 benji 提供的 basic styling: |
| 113 | + |
| 114 | +```css |
| 115 | +open-heart { |
| 116 | + border: 1px solid #aaa; |
| 117 | + border-radius: .4em; |
| 118 | + padding: .4em; |
| 119 | +} |
| 120 | +open-heart:not([disabled]):hover, |
| 121 | +open-heart:not([disabled]):focus { |
| 122 | + border-color: #fff; |
| 123 | + cursor: pointer; |
| 124 | +} |
| 125 | +open-heart[disabled] { |
| 126 | + cursor: not-allowed; |
| 127 | +} |
| 128 | +open-heart[count]:not([count="0"])::after { |
| 129 | + content: attr(count); |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +或者使用组件文档里提供的一些 [demo 样式](https://github.com/dddddddddzzzz/open-heart-element/blob/main/demo.css)([预览](https://element.openheart.fyi/))。 |
| 134 | + |
| 135 | +## References |
| 136 | + |
| 137 | +- [Interactions or Reactions | benji](https://www.benji.dog/articles/interactions-or-reactions/) |
| 138 | +- [The Open Heart protocol.](https://github.com/dddddddddzzzz/OpenHeart) |
| 139 | + - https://openheart.fyi/ |
| 140 | +- [Public API for the OpenHeart protocol.](https://github.com/dddddddddzzzz/api-oh) |
| 141 | + - https://api.oh.dddddddddzzzz.org/ |
| 142 | +- [`<open-heart>` component](https://github.com/dddddddddzzzz/open-heart-element) |
| 143 | + - demo: https://element.openheart.fyi/ |
| 144 | +- [Get started - CLI · Cloudflare Workers docs](https://developers.cloudflare.com/workers/get-started/guide/) |
| 145 | +- [Get started · Cloudflare Workers KV](https://developers.cloudflare.com/kv/get-started/) |
| 146 | + |
| 147 | + |
| 148 | +可以点⬇️这个试试哦~🥰 |
| 149 | + |
| 150 | +⬇️ |
| 151 | +⬇️ |
| 152 | +⬇️ |
| 153 | + |
| 154 | +👇 |
| 155 | +👇 |
| 156 | +👇 |
0 commit comments