Последняя версия с сервера прошлого разработчика

This commit is contained in:
2025-07-10 04:35:51 +00:00
commit c731570032
1174 changed files with 134314 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<template>
<div class="flex items-center text-gray-light">
<svg class="w-5 h-5 flex-shrink-0">
<use xlink:href="#message-circle"></use>
</svg>
<span v-show="comments" class="ml-2 text-sm">{{
comments
}}</span>
</div>
</template>
<script>
export default {
components: {
},
props: {
comments: Number,
},
};
</script>

View File

@@ -0,0 +1,19 @@
<template>
<div class="-mx-1">
<inertia-link
:href="route('feed.tags', tag.slug)"
class="inline-flex rounded-full items-center mx-1 py-0.5 px-2.5 text-sm font-medium bg-orange text-indigo-300"
v-for="tag in tags" :key="tag.id">
{{tag.name}}
</inertia-link>
</div>
</template>
<script>
export default {
components: {},
props: {
tags: Array,
},
};
</script>

View File

@@ -0,0 +1,25 @@
<template>
<inertia-link :href="route('feed.tags', slug)"
:class="[$page.component === 'Tag/Feed' ? 'bg-orange shadow-classic2' : 'shadow-classic bg-indigo-200 hover:bg-orange' , 'transition inline-flex items-center px-3 py-3 lg:px-6 lg:py-6 xl:px-10 text-sm lg:text-lg justify-center rounded-md text-white focus:outline-none']">
Все
</inertia-link>
<inertia-link :href="route('list.images.tag', slug)"
:class="[$page.component === 'Image/Index' ? 'bg-orange shadow-classic2' : 'shadow-classic bg-indigo-200 hover:bg-orange' , 'transition inline-flex items-center px-3 py-3 lg:px-6 lg:py-6 xl:px-10 text-sm lg:text-lg justify-center rounded-md text-white focus:outline-none']">
Изображения
</inertia-link>
<inertia-link :href="route('list.musics.tag', slug)"
:class="[$page.component === 'Music/Feed' ? 'bg-orange shadow-classic2' : 'shadow-classic bg-indigo-200 hover:bg-orange' , 'transition inline-flex items-center px-3 py-3 lg:px-6 lg:py-6 xl:px-10 text-sm lg:text-lg justify-center rounded-md text-white focus:outline-none']">
Музыка
</inertia-link>
<inertia-link :href="route('list.videos.tag', slug)"
:class="[$page.component === 'Video/Feed' ? 'bg-orange shadow-classic2' : 'shadow-classic bg-indigo-200 hover:bg-orange' , 'transition inline-flex items-center px-3 py-3 lg:px-6 lg:py-6 xl:px-10 text-sm lg:text-lg justify-center rounded-md text-white focus:outline-none']">
Видео
</inertia-link>
</template>
<script>
export default {
props: {
slug: String,
},
}
</script>

View File

@@ -0,0 +1,76 @@
<template>
<div class="absolute left-0 right-0 z-[100]">
<div v-if="$page.props.flash.success && show" class="mx-auto mt-4 mb-4 flex items-center justify-between bg-green rounded max-w-3xl">
<div class="flex items-center">
<svg class="ml-4 mr-2 flex-shrink-0 w-4 h-4 fill-white" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
><polygon points="0 11 2 9 7 14 18 3 20 5 7 18" /></svg>
<div class="py-4 text-white text-sm font-medium">
{{ $page.props.flash.success }}
</div>
</div>
<button type="button" class="group mr-2 p-2"
@click="show = false"
>
<svg class="block w-2 h-2 fill-green-800 group-hover:fill-white" xmlns="http://www.w3.org/2000/svg"
width="235.908" height="235.908"
viewBox="278.046 126.846 235.908 235.908"
><path d="M506.784 134.017c-9.56-9.56-25.06-9.56-34.62 0L396 210.18l-76.164-76.164c-9.56-9.56-25.06-9.56-34.62 0-9.56 9.56-9.56 25.06 0 34.62L361.38 244.8l-76.164 76.165c-9.56 9.56-9.56 25.06 0 34.62 9.56 9.56 25.06 9.56 34.62 0L396 279.42l76.164 76.165c9.56 9.56 25.06 9.56 34.62 0 9.56-9.56 9.56-25.06 0-34.62L430.62 244.8l76.164-76.163c9.56-9.56 9.56-25.06 0-34.62z" /></svg>
</button>
</div>
<div v-if="($page.props.flash.error || Object.keys($page.props.errors).length > 0) && show" class="mx-auto mt-4 mb-4 flex items-center justify-between bg-red rounded max-w-3xl">
<div class="flex items-center">
<svg class="ml-4 mr-2 flex-shrink-0 w-4 h-4 fill-white" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z" /></svg>
<div v-if="$page.props.flash.error" class="py-4 text-white text-sm font-medium">
{{ $page.props.flash.error }}
</div>
<div v-else class="py-4 text-white text-sm font-medium">
<span v-if="Object.keys($page.props.errors).length === 1">There is one form error.</span>
<span v-else>There are {{ Object.keys($page.props.errors).length }} form errors.</span>
</div>
</div>
<button type="button" class="group mr-2 p-2"
@click="show = false"
>
<svg class="block w-2 h-2 fill-red-800 group-hover:fill-white" xmlns="http://www.w3.org/2000/svg"
width="235.908" height="235.908"
viewBox="278.046 126.846 235.908 235.908"
><path d="M506.784 134.017c-9.56-9.56-25.06-9.56-34.62 0L396 210.18l-76.164-76.164c-9.56-9.56-25.06-9.56-34.62 0-9.56 9.56-9.56 25.06 0 34.62L361.38 244.8l-76.164 76.165c-9.56 9.56-9.56 25.06 0 34.62 9.56 9.56 25.06 9.56 34.62 0L396 279.42l76.164 76.165c9.56 9.56 25.06 9.56 34.62 0 9.56-9.56 9.56-25.06 0-34.62L430.62 244.8l76.164-76.163c9.56-9.56 9.56-25.06 0-34.62z" /></svg>
</button>
</div>
</div>
</template>
<script>
//import { ref, watch } from 'vue'
export default {
// setup() {
// const show = ref(true)
// watch('$page.props.flash', function(){
// this.show = true
// });
// return {
// show,
// };
// },
data() {
return {
show: true,
}
},
watch: {
'$page.props.flash': {
handler() {
this.show = true
},
deep: true,
},
},
}
</script>

View File

@@ -0,0 +1,126 @@
<template>
<slot v-bind="$attrs" />
<slot v-if="loading" name="loading"
:text="loadText"
>
<div v-if="loading" class="col-span-full flex justify-center">
<svg class="flex-shrink-0 animate-spin h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24"
> <circle class="opacity-25" cx="12"
cy="12" r="10"
stroke="currentColor" stroke-width="4"
></circle><path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path></svg>
</div>
</slot>
</template>
<script>
import { ref, onUpdated, onUnmounted, watch } from 'vue'
import axios from 'axios'
import { usePage } from '@inertiajs/inertia-vue3'
export default {
props: {
nodeElement: Object,
loadText: {
type: String,
default: 'Загрузка ...',
},
nextCursor: { type: String, default: '' },
},
emits: ['fromPagination'],
setup(props, { emit }) {
const cursor = ref(props.nextCursor)
const loading = ref(false)
let installObserver = false
let observer = null
// watch(props, (props) => {
// observer?.disconnect();
// createObserver();
// });
const loadMore = () => {
loading.value = true
if (!cursor.value) {
return Promise.resolve(null)
}
return new Promise((resolve) => {
axios
.get(usePage().url.value, { params: { cursor: cursor.value } })
.then(({ data }) => {
if (data.collections.length) {
cursor.value = data.next
emit('fromPagination', data.collections)
resolve(true)
}
resolve(false)
})
})
}
const createObserver = () => {
if (props.nodeElement) {
const intersectionCallback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
console.log('isIntersecting')
console.log(props.nodeElement)
removeObserver(entry.target)
loadMore().then((exist) => {
loading.value = false
if (exist) {
createObserver()
}
})
}
})
}
observer = new IntersectionObserver(intersectionCallback, {})
observer.observe(props.nodeElement)
}
}
const removeObserver = (target) => {
observer.unobserve(target)
observer?.disconnect()
}
onUpdated(() => {
if (!installObserver) {
createObserver()
installObserver = true
}
})
onUnmounted(() => {
observer?.disconnect()
})
// onMounted(() => {
// window.addEventListener(
// "scroll",
// debounce((e) => {
// console.log(props.nodeElement);
// let pixelsFromBottom =
// document.documentElement.offsetHeight -
// document.documentElement.scrollTop -
// window.innerHeight;
// if (pixelsFromBottom < props.bottomLine && !loading.value) {
// loading.value = true;
// props.loadMore().finally(() => (loading.value = false));
// }
// }, 200)
// );
// });
return {
loading,
}
},
}
</script>

View File

@@ -0,0 +1,24 @@
<script>
export default {
emits: ["fromPagination"],
render() {
const { lists, addTag, deleteTag } = this;
return this.$slots.default({
tags,
addTag,
deleteTag,
});
},
props: {
nodeElement: Object,
loadText: {
type: String,
default: "Загрузка ...",
},
nextCursor: { type: String, default: "" },
},
setup(){
},
};
</script>

View File

@@ -0,0 +1,32 @@
<template>
<div
:class="[
liked ? 'text-red' : 'text-gray-light',
'flex items-center',
]"
>
<button class="default" @click.stop="likeFeed">
<svg class="w-5 h-5 flex-shrink-0">
<use xlink:href="#heart"></use>
</svg>
</button>
<span v-show="likes" class="ml-2 text-sm">{{
likes
}}</span>
</div>
</template>
<script>
export default {
props: {
likes: Number,
liked: Boolean,
},
emits: ['likeFeed'],
methods: {
likeFeed() {
this.$emit('likeFeed')
},
},
}
</script>

View File

@@ -0,0 +1,13 @@
<template>
<button type="button" @click="back"><slot /></button>
</template>
<script>
export default {
methods: {
back() {
window.history.back();
},
}
}
</script>

View File

@@ -0,0 +1,25 @@
<template>
<button @click.stop="addAudio" type="button" class="default flex-shrink-0"
:class="[
liked ? 'text-red' : 'text-gray-light'
]"
>
<svg class="w-4 h-4">
<use xlink:href="#heart"></use>
</svg>
</button>
</template>
<script>
export default {
emits: ["addAudio"],
props: {
media_id: Number,
liked: Boolean,
},
methods: {
addAudio() {
this.$emit("addAudio", this.media_id);
},
},
};
</script>

View File

@@ -0,0 +1,20 @@
<template>
<div class="cursor-pointer flex items-center text-gray-light">
<svg class="w-5 h-5 flex-shrink-0">
<use xlink:href="#share"></use>
</svg>
<span v-show="shares" class="ml-2 text-sm">{{
shares
}}</span>
</div>
</template>
<script>
export default {
components: {
},
props: {
shares: Number,
},
};
</script>

View File

@@ -0,0 +1,32 @@
<template>
<button :class="[ currentSong?.id === media_id ? '' : 'hidden', 'default' ]">
<svg :class="[ playing ? 'hidden' : 'block', 'w-6 h-6' ]">
<use xlink:href="#play"></use>
</svg>
<svg :class="[ playing ? 'block' : 'hidden', 'w-6 h-6' ]">
<use xlink:href="#pause"></use>
</svg>
</button>
<button :class="[ currentSong?.id !== media_id ? '' : 'hidden', 'default' ]">
<svg class="w-6 h-6">
<use xlink:href="#play"></use>
</svg>
</button>
</template>
<script>
import { mapState, mapGetters } from "vuex";
export default {
components: {
},
props: {
media_id: Number,
},
computed: {
...mapGetters(["playing"]),
...mapState({
currentSong: (state) => state.player.currentSong,
}),
},
};
</script>

View File

@@ -0,0 +1,34 @@
<template>
<div
v-if="user.photo_path"
class="rounded-full bg-cover bg-center"
:style="setBackground()"
></div>
<div
v-else
:style="`background-color:${user.color};`"
class="select-none rounded-full font-bold flex items-center justify-center text-white"
>
{{ user.user_char }}
</div>
</template>
<script>
export default {
props: {
user: {
type: Object,
required: true
},
size: {
type: String,
default: 'small',
},
},
methods: {
setBackground() {
return `background-image: url(/img/${this.user.photo_path}?p=${this.size});`
},
},
}
</script>

View File

@@ -0,0 +1,28 @@
<template>
<div
v-if="user.banner_path"
class="bg-cover bg-center"
:style="setBackground()"
></div>
<div
v-else
class="bg-cover bg-center"
></div>
</template>
<script>
export default {
props: {
user: Object,
size: {
type: String,
default: 'small',
},
},
methods: {
setBackground() {
return `background-image: url(/img/${this.user.banner_path}?p=${this.size});`;
},
},
};
</script>

View File

@@ -0,0 +1,22 @@
<template>
<div class="count-views">
<div v-show="count" class="flex items-center text-gray-light">
<svg class="w-5 h-5 flex-shrink-0">
<use xlink:href="#eye"></use>
</svg>
<span class="ml-2 text-sm">{{ count }}</span>
</div>
</div>
</template>
<script>
export default {
components: {},
props: {
count: {
type: Number,
default: 0
},
},
}
</script>

View File

@@ -0,0 +1,6 @@
<template>
<div class="mt-2 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-orange flex-shrink-0 mr-2"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
<div class="text-sm text-gray-light">контент будет участвовать в поиске, если заполните название (а еще лучше и описание и теги)</div>
</div>
</template>