fix(mobile): increase font sizes and other mobile-centric improvements (#1907)

This commit is contained in:
Mo
2022-11-01 11:41:40 -05:00
committed by GitHub
parent f54b017f53
commit 994f824757
72 changed files with 543 additions and 283 deletions

View File

@@ -6,14 +6,23 @@ import { NotesController } from '@/Controllers/NotesController'
import { KeyboardKey } from '@standardnotes/ui-services'
import Popover from '../Popover/Popover'
import { LinkingController } from '@/Controllers/LinkingController'
import { IconType } from '@standardnotes/snjs'
type Props = {
navigationController: NavigationController
notesController: NotesController
linkingController: LinkingController
className: string
iconClassName: string
}
const AddTagOption: FunctionComponent<Props> = ({ navigationController, notesController, linkingController }) => {
const AddTagOption: FunctionComponent<Props> = ({
navigationController,
notesController,
linkingController,
className,
iconClassName,
}) => {
const menuContainerRef = useRef<HTMLDivElement>(null)
const buttonRef = useRef<HTMLButtonElement>(null)
@@ -33,10 +42,10 @@ const AddTagOption: FunctionComponent<Props> = ({ navigationController, notesCon
}
}}
ref={buttonRef}
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={className}
>
<div className="flex items-center">
<Icon type="hashtag" className="mr-2 text-neutral" />
<Icon type="hashtag" className={`${iconClassName} mr-2 text-neutral`} />
Add tag
</div>
<Icon type="chevron-right" className="text-neutral" />
@@ -52,13 +61,20 @@ const AddTagOption: FunctionComponent<Props> = ({ navigationController, notesCon
{navigationController.tags.map((tag) => (
<button
key={tag.uuid}
className="max-w-80 flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-2 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={`max-w-80 ${className.replace('justify-between', 'justify-start')}`}
onClick={() => {
notesController.isTagInSelectedNotes(tag)
? notesController.removeTagFromSelectedNotes(tag).catch(console.error)
: notesController.addTagToSelectedNotes(tag).catch(console.error)
}}
>
{tag.iconString && (
<Icon
type={tag.iconString as IconType}
size={'custom'}
className={'ml-0.5 mr-1.5 h-7 w-7 text-2xl text-neutral lg:h-6 lg:w-6 lg:text-lg'}
/>
)}
<span
className={`overflow-hidden overflow-ellipsis whitespace-nowrap
${notesController.isTagInSelectedNotes(tag) ? 'font-bold' : ''}`}

View File

@@ -9,9 +9,16 @@ import Popover from '../Popover/Popover'
type ChangeEditorOptionProps = {
application: WebApplication
note: SNNote
className: string
iconClassName: string
}
const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({ application, note }) => {
const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
application,
note,
className,
iconClassName,
}) => {
const [isOpen, setIsOpen] = useState(false)
const menuContainerRef = useRef<HTMLDivElement>(null)
const buttonRef = useRef<HTMLButtonElement>(null)
@@ -30,10 +37,10 @@ const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({ applic
}
}}
ref={buttonRef}
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={className}
>
<div className="flex items-center">
<Icon type="dashboard" className="mr-2 text-neutral" />
<Icon type="dashboard" className={`${iconClassName} mr-2 text-neutral`} />
Change note type
</div>
<Icon type="chevron-right" className="text-neutral" />

View File

@@ -9,9 +9,11 @@ import Popover from '../Popover/Popover'
type Props = {
application: WebApplication
note: SNNote
className: string
iconClassName: string
}
const ListedActionsOption: FunctionComponent<Props> = ({ application, note }) => {
const ListedActionsOption: FunctionComponent<Props> = ({ application, note, className, iconClassName }) => {
const menuContainerRef = useRef<HTMLDivElement>(null)
const buttonRef = useRef<HTMLButtonElement>(null)
@@ -37,10 +39,10 @@ const ListedActionsOption: FunctionComponent<Props> = ({ application, note }) =>
}
}}
ref={buttonRef}
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={className}
>
<div className="flex items-center">
<Icon type="listed" className="mr-2 text-neutral" />
<Icon type="listed" className={`mr-2 text-neutral ${iconClassName}`} />
Listed actions
</div>
<Icon type="chevron-right" className="text-neutral" />

View File

@@ -41,17 +41,19 @@ const ListedMenuItem: FunctionComponent<ListedMenuItemProps> = ({
onClick={handleClick}
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-2 text-left text-sm text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none"
>
<div className="flex flex-col">
<div className="font-semibold">{action.label}</div>
{action.access_type && (
<div className="mt-0.5 text-xs text-passive-0">
{'Uses '}
<strong>{action.access_type}</strong>
{' access to this note.'}
</div>
)}
<div className="flex w-full flex-row items-center justify-between">
<div className="flex flex-col">
<div className="font-semibold">{action.label}</div>
{action.access_type && (
<div className="mt-0.5 text-xs text-passive-0">
{'Uses '}
<strong>{action.access_type}</strong>
{' access to this note.'}
</div>
)}
</div>
{isRunning && <Spinner className="h-3 w-3" />}
</div>
{isRunning && <Spinner className="h-3 w-3" />}
</button>
)
}

View File

@@ -19,6 +19,8 @@ import { getNoteBlob, getNoteFileName } from '@/Utils/NoteExportUtils'
import { shareSelectedNotes } from '@/NativeMobileWeb/ShareSelectedNotes'
import { downloadSelectedNotesOnAndroid } from '@/NativeMobileWeb/DownloadSelectedNotesOnAndroid'
import ProtectedUnauthorizedLabel from '../ProtectedItemOverlay/ProtectedUnauthorizedLabel'
import { classNames } from '@/Utils/ConcatenateClassNames'
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
type DeletePermanentlyButtonProps = {
onClick: () => void
@@ -34,10 +36,11 @@ const DeletePermanentlyButton = ({ onClick }: DeletePermanentlyButtonProps) => (
</button>
)
const iconClass = 'text-neutral mr-2'
const iconClassDanger = 'text-danger mr-2'
const iconClassWarning = 'text-warning mr-2'
const iconClassSuccess = 'text-success mr-2'
const iconSize = MenuItemIconSize
const iconClass = `text-neutral mr-2 ${iconSize}`
const iconClassDanger = `text-danger mr-2 ${iconSize}`
const iconClassWarning = `text-warning mr-2 ${iconSize}`
const iconClassSuccess = `text-success mr-2 ${iconSize}`
const getWordCount = (text: string) => {
if (text.trim().length === 0) {
@@ -99,7 +102,7 @@ const NoteAttributes: FunctionComponent<{
const format = editor?.package_info?.file_type || 'txt'
return (
<div className="select-text px-3 py-1.5 text-xs font-medium text-neutral">
<div className="select-text px-3 py-1.5 text-sm font-medium text-neutral lg:text-xs">
{typeof words === 'number' && (format === 'txt' || format === 'md') ? (
<>
<div className="mb-1">
@@ -127,7 +130,8 @@ const SpellcheckOptions: FunctionComponent<{
editorForNote: SNComponent | undefined
notesController: NotesController
note: SNNote
}> = ({ editorForNote, notesController, note }) => {
className: string
}> = ({ editorForNote, notesController, note, className }) => {
const spellcheckControllable = Boolean(!editorForNote || editorForNote.package_info.spellcheckControl)
const noteSpellcheck = !spellcheckControllable
? true
@@ -138,7 +142,7 @@ const SpellcheckOptions: FunctionComponent<{
return (
<div className="flex flex-col">
<button
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={className}
onClick={() => {
notesController.toggleGlobalSpellcheckForNote(note).catch(console.error)
}}
@@ -273,14 +277,20 @@ const NotesOptions = ({
return <ProtectedUnauthorizedLabel />
}
const textClassNames = 'text-mobile-menu-item md:text-tablet-menu-item lg:text-menu-item'
const defaultClassNames = classNames(
textClassNames,
'flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none',
)
const switchClassNames = classNames(textClassNames, defaultClassNames, 'justify-between')
return (
<>
{notes.length === 1 && (
<>
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
onClick={openRevisionHistoryModal}
>
<button className={defaultClassNames} onClick={openRevisionHistoryModal}>
<Icon type="history" className={iconClass} />
Note history
</button>
@@ -288,7 +298,7 @@ const NotesOptions = ({
</>
)}
<button
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={switchClassNames}
onClick={() => {
notesController.setLockSelectedNotes(!locked)
}}
@@ -300,7 +310,7 @@ const NotesOptions = ({
<Switch className="px-0" checked={locked} />
</button>
<button
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={switchClassNames}
onClick={() => {
notesController.setHideSelectedNotePreviews(!hidePreviews)
}}
@@ -312,7 +322,7 @@ const NotesOptions = ({
<Switch className="px-0" checked={!hidePreviews} />
</button>
<button
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={switchClassNames}
onClick={() => {
notesController.setProtectSelectedNotes(!protect).catch(console.error)
}}
@@ -326,12 +336,19 @@ const NotesOptions = ({
{notes.length === 1 && (
<>
<HorizontalSeparator classes="my-2" />
<ChangeEditorOption application={application} note={notes[0]} />
<ChangeEditorOption
iconClassName={iconClass}
className={switchClassNames}
application={application}
note={notes[0]}
/>
</>
)}
<HorizontalSeparator classes="my-2" />
{navigationController.tagsCount > 0 && (
<AddTagOption
iconClassName={iconClass}
className={switchClassNames}
navigationController={navigationController}
notesController={notesController}
linkingController={linkingController}
@@ -339,7 +356,7 @@ const NotesOptions = ({
)}
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={() => {
notesController.setStarSelectedNotes(!starred)
}}
@@ -350,7 +367,7 @@ const NotesOptions = ({
{unpinned && (
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={() => {
notesController.setPinSelectedNotes(true)
}}
@@ -361,7 +378,7 @@ const NotesOptions = ({
)}
{pinned && (
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={() => {
notesController.setPinSelectedNotes(false)
}}
@@ -371,7 +388,7 @@ const NotesOptions = ({
</button>
)}
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={() => {
application.isNativeMobileWeb() ? shareSelectedNotes(application, notes) : downloadSelectedItems()
}}
@@ -380,24 +397,18 @@ const NotesOptions = ({
{application.platform === Platform.Android ? 'Share' : 'Export'}
</button>
{application.platform === Platform.Android && (
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
onClick={() => downloadSelectedNotesOnAndroid(application, notes)}
>
<button className={defaultClassNames} onClick={() => downloadSelectedNotesOnAndroid(application, notes)}>
<Icon type="download" className={iconClass} />
Export
</button>
)}
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
onClick={duplicateSelectedItems}
>
<button className={defaultClassNames} onClick={duplicateSelectedItems}>
<Icon type="copy" className={iconClass} />
Duplicate
</button>
{unarchived && (
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={async () => {
await notesController.setArchiveSelectedNotes(true).catch(console.error)
closeMenuAndToggleNotesList()
@@ -409,7 +420,7 @@ const NotesOptions = ({
)}
{archived && (
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={async () => {
await notesController.setArchiveSelectedNotes(false).catch(console.error)
closeMenuAndToggleNotesList()
@@ -429,7 +440,7 @@ const NotesOptions = ({
/>
) : (
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={async () => {
await notesController.setTrashSelectedNotes(true)
closeMenuAndToggleNotesList()
@@ -442,7 +453,7 @@ const NotesOptions = ({
{trashed && (
<>
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={async () => {
await notesController.setTrashSelectedNotes(false)
closeMenuAndToggleNotesList()
@@ -458,7 +469,7 @@ const NotesOptions = ({
}}
/>
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item"
className={defaultClassNames}
onClick={async () => {
await notesController.emptyTrash()
closeMenuAndToggleNotesList()
@@ -474,14 +485,31 @@ const NotesOptions = ({
</button>
</>
)}
{notes.length === 1 ? (
<>
<HorizontalSeparator classes="my-2" />
<ListedActionsOption application={application} note={notes[0]} />
<ListedActionsOption
iconClassName={iconClass}
className={switchClassNames}
application={application}
note={notes[0]}
/>
<HorizontalSeparator classes="my-2" />
<SpellcheckOptions editorForNote={editorForNote} notesController={notesController} note={notes[0]} />
<SpellcheckOptions
className={switchClassNames}
editorForNote={editorForNote}
notesController={notesController}
note={notes[0]}
/>
<HorizontalSeparator classes="my-2" />
<NoteAttributes application={application} note={notes[0]} />
<NoteSizeWarning note={notes[0]} />
</>
) : null}

View File

@@ -40,7 +40,7 @@ const NotesOptionsPanel = ({
return (
<>
<RoundIconButton label="Note options menu" onClick={toggleMenu} ref={buttonRef} icon="more" />
<Popover togglePopover={toggleMenu} anchorElement={buttonRef.current} open={isOpen} className="select-none py-2">
<Popover togglePopover={toggleMenu} anchorElement={buttonRef.current} open={isOpen} className="select-none">
<NotesOptions
application={application}
navigationController={navigationController}