Skip to content

Commit 0d62acf

Browse files
authored
add mobile keyboard icon. (#497)
1 parent d7e2e73 commit 0d62acf

File tree

1 file changed

+79
-2
lines changed

1 file changed

+79
-2
lines changed

client/src/components/video.vue

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@
4040
<li v-if="admin"><i @click.stop.prevent="openResolution" class="fas fa-desktop"></i></li>
4141
<li v-if="!controlLocked && !implicitHosting" :class="extraControls || 'extra-control'">
4242
<i
43-
:class="[hosted && !hosting ? 'disabled' : '', !hosted && !hosting ? 'faded' : '', 'fas', 'fa-keyboard']"
43+
:class="[
44+
hosted && !hosting ? 'disabled' : '',
45+
!hosted && !hosting ? 'faded' : '',
46+
'fas',
47+
'fa-computer-mouse',
48+
]"
4449
@click.stop.prevent="toggleControl"
4550
/>
4651
</li>
@@ -57,6 +62,13 @@
5762
class="fas fa-external-link-alt"
5863
/>
5964
</li>
65+
<li
66+
v-if="hosting && is_touch_device"
67+
:class="extraControls || 'extra-control'"
68+
@click.stop.prevent="toggleMobileKeyboard"
69+
>
70+
<i class="fas fa-keyboard" />
71+
</li>
6072
</ul>
6173
<neko-resolution ref="resolution" v-if="admin" />
6274
<neko-clipboard ref="clipboard" v-if="hosting && (!clipboard_read_available || !clipboard_write_available)" />
@@ -117,7 +129,7 @@
117129
}
118130
@media (max-width: 768px) {
119131
&.extra-control {
120-
display: inline-block;
132+
display: block;
121133
}
122134
}
123135
@@ -353,6 +365,17 @@
353365
return this.$accessor.video.horizontal
354366
}
355367
368+
get is_touch_device() {
369+
return (
370+
// check if the device has a touch screen
371+
('ontouchstart' in window || navigator.maxTouchPoints > 0) &&
372+
// we also check if the device has a pointer
373+
!window.matchMedia('(pointer:fine)').matches &&
374+
// and is capable of hover, then it probably has a mouse
375+
!window.matchMedia('(hover:hover)').matches
376+
)
377+
}
378+
356379
@Watch('width')
357380
onWidthChanged() {
358381
this.onResize()
@@ -804,5 +827,59 @@
804827
this._overlay.focus()
805828
}
806829
}
830+
831+
//
832+
// mobile keyboard
833+
//
834+
835+
kbdShow = false
836+
kbdOpen = false
837+
838+
showMobileKeyboard() {
839+
// skip if not a touch device
840+
if (!this.is_touch_device) return
841+
842+
this.kbdShow = true
843+
this.kbdOpen = false
844+
845+
const overlay = this.$refs.overlay as HTMLTextAreaElement
846+
overlay.focus()
847+
window.visualViewport?.addEventListener('resize', this.onVisualViewportResize)
848+
}
849+
850+
hideMobileKeyboard() {
851+
// skip if not a touch device
852+
if (!this.is_touch_device) return
853+
854+
this.kbdShow = false
855+
this.kbdOpen = false
856+
857+
const overlay = this.$refs.overlay as HTMLTextAreaElement
858+
window.visualViewport?.removeEventListener('resize', this.onVisualViewportResize)
859+
overlay.blur()
860+
}
861+
862+
toggleMobileKeyboard() {
863+
// skip if not a touch device
864+
if (!this.is_touch_device) return
865+
866+
if (this.kbdShow) {
867+
this.hideMobileKeyboard()
868+
} else {
869+
this.showMobileKeyboard()
870+
}
871+
}
872+
873+
// visual viewport resize event is fired when keyboard is opened or closed
874+
// android does not blur textarea when keyboard is closed, so we need to do it manually
875+
onVisualViewportResize() {
876+
if (!this.kbdShow) return
877+
878+
if (!this.kbdOpen) {
879+
this.kbdOpen = true
880+
} else {
881+
this.hideMobileKeyboard()
882+
}
883+
}
807884
}
808885
</script>

0 commit comments

Comments
 (0)