Skip to content

Commit 0a3a0e0

Browse files
authored
Merge pull request #1351 from goplus/dev
Release v1.6.2
2 parents 119c090 + 1827669 commit 0a3a0e0

File tree

102 files changed

+2311
-832
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+2311
-832
lines changed

.github/workflows/publish-docker-image.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ on:
33
push:
44
branches:
55
- dev
6-
paths-ignore:
7-
- 'docs/**'
86
jobs:
97
publish-docker-image:
108
runs-on: ubuntu-latest

.github/workflows/validate.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@ on:
44
push:
55
branches:
66
- '**'
7-
paths-ignore:
8-
- 'docs/**'
97
pull_request:
108
branches:
119
- '**'
12-
paths-ignore:
13-
- 'docs/**'
1410

1511
jobs:
1612
spx-gui-lint:

spx-backend/internal/copilot/spx_defs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ onTurning,onTurning info => {},"Listen to current sprite turning (heading change
8181
say,say word,"Make the sprite say some word, e.g., `say ""Hello!""`"
8282
say,"say word, seconds","Make the sprite say some word with duration, e.g., `say ""Hello!"", 2`"
8383
setCostume,setCostume name,"Set the current costume by specifying name, e.g., `setCostume ""happy""`"
84-
setHeading,setHeading direction,"Set heading to given value, e.g., `setHeading Up`"
84+
setHeading,setHeading direction,"Set heading to given value, e.g., `setHeading 90`"
8585
setRotationStyle,setRotationStyle style,"Set the rotation style of the sprite, e.g., `setRotationStyle LeftRight`"
8686
setSize,setSize size,"Set the size of current sprite, e.g., `setSize 2`"
8787
setXYpos,"setXYpos x, y","Set the sprite's position, e.g., `setXYpos 100, 100`"

spx-gui/src/components/asset/animation/CostumeItem.vue

Lines changed: 0 additions & 24 deletions
This file was deleted.

spx-gui/src/components/asset/animation/GroupCostumesModal.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
v-for="costume in props.sprite.costumes"
1818
:key="costume.id"
1919
:costume="costume"
20-
:selected="selectedCostumeSet.has(costume)"
20+
:checked="selectedCostumeSet.has(costume)"
2121
@click="handleCostumeClick(costume)"
2222
/>
2323
</ul>
@@ -54,7 +54,7 @@ import type { Costume } from '@/models/costume'
5454
import type { Sprite } from '@/models/sprite'
5555
import { defaultFps } from '@/models/animation'
5656
import AnimationPlayer from '@/components/editor/sprite/animation/AnimationPlayer.vue'
57-
import CostumeItem from './CostumeItem.vue'
57+
import CostumeItem from '@/components/editor/sprite/CheckableCostumeItem.vue'
5858
5959
const props = defineProps<{
6060
visible: boolean

spx-gui/src/components/asset/library/BackdropItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
:img-src="imgSrc"
44
:img-loading="!imgSrc || imgLoading"
55
:name="asset.displayName"
6-
:selected="selected"
6+
:selectable="{ selected }"
77
/>
88
</template>
99

spx-gui/src/components/asset/library/SoundItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<UISoundItem :selected="selected" :duration="formattedDuration" :name="asset.displayName">
2+
<UISoundItem :selectable="{ selected }" :duration="formattedDuration" :name="asset.displayName">
33
<template #player>
44
<SoundPlayer :src="audioSrc" color="primary" />
55
</template>
Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
<template>
2-
<UISpriteItem :selected="selected" :img-src="imgSrc" :img-loading="!imgSrc || imgLoading" :name="asset.displayName" />
2+
<UISpriteItem ref="wrapperRef" :selectable="{ selected }" :name="asset.displayName">
3+
<template #img="{ style }">
4+
<CostumesAutoPlayer
5+
v-if="animation != null && hovered"
6+
:style="style"
7+
:costumes="animation.costumes"
8+
:duration="animation.duration"
9+
:placeholder-img="imgSrc"
10+
/>
11+
<UIImg v-else :style="style" :src="imgSrc" :loading="imgLoading" />
12+
</template>
13+
</UISpriteItem>
314
</template>
415

516
<script setup lang="ts">
6-
import { UISpriteItem } from '@/components/ui'
17+
import { computed, ref } from 'vue'
18+
import { UIImg, UISpriteItem } from '@/components/ui'
719
import { useFileUrl } from '@/utils/file'
820
import type { AssetData } from '@/apis/asset'
921
import { asset2Sprite } from '@/models/common/asset'
1022
import { useAsyncComputed } from '@/utils/utils'
23+
import { useHovered } from '@/utils/dom'
24+
import CostumesAutoPlayer from '@/components/common/CostumesAutoPlayer.vue'
1125
1226
const props = defineProps<{
1327
asset: AssetData
@@ -16,4 +30,7 @@ const props = defineProps<{
1630
1731
const sprite = useAsyncComputed(() => asset2Sprite(props.asset))
1832
const [imgSrc, imgLoading] = useFileUrl(() => sprite.value?.defaultCostume?.img)
33+
const wrapperRef = ref<InstanceType<typeof UISpriteItem>>()
34+
const hovered = useHovered(() => wrapperRef.value?.$el ?? null)
35+
const animation = computed(() => sprite.value?.getDefaultAnimation() ?? null)
1936
</script>

spx-gui/src/components/asset/preprocessing/CostumeItem.vue

Lines changed: 0 additions & 24 deletions
This file was deleted.

spx-gui/src/components/asset/preprocessing/PreprocessModal.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
v-for="costume in costumes"
5454
:key="costume.id"
5555
:costume="costume"
56-
:selected="isCostumeSelected(costume)"
56+
:checked="isCostumeSelected(costume)"
5757
@click="handleCostumeClick(costume)"
5858
/>
5959
</ul>
@@ -84,7 +84,7 @@ import type { MethodComponent } from './common/types'
8484
import ProcessItem from './common/ProcessItem.vue'
8585
import ImgPreview from './common/ImgPreview.vue'
8686
import ProcessDetail from './common/ProcessDetail.vue'
87-
import CostumeItem from './CostumeItem.vue'
87+
import CostumeItem from '@/components/editor/sprite/CheckableCostumeItem.vue'
8888
import originalThumbnail from './original-thumbnail.svg'
8989
import SplitSpriteSheet from './split-sprite-sheet/SplitSpriteSheet.vue'
9090
import splitSpriteSheetThumbnail from './split-sprite-sheet/thumbnail.svg'

spx-gui/src/components/asset/scratch/BackdropItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<UIBackdropItem :selected="selected" :img-src="imgSrc" :img-loading="!imgSrc" :name="asset.name" />
2+
<UIBackdropItem :selectable="{ selected }" :img-src="imgSrc" :img-loading="!imgSrc" :name="asset.name" />
33
</template>
44

55
<script setup lang="ts">

spx-gui/src/components/asset/scratch/SoundItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<UISoundItem :selected="selected" :duration="formattedDuration" :name="asset.name">
2+
<UISoundItem :selectable="{ selected }" :duration="formattedDuration" :name="asset.name">
33
<template #player>
44
<BlobSoundPlayer :blob="asset.blob" color="primary" />
55
</template>

spx-gui/src/components/asset/scratch/SpriteItem.vue

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
<template>
2-
<UISpriteItem :selected="selected" :img-src="imgSrc" :img-loading="!imgSrc" :name="asset.name" />
2+
<UISpriteItem ref="wrapperRef" :selectable="{ selected }" :name="asset.name">
3+
<template #img="{ style }">
4+
<CostumesAutoPlayer
5+
v-if="animation != null && hovered"
6+
:style="style"
7+
:costumes="animation.costumes"
8+
:duration="animation.duration"
9+
:placeholder-img="imgSrc"
10+
/>
11+
<UIImg v-else :style="style" :src="imgSrc" :loading="imgSrc == null" />
12+
</template>
13+
</UISpriteItem>
314
</template>
415

516
<script setup lang="ts">
6-
import { UISpriteItem } from '@/components/ui'
7-
import type { ExportedScratchSprite } from '@/utils/scratch'
8-
import { ref, watchEffect } from 'vue'
17+
import { computed, ref, watchEffect } from 'vue'
18+
import { UIImg, UISpriteItem } from '@/components/ui'
19+
import { useHovered } from '@/utils/dom'
20+
import type { ExportedScratchFile, ExportedScratchSprite } from '@/utils/scratch'
21+
import { fromBlob } from '@/models/common/file'
22+
import { Costume } from '@/models/costume'
23+
import { defaultFps } from '@/models/animation'
24+
import CostumesAutoPlayer from '@/components/common/CostumesAutoPlayer.vue'
925
1026
const props = defineProps<{
1127
asset: ExportedScratchSprite
@@ -23,4 +39,23 @@ watchEffect((onCleanup) => {
2339
2440
onCleanup(() => URL.revokeObjectURL(url))
2541
})
42+
43+
const wrapperRef = ref<InstanceType<typeof UISpriteItem>>()
44+
const hovered = useHovered(() => wrapperRef.value?.$el ?? null)
45+
46+
function adaptCostume(c: ExportedScratchFile) {
47+
const file = fromBlob(c.name, c.blob)
48+
return new Costume(c.name, file, {
49+
bitmapResolution: c.bitmapResolution
50+
})
51+
}
52+
53+
const animation = computed(() => {
54+
const costumes = props.asset.costumes
55+
if (costumes.length <= 1) return null
56+
return {
57+
costumes: costumes.map(adaptCostume),
58+
duration: costumes.length / defaultFps
59+
}
60+
})
2661
</script>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script setup lang="ts">
2+
import { ref, watchEffect } from 'vue'
3+
import { useMessageHandle } from '@/utils/exception'
4+
import { getCleanupSignal, type OnCleanup } from '@/utils/disposable'
5+
import type { Costume } from '@/models/costume'
6+
import CostumesPlayer from './CostumesPlayer.vue'
7+
8+
const props = defineProps<{
9+
costumes: Costume[]
10+
/** Duration (in seconds) for all costumes to be played once */
11+
duration: number
12+
placeholderImg?: string | null
13+
}>()
14+
15+
const playerRef = ref<InstanceType<typeof CostumesPlayer>>()
16+
17+
const loadAndPlay = useMessageHandle(async (onCleanup: OnCleanup) => {
18+
const player = playerRef.value
19+
if (player == null) return
20+
const signal = getCleanupSignal(onCleanup)
21+
const { costumes, duration } = props
22+
await player.load(costumes, duration, signal)
23+
player.play(signal)
24+
}).fn
25+
26+
watchEffect(loadAndPlay)
27+
</script>
28+
29+
<template>
30+
<CostumesPlayer ref="playerRef" :placeholder-img="placeholderImg" />
31+
</template>

0 commit comments

Comments
 (0)