feat(search): add keyboard hide button and auto-hide Dock
- Add floating keyboard hide button that appears on search input focus - Create KeyboardStore to manage keyboard state globally - Auto-hide Dock component when keyboard is open on search page - Position keyboard hide button at bottom when Dock is hidden - Update keyboard state on focus, blur, and hide actions
This commit is contained in:
@@ -42,6 +42,7 @@ import {FullscreenViewport, useMiniApp, useWebAppViewport} from 'vue-tg';
|
|||||||
import {useRoute, useRouter} from "vue-router";
|
import {useRoute, useRouter} from "vue-router";
|
||||||
import {useSettingsStore} from "@/stores/SettingsStore.js";
|
import {useSettingsStore} from "@/stores/SettingsStore.js";
|
||||||
import {useProductFiltersStore} from "@/stores/ProductFiltersStore.js";
|
import {useProductFiltersStore} from "@/stores/ProductFiltersStore.js";
|
||||||
|
import {useKeyboardStore} from "@/stores/KeyboardStore.js";
|
||||||
import CartButton from "@/components/CartButton.vue";
|
import CartButton from "@/components/CartButton.vue";
|
||||||
import Dock from "@/components/Dock.vue";
|
import Dock from "@/components/Dock.vue";
|
||||||
import AppDebugMessage from "@/components/AppDebugMessage.vue";
|
import AppDebugMessage from "@/components/AppDebugMessage.vue";
|
||||||
@@ -58,6 +59,7 @@ const router = useRouter();
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const settings = useSettingsStore();
|
const settings = useSettingsStore();
|
||||||
const filtersStore = useProductFiltersStore();
|
const filtersStore = useProductFiltersStore();
|
||||||
|
const keyboardStore = useKeyboardStore();
|
||||||
const backButton = window.Telegram.WebApp.BackButton;
|
const backButton = window.Telegram.WebApp.BackButton;
|
||||||
const haptic = window.Telegram.WebApp.HapticFeedback;
|
const haptic = window.Telegram.WebApp.HapticFeedback;
|
||||||
const drawerOpen = ref(false);
|
const drawerOpen = ref(false);
|
||||||
@@ -70,7 +72,14 @@ const routesToHideAppDock = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const isAppDockShown = computed(() => {
|
const isAppDockShown = computed(() => {
|
||||||
return routesToHideAppDock.indexOf(route.name) === -1;
|
if (routesToHideAppDock.indexOf(route.name) === -1) {
|
||||||
|
// Скрываем Dock, если клавиатура открыта на странице поиска
|
||||||
|
if (route.name === 'search' && keyboardStore.isOpen) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
function navigateBack() {
|
function navigateBack() {
|
||||||
|
|||||||
15
frontend/spa/src/stores/KeyboardStore.js
Normal file
15
frontend/spa/src/stores/KeyboardStore.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import {defineStore} from "pinia";
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
|
export const useKeyboardStore = defineStore('keyboard', {
|
||||||
|
state: () => ({
|
||||||
|
isOpen: false,
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
setOpen(value) {
|
||||||
|
this.isOpen = value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
<button
|
<button
|
||||||
v-if="showHideKeyboardButton"
|
v-if="showHideKeyboardButton"
|
||||||
@click="handleHideKeyboardClick"
|
@click="handleHideKeyboardClick"
|
||||||
class="btn btn-circle btn-primary fixed bottom-20 right-4 z-50 shadow-lg"
|
class="btn btn-circle btn-primary fixed bottom-4 right-4 z-50 shadow-lg"
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="Скрыть клавиатуру"
|
aria-label="Скрыть клавиатуру"
|
||||||
>
|
>
|
||||||
@@ -124,6 +124,7 @@ import {useSearchStore} from "@/stores/SearchStore.js";
|
|||||||
import {useDebounceFn} from "@vueuse/core";
|
import {useDebounceFn} from "@vueuse/core";
|
||||||
import {computed, onMounted, ref} from "vue";
|
import {computed, onMounted, ref} from "vue";
|
||||||
import {useYaMetrikaStore} from "@/stores/yaMetrikaStore.js";
|
import {useYaMetrikaStore} from "@/stores/yaMetrikaStore.js";
|
||||||
|
import {useKeyboardStore} from "@/stores/KeyboardStore.js";
|
||||||
import {useRoute} from "vue-router";
|
import {useRoute} from "vue-router";
|
||||||
import {YA_METRIKA_GOAL} from "@/constants/yaMetrikaGoals.js";
|
import {YA_METRIKA_GOAL} from "@/constants/yaMetrikaGoals.js";
|
||||||
import BaseViewWrapper from "@/views/BaseViewWrapper.vue";
|
import BaseViewWrapper from "@/views/BaseViewWrapper.vue";
|
||||||
@@ -133,6 +134,7 @@ import {renderSmartNumber} from "../helpers.js";
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const yaMetrika = useYaMetrikaStore();
|
const yaMetrika = useYaMetrikaStore();
|
||||||
const searchStore = useSearchStore();
|
const searchStore = useSearchStore();
|
||||||
|
const keyboardStore = useKeyboardStore();
|
||||||
const searchInput = ref(null);
|
const searchInput = ref(null);
|
||||||
const debouncedSearch = useDebounceFn(() => searchStore.performSearch(), 800);
|
const debouncedSearch = useDebounceFn(() => searchStore.performSearch(), 800);
|
||||||
|
|
||||||
@@ -156,24 +158,28 @@ const handleEnter = (event) => {
|
|||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
showHideKeyboardButton.value = false;
|
showHideKeyboardButton.value = false;
|
||||||
|
keyboardStore.setOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const showHideKeyboardButton = ref(false);
|
const showHideKeyboardButton = ref(false);
|
||||||
|
|
||||||
const handleFocus = () => {
|
const handleFocus = () => {
|
||||||
showHideKeyboardButton.value = true;
|
showHideKeyboardButton.value = true;
|
||||||
|
keyboardStore.setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
// Не скрываем сразу, даем время на клик по кнопке
|
// Не скрываем сразу, даем время на клик по кнопке
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
showHideKeyboardButton.value = false;
|
showHideKeyboardButton.value = false;
|
||||||
|
keyboardStore.setOpen(false);
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleHideKeyboardClick = () => {
|
const handleHideKeyboardClick = () => {
|
||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
showHideKeyboardButton.value = false;
|
showHideKeyboardButton.value = false;
|
||||||
|
keyboardStore.setOpen(false);
|
||||||
if (searchInput.value) {
|
if (searchInput.value) {
|
||||||
searchInput.value.blur();
|
searchInput.value.blur();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user