Skip to content

Instantly share code, notes, and snippets.

@Insayt
Created January 18, 2019 10:49
Show Gist options
  • Save Insayt/2ddb94ea188a2d76cb1a71c56f4008a5 to your computer and use it in GitHub Desktop.
Save Insayt/2ddb94ea188a2d76cb1a71c56f4008a5 to your computer and use it in GitHub Desktop.
<template>
<div class="add-task">
<div class="card">
<div class="card-body">
<form @submit.prevent="savePost">
<div class="add-task-form">
<div class="add-task-form__left">
<div class="upload-file"
:class="{ disabled: finalImages.length >= 10 || (stories && finalImages.length >= 1), '_full': stories }">
<label for="exampleFormControlFile1">
<div class="upload-file__drop" ref="fileform" :class="{higlight: higlightFileDrop}">
<div class="upload-file__drop-zone" @drop.prevent="onFileChange"
@dragover.prevent></div>
<img class="upload-file__icon" src="/i/icons/drop-icon.svg"
v-show="!higlightFileDrop">
<img class="upload-file__icon" src="/i/icons/drop-icon-blue.svg"
v-show="higlightFileDrop">
<div class="upload-file__drop-title">Перетащите фото и видео</div>
<div class="upload-file__drop-or" v-show="!higlightFileDrop">или</div>
<div class="t-button upload-file__drop-btn" v-show="!higlightFileDrop">
<span class="t-button__name">
Выберите файл
</span>
</div>
</div>
</label>
<input
type="file"
accept="image/*, video/*"
class="form-control-file"
id="exampleFormControlFile1"
@change="onFileChange"
>
</div>
<div class="post-info" v-if="!stories">
<div class="add-task-form__text-wrap">
<div class="add-task-form__emoji">
<emoji-picker :onClick="handleEmojiPicker"/>
<span class="icon-smile"></span>
</div>
<textarea
class="text-field _dark-color post-text"
placeholder="Введите описание поста"
maxlength="2000"
v-model="text"
wrap="soft"
></textarea>
</div>
<div class="count-badge-wrap">
<span class="count-badge-wrap__item">
<span class="count-badge">{{ symbols }}</span> симоволов осталось.
</span>
<span class="count-badge-wrap__item">
<span class="count-badge">{{ hashtags }}</span> хэштегов осталось
</span>
</div>
</div>
</div>
<div class="add-task-form__right">
<div class="form-group">
<datetime
v-if="showCalendar"
v-model="datetime"
type="datetime"
class="theme-inline"
:inline="true"
:zone="timezone"
:phrases="{ok: 'Ок', cancel: 'Отмена'}"
:min-datetime="new Date().toISOString()"
></datetime>
</div>
</div>
</div>
<div class="preview-photos">
<div class="add-task-image-wrap" v-for="(item, $index) in finalImages">
<div class="add-task-image-wrap__content" v-if="item.type === 'image'"
:style="{ backgroundImage: 'url(' + item.src + ')' }">
<button class="add-task-image__delete" @click.prevent="removeImage($index)">
<span>&times;</span>
</button>
</div>
<div class="add-task-image-wrap__content" v-if="item.type === 'video'">
<video class="add-task-video" :src="item.src"></video>
<button class="add-task-image__delete" @click.prevent="removeImage($index)">
<span>&times;</span>
</button>
</div>
</div>
<div v-if="finalImagesLoading">
<div id="floatingCirclesG">
<div class="f_circleG" id="frotateG_01"></div>
<div class="f_circleG" id="frotateG_02"></div>
<div class="f_circleG" id="frotateG_03"></div>
<div class="f_circleG" id="frotateG_04"></div>
<div class="f_circleG" id="frotateG_05"></div>
<div class="f_circleG" id="frotateG_06"></div>
<div class="f_circleG" id="frotateG_07"></div>
<div class="f_circleG" id="frotateG_08"></div>
</div>
</div>
</div>
<div class="controls-mobile">
<div class="add-task-form__text-wrap _mobile" v-if="!stories">
<div class="add-task-form__emoji">
<emoji-picker :onClick="handleEmojiPicker"/>
<span class="icon-smile"></span>
</div>
<textarea
class="text-field _dark-color post-text_mobile"
placeholder="Введите описание поста"
maxlength="2200"
v-model="text"
></textarea>
</div>
<div class="form-group">
<datetime
v-if="showCalendar"
v-model="datetime"
type="datetime"
class="theme-inline"
:inline="true"
:zone="timezone"
:phrases="{ok: 'Ок', cancel: 'Отмена'}"
:min-datetime="new Date().toISOString()"
></datetime>
</div>
</div>
<div class="add-task-bottom">
<form class="form-inline" v-if="!stories">
<t-onoff v-model="isDelete" secondary>Автоудаление поста через
<t-help>При необходимости выставите автоудаление поста через N времени. То есть, после
выкладки поста в профиль, он будет удален через определенное время. Очень актуально
для рекламных постов
</t-help>
</t-onoff>
<input :disabled="!isDelete" v-model.number="deletenum" min="1" type="number"
class="text-field">
<div class="t-select">
<select :disabled="!isDelete" v-model="deleteRange" class="t-select__select">
<option value="minutes">{{ declOfNum(deletenum, ['минуту', 'минуты', 'минут']) }}
</option>
<option value="hours">{{ declOfNum(deletenum, ['час', 'часа', 'часов']) }}</option>
<option value="days">{{ declOfNum(deletenum, ['день', 'дня', 'дней']) }}</option>
<option value="week">{{ declOfNum(deletenum, ['неделю', 'недели', 'недель']) }}
</option>
</select>
</div>
<span class="geo-button" @click="openGeoModal">
<span v-if="!selectedGeo.title">Укажите место</span>
<span v-if="selectedGeo.title">{{ selectedGeo.title }}</span>
<span class="geo-button__close" @click.stop="deleteGeo"
v-if="selectedGeo.title">×</span>
</span>
</form>
<button type="button" class="pull-right t-button _grey" @click.prevent.stop="cancelEditMode"
v-if="editMode">
<span class="t-button__name">Отмена</span>
</button>
<button type="submit" class="pull-right t-button"
:disabled="!finalImages.length || !datetime || saveProcess || hashtags < 0">
<span class="t-button__name" v-if="!editMode && !stories">Запланировать пост</span>
<span class="t-button__name" v-if="!editMode && stories">Запланировать сторис</span>
<span class="t-button__name" v-if="editMode">Отредактировать</span>
</button>
</div>
</form>
</div>
</div>
<b-modal ref="geoModalRef"
hide-footer
title="Укажите геолокацию поста"
class="geo-modal"
>
<div>
<t-selector class="geo-modal__list" :items="geoViews" v-model="geoViewType"></t-selector>
<div class="geo-bar__form">
<div class="geo-bar__form__l-column">
<div class="fieldset">
<div class="fieldset__control">
<t-input placeholder="Укажите город или населенный пункт" icon="www" ref="geoinput"
id="googlesuggest"></t-input>
</div>
</div>
<div class="fieldset">
<div class="fieldset__control">
<t-input v-model="hash_tag_input" placeholder="Укажите название места" icon="pin"
ref="placesinput" @input="fbSearch"></t-input>
</div>
</div>
</div>
</div>
<div class="geo-bar__list founded-list" :class="{'_visible': geoViewType === 'list'}"
v-if="fbgeofound.length">
<template v-for="geotag in fbgeofound">
<div class="founded-list__item" :class="{ _active: geotag.id === preSelectedGeo.id }">
<div class="founded-list__name">{{geotag.title}}, {{geotag.address}}</div>
<div class="founded-list__add"><span class="cta-icon icon-plus"
@click="addToGeo(geotag)"></span></div>
</div>
</template>
</div>
<div class="geo-bar__map" :class="{'_visible': geoViewType === 'map'}">
<p>
<span v-if="preSelectedGeo.title">Выбранно место: {{ preSelectedGeo.title }}, {{ preSelectedGeo.address }}</span>
</p>
<div class="gmap" id="gmap" ref="geomap"></div>
</div>
<button class="t-button _block" @click="addFinalGeo">
<span class="t-button__name">Добавить геолокацию</span>
</button>
</div>
</b-modal>
<b-modal ref="myModalRef"
no-close-on-backdrop
size="lg"
hide-footer
title="Загрузка"
@shown="modalShow"
@hidden="modalHide"
>
<div v-if="uploadStep === 1">
<div class="crop-wrapper">
<div class="crop-alert" v-if="video.file">
Видео длинее 1 минуты будут автоматически обрезаны
</div>
<div class="add-task-image-wrap">
<img id="croppr" class="add-task-image">
</div>
<div class="mt-1" v-if="!finalImages.length && !stories">
Соотношение сторон:
<div class="mt-1">
<button class="t-button _medium _secondary" @click="setAspectRatio(1)">
<span class="t-button__name">1:1</span>
</button>
<button class="t-button _medium _secondary" @click="setAspectRatio(16 / 9)">
<span class="t-button__name">16:9</span>
</button>
<button class="t-button _medium _secondary" @click="setAspectRatio(8 / 10)">
<span class="t-button__name">8:10</span>
</button>
</div>
</div>
</div>
<button class="mt-2 pull-right t-button _medium" @click="cropImage">
<span class="t-button__name">Дальше</span>
</button>
<div class="clearfix"></div>
</div>
<div v-if="uploadStep === 2">
<button class="filter-btn t-button _medium" @click="applyFilter('normal')">
<span class="t-button__name">Без фильтра</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('clarendon')">
<span class="t-button__name">Clarendon</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('juno')">
<span class="t-button__name">Juno</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('lark')">
<span class="t-button__name">Lark</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('ludwig')">
<span class="t-button__name">Ludwig</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('gingham')">
<span class="t-button__name">Gingham</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('valencia')">
<span class="t-button__name">Valencia</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('xpro2')">
<span class="t-button__name">X-Pro-2</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('lofi')">
<span class="t-button__name">Lo-Fi</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('amaro')">
<span class="t-button__name">Amaro</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('brooklyn')">
<span class="t-button__name">Brooklyn</span>
</button>
<button class="filter-btn t-button _medium" @click="applyFilter('willow')">
<span class="t-button__name">Willow</span>
</button>
<div class="image-filter-wrap">
<img id="image-filter" class="cropped-image" :src="croppedImage">
</div>
<button class="mt-2 pull-right t-button _medium" @click="saveImage">
<span class="t-button__name">Сохранить</span>
</button>
<div class="clearfix"></div>
</div>
</b-modal>
<video hidden id="t-video" controls></video>
<canvas hidden id="t-canvas"></canvas>
</div>
</template>
<script>
import {DateTime} from 'luxon';
import Cropper from 'cropperjs';
import axios from 'axios';
import config from 'config';
import debounce from 'lodash/debounce';
import GoogleMapsApiLoader from 'google-maps-api-loader';
const MAX_POST_SIZE = 2000;
const MAX_HASH_TAGS = 30;
let base64;
export default {
props: ['stories'],
components: {DateTime},
data: () => ({
editMode: false,
text: '',
video: {
file: null,
base64: null
},
croppedImage: '',
filteredImage: '',
finalImages: [],
datetime: new Date().toISOString(),
isDelete: false,
datedel: '',
deletenum: 1,
formData: new FormData(),
cropper: {},
uploadStep: 1,
aspectRatio: 1,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
deleteRange: 'minutes',
finalImagesLoading: false,
firebaseId: null,
saveProcess: false,
higlightFileDrop: false,
showCalendar: true,
hash_tag_input: '',
geoViews: [
{name: 'Списком', icon: 'list', value: 'list'},
{name: 'На карте', icon: 'pin', value: 'map'}
],
geoViewType: 'list',
google: null,
map: null,
fbgeofound: [],
fbWindows: [],
initPosition: {
lat: 55.755826,
lng: 37.6173
},
preSelectedGeo: {},
selectedGeo: {}
}),
mounted () {
this.$bus.$on('edit-post', (post, isNew) => {
if (isNew) {
this.datetime = DateTime.fromMillis(post.timestamp).toISO();
this.showCalendar = false;
this.$nextTick(() => {
this.showCalendar = true;
});
return;
}
this.text = post.text;
this.finalImages = post.media;
this.timezone = post.timezone;
this.datetime = DateTime.fromMillis(post.datetime, {zone: post.timezone}).toISO();
if (post.location) {
this.selectedGeo = {
title: post.location.name,
lat: post.location.lat,
lng: post.location.lng,
facebook_places_id: post.facebook_places_id,
location: post.location
};
}
if (post.deletenum) {
this.isDelete = true;
this.datedel = post.datedel;
this.deletenum = post.deletenum;
this.deleteRange = post.deleteRange;
}
this.firebaseId = post.id;
this.editMode = true;
this.showCalendar = false;
setTimeout(() => {
this.showCalendar = true;
})
});
['dragenter', 'dragover'].forEach(eventName => {
this.$refs.fileform.addEventListener(eventName, () => {
this.higlightFileDrop = true;
}, false)
});
GoogleMapsApiLoader({
libraries: ['places'],
apiKey: config.googleApi,
language: 'ru',
}).then(google => {
this.google = google;
this.initMap();
});
$('.modal-content').on('click', this.delegateMapClick);
},
beforeDestroy () {
this.$bus.$off('edit-post');
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
this.$refs.fileform.removeEventListener(eventName)
});
$('.modal-content').off('click', this.delegateMapClick);
},
watch: {
geoViewType (newVal) {
if (newVal === 'map') {
this.$nextTick(() => {
this.initMap();
this.fbSearchPlaces();
});
}
}
},
computed: {
accountKey () {
return this.$store.getters['route']['params']['accountKey'];
},
userId () {
return this.$store.getters['user/id'];
},
symbols () {
return MAX_POST_SIZE - this.text.length;
},
hashtags () {
let hashTags = this.text.match(/(^|\W)(#[A-Za-zА-яа-я0-9_\d][\w-]*)/g) || [];
return MAX_HASH_TAGS - hashTags.length;
},
account () {
return this.$store.getters['user/accounts'][this.accountKey];
}
},
methods: {
deleteGeo () {
this.preSelectedGeo = {};
this.selectedGeo = {};
this.hash_tag_input = '';
this.fbWindows = [];
this.fbgeofound = [];
$('#googlesuggest').val('');
},
addFinalGeo () {
this.selectedGeo = Object.assign({}, this.preSelectedGeo);
this.$refs.geoModalRef.hide();
},
openGeoModal () {
this.$refs.geoModalRef.show();
},
delegateMapClick (e) {
if (e.target.classList.contains('place-iw') && e.target.getAttribute('data-id')) {
this.addToGeo(this.mapPoints[e.target.getAttribute('data-id')]);
}
},
addToGeo (geotag) {
this.preSelectedGeo = geotag;
},
drawMap () {
this.$nextTick(() => {
this.map = new this.google.maps.Map(document.getElementById('gmap'), {
center: this.initPosition,
zoom: 10,
});
});
},
initMap () {
if (!this.map) {
this.drawMap();
const autocomplete = new this.google.maps.places.Autocomplete(document.getElementById('googlesuggest'), {
types: ['geocode']
});
autocomplete.addListener('place_changed', () => {
let place = autocomplete.getPlace();
if (place.id) {
const location = place.geometry.location;
this.initPosition = {lat: location.lat(), lng: location.lng()};
this.map.setCenter(this.initPosition);
}
});
} else {
this.drawMap();
}
},
fbSearch: debounce(function () {
this.fbSearchPlaces();
}, 500),
fbSearchPlaces () {
if (this.$refs.placesinput && this.$refs.placesinput.value.length >= 2) {
this.timer = new Date().getTime();
const query = this.$refs.placesinput.value;
let distance = parseInt(156543.03392 * Math.cos(this.map.getCenter().lat() * Math.PI / 180) / Math.pow(2, this.map.getZoom()) * 250, 10);
if (distance < 350) distance = 350;
const payload = {
cookies: this.account.cookies,
proxy: this.$store.getters['user/currentAccountProxy'],
query,
lat: this.map.getCenter().lat(),
lng: this.map.getCenter().lng(),
};
this.$store.dispatch('services/fbSearch', payload).then(result => {
const places = result;
this.fbWindows.forEach(item => item.close());
this.fbWindows = [];
this.fbgeofound = [];
let minLat = this.map.getCenter().lat();
let maxLat = this.map.getCenter().lat();
let minLng = this.map.getCenter().lng();
let maxLng = this.map.getCenter().lng();
this.mapPoints = {};
places.map(item => {
const {mediaBundles, subtitle, ...rest} = item;
return rest;
}).forEach(place => {
if (place && place.lat && place.lng && place.title) {
this.mapPoints[String(place.id)] = place;
let infowindow = new this.google.maps.InfoWindow({
content: `<div class="place-iw" data-id="${place.id}">${place.title}, ${place.address}</div>`,
position: {lat: place.lat, lng: place.lng},
disableAutoPan: true,
});
this.fbgeofound.push(place);
infowindow.open(this.map);
this.fbWindows.push(infowindow);
}
});
});
}
},
handleEmojiPicker (emoji) {
this.text += emoji;
},
setAspectRatio (ratio) {
this.aspectRatio = ratio;
this.cropper.setAspectRatio(ratio);
},
cancelEditMode () {
this.text = '';
this.finalImages = [];
this.timezone = 'Europe/Moscow';
this.datetime = '';
this.datedel = '';
this.isDelete = false;
this.deletenum = 1;
this.deleteRange = 'minutes';
this.firebaseId = null;
this.editMode = false;
this.selectedGeo = {};
this.clearPostInfo();
},
declOfNum (number, titles) {
const cases = [2, 0, 1, 1, 1, 2];
return titles[(number % 100 > 4 && number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5]];
},
onFileChange (e) {
const files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
if (files[0].type.indexOf('video') !== -1) {
this.createVideo(files[0]);
} else {
this.createImage(files[0])
}
},
createVideo (file) {
const video = URL.createObjectURL(file);
if (this.stories) {
this.aspectRatio = 9 / 16;
}
let $video = document.getElementById('t-video');
$video.src = video;
$video.oncanplay = () => {
let $canvas = document.getElementById('t-canvas');
$canvas.width = $video.videoWidth;
$canvas.height = $video.videoHeight;
$canvas.getContext('2d').drawImage($video, 0, 0, $video.videoWidth, $video.videoHeight);
base64 = $canvas.toDataURL('image/png');
this.video.file = file;
this.$refs.myModalRef.show();
URL.revokeObjectURL(video);
};
},
createImage (file) {
if (this.stories) {
this.aspectRatio = 9 / 16;
}
const reader = new FileReader();
reader.onload = (e) => {
base64 = e.target.result;
this.$refs.myModalRef.show();
};
reader.readAsDataURL(file)
},
removeImage: function (index) {
this.finalImages.splice(index, 1);
if (!this.finalImages.length) {
this.aspectRatio = 1;
}
},
savePost () {
if (this.hashtags < 0) {
this.$swal('Ошибка!', 'Колличество хэштегов должно быть не больше 30', 'error');
return;
}
this.saveProcess = true;
let task = {};
task.datetime = Date.parse(this.datetime);
if (this.isDelete && this.deletenum) {
let deletePlus = {};
deletePlus[this.deleteRange] = this.deletenum;
let deleteTimeFinal = DateTime.fromISO(this.datetime).plus(deletePlus);
task.datedel = Date.parse(deleteTimeFinal.toISO());
task.deletenum = this.deletenum;
task.deleteRange = this.deleteRange;
}
if (this.stories) {
task.is_stories = true;
}
if (this.selectedGeo.title) {
task.location = this.selectedGeo.location;
} else {
task.location = null;
}
task.text = this.text.replace(/(?:\r\n|\r|\n)/g, '⠀\n');
task.timezone = this.timezone;
task.media = this.finalImages;
axios.post(config.autopostingApiUrl + '/api/create-task', {
task: task,
user: {
id: this.userId,
accountKey: this.accountKey
}
}).then((res) => {
this.saveProcess = false;
this.$swal('Отлично!', this.stories ? 'Сторис запланирован' : 'Ваш пост сохранен', 'success');
let task = res.data;
if (!this.editMode) {
this.$store.dispatch('user/addTask', {task, accountKey: this.accountKey}).then(() => {
console.log('add task!');
}).catch(e => {
console.log(error);
});
} else {
this.$store.dispatch('user/updateTask', {
task,
taskKey: this.firebaseId,
accountKey: this.accountKey
}).then(() => {
console.log('add task!');
}).catch(e => {
console.log(error);
});
}
this.datetime = '';
this.datedel = '';
this.formData = new FormData();
this.finalImages = [];
this.text = '';
this.deleteRange = 'minutes';
this.deletenum = 1;
this.isDelete = false;
this.editMode = false;
this.deleteGeo();
this.clearPostInfo();
}).catch((e) => {
this.saveProcess = false;
console.error(e);
})
},
saveImage () {
this.$refs.myModalRef.hide();
let photoForm = new FormData();
fetch(this.filteredImage)
.then(res => res.blob())
.then(blob => {
photoForm.append('photo', blob);
this.finalImagesLoading = true;
axios.post(config.autopostingApiUrl + '/api/crop-photo', photoForm)
.then((res) => {
this.finalImages.push(res.data);
this.finalImagesLoading = false;
})
.catch(() => {
this.finalImagesLoading = false;
})
})
},
clearPostInfo () {
document.getElementById('exampleFormControlFile1').value = '';
this.croppedImage = '';
this.filteredImage = '';
if (typeof this.cropper.destroy === 'function') {
this.cropper.destroy();
}
this.cropper = {};
if (!this.finalImages.length && !this.finalImagesLoading) {
this.aspectRatio = 1;
}
},
modalHide () {
this.uploadStep = 1;
this.clearPostInfo();
},
modalShow () {
setTimeout(() => {
const image = document.getElementById('croppr');
let settings = {};
settings.viewMode = 1;
settings.aspectRatio = this.aspectRatio;
image.src = base64;
this.cropper = new Cropper(image, settings);
}, 500)
},
cropImage () {
if (this.video.file) {
this.cropVideoOnServer(this.cropper.getData());
this.$refs.myModalRef.hide();
} else {
this.croppedImage = this.cropper.getCroppedCanvas().toDataURL('image/png');
this.uploadStep = 2;
setTimeout(() => {
this.applyFilter('normal');
}, 100);
}
},
cropVideoOnServer (cropData) {
let videoFormData = new FormData();
videoFormData.append('video', this.video.file);
for (let key in cropData) {
videoFormData.append(key, cropData[key]);
}
this.finalImagesLoading = true;
axios.post(config.autopostingApiUrl + '/api/crop-video', videoFormData)
.then((res) => {
this.finalImages.push(res.data);
this.video = {};
base64 = '';
this.finalImagesLoading = false;
})
.catch(() => {
this.finalImagesLoading = false;
})
},
applyFilter (filter) {
const imageDOM = document.getElementById('image-filter');
let imgObj = new Image();
imgObj.src = this.croppedImage;
let filteredImage = filterous.importImage(imgObj, {})
.applyInstaFilter(filter)
.renderHtml(imageDOM);
this.filteredImage = filteredImage.canvas.toDataURL();
}
}
}
</script>
<style scoped lang="stylus">
$desktopSm = 1024px
$tablet = 880px
$tabletSm = 768px
#circularG {
margin-right: 10px
}
.count-badge {
background-color: #ff8c00;
color: white;
font-weight: bold
padding 5px 10px
border-radius 3px
}
.count-badge-wrap {
&__item {
display: block
margin-bottom 20px
@media (max-width: $tabletSm) {
margin-top 15px
}
}
}
.crop-alert {
margin-bottom 10px;
}
.add-task-bottom {
.t-button {
min-width 90px
}
@media (max-width: $tabletSm) {
.t-button {
width 100%
}
}
.form-inline {
flex-wrap wrap
@media (max-width: $tabletSm) {
margin-bottom 20px
justify-content space-between
}
}
.t-select {
width auto
}
}
.controls-mobile {
display none
@media (max-width: $tabletSm) {
display block
.post-text_mobile {
border-radius 3px;
height: 150px
margin-bottom 10px
}
.form-group:nth-child(2) {
margin-bottom 10px
}
}
}
.preview-photos {
display: flex;
align-items: center;
flex-wrap: wrap;
padding-top 30px;
padding-bottom: 30px
@media (max-width: $tablet) {
padding-top 20px;
padding-bottom: 10px
}
@media (max-width: $tabletSm) {
padding-top 10px
}
.add-task-image-wrap {
border-radius: 3px;
margin-right: 10px;
margin-bottom: 10px;
width: 100px;
height: 100px
overflow hidden
@media (max-width: $desktopSm) {
width: calc(16.9vw - 10px)
height: calc(16.9vw - 10px)
}
@media (max-width: $tablet) {
width: 15.1vw
height: 15.1vw
&:nth-child(5n) {
margin-right 0
}
}
@media (max-width: $tabletSm) {
width: 35.3vw;
height: 35.3vw
&:nth-child(5) {
margin-right 10px
}
&:nth-child(2n) {
margin-right 0
}
}
&__content {
width: 100%
height 100%
background-size: cover
background-position: center
background-color: #f3f3f3
}
img {
width: 100%;
}
video {
height: 100%
}
}
}
.filter-btn {
margin-bottom: 5px;
@media (max-width: $tablet) {
min-height: 30px;
}
}
.image-filter-wrap {
text-align: center;
margin-top: 15px;
}
.cropped-image {
max-width: 100%;
max-height: 300px;
}
.add-task-image {
max-height: 300px;
&__delete {
position: absolute;
right: 5px;
top: 5px;
cursor: pointer;
border-radius: 3px;
border: none;
font-size: 20px;
line-height: normal;
padding: 0 5px;
color: #989898;
span {
position: relative;
top: -1px;
}
}
}
.add-task-video {
max-height: 300px;
min-width: 100%;
}
.add-task-image-wrap {
text-align: center;
position: relative;
}
.inst-ava {
width: 50px;
border-radius: 50%;
margin-right: 15px;
}
.post-info {
width 100%
}
.post-text {
border-radius 3px;
height: 250px
padding-right: 50px
margin-bottom: 10px
@media (max-width: $tablet) {
display none
}
}
.upload-file {
@media (max-width: $tablet) {
width 100%
}
input[type="file"] {
display: none;
}
label {
width: 100%;
}
&__icon {
max-width: 80px
}
&__drop {
display: flex;
align-items: center;
justify-content: center;
width: 250px
height: 250px
border-radius: 3px;
border: 1px dashed #CECECE;
margin-right: 30px
flex-wrap: wrap;
padding: 30px
position relative
@media (max-width: $tablet) {
width 100%
}
@media (max-width: $tabletSm) {
height 150px
}
&-zone {
position absolute
left: 0
right: 0
top: 0
bottom: 0
}
&-img {
}
&-title {
width: 100%
text-align: center
font-size: 14px
color: #989898
margin-top: 18px
@media (max-width: $tablet) {
display none
}
}
&-or {
width 100%
text-align: center
font-size: 14px
color: #D8D8D8
margin-top: 15px
display flex
align-items center
@media (max-width: $tablet) {
display none
}
&:before {
display block
content: ''
height 1px
width 100%
background-color #EBEBEB
margin-right: 5px
}
&:after {
display block
content: ''
height 1px
width 100%
background-color #EBEBEB
margin-left: 5px
}
}
&-btn {
min-height: 40px
min-width: 180px
margin-top: 15px
@media (max-width: $tablet) {
min-height: 30px
width 100%
}
}
&.higlight {
background-color #F8FAFF
border-color #4680FE
.upload-file__drop-title {
color #000000
margin-top 0
}
rder-color #4680FE
.upload-file__icon {
margin-top 0
margin-bottom -60px
@media (max-width: $tablet) {
margin-bottom 0
}
}
}
}
&.disabled {
pointer-events: none;
.upload-file__drop {
cursor: not-allowed;
pointer-events: none;
border: 1px solid lightgray;
color: lightgray;
}
}
&._full {
width: 100%
.upload-file__drop {
width 100%
}
}
}
#croppr {
max-width: 100%;
}
.delete-num {
max-width: 80px;
}
.add-task-form {
display flex
justify-content space-between
&__emoji {
position: absolute;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
color: #989898;
font-size: 20px;
width: 40px;
height: 40px;
right: 10px;
bottom: 10px;
@media (max-width: $tabletSm) {
bottom 20px
}
.emoji-picker {
position: absolute;
width: 100%;
height: 100%;
cursor: pointer;
}
}
&__text-wrap {
position relative
display flex
width 100%
max-height 250px
margin-bottom 10px
@media (max-width: $tabletSm) {
display none
}
&._mobile {
@media (max-width: $tabletSm) {
display block
}
}
}
&__left {
display: flex;
width: 100%;
justify-content: space-between;
margin-right: 30px
@media (max-width: $tablet) {
width 50%
}
@media (max-width: $tabletSm) {
width: 100%
margin-right 0
flex-wrap wrap
}
}
&__right {
color: #585858
@media (max-width: $tablet) {
width 50%
}
@media (max-width: $tabletSm) {
display none
}
.form-group {
margin-bottom 10px
}
.t-select__select {
margin-top: 5px
}
}
}
.post-info {
width 100%
}
.geo-button {
height 50px
border 1px solid #D2D2D2
border-radius 3px
padding 13px 18px
display flex
justify-content center
align-items center
color #989898
margin-left 20px
cursor pointer
position relative
&__icon {
width 15px
margin-left 10px
}
&__close {
width: 30px;
height: 30px;
background: lightgrey;
text-align: center;
position: absolute;
right: -10px;
top: -10px;
font-size: 18px;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
border-radius: 3px;
padding-top: 1px;
}
span {
max-width 150px
overflow hidden
display block
word-break break-all
white-space pre
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment