瀏覽代碼

fix(sub): keep copy page within mobile viewport

Constrain the copy-only subscription page to the dynamic viewport, wrap long localized text, and infer text direction so mobile browsers cannot render a horizontally shifted desktop-width page. Add regression coverage for the responsive layout contract.
Sanaei 10 小時之前
父節點
當前提交
338822ab07
共有 2 個文件被更改,包括 28 次插入4 次删除
  1. 6 4
      internal/sub/controller.go
  2. 22 0
      internal/sub/controller_browser_test.go

+ 6 - 4
internal/sub/controller.go

@@ -546,15 +546,17 @@ func (a *SUBController) serveSubscriptionCopyPage(c *gin.Context) {
   <meta name="robots" content="noindex,nofollow">
   <title>{{TITLE}}</title>
   <style>
-    html, body { margin: 0; min-height: 100%; background: #050505; color: #f2f2f2; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
-    body { min-height: 100vh; display: flex; align-items: center; justify-content: center; text-align: center; }
-    main { max-width: 520px; padding: 32px; }
+		* { box-sizing: border-box; }
+		html { min-height: 100%; background: #050505; }
+		body { margin: 0; width: 100%; min-height: 100vh; min-height: 100dvh; padding: 24px; overflow-x: hidden; display: grid; place-items: center; background: #050505; color: #f2f2f2; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; text-align: center; }
+		main { width: 100%; max-width: 520px; min-width: 0; padding: 32px; overflow-wrap: anywhere; }
     h1 { margin: 0 0 14px; font-size: 24px; font-weight: 650; letter-spacing: -0.02em; }
     p { margin: 0; color: #b8b8b8; font-size: 16px; line-height: 1.55; }
+		@media (max-width: 480px) { body { padding: 16px; } main { padding: 24px 8px; } }
   </style>
 </head>
 <body>
-  <main>
+	<main dir="auto">
     <h1>{{HEADING}}</h1>
     <p>{{INSTRUCTIONS}}</p>
   </main>

+ 22 - 0
internal/sub/controller_browser_test.go

@@ -105,6 +105,28 @@ func TestSubscriptionCopyPageUsesRequestLocale(t *testing.T) {
 	}
 }
 
+func TestSubscriptionCopyPageIsMobileSafe(t *testing.T) {
+	w := httptest.NewRecorder()
+	c, _ := gin.CreateTestContext(w)
+	c.Request = httptest.NewRequest(http.MethodGet, "/sub/abc", nil)
+
+	(&SUBController{}).serveSubscriptionCopyPage(c)
+	body := w.Body.String()
+	for _, required := range []string{
+		`<meta name="viewport" content="width=device-width, initial-scale=1">`,
+		`* { box-sizing: border-box; }`,
+		`min-height: 100dvh`,
+		`overflow-x: hidden`,
+		`overflow-wrap: anywhere`,
+		`@media (max-width: 480px)`,
+		`<main dir="auto">`,
+	} {
+		if !strings.Contains(body, required) {
+			t.Fatalf("copy page is missing mobile layout constraint %q", required)
+		}
+	}
+}
+
 func TestExplicitSubPageRequest(t *testing.T) {
 	gin.SetMode(gin.TestMode)