@@ -3,12 +3,10 @@ import { ChevronDownIcon, ExternalLinkIcon, Trash2Icon } from 'lucide-vue-next'
33import { NButton , NColorPicker , NInput , NInputNumber } from 'naive-ui'
44import { thumbHashToDataURL } from 'thumbhash'
55import { computed , defineComponent , ref } from 'vue'
6- import { toast } from 'vue-sonner'
76import type { Image as ImageModel } from '~/models/base'
87import type { PropType } from 'vue'
98
10- import { getDominantColor , getThumbhash } from '~/utils/image'
11- import { isVideoExt , pickImagesFromMarkdown } from '~/utils/markdown'
9+ import { pickImagesFromMarkdown } from '~/utils/markdown'
1210
1311export const ImageDetailSection = defineComponent ( {
1412 props : {
@@ -30,8 +28,6 @@ export const ImageDetailSection = defineComponent({
3028 } ,
3129 } ,
3230 setup ( props ) {
33- const loading = ref ( false )
34-
3531 const originImageMap = computed ( ( ) => {
3632 const map = new Map < string , ImageModel > ( )
3733 props . images . forEach ( ( image ) => {
@@ -88,103 +84,17 @@ export const ImageDetailSection = defineComponent({
8884
8985 return nextImages
9086 } )
91- const handleCorrectImageDimensions = async ( ) => {
92- loading . value = true
93-
94- const fetchImageTasks = await Promise . allSettled (
95- images . value . map ( ( item ) => {
96- return new Promise < ImageModel > ( ( resolve , reject ) => {
97- const ext = item . src . split ( '.' ) . pop ( ) !
98- const isVideo = isVideoExt ( ext )
99-
100- if ( isVideo ) {
101- const video = document . createElement ( 'video' )
102-
103- video . src = item . src
104-
105- video . addEventListener ( 'loadedmetadata' , ( ) => {
106- resolve ( {
107- height : video . videoHeight ,
108- type : ext ,
109- src : item . src ,
110- width : video . videoWidth ,
111- accent : '#fff' ,
112- } )
113- } )
114-
115- video . addEventListener ( 'error' , ( e ) => {
116- reject ( {
117- err : e ,
118- src : item . src ,
119- } )
120- } )
121- } else {
122- const $image = new Image ( )
123- $image . src = item . src
124- $image . crossOrigin = 'Anonymous'
125- $image . addEventListener ( 'load' , ( ) => {
126- resolve ( {
127- width : $image . naturalWidth ,
128- height : $image . naturalHeight ,
129- src : item . src ,
130- type : ext ,
131- accent : getDominantColor ( $image ) ,
132- thumbhash : getThumbhash ( $image ) ,
133- } )
134- } )
135- $image . onerror = ( err ) => {
136- reject ( {
137- err,
138- src : item . src ,
139- } )
140- }
141- }
142- } )
143- } ) ,
144- )
145-
146- loading . value = false
147-
148- const nextImageDimensions = [ ] as ImageModel [ ]
149- fetchImageTasks . forEach ( ( task , index ) => {
150- if ( task . status === 'fulfilled' ) {
151- nextImageDimensions . push ( task . value )
152- } else {
153- // 保留原始图片信息,避免丢失
154- const originalImage = images . value [ index ]
155- if ( originalImage ) {
156- nextImageDimensions . push ( originalImage )
157- }
158- toast . warning (
159- `获取图片信息失败:${ task . reason . src } : ${ task . reason . err } ` ,
160- )
161- }
162- } )
163-
164- props . onChange ( nextImageDimensions )
165-
166- loading . value = false
167- }
16887
16988 // 展开状态管理
17089 const expandedIndex = ref < number | null > ( null )
17190
17291 return ( ) => (
17392 < div class = "flex w-full flex-col" >
174- { /* 头部操作区 */ }
93+ { /* 头部 */ }
17594 < div class = "flex items-center justify-between gap-3" >
17695 < span class = "text-sm text-neutral-500" >
177- 调整 Markdown 中的图片信息
96+ Markdown 中的图片信息(由服务端自动写入)
17897 </ span >
179- < NButton
180- loading = { loading . value }
181- size = "tiny"
182- onClick = { handleCorrectImageDimensions }
183- type = "primary"
184- tertiary
185- >
186- 自动修正
187- </ NButton >
18898 </ div >
18999
190100 { /* 图片列表 */ }
0 commit comments