From 516657f849e166e4ef730777b3f696730d8d94a2 Mon Sep 17 00:00:00 2001 From: nite Date: Mon, 20 Oct 2025 16:45:42 +1100 Subject: [PATCH] refactor(frontend): Extract short link UI into dedicated component --- server/frontend/src/app.ts | 73 ++----- .../src/components/short-link-input-group.ts | 180 ++++++++++++++++++ 2 files changed, 199 insertions(+), 54 deletions(-) create mode 100644 server/frontend/src/components/short-link-input-group.ts diff --git a/server/frontend/src/app.ts b/server/frontend/src/app.ts index d4c18c8..8a4c75e 100644 --- a/server/frontend/src/app.ts +++ b/server/frontend/src/app.ts @@ -7,6 +7,7 @@ import { base64EncodeUnicode, base64decodeUnicode } from "./utils.js"; import "./components/rule-provider-input.js"; import "./components/rule-input.js"; import "./components/rename-input.js"; +import "./components/short-link-input-group.js"; @customElement("sub2clash-app") export class Sub2clashApp extends LitElement { @@ -145,6 +146,7 @@ export class Sub2clashApp extends LitElement { // 设置返回的短链ID和密码 this.shortLinkID = response.data.id; this.shortLinkPasswd = response.data.password; + this.showDialog("成功", "生成短链成功"); }) .catch((error) => { if (error.response && error.response.data) { @@ -183,11 +185,11 @@ export class Sub2clashApp extends LitElement { } ) .then(() => { - this.showDialog("成功", "更新成功"); + this.showDialog("成功", "更新短链成功"); }) .catch((error) => { if (error.response && error.response.status === 401) { - this.showDialog("", "密码错误"); + this.showDialog("", "短链不存在或密码错误"); } else if (error.response && error.response.data) { this.showDialog("", "更新短链失败:" + error.response.data); } else { @@ -214,7 +216,7 @@ export class Sub2clashApp extends LitElement { }, }) .then(() => { - this.showDialog("成功", "删除成功"); + this.showDialog("成功", "删除短链成功"); }) .catch((error) => { if (error.response && error.response.status === 401) { @@ -609,8 +611,7 @@ export class Sub2clashApp extends LitElement {
- + 输出配置 @@ -637,55 +638,19 @@ export class Sub2clashApp extends LitElement { -
-
- - - - - - -
-
+ +
diff --git a/server/frontend/src/components/short-link-input-group.ts b/server/frontend/src/components/short-link-input-group.ts new file mode 100644 index 0000000..9386b06 --- /dev/null +++ b/server/frontend/src/components/short-link-input-group.ts @@ -0,0 +1,180 @@ +import { html, LitElement, unsafeCSS } from "lit"; +import { customElement, property } from "lit/decorators.js"; +import globalStyles from "../index.css?inline"; + +@customElement("short-link-input-group") +export class ShortLinkInputGroup extends LitElement { + static styles = unsafeCSS(globalStyles); + + @property() + id: string = ""; + + @property({ type: Number }) + _screenSizeLevel: number = 0; + + @property() + passwd: string = ""; + + connectedCallback() { + super.connectedCallback(); + window.addEventListener("resize", this._checkScreenSize); + this._checkScreenSize(); // Initial check + } + + disconnectedCallback() { + window.removeEventListener("resize", this._checkScreenSize); + super.disconnectedCallback(); + } + + _checkScreenSize = () => { + const width = window.innerWidth; + if (width < 365) { + this._screenSizeLevel = 0; // sm + } else if (width < 640) { + this._screenSizeLevel = 1; // md + } else { + this._screenSizeLevel = 2; // other + } + }; + + async copyToClipboard(content: string, e: HTMLButtonElement) { + try { + await navigator.clipboard.writeText(content); + let text = e.textContent; + e.addEventListener("mouseout", function () { + e.textContent = text; + }); + e.textContent = "复制成功"; + } catch (err) { + console.error("复制到剪贴板失败:", err); + } + } + + idInputTemplate() { + return html``; + } + + passwdInputTemplate() { + return html``; + } + + generateBtnTemplate(extraClass: string = "") { + return html``; + } + + updateBtnTemplate(extraClass: string = "") { + return html``; + } + + deleteBtnTemplate(extraClass: string = "") { + return html``; + } + + copyBtnTemplate(extraClass: string = "") { + return html``; + } + + render() { + const sm = html`
+
+ ${this.idInputTemplate()} ${this.passwdInputTemplate()} +
+
+ ${this.generateBtnTemplate("w-1/2")} ${this.updateBtnTemplate("w-1/2")} +
+
+ ${this.deleteBtnTemplate("w-1/2")} ${this.copyBtnTemplate("w-1/2")} +
+
`; + + const md = html`
+
+ ${this.idInputTemplate()} ${this.passwdInputTemplate()} +
+
+ ${this.generateBtnTemplate("w-1/4")} ${this.updateBtnTemplate("w-1/4")} + ${this.deleteBtnTemplate("w-1/4")} ${this.copyBtnTemplate("w-1/4")} +
+
`; + + const other = html`
+
+ ${this.idInputTemplate()} ${this.passwdInputTemplate()} + ${this.generateBtnTemplate()} ${this.updateBtnTemplate()} + ${this.deleteBtnTemplate()} ${this.copyBtnTemplate()} +
+
`; + + switch (this._screenSizeLevel) { + case 0: + return sm; + case 1: + return md; + default: + return other; + } + } +} + +declare global { + interface HTMLElementTagNameMap { + "short-link-input-group": ShortLinkInputGroup; + } +}