properly handle mobile devices for autofocus

This commit is contained in:
Kévin Cocchi
2022-02-06 16:25:38 +01:00
parent e30535a975
commit 26ab8e2821
3 changed files with 44 additions and 8 deletions

View File

@ -15,7 +15,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { html, render, Component } from "../lib/htm/preact.js"
import { Spinner } from "./spinner.js"
import { shouldAutofocusSearchBar, SearchBox } from "./search-box.js"
import { shouldAutofocusSearchBar, shouldDisplayAutofocusSearchBar, SearchBox } from "./search-box.js"
import { checkMobileSafari } from "./user-agent-detect.js"
import * as widgetAPI from "./widget-api.js"
import * as frequent from "./frequently-used.js"
@ -35,7 +36,12 @@ const makeThumbnailURL = mxc => `${HOMESERVER_URL}/_matrix/media/r0/thumbnail/${
// We need to detect iOS webkit because it has a bug related to scrolling non-fixed divs
// This is also used to fix scrolling to sections on Element iOS
const isMobileSafari = navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/)
const isMobileSafari = checkMobileSafari()
// We need to detect iOS webkit / Android because autofocusing a field does not open
// the device keyboard by design, making the option obsolete
const shouldAutofocusOption = shouldAutofocusSearchBar()
const displayAutofocusOption = shouldDisplayAutofocusSearchBar()
const supportedThemes = ["light", "dark", "black"]
@ -338,14 +344,14 @@ const Settings = ({ app }) => html`
<option value="black">Black</option>
</select>
</div>
<div>
${displayAutofocusOption ? html`<div>
Autofocus search bar:
<input
type="checkbox"
checked=${shouldAutofocusSearchBar()}
checked=${shouldAutofocusOption}
onChange=${evt => app.setAutofocusSearchBar(evt.target.checked)}
/>
</div>
</div>` : null}
</div>
</section>
`

View File

@ -14,11 +14,15 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { html, Component } from "../lib/htm/preact.js"
import { checkMobileSafari, checkAndroid } from "./user-agent-detect.js"
export function shouldAutofocusSearchBar() {
return localStorage.mauAutofocusSearchBar === 'true'
export function shouldDisplayAutofocusSearchBar() {
return !checkMobileSafari() && !checkAndroid()
}
export function shouldAutofocusSearchBar() {
return localStorage.mauAutofocusSearchBar === 'true' && shouldDisplayAutofocusSearchBar()
}
export class SearchBox extends Component {
constructor(props) {
@ -33,6 +37,14 @@ export class SearchBox extends Component {
this.clearSearch = this.clearSearch.bind(this)
}
componentDidMount() {
// hack required for firefox
const inputInWebView = document.querySelector('.search-box input')
if (inputInWebView && this.autofocus) {
inputInWebView.focus()
}
}
componentWillReceiveProps(props) {
this.value = props.value
}
@ -63,7 +75,7 @@ export class SearchBox extends Component {
placeholder="Find stickers …"
value=${this.value}
onKeyUp=${this.search}
autofocus=${this.autofocus}
autoFocus=${this.autofocus}
/>
<div class=${className} title=${title} onClick=${onClick}>
<span class="icon ${iconToDisplay}" />

View File

@ -0,0 +1,18 @@
export const getUserAgent = () => navigator.userAgent || navigator.vendor || window.opera
export const checkiOSDevice = () => {
const agent = getUserAgent()
return agent.match(/(iPod|iPhone|iPad)/)
}
export const checkMobileSafari = () => {
const agent = getUserAgent()
return agent.match(/(iPod|iPhone|iPad)/) && agent.match(/AppleWebKit/)
}
export const checkAndroid = () => {
const agent = getUserAgent()
return agent.match(/android/i)
}
export const checkMobileDevice = () => checkiOSDevice() || checkAndroid()