|
@@ -1,6 +1,9 @@
|
|
|
import { StrUtil } from '@pura/harmony-utils'
|
|
import { StrUtil } from '@pura/harmony-utils'
|
|
|
import { CommonConstants } from '../common/constants/CommonConstants'
|
|
import { CommonConstants } from '../common/constants/CommonConstants'
|
|
|
|
|
+import { ButtonFancyModifier, ShadowModifier, SymbolGlyphFancyModifier } from '../common/util/AttributeModifierUtil'
|
|
|
import { VideoItem } from '../viewmodel/VideoItem'
|
|
import { VideoItem } from '../viewmodel/VideoItem'
|
|
|
|
|
+import { PlayingIndicator } from './PlayingIndicator'
|
|
|
|
|
+import { PointLightContentButton } from './PointLight/PointLightContentButton'
|
|
|
|
|
|
|
|
function getFindAlbumSongKey(item: VideoItem, index: number): string {
|
|
function getFindAlbumSongKey(item: VideoItem, index: number): string {
|
|
|
if (StrUtil.isNotEmpty(item.filePath)) {
|
|
if (StrUtil.isNotEmpty(item.filePath)) {
|
|
@@ -25,6 +28,8 @@ export struct FindAlbumDetail {
|
|
|
@Prop topSafeHeight: number = 0
|
|
@Prop topSafeHeight: number = 0
|
|
|
@Prop bottomSafeHeight: number = 0
|
|
@Prop bottomSafeHeight: number = 0
|
|
|
@Prop themeColor: string = CommonConstants.DEFAULT_THEME_COLOR
|
|
@Prop themeColor: string = CommonConstants.DEFAULT_THEME_COLOR
|
|
|
|
|
+ @StorageLink('currentSong') currentSong: VideoItem | undefined = undefined
|
|
|
|
|
+ @StorageLink('isPlaying') isPlaying: boolean = false
|
|
|
onPlayAll: () => void = () => {}
|
|
onPlayAll: () => void = () => {}
|
|
|
onRandomPlay: () => void = () => {}
|
|
onRandomPlay: () => void = () => {}
|
|
|
onBack: () => void = () => {}
|
|
onBack: () => void = () => {}
|
|
@@ -45,8 +50,8 @@ export struct FindAlbumDetail {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private getSongSubtitle(item: VideoItem): string {
|
|
private getSongSubtitle(item: VideoItem): string {
|
|
|
- if (StrUtil.isNotEmpty(item.artist) && StrUtil.isNotEmpty(item.fileName) && item.artist !== item.fileName) {
|
|
|
|
|
- return `${item.artist} · ${item.fileName}`
|
|
|
|
|
|
|
+ if (StrUtil.isNotEmpty(item.artist)) {
|
|
|
|
|
+ return `${item.artist} · ${item.duration}`
|
|
|
}
|
|
}
|
|
|
if (StrUtil.isNotEmpty(item.artist)) {
|
|
if (StrUtil.isNotEmpty(item.artist)) {
|
|
|
return item.artist as string
|
|
return item.artist as string
|
|
@@ -54,9 +59,6 @@ export struct FindAlbumDetail {
|
|
|
if (StrUtil.isNotEmpty(item.fileName)) {
|
|
if (StrUtil.isNotEmpty(item.fileName)) {
|
|
|
return item.fileName as string
|
|
return item.fileName as string
|
|
|
}
|
|
}
|
|
|
- if (StrUtil.isNotEmpty(item.album)) {
|
|
|
|
|
- return item.album as string
|
|
|
|
|
- }
|
|
|
|
|
return '本地音乐'
|
|
return '本地音乐'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -87,33 +89,6 @@ export struct FindAlbumDetail {
|
|
|
return '未知歌手'
|
|
return '未知歌手'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private getAlbumSourceText(): string {
|
|
|
|
|
- if (StrUtil.isNotEmpty(this.albumSourceLabel)) {
|
|
|
|
|
- return this.albumSourceLabel
|
|
|
|
|
- }
|
|
|
|
|
- return '专辑'
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private getSongIndexText(item: VideoItem, index: number): string {
|
|
|
|
|
- if (StrUtil.isNotEmpty(item.track)) {
|
|
|
|
|
- const parsed = Number.parseInt(item.track as string, 10)
|
|
|
|
|
- if (!Number.isNaN(parsed) && parsed > 0) {
|
|
|
|
|
- return String(parsed)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return String(index + 1)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Builder
|
|
|
|
|
- private buildSourceTag(text: string, isStrong: boolean = false) {
|
|
|
|
|
- Text(text)
|
|
|
|
|
- .fontSize(11)
|
|
|
|
|
- .fontWeight(isStrong ? FontWeight.Medium : FontWeight.Regular)
|
|
|
|
|
- .fontColor(isStrong ? $r('app.color.white') : this.getPrimaryTextColor())
|
|
|
|
|
- .padding({ left: 10, right: 10, top: 6, bottom: 6 })
|
|
|
|
|
- .backgroundColor(isStrong ? this.getThemeAccent() : '#F1EDF7')
|
|
|
|
|
- .borderRadius(999)
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
@Builder
|
|
@Builder
|
|
|
private buildHeroTag(text: string) {
|
|
private buildHeroTag(text: string) {
|
|
@@ -127,187 +102,144 @@ export struct FindAlbumDetail {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Builder
|
|
@Builder
|
|
|
- private buildHeaderActions() {
|
|
|
|
|
- Row({ space: 12 }) {
|
|
|
|
|
- Button({ type: ButtonType.Capsule, stateEffect: false }) {
|
|
|
|
|
- Row({ space: 8 }) {
|
|
|
|
|
- SymbolGlyph($r('sys.symbol.play_fill'))
|
|
|
|
|
- .fontSize(18)
|
|
|
|
|
- .fontColor([this.getThemeAccent()])
|
|
|
|
|
- .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
|
|
|
|
|
|
|
+ private buildPlayAllActionContent() {
|
|
|
|
|
+ Row({ space: 8 }) {
|
|
|
|
|
+ SymbolGlyph($r('sys.symbol.play_fill'))
|
|
|
|
|
+ .fontSize(18)
|
|
|
|
|
+ .fontColor([this.getThemeAccent()])
|
|
|
|
|
+ .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
|
|
|
|
|
|
|
|
- Text('播放全部')
|
|
|
|
|
- .fontSize(14)
|
|
|
|
|
- .fontWeight(FontWeight.Medium)
|
|
|
|
|
- .fontColor(this.getPrimaryTextColor())
|
|
|
|
|
- .maxLines(1)
|
|
|
|
|
|
|
+ Text('播放全部')
|
|
|
|
|
+ .fontSize(14)
|
|
|
|
|
+ .fontWeight(FontWeight.Medium)
|
|
|
|
|
+ .fontColor(this.getPrimaryTextColor())
|
|
|
|
|
+ .maxLines(1)
|
|
|
|
|
+ }
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ .height(48)
|
|
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
|
|
+ .alignItems(VerticalAlign.Center)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Builder
|
|
|
|
|
+ private buildRandomActionContent() {
|
|
|
|
|
+ Row({ space: 8 }) {
|
|
|
|
|
+ SymbolGlyph($r('sys.symbol.shuffle'))
|
|
|
|
|
+ .fontSize(18)
|
|
|
|
|
+ .fontColor([Color.White])
|
|
|
|
|
+ .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
|
|
|
|
|
+
|
|
|
|
|
+ Text('随机播放')
|
|
|
|
|
+ .fontSize(14)
|
|
|
|
|
+ .fontWeight(FontWeight.Medium)
|
|
|
|
|
+ .fontColor('#FFFFFFFF')
|
|
|
|
|
+ .maxLines(1)
|
|
|
|
|
+ }
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ .height(48)
|
|
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
|
|
+ .alignItems(VerticalAlign.Center)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ @Builder
|
|
|
|
|
+ private buildHeaderActions() {
|
|
|
|
|
+ Row({ space: 10 }) {
|
|
|
|
|
+ PointLightContentButton({
|
|
|
|
|
+ pointColor: this.getThemeAccent(),
|
|
|
|
|
+ buttonColor: '#1FFFFFFF',
|
|
|
|
|
+ buttonRadius: 20,
|
|
|
|
|
+ pointLightHeight: 48,
|
|
|
|
|
+ useShadow: true,
|
|
|
|
|
+ builder: () => {
|
|
|
|
|
+ this.buildPlayAllActionContent()
|
|
|
}
|
|
}
|
|
|
- .width('100%')
|
|
|
|
|
- .justifyContent(FlexAlign.Center)
|
|
|
|
|
- .alignItems(VerticalAlign.Center)
|
|
|
|
|
- }
|
|
|
|
|
- .layoutWeight(1)
|
|
|
|
|
- .height(44)
|
|
|
|
|
- .backgroundColor('#FFFFFFFF')
|
|
|
|
|
- .borderRadius(22)
|
|
|
|
|
- .border({ width: 1, color: '#10FFFFFF', radius: 22 })
|
|
|
|
|
- .shadow({ radius: 14, color: '#22000000', offsetY: 8 })
|
|
|
|
|
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.97 })
|
|
|
|
|
|
|
+ })
|
|
|
|
|
+ .width(132)
|
|
|
|
|
+ .height(48)
|
|
|
|
|
+ .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.9 })
|
|
|
|
|
+ .border({ width: 1, color: '#10FFFFFF', radius: 20 })
|
|
|
.onClick(() => {
|
|
.onClick(() => {
|
|
|
this.onPlayAll()
|
|
this.onPlayAll()
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- Button({ type: ButtonType.Capsule, stateEffect: false }) {
|
|
|
|
|
- Row({ space: 8 }) {
|
|
|
|
|
- SymbolGlyph($r('sys.symbol.arrow_clockwise'))
|
|
|
|
|
- .fontSize(18)
|
|
|
|
|
- .fontColor([Color.White])
|
|
|
|
|
- .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
|
|
|
|
|
-
|
|
|
|
|
- Text('随机播放')
|
|
|
|
|
- .fontSize(14)
|
|
|
|
|
- .fontWeight(FontWeight.Medium)
|
|
|
|
|
- .fontColor('#FFFFFFFF')
|
|
|
|
|
- .maxLines(1)
|
|
|
|
|
|
|
+ PointLightContentButton({
|
|
|
|
|
+ pointColor: Color.White,
|
|
|
|
|
+ buttonColor: '#1FFFFFFF',
|
|
|
|
|
+ buttonRadius: 20,
|
|
|
|
|
+ pointLightHeight: 48,
|
|
|
|
|
+ useShadow: true,
|
|
|
|
|
+ builder: () => {
|
|
|
|
|
+ this.buildRandomActionContent()
|
|
|
}
|
|
}
|
|
|
- .width('100%')
|
|
|
|
|
- .justifyContent(FlexAlign.Center)
|
|
|
|
|
- .alignItems(VerticalAlign.Center)
|
|
|
|
|
- }
|
|
|
|
|
- .layoutWeight(1)
|
|
|
|
|
- .height(44)
|
|
|
|
|
- .backgroundColor('#1FFFFFFF')
|
|
|
|
|
- .borderRadius(22)
|
|
|
|
|
- .border({ width: 1, color: '#30FFFFFF', radius: 22 })
|
|
|
|
|
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.97 })
|
|
|
|
|
|
|
+ })
|
|
|
|
|
+ .width(132)
|
|
|
|
|
+ .height(48).clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.96 })
|
|
|
|
|
+ .border({ width: 1, color: '#30FFFFFF', radius: 20 })
|
|
|
.onClick(() => {
|
|
.onClick(() => {
|
|
|
this.onRandomPlay()
|
|
this.onRandomPlay()
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Builder
|
|
@Builder
|
|
|
private buildHeroHeader() {
|
|
private buildHeroHeader() {
|
|
|
- Stack({ alignContent: Alignment.TopStart }) {
|
|
|
|
|
|
|
+ Stack({ alignContent: Alignment.BottomEnd }) {
|
|
|
Image(this.getAlbumCover())
|
|
Image(this.getAlbumCover())
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
- .height(410)
|
|
|
|
|
|
|
+ .height(320)
|
|
|
.objectFit(ImageFit.Cover)
|
|
.objectFit(ImageFit.Cover)
|
|
|
|
|
+ .opacity(0.7)
|
|
|
|
|
|
|
|
Column() {
|
|
Column() {
|
|
|
- Blank()
|
|
|
|
|
- }
|
|
|
|
|
- .width('100%')
|
|
|
|
|
- .height(410)
|
|
|
|
|
- .linearGradient({
|
|
|
|
|
- direction: GradientDirection.Bottom,
|
|
|
|
|
- colors: [['#05070D12', 0], ['#0A0E1F66', 0.4], ['#11141FE8', 1]]
|
|
|
|
|
- })
|
|
|
|
|
- .opacity(1)
|
|
|
|
|
|
|
|
|
|
- Column() {
|
|
|
|
|
- Row() {
|
|
|
|
|
- Button({ type: ButtonType.Circle, stateEffect: false }) {
|
|
|
|
|
- SymbolGlyph($r('sys.symbol.chevron_left'))
|
|
|
|
|
- .fontSize(20)
|
|
|
|
|
- .fontColor([Color.White])
|
|
|
|
|
- }
|
|
|
|
|
- .width(40)
|
|
|
|
|
- .height(40)
|
|
|
|
|
- .backgroundColor('#24000000')
|
|
|
|
|
- .border({ width: 1, color: '#26FFFFFF', radius: 20 })
|
|
|
|
|
- .shadow(ShadowStyle.OUTER_DEFAULT_XS)
|
|
|
|
|
- .onClick(() => {
|
|
|
|
|
- this.onBack()
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- Blank()
|
|
|
|
|
- }
|
|
|
|
|
- .width('100%')
|
|
|
|
|
- .alignItems(VerticalAlign.Center)
|
|
|
|
|
|
|
+ Column({ space: 14 }) {
|
|
|
|
|
+ Text(this.albumTitle)
|
|
|
|
|
+ .fontSize(26)
|
|
|
|
|
+ .fontWeight(FontWeight.Bold)
|
|
|
|
|
+ .textAlign(TextAlign.Center)
|
|
|
|
|
+ .fontColor('#FFFFFFFF')
|
|
|
|
|
+ .maxLines(2)
|
|
|
|
|
+ .textOverflow({ overflow: TextOverflow.Ellipsis })
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
|
|
|
- Blank()
|
|
|
|
|
|
|
+ Text(this.getAlbumArtistText())
|
|
|
|
|
+ .fontSize(18)
|
|
|
|
|
+ .lineHeight(21)
|
|
|
|
|
+ .textAlign(TextAlign.Center)
|
|
|
|
|
+ .fontWeight(FontWeight.Bold)
|
|
|
|
|
+ .fontColor('#D8FFFFFF')
|
|
|
|
|
+ .maxLines(1)
|
|
|
|
|
+ .textOverflow({ overflow: TextOverflow.Ellipsis })
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
|
|
|
- Column({ space: 14 }) {
|
|
|
|
|
- Column({ space: 8 }) {
|
|
|
|
|
- Row({ space: 8 }) {
|
|
|
|
|
- this.buildHeroTag(this.getAlbumSourceText())
|
|
|
|
|
- this.buildHeroTag(this.songs.length + ' 首歌曲')
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Text(this.albumTitle)
|
|
|
|
|
- .fontSize(26)
|
|
|
|
|
- .fontWeight(FontWeight.Bold)
|
|
|
|
|
- .textAlign(TextAlign.Start)
|
|
|
|
|
- .fontColor('#FFFFFFFF')
|
|
|
|
|
- .maxLines(2)
|
|
|
|
|
- .textOverflow({ overflow: TextOverflow.Ellipsis })
|
|
|
|
|
- .width('100%')
|
|
|
|
|
-
|
|
|
|
|
- Text(this.getAlbumArtistText())
|
|
|
|
|
- .fontSize(15)
|
|
|
|
|
- .lineHeight(21)
|
|
|
|
|
- .textAlign(TextAlign.Start)
|
|
|
|
|
- .fontColor('#D8FFFFFF')
|
|
|
|
|
- .maxLines(1)
|
|
|
|
|
- .textOverflow({ overflow: TextOverflow.Ellipsis })
|
|
|
|
|
- .width('100%')
|
|
|
|
|
- }
|
|
|
|
|
- .width('100%')
|
|
|
|
|
- .alignItems(HorizontalAlign.Start)
|
|
|
|
|
|
|
+ this.buildHeroTag(this.songs.length + ' 首歌曲')
|
|
|
|
|
|
|
|
this.buildHeaderActions()
|
|
this.buildHeaderActions()
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
- .alignItems(HorizontalAlign.Start)
|
|
|
|
|
|
|
+ .alignItems(HorizontalAlign.Center)
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
- .height(410)
|
|
|
|
|
|
|
+ .height(320)
|
|
|
.padding({ left: 18, right: 18, top: this.topSafeHeight + 8, bottom: 26 })
|
|
.padding({ left: 18, right: 18, top: this.topSafeHeight + 8, bottom: 26 })
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
- .height(410)
|
|
|
|
|
|
|
+ .height(320)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Builder
|
|
|
|
|
- private buildSongSectionHeader() {
|
|
|
|
|
- Row() {
|
|
|
|
|
- Text('曲目列表')
|
|
|
|
|
- .fontSize(18)
|
|
|
|
|
- .fontWeight(FontWeight.Bold)
|
|
|
|
|
- .fontColor(this.getPrimaryTextColor())
|
|
|
|
|
|
|
|
|
|
- Blank()
|
|
|
|
|
-
|
|
|
|
|
- this.buildSourceTag(this.songs.length + ' 首')
|
|
|
|
|
- }
|
|
|
|
|
- .width('100%')
|
|
|
|
|
- .padding({ left: 16, right: 16, top: 2, bottom: 4 })
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
@Builder
|
|
@Builder
|
|
|
- private buildSongCard(item: VideoItem, index: number) {
|
|
|
|
|
|
|
+ private buildSongCard(item: VideoItem) {
|
|
|
Row({ space: 12 }) {
|
|
Row({ space: 12 }) {
|
|
|
- Stack({ alignContent: Alignment.Center }) {
|
|
|
|
|
- Column() {
|
|
|
|
|
- Blank()
|
|
|
|
|
- }
|
|
|
|
|
- .width(34)
|
|
|
|
|
- .height(34)
|
|
|
|
|
- .backgroundColor('#F1ECF8')
|
|
|
|
|
- .borderRadius(17)
|
|
|
|
|
-
|
|
|
|
|
- Text(this.getSongIndexText(item, index))
|
|
|
|
|
- .fontSize(12)
|
|
|
|
|
- .fontWeight(FontWeight.Medium)
|
|
|
|
|
- .fontColor(this.getThemeAccent())
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
Image(this.getSongCover(item))
|
|
Image(this.getSongCover(item))
|
|
|
- .width(58)
|
|
|
|
|
- .height(58)
|
|
|
|
|
- .borderRadius(18)
|
|
|
|
|
|
|
+ .width(52)
|
|
|
|
|
+ .height(52)
|
|
|
|
|
+ .borderRadius(8)
|
|
|
.objectFit(ImageFit.Cover)
|
|
.objectFit(ImageFit.Cover)
|
|
|
|
|
|
|
|
Column({ space: 6 }) {
|
|
Column({ space: 6 }) {
|
|
@@ -320,7 +252,7 @@ export struct FindAlbumDetail {
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
|
|
|
|
|
Text(this.getSongSubtitle(item))
|
|
Text(this.getSongSubtitle(item))
|
|
|
- .fontSize(12)
|
|
|
|
|
|
|
+ .fontSize(13)
|
|
|
.lineHeight(17)
|
|
.lineHeight(17)
|
|
|
.fontColor(this.getSecondaryTextColor())
|
|
.fontColor(this.getSecondaryTextColor())
|
|
|
.maxLines(1)
|
|
.maxLines(1)
|
|
@@ -331,27 +263,19 @@ export struct FindAlbumDetail {
|
|
|
.alignItems(HorizontalAlign.Start)
|
|
.alignItems(HorizontalAlign.Start)
|
|
|
|
|
|
|
|
Column({ space: 8 }) {
|
|
Column({ space: 8 }) {
|
|
|
- Text(item.duration ? item.duration : '--:--')
|
|
|
|
|
- .fontSize(11)
|
|
|
|
|
- .fontColor(this.getSecondaryTextColor())
|
|
|
|
|
-
|
|
|
|
|
- SymbolGlyph($r('sys.symbol.play_fill'))
|
|
|
|
|
- .fontSize(13)
|
|
|
|
|
- .fontColor([this.getThemeAccent()])
|
|
|
|
|
- .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
|
|
|
|
|
|
|
+ PlayingIndicator({
|
|
|
|
|
+ isActive: this.isPlaying && this.currentSong?.filePath === item.filePath,
|
|
|
|
|
+ indicatorSize: 18,
|
|
|
|
|
+ marginRight: 20,
|
|
|
|
|
+ marginTop: 8,
|
|
|
|
|
+ marginBottom: 8
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
.alignItems(HorizontalAlign.End)
|
|
.alignItems(HorizontalAlign.End)
|
|
|
}
|
|
}
|
|
|
.width('100%')
|
|
.width('100%')
|
|
|
.padding({ left: 14, right: 14, top: 14, bottom: 14 })
|
|
.padding({ left: 14, right: 14, top: 14, bottom: 14 })
|
|
|
.backgroundColor('#FBFAFD')
|
|
.backgroundColor('#FBFAFD')
|
|
|
- .borderRadius(24)
|
|
|
|
|
- .border({ width: 1, color: '#0F000000', radius: 24 })
|
|
|
|
|
- .shadow({ radius: 12, color: '#12000000', offsetY: 6 })
|
|
|
|
|
- .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.985 })
|
|
|
|
|
- .onClick(() => {
|
|
|
|
|
- this.onSongTap(index)
|
|
|
|
|
- })
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Builder
|
|
@Builder
|
|
@@ -380,29 +304,84 @@ export struct FindAlbumDetail {
|
|
|
.justifyContent(FlexAlign.Center)
|
|
.justifyContent(FlexAlign.Center)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
build() {
|
|
build() {
|
|
|
|
|
+ Stack() {
|
|
|
|
|
+
|
|
|
|
|
+ this.buildContentView();
|
|
|
|
|
+
|
|
|
|
|
+ // 顶部区域:标题栏在上,面包屑在下
|
|
|
|
|
+ Column() {
|
|
|
|
|
+ this.topTitleBar()
|
|
|
|
|
+ }
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ .animation({
|
|
|
|
|
+ duration: 500,
|
|
|
|
|
+ curve: Curve.Friction // 可选动画曲线
|
|
|
|
|
+ })
|
|
|
|
|
+ .position({ top: 0, left: 0 })
|
|
|
|
|
+ // .backgroundColor($r('app.color.start_window_background'))
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ .height('100%')
|
|
|
|
|
+ .alignContent(Alignment.Bottom)
|
|
|
|
|
+ .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Builder
|
|
|
|
|
+ private topTitleBar() {
|
|
|
|
|
+ Column() {
|
|
|
|
|
+ Row({ space: 12 }) {
|
|
|
|
|
+ Button({ type: ButtonType.Circle, stateEffect: true }) {
|
|
|
|
|
+ SymbolGlyph($r('sys.symbol.chevron_left'))
|
|
|
|
|
+ .attributeModifier(new SymbolGlyphFancyModifier(24, '', ''))
|
|
|
|
|
+ }
|
|
|
|
|
+ .attributeModifier(new ButtonFancyModifier(40, 40))
|
|
|
|
|
+ .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
|
|
|
|
|
+ .animation({ duration: 300, curve: Curve.Ease })
|
|
|
|
|
+ .onClick(() => {
|
|
|
|
|
+ this.onBack()
|
|
|
|
|
+ })
|
|
|
|
|
+ .attributeModifier(new ShadowModifier())
|
|
|
|
|
+ .zIndex(0)
|
|
|
|
|
+ }
|
|
|
|
|
+ .padding({ top: this.topSafeHeight + 10, left: 10, right: 10, bottom: 6 })
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ .backgroundColor(Color.Transparent)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Builder
|
|
|
|
|
+ buildContentView() {
|
|
|
List({ space: 12 }) {
|
|
List({ space: 12 }) {
|
|
|
ListItem() {
|
|
ListItem() {
|
|
|
this.buildHeroHeader()
|
|
this.buildHeroHeader()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (this.songs.length === 0) {
|
|
if (this.songs.length === 0) {
|
|
|
- ListItem() {
|
|
|
|
|
- this.buildSongSectionHeader()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
ListItem() {
|
|
ListItem() {
|
|
|
this.buildEmptyState()
|
|
this.buildEmptyState()
|
|
|
}
|
|
}
|
|
|
.padding({ left: 16, right: 16 })
|
|
.padding({ left: 16, right: 16 })
|
|
|
} else {
|
|
} else {
|
|
|
- ListItem() {
|
|
|
|
|
- this.buildSongSectionHeader()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
ForEach(this.songs, (item: VideoItem, index: number) => {
|
|
ForEach(this.songs, (item: VideoItem, index: number) => {
|
|
|
ListItem() {
|
|
ListItem() {
|
|
|
- this.buildSongCard(item, index)
|
|
|
|
|
|
|
+ PointLightContentButton({
|
|
|
|
|
+ pointColor: this.getThemeAccent(),
|
|
|
|
|
+ buttonColor: '#00FFFFFF',
|
|
|
|
|
+ buttonRadius: 15,
|
|
|
|
|
+ pointLightHeight: 132,
|
|
|
|
|
+ useShadow: true,
|
|
|
|
|
+ builder: () => {
|
|
|
|
|
+ this.buildSongCard(item)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ .onClick(() => {
|
|
|
|
|
+ this.onSongTap(index)
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
.padding({ left: 16, right: 16 })
|
|
.padding({ left: 16, right: 16 })
|
|
|
}, getFindAlbumSongKey)
|
|
}, getFindAlbumSongKey)
|
|
@@ -412,7 +391,7 @@ export struct FindAlbumDetail {
|
|
|
.height('100%')
|
|
.height('100%')
|
|
|
.scrollBar(BarState.Off)
|
|
.scrollBar(BarState.Off)
|
|
|
.edgeEffect(EdgeEffect.Spring)
|
|
.edgeEffect(EdgeEffect.Spring)
|
|
|
- .backgroundColor('#F7F5FB')
|
|
|
|
|
- .padding({ bottom: this.bottomSafeHeight + 18 })
|
|
|
|
|
|
|
+ .backgroundColor($r('app.color.start_window_background'))
|
|
|
|
|
+ .padding({ bottom: this.bottomSafeHeight + 75 })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|