11import { computed , defineComponent , ref , watch } from 'vue'
22import { Button , Modal , NumberInput , addToast } from '@munet/ui'
33import { useI18n } from 'vue-i18n'
4+ import { useMagicKeys } from '@vueuse/core'
45import WaveSurfer from 'wavesurfer.js'
56import RegionsPlugin , { type Region } from 'wavesurfer.js/dist/plugins/regions.esm.js'
7+ import ZoomPlugin from 'wavesurfer.js/dist/plugins/zoom.esm.js'
8+ import HoverPlugin from 'wavesurfer.js/dist/plugins/hover.esm.js'
9+ import TimelinePlugin from 'wavesurfer.js/dist/plugins/timeline.esm.js'
610import { getAudioPreview , setAudioPreview , getAudioUrl } from '@/api'
711import { globalCapture } from '@/utils/globalCapture'
812
@@ -26,6 +30,7 @@ export default defineComponent({
2630 let ws : WaveSurfer | undefined
2731 let region : Region | undefined
2832 let updatingFromInput = false
33+ const { ctrl, shift } = useMagicKeys ( )
2934
3035 const playIcon = computed ( ( ) => isPlaying . value ? 'i-mdi-pause' : 'i-mdi-play' )
3136
@@ -83,7 +88,12 @@ export default defineComponent({
8388 waveColor : 'rgb(107,203,152)' ,
8489 progressColor : 'rgb(33,194,118)' ,
8590 url : getAudioUrl ( props . id , props . assetDir ) ,
86- plugins : [ regions ] ,
91+ plugins : [
92+ regions ,
93+ ZoomPlugin . create ( { scale : 0.05 } ) ,
94+ HoverPlugin . create ( { lineColor : 'rgba(89,89,89,0.8)' } ) ,
95+ TimelinePlugin . create ( ) ,
96+ ] ,
8797 } )
8898
8999 ws . on ( 'decode' , dur => {
@@ -101,6 +111,26 @@ export default defineComponent({
101111 dataLoad . value = false
102112 } )
103113
114+ ws . on ( 'click' , progress => {
115+ if ( ! region || ! ws ) return
116+ const time = ws . getDuration ( ) * progress
117+ if ( ctrl . value ) {
118+ if ( time >= region . end ) {
119+ addToast ( { message : t ( 'music.previewStartGtEnd' ) , type : 'error' } )
120+ return
121+ }
122+ region . setOptions ( { start : time } )
123+ syncFromRegion ( )
124+ } else if ( shift . value ) {
125+ if ( time <= region . start ) {
126+ addToast ( { message : t ( 'music.previewEndLtStart' ) , type : 'error' } )
127+ return
128+ }
129+ region . setOptions ( { end : time , start : region . start } )
130+ syncFromRegion ( )
131+ }
132+ } )
133+
104134 regions . on ( 'region-out' , ( ) => {
105135 if ( isPlaySection . value ) region ?. play ( )
106136 } )
@@ -134,7 +164,7 @@ export default defineComponent({
134164 return ( ) => (
135165 < >
136166 < Button class = "ws-nowrap shrink-0" onClick = { ( ) => show . value = true } > { t ( 'music.editPreview' ) } </ Button >
137- < Modal width = "min(90vw,55em )" title = { t ( 'music.editPreview' ) } v-model :show = { show . value } >
167+ < Modal width = "min(60vw,80em )" title = { t ( 'music.editPreview' ) } v-model :show = { show . value } esc = { false } >
138168 { {
139169 default : ( ) => (
140170 < div class = "relative flex flex-col gap-3" >
0 commit comments