First commit

This commit is contained in:
2026-03-27 10:14:29 +03:00
commit ad29150770
10404 changed files with 962562 additions and 0 deletions

133
components/StarsLine.vue Normal file
View File

@@ -0,0 +1,133 @@
<template>
<div v-if="base !== undefined" class="flex flex-col flex-nowrap" :title="title">
<div class="flex flex-row flex-nowrap">
<img
v-for="i in getYellowStarsCount"
:key="'y' + i"
:class="readOnly ? '' : 'cursor-pointer'"
:src="getImage('y', i)"
:style="'width: ' + 100/max + '%;'"
@click="click(i)"
>
<img
v-for="i in getBlueStarsCount"
:key="'b' + i"
:class="readOnly ? '' : 'cursor-pointer'"
:src="getImage('b', i+base)"
:style="'width: ' + 100/max + '%;'"
@click="click(i+base)"
>
<img
v-for="i in getInvisibleStarsCount"
:key="'i' + i"
class="hidden"
src="/img/star_b1.png"
:style="'width: ' + 100/max + '%;'"
>
</div>
<div v-if="transcendance && extra > 5" class="flex flex-row flex-nowrap">
<img
v-for="i in 5"
:key="'v' + i"
:class="getTranscendanceClass(5+i)"
:src="getTranscendanceImage(i)"
:style="'width: 20%;'"
@click="click(5+i)"
>
</div>
</div>
</template>
<script>
export default {
props: {
base: { // Yellow stars
type: Number,
required: true
},
extra: { // Blue stars
type: Number,
required: true
},
current: { // Number of checked stars
type: Number,
required: true
},
max: { // For line size
type: Number,
required: true
},
transcendance: {
type: Boolean,
default: false
},
readOnly: {
type: Boolean,
default: false
},
title: {
type: String,
default: 'Uncap level'
}
},
methods: {
isStarEnabled(index) {
return index <= this.current;
},
getImage(type, index) {
return '/img/star_' + type + (this.isStarEnabled(index) ? "1" : "0") + '.png';
},
getTranscendanceImage(index) {
if ( ! this.isStarEnabled(index + 5)) {
return '/img/star_v0.png';
}
return '/img/star_v' + index + '.png';
//return '/img/star_v' + index + '.png';
},
getTranscendanceClass(index) {
let result = '';
if ( ! this.readOnly) result += 'cursor-pointer ';
if ( ! this.isStarEnabled(index)) result += 'grayscale-80 opacity-70';
return result;
},
click(index) {
if (this.readOnly) {
return;
}
let current_stars = index;
if (index === 1 && this.current !== 0) {
// First click on 1st star sets 0 stars instead of 1
current_stars = 0;
}
else if (index === this.current) {
current_stars = index - 1;
}
this.$emit('update:current', current_stars);
}
},
computed: {
getYellowStarsCount() {
return this.base;
},
getBlueStarsCount() {
if (this.base > this.extra) {
return 0;
}
if (this.transcendance && this.extra > 5) {
return Math.min(this.extra, 5) - this.base;
}
return this.extra - this.base;
},
getInvisibleStarsCount() {
const baseStars = Math.max(this.base, this.extra);
if (baseStars > this.max) {
return 0;
}
return this.max - baseStars;
},
},
}
</script>