mirror of
https://github.com/maunium/stickerpicker.git
synced 2025-07-17 06:23:28 +02:00
properly handle mobile devices for autofocus
This commit is contained in:
@ -15,7 +15,8 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { html, render, Component } from "../lib/htm/preact.js"
|
import { html, render, Component } from "../lib/htm/preact.js"
|
||||||
import { Spinner } from "./spinner.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 widgetAPI from "./widget-api.js"
|
||||||
import * as frequent from "./frequently-used.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
|
// 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
|
// 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"]
|
const supportedThemes = ["light", "dark", "black"]
|
||||||
|
|
||||||
@ -338,14 +344,14 @@ const Settings = ({ app }) => html`
|
|||||||
<option value="black">Black</option>
|
<option value="black">Black</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
${displayAutofocusOption ? html`<div>
|
||||||
Autofocus search bar:
|
Autofocus search bar:
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked=${shouldAutofocusSearchBar()}
|
checked=${shouldAutofocusOption}
|
||||||
onChange=${evt => app.setAutofocusSearchBar(evt.target.checked)}
|
onChange=${evt => app.setAutofocusSearchBar(evt.target.checked)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>` : null}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
`
|
`
|
||||||
|
@ -14,11 +14,15 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { html, Component } from "../lib/htm/preact.js"
|
import { html, Component } from "../lib/htm/preact.js"
|
||||||
|
import { checkMobileSafari, checkAndroid } from "./user-agent-detect.js"
|
||||||
|
|
||||||
export function shouldAutofocusSearchBar() {
|
export function shouldDisplayAutofocusSearchBar() {
|
||||||
return localStorage.mauAutofocusSearchBar === 'true'
|
return !checkMobileSafari() && !checkAndroid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function shouldAutofocusSearchBar() {
|
||||||
|
return localStorage.mauAutofocusSearchBar === 'true' && shouldDisplayAutofocusSearchBar()
|
||||||
|
}
|
||||||
|
|
||||||
export class SearchBox extends Component {
|
export class SearchBox extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -33,6 +37,14 @@ export class SearchBox extends Component {
|
|||||||
this.clearSearch = this.clearSearch.bind(this)
|
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) {
|
componentWillReceiveProps(props) {
|
||||||
this.value = props.value
|
this.value = props.value
|
||||||
}
|
}
|
||||||
@ -63,7 +75,7 @@ export class SearchBox extends Component {
|
|||||||
placeholder="Find stickers …"
|
placeholder="Find stickers …"
|
||||||
value=${this.value}
|
value=${this.value}
|
||||||
onKeyUp=${this.search}
|
onKeyUp=${this.search}
|
||||||
autofocus=${this.autofocus}
|
autoFocus=${this.autofocus}
|
||||||
/>
|
/>
|
||||||
<div class=${className} title=${title} onClick=${onClick}>
|
<div class=${className} title=${title} onClick=${onClick}>
|
||||||
<span class="icon ${iconToDisplay}" />
|
<span class="icon ${iconToDisplay}" />
|
||||||
|
18
web/src/user-agent-detect.js
Normal file
18
web/src/user-agent-detect.js
Normal 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()
|
Reference in New Issue
Block a user