LIL-645 Выводить в редакторе галереи превью, а не оригиналы изображений

remotes/origin/hotfix/LIL-691
gzbender 7 years ago
parent 85e08aa8a4
commit 490987e210
  1. 2
      api/v1/serializers/mixins.py
  2. 3
      project/templates/blocks/lil_store_js.html
  3. 2
      project/templates/lilcity/edit_index.html
  4. 1
      project/urls.py
  5. 136
      web/src/components/ContestRedactor.vue
  6. 67
      web/src/components/CourseRedactor.vue
  7. 68
      web/src/components/LessonRedactor.vue
  8. 87
      web/src/components/blocks/BlockContent.vue
  9. 25
      web/src/components/blocks/BlockImages.vue
  10. 1
      web/src/components/blocks/Image.vue
  11. 16
      web/src/js/app.js
  12. 17
      web/src/js/contest-redactor.js
  13. 20
      web/src/js/course-redactor.js
  14. 228
      web/src/js/modules/api.js

@ -115,7 +115,7 @@ class DispatchContentMixin(object):
setattr(g, obj_type, obj)
g.save()
if 'images' in cdata:
for image in cdata['images']:
for image in cdata['gallery_images']:
if 'img' in image and image['img']:
if 'id' in image and image['id']:
gi = GalleryImage.objects.get(id=image['id'])

@ -6,6 +6,7 @@
isMobile: {{ request.user_agent.is_mobile|yesno:"true,false" }},
user: {
id: '{{ request.user.id|default:'' }}',
}
},
components: {}
};
</script>

@ -316,12 +316,12 @@
</div>
</div>
{% include 'templates/blocks/lil_store_js.html' %}
<script type="text/javascript" src={% static "app.js" %}></script>
<script>
var schoolDiscount = parseFloat({{ config.SERVICE_DISCOUNT }});
var schoolAmountForDiscount = parseFloat({{ config.SERVICE_DISCOUNT_MIN_AMOUNT }});
</script>
{% block foot %}{% endblock foot %}
<script type="text/javascript" src={% static "app.js" %}></script>
</body>
</html>

@ -55,6 +55,7 @@ urlpatterns = [
path('course/<str:slug>/', CourseView.as_view(), name='course'),
path('course/<int:pk>/checkout', CourseBuyView.as_view(), name='course-checkout'),
path('course/<int:pk>/edit', CourseEditView.as_view(), name='course_edit'),
path('course/<int:pk>/edit/lessons', CourseEditView.as_view(), name='course_edit_lessons'),
path('course/<int:pk>/lessons', CourseView.as_view(template_name='course/course_only_lessons.html', only_lessons=True), name='course-only-lessons'),
path('course/<int:course_id>/like', likes, name='likes'),
path('course/<int:course_id>/comment', coursecomment, name='coursecomment'),

@ -66,45 +66,7 @@
<div class="section__center center">
<div class="kit">
<div class="kit__body">
<vue-draggable v-model="contest.content" @start="drag=true" @end="drag=false" :options="{ handle: '.sortable__handle' }">
<div v-for="(block, index) in contest.content" :key="block.data.id ? block.data.id : block.data.guid">
<block-text v-if="block.type === 'text'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-image-text v-if="block.type === 'image-text'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
:image-id.sync="block.data.image_id"
:image-url.sync="block.data.image_url"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-image v-if="block.type === 'image'"
:index="index"
:title.sync="block.data.title"
:image-id.sync="block.data.image_id"
:image-url.sync="block.data.image_url"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-images v-if="block.type === 'images'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
:images.sync="block.data.images"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-video v-if="block.type === 'video'"
:index="index"
:title.sync="block.data.title"
v-on:remove="onBlockRemoved"
:video-url.sync="block.data.video_url"/>
</div>
</vue-draggable>
<block-add v-on:added="onBlockAdded"/>
<block-content :content.sync="contest.content"></block-content>
</div>
</div>
</div>
@ -113,15 +75,9 @@
</template>
<script>
import BlockText from './blocks/BlockText'
import BlockImage from './blocks/BlockImage'
import BlockImages from './blocks/BlockImages'
import BlockImageText from './blocks/BlockImageText'
import BlockVideo from './blocks/BlockVideo'
import BlockAdd from "./blocks/BlockAdd";
import {api} from "../js/modules/api";
import DatePicker from 'vuejs-datepicker';
import Draggable from 'vuedraggable';
import BlockContent from './blocks/BlockContent'
import slugify from 'slugify';
import {required, minValue, numeric, url } from 'vuelidate/lib/validators'
import _ from 'lodash';
@ -175,18 +131,6 @@
}
},
methods: {
onBlockRemoved(blockIndex) {
const blockToRemove = this.contest.content[blockIndex];
// Удаляем блок из Vue
this.contest.content.splice(blockIndex, 1);
// Если блок уже был записан в БД, отправляем запрос на сервер на удаление блока из БД
if (blockToRemove.data.id) {
api.removeContentBlock(blockToRemove, this.accessToken);
}
},
onBlockAdded(blockData) {
this.contest.content.push(blockData);
},
onTitleInput() {
this.$v.contest.title.$touch();
if (!this.slugChanged) {
@ -219,7 +163,7 @@
id: data.id,
title: data.title,
description: data.description,
content: api.convertContentResponse(data.content),
content: api.convertContentJson(data.content),
date_start: data.date_start,
date_end: data.date_end,
slug: data.slug,
@ -252,70 +196,7 @@
data.date_start = data.date_start ? moment(data.date_start).format('MM-DD-YYYY') : null;
data.date_end = data.date_end ? moment(data.date_end).format('MM-DD-YYYY') : null;
data.cover = this.contest.coverImageId || '';
data.content = this.contest.content.map((block, index) => {
if (block.type === 'text') {
return {
'type': 'text',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'txt': block.data.text,
}
}
} else if (block.type === 'image') {
return {
'type': 'image',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'img': block.data.image_id,
}
}
} else if (block.type === 'image-text') {
return {
'type': 'image-text',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'img': block.data.image_id,
'txt': block.data.text,
}
}
} else if (block.type === 'images') {
return {
'type': 'images',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'images': block.data.images.map((galleryImage) => {
return {
'id': galleryImage.id ? galleryImage.id : null,
'img': galleryImage.img,
}
}),
}
}
} else if (block.type === 'video') {
return {
'type': 'video',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'url': block.data.video_url,
}
}
}
});
data.content = api.convertContentJson(this.contest.content, true);
const request = this.contest.id
? api.put(`/api/v1/contests/${this.contest.id}/`, data, {
@ -343,15 +224,8 @@
}
},
components: {
BlockAdd,
BlockContent,
'vue-datepicker': DatePicker,
'block-text': BlockText,
'block-image': BlockImage,
'block-image-text': BlockImageText,
'block-images': BlockImages,
'block-video': BlockVideo,
'vue-draggable': Draggable,
}
};
</script>

@ -166,45 +166,7 @@
</button>
</div>
<div v-if="viewSection === 'course'" class="kit__body">
<vue-draggable v-model="course.content" @start="drag=true" @end="drag=false" :options="{ handle: '.sortable__handle' }">
<div v-for="(block, index) in course.content" :key="block.data.id ? block.data.id : block.data.guid">
<block-text v-if="block.type === 'text'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-image-text v-if="block.type === 'image-text'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
:image-id.sync="block.data.image_id"
:image-url.sync="block.data.image_url"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-image v-if="block.type === 'image'"
:index="index"
:title.sync="block.data.title"
:image-id.sync="block.data.image_id"
:image-url.sync="block.data.image_url"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-images v-if="block.type === 'images'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
:images.sync="block.data.images"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-video v-if="block.type === 'video'"
:index="index"
:title.sync="block.data.title"
v-on:remove="onBlockRemoved"
:video-url.sync="block.data.video_url"/>
</div>
</vue-draggable>
<block-add v-on:added="onBlockAdded"/>
<block-content :content.sync="course.content"></block-content>
<!--<div class="kit__foot">
<button type="submit" class="kit__submit btn btn_md" v-bind:class="{ loading: courseSaving }">
@ -269,15 +231,10 @@
import { ROLE_ADMIN, ROLE_AUTHOR } from './consts'
import LinkInput from './inputs/LinkInput'
import DatePicker from 'vuejs-datepicker'
import BlockText from './blocks/BlockText'
import BlockImage from './blocks/BlockImage'
import BlockImages from './blocks/BlockImages'
import BlockImageText from './blocks/BlockImageText'
import BlockVideo from './blocks/BlockVideo'
import BlockContent from './blocks/BlockContent'
import LilSelect from "./inputs/LilSelect";
import LessonRedactor from "./LessonRedactor";
import {api} from "../js/modules/api";
import BlockAdd from "./blocks/BlockAdd";
import $ from 'jquery';
import {required, minValue, numeric, url } from 'vuelidate/lib/validators'
import slugify from 'slugify';
@ -493,18 +450,6 @@
});
}
},
onBlockRemoved(blockIndex) {
const blockToRemove = this.course.content[blockIndex];
// Удаляем блок из Vue
this.course.content.splice(blockIndex, 1);
// Если блок уже был записан в БД, отправляем запрос на сервер на удаление блока из БД
if (blockToRemove.data.id) {
api.removeContentBlock(blockToRemove, this.accessToken);
}
},
onBlockAdded(blockData) {
this.course.content.push(blockData);
},
removeLesson(lessonIndex) {
if (!confirm('Вы действительно хотите удалить этот урок?')) {
return;
@ -1127,17 +1072,11 @@
},
components: {
BlockAdd,
LessonRedactor,
LilSelect,
BlockText,
BlockContent,
'link-input': LinkInput,
'vue-datepicker': DatePicker,
'block-text': BlockText,
'block-image': BlockImage,
'block-image-text': BlockImageText,
'block-images': BlockImages,
'block-video': BlockVideo,
'lesson-redactor': LessonRedactor,
'vue-draggable': Draggable,
}

@ -33,44 +33,7 @@
</div>
</div>
</div>
<vue-draggable v-model="lesson.content" @start="drag=true" @end="drag=false" :options="{ handle: '.sortable__handle' }">
<div v-for="(block, index) in lesson.content">
<block-text v-if="block.type === 'text'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-image-text v-if="block.type === 'image-text'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
:image-id.sync="block.data.image_id"
:image-url.sync="block.data.image_url"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-image v-if="block.type === 'image'"
:index="index"
:title.sync="block.data.title"
:image-id.sync="block.data.image_id"
:image-url.sync="block.data.image_url"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-images v-if="block.type === 'images'"
:index="index"
:title.sync="block.data.title"
:text.sync="block.data.text"
:images.sync="block.data.images"
v-on:remove="onBlockRemoved"
:access-token="accessToken"/>
<block-video v-if="block.type === 'video'"
:index="index"
:title.sync="block.data.title"
v-on:remove="onBlockRemoved"
:video-url.sync="block.data.video_url"/>
</div>
</vue-draggable>
<block-add v-on:added="onBlockAdded" />
<block-content :content.sync="lesson.content"></block-content>
<div class="kit__foot">
<button class="kit__submit btn btn_md" v-bind:class="{ loading: saving }">Сохранить</button>
@ -81,12 +44,7 @@
</template>
<script>
import BlockAdd from "./blocks/BlockAdd";
import BlockText from './blocks/BlockText'
import BlockImage from './blocks/BlockImage'
import BlockImages from './blocks/BlockImages'
import BlockImageText from './blocks/BlockImageText'
import BlockVideo from './blocks/BlockVideo'
import BlockContent from './blocks/BlockContent'
import LilImage from "./blocks/Image"
import {api} from "../js/modules/api";
import Draggable from 'vuedraggable';
@ -99,20 +57,6 @@
goBack() {
this.$emit('back');
},
onBlockAdded(blockData) {
this.lesson.content.push(blockData);
this.$emit('update:lesson', this.lesson);
},
onBlockRemoved(blockIndex) {
const blockToRemove = this.lesson.content[blockIndex];
// Удаляем блок из Vue
this.lesson.content.splice(blockIndex, 1);
this.$emit('update:lesson', this.lesson);
// Если блок уже был записан в БД, отправляем запрос на сервер на удаление блока из БД
if (blockToRemove.data.id) {
api.removeContentBlock(blockToRemove, this.accessToken);
}
},
onUpdateCoverUrl(newValue) {
this.lesson.coverImage = newValue;
},
@ -126,13 +70,7 @@
}
},
components: {
BlockAdd,
'block-text': BlockText,
'block-image': BlockImage,
'block-image-text': BlockImageText,
'block-images': BlockImages,
'block-video': BlockVideo,
'vue-draggable': Draggable,
BlockContent,
'lil-image': LilImage,
}
}

@ -0,0 +1,87 @@
<template>
<div>
<vue-draggable :list="content" @start="drag=true" @end="drag=false" :options="{ handle: '.sortable__handle' }">
<div v-for="(block, index) in content" :key="block.id ? block.id : block.uuid">
<block-text v-if="block.type === 'text'"
:index="index"
:title.sync="block.title"
:text.sync="block.text"
v-on:remove="onBlockRemoved"/>
<block-image-text v-if="block.type === 'image-text'"
:index="index"
:title.sync="block.title"
:text.sync="block.text"
:image-id.sync="block.img.id"
:image-url.sync="block.img.image_thumbnail"
v-on:remove="onBlockRemoved"
:access-token="$root.store.accessToken"/>
<block-image v-if="block.type === 'image'"
:index="index"
:title.sync="block.title"
:image-id.sync="block.img.id"
:image-url.sync="block.img.image_thumbnail"
v-on:remove="onBlockRemoved"
:access-token="$root.store.accessToken"/>
<block-images v-if="block.type === 'images'"
:index="index"
:title.sync="block.title"
:text.sync="block.text"
:images.sync="block.gallery_images"
v-on:remove="onBlockRemoved"
:access-token="$root.store.accessToken"/>
<block-video v-if="block.type === 'video'"
:index="index"
:title.sync="block.title"
v-on:remove="onBlockRemoved"
:video-url.sync="block.video_url"/>
</div>
</vue-draggable>
<block-add v-on:added="onBlockAdded"/>
</div>
</template>
<script>
import {api} from "../../js/modules/api";
import Draggable from 'vuedraggable';
import BlockText from './BlockText'
import BlockImage from './BlockImage'
import BlockImages from './BlockImages'
import BlockImageText from './BlockImageText'
import BlockVideo from './BlockVideo'
import BlockAdd from "./BlockAdd"
export default {
name: 'block-content',
props: ['content'],
methods: {
onBlockRemoved(blockIndex) {
const content = this.content;
const blockToRemove = this.content[blockIndex];
// Если блок уже был записан в БД, отправляем запрос на сервер на удаление блока из БД
if (blockToRemove.data.id) {
api.removeContentBlock(blockToRemove, this.$root.store.accessToken).then(response => {
// Удаляем блок из Vue
content.splice(blockIndex, 1);
this.$emit('update:content', content);
});
}
},
onBlockAdded(blockData) {
const content = this.content;
content.push(blockData);
this.$emit('update:content', content);
},
},
components: {
BlockAdd,
'block-text': BlockText,
'block-image': BlockImage,
'block-image-text': BlockImageText,
'block-images': BlockImages,
'block-video': BlockVideo,
'vue-draggable': Draggable,
}
}
</script>

@ -23,7 +23,7 @@
</div>
<div class="kit__gallery">
<div class="kit__preview" v-for="(image, index) in images" v-bind:class="{ 'kit__preview--loading': image.loading }">
<img :src="image.src" class="kit__pic">
<img :src="image.img.image_thumbnail" class="kit__pic">
<button type="button" @click="onRemoveImage(index)">
<svg class="icon icon-delete">
<use xlink:href="/static/img/sprite.svg#icon-delete"></use>
@ -58,20 +58,21 @@
console.log('images before before', JSON.stringify(images));
images.push({
src: reader.result,
img_file: reader.result,
img: {},
loading: true,
});
this.$emit('update:images', images);
// this.$emit('update:images', images);
api.uploadImage(reader.result, this.accessToken)
.then((response) => {
let images = this.images;
console.log('images before', JSON.stringify(images));
images.forEach((image, index) => {
if (image.src === reader.result) {
images[index].img = response.data.id;
if (image.img_file === reader.result) {
images[index].img_file = null;
images[index].img = response.data;
images[index].loading = false;
images[index].src = response.data.image;
}
});
console.log('images after', JSON.stringify(images));
@ -91,12 +92,14 @@
},
onRemoveImage(index) {
let images = this.images;
let id = images[index].img;
images.splice(index, 1);
this.$emit('update:images', images);
let id = images[index].img.id;
api.removeImage(id, this.accessToken);
api.removeImage(id, this.accessToken)
.then(response => {
images.splice(index, 1);
this.$emit('update:images', images);
});
}
}
}
</script>
</script>

@ -18,6 +18,7 @@
data() {
return {
loading: false,
}
},
methods: {

@ -24,17 +24,27 @@ import "../sass/app.sass";
import Vue from 'vue';
import Vuelidate from 'vuelidate';
import VueAutosize from '../components/directives/autosize'
import UploadContestWork from '../components/UploadContestWork.vue';
import ContestWorks from '../components/ContestWorks.vue';
import Likes from '../components/blocks/Likes.vue';
Vue.use(Vuelidate);
Vue.use(VueAutosize);
if (process.env.NODE_ENV === 'development') {
// Enable vue-devtools
Vue.config.devtools = true;
}
const components = {
UploadContestWork,
ContestWorks,
Likes,
};
Object.assign(components, window.LIL_STORE.components);
const app = new Vue({
el: '#lilcity-vue-app',
data() {
@ -42,9 +52,5 @@ const app = new Vue({
store: window.LIL_STORE,
}
},
components: {
UploadContestWork,
ContestWorks,
Likes,
}
components: components
});

@ -1,19 +1,4 @@
import Vue from 'vue'
import Vuelidate from 'vuelidate'
import VueAutosize from '../components/directives/autosize'
import ContestRedactor from '../components/ContestRedactor.vue'
if (process.env.NODE_ENV === 'development') {
// Enable vue-devtools
Vue.config.devtools = true;
}
window.LIL_STORE.components['contest-redactor'] = ContestRedactor;
Vue.use(VueAutosize);
Vue.use(Vuelidate);
let app = new Vue({
el: '#lilcity-vue-app',
components: {
'contest-redactor': ContestRedactor,
}
});

@ -1,24 +1,8 @@
import Vue from 'vue'
import VueAutosize from '../components/directives/autosize'
import Vuelidate from 'vuelidate'
import 'babel-polyfill'
import CourseRedactor from '../components/CourseRedactor.vue'
import $ from 'jquery';
if (process.env.NODE_ENV === 'development') {
// Enable vue-devtools
Vue.config.devtools = true;
}
Vue.use(VueAutosize);
Vue.use(Vuelidate);
let app = new Vue({
el: '#lilcity-vue-app',
components: {
'course-redactor': CourseRedactor,
}
});
window.LIL_STORE.components['course-redactor'] = CourseRedactor;
$(document).ready(function () {
$('#course-redactor__publish-button').on('click', function () {
@ -29,4 +13,4 @@ $(document).ready(function () {
let event = new Event('course_preview');
document.getElementById('lilcity__course-redactor').dispatchEvent(event);
});
});
});

@ -116,72 +116,9 @@ export const api = {
stream: courseObject.stream,
cover: courseObject.coverImageId ? courseObject.coverImageId : null,
gallery: {
gallery_images: courseObject.gallery && courseObject.gallery.images ? courseObject.gallery.images : []
gallery_images: courseObject.gallery && courseObject.gallery.images || []
},
content: courseObject.content.map((block, index) => {
if (block.type === 'text') {
return {
'type': 'text',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'txt': block.data.text,
}
}
} else if (block.type === 'image') {
return {
'type': 'image',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'img': block.data.image_id,
}
}
} else if (block.type === 'image-text') {
return {
'type': 'image-text',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'img': block.data.image_id,
'txt': block.data.text,
}
}
} else if (block.type === 'images') {
return {
'type': 'images',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'images': block.data.images.map((galleryImage) => {
return {
'id': galleryImage.id ? galleryImage.id : null,
'img': galleryImage.img,
}
}),
}
}
} else if (block.type === 'video') {
return {
'type': 'video',
'data': {
'id': block.data.id ? block.data.id : null,
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'url': block.data.video_url,
}
}
}
}),
content: api.convertContentJson(courseObject.content, true),
};
if(courseObject.live) {
@ -209,70 +146,7 @@ export const api = {
short_description: lessonObject.short_description,
course: lessonObject.course_id,
position: lessonObject.position,
content: lessonObject.content.map((block, index) => {
if (block.type === 'text') {
return {
'type': 'text',
'data': {
'id': block.data.id ? block.data.id : null,
'position': ++index,
'title': block.data.title,
'txt': block.data.text,
'uuid': block.uuid,
}
}
} else if (block.type === 'image') {
return {
'type': 'image',
'data': {
'id': block.data.id ? block.data.id : null,
'position': ++index,
'title': block.data.title,
'img': block.data.image_id,
'uuid': block.uuid,
}
}
} else if (block.type === 'image-text') {
return {
'type': 'image-text',
'data': {
'id': block.data.id ? block.data.id : null,
'position': ++index,
'title': block.data.title,
'img': block.data.image_id,
'txt': block.data.text,
'uuid': block.uuid,
}
}
} else if (block.type === 'images') {
return {
'type': 'images',
'data': {
'id': block.data.id ? block.data.id : null,
'position': ++index,
'title': block.data.title,
'images': block.data.images.map((galleryImage) => {
return {
'id': galleryImage.id ? galleryImage.id : null,
'img': galleryImage.img,
}
}),
'uuid': block.uuid,
}
}
} else if (block.type === 'video') {
return {
'type': 'video',
'data': {
'id': block.data.id ? block.data.id : null,
'position': ++index,
'title': block.data.title,
'url': block.data.video_url,
'uuid': block.uuid,
}
}
}
}),
content: api.convertContentJson(lessonObject.content, true),
};
if (isAdding) {
@ -288,7 +162,7 @@ export const api = {
short_description: lessonJSON.short_description,
coverImageId: lessonJSON.cover && lessonJSON.cover.id ? lessonJSON.cover.id : null,
coverImage: lessonJSON.cover && lessonJSON.cover.image ? lessonJSON.cover.image : null,
content: api.convertContentResponse(lessonJSON.content),
content: api.convertContentJson(lessonJSON.content),
position: lessonJSON.position,
}
},
@ -320,11 +194,30 @@ export const api = {
stream: courseJSON.stream,
coverImageId: courseJSON.cover && courseJSON.cover.id ? courseJSON.cover.id : null,
coverImage: courseJSON.cover && courseJSON.cover.image ? courseJSON.cover.image : null,
content: api.convertContentResponse(courseJSON.content),
content: api.convertContentJson(courseJSON.content),
gallery: {images: (courseJSON.gallery) ? courseJSON.gallery.gallery_images:[]},
}
},
convertContentResponse: (contentJson) => {
convertContentJson: (contentJson, forSaving) => {
if(forSaving){
return contentJson.map((block, index) => {
const position = ++index;
const data = Object.assign({position}, block);
if (['image', 'image-text'].indexOf(data.type) > -1) {
data.img = data.img.id;
}
else if (data.type === 'images') {
data.gallery_images = data.gallery_images.map(image => image.id);
}
else if (data.type === 'video') {
data.url = data.video_url;
}
return {
type: block.type,
data: data,
};
});
}
return contentJson.sort((a, b) => {
if (a.position < b.position) {
return -1;
@ -333,67 +226,6 @@ export const api = {
return 1;
}
return 0;
}).map((contentItem) => {
if (contentItem.type === 'text') {
return {
'type': 'text',
'uuid': contentItem.uuid,
'data': {
'id': contentItem.id ? contentItem.id : null,
'title': contentItem.title,
'text': contentItem.txt,
}
}
} else if (contentItem.type === 'image') {
return {
'type': 'image',
'uuid': contentItem.uuid,
'data': {
'id': contentItem.id ? contentItem.id : null,
'title': contentItem.title,
'image_id': (contentItem.img) ? contentItem.img.id:null,
'image_url': (contentItem.img) ? contentItem.img.image:null,
}
}
} else if (contentItem.type === 'image-text') {
return {
'type': 'image-text',
'uuid': contentItem.uuid,
'data': {
'id': contentItem.id ? contentItem.id : null,
'title': contentItem.title,
'image_id': (contentItem.img) ? contentItem.img.id:null,
'image_url': (contentItem.img) ? contentItem.img.image:null,
'text': contentItem.txt,
}
}
} else if (contentItem.type === 'images') {
return {
'type': 'images',
'uuid': contentItem.uuid,
'data': {
'id': contentItem.id ? contentItem.id : null,
'title': contentItem.title,
'images': contentItem.gallery_images.map((galleryImage) => {
return {
'id': galleryImage.id,
'img': galleryImage.img.id,
'src': galleryImage.img.image,
}
}),
}
}
} else if (contentItem.type === 'video') {
return {
'type': 'video',
'uuid': contentItem.uuid,
'data': {
'id': contentItem.id ? contentItem.id : null,
'title': contentItem.title,
'video_url': contentItem.url,
}
}
}
});
},
addCourse: (courseJson, accessToken) => {
@ -456,19 +288,19 @@ export const api = {
let removeUrl;
switch(blockData.type) {
case 'text':
removeUrl = `/api/v1/texts/${blockData.data.id}/`;
removeUrl = `/api/v1/texts/${blockData.id}/`;
break;
case 'image':
removeUrl = `/api/v1/images/${blockData.data.id}/`;
removeUrl = `/api/v1/images/${blockData.id}/`;
break;
case 'image-text':
removeUrl = `/api/v1/image-texts/${blockData.data.id}/`;
removeUrl = `/api/v1/image-texts/${blockData.id}/`;
break;
case 'images':
removeUrl = `/api/v1/galleries/${blockData.data.id}/`;
removeUrl = `/api/v1/galleries/${blockData.id}/`;
break;
case 'video':
removeUrl = `/api/v1/videos/${blockData.data.id}/`;
removeUrl = `/api/v1/videos/${blockData.id}/`;
break;
}
if (!removeUrl) {

Loading…
Cancel
Save