MoreRSS

site iconAsyncX修改

面向兴趣编程,养猫,润加拿大。INTJ/P。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

AsyncX的 RSS 预览

8月小结-锻炼/探索/进步(踩雷)

2025-08-23 19:08:00

<iframe data-testid="embed-iframe" style="border-radius:12px" src="https://open.spotify.com/embed/track/0gPPcSZ5dlAncGsxa56Ck2?utm_source=generator" width="100%" height="152" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>

前言/美食/生日

写这篇博客的时候, 国内时间正好是我上一年出发, 经苏黎世国际机场转机来到加拿大的日子. 并不是什么重大的日子但也值得纪念, 毕竟也是在异乡呆了足足一年了. 一时间感慨很多, 按照国内的卷王视角来看, 我着实是碌碌无为. 但和来到这里前的自己相比, 我认为已经全方面提升了, 至少我这么说服了我自己.

来到这边后一而再再而三的感慨很多不正常的人, 但好在幸运的遇到了比较合拍的朋友们, 我们给自己起的群名是抽象大队, 逢大家生日的时候, 都会做蛋糕, 精挑细选一家合寿星口味的饭店一起吃饭. 白桃乌龙......什么什么的蛋糕, 前缀太长了

很不错的越南餐厅- 123 Dzo

运动

距离8月中旬的Summer学期结束已经1个星期了, 8月的这段时间每周保持着和朋友们运动1~2次的频率, 运动方式为骑车/游泳/网球, 主要还是打网球. 作为一个初学者, 我把羽毛球的一套动作给带到了网球中, 后果就是第一次打完胳膊酸痛, 后面学会双手引拍后好了一些. 效果拔群!

折腾

GL-MT3000路由

这是一个便携/小巧的OpenWRT系统路由器, 我在国内的时候朋友要走了家里的华为路由组mesh, 给了我一个GL-AXT1800, 我刷入了32G的存储来跑一些小东西, 例如媒体服务之类的小功能. 走的时候担心行李超重, 就没有带这个小东西过来(太后悔了). 趁着有不错的deal我就在Amazon上购入了一个MT3000, 相比AXT1800体积更小巧, 也更fit for me. 到手后开启ssh装了一些网络加速的插件, 和之前那个十几年前的路由器相比真的是质的飞跃.

为Oneplus12刷入OxygenOS

这个就说来惭愧了...一开始, 我满怀信心的在网上多方比较了教程, 选了一个看起来靠谱且简单的. 然后就开始按着步骤操作. 但在格式化系统安装OxygenOS的时候和电脑之间出现了传输问题. 然后手机就陷入了循环重启(bootloop). 在查找修理方法无果后, 果断联系了专家: 大侠阿木, 具体方法就是远程我电脑, 用更专业的工具去重装了系统. 从手机坏到修好, 历时2天, 好在结局是好的. 使用几天后, 和国内的ColorOS系统相比, 个人感觉有以下不同:

  1. 相比国内手机嵌入的ai, 氧OS的是Gemini, 生态更完善.
  2. 默认钱包应用变成了Google Wallet, 舒适.
  3. 少了烦人的默认应用和机内小功能(主题/字体/安全管家/国内app小图标)
  4. 更高的流畅度(主观)

Hitbox

今天下午(北美时间)的时候, 小孩5-4击败了blaz拿到了EWC"街霸6"的冠军. 我也是看了整整一下午的比赛.

上一年还在国内的时候, 从英国留学回来的好朋友一直在玩这个游戏, 当时我对于格斗游戏的认知还停留在街机厅的盗版拳皇/街霸和苹果手机上的kof-i. 玩kof-i的很长时间都是去打人机, 看人物/队伍背景故事. Kof-i

直到好友拉了另外2个人入坑, 看他们菜鸡互啄让我也很感兴趣, 然后我就成为了"云"玩家, 偶尔刷到视频看一看, 刷到比赛看一看. 上个月街霸6打折的时候我买了下来, 因为就是因为看到了舞(Mai, 不知火舞, 街霸6在第二年的联动角色, 除此之外还有饿狼传说的特瑞, 上图左下那位)学了一些基础打法就开始玩排位, 直到上手才发现这个游戏想要玩好真的很难, 得益于好友的指导, 定段到了黑铁(下面还有ROOKIE).

直到和真人对战, 我终于发现了格斗游戏的乐趣. 每一次拆掉对面招数的兴奋, 被拆招的懊悔, 获胜的激动都是极其纯粹的. 你只能和自己较劲, 剔除自己的弱点, 提高自己的反应. 毫不夸张的说在和真人对战胜利后的喜悦是之前所有游戏没有办法比拟的.

于是有了今天才拿到的hitbox, 上手练了一会就去找真人了, 手感良好😊: DOIO H06 + 铝合金键帽

博客装修

Astro-blog记录(7) - 小修小改和 Status Cafe组件

补充一个额外的改动: 修复了移动端的主页bug/添加了移动端的header适配

书影音游

++movie/0iqN1YrAG0Hh0HdmFv7y8v++

++movie/0NxFGhJflscHm7pEZaiW6Y++

++movie/01OH5yp4S3vzDTRNoAOJDl++

++tv/1e1nw4EEXVAwE0bSImEp9y++

++tv/6HBkGRTvqrik3cgp9Of7mg++

Astro-blog记录(7) - 小修小改和 Status Cafe组件

2025-08-09 06:08:00

前言

不知道是我经常在互联网冲浪还是运气好, 总是能在冒出一些想法的时候找到需要的工具....最近在玩Warframe, 有一些奖励丰厚任务是随机出现的, 我就调API简单用Discord Webhook进行推送:

于是我又想到, 能不能用写一个Discord的bot, 我把一些零碎的实时状态发过去, bot会读取然后更新blog的repo, 实时显示到blog上. 但前段时间Alanone发消息更新blog的时候, 我顺便去串门看了一下, 发现了Status Cafe这个网站.

Status Cafe & 小组件

Status Cafe是一个发布实时状态的网站/组件,用户发布的状态可以RSS订阅,用网站提供的代码也可以显示到自己的网页中. 这类似于自部署的博客点赞小组件Openheart, 在curl的时候额外带上了文本. 省去了折腾的功夫. 使用过程中唯一遇到的问题就是从注册到收到成功邮件约1天时间, 看样子是站长亲自审核的, 吓得我以为是Cloudflare的邮件转发(博客的主要沟通邮箱通过Cloudflare部署)宕机了, 连着换邮箱注册了3个账户....

这个网站有一个Status stream, 你可以在上面看到所有人的status, 就像一个大型的博客聚合, 偶尔会发现让人感叹的网站. (大家怎么能这么会设计? 博客大装修再次提上日程). 闲逛过程也是发现鲜有中文的status, 不过也逛到了小鱼老师的博客, 点进去发现果然有写status的文章. Status cafe提供了一些badge, 例如:<a href="https://status.cafe/users/asyncx"><img src="https://status.cafe/users/asyncx/badge.png" alt="Status Cafe Profile"/></a>和<a href="https://status.cafe"><img src="https://status.cafe/assets/button.png" alt="Status Cafe"/></a>, 不过被我嫌丑所以没有打算用这个. 之后装修博客的时候计划为这些组件画一些像素badge(inspired by LMNT).

此外, Status cafe提供了一个显示最新状态的小组件, 通过这个小组件你就可以把最新的status显示在网页中. 自带的css略微复古, 就手搓了一个. 易于使用的小组件页面

<div
  id="statuscafe"
  class="ml-auto w-fit rounded-md border-bgdefault dark:border-fontdefault p-3 transition-colors duration-300"
>
  <div class="text-center">
    <div
      id="statuscafe-content"
      class="inline text-sm font-mono leading-relaxed text-zinc-900 dark:text-zinc-100"
    >
      Loading...
    </div>
    <span class="mx-1 text-xs text-zinc-500 dark:text-zinc-500">(</span>
    <div
      id="statuscafe-username"
      class="inline text-xs font-mono tracking-wide text-zinc-500 dark:text-zinc-500"
    >
      Loading...
    </div>
    <span class="mx-1 text-xs text-zinc-500 dark:text-zinc-500">)</span>
  </div>
</div>

PS: 因为Status cafe的主页还没装修, 目前并不打算很显式地公布link, 所以当我发现这个小组件会请求远程的js来进行渲染, 就把js嵌入到本地进一步修改了:

document.writeln(`
  <div id="statuscafe">
    <div id="statuscafe-username"></div>
    <div id="statuscafe-content"></div>
  </div>
`);
fetch("https://status.cafe/users/asyncx/status.json")
  .then((r) => r.json())
  .then((r) => {
    if (!r.content.length) {
      document.getElementById("statuscafe-content").innerHTML = "No status yet.";
      return;
    }
    document.getElementById("statuscafe-username").innerHTML = r.timeAgo;
    document.getElementById("statuscafe-content").innerHTML = r.content;
  });

效果就像在主页看到的一样:

Astro的ViewTransition

Astro v5 把 <ViewTransitions /> 组件改名成了 <ClientRouter />, 已手动修改. 但还是有一些bug没有解决, 例如整个网站对某些外部资源的请求只进行一次, 如果请求内容发生变化仍有几率不会重新请求, 进而导致显示异常, 比如Twiiko评论, 这个bug我会尽可能的修复.

发布本文2h后已修复. 解决方法为在<head>添加相应外部资源进行持久化

添加Solana赞赏

V2EX的站长Livid上线了一些加密货币的功能, 出发点是好的, 但站内充斥的乞讨信息令人厌烦. 个人建议加一个分区叫Begging. 我一直对去中心化和联邦宇宙等比中心化自由的架构形态充满兴趣, 所以买了60$的V2EX币, 也顺手给blog加上了赞赏链接, 不过为了不影响观感, 添加到了某个不显眼的地方.

移除/recent

最近做了什么这个页面我并不经常更新, 可见性没有Status cafe高, 互动性没有Mastodon强, 趁着这次更新干脆就暂时移除掉了, 后续如果有更好的想法或装修好Status cafe会再次开放.

4-7月小结-庸庸碌碌

2025-07-11 21:07:00

前言

忙于学业, 好久没有更新. 为了追上之前落下的学分, 我选择在summer term报了full-time, 又因为夏季的学期有2段, 所以有2门课程集中在了第1段, 这就类似于我在一个正常的学期一周上5门课,每门课又有1/2个LEC课和1/2个LAB课. 第一段学期对我来说实在是太难了. 好在磕磕碰碰的结束了这个学期, 除了考试我感到不满意外, 我的作业和项目几乎都拿到了高分以至于满分. 一定程度上这对我来说也是一种鼓励吧.

消费主义陷阱

4个月前称体重的时候, 我的体重还一如既往的是65kg. 上周称体重的时候, 已经69kg了. 上一年爬Saint-Bruno的时候, 也是我有史以来第一次爬山爬到上气不接下气, 心率一度到200. 刚好看到Garmin的官网在打折, 于是买了一块Garmin Fēnix 7 Pro Sapphire Solar.

到手后跑了一下, 发现我的身体机能下降到了一个不敢想象的地步.1km一圈, 跑了3圈, 配速是8' 8' 7'. 第三圈的末尾我的心率从140断崖式上升到200. 很难想初中高中那时候的跑操是怎么跑下来的.

很多专业的数据我还没有了解清楚, 我目前看的指标有: BPM(平均心率, 运动的时候看)和Body Battery(实时显示的身体电量, 休息和睡觉会充电, 压力和运动会消耗身体电量). 此外, Garmin会根据你的上述指标和其他状态来告诉你今天的理想运动内容. 目前我只用到了一部分的功能, 其他的还没有琢磨.

第二段学期只有1门课, 所以我打算在每次下课后去爬Mont-Royal来增强心肺功能.

最后, 我一如既往的折腾了一个运动网页. 本来计划想用yihong0618/running_page这个repo来实现, 但是我并不想展示轨迹, 于是在了解了Garmin connect API的原理后自己动手写了一个. 功能很简单, 具体来说就是Python模拟登录来获得运动数据的json并处理成.csv, 存储到src/component中, 前端渲染交给Astro来实现. 我会在晚些时候单独写一篇文章. 默认页详情数据展示

运行交给了Github, 部署交给了Cloudflare. 使用Actions, 在每日凌晨自动读取数据, 触发Cloudflare更新.

生活

我现在住的地方是外公外婆的房子, 天气变暖他们就从国内回来了. 所以我自然而然失去了厨房的所有权. 现在顿顿吃得极度清淡, 只能寄希望于和朋友们出门吃点口味重的. 考完试后, 我们一起去了昆虫馆:

书影音游

++game/5pvs201VxbkldH4LOEtDVt++

++game/35pyo0ZwNaEsTGrywLIsJ1++

++movie/3pzmdXn8JRf4xIulfvb9Ef++

++movie/6Vu6XIJIMSY2WWWobxj9r1++

Astro-blog记录(6) - 制作一个自同步运动数据页

2025-07-11 21:07:00

前言

本文的实现并没有包含路径展示,分年统计的功能, 如果你需要更成熟的方案, 可以使用yihong0618/running_page.

前几天购入了一块佳明, 在进行几次运动后一如既往的想要折腾一下, 就有了写一个运动数据页的想法. 我的需求很简单, 有一个总体数据展示, 并且可以兼顾隐私性(数据太多不会读)和扩展性(万一以后想加点什么). 所以初步功能就定为了:

  1. 用一列数据来展示已经运动了多少
  2. 用一个表格来汇总所有运动的细节
  3. 添加一个"更新日期"方便观察运行情况

本文基于Python模拟Garmin connect登录以获得运动数据, 并存储为csv文件, 之后使用Astro基于csv文件进行前端页面的渲染. 其中自动化运行Python是通过Github Actions完成的. 你可以访问我的库来获得详情: A5yncX/my_running

1. 运行环境

由于佳明开启心电图功能后需要二次验证(邮箱验证码/短信验证码), 并且在短时间内多次的登录会触发cloudflare的风控, 所以本文方法是基于登录生成的token登录. 你需要如下包:

pip install garminconnect httpx cloudscraper

接下来, Fork我的仓库是最快的方法, 如果你并不想fork, 也可以点击Code -> Download zip到本地修改并继续运行.

2. 首次运行的准备

在项目目录运行:

python3 running/garminconnect_exporter.py --username YOUR_MAIL --password YOUR_PSWD

这一步的作用是在本地生成2个JSON格式的Token, 用来持久化登录, 有效期据github上的大家说是1年.

在你首次运行并接收到验证码后, 这两个文件会生成到位于你电脑的根目录的.garminconnect文件夹内, 文件的名字是oauth1_token.json/oauth2_token.json, 之后你运行一下命令就可以直接基于token进行登录了:

python3 running/garminconnect_exporter.py

首次运行后你会发现csv文件生成于src/components/activities.csv. 这就是后续使用Astro可以进行读取的文件了. 接下来的步骤需要你先推送到github.

3. (重要)(可选)Github Actions自动更新

如果你更倾向于手动更新, 那么恭喜你, 你可以略过这里跳转到部署那一步了.

本地运行garminconnect_exporter.py依托于本地的那2个token, 但是在Github上如果直接将这2个json的内容作为variable传入, 会出现换行符等问题导致没法正常使用, 所以需要用base64转换并存储, 接下来是详细步骤:

3.1 生成base64文件:

到本地.garminconnect文件夹的目录中, 你会发现那2个json文件, 分别运行:

base64 -i oauth1_token.json

base64 -i oauth2_token.json

分别复制这2个命令的输出, 并点击存储库的setting: Setting->Secrets and variables->Actions->New repository secrets 设置两个secret, 命名为GARMIN_OAUTH1_B64/GARMIN_OAUTH2_B64, 分别存储这2个命令的输出.

3.2 (可选)存储账号密码到secret

这一步的作用是方便没有邮箱/短信登录验证的人使用的, 以及如果后续token失效, 你的邮箱/短信会收到一次验证码, 可以起到提醒你更新token的作用. 依旧点击存储库的setting: Setting->Secrets and variables->Actions->New repository secrets, 设置两个secret, 命名为GARMIN_USERNAME/GARMIN_PASSWORD, 值就是你的登录账号密码.

3.3 试运行

删除github repo中之前生成的csv文件, 点击Actions手动运行一下, 查看是否正确生成.

4. 部署(Cloudflare)

侧边栏选择计算(Workers), 创建pages, 模板选择Astro, 默认的命令和路径不需要改变, 等待部署成功即可.

3月小结-自得其乐

2025-04-14 05:04:00

前言

距离上次更新已经1个多月了, 拖更的原因无非是学业, 以周为单位的代码实验课再加上偶尔的其他project也让我在很多时候应接不暇. 至于标题为什么是自得其乐, 是因为这个月没怎么进行不必要的社交, 这对一个I人来说是难能可贵的.

学业

我有想过这样的问题: 为什么每次小结我都要阶段性的提及我的学习方面? 这样的分类有没有存在的必要? 不过这个纠结点只存在了一会就消失了. 现在作为一个学生, 从任何角度来说都没有对学习略过不谈的理由. 而作为一个完全没有前车之鉴就出国读书的小白, 我自认为留下一些属于自己的记录是会对大家有帮助的.

言归正传, 在停更的这段时间里, 我经历了6个实验, 2个代码考试, 1个期末考试外加几个presentation. 其中的代码考试和实验全部都是一门java编程课, 这门课的教授要求如下:

  1. 上课不能使用任何电子设备.
  2. 在实验和代码考试中你只能手写代码, 期间断网+禁止使用电子设备.

那么实验和考试是如何开始的:

  1. TA在每次实验和考试(这两者的考察模式一模一样)开始前会先检查并确认你的电脑没法访问网络
  2. TA会发卷子并讲解题目, 卷子会提供input case和output case, 这和Leetcode上的写方法不同.
  3. 完成代码并提交, 系统会测试并给你反馈.

我在本科期间的实际java代码量少的可怜, 完全没有从0到1的完成过完整的代码, 所以在这门课开始的时候我很抓瞎, 至于抓瞎到什么程度: 第一次实验的内容是你需要对一个Array进行翻转和一些种类的遍历, 我当时甚至不知道java要怎么读取用户的输入(Scanner sc = new Scanner(System.in)),在和旁边的中国同学窃窃私语得到答案后, 我又不知道怎么创建Array, 甚至不知道怎么遍历. 满分10分得了1/10.

之后我狠狠的下了一番功夫, 实验和考试是在每周一的6:30PM开始的, 因为大家的变成水平良莠不齐, 经常考到11点才能回家, 因为我家离学校很远, 几乎每天回到家都是凌晨1点. 这里也留一下我对于这门课的心得: 我会在每周六看教授在交流软件上发布的关于下次考试的内容, 然后阅读教授的个人网站上的教学代码, 在过完所有的代码后结合考点去学习方法的写法和思路, 期间会用GPT学习一些代码写法上的简单问题, 我的prompt是请你基于费曼学习法为我讲解XXXX(在这里我十分感谢汪哥, 我们之前关于获取信息的一些聊天让我受益匪浅). 在搞清楚所有可能考查的知识点后, 我会用markdown生成pdf打印下来, 便于随时看. 为了日常的交作业和打印的方便和统一, 手搓了一个Typora输出pdf的主题(宋体+Times new roman)

这个教授平心而论, 很负责人且反馈迅速, 他能记住课上110+个学生每个人的名字,每次的考试也都会和同学沟通, 会去查看答题情况进而调整下次的实验/考试.

生活

正如前言所说, 这个月没有那么多无意义的社交, 我依旧把大量的时间花费到了怎么犒劳自己的肚子上了. 这个月我也是带着诸如"我做的卤猪蹄真的很好吃"/"我煲的汤真的很好喝"的想法在做饭:

还有在和大家聚餐时候做的腌笃鲜/可乐鸡翅.....

消费主义陷阱

因为我的手机膜告急, 不得不从淘宝买新的膜, 想着单独买有些亏, 遂再次步入了消费主义陷阱:

三菱UNI KURUTOGA自动铅笔

来到这里后因为考试/日常使用, 自动铅笔成了我唯一的文具. 我的上一根笔是三菱的α-gel 什么的, 宣传点是铅芯会随着每次写字自动旋转, 以保持字迹粗细的一致(很好用),和握住的那个凝胶能集中注意力(实际用下来真的很舒服, 并且用了2年没有任何老化问题). 这次更换后高强度使用, 得益于金属笔杆, 相比于上一根, 用起来更踏实, 字迹也更好控制了(妈见打, 就不放图片了)

CASIO B5600钛合金表壳+表带

这个表是好朋友在前些时候换了CASIO的农家橡树, 他没地方用也就寄给了我. 我的手腕实在太细了, 再加上他之前给我的是不锈钢壳, 想到快到夏天就顺便买了一个好评的小厂造的钛合金表壳+表带. 我在换钛合金前的称重是131g, 在换后的重量是100g, 和之前比舒服了特别多.

迄今为止我给这个表改过:

  1. 太阳能面板(b5000黑色原装)
  2. 原装stn反显(可视角度更大)
  3. 钛合金表壳+表带

书影音游

++tv/5n1XRGkYnDWyLdkhQXMd3H++

++movie/3rsuSP1f283c5CuJdxyMIt++

++tv/7XMBvKp7G4l7hoo6oX1PMG++

2月小结-悠闲生活

2025-03-01 05:02:00

前言

一眨眼也是进入了这学期的reading week. 和第一个学期的reading week相比大家都没有那么激动了, 这次就没有出门旅游, 只是简单的聚了个餐. 就像这篇博文的标题一样, 我认为这个月的主题就是悠闲.

生活

食物方面, 从有了自己的厨房以来就没有再亏待过自己的嘴巴. 自己在家琢磨各种各样的美食. 比如下图, 按照记忆中的味道去复刻大学时候和女友吃到的土豆鸡+虾/用Instantpot去炖的猪蹄/去朋友家做的大烩菜/豉汁排骨/可乐鸡翅+虎皮蛋.

这里留一个最满意的高压锅炖猪蹄的菜谱:

  1. 猪蹄切块, 葱姜料酒焯水,水开之后焯5分钟, 捞出过冷水.
  2. 加入Instantpot(高压锅), 生抽老抽, 少盐(1~2茶勺), 多糖(约6块冰糖), 2片香叶, 1个八角, 我额外加了一些花椒黑胡椒.
  3. High pressure 25min, 手动放气
  4. 转入敞口的大锅, 大火收汁至黏稠.

我在中国超市买了2个猪蹄, 大约是8CAD, 吃了4顿. 一开始还在担心这么多的汤汁到底要浇多久的米饭才能用完, 结果好吃到仅仅4顿就连汤带肉一起消灭掉了, 一点都没有剩下.

消费主义陷阱

上个月的月度小结里没有写到这个主题, 就在这里归纳一下: 本月入手了2个小玩意.

Kindle Paperwhite 6 32G

第六期-一些Kindle的使用方法

详情我写在了这篇当中, 我着重说一下使用体验. 使用场景大概是每天的通勤2h+晚上在床上看2h, 算是中等程度的使用. 新的一代据说是暖屏(没有参照物), 我习惯将色温设置在和Marginnote4的护眼色相近的10档. 和看手机屏幕比, 体验好了不止一点, 也变相的大幅提升了我的阅读时间, 这个月看的书得超过之前5年看的书了(笑).

Rog夜魔声音包(炸虾粒客制化)

这是从国内邮寄过来的, 大概上年年末的时候遇到一个学长要回国, 在小红书上卖全新的白夜魔和xbox手柄, 价钱折合人民币不到1100, 刚好身边朋友需要xbox手柄, 我就一起购入了. 之后也一直没有顾得上改这个键盘(北美客制化的发展没有竞争对手去卷, 和国内比少太多配件了), 直到情人节, 女友问我要什么我选了这个. 白夜魔(雪武白轴)+FR4定位板(夜魔声音包9件套) 和刚到手的声音相比, 键盘的声音更偏向于麻将音了. 我还额外买了圣熊猫的镀金卫星轴, 出乎意料的是夜魔原装的简易卫星轴的发挥全方位优于圣熊猫的卫星轴, 最后我还是换上了原装的简易卫星轴.

博客装修

更清晰的点赞追踪

我在arc浏览器code分类的侧边栏根目录下保存了Umami访客统计, 一般2~3天我都会看一下读者会从哪里访问. 最多的来源一般是V2EX, 其次是我之前在知乎上发布的一些教程, astro的官网和astro中国开发者的导航页, 再其次是google, 最后是赛博友邻的友链.

言归正传, umami可以添加一些自定义的event来方便追踪用户行为, 之前对于点赞的event只定义了一个Like标志, 即使能看到有读者点赞了文章, 但是没有办法显示读者点赞了哪一篇文章. 现在修改为data-umami-event=${fileName}-Like, 这样的好处是可以知道读者点赞了哪片具体的文章.

<open-heart href={`https://xxx/${currentUrl}/like`} data-umami-event=`${fileName}-Like` emoji="♥">♥</open-heart>

书影音游页

Astro-blog记录(5)-添加NeoDB影音页

小彩蛋

这个月的闲暇时间尝试了一下像素画, 于是有了about页面右下角的产物: 点击后会出现毛毛的丑照(毛毛就是我的长毛猫, 具体可以看这篇文章)

书影音游

++book/4bVED3OmX1AIAOy52Yxp4W++

++book/0Qv4iGUnpdGHu9GEqpP5xh++

++book/3BWmn3mhMrqIazr5ZO3pTa++

++movie/6Bob1fCW9QcEpZoL56X16n++

++tv/season/6ReFpsYl0zhcWdmgiCIOoO++

++tv/7in2q2PQbOkpEcgnqr5DeP++