@@ -3,28 +3,60 @@ class ModelDisplayManager {
33 this . modelsList = document . getElementById ( 'modelsList' ) ;
44 }
55
6+ // 处理复制按钮点击
7+ handleCopyClick ( btn , filename ) {
8+ navigator . clipboard . writeText ( filename )
9+ . then ( ( ) => {
10+ // 临时改变按钮样式表示复制成功
11+ const originalHtml = btn . innerHTML ;
12+ btn . innerHTML = '<i class="bi bi-check"></i>' ;
13+ btn . classList . remove ( 'btn-outline-secondary' ) ;
14+ btn . classList . add ( 'btn-success' ) ;
15+
16+ setTimeout ( ( ) => {
17+ btn . innerHTML = originalHtml ;
18+ btn . classList . remove ( 'btn-success' ) ;
19+ btn . classList . add ( 'btn-outline-secondary' ) ;
20+ } , 1000 ) ;
21+ } )
22+ . catch ( err => console . error ( '复制失败:' , err ) ) ;
23+ }
24+
625 // 显示模型列表
726 displayModels ( models ) {
827 this . modelsList . innerHTML = models . map ( model => this . generateModelCard ( model ) ) . join ( '' ) ;
928
10- // 添加点击事件监听
11- this . modelsList . querySelectorAll ( '.model-card' ) . forEach ( card => {
12- card . addEventListener ( 'click' , ( ) => {
29+ // 仅在点击图片时触发模态窗口
30+ this . modelsList . querySelectorAll ( '.model-card img' ) . forEach ( img => {
31+ img . addEventListener ( 'click' , ( event ) => {
32+ const card = event . target . closest ( '.model-card' ) ;
1333 const modelData = JSON . parse ( card . dataset . model ) ;
1434 this . showModelDetail ( modelData ) ;
1535 } ) ;
1636 } ) ;
37+
38+ // 添加复制按钮事件监听
39+ this . modelsList . querySelectorAll ( '.copy-btn' ) . forEach ( btn => {
40+ btn . addEventListener ( 'click' , ( event ) => {
41+ this . handleCopyClick ( btn , btn . dataset . filename ) ;
42+ } ) ;
43+ } ) ;
1744 }
1845
46+
1947 // 生成模型卡片 HTML
2048 generateModelCard ( model ) {
2149 const imgSrc = model . preview_url ?. startsWith ( '/static' ) ?
2250 model . preview_url :
2351 '/static/images/' + model . preview_url ?. split ( '/' ) . pop ( ) ;
52+ // 处理 Windows 和 Unix 风格的路径
53+ const fileName = model . path . replace ( / \\ / g, '/' ) . split ( '/' ) . pop ( ) ;
54+ // 转义 JSON 字符串中的特殊字符
55+ const modelJson = JSON . stringify ( model ) . replace ( / " / g, '"' ) ;
2456
2557 return `
2658 <div class="col">
27- <div class="card h-100 d-flex flex-column model-card" data-model=' ${ JSON . stringify ( model ) } ' >
59+ <div class="card h-100 d-flex flex-column model-card" data-model=" ${ modelJson } " >
2860 <div class="row g-0 h-100">
2961 ${ model . preview_url ? `
3062 <div class="col-4 col-sm-12">
@@ -49,7 +81,21 @@ class ModelDisplayManager {
4981 <small class="d-block">类型: ${ model . type } </small>
5082 <small class="d-block">基础模型: ${ model . baseModel || '未知' } </small>
5183 </p>
52- ${ model . url ? `<a href="${ model . url } " class="btn btn-outline-secondary btn-sm" target="_blank">查看详情</a>` : '' }
84+ <div class="d-flex gap-2">
85+ <button class="btn btn-outline-secondary btn-sm copy-btn"
86+ data-filename="${ fileName } "
87+ title="复制文件名">
88+ <i class="bi bi-files"></i>
89+ </button>
90+ ${ model . url ? `
91+ <a href="${ model . url } "
92+ class="btn btn-outline-secondary btn-sm"
93+ target="_blank"
94+ title="打开 Civitai">
95+ <i class="bi bi-box-arrow-up-right"></i>
96+ </a>
97+ ` : '' }
98+ </div>
5399 </div>
54100 </div>
55101 </div>
@@ -65,6 +111,8 @@ class ModelDisplayManager {
65111 const modalTitle = document . getElementById ( 'modelDetailModalLabel' ) ;
66112 const modalImage = document . getElementById ( 'modelDetailImage' ) ;
67113 const modalInfo = document . getElementById ( 'modelDetailInfo' ) ;
114+ // 处理文件名
115+ const fileName = model . path . replace ( / \\ / g, '/' ) . split ( '/' ) . pop ( ) ;
68116
69117 // 设置标题
70118 modalTitle . textContent = model . name ;
@@ -93,14 +141,29 @@ class ModelDisplayManager {
93141 <p class="mb-2"><strong>类型:</strong> ${ model . type } </p>
94142 <p class="mb-2"><strong>基础模型:</strong> ${ model . baseModel || '未知' } </p>
95143 ${ model . description ? `<p class="mb-2"><strong>描述:</strong> ${ model . description } </p>` : '' }
96- ${ model . url ? `
97- <a href="${ model . url } " class="btn btn-outline-secondary btn-sm mt-2" target="_blank">
98- <i class="bi bi-box-arrow-up-right me-1"></i>查看详情
144+ <div class="d-flex gap-2 mt-2">
145+ <button class="btn btn-outline-secondary btn-sm copy-btn"
146+ data-filename="${ fileName } "
147+ title="复制文件名">
148+ <i class="bi bi-files"></i>
149+ </button>
150+ ${ model . url ? `
151+ <a href="${ model . url } "
152+ class="btn btn-outline-secondary btn-sm"
153+ target="_blank"
154+ title="打开 Civitai">
155+ <i class="bi bi-box-arrow-up-right"></i>
99156 </a>
100- ` : '' }
157+ ` : '' }
158+ </div>
101159 </div>
102160 ` ;
103161
162+ // 添加复制按钮事件监听
163+ modalInfo . querySelector ( '.copy-btn' ) ?. addEventListener ( 'click' , ( event ) => {
164+ this . handleCopyClick ( event . currentTarget , event . currentTarget . dataset . filename ) ;
165+ } ) ;
166+
104167 // 显示模态框
105168 modal . show ( ) ;
106169 }
0 commit comments