Commit 622ad908fb792d66b1f2432c73292c46bbb01944

Authored by ly525
1 parent 71c8884c

add video-gallery as support plugin

front-end/h5/src/components/core/support/index.js
  1 +/*
  2 + * @Author: ly525
  3 + * @Date: 2019-12-01 18:11:50
  4 + * @LastEditors: ly525
  5 + * @LastEditTime: 2020-01-12 20:42:55
  6 + * @FilePath: /luban-h5/front-end/h5/src/components/core/support/index.js
  7 + * @Github: https://github.com/ly525/luban-h5
  8 + * @Description: Do not edit
  9 + * @Copyright 2018 - 2019 luban-h5. All Rights Reserved
  10 + */
1 11 // register-global-support-component
2 12 import Vue from 'vue'
3 13 import PropMultiTextItemsEditor from './prop-multi-items-editor/text.js'
4 14 import ImageGallery from './image-gallery/gallery.js'
  15 +import VideoGallery from './video-gallery/gallery.js'
5 16 import LbpTextAlign from '@luban-h5/lbs-text-align'
6 17  
7 18 Vue.component(PropMultiTextItemsEditor.name, PropMultiTextItemsEditor)
8 19 Vue.component(ImageGallery.name, ImageGallery)
  20 +Vue.component(VideoGallery.name, VideoGallery)
9 21 Vue.component('lbs-text-align', LbpTextAlign)
... ...
front-end/h5/src/components/core/support/video-gallery/components/uploader.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + visible: {
  4 + type: Boolean,
  5 + default: false
  6 + },
  7 + handleClose: {
  8 + type: Function,
  9 + default: () => {}
  10 + },
  11 + uploadSuccess: {
  12 + type: Function,
  13 + default: () => {}
  14 + },
  15 + beforeUpload: {
  16 + type: Function,
  17 + default: (file) => file
  18 + }
  19 + },
  20 + computed: {
  21 + },
  22 + data: () => ({
  23 + loading: false
  24 + }),
  25 + methods: {
  26 + handleBeforeUpload (file) {
  27 + return this.beforeUpload(file)
  28 + },
  29 + handleChange (info) {
  30 + this.loading = true
  31 + const status = info.file.status
  32 + if (status !== 'uploading') {
  33 + console.log(info.file, info.fileList)
  34 + }
  35 + if (status === 'done') {
  36 + this.loading = false
  37 + this.uploadSuccess(info)
  38 + this.$message.success(`${info.file.name} file uploaded successfully.`)
  39 + } else if (status === 'error') {
  40 + this.$message.error(`${info.file.name} file upload failed.`)
  41 + }
  42 + }
  43 + },
  44 + render (h) {
  45 + return (
  46 + <a-upload
  47 + name="files"
  48 + action="/upload"
  49 + beforeUpload={this.handleBeforeUpload}
  50 + onChange={this.handleChange}>
  51 + <slot>
  52 + <a-button>
  53 + <a-icon type="upload" /> Click to Upload
  54 + </a-button>
  55 + </slot>
  56 + </a-upload>
  57 + )
  58 + },
  59 + mounted () {
  60 + }
  61 +}
... ...
front-end/h5/src/components/core/support/video-gallery/components/video-item.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + item: {
  4 + type: Object,
  5 + default: () => ({})
  6 + },
  7 + height: {
  8 + type: Number,
  9 + default: 240
  10 + }
  11 + },
  12 + render (h) {
  13 + return (
  14 + <a-card
  15 + hoverable
  16 + >
  17 + <video
  18 + controls
  19 + slot="cover"
  20 + src={this.item.url || this.item.url}
  21 + style={{
  22 + height: `${this.height}px`
  23 + }}>
  24 + </video>
  25 + </a-card>
  26 + )
  27 + }
  28 +}
... ...
front-end/h5/src/components/core/support/video-gallery/gallery.js 0 → 100644
  1 +import './gallery.scss'
  2 +import PersonalTab from './tabs/personal.js'
  3 +import PixabayTab from './tabs/pixabay.js'
  4 +
  5 +export default {
  6 + name: 'lbs-video-gallery',
  7 + components: {
  8 + },
  9 + props: {
  10 + visible: {
  11 + type: Boolean,
  12 + default: false
  13 + },
  14 + value: {
  15 + type: String,
  16 + default: ''
  17 + }
  18 + },
  19 + data: () => ({
  20 + tabs: [
  21 + {
  22 + value: 'personal',
  23 + label: '我的视频'
  24 + }
  25 + // {
  26 + // value: 'pixabay',
  27 + // label: 'Pixabay图库'
  28 + // }
  29 + ],
  30 + activeTab: 'personal',
  31 + innerVisible: false,
  32 + pixabayList: []
  33 + }),
  34 + computed: {
  35 + },
  36 + watch: {
  37 + visible (value) {
  38 + this.innerVisible = value
  39 + }
  40 + },
  41 + methods: {
  42 + showGallery () {
  43 + this.innerVisible = true
  44 + },
  45 + handleClose () {
  46 + this.innerVisible = false
  47 + },
  48 + changeTab ({ key }) {
  49 + this.activeTab = key
  50 + },
  51 + handleSelectImage (item) {
  52 + this.handleClose()
  53 + this.$emit('change', item.url)
  54 + },
  55 + renderContent () {
  56 + switch (this.activeTab) {
  57 + case 'personal':
  58 + return <PersonalTab onChangeItem={item => {
  59 + this.handleSelectImage(item)
  60 + }}/>
  61 + case 'pixabay':
  62 + return <PixabayTab onChangeItem={item => {
  63 + this.handleSelectImage(item)
  64 + }}/>
  65 + }
  66 + },
  67 + renderDefaultActivator () {
  68 + const activatorWithoutImg = (
  69 + <div
  70 + class="default-activator cursor-pointer empty-bg-activator"
  71 + onClick={this.showGallery}
  72 + >
  73 + <a-icon type="plus" />
  74 + </div>
  75 + )
  76 +
  77 + const activatorWithImg = (
  78 + <div onClick={this.showGallery}>
  79 + <div class="default-activator cursor-pointer "><video src={this.value} width="50%" style={{ margin: 'auto' }} /></div>
  80 + <div class="flex-space-between" style="margin-top: 8px;">
  81 + <a-button size="small">更换</a-button>
  82 + <a-button size="small" onClick={(e) => {
  83 + e.stopPropagation()
  84 + this.handleSelectImage({ url: '' })
  85 + }}>移除</a-button>
  86 + </div>
  87 + </div>
  88 + )
  89 + return (this.value ? activatorWithImg : activatorWithoutImg)
  90 + }
  91 + },
  92 + render (h) {
  93 + return (
  94 + <div>
  95 + <slot>{this.renderDefaultActivator()}</slot>
  96 + <a-modal
  97 + closable
  98 + title="视频库"
  99 + width="65%"
  100 + visible={this.innerVisible}
  101 + onOk={this.handleClose}
  102 + onCancel={this.handleClose}
  103 + bodyStyle={{ margin: 0, padding: 0 }}
  104 + >
  105 + <a-layout style="height: 500px; position: relative;">
  106 + <a-layout-sider width="200px" style="background-color: white;">
  107 + <a-menu mode="inline" defaultSelectedKeys={['personal']} onClick={this.changeTab}>
  108 + {
  109 + this.tabs.map((tab, index) => (
  110 + <a-menu-item key={tab.value} >
  111 + <a-icon type="user" />
  112 + <span>{tab.label}</span>
  113 + </a-menu-item>
  114 + ))
  115 + }
  116 + </a-menu>
  117 + </a-layout-sider>
  118 + <a-layout-content>
  119 + {this.renderContent()}
  120 + </a-layout-content>
  121 + </a-layout>
  122 + </a-modal>
  123 + </div>
  124 + )
  125 + }
  126 +}
... ...
front-end/h5/src/components/core/support/video-gallery/gallery.scss 0 → 100644
  1 +.default-activator {
  2 + border: 1px dashed #eee;
  3 + text-align: center;
  4 +
  5 + img {
  6 + width: 50%;
  7 + border: 1px dashed #ccc;
  8 + }
  9 +}
  10 +
  11 +.empty-bg-activator {
  12 + height: 178px;
  13 + line-height: 178px;
  14 +}
0 15 \ No newline at end of file
... ...
front-end/h5/src/components/core/support/video-gallery/tabs/personal.js 0 → 100644
  1 +/*
  2 + * @Author: ly525
  3 + * @Date: 2020-01-12 20:42:09
  4 + * @LastEditors : ly525
  5 + * @LastEditTime : 2020-01-13 00:39:29
  6 + * @FilePath: /luban-h5/front-end/h5/src/components/core/support/video-gallery/tabs/personal.js
  7 + * @Github: https://github.com/ly525/luban-h5
  8 + * @Description: Do not edit
  9 + * @Copyright 2018 - 2019 luban-h5. All Rights Reserved
  10 + */
  11 +import axios from 'axios'
  12 +import VideoItem from '../components/video-item.js'
  13 +import Uploader from '../components/uploader.js'
  14 +
  15 +export default {
  16 + data: () => ({
  17 + items: [],
  18 + cachedItems: [],
  19 + loading: false
  20 + }),
  21 + methods: {
  22 + uploadSuccess ({ file, fileList }) {
  23 + const response = file.response.length && file.response[0]
  24 + this.items = [{ name: response.name, url: response.url.replace('http://localhost:1337', '') }, ...this.cachedItems]
  25 + },
  26 + beforeUpload (file) {
  27 + this.items.unshift({
  28 + loading: true
  29 + })
  30 + return file
  31 + }
  32 + },
  33 + render (h) {
  34 + return (
  35 + <div>
  36 + <a-spin tip="Loading..." spinning={this.loading}>
  37 + <a-card>
  38 + <Uploader
  39 + slot="extra"
  40 + beforeUpload={file => this.beforeUpload(file)}
  41 + uploadSuccess={info => this.uploadSuccess(info)}
  42 + />
  43 + <a-list
  44 + style="height: 400px; overflow: auto;"
  45 + grid={{ gutter: 12, column: 3 }}
  46 + dataSource={this.items}
  47 + renderItem={(item, index) => (
  48 + <a-list-item onClick={() => {
  49 + this.$emit('changeItem', item)
  50 + }}>
  51 + <VideoItem item={item} />
  52 + </a-list-item>
  53 + )}
  54 + >
  55 + </a-list>
  56 + </a-card>
  57 + </a-spin>
  58 + </div>
  59 + )
  60 + },
  61 + mounted () {
  62 + // demo code
  63 + axios
  64 + .get('/upload/files', {
  65 + params: {
  66 + '_limit': 10,
  67 + '_start': 0,
  68 + mime: 'video/mp4'
  69 + }
  70 + })
  71 + .then(res => {
  72 + this.items = res.data
  73 + this.cachedItems = []
  74 + // this.cachedItems = res.data.hits.slice(0)
  75 + })
  76 + }
  77 +}
... ...
front-end/h5/src/components/core/support/video-gallery/tabs/pixabay.js 0 → 100644
  1 +import axios from 'axios'
  2 +import ImageItem from '../components/image-item.js'
  3 +
  4 +export default {
  5 + data: () => ({
  6 + items: [],
  7 + loading: false,
  8 + options: {
  9 + key: '12120348-2ad26e4cc05d9bc068097ab3b', // pixabay demo key from https://pixabay.com/zh/service/about/api/
  10 + image_type: 'photo',
  11 + pretty: true,
  12 + q: 'yellow+flowers',
  13 + orientation: 'all' // "all", "horizontal", "vertical"
  14 + }
  15 + }),
  16 + computed: {
  17 + isVertial () {
  18 + return this.options.orientation === 'vertical'
  19 + }
  20 + },
  21 + methods: {
  22 + queryAPI () {
  23 + axios
  24 + .get('https://pixabay.com/api/', { params: this.options })
  25 + .then(res => {
  26 + this.items = res.data.hits
  27 + })
  28 + }
  29 + },
  30 + render (h) {
  31 + return (
  32 + <div>
  33 + <a-spin tip="Loading..." spinning={this.loading}>
  34 + <a-card >
  35 + <div slot="extra" style={{ display: 'flex' }}>
  36 + <a-dropdown>
  37 + <a-menu slot="overlay" onClick={({ key }) => {
  38 + this.options.orientation = key
  39 + this.queryAPI()
  40 + }}>
  41 + <a-menu-item key="all"><a-icon type="user" />任意方位</a-menu-item>
  42 + <a-menu-item key="horizontal"><a-icon type="user" />水平</a-menu-item>
  43 + <a-menu-item key="vertical"><a-icon type="user" />竖直</a-menu-item>
  44 + </a-menu>
  45 + <a-button style="margin-left: 8px" type="link">
  46 + 图片方向 <a-icon type="down" />
  47 + </a-button>
  48 + </a-dropdown>
  49 + <a-input-search
  50 + placeholder="input search text"
  51 + onSearch={value => {
  52 + this.options.q = value
  53 + this.queryAPI()
  54 + }}
  55 + />
  56 + </div>
  57 + <a-list
  58 + grid={{ gutter: 12, column: this.isVertial ? 4 : 3 }}
  59 + dataSource={this.items}
  60 + renderItem={(item, index) => (
  61 + <a-list-item onClick={(event /** mouseEvent */) => {
  62 + this.$emit('changeItem', item)
  63 + }}>
  64 + <ImageItem item={item} height={this.isVertial ? 240 : 142 } />
  65 + </a-list-item>
  66 + )}
  67 + >
  68 + </a-list>
  69 + </a-card>
  70 + </a-spin>
  71 + </div>
  72 + )
  73 + },
  74 + mounted () {
  75 + this.queryAPI()
  76 + }
  77 +}
... ...