remotes/origin/editis_13-01-19
gzbender 7 years ago
parent 5b603b69bf
commit e1be03f25a
  1. 14
      api/v1/serializers/mixins.py
  2. 31
      api/v1/serializers/user.py
  3. 3
      api/v1/urls.py
  4. 11
      api/v1/views.py
  5. 27
      apps/user/templates/user/edit_gallery.html
  6. 14
      web/src/components/blocks/BlockImages.vue
  7. 47
      web/src/js/app.js
  8. 26
      web/src/js/modules/api.js
  9. 1
      web/webpack.config.js

@ -131,7 +131,7 @@ class DispatchMaterialMixin(object):
class DispatchGalleryMixin(object):
def dispatch_gallery(self, course, gallery):
def dispatch_gallery(self, obj, gallery):
if gallery:
if 'id' in gallery and gallery['id']:
g = Gallery.objects.get(id=gallery['id'])
@ -145,15 +145,19 @@ class DispatchGalleryMixin(object):
)
if 'images' in gallery:
for image in gallery['images']:
if isinstance(image['img'], ImageObject):
img = image['img']
else:
img = ImageObject.objects.get(id=image['img'])
if 'id' in image and image['id']:
gi = GalleryImage.objects.get(id=image['id'])
gi.gallery = g
gi.img = image['img']
gi.img = img
gi.save()
else:
gi = GalleryImage.objects.create(
gallery=g,
img=image['img'],
img=img,
)
course.gallery = g
course.save()
obj.gallery = g
obj.save()

@ -3,8 +3,10 @@ from rest_framework import serializers
from django.contrib.auth import get_user_model
from api.v1.serializers.content import GallerySerializer, GalleryImageSerializer, GalleryImageCreateSerializer
from . import Base64ImageField
from apps.user.models import AuthorRequest
from .mixins import DispatchGalleryMixin
User = get_user_model()
@ -104,3 +106,32 @@ class AuthorRequestSerializer(serializers.ModelSerializer):
'created_at',
'update_at',
)
class UserGallerySerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = (
'gallery',
)
class UserGalleryUpdateSerializer(DispatchGalleryMixin, serializers.ModelSerializer):
images = serializers.ListField()
class Meta:
model = User
fields = (
'images',
)
def update(self, instance, validated_data):
images = validated_data.pop('images', {})
self.dispatch_gallery(instance, {
'id': instance.gallery_id,
'images': images,
})
return instance
def to_representation(self, instance):
return UserGallerySerializer(instance=instance, context=self.context).to_representation(instance)

@ -19,7 +19,7 @@ from .views import (
SchoolScheduleViewSet, LiveLessonViewSet,
PaymentViewSet, ObjectCommentsViewSet,
ContestViewSet, ContestWorkViewSet,
AuthorBalanceUsersViewSet, CaptureEmail)
AuthorBalanceUsersViewSet, CaptureEmail, UserGalleryViewSet)
router = DefaultRouter()
router.register(r'author-requests', AuthorRequestViewSet, base_name='author-requests')
@ -45,6 +45,7 @@ router.register(r'gallery-images', GalleryImageViewSet, base_name='gallery-image
router.register(r'school-schedules', SchoolScheduleViewSet, base_name='school-schedules')
router.register(r'users', UserViewSet, base_name='users')
router.register(r'user-gallery', UserGalleryViewSet, base_name='user-gallery')
router.register(r'contests', ContestViewSet, base_name='contests')
router.register(r'contest-works', ContestWorkViewSet, base_name='contest_works')

@ -4,7 +4,7 @@ from decimal import Decimal
from django.contrib.auth import get_user_model
from django.db.models import Q
from rest_framework import status, views, viewsets, generics
from rest_framework import status, views, viewsets, generics, mixins
from rest_framework.decorators import detail_route, list_route, action, permission_classes, authentication_classes
from rest_framework.response import Response
@ -42,7 +42,7 @@ from .serializers.payment import (
from .serializers.user import (
AuthorRequestSerializer,
UserSerializer, UserPhotoSerializer,
)
UserGallerySerializer, UserGalleryUpdateSerializer)
from .serializers.contest import (
ContestCreateSerializer, ContestSerializer, ContestWorkSerializer, ContestWorkCreateSerializer
)
@ -475,6 +475,13 @@ class UserViewSet(ExtendedModelViewSet):
return Response({'success': False}, status=status.HTTP_400_BAD_REQUEST)
class UserGalleryViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
queryset = User.objects.all()
serializer_class = UserGalleryUpdateSerializer
# FIXME
authentication_classes = []
class SchoolScheduleViewSet(ExtendedModelViewSet):
queryset = SchoolSchedule.objects.all()
serializer_class = SchoolScheduleSerializer

@ -1,15 +1,34 @@
{% extends "templates/lilcity/index.html" %}
{% load static %}
{% block head %}
{{ block.super }}
<style>
.kit__photo {
width: 140px;
height: 140px;
}
</style>
{% endblock head %}
{% block pre_app_js %}
<script>
window.LIL_STORE.components['block-images'] = '../components/BlockImages.vue';
window.LIL_STORE._user_gallery_images = [{% for img in user.gallery.gallery_images.all %}{
image_thumbnail_url: '{{ img.image_thumbnail_url }}',
image_id: {{ img.id }},
id: {{ img.id }},
image_thumbnail_url: '{{ img.img.image_thumbnail.url }}',
image_id: {{ img.img.id }},
},{% endfor %}];
</script>
<script src="{% static 'userGalleryEdit.js' %}"></script>
{% endblock pre_app_js %}
{% block content %}
<block-images :images="$root.store._user_gallery_images" :access-token="$root.store.accessToken"/>
<div class="section section_gray">
<div class="section__center center center_sm">
<div>
<block-images :images="$root.store._user_gallery_images" :access-token="$root.store.accessToken" no-title="1"/>
</div>
<a href="#" id="gallery-save" class="btn">Сохранить</a>
</div>
</div>
{% endblock %}

@ -1,6 +1,6 @@
<template>
<div>
<div class="kit__field field">
<div v-if="! noTitle" class="kit__field field">
<div class="field__wrap field__wrap--title">
<input :readonly="readOnly" type="text"
:value="title"
@ -33,7 +33,7 @@
export default {
name: "block-images",
props: ["index", "title", "images", "accessToken", "readOnly", "longSide"],
props: ["index", "title", "images", "accessToken", "readOnly", "longSide", "noTitle"],
methods: {
onTitleChange(event) {
this.$emit('update:title', event.target.value);
@ -46,7 +46,6 @@
let images = this.images;
images.push({
src: reader.result,
loading: true,
});
this.$emit('update:images', images);
@ -59,15 +58,6 @@
images[index].loading = false;
images[index].image_url = response.data.image;
images[index].image_thumbnail_url = response.data.image_thumbnail;
/* images.forEach((image, index) => {
if (image.src === reader.result) {
images[index].image_id = response.data.id;
images[index].loading = false;
images[index].image_url = response.data.image;
images[index].image_thumbnail_url = response.data.image_thumbnail;
}
}); */
this.$emit('update:images', images);
})
.catch((error) => {

@ -46,33 +46,22 @@ const components = {
Object.assign(components, window.LIL_STORE.components);
const promises = [];
(async () => {
for(let k in components){
if(typeof components[k] === 'string'){
components[k] = await import(components[k]);
}
}
const app = new Vue({
el: '#lilcity-vue-app',
data() {
return {
store: window.LIL_STORE,
}
},
mounted(){
if(this.urlIs('userProfileEdit') || this.urlIs('userBonuses')){
profileMain(this);
}
const app = new Vue({
el: '#lilcity-vue-app',
data() {
return {
store: window.LIL_STORE,
}
},
mounted(){
if(this.urlIs('userProfileEdit') || this.urlIs('userBonuses')){
profileMain(this);
}
},
methods: {
urlIs(urlPatternName){
return window.location.pathname.search(this.store.urls[urlPatternName]) > -1;
},
methods: {
urlIs(urlPatternName){
return window.location.pathname.search(this.store.urls[urlPatternName]) > -1;
},
},
components: components
});
})();
},
components: components
});

@ -199,6 +199,14 @@ export const api = {
gallery: {images: (courseJSON.gallery) ? courseJSON.gallery.gallery_images:[]},
}
},
convertGalleryImagesJson: (images) => {
return images.map((galleryImage) => {
return {
'id': galleryImage.id ? galleryImage.id : null,
'img': galleryImage.image_id,
}
});
},
convertContentJson: (contentJson, forSaving) => {
if(forSaving){
return contentJson.map((block, index) => {
@ -244,12 +252,7 @@ export const api = {
'uuid': block.uuid,
'position': ++index,
'title': block.data.title,
'images': block.data.images.map((galleryImage) => {
return {
'id': galleryImage.id ? galleryImage.id : null,
'img': galleryImage.image_id,
}
}),
'images': api.convertGalleryImagesJson(block.data.images),
}
}
} else if (block.type === 'video') {
@ -486,5 +489,14 @@ export const api = {
'Authorization': `Token ${window.LIL_STORE.accessToken}`,
}
});
}
},
saveUserGallery: (images) => {
return api.patch(`/api/v1/user-gallery/${window.LIL_STORE.user.id}/`, {
images: api.convertGalleryImagesJson(images),
}, {
headers: {
'Authorization': `Token ${window.LIL_STORE.accessToken}`,
}
});
},
};

@ -10,6 +10,7 @@ module.exports = {
app: "./src/js/app.js",
courseRedactor: "./src/js/course-redactor.js",
contestRedactor: "./src/js/contest-redactor.js",
userGalleryEdit: "./src/js/user-gallery-edit.js",
mixpanel: "./src/js/third_party/mixpanel-2-latest.js",
sprite: glob('./src/icons/*.svg'),
images: glob('./src/img/*.*'),

Loading…
Cancel
Save