import * as React from 'react'; import { callHandler } from 'nejsbridge/dist/bridge.lofter.es'; import { PostCardType, PostCardConfig, PostDetail, AllDetail, Props, State } from './type'; import { Container, Bangs, } from './index.style'; import { rem } from '../style/function.style'; import { fetchPostDetail } from './fetch-post'; import { fetchCollectionDetail } from './fetch-collection'; import { fetchPushCollectionDetail } from './fetch-push-collection'; import { fetchPostPermaLinksDetail } from './fetch-permalinks-post' import { LofterPostColumnCard } from './post/ColumnCard'; import { LofterPostRowCard } from './post/RowCard'; import { LofterPostTextRowCard } from './post/TextRowCard'; import { LofterSelectedRowCard } from './post/SelectedCard'; import { LofterSelectedColCard } from './post/SelectedColCard' import { BaseComponent } from '../base-component' import { checkIsMp } from '../utils/detect' import { formatPostUrlToMpPreviewUrl } from '../utils/format' const CardMap = { 1: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => ( ), 2: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => ( ), 3: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => ( ), 4: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => ( ), 5: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => ( ), 6: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => ( ), 7: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail, isEdit?: boolean | undefined, rightWidth?: number, useWithoutPrivacy?: boolean) => ( ), 8: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail, isEdit?: boolean | undefined) => ( ), } const fetchDetailMap = { 1: fetchPostDetail, 2: fetchCollectionDetail, 4: fetchPushCollectionDetail, // type 4 新增的推集类型 5: fetchPostPermaLinksDetail, // type 5 文章类型新 } export class LofterPost extends React.Component { static defaultProps = new Props(); state = new State(); willUpdateNextLoop = false; postsDetail: { [postId: number]: false | AllDetail } = {}; postsFetching: { [postId: number]: boolean } = {}; private unmounted = false; componentWillUnmount() { this.unmounted = true; } componentDidMount() { this.refresh(); // 20220920,719版本隐私合规需求 const { useWithoutPrivacy, isEdit } = this.props; console.log('useWithoutPrivacy', useWithoutPrivacy); if (useWithoutPrivacy && !isEdit) { callHandler('hideActionMenu'); const bar = document.createElement('div'); bar.innerText = `解锁更多个性化推荐与功能` bar.style.cssText = ` height: ${rem(64)}; width: ${rem(718)}; box-sizing: border-box; padding: 0 ${rem(24)}; margin: 0 auto ${rem(16)}; border-radius: ${rem(16)}; background: #f5f5f5; display: flex; justify-content: center; align-items: center; font-size: ${rem(22)}; font-weight: 500; color: #2E2E2E; ` const action = document.createElement('span'); action.innerText = '进入完整功能模式'; action.style.cssText = ` margin-left: auto; box-sizing: border-box; padding: ${rem(7)} ${rem(16)}; font-size: ${rem(24)}; border-radius: ${rem(24)}; border: 1px solid #2E2E2E; display: flex; justify-content: center; align-items: center; ` bar.appendChild(action); bar.addEventListener('click', () => { callHandler('njb_unlock_more'); }) const app = document.querySelector('#app'); document.body.insertBefore(bar, app) } } componentDidUpdate(prevProps: any) { if ( prevProps.posts !== this.props.posts && !this.unmounted ) { this.refresh(); } } refresh() { if (this.unmounted) return; const { posts, style: oriStyle, } = this.props; posts.forEach((postCardConfig) => { const { postId, // 此type值为处理type为空情况时请求的map类型,勿改 type = 1, } = postCardConfig; // 此处为了尽量复用已有的文章类型支持,只从type扩展 // 1为文章,2为扩展的合集,4为推集,3为其他类型(自由配置),数据类型尽量保持和文章一致 // type=3时不做请求,直接mock假数据,全部交由运营配置 // 这里ts 提示是因为之前是文章类型,后来增加了合集类型,合集类型缺失一些文章类型的属性,后来又增加了推集 if (postId && type === 3) { this.postsDetail[postId] = { id: postId, // originType: 'other', classifyType: 3, title: '', digest: '', postPageUrl: '' } return; } if ( !postId || this.postsFetching[postId] || typeof this.postsDetail[postId] !== 'undefined' ) { return; } this.postsFetching[postId] = true; fetchDetailMap[type](postId) .then((postDetail: AllDetail) => { // if (this.destroyed) return; // console.log('postDetail', postDetail) if (postDetail) { // 增加小程序内单日志展示链接处理 if (checkIsMp() && postDetail.postPageUrl) { postDetail.postPageUrl = formatPostUrlToMpPreviewUrl(postDetail.postPageUrl) } this.postsDetail[postId] = postDetail; } else { this.postsDetail[postId] = false; } this.updateNextLoop() }); }) } updateNextLoop() { if (this.willUpdateNextLoop) return; this.willUpdateNextLoop = true; setTimeout(() => { // if (this.destroyed) return; this.forceUpdate(); this.willUpdateNextLoop = false; }, 0) } renderPost( type: PostCardType, postCardConfig: PostCardConfig, index: number, isEdit?: boolean | undefined, rightWidth?: number, useWithoutPrivacy?: boolean, ) { if ( CardMap[type] ) { const postId = postCardConfig.postId; const postDetail = this.postsDetail[postId]; if ( (postDetail === false || !postId) && !this.props.isEdit ) return; return CardMap[type]( postCardConfig, index, postDetail, isEdit, rightWidth, useWithoutPrivacy, ); } } public render() { const { style, type, posts, marginTop, isEdit, rightWidth, selectedNegativeMargin, useWithoutPrivacy, } = this.props; // 是否为精选样式 const isSelected = type === 7; //只有精选样式水平才有上面的推荐语 return ( { isSelected && selectedNegativeMargin && } { posts && posts.map((post, index) => this.renderPost( type, post, index, isEdit, rightWidth, useWithoutPrivacy, )) } ) } }