/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeComponent, CacheStrategy } from '@ohos/libraryimageknife'
import { PageViewModel } from './model/PageViewModel'
class PostData {
avatar: string | Resource = $r('app.media.startIcon')
name: string = ''
message: string = ''
images: string[] = []
}
@Entry
@Component
struct ImageMirrorEnd {
@State isPersonalPageShow: boolean = false
@State selectedIndex: number = 0
@State alphaValue: number = 1
private allPostData: PostData[] = [
{
avatar: PageViewModel.getDataIs()[0],
name: 'Alice',
message: 'sunshine',
images: [PageViewModel.getDataIs()[1], PageViewModel.getDataIs()[1], PageViewModel.getDataIs()[1]]
},
{
avatar: PageViewModel.getDataIs()[2],
name: 'Bob',
message: 'hello',
images: [PageViewModel.getDataIs()[1], PageViewModel.getDataIs()[1]]
},
{
avatar: PageViewModel.getDataIs()[3],
name: 'Carl',
message: 'animal',
images: [PageViewModel.getDataIs()[1]]
}
]
private onAvatarClicked(index: number) {
this.selectedIndex = index
this.getUIContext()?.animateTo({
duration: 350,
curve: Curve.Friction
}, () => {
this.isPersonalPageShow = !this.isPersonalPageShow
})
}
private onPersonalPageBack() {
this.getUIContext()?.animateTo({
duration: 350,
curve: Curve.Friction
}, () => {
this.isPersonalPageShow = !this.isPersonalPageShow
})
}
@Builder
PersonalPageBuilder(index: number) {
Column({ space: 20 }) {
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: PageViewModel.getLongMenus()[0],
placeholderSrc: this.allPostData[index].avatar,
errorholderSrc: $r('app.media.failed'),
border: { radius: 100 },
signature: Date.now() + '',
writeCacheStrategy: CacheStrategy.File
}
})
.size({ width: 200, height: 200 })
.geometryTransition(index.toString())
.clip(true)
.transition(TransitionEffect.opacity(0.99))
Text(this.allPostData[index].name)
.font({ size: 30, weight: 600 })
.transition(TransitionEffect.asymmetric(
TransitionEffect.OPACITY
.combine(TransitionEffect.translate({ y: 100 })),
TransitionEffect.OPACITY.animation({ duration: 0 })
))
Text('Hello:' + this.allPostData[index].message)
.transition(TransitionEffect.asymmetric(
TransitionEffect.OPACITY
.combine(TransitionEffect.translate({ y: 100 })),
TransitionEffect.OPACITY.animation({ duration: 0 })
))
}
.padding({ top: 20 })
.size({ width: '100%', height: '100%' })
.backgroundColor(Color.White)
.onClick(() => {
this.onPersonalPageBack()
})
.transition(TransitionEffect.asymmetric(
TransitionEffect.opacity(0.99),
TransitionEffect.OPACITY
))
}
build() {
Column({ space: 20 }) {
ForEach(this.allPostData, (postData: PostData, index: number) => {
Column() {
Post({
data: postData, index: index, onAvatarClicked: (index: number) => {
this.onAvatarClicked(index)
}
})
}
.width('100%')
}, (PostData: PostData, index: number) => index.toString())
}
.size({ width: '100%', height: '100%' })
.backgroundColor('#40808080')
.bindContentCover(this.isPersonalPageShow,
this.PersonalPageBuilder(this.selectedIndex), { modalTransition: ModalTransition.NONE })
.opacity(this.alphaValue)
}
}
@Component
export struct Post {
@Prop data: PostData
@Prop index: number
@State expandImageSize: number = 100
@State avatarSize: number = 50
private onAvatarClicked: (index: number) => void = (index: number) => {
}
build() {
Column({ space: 20 }) {
Row({ space: 10 }) {
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.data.avatar,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
border: { radius: this.avatarSize / 2 },
writeCacheStrategy: CacheStrategy.File,
pixelName: 'avatar-pixel'
}
})
.size({
width: this.avatarSize, height: this.avatarSize
})
.onClick(() => {
this.onAvatarClicked(this.index)
})
.geometryTransition(this.index.toString(), { follow: true })
.transition(TransitionEffect.OPACITY.animation({ duration: 10, curve: Curve.Friction }))
Text(this.data.name)
}
.justifyContent(FlexAlign.Start)
Text(this.data.message)
Row({ space: 15 }) {
ForEach(this.data.images, (imageResource: string) => {
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: imageResource,
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.failed'),
pixelName: 'item-pixel'
}
})
.size({ width: 100, height: 100 })
}, (imageResource: string, index: number) => index.toString())
}
}
.backgroundColor(Color.White)
.size({ width: '100%', height: 250 })
.alignItems(HorizontalAlign.Start)
.padding({ left: 10, top: 10 })
}
}