Skip to content

Commit

Permalink
Refactor tag dialog by pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
apqx committed Jan 6, 2025
1 parent fd22e61 commit 9aa71c6
Show file tree
Hide file tree
Showing 15 changed files with 253 additions and 379 deletions.
6 changes: 3 additions & 3 deletions _posts/opera/2022-09-25-昆曲「西厢记」四折.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ actor: 施洋 方莛玉 罗轩
mention: 王翼骅 李琼瑶
date: 2022-09-25 +0800
location: 杭州大剧院·可变剧场
description: 同一个剧团,同一台戏,感觉上,阿逍的红娘是很小只的灵动可爱,而施洋则是另一种风格,戏曲演员中少见的纤细高挑,真的很搭一个「洋」字💃🏻。
description: 同一个剧团,同一台戏,感觉上,阿逍的红娘是很小只的灵动可爱,而施洋则是另一种风格,戏曲演员中少见的纤细高挑,很搭一个「洋」字💃🏻。
cover: https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20220925/xixiangji/DSC03690_thumb.jpg
cover-alt: 昆曲 西厢记 跳墙着棋 施洋 方莛玉 罗轩
tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 西厢记 寄柬 跳墙着棋 佳期 拷红 施洋 方莛玉 罗轩 王翼骅 李琼瑶 杭州大剧院·可变剧场
Expand All @@ -25,13 +25,13 @@ tags: 看剧 摄影 戏剧 杭州 昆曲 浙昆 西厢记 寄柬 跳墙着棋

**拷红**`莺莺``红娘`撮合下,夜奔西厢探慰`张生`,事后被`老夫人`发觉,拷问`红娘``红娘`据实以告、以理服人,最后`老夫人`迫不得已,见木已成舟,只好将`莺莺`许配给`张生`

同一个剧团,同一台戏,感觉上,[阿逍的红娘]({% link _posts/opera/2022-08-21-昆曲「西厢记·跳墙着棋」折子.md %}){: target="_blank" }是很小只的灵动可爱,而施洋则是另一种风格,戏曲演员中少见的纤细高挑,真的很搭一个「洋」字💃🏻。
同一个剧团,同一台戏,感觉上,[阿逍的红娘]({% link _posts/opera/2022-08-21-昆曲「西厢记·跳墙着棋」折子.md %}){: target="_blank" }是很小只的灵动可爱,而施洋则是另一种风格,戏曲演员中少见的纤细高挑,很搭一个「洋」字💃🏻。

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20220925/xixiangji/zhangtangxiao_shiyang_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="红娘 张唐逍 施洋" }

这应该是他/她们仨第一次演完整的《西厢记》,而且是在近距离的小剧场。开始前我竖着耳朵隐约“偷听”到好像他/她们老师也来看了(小声说:其实还偷听到了另一些有趣的事🙃),就坐我前面,我不知道她会如何评价,但从一个普通的台下观众的视角,我看到的是一场精彩的演出,收获的是一个开心的周末,真不错。

*偷听.jpg 👀*
*偷听.jpg👀*

![](https://apqx.oss-cn-hangzhou.aliyuncs.com/blog/opera/20220925/xixiangji/IMG_2811_thumb.jpg){: loading="lazy" class="clickable clickShowOriginalImg operaCopyright" alt="张唐逍" }

Expand Down
11 changes: 11 additions & 0 deletions api/paginate/tags/看剧&上海.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
layout: paginate-posts-json
sitemap: false
permalink: /api/paginate/tags/看剧&上海
pagination:
permalink: ""
enabled: true
tag: "看剧,上海"
extension: .json
indexpage: 'page-:num'
---
11 changes: 11 additions & 0 deletions api/paginate/tags/看剧&南京.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
layout: paginate-posts-json
sitemap: false
permalink: /api/paginate/tags/看剧&南京
pagination:
permalink: ""
enabled: true
tag: "看剧,南京"
extension: .json
indexpage: 'page-:num'
---
11 changes: 11 additions & 0 deletions api/paginate/tags/看剧&杭州.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
layout: paginate-posts-json
sitemap: false
permalink: /api/paginate/tags/看剧&杭州
pagination:
permalink: ""
enabled: true
tag: "看剧,杭州"
extension: .json
indexpage: 'page-:num'
---
2 changes: 1 addition & 1 deletion npm/dist/blog-index-v2.0.0.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions npm/dist/blog-scaffold-v2.0.0.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion npm/src/component/dialog/SearchDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class SearchDialog extends BasicDialog<BasicDialogProps, SearchDialogStat
onDialogClose(): void {
super.onDialogClose()
this.presenter.abortSearch()
this.presenter.reduceResult()
// this.presenter.reduceResult()
}

componentDidMount(): void {
Expand Down
154 changes: 107 additions & 47 deletions npm/src/component/dialog/TagDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,57 @@ import { MDCList } from "@material/list"
import { MDCRipple } from "@material/ripple"
import { BasicDialog, BasicDialogProps, TAG_DIALOG_WRAPPER_ID, showDialog } from "./BasicDialog"
import { consoleDebug } from "../../util/log"
import { TagDialogPresenter } from "./TagDialogPresenter"
import ReactDOM from "react-dom"
import { initListItem } from "../list"
import { ERROR_HINT, LoadingHint } from "../react/LoadingHint"
import { HeightAnimationContainer } from "../animation/HeightAnimationContainer"
import { BasePostPaginateShow, BasePostPaginateShowProps, BasePostPaginateShowState, Post } from "../react/post/BasePostPaginateShow"
import { IPostPaginateShowPresenter } from "../react/post/IPostPaginateShowPresenter"
import { PostPaginateShowPresenter } from "../react/post/PostPaginateShowPresenter"
import { getSectionTypeByPath, SECTION_TYPE_OPERA, SECTION_TYPE_ORIGINAL, SectionType } from "../../base/constant"
// import "./TagEssayListDialog.scss"

interface DialogContentProps extends BasicDialogProps {
tag: string,
}

interface DialogContentState {
loading: boolean,
resultSize: number,
postList: PostItemData[]
loadHint: string
dialogOpened: boolean,
loadMoreId: number,
}

export class TagDialog extends BasicDialog<DialogContentProps, DialogContentState> {
presenter: TagDialogPresenter = null
heightAnimationContainer: HeightAnimationContainer = null

constructor(props) {
super(props)
consoleDebug("TagDialogContent constructor")
this.onClickLoadMore = this.onClickLoadMore.bind(this)
this.onListSizeChanged = this.onListSizeChanged.bind(this)
// this.scrollToTopOnDialogOpen = false
this.listenScroll = true
this.presenter = new TagDialogPresenter(this)
this.state = {
loading: true,
resultSize: 0,
postList: [],
loadHint: null
dialogOpened: false,
loadMoreId: 0,
}
}

onDialogOpen() {
super.onDialogOpen()
// 检查是否应该触发fetch数据
if (this.state.postList.length == 0) {
this.presenter.findTaggedPosts(this.props.tag)
}
this.setState({ dialogOpened: true })
}

onDialogClose() {
super.onDialogClose()
this.presenter.abortFetch()
// this.presenter.reduceResult()
this.setState({ dialogOpened: false })
}

onClickLoadMore() {
this.presenter.loadMore(true)
}

scrollNearToBottom(): void {
if (this.state.loadHint == ERROR_HINT) return
this.presenter.loadMore(false)
this.setState({ loadMoreId: this.state.loadMoreId + 1 })
}

onListSizeChanged() {
this.heightAnimationContainer.update()
}

componentDidMount() {
Expand All @@ -69,11 +62,6 @@ export class TagDialog extends BasicDialog<DialogContentProps, DialogContentStat
this.heightAnimationContainer = new HeightAnimationContainer(this.rootE.querySelector(".height-animation-container"))
}

componentDidUpdate(prevProps: Readonly<BasicDialogProps>, prevState: Readonly<any>, snapshot?: any): void {
super.componentDidUpdate(prevProps, prevState, snapshot)
this.heightAnimationContainer.update()
}

componentWillUnmount(): void {
if (this.heightAnimationContainer != null) this.heightAnimationContainer.destroy()
}
Expand All @@ -88,36 +76,81 @@ export class TagDialog extends BasicDialog<DialogContentProps, DialogContentStat

dialogContent(): JSX.Element {
consoleDebug("TagDialogContent render")

return (
<div className="height-animation-container">
<ResultWrapper category={""} tag={this.props.tag} pinedPosts={[]} loadedPosts={[]}
onUpdate={this.onListSizeChanged} dialogOpened={this.state.dialogOpened}
loadMoreId={this.state.loadMoreId} />
</div>
)
}
}

interface ResultWrapperProps extends BasePostPaginateShowProps {
dialogOpened: boolean
loadMoreId: number
}

class ResultWrapper extends BasePostPaginateShow<ResultWrapperProps> {

constructor(props: ResultWrapperProps) {
super(props)
this.loadFirstPageOnMount = false
}

createPresenter(): IPostPaginateShowPresenter {
return new PostPaginateShowPresenter(this, true)
}

shouldComponentUpdate(nextProps: Readonly<ResultWrapperProps>, nextState: Readonly<BasePostPaginateShowState>, nextContext: any): boolean {
if (nextProps.loadMoreId > 0 && this.props.loadMoreId != nextProps.loadMoreId &&
(this.presenter.isLastPage() || this.state.loadHint == ERROR_HINT)) {
// 如果是最后一页,不触发加载
// 如果是异常状态,不触发加载,等待用户点击
return false
}
return true
}

componentDidUpdate(prevProps: Readonly<ResultWrapperProps>, prevState: Readonly<BasePostPaginateShowState>, snapshot?: any): void {
super.componentDidUpdate(prevProps, prevState, snapshot)
if (this.props.dialogOpened && !prevProps.dialogOpened && this.state.posts.length == 0) {
this.loadFirstPage()
}
if (!this.props.dialogOpened && prevProps.dialogOpened) {
this.presenter.abortLoad()
}
if (this.props.loadMoreId > 0 && this.props.loadMoreId != prevProps.loadMoreId) {
this.loadMore()
}
}

render(): React.ReactNode {
let count: JSX.Element
if (this.state.postList.length == 0) {
if (this.state.posts.length == 0) {
count = <></>
} else {
count = <><span>{this.state.resultSize}</span></>
count = <><span>{this.state.totalPostsSize}</span></>
}
return (
<>
<p className="mdc-theme--on-surface">标记 {this.props.tag}{count}篇博文
<p>标记 {this.props.tag}{count}篇博文
</p>

{/* <ProgressLinear loading={this.state.loading} /> */}
<div className="height-animation-container">
<div>
{this.state.postList != null && this.state.postList.length != 0 &&
<PostResult list={this.state.postList} />
}
{(this.state.loading || this.state.loadHint != null) &&
<LoadingHint loading={this.state.loading} loadHint={this.state.loadHint} onClickHint={this.onClickLoadMore} />
}
</div>
</div>
{this.state.posts != null && this.state.posts.length != 0 &&
<PostResult list={this.state.posts} />
}
{(this.state.loading || this.state.loadHint != null) &&
<LoadingHint loading={this.state.loading} loadHint={this.state.loadHint} onClickHint={this.loadMoreByClick} />
}
</>
)
}
}


interface PostResultProps {
list: PostItemData[]
list: Post[]
}

class PostResult extends React.Component<PostResultProps, any> {
Expand All @@ -132,15 +165,42 @@ class PostResult extends React.Component<PostResultProps, any> {
new MDCList(e)
}

getPostType(item: Post): SectionType {
return getSectionTypeByPath(item.path)
}

/**
* 获取一个文章要显示的块,包括author作者、actor演员、mention提到
* 显示,一共就2个block,用不同的颜色区分
*/
getPostBlocks(author: string, actor: Array<string>, mention: Array<string>, postType: SectionType): [string[], string[]] {
if (postType.identifier === SECTION_TYPE_ORIGINAL.identifier) {
// 随笔,不显示author,显示actor和mention
return [actor, mention]
} else if (postType.identifier === SECTION_TYPE_OPERA.identifier) {
// 看剧,显示actor和mention
return [actor, mention]
} else {
// 其它类型,显示author和mention
return [[author], mention]
}
}

render() {
const items = this.props.list.map((item) => {
const postType = this.getPostType(item)
const postBlocks = this.getPostBlocks(item.author, item.actor, item.mention, postType)
// 两个chip列表
return new PostItemData(item.path, item.title, item.date, postType.name, postBlocks[0], postBlocks[1])
})
return (
<ul className="mdc-deprecated-list">
{this.props.list.map((item) =>
{items.map((item) =>
<PostItem
key={item.title + item.date}
data={new PostItemData(item.url, item.title, item.date, item.type, item.block1Array, item.block2Array)}
first={this.props.list.indexOf(item) === 0}
last={this.props.list.indexOf(item) === (this.props.list.length - 1)}
first={items.indexOf(item) === 0}
last={items.indexOf(item) === (this.props.list.length - 1)}
/>
)}
</ul>
Expand Down
Loading

0 comments on commit 9aa71c6

Please sign in to comment.