@x-edu/live-player 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,123 @@
1
+ .container {
2
+ padding: 24px 0;
3
+ margin: 0 24px;
4
+ display: flex;
5
+ justify-content: flex-start;
6
+ border-top: 1px solid #eee;
7
+ cursor: pointer;
8
+
9
+ &:first-child {
10
+ border-top: none;
11
+ }
12
+
13
+ .left {
14
+ margin-right: 24px;
15
+ border-radius: 8px;
16
+ position: relative;
17
+
18
+ .avatar {
19
+ width: 204px;
20
+ height: 120px;
21
+ border-radius: 4px;
22
+ object-fit: cover;
23
+ }
24
+
25
+ .tag {
26
+ position: absolute;
27
+ top: 0px;
28
+ border-radius: 4px 0px;
29
+ font-size: 12px;
30
+ line-height: 12px;
31
+ height: 20px;
32
+ padding: 0 8px;
33
+ display: flex;
34
+ align-items: center;
35
+ color: #fff;
36
+ }
37
+
38
+ .tag0 { // 预告
39
+ background-color: #FF7826;
40
+ }
41
+
42
+ .tag1 { // 直播中
43
+ background-color: #1E62EC;
44
+ padding: 0 5px;
45
+
46
+ img {
47
+ transform: rotate(180deg);
48
+ height: 10px;
49
+ width: 10px;
50
+ margin-right: 5px;
51
+ }
52
+ }
53
+
54
+ .tag2 { // 回放
55
+ background-color: rgba(0, 0, 0, 0.60);
56
+ }
57
+ }
58
+
59
+ .right {
60
+ display: flex;
61
+ flex-direction: column;
62
+ justify-content: space-between;
63
+ width: calc(100% - 228px);
64
+
65
+ &-top {
66
+ .title {
67
+ overflow: hidden;
68
+ text-overflow: ellipsis;
69
+ display: -webkit-box;
70
+ -webkit-box-orient: vertical;
71
+ word-wrap: break-word;
72
+ line-height: 28px;
73
+ -webkit-line-clamp: 2;
74
+ font-size: 20px;
75
+ font-weight: 600;
76
+ color: #333;
77
+ }
78
+ }
79
+
80
+ &-bottom {
81
+ display: flex;
82
+ justify-content: space-between;
83
+ align-items: center;
84
+
85
+ .time {
86
+ font-size: 14px;
87
+ color: #999;
88
+ display: flex;
89
+ align-items: center;
90
+ &-icon {
91
+ width: 16px;
92
+ height: 16px;
93
+ color: #ccc;
94
+ margin-right: 4px;
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ .container:hover {
102
+ .title {
103
+ color: #1E62EC;
104
+ }
105
+ }
106
+
107
+ .action {
108
+ font-size: 14px;
109
+ line-height: 22px;
110
+ color: #1E62EC;
111
+ border-radius: 144.889px;
112
+ border: 1px solid #1E62EC;
113
+ width: 88px;
114
+ height: 32px;
115
+ display: flex;
116
+ align-items: center;
117
+ justify-content: center;
118
+ }
119
+
120
+ .action-subscribe {
121
+ background: #1E62EC;
122
+ color: #fff;
123
+ }
@@ -0,0 +1,150 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import classNames from 'classnames'
3
+ import { Tabs } from 'fish'
4
+ import { OpenLiveSearchFront, getSubscription } from '@/service/live'
5
+ import { setUC } from '@/util/auth/func'
6
+ import config from '@/config/env'
7
+ import Loading from '@/component/status/Loading'
8
+ import Empty from './Empty'
9
+ import Pagination from '@/component/Pagination'
10
+ import ListItem from './ListItem'
11
+ import style from './index.module.less'
12
+
13
+ const PageSize = 7
14
+
15
+ const StatusEnum = [
16
+ {
17
+ label: '全部',
18
+ value: 'all'
19
+ },
20
+ {
21
+ label: '直播中',
22
+ value: 1
23
+ },
24
+ {
25
+ label: '预告',
26
+ value: 0
27
+ },
28
+ {
29
+ label: '回放',
30
+ value: 2
31
+ }
32
+ ]
33
+
34
+ export default function PublicLiveList({
35
+ scopeType,
36
+ scopeId,
37
+ containerClassName,
38
+ uc,
39
+ loginInfo,
40
+ sdpAppId: propSdpAppId,
41
+ onDetailClick,
42
+ handleLogin = () => {},
43
+ onSubscribe = () => {}
44
+ }) {
45
+ setUC(uc, loginInfo?.userInfo)
46
+ if (propSdpAppId) {
47
+ config.app.appid = propSdpAppId
48
+ }
49
+
50
+ const [list, setList] = useState([])
51
+ const [total, setTotal] = useState(0)
52
+ const [loading, setLoading] = useState(true)
53
+ const [page, setPage] = useState(1)
54
+ const [status, setStatus] = useState('all')
55
+ const [subscription, setSubscription] = useState([])
56
+ const [isLogin, setIsLogin] = useState(false)
57
+
58
+ const handleTabChange = (value) => {
59
+ setStatus(value)
60
+ setPage(1)
61
+ }
62
+
63
+ const handlePageChange = (value) => {
64
+ setPage(value)
65
+ }
66
+
67
+ // 分页获取直播列表
68
+ useEffect(() => {
69
+ async function getList() {
70
+ setLoading(true)
71
+ const data = await OpenLiveSearchFront({
72
+ status,
73
+ scopeType,
74
+ scopeId,
75
+ offset: (page - 1) * PageSize,
76
+ limit: PageSize
77
+ })
78
+ const { items, count } = data
79
+ if (uc) {
80
+ const curIsLogin = await uc.isLogin()
81
+ if (curIsLogin) {
82
+ const curSubscription = await getSubscription()
83
+ setSubscription(curSubscription)
84
+ setIsLogin(true)
85
+ }
86
+ }
87
+ setList(items)
88
+ setTotal(count)
89
+ setLoading(false)
90
+ }
91
+ getList()
92
+ }, [page, status])
93
+
94
+ return (
95
+ <div
96
+ className={classNames(
97
+ containerClassName,
98
+ style.container
99
+ )}
100
+ >
101
+ <Tabs
102
+ accessKey={status}
103
+ onChange={handleTabChange}
104
+ >
105
+ {StatusEnum.map((item) => (
106
+ <Tabs.TabPane
107
+ key={item.value}
108
+ tab={item.label}
109
+ >
110
+ <Loading
111
+ loading={loading}
112
+ >
113
+ <div className={style.list}>
114
+ {loading ? null : (
115
+ <>
116
+ {!loading && list.length ? (
117
+ <>
118
+ {list.map((listItem) => (
119
+ <ListItem
120
+ data={listItem}
121
+ key={listItem.live_id}
122
+ subscription={subscription}
123
+ onDetailClick={onDetailClick}
124
+ handleLogin={handleLogin}
125
+ isLogin={isLogin}
126
+ onSubscribe={onSubscribe}
127
+ />
128
+ ))}
129
+ <Pagination
130
+ total={total}
131
+ pageSize={PageSize}
132
+ current={page}
133
+ onChange={handlePageChange}
134
+ />
135
+ </>
136
+ ) : (
137
+ <Empty
138
+ tip="暂无内容"
139
+ />
140
+ )}
141
+ </>
142
+ )}
143
+ </div>
144
+ </Loading>
145
+ </Tabs.TabPane>
146
+ ))}
147
+ </Tabs>
148
+ </div>
149
+ )
150
+ }
@@ -0,0 +1,36 @@
1
+ .container {
2
+ max-width: 1300px;
3
+ margin: 0 auto;
4
+ padding: 24px 24px 0px 24px;
5
+ width: 956px;
6
+
7
+ :global {
8
+ .fish-tabs-nav {
9
+ margin-bottom: 24px;
10
+ }
11
+ .fish-tabs-nav::before {
12
+ display: none;
13
+ }
14
+ .fish-tabs-ink-bar {
15
+ display: none;
16
+ }
17
+ .fish-tabs-tab + .fish-tabs-tab {
18
+ margin-left: 0px;
19
+ }
20
+ .fish-tabs-tab {
21
+ padding: 9px 20px;
22
+ }
23
+ .fish-tabs-tab-btn {
24
+ font-size: 14px;
25
+ line-height: 14px;
26
+ color: #666
27
+ }
28
+ .fish-tabs-tab-active {
29
+ border-radius: 16px;
30
+ background: var(--f-3-f-7-ff, #F3F7FF);
31
+ .fish-tabs-tab-btn {
32
+ color: #1E62EC;
33
+ }
34
+ }
35
+ }
36
+ }
@@ -234,3 +234,60 @@ export async function getLiveInfo(ids) {
234
234
  return result.map((res) => res.data)
235
235
  // return result?.data || {}
236
236
  }
237
+
238
+ /**
239
+ * 查询直播列表-前台
240
+ */
241
+ export async function OpenLiveSearchFront({
242
+ status,
243
+ scopeType,
244
+ scopeId,
245
+ offset,
246
+ limit
247
+ }) {
248
+ try {
249
+ const url = '/v1/open_class_lives/search_front'
250
+ const response = await proxyApi.get(url, {
251
+ params: {
252
+ status: status === 'all' ? undefined : status,
253
+ scope_type: scopeType,
254
+ scope_id: scopeId,
255
+ offset,
256
+ limit
257
+ }
258
+ })
259
+ return response?.data || {
260
+ count: 0,
261
+ items: []
262
+ }
263
+ } catch (_) {
264
+ return {
265
+ count: 0,
266
+ items: []
267
+ }
268
+ }
269
+ }
270
+
271
+ /**
272
+ * 获取预约直播
273
+ */
274
+ export async function getSubscription() {
275
+ try {
276
+ const url = '/v1/open_class_lives/actions/get_subscription'
277
+ const response = await liveActivityAPI.get(url)
278
+ return response.data
279
+ } catch (_) {
280
+ return []
281
+ }
282
+ }
283
+
284
+ /**
285
+ * 预约直播
286
+ */
287
+ export async function openLiveSubscribe({
288
+ liveId
289
+ }) {
290
+ const url = `/v1/open_class_lives/${liveId}/actions/subscribe`
291
+ const response = await liveActivityAPI.post(url)
292
+ return response?.data
293
+ }