Add Polymarket market link and refresh side panel docs

This commit is contained in:
2569718930@qq.com
2026-03-30 00:09:35 +08:00
parent 6c7b6de8f9
commit ee114fb5bf
5 changed files with 199 additions and 31 deletions
+25 -21
View File
@@ -1,27 +1,31 @@
# PolyWeather 侧边栏插件(MVP
# PolyWeather Side Panel
这是一个 Chrome / Edge 侧边栏扩展的 MVP,用于把 PolyWeather 右侧城市卡片移植到浏览器侧边栏
`PolyWeather Side Panel` 是一个面向天气交易场景的 Chrome / Edge 浏览器侧边栏工具
## 功能
- 侧边栏展示:
- 城市选择
- 风险徽章
- 城市档案(结算源 / 距离 / 观测更新时间 / 周边站点)
- 今日日内走势(简版 Canvas
- 多日预报(`DEB` 优先)
- 基础判断卡(方向 / 置信度 / 原因)
- 快捷按钮:
- 今日日内分析
- 历史对账
- 打开网站查看更多
- 自动识别城市:
- 监听当前激活标签页 URL(例如 Polymarket `.../event/highest-temperature-in-ankara-...`
- 自动将侧边栏城市切换为 URL 对应城市
- 设置页可配置:
- 网站基础地址
- API 基础地址
- Bearer Token(可选)
1. 自动识别当前 Polymarket 页面中的城市,也支持手动切换。
2. 展示城市档案:结算站点、站点距离、观测更新时间、周边站点数量。
3. 展示今日日内走势(简版):`DEB` 走势与官方观测(`METAR / HKO / CWA`)对照,可悬停查看时间与温度。
4. 展示多日最高温预报(简版),当前以 `DEB` 优先。
5. 支持一键刷新,强制拉取最新温度数据。
6. 支持本地缓存,提升打开速度;刷新时自动更新缓存。
7. 支持一键跳转到完整网站分析页面。
## 数据说明
- 香港使用 `HKO`(香港天文台)结算源。
- 其他城市按配置使用 `METAR / NOAA / 官方数据源`
## 权限说明
- `tabs`:用于识别当前活动标签页 URL 并自动匹配城市。
- `storage`:用于保存插件配置与本地缓存,仅存储在本地浏览器。
- `sidePanel`:用于在浏览器侧边栏展示界面。
## 隐私说明
本扩展不要求用户登录,不收集个人身份信息,不上传浏览历史,仅在必要时请求天气接口数据以完成展示功能。
## 本地安装(开发者模式)
@@ -43,7 +47,7 @@
## 说明
- 当前版本仍是轻量 MVP,重点是“监控 + 基础判断 + 导流回站”,未接入支付链路。
- 当前版本仍是轻量产品,重点是“监控 + 基础判断 + 导流回站”,未接入支付链路。
- 若你的 API 做了严格鉴权,请先在设置页填写 token 再使用。
- 台北现在按 `NOAA RCTP` 结算参考展示。
- 插件不会承载完整分析;完整结构判断、历史对账和更多信号仍以主站为准。
+2 -2
View File
@@ -1,8 +1,8 @@
{
"manifest_version": 3,
"name": "PolyWeather Side Panel",
"description": "PolyWeather 右侧城市卡片(浏览器侧边栏)",
"version": "0.1.6",
"description": "Weather side panel for Polymarket: auto-detect city, city profile, compact intraday DEB vs official observations, multi-day highs, refresh, cache, and quick jump to full analysis.",
"version": "0.1.7",
"icons": {
"16": "icon-16.png",
"32": "icon-32.png",
@@ -11,6 +11,7 @@ import { useI18n } from "@/hooks/useI18n";
import { getOfficialSourceLinks } from "@/lib/dashboard-official-sources";
import { getCityScenery } from "@/lib/dashboard-scenery";
import { CityDetail } from "@/lib/dashboard-types";
import { getTodayPolymarketUrl } from "@/lib/polymarket-market-links";
import {
getCityProfileStats,
getRiskBadgeLabel,
@@ -167,6 +168,10 @@ export function DetailPanel() {
() => (detail ? getOfficialSourceLinks(detail) : []),
[detail],
);
const marketUrl = useMemo(
() => getTodayPolymarketUrl(detail, locale),
[detail, locale],
);
const scenery = getCityScenery(detail?.name);
const blurActiveElement = () => {
if (typeof document === "undefined") return;
@@ -280,6 +285,21 @@ export function DetailPanel() {
{getRiskBadgeLabel(panelRiskLevel, locale)}
</span>
<div className="relative group">
{marketUrl ? (
<a
className="history-btn"
href={marketUrl}
target="_blank"
rel="noreferrer"
title={
locale === "en-US"
? "Open today's Polymarket market"
: "打开今日 Polymarket 题目页"
}
>
{locale === "en-US" ? "Open Market" : "打开 Polymarket"}
</a>
) : null}
<button
type="button"
className={clsx("history-btn", !isPro && "pro-locked")}
+40 -8
View File
@@ -351,7 +351,7 @@ export const DOCS_PAGES: DocsPage[] = [
content: {
"zh-CN": {
title: "浏览器插件",
description: "侧边栏插件是主站的轻量入口,负责监控、基础判断和导流,不承载完整分析链路。",
description: "PolyWeather Side Panel 是一个面向天气交易场景的浏览器侧边栏工具,负责自动识别城市、展示简版走势与城市档案,并把用户导回完整分析页面。",
sections: [
{
id: "extension-install",
@@ -372,9 +372,25 @@ export const DOCS_PAGES: DocsPage[] = [
{
type: "bullets",
items: [
"自动识别当前市场 URL,对应切换城市。",
"展示风险徽章、城市档案、今日日内走势简版和多日预报。",
"提供今日日内分析、历史对账和返回主站的快捷入口。",
"自动识别当前 Polymarket 页面中的城市,也支持手动切换。",
"展示城市档案:结算站点、站点距离、观测更新时间、周边站点数量。",
"展示今日日内走势(简版):DEB 走势与官方观测(METAR / HKO / CWA)对照,可悬停查看时间与温度。",
"展示多日最高温预报(简版),并提供一键刷新与跳转主站入口。",
],
},
],
},
{
id: "extension-permission",
title: "权限与隐私",
blocks: [
{
type: "bullets",
items: [
"`tabs`:用于识别当前活动标签页 URL 并自动匹配城市。",
"`storage`:用于保存插件配置与本地缓存,仅存储在本地浏览器。",
"`sidePanel`:用于在浏览器侧边栏展示界面。",
"插件不要求用户登录,不收集个人身份信息,不上传浏览历史,仅在必要时请求天气接口数据。",
],
},
],
@@ -409,7 +425,7 @@ export const DOCS_PAGES: DocsPage[] = [
},
"en-US": {
title: "Browser Extension",
description: "The side-panel extension is a lightweight lead-in to the main site. It focuses on monitoring, basic bias, and traffic flow back to the full dashboard.",
description: "PolyWeather Side Panel is a browser side-panel tool for weather trading workflows. It auto-detects cities, shows compact intraday and city-profile context, and routes users back to the full dashboard.",
sections: [
{
id: "extension-install",
@@ -430,9 +446,25 @@ export const DOCS_PAGES: DocsPage[] = [
{
type: "bullets",
items: [
"Auto-detects the current market URL and switches the side panel to the matching city.",
"Shows risk badges, city profile, a compact intraday chart, and multi-day forecast.",
"Provides quick links into the main intraday analysis and history reconciliation views.",
"Auto-detects the current Polymarket page city, with manual switching also available.",
"Shows a city profile with settlement station, station distance, observation timestamp, and nearby station count.",
"Shows a compact intraday chart with DEB versus official observations (METAR / HKO / CWA), including hoverable time and temperature.",
"Shows a compact multi-day daily-high forecast, plus refresh and jump-to-site actions.",
],
},
],
},
{
id: "extension-permission",
title: "Permissions and privacy",
blocks: [
{
type: "bullets",
items: [
"`tabs`: used to inspect the active tab URL and match the current city.",
"`storage`: used for local configuration and local cache only.",
"`sidePanel`: used to render the browser side panel UI.",
"The extension does not require login, does not collect personally identifiable information, and does not upload browsing history. It only requests weather endpoints when needed to render the panel.",
],
},
],
+112
View File
@@ -0,0 +1,112 @@
import type { CityDetail } from "@/lib/dashboard-types";
import type { Locale } from "@/lib/i18n";
const CITY_TO_MARKET_SLUG: Record<string, string> = {
ankara: "ankara",
atlanta: "atlanta",
austin: "austin",
beijing: "beijing",
"buenos aires": "buenos-aires",
chengdu: "chengdu",
chicago: "chicago",
chongqing: "chongqing",
dallas: "dallas",
houston: "houston",
"hong kong": "hong-kong",
istanbul: "istanbul",
london: "london",
"los angeles": "los-angeles",
lucknow: "lucknow",
madrid: "madrid",
mexico: "mexico-city",
"mexico city": "mexico-city",
miami: "miami",
milan: "milan",
munich: "munich",
"new york": "nyc",
paris: "paris",
"san francisco": "san-francisco",
"sao paulo": "sao-paulo",
seattle: "seattle",
seoul: "seoul",
shanghai: "shanghai",
shenzhen: "shenzhen",
singapore: "singapore",
taipei: "taipei",
"tel aviv": "tel-aviv",
tokyo: "tokyo",
toronto: "toronto",
warsaw: "warsaw",
wellington: "wellington",
wuhan: "wuhan",
};
const MONTHS = [
"january",
"february",
"march",
"april",
"may",
"june",
"july",
"august",
"september",
"october",
"november",
"december",
];
function normalizeCityKey(detail?: CityDetail | null) {
return String(detail?.name || detail?.display_name || "")
.trim()
.toLowerCase();
}
function slugifyCityName(cityKey: string) {
return cityKey
.trim()
.toLowerCase()
.replace(/['.]/g, "")
.replace(/&/g, " and ")
.replace(/\s+/g, "-");
}
function normalizeDateParts(localDate?: string | null) {
const value = String(localDate || "").trim();
const match = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
if (!match) return null;
const year = Number(match[1]);
const monthIndex = Number(match[2]) - 1;
const day = Number(match[3]);
if (
!Number.isFinite(year) ||
!Number.isFinite(monthIndex) ||
!Number.isFinite(day) ||
monthIndex < 0 ||
monthIndex > 11
) {
return null;
}
return {
year,
month: MONTHS[monthIndex],
day,
};
}
export function getTodayPolymarketUrl(
detail?: CityDetail | null,
locale: Locale = "en-US",
) {
const cityKey = normalizeCityKey(detail);
const citySlug = CITY_TO_MARKET_SLUG[cityKey] || slugifyCityName(cityKey);
const dateParts = normalizeDateParts(detail?.local_date);
if (!citySlug || !dateParts) return null;
const prefix =
locale === "zh-CN"
? "https://polymarket.com/zh/event/"
: "https://polymarket.com/event/";
return `${prefix}highest-temperature-in-${citySlug}-on-${dateParts.month}-${dateParts.day}-${dateParts.year}`;
}