Последняя версия с сервера прошлого разработчика
This commit is contained in:
3
resources/js/includes/composables/index.js
vendored
Executable file
3
resources/js/includes/composables/index.js
vendored
Executable file
@@ -0,0 +1,3 @@
|
||||
export { useIntersectionObserver } from '@/includes/composables/useIntersectionObserver'
|
||||
export { useAutoresizeTextarea } from '@/includes/composables/useAutoresizeTextarea'
|
||||
export { useApi } from '@/includes/composables/useApi'
|
||||
22
resources/js/includes/composables/useApi.js
vendored
Executable file
22
resources/js/includes/composables/useApi.js
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useApi = (getResult) => {
|
||||
const result = ref(null)
|
||||
const loading = ref(false)
|
||||
const error = ref(false)
|
||||
|
||||
async function callAPI() {
|
||||
result.value = null
|
||||
loading.value = true
|
||||
error.value = false
|
||||
try {
|
||||
result.value = await getResult()
|
||||
} catch {
|
||||
error.value = true
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
return { result, loading, error, callAPI }
|
||||
}
|
||||
17
resources/js/includes/composables/useAutoresizeTextarea.js
vendored
Executable file
17
resources/js/includes/composables/useAutoresizeTextarea.js
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
import { watchEffect } from 'vue'
|
||||
|
||||
export const useAutoresizeTextarea = (element) => {
|
||||
|
||||
const resizeTextarea = () => {
|
||||
element.value.style.height = 'auto'
|
||||
element.value.style.height = element.value.scrollHeight + 'px'
|
||||
}
|
||||
|
||||
watchEffect(onInvalidate => {
|
||||
if (! element.value) return
|
||||
resizeTextarea()
|
||||
element.value.addEventListener('input', resizeTextarea)
|
||||
|
||||
onInvalidate(() => element.value?.removeEventListener('input', resizeTextarea))
|
||||
})
|
||||
}
|
||||
97
resources/js/includes/composables/useInfinityScroll.js
vendored
Executable file
97
resources/js/includes/composables/useInfinityScroll.js
vendored
Executable file
@@ -0,0 +1,97 @@
|
||||
import { ref, watch, onUnmounted } from 'vue'
|
||||
import { useApi } from '@/includes/composables'
|
||||
|
||||
export const useInfinityScroll = (query) => {
|
||||
|
||||
let observer = null
|
||||
|
||||
const domElement = ref(null)
|
||||
const lastID = ref(0)
|
||||
const cursor = ref('')
|
||||
const data = ref({})
|
||||
|
||||
const { loading, result, error, callAPI } = useApi(query)
|
||||
|
||||
|
||||
watch(domElement, (changeElement) => {
|
||||
// console.log(changeElement)
|
||||
createObserver(changeElement)
|
||||
})
|
||||
|
||||
watch(result, (response) => {
|
||||
if(!response) return
|
||||
console.log(response.records)
|
||||
Object.entries(response.records).forEach(([key,value]) => {
|
||||
lastID.value = value[value.length - 1]?.id
|
||||
if(data.value[[key]]){
|
||||
data.value[[key]] = { ...value, ...data.value[[key]] }
|
||||
}else{
|
||||
data.value[[key]] = value
|
||||
}
|
||||
})
|
||||
|
||||
cursor.value = response.cursor
|
||||
Object.entries(response.records).forEach(([,value]) => {
|
||||
lastID.value = value[value.length - 1]?.id
|
||||
})
|
||||
})
|
||||
|
||||
const createObserver = (dom) => {
|
||||
observer?.disconnect()
|
||||
if(!cursor.value) return
|
||||
if (dom) {
|
||||
const intersectionCallback = (entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
removeObserver(entry.target)
|
||||
callAPI()
|
||||
}
|
||||
})
|
||||
}
|
||||
observer = new IntersectionObserver(intersectionCallback, {})
|
||||
observer.observe(dom)
|
||||
}
|
||||
}
|
||||
|
||||
const removeObserver = (target) => {
|
||||
observer.unobserve(target)
|
||||
observer?.disconnect()
|
||||
}
|
||||
|
||||
const refetchApi = () => {
|
||||
cursor.value = ''
|
||||
data.value = {}
|
||||
observer?.disconnect()
|
||||
callAPI()
|
||||
}
|
||||
|
||||
const domNodeFn = (el, idx) => {
|
||||
if(lastID.value === idx){
|
||||
if(el){
|
||||
domElement.value = el.$el
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
observer?.disconnect()
|
||||
})
|
||||
|
||||
// watchEffect(onInvalidate => {
|
||||
// onInvalidate(() => observer?.disconnect())
|
||||
|
||||
// console.log(1)
|
||||
// })
|
||||
|
||||
return {
|
||||
domElement,
|
||||
loading,
|
||||
error,
|
||||
callAPI,
|
||||
cursor,
|
||||
data,
|
||||
lastID,
|
||||
refetchApi,
|
||||
domNodeFn
|
||||
}
|
||||
}
|
||||
43
resources/js/includes/composables/useIntersectionObserver.js
vendored
Executable file
43
resources/js/includes/composables/useIntersectionObserver.js
vendored
Executable file
@@ -0,0 +1,43 @@
|
||||
import { ref, unref, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
export const useIntersectionObserver = (el, options = {}, onEntry) => {
|
||||
console.log({ options })
|
||||
|
||||
let observer = null
|
||||
let isIntersecting = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
const $el = unref(el)
|
||||
if (!($el instanceof HTMLElement))
|
||||
throw new Error(
|
||||
'useIntersectionObserver: ref.value is not an HTMLElement'
|
||||
)
|
||||
|
||||
// Render the VeryLargeComponent when the container intersects
|
||||
const intersectionCallback = entries => {
|
||||
entries.forEach(entry => {
|
||||
console.log('entry', entry)
|
||||
|
||||
isIntersecting.value = entry.isIntersecting
|
||||
// if (entry.isIntersecting) {
|
||||
// observer.unobserve(entry.target);
|
||||
// }
|
||||
if (typeof onEntry === 'function') onEntry(entry)
|
||||
})
|
||||
}
|
||||
observer = new IntersectionObserver(intersectionCallback, options)
|
||||
|
||||
observer.observe($el)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
console.log('UNMOUNTED')
|
||||
|
||||
observer?.disconnect()
|
||||
})
|
||||
|
||||
return {
|
||||
isIntersecting,
|
||||
observer,
|
||||
}
|
||||
}
|
||||
24
resources/js/includes/helper.js
vendored
Executable file
24
resources/js/includes/helper.js
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
export default {
|
||||
formatTime(time) {
|
||||
var minutes = Math.floor(time / 60) || 0
|
||||
var seconds = Math.round((time - minutes * 60) || 0)
|
||||
|
||||
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
|
||||
},
|
||||
declOfNum (n, titles) {
|
||||
return titles[n % 10 === 1 && n % 100 !== 11 ?
|
||||
0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2]
|
||||
},
|
||||
declNumPosts(number){
|
||||
const array_word = ['публикация', 'публикации', 'публикаций']
|
||||
return this.declOfNum(number, array_word)
|
||||
},
|
||||
declNumReaders(number){
|
||||
const array_word = ['подписка', 'подписок', 'подписок']
|
||||
return this.declOfNum(number, array_word)
|
||||
},
|
||||
declNumSubs(number){
|
||||
const array_word = ['подписчик', 'подписчика', 'подписчиков']
|
||||
return this.declOfNum(number, array_word)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user