deptyped / vue-telegram

Telegram integration for Vue
https://vue-tg.deptyped.com
MIT License
172 stars 11 forks source link

Is it possible to disable app close when swipe down? #11

Closed Raxort closed 2 months ago

Raxort commented 8 months ago

Hello! Right now if the mini app is open (fully expanded) and you swipe screen down the app closes. It's a standard behavior for many apps. But I have seen an app that doesn't cloce on swipe-down. It stays open and it doesn't even change the viewport size when you drag it down. It stays full height despite this.

Is it possible to do the same with vue-telegram ???

Thank you in advance!

deptyped commented 8 months ago

Hello!

But I have seen an app that doesn't cloce on swipe-down. It stays open and it doesn't even change the viewport size when you drag it down

Can you show me an app doing this? Probably some hacks are used to make Telegram app think that there is scrollable content in the webview.

The intended way to prevent an app from closing is to use a closing confirmation:

<script lang="ts" setup>
import { useWebAppClosingConfirmation } from 'vue-tg'

const { enableClosingConfirmation, disableClosingConfirmation } = useWebAppClosingConfirmation()

enableClosingConfirmation()

// or

const { isClosingConfirmationEnabled } = useWebAppClosingConfirmation()

isClosingConfirmationEnabled.value = true
</script>

This will open a confirmation popup when the app closes.

Raxort commented 8 months ago

Here is an example of the App that doesn't close on drag down: https://t.me/notcoin_bot It's a game and in this case such App behavior doesn't break user experience.

deptyped commented 8 months ago

Here is an example of the App that doesn't close on drag down: t.me/notcoin_bot

Doesn't work for me. If I understand you correctly I should not be able to close the app this way?

https://github.com/deptyped/vue-telegram/assets/26162440/914ee473-50d6-4ad6-85b7-45db8cdfe67b

Telegram Android v10.6.3 (4355)

Raxort commented 8 months ago

Yes, you got me right. But on my smartphone, it doesn't close when you drag it down... iPhone.

deptyped commented 8 months ago

Yes, it works on iPhone but unreliably, sometimes I can close the app this way, sometimes not. Looks more like a bug in the Telegram app rather than something done on the Notcoin web app side.

maybephilipp commented 6 months ago

Another app that have done that perfectly (tg bot) @tapswap_bot

I'm still investigating how they have done that, but it doesn't even try to swipe, just locked.

deptyped commented 6 months ago

@maybephilipp Interesting, looks like some height: 100vh + overflow: hidden magic, this prevents closing, but also breaks scrolling

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://telegram.org/js/telegram-web-app.js"></script>
    <style>
        body {
            height: 100vh;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <script>
        Telegram.WebApp.expand()
        window.addEventListener("touchmove", (e) => e.preventDefault(), { passive: false });
        window.scrollTo(0, 100);
        Telegram.WebApp.ready()
    </script>
</body>
</html>
maybephilipp commented 6 months ago

Yeah @deptyped I've investigated their source code (debug) and found the solution. I've also made the scrolling working (their solution was breaking it)

So steps to implement:

  1. Document/body magic (without this touchmove step doesn't fix the problem for some reason):

(tailwind style) document: h-auto, overflow-hidden body: min-h-screen h-screen overflow-hidden

js code:

const overflow = 100
document.body.style.overflowY = 'hidden'
document.body.style.marginTop = `${overflow}px`
document.body.style.height = window.innerHeight + overflow + "px"
document.body.style.paddingBottom = `${overflow}px`
window.scrollTo(0, overflow)
  1. Block touchmove (block scroll on doc and body, because of the first step. Make body's child scrollable and then...):
    let ts: number | undefined
    const onTouchStart = (e: TouchEvent) => {
    ts = e.touches[0].clientY
    }
    const onTouchMove = (e: TouchEvent) => {
    if (scrollableEl) {
    const scroll = scrollableEl.scrollTop
    const te = e.changedTouches[0].clientY
    if (scroll <= 0 && ts! < te) {
      e.preventDefault()
    }
    } else {
    e.preventDefault()
    }
    }
    document.documentElement.addEventListener('touchstart', onTouchStart, { passive: false })
    document.documentElement.addEventListener('touchmove', onTouchMove, { passive: false })

After that it works perfectly, no rage scroll breaks it. The only concern is that maybe some device has reversed scroll direction, in that case we will need to reverse touchmove condition logic, but anyway - it's working.

Chambo015 commented 5 months ago
onst overflow = 100
document.body.style.overflowY = 'hidden'
document.body.style.marginTop = `${overflow}px`
document.body.style.height = window.innerHeight + overflow + "px"
document.body.style.paddingBottom = `${overflow}px`
window.scrollTo(0, overflow)

it's awesome !

hosseinmobarakian commented 4 months ago
const overflow = 100
document.body.style.overflowY = 'hidden'
document.body.style.marginTop = `${overflow}px`
document.body.style.height = window.innerHeight + overflow + "px"
document.body.style.paddingBottom = `${overflow}px`
window.scrollTo(0, overflow)

It's work for me also, Thank you bro @maybephilipp

Reeennooo commented 4 months ago

@maybephilipp, what is scrollableEl ? Could you provide the component code?

maybephilipp commented 4 months ago

@maybephilipp, what is scrollableEl ? Could you provide the component code?

@Reeennooo please find it here: https://github.com/TelegramMessenger/Telegram-iOS/issues/1070#issuecomment-2053975640

php-lixianzi commented 3 months ago

Yeah @deptyped I've investigated their source code (debug) and found the solution. I've also made the scrolling working (their solution was breaking it)

So steps to implement:

  1. Document/body magic (without this touchmove step doesn't fix the problem for some reason):

(tailwind style) document: h-auto, overflow-hidden body: min-h-screen h-screen overflow-hidden

js code:

const overflow = 100
document.body.style.overflowY = 'hidden'
document.body.style.marginTop = `${overflow}px`
document.body.style.height = window.innerHeight + overflow + "px"
document.body.style.paddingBottom = `${overflow}px`
window.scrollTo(0, overflow)
  1. Block touchmove (block scroll on doc and body, because of the first step. Make body's child scrollable and then...):
let ts: number | undefined
const onTouchStart = (e: TouchEvent) => {
  ts = e.touches[0].clientY
}
const onTouchMove = (e: TouchEvent) => {
  if (scrollableEl) {
    const scroll = scrollableEl.scrollTop
    const te = e.changedTouches[0].clientY
    if (scroll <= 0 && ts! < te) {
      e.preventDefault()
    }
  } else {
    e.preventDefault()
  }
}
document.documentElement.addEventListener('touchstart', onTouchStart, { passive: false })
document.documentElement.addEventListener('touchmove', onTouchMove, { passive: false })

After that it works perfectly, no rage scroll breaks it. The only concern is that maybe some device has reversed scroll direction, in that case we will need to reverse touchmove condition logic, but anyway - it's working.

牛逼

zlccns commented 3 months ago

是的@deptyped 我调查了他们的源代码(调试)并找到了解决方案。我还是使用滚动功能阅读(破坏他们的解决方案)

实施步骤如下:

  1. 文档/正文(缺少此touchmove步骤,由于某种原因无法执行):

(顺风风格) document: h-auto, overflow-hidden body: min-h-screen h-screen overflow-hidden

js代码:

const overflow = 100
document.body.style.overflowY = 'hidden'
document.body.style.marginTop = `${overflow}px`
document.body.style.height = window.innerHeight + overflow + "px"
document.body.style.paddingBottom = `${overflow}px`
window.scrollTo(0, overflow)
  1. 阻止 touchmove(阻止在 doc 和 body 上滚动,因为第一步。使 body 的子项可滚动然后...):
let ts: number | undefined
const onTouchStart = (e: TouchEvent) => {
  ts = e.touches[0].clientY
}
const onTouchMove = (e: TouchEvent) => {
  if (scrollableEl) {
    const scroll = scrollableEl.scrollTop
    const te = e.changedTouches[0].clientY
    if (scroll <= 0 && ts! < te) {
      e.preventDefault()
    }
  } else {
    e.preventDefault()
  }
}
document.documentElement.addEventListener('touchstart', onTouchStart, { passive: false })
document.documentElement.addEventListener('touchmove', onTouchMove, { passive: false })

之后,它就完美地运行了,没有愤怒滚动会破坏它。唯一担心的是,也许有些设备反转了滚动方向,这样,我们需要反转 touchmove 条件逻辑,但无论如何 - 它正在工作。

牛逼

mikiyasET commented 2 months ago

Thanks maybephilipp...

In addition to maybephilipp solution you have to expand the window in some cases for this to work using Telegram.WebApp.expand() or if you are using packages like telegram-mini-app use WebApp.expand()

deptyped commented 2 months ago

Finally, with the latest Bot API 7.7 update, Telegram supports this natively 🎉

Support for Bot API 7.7 has been added to vue-tg in 0.7.0.

You can now disable vertical swipes easily:

<script lang="ts" setup>
import { useWebAppViewport } from 'vue-tg'

const { enableVerticalSwipes, disableVerticalSwipes } = useWebAppViewport()

disableVerticalSwipes()

// or

const { isVerticalSwipesEnabled } = useWebAppViewport()

isVerticalSwipesEnabled.value = false
</script>

Also, you can check if this feature is supported:

<script lang="ts" setup>
import { useWebApp, useWebAppViewport } from 'vue-tg'

const { isFeatureSupported } = useWebApp()
const { disableVerticalSwipes } = useWebAppViewport()

if (isFeatureSupported('DisableVerticalSwipes')) {
  disableVerticalSwipes()
} else {
  // some kind of fallback or alert
}
</script>
rn-lazuka commented 2 months ago

But it isn't work, in console I can see warning that current version 7.6 doesn't support this feature...

deptyped commented 2 months ago

@rn-lazuka This is correct, Bot API 7.6 does not support this feature. Make sure your Telegram client supports Bot API 7.7.

<script lang="ts" setup>
import { useWebApp } from 'vue-tg'

const { version } = useWebApp()

console.log('Supported Bot API version:', version)
</script>
rn-lazuka commented 2 months ago

@rn-lazuka This is correct, Bot API 7.6 does not support this feature. Make sure your Telegram client supports Bot API 7.7.

<script lang="ts" setup>
import { useWebApp } from 'vue-tg'

const { version } = useWebApp()

console.log('Supported Bot API version:', version)
</script>

It's not my client, it's telegram client, and they don't update it. Since begining of July

deptyped commented 2 months ago

@rn-lazuka Bot API 7.7 available in beta version of some Telegram apps (Telegram Android Beta, for example)