Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions bridge/src/quotaframe_bridge/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ def ota_transfer_bytes(self) -> int:
release_stem="mindreset-read-pico",
image_chip_id=9,
ota_partition_bytes=4 * 1024 * 1024,
web_flash=WebFlashDefinition(
name="MindReset Read Pico",
description="684 × 1216 十六灰阶墨水屏 · 触屏与按键操作",
chip_family="ESP32-S3",
asset="assets/devices/mindreset_read_pico.png",
),
),
)

Expand Down
1 change: 1 addition & 0 deletions bridge/tests/test_target_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ def test_new_web_targets_match_chip_families(self) -> None:
("waveshare_epaper_397", "ESP32-S3"),
("esp_mosaico", "ESP32-S31"),
("waveshare_rlcd_42", "ESP32-S3"),
("mindreset_read_pico", "ESP32-S3"),
):
web = TARGETS_BY_ID[target_id].web_flash
self.assertIsNotNone(web)
Expand Down
8 changes: 8 additions & 0 deletions bridge/tests/test_web_flasher.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ def test_public_target_document_contains_only_browser_fields(self) -> None:
"image": "waveshare-esp32-s3-rlcd-42-full-v1.2.3.bin",
"manifest": "manifests/waveshare_rlcd_42.json",
},
{
"id": "mindreset_read_pico",
"name": "MindReset Read Pico",
"description": "684 × 1216 十六灰阶墨水屏 · 触屏与按键操作",
"asset": "assets/devices/mindreset_read_pico.png",
"image": "mindreset-read-pico-full-v1.2.3.bin",
"manifest": "manifests/mindreset_read_pico.json",
},
],
)

Expand Down
7 changes: 5 additions & 2 deletions web/assets/devices/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Device photographs

Official product imagery, downloaded on 2026-09-08, 2026-09-20 and 2026-10-01. These images identify the
Official product imagery, downloaded on 2026-09-08, 2026-09-20, 2026-10-01 and 2026-10-06. These images identify the
supported hardware. Their screen contents are vendor demos, not QuotaFrame.
The page credits the respective official documentation next to the images.

Expand All @@ -20,8 +20,11 @@ The page credits the respective official documentation next to the images.
- `waveshare_rlcd_42.jpg`: Waveshare ESP32-S3-RLCD-4.2.
Source: https://docs.waveshare.com/ESP32-S3-RLCD-4.2
Image: https://docs.waveshare.com/assets/images/ESP32-S3-RLCD-4.2-DocHeader-fc9cf7209028a9fad948c565b694bd6b.webp
- `mindreset_read_pico.png`: MindReset Read Pico.
Source: https://dot.mindreset.tech/docs/read_0
Image: https://os-cdn.mindreset.tech/dot/docs/%25E6%25A0%2587%25E5%2587%2586_1790742665415.png

Images retain the rights of their respective owners and are not covered by the
repository's source code license. No screen replacement or device alteration
has been applied. The M5StickS3, AMOLED 2.16 and RLCD 4.2 photos are cropped and encoded as JPEG.
The ePaper 3.97 and ESP-Mosaico images retain their original encoding.
The ePaper 3.97 and ESP-Mosaico images retain their original encoding. The Read Pico image is scaled down and kept as PNG.
Binary file added web/assets/devices/mindreset_read_pico.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions web/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,10 @@ export async function initialize({
get("chosen-device-image").src = item.asset;
get("flash-panel").hidden = false;
get("flash-title").focus({ preventScroll: true });
// Hiding the picker shortens the page, which leaves the panel above the viewport
// when the chosen card was in a lower row.
const summary = get("device-summary");
if (summary.getBoundingClientRect().top < 0) summary.scrollIntoView({ block: "start" });
document.querySelectorAll("[data-target-id]").forEach((other) => {
const selected = other === card;
other.classList.toggle("is-selected", selected);
Expand Down
32 changes: 17 additions & 15 deletions web/src/components/HomePage.astro
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,9 @@ const assetRoot = locale === "en" ? "../" : "./";
<a href="https://docs.m5stack.com/en/core/StickS3">M5Stack</a>{t("、")}
<a href="https://docs.waveshare.com/ESP32-S3-Touch-AMOLED-2.16"
>{t("微雪官方文档")}</a
>{t("与")}
<a href="https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s31/esp-mosaico/user_guide.html">{t("乐鑫官方文档")}</a>{t(",屏幕内容为厂商演示。")}
>{t("、")}
<a href="https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s31/esp-mosaico/user_guide.html">{t("乐鑫官方文档")}</a>{t("与")}
<a href="https://dot.mindreset.tech/docs/read_0">{t("MindReset 官方文档")}</a>{t(",屏幕内容为厂商演示。")}
</p>
</section>
<div
Expand Down Expand Up @@ -441,7 +442,7 @@ const assetRoot = locale === "en" ? "../" : "./";
<section id="compare" class="compare wrap" aria-labelledby="compare-title">
<div class="section-intro">
<p class="eyebrow">CHOOSE YOUR SCREEN</p>
<h2 id="compare-title">{t("五块小屏,各有所长。")}</h2>
<h2 id="compare-title">{t("六块小屏,各有所长。")}</h2>
<p>{t("显示内容相同,差别在屏幕与交互。")}</p>
</div>
<p class="compare-hint" aria-hidden="true">{t("左右滑动查看全部设备 →")}</p>
Expand All @@ -455,25 +456,26 @@ const assetRoot = locale === "en" ? "../" : "./";
<th scope="col"><img src={assetRoot + "assets/devices/waveshare_epaper_397.jpg"} alt="" loading="lazy" /><small>{t("微雪")}</small>ePaper 3.97</th>
<th scope="col"><img src={assetRoot + "assets/devices/esp_mosaico.png"} alt="" loading="lazy" /><small>{t("乐鑫")}</small>ESP-Mosaico</th>
<th scope="col"><img src={assetRoot + "assets/devices/waveshare_rlcd_42.jpg"} alt="" loading="lazy" /><small>{t("微雪")}</small>RLCD 4.2</th>
<th scope="col"><img src={assetRoot + "assets/devices/mindreset_read_pico.png"} alt="" loading="lazy" /><small>MindReset</small>Read Pico</th>
</tr>
</thead>
<tbody>
<tr><th scope="row">{t("屏幕")}</th><td>{t("480 × 480 圆角方形 AMOLED")}</td><td>135 × 240 LCD</td><td>{t("800 × 480 四灰阶墨水屏")}</td><td>480 × 480 AMOLED</td><td>{t("400 × 300 黑白反射式 LCD")}</td></tr>
<tr><th scope="row">{t("用量页面")}</th><td>{t("总览 / Codex / Claude")}</td><td>{t("总览 / Codex / Claude")}</td><td>{t("主页同屏显示 Codex 与 Claude,另有趋势页")}</td><td>{t("总览 / Codex / Claude")}</td><td>{t("总览 / Codex / Claude,另有趋势页")}</td></tr>
<tr><th scope="row">{t("翻页")}</th><td>{t("触控标签、左右滑动")}</td><td>{t("正面按键")}</td><td>{t("三向拨轮")}</td><td>{t("触控标签、左右滑动、AI 键")}</td><td>{t("KEY / BOOT 按键")}</td></tr>
<tr><th scope="row">{t("时钟屏保")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("断电后需电脑端重新校时")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td></tr>
<tr><th scope="row">{t("屏保用量细条")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td></tr>
<tr><th scope="row">{t("自动旋转")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("四向")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("四向")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("四向")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td></tr>
<tr><th scope="row">{t("摇动 / 翻转唤醒")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td></tr>
<tr><th scope="row">{t("屏上设置")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("亮度、时钟超时")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("刷新间隔、方向")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("亮度、时钟超时")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("自动轮播、告警、方向")}</small></td></tr>
<tr><th scope="row">{t("托盘单击切换时钟")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td></tr>
<tr><th scope="row">{t("温湿度")}</th><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("时钟页")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("时钟页")}</small></td></tr>
<tr><th scope="row">{t("用量趋势")}</th><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("需 SD 卡")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("需 SD 卡")}</small></td></tr>
<tr><th scope="row">{t("屏幕")}</th><td>{t("480 × 480 圆角方形 AMOLED")}</td><td>135 × 240 LCD</td><td>{t("800 × 480 四灰阶墨水屏")}</td><td>480 × 480 AMOLED</td><td>{t("400 × 300 黑白反射式 LCD")}</td><td>{t("684 × 1216 十六灰阶墨水屏")}</td></tr>
<tr><th scope="row">{t("用量页面")}</th><td>{t("总览 / Codex / Claude")}</td><td>{t("总览 / Codex / Claude")}</td><td>{t("主页同屏显示 Codex 与 Claude,另有趋势页")}</td><td>{t("总览 / Codex / Claude")}</td><td>{t("总览 / Codex / Claude,另有趋势页")}</td><td>{t("主页同屏显示 Codex、Claude 与趋势")}</td></tr>
<tr><th scope="row">{t("翻页")}</th><td>{t("触控标签、左右滑动")}</td><td>{t("正面按键")}</td><td>{t("三向拨轮")}</td><td>{t("触控标签、左右滑动、AI 键")}</td><td>{t("KEY / BOOT 按键")}</td><td>{t("触屏与三枚触摸键")}</td></tr>
<tr><th scope="row">{t("时钟屏保")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("断电后需电脑端重新校时")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td></tr>
<tr><th scope="row">{t("屏保用量细条")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td></tr>
<tr><th scope="row">{t("自动旋转")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("四向")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("四向")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("四向")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("四向")}</small></td></tr>
<tr><th scope="row">{t("摇动 / 翻转唤醒")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td></tr>
<tr><th scope="row">{t("屏上设置")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("亮度、时钟超时")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("刷新间隔、方向")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("亮度、时钟超时")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("自动轮播、告警、方向")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("刷新间隔、时钟超时、方向")}</small></td></tr>
<tr><th scope="row">{t("托盘单击切换时钟")}</th><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span></td></tr>
<tr><th scope="row">{t("温湿度")}</th><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("时钟页")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("时钟页")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td></tr>
<tr><th scope="row">{t("用量趋势")}</th><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("需 SD 卡")}</small></td><td class="compare-no"><span aria-hidden="true">—</span><span class="sr-only">{t("不支持")}</span></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("需 SD 卡")}</small></td><td><span aria-hidden="true">✓</span><span class="sr-only">{t("支持")}</span><small>{t("需 SD 卡")}</small></td></tr>
</tbody>
</table>
</div>
<p class="compare-note">
{t("五块屏都支持:Codex / Claude 用量显示、电量显示、断连保留最后用量、在托盘图标上滚动翻页、电脑端 OTA 更新与网页安装。")}
{t("六块屏都支持:Codex / Claude 用量显示、电量显示、断连保留最后用量、在托盘图标上滚动翻页、电脑端 OTA 更新与网页安装。")}
</p>
</section>
<section id="privacy" class="privacy-section wrap" aria-labelledby="privacy-title">
Expand Down
Loading
Loading