This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Doric/doric-demo/src/ScrolledSliderDemo.ts

181 lines
5.3 KiB
TypeScript
Raw Normal View History

2020-03-03 13:10:35 +08:00
import { Group, text, gravity, Color, LayoutSpec, vlayout, hlayout, layoutConfig, scroller, Text, ViewHolder, VMPanel, ViewModel, network, loge, HLayout, stack, image, Gravity, takeNonNull, Scroller } from "doric";
2020-03-02 14:33:08 +08:00
import { colors } from "./utils";
interface DoubanModel {
count: number
start: number
total: number
subjects: Array<{
rating: {
max: number,
average: number,
details: {
"1": number,
"2": number,
"3": number,
"4": number,
"5": number,
},
stars: number
min: number,
}
genres: string[],
title: string
casts: Array<{
avatars: {
small: string,
large: string,
medium: string,
},
name_en: string
name: string
alt: string
id: string
}>
durations: string[]
collect_count: number
mainland_pubdate: string
has_video: boolean
original_title: string
subtype: string
directors: Array<{
avatars: {
small: string,
large: string,
medium: string,
},
name_en: string
name: string
alt: string
id: string
}>,
pubdates: string[],
year: string,
images: {
small: string,
large: string,
medium: string,
}
alt: string
id: string
}>
title: string
}
interface MovieModel {
doubanModel?: DoubanModel
2020-03-03 13:10:35 +08:00
selectedIdx: number
2020-03-02 14:33:08 +08:00
}
class MovieVH extends ViewHolder {
title!: Text
gallery!: HLayout
2020-03-03 13:10:35 +08:00
scrolled!: Scroller
movieTitle!: Text
movieYear!: Text
2020-03-02 14:33:08 +08:00
build(root: Group) {
vlayout(
[
this.title = text({
layoutConfig: {
widthSpec: LayoutSpec.MOST,
heightSpec: LayoutSpec.JUST,
},
textSize: 30,
textColor: Color.WHITE,
backgroundColor: colors[1],
textAlignment: gravity().center(),
height: 50,
}),
2020-03-03 13:10:35 +08:00
this.scrolled = scroller(
2020-03-02 14:33:08 +08:00
this.gallery = hlayout(
[],
{
2020-03-03 11:59:27 +08:00
layoutConfig: layoutConfig().fit(),
space: 20,
padding: {
top: 20,
left: 20,
right: 20,
bottom: 20,
2020-03-03 13:10:35 +08:00
},
gravity: Gravity.Center,
2020-03-02 14:33:08 +08:00
}),
{
2020-03-03 11:59:27 +08:00
layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT),
2020-03-02 14:33:08 +08:00
backgroundColor: Color.parse("#eeeeee"),
2020-03-03 13:10:35 +08:00
}),
vlayout(
[
this.movieTitle = text({
textSize: 20,
}),
this.movieYear = text({
textSize: 20,
}),
],
{
layoutConfig: layoutConfig().fit().configWidth(LayoutSpec.MOST),
gravity: Gravity.Center
}),
2020-03-02 14:33:08 +08:00
],
{
layoutConfig: layoutConfig().most(),
space: 50,
}).in(root)
}
}
class MovieVM extends ViewModel<MovieModel, MovieVH>{
onAttached() {
network(context).get("https://douban.uieee.com/v2/movie/top250").then(ret => {
this.updateState(state => state.doubanModel = JSON.parse(ret.data) as DoubanModel)
})
}
onBind(state: MovieModel, vh: MovieVH) {
if (state.doubanModel) {
vh.title.text = state.doubanModel.title
vh.gallery.children.length = 0
2020-03-03 13:10:35 +08:00
state.doubanModel.subjects.slice(0, 5).forEach((e, idx) => {
2020-03-02 14:33:08 +08:00
vh.gallery.addChild(stack(
[
image({
layoutConfig: layoutConfig().just(),
2020-03-03 13:10:35 +08:00
width: 270 / 2 * (idx == state.selectedIdx ? 1.2 : 1),
height: 400 / 2 * (idx == state.selectedIdx ? 1.2 : 1),
imageUrl: e.images.large,
onClick: () => {
this.updateState(state => state.selectedIdx = idx)
vh.scrolled.contentOffset = { x: idx * 200, y: 0 }
2020-03-03 13:10:35 +08:00
},
2020-03-02 14:33:08 +08:00
})
],
{
}))
})
2020-03-03 13:10:35 +08:00
takeNonNull(state.doubanModel.subjects[state.selectedIdx])(it => {
vh.movieTitle.text = it.title
vh.movieYear.text = it.year
})
2020-03-02 14:33:08 +08:00
}
}
}
@Entry
class SliderPanel extends VMPanel<MovieModel, MovieVH>{
getViewModelClass() {
return MovieVM
}
getViewHolderClass() {
return MovieVH
}
getState() {
2020-03-03 13:10:35 +08:00
return { selectedIdx: 0 }
2020-03-02 14:33:08 +08:00
}
}