mirror of
				https://github.com/bestnite/sub2clash.git
				synced 2025-11-04 04:40:36 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			v1.1.0-rc
			...
			v1.1.0-rc.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						516657f849
	
				 | 
					
					
						
@@ -7,6 +7,7 @@ import { base64EncodeUnicode, base64decodeUnicode } from "./utils.js";
 | 
				
			|||||||
import "./components/rule-provider-input.js";
 | 
					import "./components/rule-provider-input.js";
 | 
				
			||||||
import "./components/rule-input.js";
 | 
					import "./components/rule-input.js";
 | 
				
			||||||
import "./components/rename-input.js";
 | 
					import "./components/rename-input.js";
 | 
				
			||||||
 | 
					import "./components/short-link-input-group.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@customElement("sub2clash-app")
 | 
					@customElement("sub2clash-app")
 | 
				
			||||||
export class Sub2clashApp extends LitElement {
 | 
					export class Sub2clashApp extends LitElement {
 | 
				
			||||||
@@ -145,6 +146,7 @@ export class Sub2clashApp extends LitElement {
 | 
				
			|||||||
        // 设置返回的短链ID和密码
 | 
					        // 设置返回的短链ID和密码
 | 
				
			||||||
        this.shortLinkID = response.data.id;
 | 
					        this.shortLinkID = response.data.id;
 | 
				
			||||||
        this.shortLinkPasswd = response.data.password;
 | 
					        this.shortLinkPasswd = response.data.password;
 | 
				
			||||||
 | 
					        this.showDialog("成功", "生成短链成功");
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .catch((error) => {
 | 
					      .catch((error) => {
 | 
				
			||||||
        if (error.response && error.response.data) {
 | 
					        if (error.response && error.response.data) {
 | 
				
			||||||
@@ -183,11 +185,11 @@ export class Sub2clashApp extends LitElement {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
      .then(() => {
 | 
					      .then(() => {
 | 
				
			||||||
        this.showDialog("成功", "更新成功");
 | 
					        this.showDialog("成功", "更新短链成功");
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .catch((error) => {
 | 
					      .catch((error) => {
 | 
				
			||||||
        if (error.response && error.response.status === 401) {
 | 
					        if (error.response && error.response.status === 401) {
 | 
				
			||||||
          this.showDialog("", "密码错误");
 | 
					          this.showDialog("", "短链不存在或密码错误");
 | 
				
			||||||
        } else if (error.response && error.response.data) {
 | 
					        } else if (error.response && error.response.data) {
 | 
				
			||||||
          this.showDialog("", "更新短链失败:" + error.response.data);
 | 
					          this.showDialog("", "更新短链失败:" + error.response.data);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -214,7 +216,7 @@ export class Sub2clashApp extends LitElement {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .then(() => {
 | 
					      .then(() => {
 | 
				
			||||||
        this.showDialog("成功", "删除成功");
 | 
					        this.showDialog("成功", "删除短链成功");
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .catch((error) => {
 | 
					      .catch((error) => {
 | 
				
			||||||
        if (error.response && error.response.status === 401) {
 | 
					        if (error.response && error.response.status === 401) {
 | 
				
			||||||
@@ -609,8 +611,7 @@ export class Sub2clashApp extends LitElement {
 | 
				
			|||||||
          </fieldset>
 | 
					          </fieldset>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <fieldset class="fieldset mb-8">
 | 
					          <fieldset class="fieldset mb-8">
 | 
				
			||||||
            <legend
 | 
					            <legend class="fieldset-legend text-2xl font-semibold mb-4">
 | 
				
			||||||
              class="fieldset-legend text-2xl font-semibold mb-4 text-center">
 | 
					 | 
				
			||||||
              输出配置
 | 
					              输出配置
 | 
				
			||||||
            </legend>
 | 
					            </legend>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -637,55 +638,19 @@ export class Sub2clashApp extends LitElement {
 | 
				
			|||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div class="form-control mb-2">
 | 
					            <short-link-input-group
 | 
				
			||||||
              <div class="join w-full">
 | 
					              .id="${this.shortLinkID}"
 | 
				
			||||||
                <input
 | 
					              .passwd="${this.shortLinkPasswd}"
 | 
				
			||||||
                  class="input input-bordered w-1/2 join-item"
 | 
					              @id-change="${(e: Event) => {
 | 
				
			||||||
                  type="text"
 | 
					                this.shortLinkID = (e.target as HTMLInputElement).value;
 | 
				
			||||||
                  placeholder="ID(可选)"
 | 
					              }}"
 | 
				
			||||||
                  .value="${this.shortLinkID}"
 | 
					              @passwd-change="${(e: Event) => {
 | 
				
			||||||
                  @change="${(e: Event) => {
 | 
					                this.shortLinkPasswd = (e.target as HTMLInputElement).value;
 | 
				
			||||||
                    this.shortLinkID = (e.target as HTMLInputElement).value;
 | 
					              }}"
 | 
				
			||||||
                  }}" />
 | 
					              @generate-btn-click="${this.generateShortLink}"
 | 
				
			||||||
                <input
 | 
					              @update-btn-click="${this.updateShortLink}"
 | 
				
			||||||
                  class="input input-bordered w-1/2 join-item"
 | 
					              @delete-btn-click="${this.deleteShortLink}">
 | 
				
			||||||
                  type="text"
 | 
					            </short-link-input-group>
 | 
				
			||||||
                  placeholder="密码"
 | 
					 | 
				
			||||||
                  .value="${this.shortLinkPasswd}"
 | 
					 | 
				
			||||||
                  @change="${(e: Event) => {
 | 
					 | 
				
			||||||
                    this.shortLinkPasswd = (e.target as HTMLInputElement).value;
 | 
					 | 
				
			||||||
                  }}" />
 | 
					 | 
				
			||||||
                <button
 | 
					 | 
				
			||||||
                  class="btn btn-primary join-item"
 | 
					 | 
				
			||||||
                  type="button"
 | 
					 | 
				
			||||||
                  @click="${this.generateShortLink}">
 | 
					 | 
				
			||||||
                  生成短链
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
                <button
 | 
					 | 
				
			||||||
                  class="btn btn-primary join-item"
 | 
					 | 
				
			||||||
                  @click="${this.updateShortLink}"
 | 
					 | 
				
			||||||
                  type="button">
 | 
					 | 
				
			||||||
                  更新短链
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
                <button
 | 
					 | 
				
			||||||
                  class="btn btn-primary join-item"
 | 
					 | 
				
			||||||
                  @click="${this.deleteShortLink}"
 | 
					 | 
				
			||||||
                  type="button">
 | 
					 | 
				
			||||||
                  删除短链
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
                <button
 | 
					 | 
				
			||||||
                  class="btn btn-primary join-item"
 | 
					 | 
				
			||||||
                  type="button"
 | 
					 | 
				
			||||||
                  @click="${(e: Event) => {
 | 
					 | 
				
			||||||
                    this.copyToClipboard(
 | 
					 | 
				
			||||||
                      `${window.location.origin}${window.location.pathname}s/${this.shortLinkID}?password=${this.shortLinkPasswd}`,
 | 
					 | 
				
			||||||
                      e.target as HTMLButtonElement
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                  }}">
 | 
					 | 
				
			||||||
                  复制短链
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
          </fieldset>
 | 
					          </fieldset>
 | 
				
			||||||
        </form>
 | 
					        </form>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										180
									
								
								server/frontend/src/components/short-link-input-group.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								server/frontend/src/components/short-link-input-group.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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`<input
 | 
				
			||||||
 | 
					      class="input input-bordered w-1/2 join-item"
 | 
				
			||||||
 | 
					      type="text"
 | 
				
			||||||
 | 
					      placeholder="ID(可选)"
 | 
				
			||||||
 | 
					      .value="${this.id}"
 | 
				
			||||||
 | 
					      @change="${(e: Event) => {
 | 
				
			||||||
 | 
					        this.id = (e.target as HTMLInputElement).value;
 | 
				
			||||||
 | 
					        this.dispatchEvent(
 | 
				
			||||||
 | 
					          new CustomEvent("id-change", {
 | 
				
			||||||
 | 
					            detail: this.id,
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }}" />`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  passwdInputTemplate() {
 | 
				
			||||||
 | 
					    return html`<input
 | 
				
			||||||
 | 
					      class="input input-bordered w-1/2 join-item"
 | 
				
			||||||
 | 
					      type="text"
 | 
				
			||||||
 | 
					      placeholder="密码"
 | 
				
			||||||
 | 
					      .value="${this.passwd}"
 | 
				
			||||||
 | 
					      @change="${(e: Event) => {
 | 
				
			||||||
 | 
					        this.passwd = (e.target as HTMLInputElement).value;
 | 
				
			||||||
 | 
					        this.dispatchEvent(
 | 
				
			||||||
 | 
					          new CustomEvent("passwd-change", {
 | 
				
			||||||
 | 
					            detail: this.passwd,
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }}" />`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  generateBtnTemplate(extraClass: string = "") {
 | 
				
			||||||
 | 
					    return html`<button
 | 
				
			||||||
 | 
					      class="btn btn-primary join-item ${extraClass}"
 | 
				
			||||||
 | 
					      type="button"
 | 
				
			||||||
 | 
					      @click="${(e: Event) => {
 | 
				
			||||||
 | 
					        this.dispatchEvent(
 | 
				
			||||||
 | 
					          new CustomEvent("generate-btn-click", { detail: e })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }}">
 | 
				
			||||||
 | 
					      生成短链
 | 
				
			||||||
 | 
					    </button>`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  updateBtnTemplate(extraClass: string = "") {
 | 
				
			||||||
 | 
					    return html`<button
 | 
				
			||||||
 | 
					      class="btn btn-primary join-item ${extraClass}"
 | 
				
			||||||
 | 
					      @click="${(e: Event) => {
 | 
				
			||||||
 | 
					        this.dispatchEvent(new CustomEvent("update-btn-click", { detail: e }));
 | 
				
			||||||
 | 
					      }}"
 | 
				
			||||||
 | 
					      type="button">
 | 
				
			||||||
 | 
					      更新短链
 | 
				
			||||||
 | 
					    </button>`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  deleteBtnTemplate(extraClass: string = "") {
 | 
				
			||||||
 | 
					    return html`<button
 | 
				
			||||||
 | 
					      class="btn btn-primary join-item ${extraClass}"
 | 
				
			||||||
 | 
					      @click="${(e: Event) => {
 | 
				
			||||||
 | 
					        this.dispatchEvent(new CustomEvent("delete-btn-click", { detail: e }));
 | 
				
			||||||
 | 
					      }}"
 | 
				
			||||||
 | 
					      type="button">
 | 
				
			||||||
 | 
					      删除短链
 | 
				
			||||||
 | 
					    </button>`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  copyBtnTemplate(extraClass: string = "") {
 | 
				
			||||||
 | 
					    return html`<button
 | 
				
			||||||
 | 
					      class="btn btn-primary join-item ${extraClass}"
 | 
				
			||||||
 | 
					      type="button"
 | 
				
			||||||
 | 
					      @click="${(e: Event) => {
 | 
				
			||||||
 | 
					        this.copyToClipboard(
 | 
				
			||||||
 | 
					          `${window.location.origin}${window.location.pathname}s/${this.id}?password=${this.passwd}`,
 | 
				
			||||||
 | 
					          e.target as HTMLButtonElement
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }}">
 | 
				
			||||||
 | 
					      复制短链
 | 
				
			||||||
 | 
					    </button>`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    const sm = html`<div class="form-control mb-2">
 | 
				
			||||||
 | 
					      <div class="join w-full mb-1">
 | 
				
			||||||
 | 
					        ${this.idInputTemplate()} ${this.passwdInputTemplate()}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="join w-full mb-1">
 | 
				
			||||||
 | 
					        ${this.generateBtnTemplate("w-1/2")} ${this.updateBtnTemplate("w-1/2")}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="join w-full">
 | 
				
			||||||
 | 
					        ${this.deleteBtnTemplate("w-1/2")} ${this.copyBtnTemplate("w-1/2")}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const md = html`<div class="form-control mb-2">
 | 
				
			||||||
 | 
					      <div class="join w-full mb-1">
 | 
				
			||||||
 | 
					        ${this.idInputTemplate()} ${this.passwdInputTemplate()}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="join w-full">
 | 
				
			||||||
 | 
					        ${this.generateBtnTemplate("w-1/4")} ${this.updateBtnTemplate("w-1/4")}
 | 
				
			||||||
 | 
					        ${this.deleteBtnTemplate("w-1/4")} ${this.copyBtnTemplate("w-1/4")}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const other = html`<div class="form-control mb-2">
 | 
				
			||||||
 | 
					      <div class="join w-full">
 | 
				
			||||||
 | 
					        ${this.idInputTemplate()} ${this.passwdInputTemplate()}
 | 
				
			||||||
 | 
					        ${this.generateBtnTemplate()} ${this.updateBtnTemplate()}
 | 
				
			||||||
 | 
					        ${this.deleteBtnTemplate()} ${this.copyBtnTemplate()}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (this._screenSizeLevel) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        return sm;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        return md;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        return other;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare global {
 | 
				
			||||||
 | 
					  interface HTMLElementTagNameMap {
 | 
				
			||||||
 | 
					    "short-link-input-group": ShortLinkInputGroup;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user