фикс свайпов
This commit is contained in:
parent
2bc0e9c701
commit
d1b953a75a
37
package-lock.json
generated
37
package-lock.json
generated
@ -23,7 +23,9 @@
|
|||||||
"multer": "^1.4.5-lts.2",
|
"multer": "^1.4.5-lts.2",
|
||||||
"socket.io-client": "^4.8.1",
|
"socket.io-client": "^4.8.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-router": "^4.5.1"
|
"vue-hammer": "^0.2.0",
|
||||||
|
"vue-router": "^4.5.1",
|
||||||
|
"vue-swipe": "^2.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^5.2.3",
|
"@vitejs/plugin-vue": "^5.2.3",
|
||||||
@ -4148,6 +4150,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/hammerjs": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/has-bigints": {
|
"node_modules/has-bigints": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
||||||
@ -6864,6 +6875,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-hammer": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-hammer/-/vue-hammer-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-u/J/TniXJAI/0cL2t3y+ZsEflw7sBl6cWhdlO0qToCDvKN31gaxxBMzZokhJ/SFzI5p2EGO8g0bmXWkbG10rVw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"hammerjs": "^2.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vue-router": {
|
"node_modules/vue-router": {
|
||||||
"version": "4.5.1",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
|
||||||
@ -6879,6 +6899,15 @@
|
|||||||
"vue": "^3.2.0"
|
"vue": "^3.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-swipe": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-swipe/-/vue-swipe-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-0N5gOED0XF/KsyeF7mT+52J2hGdnHx47xiBbVlZjCxzOyLHWX03W2/G4VhC7bvlMZO7kMt9I/rMPwKZhmk1XTQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"wind-dom": "0.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||||
@ -6987,6 +7016,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/wind-dom": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/wind-dom/-/wind-dom-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-TlL8trn5lguxKs2O9smpnWC8Ti8rvWP1p7A+k+0DKP9mPRwFzYuijebE1I5BbbklAoBlBS1nwT8ng2DZI51tQg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/workbox-background-sync": {
|
"node_modules/workbox-background-sync": {
|
||||||
"version": "7.3.0",
|
"version": "7.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz",
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
"multer": "^1.4.5-lts.2",
|
"multer": "^1.4.5-lts.2",
|
||||||
"socket.io-client": "^4.8.1",
|
"socket.io-client": "^4.8.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-router": "^4.5.1"
|
"vue-hammer": "^0.2.0",
|
||||||
|
"vue-router": "^4.5.1",
|
||||||
|
"vue-swipe": "^2.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^5.2.3",
|
"@vitejs/plugin-vue": "^5.2.3",
|
||||||
|
@ -2,6 +2,8 @@ import { createApp } from 'vue';
|
|||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
import router from './router';
|
import router from './router';
|
||||||
import { useAuth } from './auth'; // 1. Импортируем useAuth
|
import { useAuth } from './auth'; // 1. Импортируем useAuth
|
||||||
|
import { VueHammer } from 'vue3-hammer';
|
||||||
|
import VueSwipe from 'vue-swipe';
|
||||||
|
|
||||||
// Импорт стилей Bootstrap
|
// Импорт стилей Bootstrap
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
@ -9,6 +11,11 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
|||||||
// Создаем приложение
|
// Создаем приложение
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
// Регистрируем библиотеки для улучшенного свайпа
|
||||||
|
app.use(VueHammer);
|
||||||
|
app.component('swipe', VueSwipe.Swipe);
|
||||||
|
app.component('swipe-item', VueSwipe.SwipeItem);
|
||||||
|
|
||||||
// Используем роутер
|
// Используем роутер
|
||||||
app.use(router);
|
app.use(router);
|
||||||
|
|
||||||
|
@ -42,8 +42,12 @@
|
|||||||
<div v-if="!loading && suggestions.length > 0 && !error" class="swipe-content">
|
<div v-if="!loading && suggestions.length > 0 && !error" class="swipe-content">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="swipe-area" ref="swipeArea">
|
<div class="swipe-area" ref="swipeArea">
|
||||||
<transition-group name="card-stack" tag="div" class="card-stack-container">
|
<swipe v-if="visibleUsers.length > 0"
|
||||||
<div
|
:auto="0"
|
||||||
|
:show-indicators="false"
|
||||||
|
class="card-stack-container"
|
||||||
|
:allowVerticalScrolling="true">
|
||||||
|
<swipe-item
|
||||||
v-for="(user, index) in visibleUsers"
|
v-for="(user, index) in visibleUsers"
|
||||||
:key="user._id"
|
:key="user._id"
|
||||||
class="swipe-card"
|
class="swipe-card"
|
||||||
@ -54,13 +58,9 @@
|
|||||||
'swiping-right': swipeDirection === 'right' && index === 0
|
'swiping-right': swipeDirection === 'right' && index === 0
|
||||||
}"
|
}"
|
||||||
:style="index === 0 ? cardStyle : {}"
|
:style="index === 0 ? cardStyle : {}"
|
||||||
@touchstart="startTouch"
|
v-hammer:pan="index === 0 ? onPan : null"
|
||||||
@touchmove="moveTouch"
|
v-hammer:panend="index === 0 ? onPanEnd : null"
|
||||||
@touchend="endTouch"
|
v-hammer:tap="handleCardTap"
|
||||||
@mousedown="startDrag"
|
|
||||||
@mousemove="moveDrag"
|
|
||||||
@mouseup="endDrag"
|
|
||||||
@mouseleave="cancelDrag"
|
|
||||||
>
|
>
|
||||||
<!-- Photo Section -->
|
<!-- Photo Section -->
|
||||||
<div class="card-photo-section">
|
<div class="card-photo-section">
|
||||||
@ -160,8 +160,8 @@
|
|||||||
<p class="bio-text">{{ user.bio || 'Нет описания.' }}</p>
|
<p class="bio-text">{{ user.bio || 'Нет описания.' }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</swipe-item>
|
||||||
</transition-group>
|
</swipe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
@ -240,17 +240,10 @@ const currentPhotoIndex = reactive({});
|
|||||||
|
|
||||||
// Для свайпа
|
// Для свайпа
|
||||||
const swipeDirection = ref(null);
|
const swipeDirection = ref(null);
|
||||||
const touchStartX = ref(0);
|
const swipeThreshold = 80; // Минимальное расстояние для срабатывания свайпа
|
||||||
const touchStartY = ref(0);
|
|
||||||
const touchEndX = ref(0);
|
|
||||||
const touchEndY = ref(0);
|
|
||||||
const swipeThreshold = 100; // Минимальное расстояние для срабатывания свайпа
|
|
||||||
const isDragging = ref(false);
|
|
||||||
const dragStartX = ref(0);
|
|
||||||
const dragStartY = ref(0);
|
|
||||||
const dragOffset = ref({ x: 0, y: 0 });
|
|
||||||
const cardStyle = ref({});
|
const cardStyle = ref({});
|
||||||
const swipeAngle = 12; // Угол наклона карты при свайпе (в градусах)
|
const swipeAngle = 12; // Угол наклона карты при свайпе (в градусах)
|
||||||
|
const isPanning = ref(false);
|
||||||
|
|
||||||
// Вычисляемые свойства
|
// Вычисляемые свойства
|
||||||
const currentUserToSwipe = computed(() => {
|
const currentUserToSwipe = computed(() => {
|
||||||
@ -291,12 +284,12 @@ const initPhotoIndices = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const changePhoto = (userId, index) => {
|
const changePhoto = (userId, index) => {
|
||||||
if (isDragging.value) return; // Не меняем фото во время свайпа
|
if (isPanning.value) return; // Не меняем фото во время свайпа
|
||||||
currentPhotoIndex[userId] = index;
|
currentPhotoIndex[userId] = index;
|
||||||
};
|
};
|
||||||
|
|
||||||
const nextPhoto = (userId) => {
|
const nextPhoto = (userId) => {
|
||||||
if (isDragging.value) return;
|
if (isPanning.value) return;
|
||||||
const user = suggestions.value.find(u => u._id === userId);
|
const user = suggestions.value.find(u => u._id === userId);
|
||||||
if (user && user.photos && user.photos.length > 0) {
|
if (user && user.photos && user.photos.length > 0) {
|
||||||
currentPhotoIndex[userId] = (currentPhotoIndex[userId] + 1) % user.photos.length;
|
currentPhotoIndex[userId] = (currentPhotoIndex[userId] + 1) % user.photos.length;
|
||||||
@ -304,65 +297,55 @@ const nextPhoto = (userId) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const prevPhoto = (userId) => {
|
const prevPhoto = (userId) => {
|
||||||
if (isDragging.value) return;
|
if (isPanning.value) return;
|
||||||
const user = suggestions.value.find(u => u._id === userId);
|
const user = suggestions.value.find(u => u._id === userId);
|
||||||
if (user && user.photos && user.photos.length > 0) {
|
if (user && user.photos && user.photos.length > 0) {
|
||||||
currentPhotoIndex[userId] = (currentPhotoIndex[userId] - 1 + user.photos.length) % user.photos.length;
|
currentPhotoIndex[userId] = (currentPhotoIndex[userId] - 1 + user.photos.length) % user.photos.length;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Методы для свайпа на мобильных
|
// Обработчики жестов для Hammer.js
|
||||||
const startTouch = (event) => {
|
const onPan = (event) => {
|
||||||
touchStartX.value = event.touches[0].clientX;
|
isPanning.value = true;
|
||||||
touchStartY.value = event.touches[0].clientY;
|
|
||||||
swipeDirection.value = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const moveTouch = (event) => {
|
|
||||||
if (!touchStartX.value) return;
|
|
||||||
|
|
||||||
const currentX = event.touches[0].clientX;
|
// Получаем смещение по x и y
|
||||||
const currentY = event.touches[0].clientY;
|
const deltaX = event.deltaX;
|
||||||
|
const deltaY = event.deltaY;
|
||||||
|
|
||||||
// Сохраняем текущую позицию для использования в endTouch
|
// Определяем направление свайпа для индикаторов
|
||||||
touchEndX.value = currentX;
|
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||||
touchEndY.value = currentY;
|
if (deltaX > 20) {
|
||||||
|
|
||||||
const diffX = currentX - touchStartX.value;
|
|
||||||
const diffY = currentY - touchStartY.value;
|
|
||||||
|
|
||||||
// Применяем точное смещение к карточке, чтобы она следовала за пальцем
|
|
||||||
// Нет дополнительных коэффициентов, карточка перемещается точно на то же расстояние, что и палец
|
|
||||||
if (Math.abs(diffX) > Math.abs(diffY)) {
|
|
||||||
// Определяем направление свайпа для индикаторов
|
|
||||||
if (diffX > 20) {
|
|
||||||
swipeDirection.value = 'right';
|
swipeDirection.value = 'right';
|
||||||
} else if (diffX < -20) {
|
} else if (deltaX < -20) {
|
||||||
swipeDirection.value = 'left';
|
swipeDirection.value = 'left';
|
||||||
} else {
|
} else {
|
||||||
swipeDirection.value = null;
|
swipeDirection.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Применяем небольшой поворот для естественности, но меньший чем был
|
// Применяем небольшой поворот для естественности
|
||||||
// 0.05 вместо 0.1, чтобы эффект был легче
|
const rotate = deltaX * 0.05;
|
||||||
const rotate = diffX * 0.05;
|
|
||||||
|
|
||||||
|
// Применяем точное смещение к карточке, она следует за пальцем 1 к 1
|
||||||
cardStyle.value = {
|
cardStyle.value = {
|
||||||
transform: `translateX(${diffX}px) rotate(${rotate}deg)`,
|
transform: `translateX(${deltaX}px) rotate(${rotate}deg)`,
|
||||||
transition: 'none'
|
transition: 'none'
|
||||||
};
|
};
|
||||||
|
}
|
||||||
// Блокируем скролл страницы
|
|
||||||
event.preventDefault();
|
// Блокируем скролл страницы при горизонтальном свайпе
|
||||||
|
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||||
|
event.srcEvent.preventDefault();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const endTouch = () => {
|
const onPanEnd = (event) => {
|
||||||
const diffX = touchEndX.value - touchStartX.value;
|
isPanning.value = false;
|
||||||
|
|
||||||
if (Math.abs(diffX) > swipeThreshold) {
|
// Проверяем, достаточно ли было смещение для действия
|
||||||
// Если свайп был достаточно длинный, анимируем к краю экрана
|
if (Math.abs(event.deltaX) > swipeThreshold) {
|
||||||
if (diffX > 0) {
|
// Если свайп был достаточно сильным, выполняем соответствующее действие
|
||||||
|
if (event.deltaX > 0) {
|
||||||
|
// Свайп вправо (лайк)
|
||||||
cardStyle.value = {
|
cardStyle.value = {
|
||||||
transform: `translateX(120%) rotate(${swipeAngle}deg)`,
|
transform: `translateX(120%) rotate(${swipeAngle}deg)`,
|
||||||
transition: 'transform 0.3s ease'
|
transition: 'transform 0.3s ease'
|
||||||
@ -370,6 +353,7 @@ const endTouch = () => {
|
|||||||
// Плавная анимация уходящей карточки
|
// Плавная анимация уходящей карточки
|
||||||
setTimeout(() => handleLike(), 300);
|
setTimeout(() => handleLike(), 300);
|
||||||
} else {
|
} else {
|
||||||
|
// Свайп влево (пропуск)
|
||||||
cardStyle.value = {
|
cardStyle.value = {
|
||||||
transform: `translateX(-120%) rotate(-${swipeAngle}deg)`,
|
transform: `translateX(-120%) rotate(-${swipeAngle}deg)`,
|
||||||
transition: 'transform 0.3s ease'
|
transition: 'transform 0.3s ease'
|
||||||
@ -385,98 +369,11 @@ const endTouch = () => {
|
|||||||
};
|
};
|
||||||
swipeDirection.value = null;
|
swipeDirection.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Сбрасываем значения
|
|
||||||
touchStartX.value = 0;
|
|
||||||
touchStartY.value = 0;
|
|
||||||
touchEndX.value = 0;
|
|
||||||
touchEndY.value = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Методы для свайпа на десктопе (drag)
|
const handleCardTap = (event) => {
|
||||||
const startDrag = (event) => {
|
// Обрабатываем обычный тап по карточке, если нужно
|
||||||
isDragging.value = true;
|
// Например, можно открыть полную информацию о пользователе
|
||||||
dragStartX.value = event.clientX;
|
|
||||||
dragStartY.value = event.clientY;
|
|
||||||
dragOffset.value = { x: 0, y: 0 };
|
|
||||||
swipeDirection.value = null;
|
|
||||||
|
|
||||||
// Предотвращаем выделение текста
|
|
||||||
event.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
const moveDrag = (event) => {
|
|
||||||
if (!isDragging.value) return;
|
|
||||||
|
|
||||||
dragOffset.value = {
|
|
||||||
x: event.clientX - dragStartX.value,
|
|
||||||
y: event.clientY - dragStartY.value
|
|
||||||
};
|
|
||||||
|
|
||||||
// Определяем направление свайпа для индикаторов
|
|
||||||
if (Math.abs(dragOffset.value.x) > Math.abs(dragOffset.value.y)) {
|
|
||||||
if (dragOffset.value.x > 20) {
|
|
||||||
swipeDirection.value = 'right';
|
|
||||||
} else if (dragOffset.value.x < -20) {
|
|
||||||
swipeDirection.value = 'left';
|
|
||||||
} else {
|
|
||||||
swipeDirection.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Применяем небольшой поворот для естественности (уменьшен)
|
|
||||||
const rotate = dragOffset.value.x * 0.05;
|
|
||||||
|
|
||||||
// Карточка следует точно за курсором, без дополнительных коэффициентов
|
|
||||||
cardStyle.value = {
|
|
||||||
transform: `translateX(${dragOffset.value.x}px) rotate(${rotate}deg)`,
|
|
||||||
transition: 'none'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
const endDrag = () => {
|
|
||||||
if (!isDragging.value) return;
|
|
||||||
|
|
||||||
if (Math.abs(dragOffset.value.x) > swipeThreshold) {
|
|
||||||
// Если перетаскивание было достаточно большим, выполняем действие лайка/пропуска с анимацией
|
|
||||||
if (dragOffset.value.x > 0) {
|
|
||||||
cardStyle.value = {
|
|
||||||
transform: `translateX(120%) rotate(${swipeAngle}deg)`,
|
|
||||||
transition: 'transform 0.3s ease'
|
|
||||||
};
|
|
||||||
// Плавная анимация уходящей карточки
|
|
||||||
setTimeout(() => handleLike(), 300);
|
|
||||||
} else {
|
|
||||||
cardStyle.value = {
|
|
||||||
transform: `translateX(-120%) rotate(-${swipeAngle}deg)`,
|
|
||||||
transition: 'transform 0.3s ease'
|
|
||||||
};
|
|
||||||
// Плавная анимация уходящей карточки
|
|
||||||
setTimeout(() => handlePass(), 300);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Если перетаскивание небольшое, плавно возвращаем карточку в исходное положение
|
|
||||||
cardStyle.value = {
|
|
||||||
transform: 'none',
|
|
||||||
transition: 'transform 0.3s ease'
|
|
||||||
};
|
|
||||||
swipeDirection.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
isDragging.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const cancelDrag = () => {
|
|
||||||
if (isDragging.value) {
|
|
||||||
cardStyle.value = {
|
|
||||||
transform: 'none',
|
|
||||||
transition: 'transform 0.3s ease'
|
|
||||||
};
|
|
||||||
swipeDirection.value = null;
|
|
||||||
isDragging.value = false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Основные функции
|
// Основные функции
|
||||||
@ -641,22 +538,10 @@ onMounted(() => {
|
|||||||
error.value = "Пожалуйста, войдите в систему, чтобы просматривать анкеты.";
|
error.value = "Пожалуйста, войдите в систему, чтобы просматривать анкеты.";
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Предотвращаем скролл страницы при свайпе
|
|
||||||
if (swipeArea.value) {
|
|
||||||
swipeArea.value.addEventListener('touchmove', (e) => {
|
|
||||||
if (isDragging.value) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
}, { passive: false });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// Удаляем слушатели событий
|
// Здесь можно выполнить очистку, если необходимо
|
||||||
if (swipeArea.value) {
|
|
||||||
swipeArea.value.removeEventListener('touchmove', null);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Следим за изменениями в списке предложений
|
// Следим за изменениями в списке предложений
|
||||||
@ -1250,6 +1135,18 @@ watch(suggestions, () => {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Добавляем стили для Swipe компонентов */
|
||||||
|
.swipe {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swipe-item {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Responsive Adjustments */
|
/* Responsive Adjustments */
|
||||||
@media (max-width: 576px) {
|
@media (max-width: 576px) {
|
||||||
.swipe-area {
|
.swipe-area {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user