Browse Source

add video

KaysonCui 5 years ago
parent
commit
7516645a7e

+ 81 - 9
front/project/www/components/Video/index.js

@@ -2,12 +2,59 @@ import React, { Component } from 'react';
 import './index.less';
 import videojs from 'video.js';
 import Assets from '@src/components/Assets';
+import { generateUUID } from '@src/services/Tools';
+
+function fullScreen(id) {
+  const element = document.getElementById(id);
+  if (element.requestFullscreen) {
+    element.requestFullscreen();
+  } else if (element.msRequestFullscreen) {
+    element.msRequestFullscreen();
+  } else if (element.mozRequestFullScreen) {
+    element.mozRequestFullScreen();
+  } else if (element.webkitRequestFullscreen) {
+    element.webkitRequestFullscreen();
+  }
+}
+
+function exitFullscreen() {
+  if (document.exitFullscreen) {
+    document.exitFullscreen();
+  } else if (document.msExitFullscreen) {
+    document.msExitFullscreen();
+  } else if (document.mozCancelFullScreen) {
+    document.mozCancelFullScreen();
+  } else if (document.webkitExitFullscreen) {
+    document.webkitExitFullscreen();
+  }
+}
+
+let fullAgent = null;
+
+document.addEventListener('fullscreenchange', () => {
+  if (fullAgent) fullAgent();
+});
+
+/* Firefox */
+document.addEventListener('mozfullscreenchange', () => {
+  if (fullAgent) fullAgent();
+});
+
+/* Chrome, Safari and Opera */
+document.addEventListener('webkitfullscreenchange', () => {
+  if (fullAgent) fullAgent();
+});
+
+/* IE / Edge */
+document.addEventListener('msfullscreenchange', () => {
+  if (fullAgent) fullAgent();
+});
 
 export default class Video extends Component {
   constructor(props) {
     super(props);
     this.ready = false;
-    this.state = { playing: false, fulling: false };
+    this.state = { id: generateUUID(8), playing: false, fulling: false };
   }
 
   componentDidMount() {
@@ -50,11 +97,25 @@ export default class Video extends Component {
     this.player.playbackRate(speed);
   }
 
+  onFullChange() {
+    this.setState({ fulling: !this.state.fulling });
+    if (this.props.onFullChange) this.props.onFullChange();
+  }
+
+  onFull() {
+    fullAgent = () => this.onFullChange();
+    fullScreen(this.state.id);
+  }
+
+  onExitFull() {
+    exitFullscreen();
+  }
+
   render() {
-    const { action = true, btnList = [], onAction } = this.props;
-    const { playing, fulling } = this.state;
+    const { action = true, btnList = [], children, onAction } = this.props;
+    const { playing, fulling, id } = this.state;
     return (
-      <div className={`video-item ${action ? 'action' : ''}`}>
+      <div id={id} className={`video-item ${action ? 'action' : ''} ${fulling ? 'full' : ''}`}>
         <div className="video-wrapper">
           <video
             ref={node => {
@@ -77,11 +138,21 @@ export default class Video extends Component {
               </div>
               <div className="flex-block" />
               {btnList.map(btn => {
+                if (btn.full && !fulling) return '';
                 return (
                   <div className="d-i-b m-r-1">
-                    <div className="btn" onClick={() => onAction && onAction(btn.key)}>
-                      {btn.title}
-                    </div>
+                    {btn.render ? (
+                      <div className="fix-btn d-i-b" onClick={() => onAction && onAction(btn.key)}>
+                        {btn.render(btn.active)}
+                      </div>
+                    ) : (
+                      <div
+                        className={`btn ${btn.active ? 'active' : ''}`}
+                        onClick={() => onAction && onAction(btn.key)}
+                      >
+                        {btn.title}
+                      </div>
+                    )}
                   </div>
                 );
               })}
@@ -89,12 +160,13 @@ export default class Video extends Component {
                 <div className="btn">倍速</div>
               </div>
               <div className="d-i-b">
-                {!fulling && <Assets name="full2" />}
-                {fulling && <Assets name="reduction2" />}
+                {!fulling && <Assets name="full2" onClick={() => this.onFull()} />}
+                {fulling && <Assets name="reduction2" onClick={() => this.onExitFull()} />}
               </div>
             </div>
           )}
         </div>
+        {children}
       </div>
     );
   }

+ 13 - 2
front/project/www/components/Video/index.less

@@ -3,6 +3,8 @@
   height: 100%;
   padding-bottom: 3px;
   position: relative;
+  overflow: hidden;
+  background: #3A3A3AFF;
 
   .video-bottom {
     position: absolute;
@@ -26,6 +28,10 @@
       cursor: pointer;
     }
 
+    .fix-btn {
+      transform: translateY(-1px);
+    }
+
     .btn {
       display: inline-block;
       font-size: 12px;
@@ -38,8 +44,13 @@
       border-radius: 12px;
     }
 
-    .btn:hover {
-      background: darken(#696969, 10);
+    // .btn:hover {
+    //   background: darken(#696969, 10);
+    // }
+
+    .btn.active,
+    .btn.active:hover {
+      background: #4292f0;
     }
   }
 

+ 44 - 6
front/project/www/routes/course/detail/index.less

@@ -46,18 +46,46 @@
           width: 100%;
           height: 520px;
           background: #3A3A3AFF;
+
+          .video-item.full {
+            .video-fixed {
+              display: block;
+            }
+          }
+
+          .video-fixed {
+            display: none;
+            width: 400px;
+            bottom: 60px;
+            right: 10px;
+            position: absolute;
+
+            .tab-body {
+              padding: 0 15px;
+            }
+
+            .answer-layout {
+              height: 480px;
+            }
+
+            .item-layout {
+              height: 530px;
+            }
+          }
         }
       }
 
-      .right {
-        padding-left: 790px;
-
+      .tab-warpper {
         .tabs {
-          margin-bottom: 5px;
           line-height: 36px;
           height: 36px;
         }
 
+        .tab-body {
+          padding-top: 5px;
+          background: #fff;
+        }
+
         .all-answer {
           line-height: 20px;
           height: 40px;
@@ -76,7 +104,6 @@
         }
 
         .answer-layout {
-          height: 430px;
           overflow-y: auto;
 
           .answer-item {
@@ -102,7 +129,6 @@
         }
 
         .item-layout {
-          height: 480px;
           overflow-y: auto;
 
           .item {
@@ -119,6 +145,18 @@
         }
       }
 
+      .right {
+        padding-left: 790px;
+
+        .answer-layout {
+          height: 430px;
+        }
+
+        .item-layout {
+          height: 480px;
+        }
+      }
+
       .right.progress {
         .answer-layout {
           height: 500px;

+ 49 - 4
front/project/www/routes/course/detail/page.js

@@ -62,8 +62,24 @@ export default class extends Page {
     this.setState({ key });
   }
 
+  onVideoAction(key) {
+    const { rightTab, showTab, showQuestion, showNote } = this.state;
+    switch (key) {
+      case 'question':
+        return this.setState({ showQuestion: !showQuestion });
+      case 'note':
+        return this.setState({ showNote: !showNote });
+      case 'answer':
+        return this.setState({ showTab: rightTab === '1' ? !showTab : true, rightTab: '1' });
+      case 'list':
+        return this.setState({ showTab: rightTab === '2' ? !showTab : true, rightTab: '2' });
+      default:
+        return '';
+    }
+  }
+
   renderView() {
-    const { base = {}, data = {}, add, progress, rightTab } = this.state;
+    const { base = {}, data = {}, add, progress, rightTab, showTab, showQuestion, showNote } = this.state;
     return (
       <div>
         <div className="top content t-8">
@@ -94,10 +110,39 @@ export default class extends Page {
                 </Button>
               </div>
               <div className="video-layout">
-                <Video src="/01.mp4" btnList={[{ title: '提问', key: 'answer' }, { title: '笔记', key: 'note' }]} />
+                <Video
+                  src="/01.mp4"
+                  btnList={[
+                    { title: '提问', key: 'question', active: showQuestion },
+                    {
+                      key: 'answer',
+                      render(active) {
+                        return <Assets name={active ? 'question_on' : 'question_off'} />;
+                      },
+                      full: true,
+                      active: showTab && rightTab === '1',
+                    },
+                    { title: '笔记', key: 'note', active: showNote },
+                    { title: '课表', key: 'list', full: true, active: showTab && rightTab === '2' },
+                  ]}
+                  onAction={key => this.onVideoAction(key)}
+                  onFullChange={() => this.setState({ showTab: true, rightTab: '1' })}
+                >
+                  <div hidden={!showTab} className="video-fixed tab-warpper">
+                    <Tabs
+                      type="division"
+                      theme="gray"
+                      space={2.5}
+                      active={rightTab}
+                      tabs={[{ title: '精选问答', key: '1' }, { title: '课时列表', key: '2' }]}
+                      onChange={key => this.onChangeRightTab(key)}
+                    />
+                    <div className="tab-body">{this[`renderRightTab${rightTab}`]()}</div>
+                  </div>
+                </Video>
               </div>
             </div>
-            <div className={`right ${progress > 0 ? 'progress' : ''}`}>
+            <div className={`right ${progress > 0 ? 'progress' : ''}  tab-warpper`}>
               <Tabs
                 type="division"
                 theme="gray"
@@ -106,7 +151,7 @@ export default class extends Page {
                 tabs={[{ title: '精选问答', key: '1' }, { title: '课时列表', key: '2' }]}
                 onChange={key => this.onChangeRightTab(key)}
               />
-              {this[`renderRightTab${rightTab}`]()}
+              <div className="tab-body">{this[`renderRightTab${rightTab}`]()}</div>
             </div>
           </div>
           <UserTable columns={this.columns} />

+ 9 - 0
front/project/www/routes/page/export/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}

+ 9 - 0
front/project/www/routes/page/ready/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}

+ 9 - 0
front/project/www/routes/question/search/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}

+ 9 - 0
front/project/www/routes/question/searchHistory/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}

+ 9 - 0
front/project/www/routes/textbook/main/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}

+ 9 - 0
front/project/www/routes/textbook/topic/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}

+ 9 - 0
front/project/www/routes/textbook/topicDetail/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}

+ 9 - 0
front/project/www/routes/textbook/year/page.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  renderView() {
+    return <div>1</div>;
+  }
+}