mirror of
https://github.com/ThaUnknown/miru.git
synced 2026-03-11 22:15:35 +00:00
fix: improve keyboard navigation in text inputs
fix: w2g link pasting
This commit is contained in:
parent
1c76730528
commit
1df63a0716
8 changed files with 25 additions and 15 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ui",
|
||||
"version": "6.4.66",
|
||||
"version": "6.4.67",
|
||||
"license": "BUSL-1.1",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@9.15.5",
|
||||
|
|
|
|||
4
src/app.d.ts
vendored
4
src/app.d.ts
vendored
|
|
@ -36,8 +36,8 @@ declare global {
|
|||
}
|
||||
|
||||
interface Navigator {
|
||||
userAgentData: {
|
||||
getHighEntropyValues: (keys: string[]) => Promise<Record<string, string>>
|
||||
userAgentData?: {
|
||||
getHighEntropyValues?: (keys: string[]) => Promise<Record<string, string>>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
<Tabs.Trigger tabindex={0} value='extensions'>Extensions</Tabs.Trigger>
|
||||
<Tabs.Trigger tabindex={0} value='repositories'>Repositories</Tabs.Trigger>
|
||||
</Tabs.List>
|
||||
<div class='flex items-center relative scale-parent md:max-w-72 w-full'>
|
||||
<div class='flex items-center relative scale-parent md:max-w-56 w-full'>
|
||||
<Input
|
||||
class='pl-9 bg-neutral-950 select:bg-accent select:text-accent-foreground shadow-sm no-scale placeholder:opacity-50'
|
||||
placeholder='Search {value}...'
|
||||
|
|
|
|||
|
|
@ -213,15 +213,28 @@ function getElementsInDesiredDirection (keyboardFocusable: ElementPosition[], cu
|
|||
})
|
||||
}
|
||||
|
||||
// is input utility class
|
||||
function inInputEl (element: HTMLElement): element is HTMLInputElement {
|
||||
return element.matches('input, textarea')
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates using D-pad keys.
|
||||
*/
|
||||
function navigateDPad (direction = 'up') {
|
||||
function navigateDPad (direction = 'up', e: KeyboardEvent) {
|
||||
const keyboardFocusable = getFocusableElementPositions()
|
||||
const nofocus = !document.activeElement || document.activeElement === document.body
|
||||
const currentElement = nofocus ? keyboardFocusable[0]! : getElementPosition(document.activeElement as HTMLElement)
|
||||
|
||||
if (nofocus) return focusElement(currentElement.element)
|
||||
if (inInputEl(currentElement.element)) {
|
||||
const input = currentElement.element
|
||||
if (direction === 'left' && input.selectionStart !== 0) return
|
||||
if (direction === 'right' && input.selectionEnd !== input.value.length) return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
// allow overrides via data attributes ex: <div data-up="#id, #id2"?> but order them, as querySelectorAll returns them in order of appearance rather than order of selectors
|
||||
for (const selector of currentElement.element.dataset[direction]?.split(',') ?? []) {
|
||||
|
|
@ -260,13 +273,13 @@ function navigateDPad (direction = 'up') {
|
|||
|
||||
function focusElement (element?: HTMLElement | null) {
|
||||
if (!element) return false
|
||||
const isInput = element.matches('input[type=text], input[type=url], input[type=number], textarea')
|
||||
const isInput = inInputEl(element)
|
||||
if (isInput) {
|
||||
const input = element as HTMLInputElement
|
||||
const input = element
|
||||
input.readOnly = true
|
||||
}
|
||||
element.focus()
|
||||
if (isInput) setTimeout(() => { (element as HTMLInputElement).readOnly = false })
|
||||
if (isInput) setTimeout(() => { element.readOnly = false })
|
||||
element.scrollIntoView({ block: 'center', inline: 'center', behavior: 'smooth' })
|
||||
|
||||
element.dispatchEvent(new CustomEvent('navigate', { bubbles: true, composed: true, detail: { target: element.id, value: element.dataset.value } }))
|
||||
|
|
@ -280,10 +293,8 @@ document.addEventListener('keydown', navigate)
|
|||
|
||||
export function navigate (e: KeyboardEvent) {
|
||||
if (e.key in DirectionKeyMap) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
inputType.value = 'dpad'
|
||||
navigateDPad(DirectionKeyMap[e.key as 'ArrowDown' | 'ArrowUp' | 'ArrowLeft' | 'ArrowRight'])
|
||||
navigateDPad(DirectionKeyMap[e.key as 'ArrowDown' | 'ArrowUp' | 'ArrowLeft' | 'ArrowRight'], e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ export const flyAndScale = (
|
|||
|
||||
export const sleep = (t: number) => new Promise<void>(resolve => setTimeout(resolve, t))
|
||||
|
||||
export const highEntropyValues = 'userAgentData' in navigator && navigator.userAgentData.getHighEntropyValues(['architecture', 'platform', 'platformVersion'])
|
||||
export const highEntropyValues = 'userAgentData' in navigator && navigator.userAgentData?.getHighEntropyValues?.(['architecture', 'platform', 'platformVersion'])
|
||||
|
||||
export function safeLocalStorage<T> (key: string): T | undefined {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
const imageRx = /\.(jpeg|jpg|gif|png|webp)/i
|
||||
|
||||
const w2gRx = /hayase(?:(?:\.watch)|(?::\/))\/w2g\/(.+)/
|
||||
const w2gRx = /hayas.?ee?(?:(?:\.watch)|(?::\/))?\/w2g\/(.+)/
|
||||
|
||||
async function handleTransfer (e: { dataTransfer?: DataTransfer | null, clipboardData?: DataTransfer | null } & Event) {
|
||||
const promises = [...(e.dataTransfer ?? e.clipboardData)!.items].map(item => {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
const info = {
|
||||
...device,
|
||||
appInfo: {
|
||||
userAgent: await navigator.userAgentData.getHighEntropyValues(['architecture', 'platform', 'platformVersion']),
|
||||
userAgent: await navigator.userAgentData?.getHighEntropyValues?.(['architecture', 'platform', 'platformVersion']),
|
||||
support: SUPPORTS,
|
||||
settings: $settings
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
<div class='text-6xl text-center font-bold'>Update Required</div>
|
||||
<Separator class='my-6 w-40' />
|
||||
<div class='text-xl text-wrap max-w-full text-center mb-6'>A mandatory update is available for the {#await outdatedComponent then name}{name}{/await}.<br />Please update to continue.</div>
|
||||
|
||||
{#await outdatedComponent then name}
|
||||
{#if name === 'client'}
|
||||
{#await native.updateReady()}
|
||||
|
|
|
|||
Loading…
Reference in a new issue