Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(spx-gui): implement audio preview #908

Merged
merged 3 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion spx-gui/src/components/editor/code-editor/EditorUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,11 @@ export class EditorUI extends Disposable {
.filter((item): item is { type: 'doc'; layer: DocPreview } => item.type === 'doc')
.map((item) => item.layer)

const audioPlayers = result
// add `item is { type: 'audio'; layer: AudioPlayer }` to pass npm script type-check
.filter((item): item is { type: 'audio'; layer: AudioPlayer } => item.type === 'audio')
.map((item) => item.layer)

const attentionHintDecorations = this.attentionHint?.attentionHintDecorations.filter(
(item) => item.range.startLineNumber === position.lineNumber
)
Expand All @@ -498,7 +503,14 @@ export class EditorUI extends Disposable {
endColumn: word.endColumn
})

// todo: when show audio preview, add code `item is { type: 'audio'; layer: AudioPlayer }` to pass npm script type-check
const [audioPlayer] = audioPlayers
if (audioPlayer)
this.hoverPreview?.showAudioPlayer(audioPlayer, {
startLineNumber: position.lineNumber,
startColumn: word.startColumn,
endLineNumber: position.lineNumber,
endColumn: word.endColumn
})

return {
// we only need to know when to trigger hover preview, no need to show raw content
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import type { EditorUI, LayerContent, TextModel } from '@/components/editor/code-editor/EditorUI'
import { DocPreviewLevel, Icon } from '@/components/editor/code-editor/EditorUI'
import {
DocPreviewLevel,
type EditorUI,
Icon,
type LayerContent,
type TextModel
} from '@/components/editor/code-editor/EditorUI'
import { DocAbility } from '@/components/editor/code-editor/document'
import type { Position } from 'monaco-editor'
import type { Definition, TokenUsage } from '@/components/editor/code-editor/compiler'
Expand All @@ -11,6 +16,10 @@
import type { TokenWithDoc, UsageWithDoc } from '@/components/editor/code-editor/tokens/types'
import { usageEffect2Icon } from '@/components/editor/code-editor/coordinators/index'
import type { Project } from '@/models/project'
import type { Sound } from '@/models/sound'
import { useAudioDuration } from '@/utils/audio'
import { untilNotNull } from '@/utils/utils'
import { useFileUrl } from '@/utils/file'

export class HoverProvider {
private ui: EditorUI
Expand Down Expand Up @@ -41,20 +50,27 @@
}
): Promise<LayerContent[]> {
const definition = this.findDefinition(this.currentFilename, ctx.position)
if (!definition) return []
const sound = this.findMediaName(this.currentFilename, ctx.position)
if (!definition && !sound) return []
const layerContents: LayerContent[] = []
if (definition) {
const content = await this.docAbility.getNormalDoc({
pkgPath: definition.pkgPath,
name: definition.name
})

const content = await this.docAbility.getNormalDoc({
pkgPath: definition.pkgPath,
name: definition.name
})
if (this.isDefinitionCanBeRenamed(definition)) {
const [usage] = definition.usages
if (!usage) throw new Error('definition should have at least one usage!')
layerContents.push(this.createVariableRenameContent(usage, definition))
} else {
layerContents.push(...this.createDocContents(content, definition))
}
}

const layerContents: LayerContent[] = []
if (this.isDefinitionCanBeRenamed(definition)) {
const [usage] = definition.usages
if (!usage) throw new Error('definition should have at least one usage!')
layerContents.push(this.createVariableRenameContent(usage, definition))
} else {
layerContents.push(...this.createDocContents(content, definition))
if (sound) {
const [audioSrc] = useFileUrl(() => sound.file)
Copy link
Collaborator

@nighca nighca Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: 这些获取 url、duration 的事情都放在组件里去做可能会更合适一点

放在组件里做的话,自然的结果就是:在获取 url、duration 等待的时候,会展示一个 audio card(里边空白或者放个 loading);放在这里做,自然的结果就是:在等的时候啥都不展示;前者一般会更好一点

以及 useFileUrluseAudioDuration 这些“hook”,与 react hook 类似,预期是放在组件中调用的,放在这里调用容易有内存泄漏的问题

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的我会再把加载逻辑放到组件里面

layerContents.push(await this.createAudioContent(await untilNotNull(audioSrc)))
}

return layerContents
Expand All @@ -79,6 +95,36 @@
})
}

private findMediaName(filename: string, position: Position): Sound | undefined {
const hint = this.coordinatorState.inlayHints.find((inlayHint) => {
if (inlayHint.startPosition.filename !== filename) return false
const tokenLen = inlayHint.endPos - inlayHint.startPos
const line = inlayHint.startPosition.line
const startColumn = inlayHint.startPosition.column
const endColumn = startColumn + tokenLen
return (
position.lineNumber === line &&
position.column >= startColumn &&
position.column <= endColumn &&
inlayHint.name === 'mediaName'
)
})
if (!hint) return
return this.project.sounds.find((sound) => `"${sound.name}"` === hint.value)
}

private async createAudioContent(audioSrc: string): Promise<LayerContent> {
const { duration: _duration } = useAudioDuration(() => audioSrc)
const duration = await untilNotNull(_duration)
return {
type: 'audio',
layer: {
duration,
src: audioSrc
}
}
}

private createVariableRenameContent(usage: TokenUsage, definition: Definition): LayerContent {
// if this is function we need remap declaration
const declarationMap = this.createDefinitionDeclaration(definition.name, [usage])
Expand All @@ -104,9 +150,9 @@
en: 'Please enter a new name'
}),
onSubmit: async (
newName: string,

Check warning on line 153 in spx-gui/src/components/editor/code-editor/coordinators/hoverProvider.ts

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'newName' is defined but never used
ctx: { signal: AbortSignal },

Check warning on line 154 in spx-gui/src/components/editor/code-editor/coordinators/hoverProvider.ts

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'ctx' is defined but never used
setError: (message: string) => void

Check warning on line 155 in spx-gui/src/components/editor/code-editor/coordinators/hoverProvider.ts

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'setError' is defined but never used
) => {
// TODO: Add some logic code
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
type TextModel
} from '@/components/editor/code-editor/EditorUI'
import { Runtime } from '../runtime'
import type { Definition, TokenDetail } from '../compiler'
import type { Definition, TokenDetail, Hint } from '../compiler'
import { Compiler } from '../compiler'
import { ChatBot, Suggest } from '../chat-bot'
import { DocAbility } from '../document'
Expand Down Expand Up @@ -41,6 +41,7 @@

export type CoordinatorState = {
definitions: Definition[]
inlayHints: Hint[]
}

export class Coordinator {
Expand All @@ -51,7 +52,8 @@
compiler: Compiler
public updateDefinition = debounce(this._updateDefinition, 300)
private coordinatorState: CoordinatorState = {
definitions: []
definitions: [],
inlayHints: []
}
private readonly hoverProvider: HoverProvider
private suggest: Suggest
Expand Down Expand Up @@ -245,7 +247,7 @@
)

if (ctx.signal.aborted) return []

this.coordinatorState.inlayHints = inlayHints
return inlayHints.flatMap((inlayHint): InlayHintDecoration[] => {
// from compiler has two type of inlay hint, so here use if else to distinguish
if (inlayHint.type === 'play') {
Expand Down Expand Up @@ -399,7 +401,7 @@
)
}

public jump(position: JumpPosition): void {}

Check warning on line 404 in spx-gui/src/components/editor/code-editor/coordinators/index.ts

View workflow job for this annotation

GitHub Actions / spx-gui-lint

'position' is defined but never used
}

async function toolCategory2InputItemCategory(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ onUnmounted(() => {
</script>

<template>
<!-- eslint-disable vue/no-v-html -->
<!-- this ul element area is sidebar tab nav -->
<ul
class="categories-wrapper skeleton-wrapper"
Expand Down
Loading
Loading