Skip to content

Commit 655a706

Browse files
committed
feat: 基本信息组件
1 parent b718e03 commit 655a706

File tree

9 files changed

+1527
-956
lines changed

9 files changed

+1527
-956
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
],
1818
"cSpell.words": [
1919
"Vercel",
20+
"douyin",
2021
"gitee",
2122
"immer",
2223
"standardjs",

backend/src/models/Video.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class Video extends Model {
1010
description?: string
1111
like_count!: number
1212
play_count!: number
13+
reference!: number
1314
public readonly createdAt!: Date
1415
public readonly updatedAt!: Date
1516
}
@@ -56,6 +57,14 @@ Video.init(
5657
defaultValue: 0,
5758
allowNull: false,
5859
},
60+
reference: {
61+
type: DataTypes.INTEGER.UNSIGNED,
62+
comment: '这支视频引用的视频',
63+
references: {
64+
model: Video,
65+
key: 'id',
66+
},
67+
},
5968
},
6069
{
6170
sequelize,

frontend/.storybook/main.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ const path = require('path')
33
const postcssNormalize = require('postcss-normalize')
44

55
module.exports = {
6+
addons: [
7+
'@storybook/addon-backgrounds/register',
8+
'@storybook/addon-viewport'
9+
],
610
"stories": [
711
"../src/**/*.stories.mdx",
812
"../src/**/*.stories.@(js|jsx|ts|tsx)"

frontend/.storybook/preview.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11

22
export const parameters = {
33
actions: { argTypesRegex: "^on[A-Z].*" },
4-
}
4+
backgrounds: {
5+
default: 'twitter',
6+
values: [
7+
{
8+
name: 'douyin',
9+
value: '#111',
10+
},
11+
{
12+
name: 'white',
13+
value: '#fff',
14+
},
15+
{
16+
name: 'black',
17+
value: '#000',
18+
},
19+
],
20+
},
21+
}

frontend/package-lock.json

Lines changed: 1292 additions & 955 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@
3030
"@babel/core": "7.12.3",
3131
"@pmmmwh/react-refresh-webpack-plugin": "0.4.2",
3232
"@storybook/addon-actions": "^6.1.15",
33+
"@storybook/addon-backgrounds": "^6.1.17",
3334
"@storybook/addon-essentials": "^6.1.15",
3435
"@storybook/addon-links": "^6.1.15",
36+
"@storybook/addon-viewport": "^6.1.17",
3537
"@storybook/react": "^6.1.15",
3638
"@svgr/webpack": "5.4.0",
3739
"@testing-library/jest-dom": "^5.11.4",
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
@img-size: 40px;
2+
@border-size: 10px;
3+
4+
.video-info {
5+
position: absolute;
6+
bottom: 10px;
7+
right: 0;
8+
width: 100%;
9+
color: white;
10+
font-size: 14px;
11+
display: flex;
12+
justify-content: space-between;
13+
align-items: flex-end;
14+
&-left {
15+
flex-grow: 1;
16+
}
17+
&-username {
18+
font-size: 16px;
19+
font-weight: bolder;
20+
}
21+
&-description {
22+
margin-top: 4px;
23+
margin-bottom: 8px;
24+
}
25+
&-text {
26+
color: darken(white, 10%);
27+
}
28+
&-tags {
29+
margin-left: 10px;
30+
}
31+
&-right {
32+
position: relative;
33+
}
34+
&-reference {
35+
&-avatar {
36+
margin-right: 5px;
37+
}
38+
&-img {
39+
width: @img-size;
40+
height: @img-size;
41+
border-radius: @img-size;
42+
border: @border-size solid lighten(#111, 10%);
43+
animation: spin 15s linear infinite;
44+
@keyframes spin {
45+
0% {
46+
transform: rotate(0deg);
47+
}
48+
100% {
49+
transform: rotate(360deg);
50+
}
51+
}
52+
}
53+
}
54+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from 'react'
2+
import { Meta } from '@storybook/react/types-6-0'
3+
import { VideoInfo, VideoInfoProps } from '.'
4+
5+
// import './index.stories.less'
6+
7+
export default {
8+
title: 'Example/VideoInfo',
9+
component: VideoInfo,
10+
parameters: {
11+
backgrounds: { default: 'douyin' },
12+
},
13+
} as Meta
14+
15+
const videoInfoProps: VideoInfoProps = {
16+
userName: '胖超说艺考',
17+
description: '没有张主任不会的乐器...',
18+
tags: [
19+
{
20+
content: '破音师徒花式反转',
21+
tid: 1,
22+
},
23+
{
24+
content: '踏山河',
25+
tid: 2,
26+
},
27+
],
28+
onTagClick(tid) {
29+
console.log('tid', tid, 'clicked')
30+
},
31+
musicAuthor: '胖超说艺考',
32+
musicName: '音乐名称',
33+
referencedAvatarUrl:
34+
'https://avatars.githubusercontent.com/u/24741764?s=400&u=a8929e616a4f6253e805996a8810bc56b9e02731&v=4',
35+
onDescriptionClick() {
36+
console.log('onDescriptionClick')
37+
},
38+
onMusicNameClick() {
39+
console.log('onMusicNameClick')
40+
},
41+
onUserNameClick() {
42+
console.log('onUserNameClick')
43+
},
44+
onReferencedAvatarClick() {
45+
console.log('onReferencedAvatarClick')
46+
},
47+
}
48+
// 点播播放器的使用方法
49+
export const videoInfo = () => <VideoInfo {...videoInfoProps} />
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React from 'react'
2+
import classnames from 'classnames'
3+
4+
import './index.less'
5+
6+
export interface VideoTag {
7+
/* tag 唯一 id */
8+
tid: number
9+
/* tag 内容 */
10+
content: string
11+
}
12+
13+
export interface VideoInfoProps {
14+
/* 用户名 */
15+
userName: string
16+
/* 用户名被点击 */
17+
onUserNameClick?: () => void
18+
/* 简介 */
19+
description?: string
20+
tags?: VideoTag[]
21+
onTagClick?: (tid: VideoTag['tid']) => void
22+
/* 简介被点击 */
23+
onDescriptionClick?: () => void
24+
/* 音乐作者 */
25+
musicAuthor?: string
26+
/* 音乐名称 */
27+
musicName?: string
28+
/* 音乐名称点击回调 */
29+
onMusicNameClick?: () => void
30+
/* 被引用者头像 */
31+
referencedAvatarUrl?: string
32+
/* 被引用者头像点击回调 */
33+
onReferencedAvatarClick?: () => void
34+
/* 自定义类名 */
35+
className?: string
36+
}
37+
38+
export const VideoInfo: React.FC<VideoInfoProps> = ({
39+
userName,
40+
onUserNameClick,
41+
description,
42+
onDescriptionClick,
43+
tags = [],
44+
onTagClick,
45+
musicAuthor,
46+
musicName,
47+
onMusicNameClick,
48+
referencedAvatarUrl,
49+
onReferencedAvatarClick,
50+
className,
51+
}) => {
52+
return (
53+
<div className={classnames('video-info', className)}>
54+
<div className="video-info-left">
55+
<div
56+
className="video-info-username"
57+
onClick={() => onUserNameClick?.()}
58+
>
59+
@{userName}
60+
</div>
61+
<div
62+
className="video-info-description"
63+
onClick={() => onDescriptionClick?.()}
64+
>
65+
<span className="video-info-text">{description}</span>
66+
<span className="video-info-tags">
67+
{tags.map((tag) => (
68+
<span
69+
className="video-info-tag"
70+
key={tag.tid}
71+
onClick={(e) => {
72+
onTagClick?.(tag.tid)
73+
e.stopPropagation()
74+
}}
75+
>
76+
#{tag.content}
77+
</span>
78+
))}
79+
</span>
80+
</div>
81+
<div
82+
className="video-info-reference-text"
83+
onClick={() => onMusicNameClick?.()}
84+
>
85+
@{musicAuthor}创作的原声——{musicName}
86+
</div>
87+
</div>
88+
<div className="video-info-right">
89+
<div
90+
className="video-info-reference-avatar"
91+
onClick={() => onReferencedAvatarClick?.()}
92+
>
93+
<img className="video-info-reference-img" src={referencedAvatarUrl} />
94+
</div>
95+
</div>
96+
</div>
97+
)
98+
}

0 commit comments

Comments
 (0)