fix: Added backspace button on Super toolbar on Android as a workaround for backspace issue
This commit is contained in:
4
packages/icons/src/Icons/ic-backspace.svg
Normal file
4
packages/icons/src/Icons/ic-backspace.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="currentColor"
|
||||
d="m11.4 16l2.6-2.6l2.6 2.6l1.4-1.4l-2.6-2.6L18 9.4L16.6 8L14 10.6L11.4 8L10 9.4l2.6 2.6l-2.6 2.6l1.4 1.4ZM3 12l4.35-6.15q.275-.4.713-.625T9 5h10q.825 0 1.413.588T21 7v10q0 .825-.588 1.413T19 19H9q-.5 0-.938-.225t-.712-.625L3 12Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 330 B |
@@ -6,6 +6,7 @@ import AccountVariantIcon from './ic-account-variant.svg'
|
||||
import AddBoldIcon from './ic-add-bold.svg'
|
||||
import AddIcon from './ic-add.svg'
|
||||
import AddTextIcon from './ic-add-text.svg'
|
||||
import AegisIcon from './ic-aegis.svg'
|
||||
import ArchiveIcon from './ic-archive.svg'
|
||||
import ArrowDownCheckmarkIcon from './arrow-down-checkmark.svg'
|
||||
import ArrowDownIcon from './ic-arrow-down.svg'
|
||||
@@ -21,6 +22,7 @@ import AttachmentFileIcon from './ic-attachment-file.svg'
|
||||
import AuthenticatorIcon from './ic-authenticator.svg'
|
||||
import AuthenticatorVariantIcon from './ic-authenticator-variant.svg'
|
||||
import BackIosIcon from './ic-back-ios.svg'
|
||||
import BackspaceIcon from './ic-backspace.svg'
|
||||
import BlockIcon from './ic-block.svg'
|
||||
import BlueDotIcon from './blue-dot.svg'
|
||||
import BoldIcon from './ic-bold.svg'
|
||||
@@ -57,6 +59,7 @@ import EditorIcon from './ic-editor.svg'
|
||||
import EmailFilledIcon from './ic-email-filled.svg'
|
||||
import EmailIcon from './ic-email.svg'
|
||||
import EnterIcon from './ic-enter.svg'
|
||||
import EvernoteIcon from './ic-evernote.svg'
|
||||
import EyeFilledIcon from './ic-eye-filled.svg'
|
||||
import EyeIcon from './ic-eye.svg'
|
||||
import EyeOffFilledIcon from './ic-eye-off-filled.svg'
|
||||
@@ -87,6 +90,7 @@ import ForwardIosIcon from './ic-forward-ios.svg'
|
||||
import FullscreenExitIcon from './ic-fullscreen-exit.svg'
|
||||
import FullscreenIcon from './ic-fullscreen.svg'
|
||||
import GiftOutlineIcon from './ic-gift-outline.svg'
|
||||
import GoogleKeepIcon from './ic-gkeep.svg'
|
||||
import HashtagFilledIcon from './ic-hashtag-filled.svg'
|
||||
import HashtagIcon from './ic-hashtag.svg'
|
||||
import HashtagOffIcon from './ic-hashtag-off.svg'
|
||||
@@ -112,9 +116,9 @@ import LineWidthIcon from './ic-line-width.svg'
|
||||
import LinkIcon from './ic-link.svg'
|
||||
import LinkOffIcon from './ic-link-off.svg'
|
||||
import ListBulleted from './ic-list-bulleted.svg'
|
||||
import ListNumbered from './ic-list-numbered.svg'
|
||||
import ListedFilledIcon from './ic-listed-filled.svg'
|
||||
import ListedIcon from './ic-listed.svg'
|
||||
import ListNumbered from './ic-list-numbered.svg'
|
||||
import LockFilledIcon from './ic-lock-filled.svg'
|
||||
import LockIcon from './ic-lock.svg'
|
||||
import MarkdownIcon from './ic-markdown.svg'
|
||||
@@ -146,6 +150,8 @@ import PrintIcon from './ic-print.svg'
|
||||
import ProtectedIllustration from './il-protected.svg'
|
||||
import RedoIcon from './ic-redo.svg'
|
||||
import ReorderIcon from './ic-reorder.svg'
|
||||
import ReplaceAllIcon from './ic-replace-all.svg'
|
||||
import ReplaceIcon from './ic-replace.svg'
|
||||
import RestoreIcon from './ic-restore.svg'
|
||||
import RichTextIcon from './ic-text-rich.svg'
|
||||
import SafeIcon from './ic-safe.svg'
|
||||
@@ -164,6 +170,7 @@ import ShareIcon from './ic-share.svg'
|
||||
import ShortcutButtonIcon from './ic-shortcut-button.svg'
|
||||
import SignInIcon from './ic-signin.svg'
|
||||
import SignOutIcon from './ic-signout.svg'
|
||||
import SimplenoteIcon from './ic-simplenote.svg'
|
||||
import SNLogoAltIcon from './ic-standard-notes-2.svg'
|
||||
import SNLogoFull from './ic-sn-logo-full.svg'
|
||||
import SNLogoIcon from './ic-standard-notes.svg'
|
||||
@@ -201,12 +208,6 @@ import UserSwitch from './ic-user-switch.svg'
|
||||
import ViewIcon from './ic-view.svg'
|
||||
import WarningIcon from './ic-warning.svg'
|
||||
import WindowIcon from './ic-window.svg'
|
||||
import EvernoteIcon from './ic-evernote.svg'
|
||||
import GoogleKeepIcon from './ic-gkeep.svg'
|
||||
import SimplenoteIcon from './ic-simplenote.svg'
|
||||
import AegisIcon from './ic-aegis.svg'
|
||||
import ReplaceIcon from './ic-replace.svg'
|
||||
import ReplaceAllIcon from './ic-replace-all.svg'
|
||||
|
||||
export {
|
||||
AccessibilityIcon,
|
||||
@@ -232,6 +233,7 @@ export {
|
||||
AuthenticatorIcon,
|
||||
AuthenticatorVariantIcon,
|
||||
BackIosIcon,
|
||||
BackspaceIcon,
|
||||
BlockIcon,
|
||||
BlueDotIcon,
|
||||
BoldIcon,
|
||||
|
||||
@@ -41,7 +41,7 @@ const getColorsForPrimaryVariant = (style: AlertButtonStyle) => {
|
||||
type AlertButton = {
|
||||
text: string
|
||||
style: AlertButtonStyle
|
||||
action: () => void
|
||||
action?: () => void
|
||||
primary?: boolean
|
||||
}
|
||||
|
||||
@@ -168,7 +168,9 @@ export class SKAlert {
|
||||
this.buttons.forEach((buttonDesc, index) => {
|
||||
const buttonElem = this.element.querySelector(`#button-${index}`) as HTMLButtonElement
|
||||
buttonElem.onclick = () => {
|
||||
buttonDesc.action && buttonDesc.action()
|
||||
if (buttonDesc.action) {
|
||||
buttonDesc.action()
|
||||
}
|
||||
this.dismiss()
|
||||
}
|
||||
if (index === 0) {
|
||||
|
||||
@@ -73,6 +73,7 @@ export const IconNameToSvgMapping = {
|
||||
archive: icons.ArchiveIcon,
|
||||
asterisk: icons.AsteriskIcon,
|
||||
authenticator: icons.AuthenticatorIcon,
|
||||
backspace: icons.BackspaceIcon,
|
||||
bold: icons.BoldIcon,
|
||||
camera: icons.CameraIcon,
|
||||
check: icons.CheckIcon,
|
||||
|
||||
@@ -4,7 +4,7 @@ import useModal from '../../Lexical/Hooks/useModal'
|
||||
import { InsertTableDialog } from '../../Plugins/TablePlugin'
|
||||
import { getSelectedNode } from '../../Lexical/Utils/getSelectedNode'
|
||||
import { sanitizeUrl } from '../../Lexical/Utils/sanitizeUrl'
|
||||
import { $getSelection, $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical'
|
||||
import { $getSelection, $isRangeSelection, DELETE_CHARACTER_COMMAND, FORMAT_TEXT_COMMAND } from 'lexical'
|
||||
import { $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { GetAlignmentBlocks } from '../Blocks/Alignment'
|
||||
@@ -23,11 +23,14 @@ import { GetPasswordBlock } from '../Blocks/Password'
|
||||
import { GetQuoteBlock } from '../Blocks/Quote'
|
||||
import { GetTableBlock } from '../Blocks/Table'
|
||||
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
|
||||
import { classNames } from '@standardnotes/snjs'
|
||||
import { classNames, Platform } from '@standardnotes/snjs'
|
||||
import { SUPER_TOGGLE_SEARCH } from '@standardnotes/ui-services'
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
import { GetRemoteImageBlock } from '../Blocks/RemoteImage'
|
||||
import { InsertRemoteImageDialog } from '../RemoteImagePlugin/RemoteImagePlugin'
|
||||
import { SKAlert } from '@standardnotes/styles'
|
||||
|
||||
const DontShowSuperAndroidBackspaceAlertKey = 'dontShowSuperAndroidBackspaceAlert'
|
||||
|
||||
const MobileToolbarPlugin = () => {
|
||||
const application = useApplication()
|
||||
@@ -37,8 +40,10 @@ const MobileToolbarPlugin = () => {
|
||||
const [isInEditor, setIsInEditor] = useState(false)
|
||||
const [isInToolbar, setIsInToolbar] = useState(false)
|
||||
const isMobile = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
||||
const isAndroid = application.platform === Platform.Android
|
||||
|
||||
const toolbarRef = useRef<HTMLDivElement>(null)
|
||||
const backspaceButtonRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
const insertLink = useCallback(() => {
|
||||
const selection = $getSelection()
|
||||
@@ -156,7 +161,8 @@ const MobileToolbarPlugin = () => {
|
||||
|
||||
const handleFocus = () => setIsInEditor(true)
|
||||
const handleBlur = (event: FocusEvent) => {
|
||||
if (toolbarRef.current?.contains(event.relatedTarget as Node)) {
|
||||
const elementToBeFocused = event.relatedTarget as Node
|
||||
if (toolbarRef.current?.contains(elementToBeFocused) || elementToBeFocused === backspaceButtonRef.current) {
|
||||
return
|
||||
}
|
||||
setIsInEditor(false)
|
||||
@@ -179,7 +185,13 @@ const MobileToolbarPlugin = () => {
|
||||
const toolbar = toolbarRef.current
|
||||
|
||||
const handleFocus = () => setIsInToolbar(true)
|
||||
const handleBlur = () => setIsInToolbar(false)
|
||||
const handleBlur = (event: FocusEvent) => {
|
||||
const elementToBeFocused = event.relatedTarget as Node
|
||||
if (elementToBeFocused === backspaceButtonRef.current) {
|
||||
return
|
||||
}
|
||||
setIsInToolbar(false)
|
||||
}
|
||||
|
||||
toolbar.addEventListener('focus', handleFocus)
|
||||
toolbar.addEventListener('blur', handleBlur)
|
||||
@@ -190,6 +202,38 @@ const MobileToolbarPlugin = () => {
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAndroid) {
|
||||
return
|
||||
}
|
||||
|
||||
const dontShowAgain = application.getValue(DontShowSuperAndroidBackspaceAlertKey)
|
||||
|
||||
if (dontShowAgain) {
|
||||
return
|
||||
}
|
||||
|
||||
const alert = new SKAlert({
|
||||
title: 'Android backspace issue',
|
||||
text: 'There is a known issue with Super on Android where pressing the backspace will also delete the character after the cursor. We are working on a fix for this. Please use the backspace button in the toolbar as a workaround.',
|
||||
buttons: [
|
||||
{
|
||||
text: 'OK',
|
||||
style: 'default',
|
||||
},
|
||||
{
|
||||
text: "Don't show again",
|
||||
style: 'default',
|
||||
action: () => {
|
||||
application.setValue(DontShowSuperAndroidBackspaceAlertKey, true)
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
alert.present()
|
||||
}, [application, isAndroid])
|
||||
|
||||
const isFocusInEditorOrToolbar = isInEditor || isInToolbar
|
||||
if (!isMobile || !isFocusInEditorOrToolbar) {
|
||||
return null
|
||||
@@ -223,6 +267,20 @@ const MobileToolbarPlugin = () => {
|
||||
>
|
||||
<Icon type="keyboard-close" size="medium" />
|
||||
</button>
|
||||
{isAndroid && (
|
||||
<button
|
||||
className="flex flex-shrink-0 items-center justify-center rounded border-l border-border py-3 px-3"
|
||||
aria-label="Backspace"
|
||||
ref={backspaceButtonRef}
|
||||
onClick={() => {
|
||||
editor.update(() => {
|
||||
editor.dispatchCommand(DELETE_CHARACTER_COMMAND, true)
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Icon type="backspace" size="medium" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user