125125 </p >
126126
127127 <ul class =" skill-list" >
128- <li v-for =" skill in skills" :key =" skill.id" class =" skill-item" >
128+ <li
129+ v-for =" skill in skills"
130+ :key =" skill.id"
131+ :ref =" (el) => bindSkillItem(skill.id, el)"
132+ class =" skill-item"
133+ :class =" { 'skill-item--focused': focusedSkillId === skill.id }"
134+ >
129135 <div class =" skill-status-ring" :title =" statusLabel(skill)" >
130136 <t-progress
131137 v-if =" isBusy(skill)"
154160 <span v-if =" skill.version" >{{ skill.version }} · </span >
155161 <span >{{ statusLabel(skill) }}</span >
156162 <span v-if =" isBusy(skill)" > · {{ progressOf(skill) }}%</span >
163+ <span v-if =" isBusy(skill) && progressLog(skill)" > · {{ progressLog(skill) }}</span >
157164 </p >
158165 </div >
159166 <div class =" skill-item__actions" >
275282</template >
276283
277284<script setup lang="ts">
278- import { computed , onUnmounted , ref , watch } from ' vue'
285+ import { computed , nextTick , onUnmounted , ref , watch } from ' vue'
279286import { MessagePlugin } from ' tdesign-vue-next'
280287import { useI18n } from ' vue-i18n'
281288import { fetchEventSource } from ' @microsoft/fetch-event-source'
@@ -330,6 +337,9 @@ const deletingId = ref('')
330337const expandedSkillId = ref (' ' )
331338const expandedCopyIds = ref <Set <string >>(new Set ())
332339const transcriptEpoch = ref (0 )
340+ const focusedSkillId = ref (' ' )
341+ const skillItemEls = new Map <string , HTMLElement >()
342+ let focusTimer: number | null = null
333343const fileInputRef = ref <HTMLInputElement | null >(null )
334344const progressById = ref <Record <string , ConfigSkillInstallEvent >>({})
335345
@@ -408,6 +418,26 @@ function hasTranscript(skill: ConfigSkill): boolean {
408418 return Boolean (skill .install_session_id && skill .install_message_id )
409419}
410420
421+ function bindSkillItem(id : string , el : unknown ) {
422+ if (el instanceof HTMLElement ) {
423+ skillItemEls .set (id , el )
424+ return
425+ }
426+ skillItemEls .delete (id )
427+ }
428+
429+ function revealSkill(skillId : string ) {
430+ focusedSkillId .value = skillId
431+ void nextTick (() => {
432+ skillItemEls .get (skillId )?.scrollIntoView ({ behavior: ' smooth' , block: ' center' })
433+ })
434+ if (focusTimer != null ) window .clearTimeout (focusTimer )
435+ focusTimer = window .setTimeout (() => {
436+ if (focusedSkillId .value === skillId ) focusedSkillId .value = ' '
437+ focusTimer = null
438+ }, 2400 )
439+ }
440+
411441function onTranscriptVisible(skill : ConfigSkill , visible : boolean ) {
412442 if (visible ) {
413443 if (expandedSkillId .value !== skill .id ) {
@@ -671,7 +701,10 @@ async function uploadFile(file: File) {
671701 const skillId = res ?.data ?.skill_id
672702 await loadSkills ()
673703 await refreshImage ()
674- if (skillId ) followProgress (skillId )
704+ if (skillId ) {
705+ followProgress (skillId )
706+ revealSkill (skillId )
707+ }
675708 } catch (e : any ) {
676709 MessagePlugin .error (e ?.message || t (' settings.sandbox.skillUploadFailed' ))
677710 } finally {
@@ -698,7 +731,10 @@ async function installFromSource() {
698731 const skillId = res ?.data ?.skill_id
699732 await loadSkills ()
700733 await refreshImage ()
701- if (skillId ) followProgress (skillId )
734+ if (skillId ) {
735+ followProgress (skillId )
736+ revealSkill (skillId )
737+ }
702738 } catch (e : any ) {
703739 MessagePlugin .error (e ?.message || t (' settings.sandbox.skillSourceFailed' ))
704740 } finally {
@@ -773,6 +809,7 @@ watch(
773809onUnmounted (() => {
774810 stopAllFollows ()
775811 stopPoll ()
812+ if (focusTimer != null ) window .clearTimeout (focusTimer )
776813})
777814 </script >
778815
@@ -976,6 +1013,12 @@ onUnmounted(() => {
9761013 border : 1px solid var (--td-component-stroke );
9771014 border-radius : 8px ;
9781015 background : var (--td-bg-color-container );
1016+ transition : border- color 0.2s ease , box- shadow 0.2s ease ;
1017+ }
1018+
1019+ .skill-item--focused {
1020+ border-color : var (--td-brand-color );
1021+ box-shadow : 0 0 0 2px var (--td-brand-color-focus , rgba (0 , 168 , 112 , 0.18 ));
9791022}
9801023
9811024.skill-transcript-toggle--on {
0 commit comments