From a1c391271ed17e40be02e027f81416b1f8bf0830 Mon Sep 17 00:00:00 2001 From: gzbender Date: Wed, 24 Oct 2018 18:54:21 +0500 Subject: [PATCH] =?UTF-8?q?LIL-684=20=D0=9F=D1=80=D0=BE=D1=81=D0=BC=D0=BE?= =?UTF-8?q?=D1=82=D1=80=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BD=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D1=83=D1=80=D0=BE=D0=BA=D0=B0=20-=20=D0=94=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D1=84=D0=BE=D1=80=D0=BC=D1=83?= =?UTF-8?q?=20=D0=B7=D0=B0=D1=85=D0=B2=D0=B0=D1=82=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=87=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/urls.py | 3 +- api/v1/views.py | 43 ++++++ .../templates/blocks/schedule_item.html | 4 +- .../templates/blocks/popup_capture_email.html | 28 ++++ .../templates/blocks/popup_school_buy.html | 2 +- project/templates/blocks/teachers.html | 2 +- project/templates/lilcity/index.html | 1 + web/package.json | 2 +- web/src/js/app.js | 2 - web/src/js/modules/api.js | 7 + web/src/js/modules/popup.js | 132 +++++++++++++++++- web/src/js/utils.js | 6 + web/src/sass/_common.sass | 7 + 13 files changed, 224 insertions(+), 15 deletions(-) create mode 100644 project/templates/blocks/popup_capture_email.html diff --git a/api/v1/urls.py b/api/v1/urls.py index 69a56e18..68a96ea2 100644 --- a/api/v1/urls.py +++ b/api/v1/urls.py @@ -19,7 +19,7 @@ from .views import ( SchoolScheduleViewSet, LiveLessonViewSet, PaymentViewSet, ObjectCommentsViewSet, ContestViewSet, ContestWorkViewSet, - AuthorBalanceUsersViewSet) + AuthorBalanceUsersViewSet, CaptureEmail) router = DefaultRouter() router.register(r'author-requests', AuthorRequestViewSet, base_name='author-requests') @@ -64,6 +64,7 @@ schema_view = get_schema_view( ) urlpatterns = [ + path('capture-email/', CaptureEmail.as_view(), name='capture-email'), path('author-balance-users/', AuthorBalanceUsersViewSet.as_view(), name='author-balance-users'), path('api-token-auth/', ObtainToken.as_view(), name='api-token-auth'), path('temp-auth-token/', ObtainTempToken.as_view(), name='temp-auth-token'), diff --git a/api/v1/views.py b/api/v1/views.py index f792972b..bb7a0aca 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -1,3 +1,4 @@ +import json from datetime import datetime from decimal import Decimal @@ -71,6 +72,7 @@ from apps.payment.models import ( from apps.school.models import SchoolSchedule, LiveLesson from apps.user.models import AuthorRequest from project.pusher import pusher +from project.sengrid import get_sendgrid_client User = get_user_model() @@ -656,3 +658,44 @@ class ContestWorkViewSet(ExtendedModelViewSet): if ContestWork.objects.filter(user=user).exists(): return Response(status=status.HTTP_400_BAD_REQUEST) return super().create(request, *args, **kwargs) + + +class CaptureEmail(views.APIView): + authentication_classes = () + + def post(self, request): + list_id = None + list_name = 'captured-emails' + recipient_id = None + email = request.data.get('email') + sg = get_sendgrid_client() + + # берем все списки + response = sg.client.contactdb.lists.get() + if response.status_code != 200: + return Response({'error': 'Cannot get list of lists'}, status=status.HTTP_400_BAD_REQUEST) + # ищем нужный список + for sg_list in response.to_dict.get('lists'): + if sg_list.get('name') == list_name: + list_id = sg_list.get('id') + break + # не нашли - создаем + if not list_id: + response = sg.client.contactdb.lists.post(request_body={'name': list_name}) + if response.status_code != 201: + return Response({'error': 'List was not created'}, status=status.HTTP_400_BAD_REQUEST) + list_id = response.to_dict.get('id') + # добавляем получателя + response = sg.client.contactdb.recipients.patch(request_body=[{ + 'email': email, + }]) + if response.status_code != 201: + return Response({'error': 'Cannot update recipients'}, status=status.HTTP_400_BAD_REQUEST) + recipient_id = response.to_dict.get('persisted_recipients')[0] + # добавляем получателя в отдельный список + response = sg.client.contactdb.lists._(list_id).recipients._(recipient_id).post() + if response.status_code != 201: + return Response({'error': 'Cannot add recipient to list'}, status=status.HTTP_400_BAD_REQUEST) + + return Response({'status': 'ok'}) + diff --git a/apps/school/templates/blocks/schedule_item.html b/apps/school/templates/blocks/schedule_item.html index 00d00d70..17a1bcce 100644 --- a/apps/school/templates/blocks/schedule_item.html +++ b/apps/school/templates/blocks/schedule_item.html @@ -5,7 +5,7 @@
{{ school_schedule }} {% if not is_purchased and request.user_agent.is_mobile and school_schedule.trial_lesson %} - Пробный урок + Пробный урок {% endif %}
{% if is_purchased and live_lesson %} @@ -21,7 +21,7 @@ {% include './day_pay_btn.html' %} {% endif %} {% if not is_purchased and not request.user_agent.is_mobile and school_schedule.trial_lesson %} - Пробный урок + Пробный урок {% endif %} diff --git a/project/templates/blocks/popup_capture_email.html b/project/templates/blocks/popup_capture_email.html new file mode 100644 index 00000000..5eee0add --- /dev/null +++ b/project/templates/blocks/popup_capture_email.html @@ -0,0 +1,28 @@ +{% load static %} + diff --git a/project/templates/blocks/popup_school_buy.html b/project/templates/blocks/popup_school_buy.html index 7178b415..a20ef53d 100644 --- a/project/templates/blocks/popup_school_buy.html +++ b/project/templates/blocks/popup_school_buy.html @@ -45,7 +45,7 @@ Куплено {% else %} {% if school_schedule.trial_lesson %} - Пробный урок + Пробный урок {% endif %} {% endif %} diff --git a/project/templates/blocks/teachers.html b/project/templates/blocks/teachers.html index 32b022bd..8c3b0b7e 100644 --- a/project/templates/blocks/teachers.html +++ b/project/templates/blocks/teachers.html @@ -25,7 +25,7 @@ {% endif %} {% if teacher.trial_lesson %} - ПРОБНЫЙ УРОК + ПРОБНЫЙ УРОК {% endif %}
diff --git a/project/templates/lilcity/index.html b/project/templates/lilcity/index.html index 70189e29..60d189f9 100644 --- a/project/templates/lilcity/index.html +++ b/project/templates/lilcity/index.html @@ -147,6 +147,7 @@ {% endif %} {% include "templates/blocks/popup_course_lock.html" %} {% include "templates/blocks/popup_subscribe.html" %} + {% include "templates/blocks/popup_capture_email.html" %}
{% include 'templates/blocks/lil_store_js.html' %} diff --git a/web/package.json b/web/package.json index ea8ef31f..f2c6d260 100755 --- a/web/package.json +++ b/web/package.json @@ -48,7 +48,7 @@ "jquery": "^3.3.1", "js-cookie": "^2.2.0", "lodash.debounce": "^4.0.8", - "modal-video": "^2.4.2", + "modal-video": "git+https://github.com/gzbender/modal-video.git", "moment": "^2.20.1", "owl.carousel": "^2.2.0", "slugify": "^1.2.9", diff --git a/web/src/js/app.js b/web/src/js/app.js index 2713baeb..7a24f77a 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -3,8 +3,6 @@ */ import 'ilyabirman-likely/release/likely.js'; import 'ilyabirman-likely/release/likely.css'; -import "modal-video/js/jquery-modal-video.min.js"; -import "modal-video/css/modal-video.min.css"; import "./modules/common"; import "./modules/header"; import "./modules/search"; diff --git a/web/src/js/modules/api.js b/web/src/js/modules/api.js index bc6f2292..7b933fa6 100644 --- a/web/src/js/modules/api.js +++ b/web/src/js/modules/api.js @@ -479,5 +479,12 @@ export const api = { 'Authorization': `Token ${window.LIL_STORE.accessToken}`, } }); + }, + captureEmail: (email) => { + return api.post('/api/v1/capture-email/', {email}, { + headers: { + 'Authorization': `Token ${window.LIL_STORE.accessToken}`, + } + }); } }; diff --git a/web/src/js/modules/popup.js b/web/src/js/modules/popup.js index 286797c6..22f27ffb 100644 --- a/web/src/js/modules/popup.js +++ b/web/src/js/modules/popup.js @@ -1,11 +1,66 @@ import $ from 'jquery'; import moment from 'moment'; import {api} from './api'; +import "modal-video/js/jquery-modal-video.js"; +import "modal-video/css/modal-video.min.css"; +import {email as emailValid} from 'vuelidate/lib/validators'; +import Cookies from 'js-cookie' moment.locale('ru'); var selectedWeekdays = {}; $(document).ready(function () { + let body = $('body'), + popup = $('.popup.visible.open'), + prevPopup = null; + + // CAPTURE EMAIL + const EMAIL_CAPTURED_COOKIE = 'email-captured'; + + if(window.LIL_STORE.user.id){ + Cookies.remove(EMAIL_CAPTURED_COOKIE); + } + + $('.js-popup-capture-email .js-popup-close').on('click', function(e){ + e.preventDefault(); + hidePopup().then(() => { + popup = prevPopup; + }); + $('.modal-video').remove(); + }); + + const captureEmail = (callback) => { + prevPopup = popup; + popup = $('.js-popup-capture-email'); + const $modalVideo = $('.modal-video'); + const $email = popup.find('.capture-email__email'); + const $error = popup.find('.capture-email__error'); + $modalVideo.css('opacity', 0); + $email.val(''); + $error.text(''); + popup.css('z-index', 1000001); + showPopup(); + popup.find('.capture-email__btn').unbind('click').click(e => { + e.preventDefault(); + const email = $email.val(); + if(! email){ + $error.text('Пожалуйста, укажите почту'); + return; + } + if(! emailValid(email)){ + $error.text('Пожалуйста, укажите коректную почту'); + return; + } + api.captureEmail(email); + hidePopup().then(() => { + popup = prevPopup; + }); + $modalVideo.css('opacity', 1); + Cookies.set(EMAIL_CAPTURED_COOKIE, 1); + callback(); + }); + }; + $(".js-video-modal").each(function(){ const $this = $(this); const url = $this.data('videoUrl'); @@ -31,11 +86,65 @@ $(document).ready(function () { } $this.attr('data-video-id', videoId); $this.attr('data-video-url', ''); - $this.modalVideo({ channel }); + $this.attr('data-channel', channel); + $this.modalVideo({ channel, jsapi: true }); }); - let body = $('body'), - popup = $('.popup.visible.open'); + $(".js-video-modal").on('player-created', e => { + if(window.LIL_STORE.user.id || ! $(e.target).data('trialLesson') || Cookies.get(EMAIL_CAPTURED_COOKIE)){ + return; + } + let stopVideo = () => {}; + let playVideo = () => {}; + const channel = $(e.target).data('channel'); + const $iframe = $('.modal-video-movie-wrap iframe'); + const player = e.detail.player; + let timeout = null; + const interval = 1000 * 10;// 60 * 2; // 2 min + if(channel == 'youtube'){ + const pauseVideo = () => { + clearTimeout(timeout); + if(! $('.modal-video').length){ + return; + } + player.pauseVideo(); + captureEmail(() => { + player.playVideo(); + }); + } + window.onYTPlayerStateChange = (event) => { + if(event.data == YT.PlayerState.PLAYING && ! timeout){ + timeout = setTimeout(pauseVideo, interval); + } + if(event.data == YT.PlayerState.ENDED && timeout){ + clearTimeout(timeout); + } + } + player.addEventListener('onStateChange', 'onYTPlayerStateChange'); + } + else if (channel == 'vimeo'){ + const pauseVideo = () => { + clearTimeout(timeout); + if(! $('.modal-video').length){ + return; + } + player.pause(); + captureEmail(() => { + player.play(); + }); + } + player.on('play', () => { + if(! timeout){ + timeout = setTimeout(pauseVideo, interval); + } + }) + player.on('ended', () => { + if(timeout){ + clearTimeout(timeout); + } + }); + } + }); body.on('click', '[data-popup]', function(e){ const $this = $(this); @@ -50,7 +159,6 @@ $(document).ready(function () { showPopup(); if(data === '.js-popup-buy') { - console.log('reset selected'); popup.data('date-start', $this.data('date-start') || ''); popup.data('day', $this.data('day') || ''); $('[data-day]').prop('checked', false); @@ -140,12 +248,15 @@ $(document).ready(function () { }); $('.js-popup-close').on('click', function(e){ + if(popup.data('manual-close')){ + return; + } e.preventDefault(); hidePopup(); }); body.on('click', '.js-outer', function(){ - if (popup !== undefined) { + if (popup !== undefined && ! popup.data('manual-close')) { hidePopup(); } }); @@ -155,16 +266,22 @@ $(document).ready(function () { }); $(document).keyup(function(e){ - if (e.keyCode === 27) hidePopup(); + if (e.keyCode === 27 && ! popup.data('manual-close')) { + hidePopup(); + } }); - function showPopup(){ + function showPopup(popupName){ + if(! popup && popupName){ + popup = $(popupName); + } body.addClass('no-scroll'); popup.addClass('open'); return new Promise((resolve) => { setTimeout(function(){ popup.addClass('visible'); resolve(); + $(document).trigger('popup-opened', popup); }, 100); }); } @@ -181,6 +298,7 @@ $(document).ready(function () { setTimeout(function(){ popup.removeClass('open'); resolve(); + $(document).trigger('popup-closed', popup); }, 300); }); } diff --git a/web/src/js/utils.js b/web/src/js/utils.js index 0039ba47..0cc69907 100644 --- a/web/src/js/utils.js +++ b/web/src/js/utils.js @@ -3,3 +3,9 @@ export const rupluralize = (value, args) => { digit = digit[digit.length - 1]; return value + ' ' + args[digit == '1' ? 0 : ('234'.search(digit) > -1 ? 1 : 2)]; } + +export const loadScript = (url, onload) => { + const tag = document.createElement('script'); + tag.url = url; + document.getElementsByTagName('body'); +} diff --git a/web/src/sass/_common.sass b/web/src/sass/_common.sass index 6cecc9c0..feb8e121 100755 --- a/web/src/sass/_common.sass +++ b/web/src/sass/_common.sass @@ -827,6 +827,11 @@ a[name] +t text-align: center +.subtitle2 + margin-bottom: 20px + font-size: 18px + font-weight: bold + .text position: relative max-width: 620px @@ -2383,6 +2388,8 @@ a.grey-link border-radius: 3px transform: scale(.9) transition: transform .2s + &_sm + max-width: 500px &_md max-width: 620px &_lg