You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.8 KiB
114 lines
3.8 KiB
<template>
|
|
<div class="contest-works">
|
|
<div class="contest-works__works" v-if="! $root.store.isMobile">
|
|
<div class="contest-works__column">
|
|
<contest-work v-for="contestWork in columns[0]" :key="contestWork.id" :contest-work="contestWork"></contest-work>
|
|
</div>
|
|
<div class="contest-works__column">
|
|
<contest-work v-for="contestWork in columns[1]" :key="contestWork.id" :contest-work="contestWork"></contest-work>
|
|
</div>
|
|
<div class="contest-works__column">
|
|
<contest-work v-for="contestWork in columns[2]" :key="contestWork.id" :contest-work="contestWork"></contest-work>
|
|
</div>
|
|
</div>
|
|
<div class="contest-works__works" v-if="$root.store.isMobile" style="display: block;">
|
|
<contest-work v-for="contestWork in contestWorks" :key="contestWork.id" :contest-work="contestWork"></contest-work>
|
|
</div>
|
|
<div v-show="loading" class="contest-works__loader"><div class="loading-loader"></div></div>
|
|
<div v-if="loaded && !contestWorks.length" class="contest-works__no-works">Здесь вы сможете увидеть работы участников после их добавления</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {api} from "../js/modules/api";
|
|
import $ from 'jquery';
|
|
import ContestWork from "./blocks/ContestWork.vue";
|
|
|
|
export default {
|
|
name: "contest-works",
|
|
props: ['contestId', 'autoload'],
|
|
data(){
|
|
return {
|
|
page: 1,
|
|
lastPage: null,
|
|
loading: false,
|
|
loaded: false,
|
|
contestWorks: [],
|
|
};
|
|
},
|
|
mounted() {
|
|
this.load();
|
|
if(this.autoload) {
|
|
$(window).scroll(() => {
|
|
const pos = $(this.$el).offset().top + this.$el.clientHeight - 100;
|
|
if($(window).scrollTop() + $(window).height() >= pos
|
|
&& !this.loading && !this.lastPage) {
|
|
this.page += 1;
|
|
this.load();
|
|
}
|
|
});
|
|
}
|
|
},
|
|
computed: {
|
|
columns() {
|
|
const columnWidth = 300;
|
|
const heights = [0, 0, 0];
|
|
const first = [];
|
|
const second = [];
|
|
const third = [];
|
|
let index = 0;
|
|
for(let i=0; i < this.contestWorks.length; i++) {
|
|
const work = this.contestWorks[i];
|
|
let column = index % 3;
|
|
const workHeight = work.img_height / work.img_width * columnWidth + 50;
|
|
let minHeight = 0;
|
|
if(i > 3){
|
|
for(let j=0; j < 3; j++){
|
|
let col = j % 3;
|
|
if(! minHeight || heights[j] < minHeight){
|
|
minHeight = heights[j];
|
|
if(heights[column] - heights[j] > workHeight * 0.1){
|
|
column = j;
|
|
index += j - column;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
heights[column] += workHeight;
|
|
[first, second, third][column].push(work);
|
|
index++;
|
|
}
|
|
return [first, second, third];
|
|
}
|
|
},
|
|
methods: {
|
|
load() {
|
|
this.loading = true;
|
|
api.get(`/api/v1/contest-works/?contest=${this.contestId}&page=${this.page}¤t_user=${this.$root.store.user.id}`, {
|
|
headers: {
|
|
'Authorization': `Token ${this.$root.store.accessToken}`,
|
|
}
|
|
})
|
|
.then(response => {
|
|
this.loading = false;
|
|
this.loaded = true;
|
|
if(this.page > 1){
|
|
this.contestWorks = this.contestWorks.concat(response.data.results);
|
|
}
|
|
else{
|
|
this.contestWorks = response.data.results;
|
|
}
|
|
})
|
|
.catch((response) => {
|
|
this.loading = false;
|
|
this.loaded = true;
|
|
if(response.response.status == 404){
|
|
this.lastPage = this.page;
|
|
}
|
|
});
|
|
}
|
|
},
|
|
components: {ContestWork},
|
|
}
|
|
</script>
|
|
|