From 770dbbd68a4fe278970859864ba667f21692088d Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Thu, 7 Apr 2022 15:54:07 -0700 Subject: [PATCH 01/91] Add margins on wider screens, keyboard commands to adjust --- .../components/templates/PrimaryLayout.tsx | 9 ++++++- .../templates/article/ArticleContainer.tsx | 24 +++++++++++++++---- .../keyboardShortcuts/navigationShortcuts.ts | 14 +++++++++++ .../web/pages/[username]/[slug]/index.tsx | 19 ++++++++++++++- 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/packages/web/components/templates/PrimaryLayout.tsx b/packages/web/components/templates/PrimaryLayout.tsx index 17757cacd..b3b1d1db6 100644 --- a/packages/web/components/templates/PrimaryLayout.tsx +++ b/packages/web/components/templates/PrimaryLayout.tsx @@ -62,7 +62,14 @@ export function PrimaryLayout(props: PrimaryLayoutProps): JSX.Element { {props.pageMetaDataProps ? ( ) : null} - + l.id) || [] ) const updateFontSize = async (newFontSize: number) => { - setFontSize(newFontSize) - await userPersonalizationMutation({ fontSize: newFontSize }) + if (fontSize !== newFontSize) { + setFontSize(newFontSize) + await userPersonalizationMutation({ fontSize: newFontSize }) + } + } + + const updateMargin = async (newMargin: number) => { + if (margin !== newMargin) { + setMargin(newMargin) + await userPersonalizationMutation({ margin: newMargin }) + } } useEffect(() => { updateFontSize(props.fontSize ?? 20) }, [props.fontSize]) + useEffect(() => { + updateMargin(props.margin ?? 140) + }, [props.margin]) + // Listen for font size and color mode change events sent from host apps (ios, macos...) useEffect(() => { const increaseFontSize = async () => { @@ -101,6 +115,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { css={{ padding: '16px', maxWidth: '94%', + background: props.isAppleAppEmbed ? 'unset' : theme.colors.grayBg.toString(), '--text-font-family': styles.fontFamily, '--text-font-size': `${styles.fontSize}px`, '--line-height': `150%`, @@ -112,12 +127,13 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { '--font-color-transparent': styles.readerFontColorTransparent, '--table-header-color': styles.readerTableHeaderColor, '--headers-color': styles.readerHeadersColor, + margin: `30px 0px`, '@sm': { '--blockquote-padding': '1em 2em', '--blockquote-icon-font-size': '1.7rem', '--figure-margin': '2.6875rem auto', '--hr-margin': '2em', - margin: `30px ${styles.margin / 2}px`, + margin: `30px 0px`, }, '@md': { maxWidth: '92%', @@ -125,7 +141,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { '@lg': { margin: `30px 0`, width: 'auto', - maxWidth: 1024 - styles.margin, + maxWidth: 1024 - (styles.margin), }, }} > diff --git a/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts b/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts index e516aa2fe..2ce3f7ab8 100644 --- a/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts +++ b/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts @@ -207,6 +207,8 @@ type ArticleKeyboardAction = | 'openOriginalArticle' | 'incrementFontSize' | 'decrementFontSize' + | 'incrementMarginWidth' + | 'decrementMarginWidth' | 'editLabels' export function articleKeyboardCommands( @@ -238,6 +240,18 @@ export function articleKeyboardCommands( shortcutKeyDescription: '-', callback: () => actionHandler('decrementFontSize'), }, + { + shortcutKeys: [']'], + actionDescription: 'Increase margin width', + shortcutKeyDescription: ']', + callback: () => actionHandler('incrementMarginWidth'), + }, + { + shortcutKeys: ['['], + actionDescription: 'Decrease margin width', + shortcutKeyDescription: '[', + callback: () => actionHandler('decrementMarginWidth'), + }, { shortcutKeys: ['l'], actionDescription: 'Edit labels', diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index a341789af..4bbf2cc2e 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -23,6 +23,7 @@ import Script from 'next/script' import { EditLabelsModal } from '../../../components/templates/article/EditLabelsModal' import { Label } from '../../../lib/networking/fragments/labelFragment' import { isVipUser } from '../../../lib/featureFlag' +import { theme } from '../../../components/tokens/stitches.config' const PdfArticleContainerNoSSR = dynamic( () => import('./../../../components/templates/article/PdfArticleContainer'), @@ -45,12 +46,16 @@ export default function Home(): JSX.Element { const { preferencesData } = useGetUserPreferences() const article = articleData?.article.article const [fontSize, setFontSize] = useState(preferencesData?.fontSize ?? 20) + const [marginWidth, setMarginWidth] = useState(preferencesData?.fontSize ?? 20) useKeyboardShortcuts(navigationCommands(router)) const updateFontSize = async (newFontSize: number) => { setFontSize(newFontSize) - await userPersonalizationMutation({ fontSize: newFontSize }) + } + + const updateMarginWidth = async (newMargin: number) => { + setMarginWidth(newMargin) } useKeyboardShortcuts( @@ -68,6 +73,12 @@ export default function Home(): JSX.Element { case 'decrementFontSize': await updateFontSize(Math.max(fontSize - 2, 10)) break + case 'incrementMarginWidth': + updateMarginWidth(Math.min(marginWidth + 50, 560)) + break + case 'decrementMarginWidth': + updateMarginWidth(Math.max(marginWidth - 50, 0)) + break case 'editLabels': if (viewerData?.me && isVipUser(viewerData?.me)) { setShowLabelsModal(true) @@ -108,6 +119,11 @@ export default function Home(): JSX.Element { distribution="center" ref={scrollRef} className="disable-webkit-callout" + css={{ + '@smDown': { + background: theme.colors.grayBg.toString(), + } + }} > Date: Thu, 7 Apr 2022 20:23:27 -0700 Subject: [PATCH 02/91] WIP: reader control breakpoints This implements the left side controls on desktop and in the header on smaller screens. partial work, committing as-is to test on device --- .../elements/images/OmnivoreNameLogo.tsx | 3 +- .../web/components/patterns/PrimaryHeader.tsx | 47 +++++++++++++- .../templates/article/ArticleContainer.tsx | 10 +-- .../web/components/tokens/stitches.config.ts | 1 + .../web/pages/[username]/[slug]/index.tsx | 63 ++++++++++++++++++- 5 files changed, 112 insertions(+), 12 deletions(-) diff --git a/packages/web/components/elements/images/OmnivoreNameLogo.tsx b/packages/web/components/elements/images/OmnivoreNameLogo.tsx index 482845d0d..0f3e25328 100644 --- a/packages/web/components/elements/images/OmnivoreNameLogo.tsx +++ b/packages/web/components/elements/images/OmnivoreNameLogo.tsx @@ -2,6 +2,7 @@ import { config } from '../../tokens/stitches.config' import Image from 'next/image' import { StyledText } from '../../elements/StyledText' import Link from 'next/link' +import { SpanBox } from '../LayoutPrimitives' export function OmnivoreNameLogoImage(): JSX.Element { return ( @@ -51,7 +52,7 @@ export function OmnivoreNameLogo(props: OmnivoreNameLogoProps): JSX.Element { - Omnivore + {/* Omnivore */} ) diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index a74c39999..32e347c37 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -17,7 +17,7 @@ import { UserBasicData } from '../../lib/networking/queries/useGetViewerQuery' import { setupAnalytics } from '../../lib/analytics' import { Button } from '../elements/Button' import Link from 'next/link' -import { ArrowSquareOut } from 'phosphor-react' +import { ArchiveBox, ArrowSquareOut, DotsThree, HighlighterCircle, TagSimple, TextAa } from 'phosphor-react' type HeaderProps = { user?: UserBasicData @@ -183,12 +183,53 @@ function NavHeader(props: NavHeaderProps): JSX.Element { + + + + + + + + + + + + + + + {props.username ? ( - + {/* - + */} l.id) || [] ) @@ -99,7 +100,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { }, [props.article]) const styles = { - margin: props.margin ?? 140, + margin: props.margin ?? 360, fontSize, fontFamily: props.fontFamily ?? 'inter', readerFontColor: theme.colors.readerFont.toString(), @@ -114,7 +115,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { id="article-container" css={{ padding: '16px', - maxWidth: '94%', + maxWidth: '100%', background: props.isAppleAppEmbed ? 'unset' : theme.colors.grayBg.toString(), '--text-font-family': styles.fontFamily, '--text-font-size': `${styles.fontSize}px`, @@ -127,7 +128,6 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { '--font-color-transparent': styles.readerFontColorTransparent, '--table-header-color': styles.readerTableHeaderColor, '--headers-color': styles.readerHeadersColor, - margin: `30px 0px`, '@sm': { '--blockquote-padding': '1em 2em', '--blockquote-icon-font-size': '1.7rem', @@ -136,7 +136,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { margin: `30px 0px`, }, '@md': { - maxWidth: '92%', + maxWidth: 1024 - (styles.margin), }, '@lg': { margin: `30px 0`, diff --git a/packages/web/components/tokens/stitches.config.ts b/packages/web/components/tokens/stitches.config.ts index 7e9500fcf..de59a709b 100644 --- a/packages/web/components/tokens/stitches.config.ts +++ b/packages/web/components/tokens/stitches.config.ts @@ -156,6 +156,7 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } = xsmDown: '(max-width: 375px)', smDown: '(max-width: 575px)', mdDown: '(max-width: 768px)', + lgDown: '(max-width: 992px)', sm: '(min-width: 576px)', md: '(min-width: 768px)', lg: '(min-width: 992px)', diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index 4bbf2cc2e..697c3f9c3 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -23,7 +23,18 @@ import Script from 'next/script' import { EditLabelsModal } from '../../../components/templates/article/EditLabelsModal' import { Label } from '../../../lib/networking/fragments/labelFragment' import { isVipUser } from '../../../lib/featureFlag' -import { theme } from '../../../components/tokens/stitches.config' +import { styled, theme } from '../../../components/tokens/stitches.config' +import { Button } from '../../../components/elements/Button' +import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from 'phosphor-react' +import { Separator } from '@radix-ui/react-separator' + +const MenuSeparator = styled(Separator, { + width: '100%', + margin: 0, + backgroundColor: 'red', + borderBottom: `1px solid ${theme.colors.grayLine.toString()}`, + my: '8px', +}) const PdfArticleContainerNoSSR = dynamic( () => import('./../../../components/templates/article/PdfArticleContainer'), @@ -46,15 +57,17 @@ export default function Home(): JSX.Element { const { preferencesData } = useGetUserPreferences() const article = articleData?.article.article const [fontSize, setFontSize] = useState(preferencesData?.fontSize ?? 20) - const [marginWidth, setMarginWidth] = useState(preferencesData?.fontSize ?? 20) + const [marginWidth, setMarginWidth] = useState(preferencesData?.margin ?? 360) useKeyboardShortcuts(navigationCommands(router)) const updateFontSize = async (newFontSize: number) => { setFontSize(newFontSize) + await userPersonalizationMutation({ fontSize: newFontSize }) } const updateMarginWidth = async (newMargin: number) => { + console.log('margin', newMargin) setMarginWidth(newMargin) } @@ -77,7 +90,7 @@ export default function Home(): JSX.Element { updateMarginWidth(Math.min(marginWidth + 50, 560)) break case 'decrementMarginWidth': - updateMarginWidth(Math.max(marginWidth - 50, 0)) + updateMarginWidth(Math.max(marginWidth - 50, 200)) break case 'editLabels': if (viewerData?.me && isVipUser(viewerData?.me)) { @@ -108,6 +121,50 @@ export default function Home(): JSX.Element { /> + + + + + + + + + + + + + + + + {article.contentReader == 'PDF' ? ( Date: Thu, 7 Apr 2022 20:50:59 -0700 Subject: [PATCH 03/91] Simplify --- packages/web/components/patterns/PrimaryHeader.tsx | 10 +++++----- packages/web/pages/[username]/[slug]/index.tsx | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index 32e347c37..2dde10616 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -202,22 +202,22 @@ function NavHeader(props: NavHeaderProps): JSX.Element { m: '0px', }} > - - - - - diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index 697c3f9c3..0a0711f70 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -141,25 +141,25 @@ export default function Home(): JSX.Element { m: '0px', }} > - - - - + - - + - From 602dbb29be362f0af2e8a55b3cac61be52220639 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Thu, 7 Apr 2022 21:11:40 -0700 Subject: [PATCH 04/91] Play with transparent header in desktop --- packages/web/components/patterns/PrimaryHeader.tsx | 7 ++++--- packages/web/components/templates/PrimaryLayout.tsx | 12 ++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index 2dde10616..9e40bf6f7 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -159,16 +159,17 @@ function NavHeader(props: NavHeaderProps): JSX.Element { zIndex: 5, width: '100%', boxShadow: props.isDisplayingShadow ? '$panelShadow' : 'unset', - bg: '$grayBase', p: '0px $3 0px $3', height: '68px', position: 'fixed', - minHeight: '68px', + bg: 'transparent', '@smDown': { height: '48px', - minHeight: '48px', p: '0px 18px 0px 16px', }, + '@lgDown': { + bg: '$grayBase', + }, }} > diff --git a/packages/web/components/templates/PrimaryLayout.tsx b/packages/web/components/templates/PrimaryLayout.tsx index b3b1d1db6..3c7764c90 100644 --- a/packages/web/components/templates/PrimaryLayout.tsx +++ b/packages/web/components/templates/PrimaryLayout.tsx @@ -84,8 +84,8 @@ export function PrimaryLayout(props: PrimaryLayoutProps): JSX.Element { + {props.children} {showLogoutConfirmation ? ( Date: Fri, 8 Apr 2022 09:56:29 -0700 Subject: [PATCH 05/91] Encapsulate the article actions menu, standardize header height at 48px --- .../templates/article/ArticleActionsMenu.tsx | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 packages/web/components/templates/article/ArticleActionsMenu.tsx diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx new file mode 100644 index 000000000..0e30ec958 --- /dev/null +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -0,0 +1,69 @@ +import { Separator } from "@radix-ui/react-separator" +import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from "phosphor-react" +import { Button } from "../../elements/Button" +import { Box } from "../../elements/LayoutPrimitives" +import { styled, theme } from "../../tokens/stitches.config" + +export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' + +type ArticleActionsMenuProps = { + // pageTestId: string + // hideHeader?: boolean + // pageMetaDataProps?: PageMetaDataProps + // scrollElementRef?: MutableRefObject + // displayFontStepper?: boolean + layout: ArticleActionsMenuLayout +} + + + +export function MenuSeparator(props: ArticleActionsMenuProps) { + const LineSeparator = styled(Separator, { + width: '100%', + margin: 0, + backgroundColor: 'red', + borderBottom: `1px solid ${theme.colors.grayLine.toString()}`, + my: '8px', + }) + return (props.layout == 'vertical' ? : <>) +} + +export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element { + return ( + + + + + + + + + + + + + + ) +} \ No newline at end of file From 19e3af66d5a06861ea426b7a4ae4a98462a0ae18 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 10:01:14 -0700 Subject: [PATCH 06/91] Encapsulate the article actions menu, standardize header height at 48px --- packages/web/components/elements/Button.tsx | 8 ++++ .../web/components/patterns/PrimaryHeader.tsx | 46 ++----------------- .../components/templates/PrimaryLayout.tsx | 5 +- .../components/templates/SettingsLayout.tsx | 3 +- .../web/pages/[username]/[slug]/index.tsx | 36 ++------------- 5 files changed, 17 insertions(+), 81 deletions(-) diff --git a/packages/web/components/elements/Button.tsx b/packages/web/components/elements/Button.tsx index b3ccce06d..ccd3b0131 100644 --- a/packages/web/components/elements/Button.tsx +++ b/packages/web/components/elements/Button.tsx @@ -153,6 +153,14 @@ export const Button = styled('button', { opacity: 0.8, }, }, + articleActionIcon: { + bg: 'transparent', + border: 'none', + cursor: 'pointer', + '&:hover': { + opacity: 0.8, + }, + }, ghost: { color: 'transparent', border: 'none', diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index 9e40bf6f7..2d62089c7 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -18,6 +18,7 @@ import { setupAnalytics } from '../../lib/analytics' import { Button } from '../elements/Button' import Link from 'next/link' import { ArchiveBox, ArrowSquareOut, DotsThree, HighlighterCircle, TagSimple, TextAa } from 'phosphor-react' +import { ArticleActionsMenu } from '../templates/article/ArticleActionsMenu' type HeaderProps = { user?: UserBasicData @@ -160,11 +161,10 @@ function NavHeader(props: NavHeaderProps): JSX.Element { width: '100%', boxShadow: props.isDisplayingShadow ? '$panelShadow' : 'unset', p: '0px $3 0px $3', - height: '68px', + height: '48px', position: 'fixed', bg: 'transparent', '@smDown': { - height: '48px', p: '0px 18px 0px 16px', }, '@lgDown': { @@ -195,33 +195,8 @@ function NavHeader(props: NavHeaderProps): JSX.Element { mr: '16px', }} > - - + - - - - - - - @@ -230,21 +205,6 @@ function NavHeader(props: NavHeaderProps): JSX.Element { alignment="center" css={{ display: 'flex', alignItems: 'center' }} > - {/* - - - - */} {props.children} diff --git a/packages/web/components/templates/SettingsLayout.tsx b/packages/web/components/templates/SettingsLayout.tsx index 7f8f09f26..c2df14f0d 100644 --- a/packages/web/components/templates/SettingsLayout.tsx +++ b/packages/web/components/templates/SettingsLayout.tsx @@ -54,8 +54,7 @@ export function SettingsLayout(props: SettingsLayoutProps): JSX.Element { /> - - - - - - - - - - - - - + - {article.contentReader == 'PDF' ? ( Date: Fri, 8 Apr 2022 10:36:45 -0700 Subject: [PATCH 07/91] Use a themed font colour for the article actions buttons --- .../templates/article/ArticleActionsMenu.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 0e30ec958..4e0eb283c 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -44,25 +44,25 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element }} > ) From 32b08d11124e7db5f9f4ea94a758d348eba28edc Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 10:42:20 -0700 Subject: [PATCH 08/91] Disable dots menu Since there are no extra actions yet --- .../templates/article/ArticleActionsMenu.tsx | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 4e0eb283c..8be346b8c 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -7,16 +7,9 @@ import { styled, theme } from "../../tokens/stitches.config" export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' type ArticleActionsMenuProps = { - // pageTestId: string - // hideHeader?: boolean - // pageMetaDataProps?: PageMetaDataProps - // scrollElementRef?: MutableRefObject - // displayFontStepper?: boolean layout: ArticleActionsMenuLayout } - - export function MenuSeparator(props: ArticleActionsMenuProps) { const LineSeparator = styled(Separator, { width: '100%', @@ -33,11 +26,12 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element + @@ -59,11 +54,11 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element - + {/* + */} ) } \ No newline at end of file From 78129a4a85ccc15cc603ab4017f4ba03819ebcfe Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 15:26:18 -0700 Subject: [PATCH 09/91] WIP: article actoins and reader settings --- .../components/elements/DropdownElements.tsx | 8 ++ .../components/elements/TickedRangeSlider.tsx | 39 ++++++ .../web/components/elements/images/AIcon.tsx | 14 +++ .../templates/article/ArticleActionsMenu.tsx | 52 ++++++-- .../templates/article/EditLabelsModal.tsx | 1 - .../templates/article/ReaderSettingsModal.tsx | 90 ++++++++++++++ .../web/pages/[username]/[slug]/index.tsx | 113 +++++++++++------- packages/web/styles/globals.css | 36 ++++++ 8 files changed, 299 insertions(+), 54 deletions(-) create mode 100644 packages/web/components/elements/TickedRangeSlider.tsx create mode 100644 packages/web/components/elements/images/AIcon.tsx create mode 100644 packages/web/components/templates/article/ReaderSettingsModal.tsx diff --git a/packages/web/components/elements/DropdownElements.tsx b/packages/web/components/elements/DropdownElements.tsx index 818898f06..d5f3b78c6 100644 --- a/packages/web/components/elements/DropdownElements.tsx +++ b/packages/web/components/elements/DropdownElements.tsx @@ -65,6 +65,7 @@ const StyledLabel = styled(Label, { }) export type DropdownAlignment = 'start' | 'end' | 'center' +export type DropdownSide = 'top' | 'right' | 'bottom' | 'left' type DropdownProps = { labelText?: string @@ -73,6 +74,8 @@ type DropdownProps = { children: React.ReactNode styledArrow?: boolean align?: DropdownAlignment + side?: DropdownSide + sideOffset?: number disabled?: boolean css?: CSS } @@ -108,8 +111,11 @@ export function Dropdown({ labelText, showArrow = true, disabled = false, + side = 'bottom', + sideOffset = 0, css }: DropdownProps): JSX.Element { + console.log('side', side) return ( {triggerElement} @@ -119,6 +125,8 @@ export function Dropdown({ // remove focus from dropdown ;(document.activeElement as HTMLElement).blur() }} + side={side} + sideOffset={sideOffset} align={align ? align : 'center'} > {labelText && {labelText}} diff --git a/packages/web/components/elements/TickedRangeSlider.tsx b/packages/web/components/elements/TickedRangeSlider.tsx new file mode 100644 index 000000000..c112d8d73 --- /dev/null +++ b/packages/web/components/elements/TickedRangeSlider.tsx @@ -0,0 +1,39 @@ + + +import { Box, HStack } from './LayoutPrimitives' +import { styled, theme } from '../tokens/stitches.config' + +type TickedRangeSliderProps = { + ticks?: number, + value: number, + onChange: (value: number) => void, + min?: number, + max?: number, + step?: number, +} + +const Tick = styled(Box, { + background: theme.colors.grayBorderHover, + width: 2, + height: 8, +}) + +export function TickedRangeSlider({ + ticks = 8, + min = 10, + max = 28, + step = 1, + value, + onChange, + } : TickedRangeSliderProps +): JSX.Element { + + return ( + + onChange(e.target.value as any)} value={value} type="range" min={min} max={max} step={step} className='slider'/> + + {[...Array(ticks)].map((val, idx) => )} + + + ) +} \ No newline at end of file diff --git a/packages/web/components/elements/images/AIcon.tsx b/packages/web/components/elements/images/AIcon.tsx new file mode 100644 index 000000000..f7972a2f0 --- /dev/null +++ b/packages/web/components/elements/images/AIcon.tsx @@ -0,0 +1,14 @@ +type AIconProps = { + size: number + color: string + style?: React.CSSProperties +} + +export function AIcon(props: AIconProps): JSX.Element { + return ( + + + + + ) +} \ No newline at end of file diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 8be346b8c..0dab2698f 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -1,20 +1,26 @@ import { Separator } from "@radix-ui/react-separator" import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from "phosphor-react" import { Button } from "../../elements/Button" -import { Box } from "../../elements/LayoutPrimitives" +import { Dropdown } from "../../elements/DropdownElements" +import { Box, SpanBox } from "../../elements/LayoutPrimitives" import { styled, theme } from "../../tokens/stitches.config" +import { ReaderSettings } from "./ReaderSettingsModal" export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' type ArticleActionsMenuProps = { layout: ArticleActionsMenuLayout + articleActionHandler: (action: string, arg?: number) => void } -export function MenuSeparator(props: ArticleActionsMenuProps) { +type MenuSeparatorProps = { + layout: ArticleActionsMenuLayout +} + +export function MenuSeparator(props: MenuSeparatorProps) { const LineSeparator = styled(Separator, { width: '100%', margin: 0, - backgroundColor: 'red', borderBottom: `1px solid ${theme.colors.grayLine.toString()}`, my: '8px', }) @@ -23,12 +29,12 @@ export function MenuSeparator(props: ArticleActionsMenuProps) { export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element { return ( + <> - + + + + } + css={{ m: '0px', p: '0px', outlineStyle: 'solid', outlineWidth: '1px', outlineColor: theme.colors.grayLine.toString() }} + > + + + - + + + + } + css={{ background: 'red' }} + > + {/* */} + - - {/* @@ -60,5 +85,6 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element */} + ) } \ No newline at end of file diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index 6b3e043d5..d06cc6e04 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -15,7 +15,6 @@ import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticle import { LabelChip } from '../../elements/LabelChip' type EditLabelsModalProps = { - labels: Label[] article: ArticleAttributes onOpenChange: (open: boolean) => void setLabels: (labels: Label[]) => void diff --git a/packages/web/components/templates/article/ReaderSettingsModal.tsx b/packages/web/components/templates/article/ReaderSettingsModal.tsx new file mode 100644 index 000000000..b51669c2c --- /dev/null +++ b/packages/web/components/templates/article/ReaderSettingsModal.tsx @@ -0,0 +1,90 @@ +import { + ModalRoot, + ModalOverlay, + ModalContent, +} from '../../elements/ModalPrimitives' +import { Box, HStack, VStack, Separator, SpanBox } from '../../elements/LayoutPrimitives' +import { Button } from '../../elements/Button' +import { StyledText } from '../../elements/StyledText' +import { CrossIcon } from '../../elements/images/CrossIcon' +import { CommentIcon } from '../../elements/images/CommentIcon' +import { TrashIcon } from '../../elements/images/TrashIcon' +import { styled, theme } from '../../tokens/stitches.config' +import type { Highlight } from '../../../lib/networking/fragments/highlightFragment' +import { HighlightView } from '../../patterns/HighlightView' +import { useCallback, useState } from 'react' +import { StyledTextArea } from '../../elements/StyledTextArea' +import { ConfirmationModal } from '../../patterns/ConfirmationModal' +import { AlignCenterHorizontalSimple, ArrowsInLineHorizontal, ArrowsOutLineHorizontal, Minus, Pen, Plus, Trash } from 'phosphor-react' +import { AIcon } from '../../elements/images/AIcon' +import { TickedRangeSlider } from '../../elements/TickedRangeSlider' + +type ReaderSettingsProps = { + +} + +export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { + const VerticalDivider = styled(SpanBox, { + width: '1px', + height: '100%', + background: `${theme.colors.grayLine.toString()}`, + }) + return ( + + + + + + + + Margin: + + + {}} /> + + + + + Line Height: + + + {}} /> + + + + + ) +} diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index 14b61bcb2..f35f94e8a 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -29,6 +29,8 @@ import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from 'pho import { Separator } from '@radix-ui/react-separator' import { Article } from '../../../components/templates/article/Article' import { ArticleActionsMenu } from '../../../components/templates/article/ArticleActionsMenu' +import { HighlightsModal } from '../../../components/templates/article/HighlightsModal' +import { setLinkArchivedMutation } from '../../../lib/networking/mutations/setLinkArchivedMutation' const MenuSeparator = styled(Separator, { width: '100%', @@ -48,6 +50,7 @@ export default function Home(): JSX.Element { const scrollRef = useRef(null) const { slug } = router.query const [showLabelsModal, setShowLabelsModal] = useState(false) + const [showHighlightsModal, setShowHighlightsModal] = useState(false) // Populate data cache const { viewerData } = useGetViewerQuery() @@ -73,33 +76,51 @@ export default function Home(): JSX.Element { setMarginWidth(newMargin) } + const actionHandler = async (action: string, arg?: number) => { + switch (action) { + case 'archive': + if (article) { + await setLinkArchivedMutation({ + linkId: article.id, + archived: true, + }) + // TODO: merge from article actions PR + // removeItemFromCache(cache, mutate, props.article.id) + router.push(`/home`) + } + break + case 'openOriginalArticle': + const url = article?.url + if (url) { + window.open(url, '_blank') + } + break + case 'showHighlights': + setShowHighlightsModal(true) + break + case 'incrementFontSize': + await updateFontSize(Math.min(fontSize + 2, 28)) + break + case 'decrementFontSize': + await updateFontSize(Math.max(fontSize - 2, 10)) + break + case 'incrementMarginWidth': + updateMarginWidth(Math.min(marginWidth + 50, 560)) + break + case 'decrementMarginWidth': + updateMarginWidth(Math.max(marginWidth - 50, 200)) + break + case 'editLabels': + if (viewerData?.me && isVipUser(viewerData?.me)) { + setShowLabelsModal(true) + } + break + } + }; + useKeyboardShortcuts( articleKeyboardCommands(router, async (action) => { - switch (action) { - case 'openOriginalArticle': - const url = article?.url - if (url) { - window.open(url, '_blank') - } - break - case 'incrementFontSize': - await updateFontSize(Math.min(fontSize + 2, 28)) - break - case 'decrementFontSize': - await updateFontSize(Math.max(fontSize - 2, 10)) - break - case 'incrementMarginWidth': - updateMarginWidth(Math.min(marginWidth + 50, 560)) - break - case 'decrementMarginWidth': - updateMarginWidth(Math.max(marginWidth - 50, 200)) - break - case 'editLabels': - if (viewerData?.me && isVipUser(viewerData?.me)) { - setShowLabelsModal(true) - } - break - } + actionHandler(action) }) ) @@ -124,19 +145,22 @@ export default function Home(): JSX.Element { - - + position: 'fixed', + flexDirection: 'row-reverse', + top: '-120px', + left: 8, + height: '100%', + width: '48px', + '@lgDown': { + display: 'none', + }, + }} + > + + {article.contentReader == 'PDF' ? ( + + )} + {showHighlightsModal && ( + setShowHighlightsModal(false)} + deleteHighlightAction={(highlightId: string) => { + // removeHighlightCallback(highlightId) + }} + /> + )} {/* {showLabelsModal && ( )} */} - - )} ) } diff --git a/packages/web/styles/globals.css b/packages/web/styles/globals.css index 573f58d7f..dda271556 100644 --- a/packages/web/styles/globals.css +++ b/packages/web/styles/globals.css @@ -99,3 +99,39 @@ div#appleid-signin { border-bottom-color: transparent; border-left-color: transparent; } + +.slider { + -webkit-appearance: none; + appearance: none; + width: 100%; + height: 1px; + background: var(--colors-grayBorderHover); +} + +.slider::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 16px !important; + height: 16px; + border-radius: 50%; + background: var(--colors-utilityTextContrast); + cursor: pointer; +} + +.slider::-moz-range-thumb { + -webkit-appearance: none; + width: 16px !important; + height: 16px; + border-radius: 50%; + background: var(--colors-utilityTextContrast); + cursor: pointer; +} + +input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + border: none; + height: 16px; + width: 16px; + border-radius: 50%; + background: var(--colors-grayTextContrast); +} \ No newline at end of file From ba301c4f0f428c6934ce618aaacf2245dc638f81 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 15:44:52 -0700 Subject: [PATCH 10/91] Sliders --- .../web/components/patterns/PrimaryHeader.tsx | 2 +- .../templates/article/ArticleActionsMenu.tsx | 4 +- .../templates/article/ArticleContainer.tsx | 1 - .../templates/article/ReaderSettingsModal.tsx | 44 ++++++++++--------- .../web/pages/[username]/[slug]/index.tsx | 1 + 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index 2d62089c7..f539fa5fd 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -195,7 +195,7 @@ function NavHeader(props: NavHeaderProps): JSX.Element { mr: '16px', }} > - + {/* */} diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 0dab2698f..01cc1d26c 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -1,5 +1,6 @@ import { Separator } from "@radix-ui/react-separator" import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from "phosphor-react" +import { UserPreferences } from "../../../lib/networking/queries/useGetUserPreferences" import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" import { Box, SpanBox } from "../../elements/LayoutPrimitives" @@ -10,6 +11,7 @@ export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' type ArticleActionsMenuProps = { layout: ArticleActionsMenuLayout + userPreferences?: UserPreferences articleActionHandler: (action: string, arg?: number) => void } @@ -54,7 +56,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } css={{ m: '0px', p: '0px', outlineStyle: 'solid', outlineWidth: '1px', outlineColor: theme.colors.grayLine.toString() }} > - + diff --git a/packages/web/components/templates/article/ArticleContainer.tsx b/packages/web/components/templates/article/ArticleContainer.tsx index 6dc5dd79a..de0866809 100644 --- a/packages/web/components/templates/article/ArticleContainer.tsx +++ b/packages/web/components/templates/article/ArticleContainer.tsx @@ -13,7 +13,6 @@ import { ArticleHeaderToolbar } from './ArticleHeaderToolbar' import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation' import { updateThemeLocally } from '../../../lib/themeUpdater' import { ArticleMutations } from '../../../lib/articleActions' -import { TextAa } from 'phosphor-react' type ArticleContainerProps = { article: ArticleAttributes diff --git a/packages/web/components/templates/article/ReaderSettingsModal.tsx b/packages/web/components/templates/article/ReaderSettingsModal.tsx index b51669c2c..f6eccae5d 100644 --- a/packages/web/components/templates/article/ReaderSettingsModal.tsx +++ b/packages/web/components/templates/article/ReaderSettingsModal.tsx @@ -18,9 +18,11 @@ import { ConfirmationModal } from '../../patterns/ConfirmationModal' import { AlignCenterHorizontalSimple, ArrowsInLineHorizontal, ArrowsOutLineHorizontal, Minus, Pen, Plus, Trash } from 'phosphor-react' import { AIcon } from '../../elements/images/AIcon' import { TickedRangeSlider } from '../../elements/TickedRangeSlider' +import { UserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' type ReaderSettingsProps = { - + userPreferences?: UserPreferences + articleActionHandler: (action: string, arg?: number) => void } export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { @@ -34,40 +36,42 @@ export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { - - - + Margin: - - {}} /> - - - + */} ) } diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index f35f94e8a..c0514ca29 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -158,6 +158,7 @@ export default function Home(): JSX.Element { > From 278a885f83a466cc7ed03efb003288cf640262f5 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 20:19:18 -0700 Subject: [PATCH 11/91] Edit labels menu --- .../templates/article/ArticleActionsMenu.tsx | 8 +- .../templates/article/EditLabelsModal.tsx | 333 +++++++++++++----- .../templates/article/ReaderSettingsModal.tsx | 2 +- 3 files changed, 260 insertions(+), 83 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 01cc1d26c..1d989599c 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -5,6 +5,7 @@ import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" import { Box, SpanBox } from "../../elements/LayoutPrimitives" import { styled, theme } from "../../tokens/stitches.config" +import { EditLabelsModal } from "./EditLabelsModal" import { ReaderSettings } from "./ReaderSettingsModal" export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' @@ -54,7 +55,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } - css={{ m: '0px', p: '0px', outlineStyle: 'solid', outlineWidth: '1px', outlineColor: theme.colors.grayLine.toString() }} + css={{ m: '0px', p: '0px' }} > @@ -63,13 +64,16 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } - css={{ background: 'red' }} + css={{ m: '0px', p: '0px' }} > + {/* */} diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index d06cc6e04..1d74f4574 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -3,108 +3,281 @@ import { ModalOverlay, ModalRoot, } from '../../elements/ModalPrimitives' -import { HStack, VStack } from '../../elements/LayoutPrimitives' +import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives' import { Button } from '../../elements/Button' import { StyledText } from '../../elements/StyledText' import { CrossIcon } from '../../elements/images/CrossIcon' -import { theme } from '../../tokens/stitches.config' +import { styled, theme } from '../../tokens/stitches.config' import { Label, useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery' -import { ChangeEvent, useCallback, useState } from 'react' +import { ChangeEvent, useCallback, useRef, useState, useMemo } from 'react' import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation' import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery' import { LabelChip } from '../../elements/LabelChip' +import { Check, Circle, Pen, PencilSimple, PencilSimpleLine, Plus, TagSimple } from 'phosphor-react' +import Link from 'next/link' type EditLabelsModalProps = { - article: ArticleAttributes - onOpenChange: (open: boolean) => void - setLabels: (labels: Label[]) => void + // labels: Label[] + // article: ArticleAttributes + // onOpenChange: (open: boolean) => void + // setLabels: (labels: Label[]) => void +} + +type HeaderProps = { + filterText: string + setFilterText: (text: string) => void +} + +const FormInput = styled('input', { + width: '100%', + fontSize: '16px', + fontFamily: 'inter', + fontWeight: 'normal', + lineHeight: '1.8', + color: '$grayTextContrast', + '&:focus': { + outline: 'none', + }, +}) + +const StyledLabel = styled('label', { + display: 'flex', + justifyContent: 'flex-start', + '&:focus-visible': { + backgroundColor: 'red', + }, +}) + +function Header(props: HeaderProps): JSX.Element { + const inputRef = useRef(null) + + return ( + + {/* */} + {/* + Apply labels to this page + */} + {/* */} + {/* */} + +
{ + // event.preventDefault() + // props.applySearchQuery(searchTerm || '') + inputRef.current?.blur() + }} + > + { + event.target.select() + //setFocused(true) + }} + onBlur={() => { + //setFocused(false) + console.log('blurred') + }} + onKeyDown={(event) => { + console.log('keydown', event.key) + }} + onChange={(event) => { + console.log('event', event) + props.setFilterText(event.target.value) + }} + css={{ + border: '1px solid $grayBorder', + borderRadius: '8px', + width: '100%', + bg: 'transparent', + fontSize: '16px', + fontFamily: 'inter', + fontWeight: 'normal', + marginBottom: '2px', + textIndent: '8px', + paddingLeft: '8px', + color: '$grayTextContrast', + '&:focus': { + outline: 'none', + boxShadow: '0px 0px 2px 2px rgba(255, 234, 159, 0.56)', + }, + }} + /> + +
+
) +} + +type LabelsListProps = { + // pageId: string + // selectedLabels: Label[] + availableLabels: Label[] +// setSelectedLabels: (labels: Label[]) => void +} + +function LabelsList(props: LabelsListProps): JSX.Element { + const isSelected = useCallback((label: Label) => { + // return props.selectedLabels.some((other) => { + // return other.id === label.id + // }) + return false + }, []) + + return ( + + {props.availableLabels && + props.availableLabels.map((label, idx) => ( + { + // console.log('selected label', label) + // if (props.selectedLabels.includes(label)) { + // props.setSelectedLabels( + // props.selectedLabels.filter((id) => id !== label) + // ) + // } else { + // props.setSelectedLabels([...props.selectedLabels, label]) + // } + // const result = await setLabelsMutation(props.pageId, props.selectedLabels.map((l) => l.id)) + // console.log('result', result) + }} + > + + {isSelected(label) && } + + + + + + {label.name} + + + {isSelected(label) && } + + {/* + + */} + {/* */} + + ))} + ) } export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { - const [selectedLabels, setSelectedLabels] = useState(props.labels) + const [filterText, setFilterText] = useState('') + const [selectedLabels, setSelectedLabels] = useState([]) const { labels } = useGetLabelsQuery() const saveAndExit = useCallback(async () => { - const result = await setLabelsMutation(props.article.id, selectedLabels.map((l) => l.id)) - console.log('result of setting labels', result) - props.onOpenChange(false) - props.setLabels(selectedLabels) + // const result = await setLabelsMutation(props.article.id, selectedLabels.map((l) => l.id)) + // console.log('result of setting labels', result) + // // props.onOpenChange(false) + // // props.setLabels(selectedLabels) }, [props, selectedLabels]) - const handleChange = useCallback( - (event: ChangeEvent) => { - // const label = event.target.value - // if (event.target.checked) { - // setSelectedLabels([...selectedLabels, label]) - // } else { - // setSelectedLabels(selectedLabels.filter((l) => l !== label)) - // } - }, - [selectedLabels] - ) + const filteredLabels = useMemo(() => { + if (!labels) { + return [] + } + return labels.filter((label) => { + return label.name.toLowerCase().includes(filterText.toLowerCase()) + }) + }, [labels, filterText]) return ( - - - { - event.preventDefault() - }} - css={{ overflow: 'auto', p: '0' }} - > - - - - Edit Labels - - - - {labels && - labels.map((label) => ( - { - // if (selectedLabels.includes(label.id)) { - // setSelectedLabels( - // selectedLabels.filter((id) => id !== label.id) - // ) - // } else { - // setSelectedLabels([...selectedLabels, label.id]) - // } - }} - > - - - - ))} - - + + + {`Create new label "${filterText}"`} + + )} + {/* Footer */} + + + Edit labels - - + // + // ) -} +} \ No newline at end of file diff --git a/packages/web/components/templates/article/ReaderSettingsModal.tsx b/packages/web/components/templates/article/ReaderSettingsModal.tsx index f6eccae5d..f1043837a 100644 --- a/packages/web/components/templates/article/ReaderSettingsModal.tsx +++ b/packages/web/components/templates/article/ReaderSettingsModal.tsx @@ -65,7 +65,7 @@ export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { - {}} /> + {}} /> From a9988d47068e74a5b19ff8f386acfbd47b5b025a Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 20:37:09 -0700 Subject: [PATCH 12/91] Re-enable top menu on small screens --- .../web/components/patterns/PrimaryHeader.tsx | 24 +++++++++---------- .../templates/article/ArticleActionsMenu.tsx | 9 +++---- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index f539fa5fd..bcb8b22ab 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -186,19 +186,17 @@ function NavHeader(props: NavHeaderProps): JSX.Element { - {/* */} - - - + height: '100%', + width: '100%', + display: 'none', + '@lgDown': { + display: 'flex', + }, + mr: '16px', + }} + > + {}} /> + {props.username ? ( void } @@ -31,6 +30,8 @@ export function MenuSeparator(props: MenuSeparatorProps) { } export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element { + const { preferencesData } = useGetUserPreferences() + return ( <> - + From 0998048163b4d8cb282db978ea7150f07f8f22c0 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 20:50:53 -0700 Subject: [PATCH 13/91] Remove unused prop --- packages/web/pages/[username]/[slug]/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index c0514ca29..f35f94e8a 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -158,7 +158,6 @@ export default function Home(): JSX.Element { > From d8e064807050a30e9d867dbc39858ca489baf991 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 21:06:51 -0700 Subject: [PATCH 14/91] Remove empty arrow function --- packages/web/components/patterns/PrimaryHeader.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index bcb8b22ab..f96f5138b 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -195,7 +195,9 @@ function NavHeader(props: NavHeaderProps): JSX.Element { mr: '16px', }} > - {}} /> + { + console.log('action handler') + }} /> {props.username ? ( From 0b4f223b2670b7dd99a71f0426fa969dd25946ca Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 21:31:19 -0700 Subject: [PATCH 15/91] Spacing on top dropdowns --- .../templates/article/ArticleActionsMenu.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 72e2d5c41..cd5ea9071 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -48,9 +48,9 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element }} > @@ -64,9 +64,10 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element From 0d16b32ae712e65730b34b002560e4b09c2ab4d0 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 8 Apr 2022 22:00:57 -0700 Subject: [PATCH 16/91] Test with bottom sheet --- .../components/elements/DropdownElements.tsx | 1 - .../templates/article/ArticleActionsMenu.tsx | 19 ++++++++++++++++--- .../templates/article/EditLabelsModal.tsx | 3 ++- .../templates/article/ReaderSettingsModal.tsx | 7 +++++-- packages/web/package.json | 1 + 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/web/components/elements/DropdownElements.tsx b/packages/web/components/elements/DropdownElements.tsx index d5f3b78c6..6b63da219 100644 --- a/packages/web/components/elements/DropdownElements.tsx +++ b/packages/web/components/elements/DropdownElements.tsx @@ -115,7 +115,6 @@ export function Dropdown({ sideOffset = 0, css }: DropdownProps): JSX.Element { - console.log('side', side) return ( {triggerElement} diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index cd5ea9071..c806fa655 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -1,5 +1,7 @@ import { Separator } from "@radix-ui/react-separator" import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from "phosphor-react" +import { useState } from "react" +import { BottomSheet } from "react-spring-bottom-sheet" import { useGetUserPreferences, UserPreferences } from "../../../lib/networking/queries/useGetUserPreferences" import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" @@ -8,6 +10,10 @@ import { styled, theme } from "../../tokens/stitches.config" import { EditLabelsModal } from "./EditLabelsModal" import { ReaderSettings } from "./ReaderSettingsModal" +// if setting up the CSS is tricky, you can add this to your page somewhere: +// +import 'react-spring-bottom-sheet/dist/style.css' + export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' type ArticleActionsMenuProps = { @@ -31,6 +37,7 @@ export function MenuSeparator(props: MenuSeparatorProps) { export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element { const { preferencesData } = useGetUserPreferences() + const [open, setOpen] = useState(false) return ( <> @@ -56,7 +63,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } - css={{ m: '0px', p: '0px' }} + css={{ m: '0px', p: '0px' }} > @@ -83,8 +90,8 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element - - {/* @@ -92,6 +99,12 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element */} + minHeight} + open={open} onDismiss={() => setOpen(false)}> + + {/* */} + ) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index 1d74f4574..c7205b43d 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -241,7 +241,8 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { // >
@@ -65,7 +66,9 @@ export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { - {}} /> + { + console.log('range changed') + }} /> diff --git a/packages/web/package.json b/packages/web/package.json index 7858d890b..39c1eba08 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -40,6 +40,7 @@ "react-hot-toast": "^2.1.1", "react-intl": "^5.20.12", "react-loading-skeleton": "^3.0.2", + "react-spring-bottom-sheet": "^3.4.0", "react-twitter-widgets": "^1.10.0", "swr": "^1.0.1", "uuid": "^8.3.2" From f87db8bfad58599d3f28da115031295b908abded Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 09:40:07 -0700 Subject: [PATCH 17/91] Revert "Test with bottom sheet" This reverts commit 44faad1172580bf4b7ca85d00f0495f76226dc2d. --- .../components/elements/DropdownElements.tsx | 1 + .../templates/article/ArticleActionsMenu.tsx | 19 +++---------------- .../templates/article/EditLabelsModal.tsx | 3 +-- .../templates/article/ReaderSettingsModal.tsx | 7 ++----- packages/web/package.json | 1 - 5 files changed, 7 insertions(+), 24 deletions(-) diff --git a/packages/web/components/elements/DropdownElements.tsx b/packages/web/components/elements/DropdownElements.tsx index 6b63da219..d5f3b78c6 100644 --- a/packages/web/components/elements/DropdownElements.tsx +++ b/packages/web/components/elements/DropdownElements.tsx @@ -115,6 +115,7 @@ export function Dropdown({ sideOffset = 0, css }: DropdownProps): JSX.Element { + console.log('side', side) return ( {triggerElement} diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index c806fa655..cd5ea9071 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -1,7 +1,5 @@ import { Separator } from "@radix-ui/react-separator" import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from "phosphor-react" -import { useState } from "react" -import { BottomSheet } from "react-spring-bottom-sheet" import { useGetUserPreferences, UserPreferences } from "../../../lib/networking/queries/useGetUserPreferences" import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" @@ -10,10 +8,6 @@ import { styled, theme } from "../../tokens/stitches.config" import { EditLabelsModal } from "./EditLabelsModal" import { ReaderSettings } from "./ReaderSettingsModal" -// if setting up the CSS is tricky, you can add this to your page somewhere: -// -import 'react-spring-bottom-sheet/dist/style.css' - export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' type ArticleActionsMenuProps = { @@ -37,7 +31,6 @@ export function MenuSeparator(props: MenuSeparatorProps) { export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element { const { preferencesData } = useGetUserPreferences() - const [open, setOpen] = useState(false) return ( <> @@ -63,7 +56,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } - css={{ m: '0px', p: '0px' }} + css={{ m: '0px', p: '0px' }} > @@ -90,8 +83,8 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element -{/* // props.articleActionHandler('archive') */} - {/* @@ -99,12 +92,6 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element */} - minHeight} - open={open} onDismiss={() => setOpen(false)}> - - {/* */} - ) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index c7205b43d..1d74f4574 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -241,8 +241,7 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { // >
@@ -66,9 +65,7 @@ export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { - { - console.log('range changed') - }} /> + {}} /> diff --git a/packages/web/package.json b/packages/web/package.json index 39c1eba08..7858d890b 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -40,7 +40,6 @@ "react-hot-toast": "^2.1.1", "react-intl": "^5.20.12", "react-loading-skeleton": "^3.0.2", - "react-spring-bottom-sheet": "^3.4.0", "react-twitter-widgets": "^1.10.0", "swr": "^1.0.1", "uuid": "^8.3.2" From d8e03c090688d5ceab78b3f3a844246b186664bd Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 09:42:38 -0700 Subject: [PATCH 18/91] Make arrow styles more closely match design --- packages/web/components/elements/DropdownElements.tsx | 6 +++--- .../web/components/templates/article/ArticleActionsMenu.tsx | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/web/components/elements/DropdownElements.tsx b/packages/web/components/elements/DropdownElements.tsx index d5f3b78c6..853bc71bc 100644 --- a/packages/web/components/elements/DropdownElements.tsx +++ b/packages/web/components/elements/DropdownElements.tsx @@ -49,12 +49,12 @@ export const DropdownContent = styled(Content, { backgroundColor: '$grayBg', borderRadius: '0.5em', padding: 5, - border: '1px solid $grayBorder', + outline: '1px solid $grayBorder', boxShadow: '$cardBoxShadow', }) const StyledArrow = styled(Arrow, { - fill: '$grayBase', + fill: '$grayBg', }) const StyledLabel = styled(Label, { @@ -131,7 +131,7 @@ export function Dropdown({ > {labelText && {labelText}} {children} - {showArrow && } + {showArrow && } ) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index cd5ea9071..72e5417e2 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -48,6 +48,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element }} > Date: Sun, 10 Apr 2022 09:47:24 -0700 Subject: [PATCH 19/91] Dont autofocus the labels filter on touch devices as the keyboard uses too much screen space --- packages/web/components/templates/article/EditLabelsModal.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index 1d74f4574..0a3bf1499 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -15,6 +15,7 @@ import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticle import { LabelChip } from '../../elements/LabelChip' import { Check, Circle, Pen, PencilSimple, PencilSimpleLine, Plus, TagSimple } from 'phosphor-react' import Link from 'next/link' +import { isTouchScreenDevice } from '../../../lib/deviceType' type EditLabelsModalProps = { // labels: Label[] @@ -96,7 +97,7 @@ function Header(props: HeaderProps): JSX.Element { { From 05e7ba7ced62731ec8976f8b14730baf048757e1 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 09:48:43 -0700 Subject: [PATCH 20/91] Remove empty arrow function --- .../web/components/templates/article/ReaderSettingsModal.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/ReaderSettingsModal.tsx b/packages/web/components/templates/article/ReaderSettingsModal.tsx index f1043837a..e8c70709b 100644 --- a/packages/web/components/templates/article/ReaderSettingsModal.tsx +++ b/packages/web/components/templates/article/ReaderSettingsModal.tsx @@ -65,7 +65,9 @@ export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { - {}} /> + { + console.log('range changed', value) + }} /> From eeea5b7c28a87caac804c3ce3b54c97fdd7d241f Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 10:20:34 -0700 Subject: [PATCH 21/91] Consistent dropdown layout for article actions We also offset a little to display the popover in the middle of the article action button on desktop Disable autofocus on touch devices so the keyboard doesn't take up too much space --- .../components/elements/DropdownElements.tsx | 27 ++++++------ .../templates/article/ArticleActionsMenu.tsx | 43 ++++++++++++------- .../templates/article/EditLabelsModal.tsx | 2 +- .../templates/article/ReaderSettingsModal.tsx | 8 ++-- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/packages/web/components/elements/DropdownElements.tsx b/packages/web/components/elements/DropdownElements.tsx index 853bc71bc..61dfeaac2 100644 --- a/packages/web/components/elements/DropdownElements.tsx +++ b/packages/web/components/elements/DropdownElements.tsx @@ -8,6 +8,7 @@ import { Arrow, Label, } from '@radix-ui/react-dropdown-menu' +import { PopperContentProps } from '@radix-ui/react-popover'; import { CSS } from '@stitches/react'; import { styled } from './../tokens/stitches.config' @@ -104,18 +105,19 @@ export function DropdownOption(props: DropdownOptionProps): JSX.Element { ) } -export function Dropdown({ - children, - align, - triggerElement, - labelText, - showArrow = true, - disabled = false, - side = 'bottom', - sideOffset = 0, - css -}: DropdownProps): JSX.Element { - console.log('side', side) +export function Dropdown(props: DropdownProps & PopperContentProps): JSX.Element { + const { + children, + align, + triggerElement, + labelText, + showArrow = true, + disabled = false, + side = 'bottom', + sideOffset = 0, + alignOffset = 0, + css + } = props return ( {triggerElement} @@ -128,6 +130,7 @@ export function Dropdown({ side={side} sideOffset={sideOffset} align={align ? align : 'center'} + alignOffset={alignOffset} > {labelText && {labelText}} {children} diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 72e5417e2..a97a4370d 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -19,7 +19,7 @@ type MenuSeparatorProps = { layout: ArticleActionsMenuLayout } -export function MenuSeparator(props: MenuSeparatorProps) { +const MenuSeparator = (props: MenuSeparatorProps): JSX.Element => { const LineSeparator = styled(Separator, { width: '100%', margin: 0, @@ -29,6 +29,26 @@ export function MenuSeparator(props: MenuSeparatorProps) { return (props.layout == 'vertical' ? : <>) } +type ActionDropdownProps = { + layout: ArticleActionsMenuLayout + triggerElement: JSX.Element + children: JSX.Element +} + +const ActionDropdown = (props: ActionDropdownProps): JSX.Element => { + return + {props.children} + +} + export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element { const { preferencesData } = useGetUserPreferences() @@ -47,38 +67,29 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element m: '0px', }} > - } - css={{ m: '0px', p: '0px' }} > - + - } - css={{ m: '0px', p: '0px' }} > - {/* */} - + - {/* - {}} /> + { + console.log('changed line spacing') + }} /> - */} + ) } From 1427ffc783d531f32045f33c4b38563ac98c336a Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 10:42:02 -0700 Subject: [PATCH 22/91] Test some smaller sizes for mobile screens --- .../web/components/templates/article/EditLabelsModal.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index ba441f215..b66b951b5 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -97,6 +97,7 @@ function Header(props: HeaderProps): JSX.Element {
Date: Sun, 10 Apr 2022 11:13:30 -0700 Subject: [PATCH 23/91] Increase small screen maxheight --- packages/web/components/templates/article/EditLabelsModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index b66b951b5..c04f7321f 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -246,7 +246,7 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { maxWidth: '265px', '@mdDown': { maxWidth: '100%', - maxHeight: '280px', + maxHeight: '320px', }, }}>
From 0a4215c57ba18e28775a3845ea16ac77c43ae78b Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 14:52:30 -0700 Subject: [PATCH 24/91] Handle toggling label state --- .../templates/article/ArticleActionsMenu.tsx | 1 + .../templates/article/EditLabelsModal.tsx | 358 ++++++++++-------- 2 files changed, 194 insertions(+), 165 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index a97a4370d..42b8651a5 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -1,5 +1,6 @@ import { Separator } from "@radix-ui/react-separator" import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from "phosphor-react" +import { useRef } from "react" import { useGetUserPreferences, UserPreferences } from "../../../lib/networking/queries/useGetUserPreferences" import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index c04f7321f..e9b2172e0 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -9,7 +9,7 @@ import { StyledText } from '../../elements/StyledText' import { CrossIcon } from '../../elements/images/CrossIcon' import { styled, theme } from '../../tokens/stitches.config' import { Label, useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery' -import { ChangeEvent, useCallback, useRef, useState, useMemo } from 'react' +import { ChangeEvent, useCallback, useRef, useState, useMemo, useEffect } from 'react' import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation' import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery' import { LabelChip } from '../../elements/LabelChip' @@ -26,6 +26,8 @@ type EditLabelsModalProps = { type HeaderProps = { filterText: string + focused: boolean + parentRef: React.RefObject setFilterText: (text: string) => void } @@ -44,70 +46,68 @@ const FormInput = styled('input', { const StyledLabel = styled('label', { display: 'flex', justifyContent: 'flex-start', - '&:focus-visible': { - backgroundColor: 'red', + '&:focus': { + bg: '$grayBgActive', + }, + 'input:&:focus-within': { + bg: '$grayBgActive', }, }) +const useToggleLabels = () => { + const [selectedLabels, setSelectedLabels] = useState([]) + + const isSelected = useCallback((label: Label): boolean => { + return selectedLabels.some((other) => { + return other.id === label.id + }) + }, [selectedLabels]) + + const toggleLabel = useCallback((label: Label) => { + if (isSelected(label)) { + setSelectedLabels(selectedLabels.filter((other) => { + return other.id !== label.id + })) + } else { + setSelectedLabels([...selectedLabels, label]) + } + }, [isSelected, selectedLabels]) + + return [isSelected, toggleLabel] +} + function Header(props: HeaderProps): JSX.Element { const inputRef = useRef(null) + useEffect(() => { + if (props.focused && inputRef.current) { + inputRef.current.focus() + } + }, [props.focused]) + return ( - {/* */} - {/* - Apply labels to this page - */} - {/* */} - {/* */} -
{ - // event.preventDefault() - // props.applySearchQuery(searchTerm || '') - inputRef.current?.blur() - }} - > { event.target.select() //setFocused(true) + console.log('input::focused()') }} onBlur={() => { - //setFocused(false) - console.log('blurred') + // setFocused(false) + console.log('input::blurred') }} onKeyDown={(event) => { console.log('keydown', event.key) @@ -134,94 +134,82 @@ function Header(props: HeaderProps): JSX.Element { }, }} /> -
) } -type LabelsListProps = { - // pageId: string - // selectedLabels: Label[] - availableLabels: Label[] -// setSelectedLabels: (labels: Label[]) => void +type LabelListItemProps = { + label: Label + focused: boolean + selected: boolean } -function LabelsList(props: LabelsListProps): JSX.Element { - const isSelected = useCallback((label: Label) => { - // return props.selectedLabels.some((other) => { - // return other.id === label.id - // }) - return false - }, []) +function LabelListItem(props: LabelListItemProps): JSX.Element { + const ref = useRef(null) + const { label, focused, selected } = props + + useEffect(() => { + if (props.focused && ref.current) { + ref.current.focus() + } + }, [props.focused]) return ( - - {props.availableLabels && - props.availableLabels.map((label, idx) => ( - { - // console.log('selected label', label) - // if (props.selectedLabels.includes(label)) { - // props.setSelectedLabels( - // props.selectedLabels.filter((id) => id !== label) - // ) - // } else { - // props.setSelectedLabels([...props.selectedLabels, label]) - // } - // const result = await setLabelsMutation(props.pageId, props.selectedLabels.map((l) => l.id)) - // console.log('result', result) - }} - > - - {isSelected(label) && } - - - - - - {label.name} - - - {isSelected(label) && } - - {/* - - */} - {/* */} - - ))} - ) + { + console.log('toggling label') + }} + > + + + {selected && } + + + + + + {label.name} + + + {selected && } + + + ) } export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { + const parentRef = useRef(null) const [filterText, setFilterText] = useState('') - const [selectedLabels, setSelectedLabels] = useState([]) const { labels } = useGetLabelsQuery() - const saveAndExit = useCallback(async () => { - // const result = await setLabelsMutation(props.article.id, selectedLabels.map((l) => l.id)) - // console.log('result of setting labels', result) - // // props.onOpenChange(false) - // // props.setLabels(selectedLabels) - }, [props, selectedLabels]) + const [selectedLabels, setSelectedLabels] = useState([]) + + const isSelected = useCallback((label: Label): boolean => { + return selectedLabels.some((other) => { + return other.id === label.id + }) + }, [selectedLabels]) + + const toggleLabel = useCallback((label: Label) => { + if (isSelected(label)) { + setSelectedLabels(selectedLabels.filter((other) => { + return other.id !== label.id + })) + } else { + setSelectedLabels([...selectedLabels, label]) + } + }, [isSelected, selectedLabels]) const filteredLabels = useMemo(() => { if (!labels) { @@ -232,58 +220,98 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { }) }, [labels, filterText]) + useEffect(() => { + setFocusedIndex(undefined) + }, [filterText]) + + // Move focus through the labels list on tab or arrow up/down keys + const [focusedIndex, setFocusedIndex] = useState(undefined) + const handleKeyDown = useCallback((event: React.KeyboardEvent) => { + if (event.key === 'ArrowUp') { + event.preventDefault() + if (focusedIndex) { + setFocusedIndex(Math.max(0, focusedIndex - 1)) + } else { + setFocusedIndex(undefined) + } + } + if (event.key === 'ArrowDown' || event.key === 'Tab') { + event.preventDefault() + if (focusedIndex === undefined) { + setFocusedIndex(0) + } else { + setFocusedIndex(Math.min(filteredLabels.length - 1, focusedIndex + 1)) + } + } + if (event.key === 'Enter') { + event.preventDefault() + if (focusedIndex !== undefined) { + const label = filteredLabels[focusedIndex] + if (label) { + toggleLabel(label) + } + } + } + }, [filteredLabels, focusedIndex]) + return ( - // - // - // { - // event.preventDefault() - // }} - // css={{ p: '0', width: '100%', maxWidth: '400px' }} - // > - +
+ + {labels && + labels.map((label, idx) => ( + + ))} + + {filterText && ( + )} + {/* Footer */} + -
- - {filterText && ( - )} - {/* Footer */} - - - Edit labels - - - // - // + 'a:visited': { + color: theme.colors.grayText.toString(), + }, + }} + > + + Edit labels + + ) } \ No newline at end of file From 6dd39d54887089b04b08e38308076935b9c32767 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 15:14:49 -0700 Subject: [PATCH 25/91] Handle toggling labels with mouse --- .../templates/article/EditLabelsModal.tsx | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index e9b2172e0..af3db7061 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -9,7 +9,7 @@ import { StyledText } from '../../elements/StyledText' import { CrossIcon } from '../../elements/images/CrossIcon' import { styled, theme } from '../../tokens/stitches.config' import { Label, useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery' -import { ChangeEvent, useCallback, useRef, useState, useMemo, useEffect } from 'react' +import { ChangeEvent, useCallback, useRef, useState, useMemo, useEffect, MouseEventHandler } from 'react' import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation' import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery' import { LabelChip } from '../../elements/LabelChip' @@ -49,9 +49,6 @@ const StyledLabel = styled('label', { '&:focus': { bg: '$grayBgActive', }, - 'input:&:focus-within': { - bg: '$grayBgActive', - }, }) const useToggleLabels = () => { @@ -142,6 +139,7 @@ type LabelListItemProps = { label: Label focused: boolean selected: boolean + toggleLabel: (label: Label) => void } function LabelListItem(props: LabelListItemProps): JSX.Element { @@ -164,8 +162,10 @@ function LabelListItem(props: LabelListItemProps): JSX.Element { bg: props.focused ? '$grayBgActive' : 'unset', }} tabIndex={props.focused ? 0 : -1} - onClick={async () => { - console.log('toggling label') + onClick={(event) => { + event.preventDefault() + props.toggleLabel(label) + ref.current?.blur() }} > @@ -260,13 +260,16 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { distribution="start" onKeyDown={handleKeyDown} css={{ - p: '0', - maxHeight: '92%', - maxWidth: '265px', - '@mdDown': { - maxWidth: '100%', + p: '0', + width: '265px', maxHeight: '92%', - }, + '@mdDown': { + maxHeight: '92%', + }, + '@smDown': { + maxHeight: '92%', + maxWidth: '92%', + } }}>
- {labels && - labels.map((label, idx) => ( + {filteredLabels && + filteredLabels.map((label, idx) => ( ))} From 92ea5efb9867b7dbf1c1032cbd6d29438397de00 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 15:43:14 -0700 Subject: [PATCH 26/91] Update naming --- .../templates/article/EditLabelsControl.tsx | 321 ++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 packages/web/components/templates/article/EditLabelsControl.tsx diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx new file mode 100644 index 000000000..33d064c3e --- /dev/null +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -0,0 +1,321 @@ +import { + ModalContent, + ModalOverlay, + ModalRoot, +} from '../../elements/ModalPrimitives' +import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives' +import { Button } from '../../elements/Button' +import { StyledText } from '../../elements/StyledText' +import { CrossIcon } from '../../elements/images/CrossIcon' +import { styled, theme } from '../../tokens/stitches.config' +import { Label, useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery' +import { ChangeEvent, useCallback, useRef, useState, useMemo, useEffect, MouseEventHandler } from 'react' +import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation' +import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticleQuery' +import { LabelChip } from '../../elements/LabelChip' +import { Check, Circle, Pen, PencilSimple, PencilSimpleLine, Plus, TagSimple } from 'phosphor-react' +import Link from 'next/link' +import { isTouchScreenDevice } from '../../../lib/deviceType' + +type EditLabelsControlProps = { + // labels: Label[] + // article: ArticleAttributes + // onOpenChange: (open: boolean) => void + // setLabels: (labels: Label[]) => void +} + +type HeaderProps = { + filterText: string + focused: boolean + parentRef: React.RefObject + setFilterText: (text: string) => void +} + +const FormInput = styled('input', { + width: '100%', + fontSize: '16px', + fontFamily: 'inter', + fontWeight: 'normal', + lineHeight: '1.8', + color: '$grayTextContrast', + '&:focus': { + outline: 'none', + }, +}) + +const StyledLabel = styled('label', { + display: 'flex', + justifyContent: 'flex-start', + '&:focus': { + bg: '$grayBgActive', + }, +}) + +const useToggleLabels = () => { + const [selectedLabels, setSelectedLabels] = useState([]) + + const isSelected = useCallback((label: Label): boolean => { + return selectedLabels.some((other) => { + return other.id === label.id + }) + }, [selectedLabels]) + + const toggleLabel = useCallback((label: Label) => { + if (isSelected(label)) { + setSelectedLabels(selectedLabels.filter((other) => { + return other.id !== label.id + })) + } else { + setSelectedLabels([...selectedLabels, label]) + } + }, [isSelected, selectedLabels]) + + return [isSelected, toggleLabel] +} + +function Header(props: HeaderProps): JSX.Element { + const inputRef = useRef(null) + + useEffect(() => { + if (props.focused && inputRef.current) { + inputRef.current.focus() + } + }, [props.focused]) + + return ( + + + { + event.target.select() + //setFocused(true) + console.log('input::focused()') + }} + onBlur={() => { + // setFocused(false) + console.log('input::blurred') + }} + onKeyDown={(event) => { + console.log('keydown', event.key) + }} + onChange={(event) => { + console.log('event', event) + props.setFilterText(event.target.value) + }} + css={{ + border: '1px solid $grayBorder', + borderRadius: '8px', + width: '100%', + bg: 'transparent', + fontSize: '16px', + fontFamily: 'inter', + fontWeight: 'normal', + marginBottom: '2px', + textIndent: '8px', + paddingLeft: '8px', + color: '$grayTextContrast', + '&:focus': { + outline: 'none', + boxShadow: '0px 0px 2px 2px rgba(255, 234, 159, 0.56)', + }, + }} + /> + + ) +} + +type LabelListItemProps = { + label: Label + focused: boolean + selected: boolean + toggleLabel: (label: Label) => void +} + +function LabelListItem(props: LabelListItemProps): JSX.Element { + const ref = useRef(null) + const { label, focused, selected } = props + + useEffect(() => { + if (props.focused && ref.current) { + ref.current.focus() + } + }, [props.focused]) + + return ( + { + event.preventDefault() + props.toggleLabel(label) + ref.current?.blur() + }} + > + + + {selected && } + + + + + + {label.name} + + + {selected && } + + + ) +} + +export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { + const parentRef = useRef(null) + const [filterText, setFilterText] = useState('') + const { labels } = useGetLabelsQuery() + + const [selectedLabels, setSelectedLabels] = useState([]) + + const isSelected = useCallback((label: Label): boolean => { + return selectedLabels.some((other) => { + return other.id === label.id + }) + }, [selectedLabels]) + + const toggleLabel = useCallback((label: Label) => { + if (isSelected(label)) { + setSelectedLabels(selectedLabels.filter((other) => { + return other.id !== label.id + })) + } else { + setSelectedLabels([...selectedLabels, label]) + } + }, [isSelected, selectedLabels]) + + const filteredLabels = useMemo(() => { + if (!labels) { + return [] + } + return labels.filter((label) => { + return label.name.toLowerCase().includes(filterText.toLowerCase()) + }) + }, [labels, filterText]) + + useEffect(() => { + setFocusedIndex(undefined) + }, [filterText]) + + // Move focus through the labels list on tab or arrow up/down keys + const [focusedIndex, setFocusedIndex] = useState(undefined) + const handleKeyDown = useCallback((event: React.KeyboardEvent) => { + if (event.key === 'ArrowUp') { + event.preventDefault() + if (focusedIndex) { + setFocusedIndex(Math.max(0, focusedIndex - 1)) + } else { + setFocusedIndex(undefined) + } + } + if (event.key === 'ArrowDown' || event.key === 'Tab') { + event.preventDefault() + if (focusedIndex === undefined) { + setFocusedIndex(0) + } else { + setFocusedIndex(Math.min(filteredLabels.length - 1, focusedIndex + 1)) + } + } + if (event.key === 'Enter') { + event.preventDefault() + if (focusedIndex !== undefined) { + const label = filteredLabels[focusedIndex] + if (label) { + toggleLabel(label) + } + } + } + }, [filteredLabels, focusedIndex]) + + return ( + +
+ + {filteredLabels && + filteredLabels.map((label, idx) => ( + + ))} + + {filterText && ( + )} + {/* Footer */} + + + Edit labels + + + ) +} \ No newline at end of file From de72df98282fdb5866fa487ce5e8591215a1c5ee Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 15:54:51 -0700 Subject: [PATCH 27/91] Naming, update small screen layout --- .../templates/article/ArticleActionsMenu.tsx | 4 +- .../templates/article/EditLabelsControl.tsx | 28 +- .../templates/article/EditLabelsModal.tsx | 321 ------------------ .../web/pages/[username]/[slug]/index.tsx | 2 +- 4 files changed, 7 insertions(+), 348 deletions(-) delete mode 100644 packages/web/components/templates/article/EditLabelsModal.tsx diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 42b8651a5..0f115e180 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -6,7 +6,7 @@ import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" import { Box, SpanBox } from "../../elements/LayoutPrimitives" import { styled, theme } from "../../tokens/stitches.config" -import { EditLabelsModal } from "./EditLabelsModal" +import { EditLabelsControl } from "./EditLabelsControl" import { ReaderSettings } from "./ReaderSettingsModal" export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' @@ -89,7 +89,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } > - + )} - {/* Footer */} - - - Edit labels - - - ) -} \ No newline at end of file diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index f35f94e8a..0cc663a63 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -20,7 +20,7 @@ import { articleReadingProgressMutation } from '../../../lib/networking/mutation import { updateHighlightMutation } from '../../../lib/networking/mutations/updateHighlightMutation' import { userPersonalizationMutation } from '../../../lib/networking/mutations/userPersonalizationMutation' import Script from 'next/script' -import { EditLabelsModal } from '../../../components/templates/article/EditLabelsModal' +import { EditLabelsControl } from '../../../components/templates/article/EditLabelsControl' import { Label } from '../../../lib/networking/fragments/labelFragment' import { isVipUser } from '../../../lib/featureFlag' import { styled, theme } from '../../../components/tokens/stitches.config' From e7528cfc439351cbd2ea0040f10871fb0756677b Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 10 Apr 2022 16:07:25 -0700 Subject: [PATCH 28/91] Attempt to dismiss focus on mobile --- packages/web/components/templates/article/EditLabelsControl.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index 52f3604a4..7551fc7eb 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -92,7 +92,7 @@ function Header(props: HeaderProps): JSX.Element { Date: Sun, 10 Apr 2022 17:22:06 -0700 Subject: [PATCH 29/91] Wire up article actions to have an article instance when hosted in the header --- .../web/components/patterns/PrimaryHeader.tsx | 35 +++++++++---------- .../components/templates/PrimaryLayout.tsx | 3 +- .../templates/article/ArticleActionsMenu.tsx | 14 +++++++- .../web/pages/[username]/[slug]/index.tsx | 29 ++++++++------- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index f96f5138b..57b6cc0ed 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -17,8 +17,6 @@ import { UserBasicData } from '../../lib/networking/queries/useGetViewerQuery' import { setupAnalytics } from '../../lib/analytics' import { Button } from '../elements/Button' import Link from 'next/link' -import { ArchiveBox, ArrowSquareOut, DotsThree, HighlighterCircle, TagSimple, TextAa } from 'phosphor-react' -import { ArticleActionsMenu } from '../templates/article/ArticleActionsMenu' type HeaderProps = { user?: UserBasicData @@ -28,6 +26,7 @@ type HeaderProps = { isFixedPosition: boolean scrollElementRef?: React.RefObject displayFontStepper?: boolean + toolbarControl?: JSX.Element setShowLogoutConfirmation: (showShareModal: boolean) => void setShowKeyboardCommandsModal: (showShareModal: boolean) => void } @@ -56,9 +55,6 @@ export function PrimaryHeader(props: HeaderProps): JSX.Element { (changeset: ScrollOffsetChangeset) => { const isScrolledBeyondMinThreshold = changeset.current.y >= 50 const isScrollingDown = changeset.current.y > changeset.previous.y - - // setIsScrolled(isScrolledBeyondMinThreshold) - // setShowHeader(!(isScrollingDown && isScrolledBeyondMinThreshold)) }, 0 ) @@ -129,6 +125,7 @@ export function PrimaryHeader(props: HeaderProps): JSX.Element { isDisplayingShadow={isScrolled} isVisible={true} isFixedPosition={true} + toolbarControl={props.toolbarControl} displayFontStepper={props.displayFontStepper} /> @@ -145,6 +142,7 @@ type NavHeaderProps = { isVisible?: boolean isFixedPosition: boolean displayFontStepper?: boolean + toolbarControl?: JSX.Element } function NavHeader(props: NavHeaderProps): JSX.Element { @@ -185,20 +183,19 @@ function NavHeader(props: NavHeaderProps): JSX.Element { - - { - console.log('action handler') - }} /> - + {props.toolbarControl && ( + + {props.toolbarControl} + + )} {props.username ? ( displayFontStepper?: boolean + headerToolbarControl?: JSX.Element } export function PrimaryLayout(props: PrimaryLayoutProps): JSX.Element { @@ -76,6 +76,7 @@ export function PrimaryLayout(props: PrimaryLayoutProps): JSX.Element { userInitials={viewerData?.me?.name.charAt(0) ?? ''} profileImageURL={viewerData?.me?.profile.pictureUrl} isFixedPosition={true} + toolbarControl={props.headerToolbarControl} scrollElementRef={props.scrollElementRef} displayFontStepper={props.displayFontStepper} setShowLogoutConfirmation={setShowLogoutConfirmation} diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 0f115e180..e28a41dca 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -1,6 +1,7 @@ import { Separator } from "@radix-ui/react-separator" import { ArchiveBox, DotsThree, HighlighterCircle, TagSimple, TextAa } from "phosphor-react" import { useRef } from "react" +import { ArticleAttributes } from "../../../lib/networking/queries/useGetArticleQuery" import { useGetUserPreferences, UserPreferences } from "../../../lib/networking/queries/useGetUserPreferences" import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" @@ -12,6 +13,7 @@ import { ReaderSettings } from "./ReaderSettingsModal" export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' type ArticleActionsMenuProps = { + article: ArticleAttributes layout: ArticleActionsMenuLayout articleActionHandler: (action: string, arg?: number) => void } @@ -39,7 +41,7 @@ type ActionDropdownProps = { const ActionDropdown = (props: ActionDropdownProps): JSX.Element => { return +{/* + */} - { - console.log('range changed', value) + { + setMarginWidth(value) + props.articleActionHandler('setMarginWidth', value) }} /> { setMarginWidth(value) props.articleActionHandler('setMarginWidth', value) }} /> - + - { - console.log('changed line spacing') + { + setLineHeight(value) + props.articleActionHandler('setLineHeight', value) }} /> - { + { setLineHeight(value) props.articleActionHandler('setLineHeight', value) }} /> diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index cb820d9d8..4bd1c9559 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -38,14 +38,13 @@ export default function Home(): JSX.Element { const { slug } = router.query const [showHighlightsModal, setShowHighlightsModal] = useState(false) - // Populate data cache const { viewerData } = useGetViewerQuery() - const { preferencesData } = useGetUserPreferences() const [fontSize, setFontSize] = useState(preferencesData?.fontSize ?? 20) const [marginWidth, setMarginWidth] = useState(preferencesData?.margin ?? 360) + const [lineHeight, setLineHeight] = useState(preferencesData?.lineHeight ?? 150) - const { articleData, mutate } = useGetArticleQuery({ + const { articleData } = useGetArticleQuery({ username: router.query.username as string, slug: router.query.slug as string, includeFriendsHighlights: false, @@ -103,7 +102,7 @@ export default function Home(): JSX.Element { break case 'setMarginWidth': { const value = Number(arg) - if (value > 200 && value < 560) { + if (value >= 200 && value <= 560) { updateMarginWidth(value) } break @@ -114,6 +113,13 @@ export default function Home(): JSX.Element { case 'decrementMarginWidth': updateMarginWidth(Math.max(marginWidth - 45, 200)) break + case 'setLineHeight': { + const value = Number(arg) + if (value >= 100 && value <= 300) { + setLineHeight(value) + } + break + } } }; @@ -193,6 +199,7 @@ export default function Home(): JSX.Element { highlightsBaseURL={`${webBaseURL}/${viewerData.me?.profile?.username}/${slug}/highlights`} fontSize={fontSize} margin={marginWidth} + lineHeight={lineHeight} labels={labels} articleMutations={{ createHighlightMutation, From 9a627c225e229273e42ae223f1ba89e8e3a3a74e Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 08:58:48 -0700 Subject: [PATCH 40/91] Add tooltips to article actions --- packages/web/components/elements/Tooltip.tsx | 18 +++++++- .../templates/article/ArticleActionsMenu.tsx | 43 +++++++++++++------ 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/packages/web/components/elements/Tooltip.tsx b/packages/web/components/elements/Tooltip.tsx index 241c20e8e..b1139061a 100644 --- a/packages/web/components/elements/Tooltip.tsx +++ b/packages/web/components/elements/Tooltip.tsx @@ -62,6 +62,15 @@ type TooltipWrappedProps = { style?: TooltipPrimitive.TooltipContentProps['style'] } +const DefaultTooltipStyle = { + backgroundColor: '#F9D354', + color: '#0A0806', +} + +const DefaultArrowStyle = { + fill: '#F9D354' +} + export const TooltipWrapped: FC = ({ children, active, @@ -73,9 +82,14 @@ export const TooltipWrapped: FC = ({ return ( {children} - + {tooltipContent} - + ) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 1a8762f84..abcec99a3 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -4,7 +4,8 @@ import { ArticleAttributes } from "../../../lib/networking/queries/useGetArticle import { useGetUserPreferences } from "../../../lib/networking/queries/useGetUserPreferences" import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" -import { Box, SpanBox } from "../../elements/LayoutPrimitives" +import { Box } from "../../elements/LayoutPrimitives" +import { TooltipWrapped } from "../../elements/Tooltip" import { styled, theme } from "../../tokens/stitches.config" import { EditLabelsControl } from "./EditLabelsControl" import { ReaderSettings } from "./ReaderSettingsModal" @@ -59,22 +60,23 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element - - + + + } > @@ -85,9 +87,12 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element - - + + + } > */} - + + + {/* From ebe22f3df8959726e6249ad9f8a3916fb8c70215 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 09:10:38 -0700 Subject: [PATCH 41/91] Wrap the button so style isnt changed --- .../templates/article/ArticleActionsMenu.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index abcec99a3..f8fbb8c22 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -111,14 +111,15 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element */} - - - + + + { setLineHeight(value) props.articleActionHandler('setLineHeight', value) }} /> - + + ) diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index 4bd1c9559..7eb2c194e 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -120,6 +120,12 @@ export default function Home(): JSX.Element { } break } + case 'resetReaderSettings': { + updateFontSize(20) + updateMarginWidth(360) + setLineHeight(150) + break + } } }; From c280b2cf01bf83277e3a1acd4a2bbcd9761d68a1 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 11:13:58 -0700 Subject: [PATCH 45/91] Remove items from cache when archived from the article actions menu --- .../networking/queries/useGetArticleQuery.tsx | 64 ++++++++++++++----- .../queries/useGetLibraryItemsQuery.tsx | 2 +- .../web/pages/[username]/[slug]/index.tsx | 17 ++++- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/packages/web/lib/networking/queries/useGetArticleQuery.tsx b/packages/web/lib/networking/queries/useGetArticleQuery.tsx index a75f5f72a..0d7422db2 100644 --- a/packages/web/lib/networking/queries/useGetArticleQuery.tsx +++ b/packages/web/lib/networking/queries/useGetArticleQuery.tsx @@ -1,11 +1,11 @@ import { gql } from 'graphql-request' -import useSWRImmutable from 'swr' -import useSWR from 'swr' +import useSWRImmutable, { Cache } from 'swr' import { makeGqlFetcher, RequestContext, ssrFetcher } from '../networkHelpers' import { articleFragment, ContentReader } from '../fragments/articleFragment' import { Highlight, highlightFragment } from '../fragments/highlightFragment' -import { KeyedMutator, ScopedMutator } from 'swr/dist/types' +import { ScopedMutator } from 'swr/dist/types' import { Label, labelFragment } from '../fragments/labelFragment' +import { LibraryItems } from './useGetLibraryItemsQuery' type ArticleQueryInput = { username?: string @@ -17,7 +17,6 @@ type ArticleQueryOutput = { articleData?: ArticleData articleFetchError: unknown isLoading: boolean - mutate: KeyedMutator } type ArticleData = { @@ -79,16 +78,7 @@ const query = gql` ${highlightFragment} ${labelFragment} ` -export const cacheArticle = ( - mutate: ScopedMutator, - username: string, - article: ArticleAttributes, - includeFriendsHighlights = false -) => { - mutate([query, username, article.slug, includeFriendsHighlights], { - article: { article: { ...article, cached: true } }, - }) -} + export function useGetArticleQuery({ username, @@ -101,7 +91,7 @@ export function useGetArticleQuery({ includeFriendsHighlights, } - const { data, error, mutate } = useSWR( + const { data, error, mutate } = useSWRImmutable( slug ? [query, username, slug, includeFriendsHighlights] : null, makeGqlFetcher(variables) ) @@ -118,7 +108,6 @@ export function useGetArticleQuery({ } return { - mutate, articleData: resultData, articleFetchError: resultError as unknown, isLoading: !error && !data, @@ -136,3 +125,46 @@ export async function articleQuery( return Promise.reject() } + +export const cacheArticle = ( + mutate: ScopedMutator, + username: string, + article: ArticleAttributes, + includeFriendsHighlights = false +) => { + mutate([query, username, article.slug, includeFriendsHighlights], { + article: { article: { ...article, cached: true } }, + }) +} + + +export const removeItemFromCache = ( + cache: Cache, + mutate: ScopedMutator, + itemId: string, +) => { + try { + const mappedCache = cache as Map + mappedCache.forEach((value: any, key) => { + if (typeof value == 'object' && 'articles' in value) { + const articles = value.articles as LibraryItems + const idx = articles.edges.findIndex((edge) => edge.node.id == itemId) + if (idx > -1) { + value.articles.edges.splice(idx, 1) + mutate(key, value, false) + } + } + }) + + mappedCache.forEach((value: any, key) => { + if (Array.isArray(value)) { + const idx = value.findIndex((item) => 'articles' in item) + if (idx > -1) { + mutate(key, value, false) + } + } + }) + } catch (error) { + console.log('error removing item from cache', error) + } +} diff --git a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx index 3a761076e..ad02f5e96 100644 --- a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx +++ b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx @@ -40,7 +40,7 @@ export type LibraryItemsData = { articles: LibraryItems } -type LibraryItems = { +export type LibraryItems = { edges: LibraryItem[] pageInfo: PageInfo errorCodes?: string[] diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index 7eb2c194e..dbfbb69d6 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -1,7 +1,7 @@ import { PrimaryLayout } from '../../../components/templates/PrimaryLayout' import { LoadingView } from '../../../components/patterns/LoadingView' import { useGetViewerQuery } from '../../../lib/networking/queries/useGetViewerQuery' -import { useGetArticleQuery } from '../../../lib/networking/queries/useGetArticleQuery' +import { removeItemFromCache, useGetArticleQuery } from '../../../lib/networking/queries/useGetArticleQuery' import { useRouter } from 'next/router' import { VStack } from './../../../components/elements/LayoutPrimitives' import { ArticleContainer } from './../../../components/templates/article/ArticleContainer' @@ -25,6 +25,8 @@ import { ArticleActionsMenu } from '../../../components/templates/article/Articl import { HighlightsModal } from '../../../components/templates/article/HighlightsModal' import { setLinkArchivedMutation } from '../../../lib/networking/mutations/setLinkArchivedMutation' import { Label } from '../../../lib/networking/fragments/labelFragment' +import { useSWRConfig } from 'swr' +import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers' const PdfArticleContainerNoSSR = dynamic( @@ -34,6 +36,7 @@ const PdfArticleContainerNoSSR = dynamic( export default function Home(): JSX.Element { const router = useRouter() + const { cache, mutate } = useSWRConfig() const scrollRef = useRef(null) const { slug } = router.query const [showHighlightsModal, setShowHighlightsModal] = useState(false) @@ -73,12 +76,20 @@ export default function Home(): JSX.Element { switch (action) { case 'archive': if (article) { + removeItemFromCache(cache, mutate, article.id) + await setLinkArchivedMutation({ linkId: article.id, archived: true, + }).then((res) => { + if (res) { + showSuccessToast('Link archived', { position: 'bottom-right' }) + } else { + // todo: + showErrorToast('Error archiving link', { position: 'bottom-right' }) + } }) - // TODO: merge from article actions PR - // removeItemFromCache(cache, mutate, props.article.id) + router.push(`/home`) } break From 34d892a9a26748702461b44ed505ce2fa223012a Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 11:16:04 -0700 Subject: [PATCH 46/91] Update comment --- packages/web/pages/[username]/[slug]/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index dbfbb69d6..b4d84cfda 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -85,7 +85,7 @@ export default function Home(): JSX.Element { if (res) { showSuccessToast('Link archived', { position: 'bottom-right' }) } else { - // todo: + // todo: revalidate or put back in cache? showErrorToast('Error archiving link', { position: 'bottom-right' }) } }) From 110a503927eb80bec2f84e7c85daa6df3898cd8c Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 11:31:28 -0700 Subject: [PATCH 47/91] Implement the Create new Label button --- .../templates/article/EditLabelsControl.tsx | 21 ++++++++++++------- .../mutations/createLabelMutation.ts | 14 +++++++++++-- .../labels/labelColorObjects.tsx | 6 ++++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index a4910b2ca..ed70506a6 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -12,6 +12,9 @@ import { Check, Circle, PencilSimple, Plus } from 'phosphor-react' import { isTouchScreenDevice } from '../../../lib/deviceType' import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation' +import { createLabelMutation } from '../../../lib/networking/mutations/createLabelMutation' +import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers' +import { randomLabelColorHex } from '../../../utils/settings-page/labels/labelColorObjects' type EditLabelsControlProps = { article: ArticleAttributes @@ -194,8 +197,6 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { ) props.article.labels = result props.articleActionHandler('refreshLabels', result) - - console.log('refreshing article with labels', props.article.labels) }, [isSelected, selectedLabels]) const filteredLabels = useMemo(() => { @@ -276,17 +277,23 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { )} - {/* Footer */} + + )} + { + const colorHexes = Object.keys(labelColorObjects).slice(0, -1) + const randomColorHex = colorHexes[Math.floor(Math.random() * colorHexes.length)] + return randomColorHex +} \ No newline at end of file From 96ba44df6e45a11fe90710c58b14bcd1f39cedf8 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 11:53:43 -0700 Subject: [PATCH 48/91] Remove unused ref prop --- .../web/components/templates/article/EditLabelsControl.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index ed70506a6..1771b1fb8 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -24,7 +24,6 @@ type EditLabelsControlProps = { type HeaderProps = { filterText: string focused: boolean - parentRef: React.RefObject setFilterText: (text: string) => void } @@ -169,7 +168,6 @@ function LabelListItem(props: LabelListItemProps): JSX.Element { } export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { - const parentRef = useRef(null) const [filterText, setFilterText] = useState('') const { labels } = useGetLabelsQuery() const [selectedLabels, setSelectedLabels] = useState(props.article.labels || []) @@ -244,7 +242,6 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { return (
From 4888c75b9afca8b528afc02f81e162ca9efa7d75 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 11:59:33 -0700 Subject: [PATCH 49/91] Reset focused index when search bar gets focus This is needed if someone combines keyboard navigation and using the mouse to select the textbox --- .../templates/article/EditLabelsControl.tsx | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index 1771b1fb8..5b034a14f 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -24,6 +24,7 @@ type EditLabelsControlProps = { type HeaderProps = { filterText: string focused: boolean + resetFocusedIndex: () => void setFilterText: (text: string) => void } @@ -47,28 +48,6 @@ const StyledLabel = styled('label', { }, }) -const useToggleLabels = () => { - const [selectedLabels, setSelectedLabels] = useState([]) - - const isSelected = useCallback((label: Label): boolean => { - return selectedLabels.some((other) => { - return other.id === label.id - }) - }, [selectedLabels]) - - const toggleLabel = useCallback((label: Label) => { - if (isSelected(label)) { - setSelectedLabels(selectedLabels.filter((other) => { - return other.id !== label.id - })) - } else { - setSelectedLabels([...selectedLabels, label]) - } - }, [isSelected, selectedLabels]) - - return [isSelected, toggleLabel] -} - function Header(props: HeaderProps): JSX.Element { const inputRef = useRef(null) @@ -95,6 +74,9 @@ function Header(props: HeaderProps): JSX.Element { onChange={(event) => { props.setFilterText(event.target.value) }} + onFocus={() => { + props.resetFocusedIndex() + }} css={{ border: '1px solid $grayBorder', borderRadius: '8px', @@ -213,6 +195,7 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { // Move focus through the labels list on tab or arrow up/down keys const [focusedIndex, setFocusedIndex] = useState(undefined) const handleKeyDown = useCallback((event: React.KeyboardEvent) => { + const maxIndex = filteredLabels.length + 2 if (event.key === 'ArrowUp') { event.preventDefault() if (focusedIndex) { @@ -226,8 +209,9 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { if (focusedIndex === undefined) { setFocusedIndex(0) } else { - setFocusedIndex(Math.min(filteredLabels.length - 1, focusedIndex + 1)) + setFocusedIndex(Math.min(maxIndex, focusedIndex + 1)) } + console.log('focusedIndex', focusedIndex) } if (event.key === 'Enter') { event.preventDefault() @@ -255,6 +239,7 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { }}>
setFocusedIndex(undefined)} setFilterText={setFilterText} filterText={filterText} /> @@ -290,7 +275,7 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { )} - Date: Mon, 11 Apr 2022 13:05:26 -0700 Subject: [PATCH 50/91] Allow selection of the bottom edit labels footer --- .../templates/article/EditLabelsControl.tsx | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index 5b034a14f..d4a09e38d 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -43,9 +43,6 @@ const FormInput = styled('input', { const StyledLabel = styled('label', { display: 'flex', justifyContent: 'flex-start', - '&:focus': { - bg: '$grayBgActive', - }, }) function Header(props: HeaderProps): JSX.Element { @@ -149,6 +146,39 @@ function LabelListItem(props: LabelListItemProps): JSX.Element { ) } +type EditLabelsButtonFooterProps = { + focused: boolean +} + +function EditLabelsButtonFooter(props: EditLabelsButtonFooterProps): JSX.Element { + const ref = useRef(null) + + useEffect(() => { + if (props.focused && ref.current) { + ref.current.focus() + } + }, [props.focused]) + + return ( + + + Edit labels + + ) +} + export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { const [filterText, setFilterText] = useState('') const { labels } = useGetLabelsQuery() @@ -211,7 +241,6 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { } else { setFocusedIndex(Math.min(maxIndex, focusedIndex + 1)) } - console.log('focusedIndex', focusedIndex) } if (event.key === 'Enter') { event.preventDefault() @@ -275,19 +304,7 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { )} - - - Edit labels - + ) } \ No newline at end of file From 454f379e700670b64620557d3543d3a34ee110fe Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 13:27:43 -0700 Subject: [PATCH 51/91] Navigate via keyboard to edit labels page --- .../templates/article/EditLabelsControl.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index d4a09e38d..d0bfd9f31 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -15,6 +15,7 @@ import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMu import { createLabelMutation } from '../../../lib/networking/mutations/createLabelMutation' import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers' import { randomLabelColorHex } from '../../../utils/settings-page/labels/labelColorObjects' +import Router, { useRouter } from 'next/router' type EditLabelsControlProps = { article: ArticleAttributes @@ -180,6 +181,7 @@ function EditLabelsButtonFooter(props: EditLabelsButtonFooterProps): JSX.Element } export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { + const router = useRouter() const [filterText, setFilterText] = useState('') const { labels } = useGetLabelsQuery() const [selectedLabels, setSelectedLabels] = useState(props.article.labels || []) @@ -207,7 +209,7 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { ) props.article.labels = result props.articleActionHandler('refreshLabels', result) - }, [isSelected, selectedLabels]) + }, [isSelected, selectedLabels, setSelectedLabels]) const filteredLabels = useMemo(() => { if (!labels) { @@ -244,6 +246,10 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { } if (event.key === 'Enter') { event.preventDefault() + if (focusedIndex === maxIndex) { + router.push('/settings/labels') + return + } if (focusedIndex !== undefined) { const label = filteredLabels[focusedIndex] if (label) { @@ -251,7 +257,7 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { } } } - }, [filteredLabels, focusedIndex]) + }, [filteredLabels, focusedIndex, isSelected, selectedLabels, setSelectedLabels]) return ( {filterText && ( )} From 113101fd6380ffb064eae991b9b0ef33cfb37193 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 13:58:38 -0700 Subject: [PATCH 53/91] Handle creating labels via keyboard --- .../templates/article/EditLabelsControl.tsx | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index edb5ea129..f0b403c7e 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -183,9 +183,13 @@ function EditLabelsButtonFooter(props: EditLabelsButtonFooterProps): JSX.Element export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { const router = useRouter() const [filterText, setFilterText] = useState('') - const { labels } = useGetLabelsQuery() + const { labels, revalidate } = useGetLabelsQuery() const [selectedLabels, setSelectedLabels] = useState(props.article.labels || []) + useEffect(() => { + setFocusedIndex(undefined) + }, [filterText]) + const isSelected = useCallback((label: Label): boolean => { return selectedLabels.some((other) => { return other.id === label.id @@ -207,8 +211,11 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { props.article.linkId, newSelectedLabels.map((label) => label.id) ) + props.article.labels = result props.articleActionHandler('refreshLabels', result) + + revalidate() }, [isSelected, selectedLabels, setSelectedLabels]) const filteredLabels = useMemo(() => { @@ -220,13 +227,9 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { }) }, [labels, filterText]) - useEffect(() => { - setFocusedIndex(undefined) - }, [filterText]) - // Move focus through the labels list on tab or arrow up/down keys const [focusedIndex, setFocusedIndex] = useState(undefined) - const handleKeyDown = useCallback((event: React.KeyboardEvent) => { + const handleKeyDown = useCallback(async (event: React.KeyboardEvent) => { const maxIndex = filteredLabels.length + 1 if (event.key === 'ArrowUp') { event.preventDefault() @@ -264,6 +267,10 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { router.push('/settings/labels') return } + if (focusedIndex === maxIndex - 1) { + await createLabelFromFilterText() + return + } if (focusedIndex !== undefined) { const label = filteredLabels[focusedIndex] if (label) { @@ -271,7 +278,17 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { } } } - }, [filteredLabels, focusedIndex, isSelected, selectedLabels, setSelectedLabels]) + }, [filterText, filteredLabels, focusedIndex, isSelected, selectedLabels, setSelectedLabels]) + + const createLabelFromFilterText = useCallback(async () => { + const label = await createLabelMutation(filterText, randomLabelColorHex(), '') + if (label) { + showSuccessToast(`Created label ${label.name}`, { position: 'bottom-right' }) + toggleLabel(label) + } else { + showErrorToast('Failed to create label', { position: 'bottom-right' }) + } + }, [filterText, selectedLabels, setSelectedLabels, toggleLabel]) return ( { - const label = await createLabelMutation(filterText, randomLabelColorHex(), '') - if (label) { - showSuccessToast(`Created label ${label.name}`, { position: 'bottom-right' }) - toggleLabel(label) - } else { - showErrorToast('Failed to create label', { position: 'bottom-right' }) - } - }} + onClick={createLabelFromFilterText} > From aa9797f4d44b7d30d6be7e57865d713029586f41 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 14:06:11 -0700 Subject: [PATCH 54/91] Dont reserve label space if there are no labels --- packages/web/components/templates/article/ArticleContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/ArticleContainer.tsx b/packages/web/components/templates/article/ArticleContainer.tsx index cb4a31003..74fda11f6 100644 --- a/packages/web/components/templates/article/ArticleContainer.tsx +++ b/packages/web/components/templates/article/ArticleContainer.tsx @@ -148,7 +148,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { href={props.article.url} /> {props.labels ? ( - + {props.labels?.map((label) => )} From 8d5425bc536cac21ce77719144405ac442ada68a Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 14:45:29 -0700 Subject: [PATCH 55/91] Show a success message when reader settings are reset --- .../web/components/templates/article/ReaderSettingsModal.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/web/components/templates/article/ReaderSettingsModal.tsx b/packages/web/components/templates/article/ReaderSettingsModal.tsx index 0923b7e09..e8a312370 100644 --- a/packages/web/components/templates/article/ReaderSettingsModal.tsx +++ b/packages/web/components/templates/article/ReaderSettingsModal.tsx @@ -19,6 +19,7 @@ import { AlignCenterHorizontalSimple, ArrowsInLineHorizontal, ArrowsOutLineHoriz import { AIcon } from '../../elements/images/AIcon' import { TickedRangeSlider } from '../../elements/TickedRangeSlider' import { UserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' +import { showSuccessToast } from '../../../lib/toastHelpers' type ReaderSettingsProps = { userPreferences?: UserPreferences @@ -124,6 +125,7 @@ export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { setMarginWidth(360) setLineHeight(150) props.articleActionHandler('resetReaderSettings') + showSuccessToast('Display settings reset', { position: 'bottom-right' }) }} > From a6566e4a9b152d7ae67f5ce820ccfb00a2e33ee6 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 14:46:02 -0700 Subject: [PATCH 56/91] Rename notes sidebar to highlights modal --- .../components/templates/article/ArticleContainer.tsx | 11 +++++++---- .../templates/article/ArticleHeaderToolbar.tsx | 4 ++-- .../components/templates/article/HighlightsLayer.tsx | 8 ++++---- packages/web/pages/[username]/[slug]/index.tsx | 11 ++--------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/web/components/templates/article/ArticleContainer.tsx b/packages/web/components/templates/article/ArticleContainer.tsx index 74fda11f6..6d318bdbb 100644 --- a/packages/web/components/templates/article/ArticleContainer.tsx +++ b/packages/web/components/templates/article/ArticleContainer.tsx @@ -15,6 +15,7 @@ import { updateThemeLocally } from '../../../lib/themeUpdater' import { ArticleMutations } from '../../../lib/articleActions' import { LabelChip } from '../../elements/LabelChip' import { Label } from '../../../lib/networking/fragments/labelFragment' +import { HighlightsModal } from './HighlightsModal' type ArticleContainerProps = { article: ArticleAttributes @@ -28,11 +29,13 @@ type ArticleContainerProps = { fontSize?: number fontFamily?: string lineHeight?: number + showHighlightsModal?: boolean + setShowHighlightsModal?: (show: boolean) => void } export function ArticleContainer(props: ArticleContainerProps): JSX.Element { const [showShareModal, setShowShareModal] = useState(false) - const [showNotesSidebar, setShowNotesSidebar] = useState(false) + const [showHighlightsModal, setShowHighlightsModal] = useState(false) const [showReportIssuesModal, setShowReportIssuesModal] = useState(false) const [fontSize, setFontSize] = useState(props.fontSize ?? 20) @@ -157,7 +160,7 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { 0} /> @@ -193,9 +196,9 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { articleId={props.article.id} isAppleAppEmbed={props.isAppleAppEmbed} highlightBarDisabled={props.highlightBarDisabled} - showNotesSidebar={showNotesSidebar} + showHighlightsModal={showHighlightsModal} highlightsBaseURL={props.highlightsBaseURL} - setShowNotesSidebar={setShowNotesSidebar} + setShowHighlightsModal={setShowHighlightsModal} articleMutations={props.articleMutations} /> {showReportIssuesModal ? ( diff --git a/packages/web/components/templates/article/ArticleHeaderToolbar.tsx b/packages/web/components/templates/article/ArticleHeaderToolbar.tsx index c870a7682..ca2edb16d 100644 --- a/packages/web/components/templates/article/ArticleHeaderToolbar.tsx +++ b/packages/web/components/templates/article/ArticleHeaderToolbar.tsx @@ -14,7 +14,7 @@ type ArticleHeaderToolbarProps = { articleTitle: string articleShareURL: string hasHighlights: boolean - setShowNotesSidebar: (showNotesSidebar: boolean) => void + setShowHighlightsModal: (showHighlightsModal: boolean) => void setShowShareArticleModal: (showShareModal: boolean) => void } @@ -46,7 +46,7 @@ export function ArticleHeaderToolbar( return ( {props.hasHighlights && ( - From f0a725b7efc8e5f886113a15cd5f6cc0e3afb08e Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 15:20:07 -0700 Subject: [PATCH 59/91] Dont let labels list expand too wide --- .../web/components/templates/article/ArticleActionsMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index f8fbb8c22..6514f5000 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -41,7 +41,7 @@ type ActionDropdownProps = { const ActionDropdown = (props: ActionDropdownProps): JSX.Element => { return Date: Mon, 11 Apr 2022 15:24:19 -0700 Subject: [PATCH 60/91] Set the label modal width to be consistent --- .../web/components/templates/article/ArticleActionsMenu.tsx | 2 +- packages/web/components/templates/article/EditLabelsControl.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 6514f5000..7c411dbad 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -41,7 +41,7 @@ type ActionDropdownProps = { const ActionDropdown = (props: ActionDropdownProps): JSX.Element => { return Date: Mon, 11 Apr 2022 15:36:19 -0700 Subject: [PATCH 61/91] Only show the old article toolbar on ios embedded web (/app) --- .../templates/article/ArticleContainer.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/web/components/templates/article/ArticleContainer.tsx b/packages/web/components/templates/article/ArticleContainer.tsx index ab3b00800..3c879b7cb 100644 --- a/packages/web/components/templates/article/ArticleContainer.tsx +++ b/packages/web/components/templates/article/ArticleContainer.tsx @@ -157,13 +157,15 @@ export function ArticleContainer(props: ArticleContainerProps): JSX.Element { )} ) : null} - 0} - /> + {props.isAppleAppEmbed && ( + 0} + /> + )}
Date: Mon, 11 Apr 2022 15:36:35 -0700 Subject: [PATCH 62/91] Dont set a max width on smaller devices for the labels modal --- .../web/components/templates/article/EditLabelsControl.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index b988fda21..de29a323e 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -297,10 +297,6 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { css={{ p: '0', maxHeight: '92%', - '@mdDown': { - maxWidth: '100%', - maxHeight: '92%', - }, }}>
Date: Mon, 11 Apr 2022 18:46:51 -0700 Subject: [PATCH 63/91] Use a modal instead of dropdown on small screens --- .../templates/article/ArticleActionsMenu.tsx | 56 +++++++++++-------- .../templates/article/ArticleContainer.tsx | 1 - .../templates/article/EditLabelsControl.tsx | 32 ++++++----- .../templates/article/EditLabelsModal.tsx | 42 ++++++++++++-- .../web/pages/[username]/[slug]/index.tsx | 15 +++++ 5 files changed, 103 insertions(+), 43 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 7c411dbad..3b13c4d5c 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -4,7 +4,7 @@ import { ArticleAttributes } from "../../../lib/networking/queries/useGetArticle import { useGetUserPreferences } from "../../../lib/networking/queries/useGetUserPreferences" import { Button } from "../../elements/Button" import { Dropdown } from "../../elements/DropdownElements" -import { Box } from "../../elements/LayoutPrimitives" +import { Box, SpanBox } from "../../elements/LayoutPrimitives" import { TooltipWrapped } from "../../elements/Tooltip" import { styled, theme } from "../../tokens/stitches.config" import { EditLabelsControl } from "./EditLabelsControl" @@ -84,32 +84,40 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element - - - - } + - - -{/* - */} + + + + ) diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index c0dfc3589..5748a0013 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -27,6 +27,8 @@ import { setLinkArchivedMutation } from '../../../lib/networking/mutations/setLi import { Label } from '../../../lib/networking/fragments/labelFragment' import { useSWRConfig } from 'swr' import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers' +import { EditLabelsControl } from '../../../components/templates/article/EditLabelsControl' +import { EditLabelsModal } from '../../../components/templates/article/EditLabelsModal' const PdfArticleContainerNoSSR = dynamic( @@ -46,6 +48,7 @@ export default function Home(): JSX.Element { const [fontSize, setFontSize] = useState(preferencesData?.fontSize ?? 20) const [marginWidth, setMarginWidth] = useState(preferencesData?.margin ?? 360) const [lineHeight, setLineHeight] = useState(preferencesData?.lineHeight ?? 150) + const [showEditLabelsModal, setShowEditLabelsModal] = useState(false) const { articleData } = useGetArticleQuery({ username: router.query.username as string, @@ -131,6 +134,10 @@ export default function Home(): JSX.Element { } break } + case 'editLabels': { + setShowEditLabelsModal(true) + break + } case 'resetReaderSettings': { updateFontSize(20) updateMarginWidth(360) @@ -230,6 +237,14 @@ export default function Home(): JSX.Element { /> )} + + {showEditLabelsModal && ( + setShowEditLabelsModal(false)} + /> + )} ) } From 68933689f6118f9bfaaed7b20f04d5cc9eb9f117 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 19:08:19 -0700 Subject: [PATCH 64/91] Close labels modal when tap outside --- packages/web/components/templates/article/EditLabelsModal.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index 2e048310e..ca45e65f8 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -23,10 +23,11 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { { event.preventDefault() + props.onOpenChange(false) }} - css={{ overflow: 'auto', p: '0', width: '100%' }} > Date: Mon, 11 Apr 2022 20:38:54 -0700 Subject: [PATCH 65/91] Smaller display settings dropdown on small screens. Better shadows --- .../templates/article/ArticleActionsMenu.tsx | 3 ++- .../templates/article/ReaderSettingsModal.tsx | 4 ++-- packages/web/pages/[username]/[slug]/index.tsx | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 3b13c4d5c..a1d3f951b 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -41,7 +41,7 @@ type ActionDropdownProps = { const ActionDropdown = (props: ActionDropdownProps): JSX.Element => { return + - Margin: + Margin: + + + + + + ) +} From 9834303b3c5e5e75e34deb66df3c3d7c5b209e28 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 11 Apr 2022 21:17:26 -0700 Subject: [PATCH 67/91] Refine box shadows in dark mode --- packages/web/components/tokens/stitches.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/tokens/stitches.config.ts b/packages/web/components/tokens/stitches.config.ts index de59a709b..1a45ef788 100644 --- a/packages/web/components/tokens/stitches.config.ts +++ b/packages/web/components/tokens/stitches.config.ts @@ -200,7 +200,7 @@ const darkThemeSpec = { }, shadows: { cardBoxShadow: - '0px 0px 9px -2px rgba(32, 31, 29, 0.09), 0px 7px 12px rgba(32, 31, 29, 0.07)', + '0px 0px 9px -2px rgba(255, 255, 255, 0.09), 0px 7px 12px rgba(255, 255, 255, 0.07)', }, } From cbff548b9854cb17ff2c75d7ae6ae2b5eb362a7c Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 08:42:15 -0700 Subject: [PATCH 68/91] Tweak box shadows in dark mode --- packages/web/components/tokens/stitches.config.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/web/components/tokens/stitches.config.ts b/packages/web/components/tokens/stitches.config.ts index 1a45ef788..f9937aa33 100644 --- a/packages/web/components/tokens/stitches.config.ts +++ b/packages/web/components/tokens/stitches.config.ts @@ -102,8 +102,7 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } = borderStyles: {}, shadows: { panelShadow: '0px 4px 18px rgba(120, 123, 134, 0.12)', - cardBoxShadow: - '0px 0px 9px -2px rgba(32, 31, 29, 0.09), 0px 7px 12px rgba(32, 31, 29, 0.07)', + cardBoxShadow: '0px 0px 4px 0px rgb(255 255 255 / 10%)', }, zIndices: {}, transitions: {}, From 244cced8b400f0a81625df82ca4f2f16bce37d7a Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 12:35:56 -0700 Subject: [PATCH 69/91] Make the labels modal non-scrollable on small screens, add a border --- packages/web/components/templates/article/EditLabelsModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index ca45e65f8..1ef6da940 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -23,7 +23,7 @@ export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { { event.preventDefault() props.onOpenChange(false) From 0d1b05d4fc246e00e0ec0886c27cafa5e9108e41 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 12:58:04 -0700 Subject: [PATCH 70/91] Rename reader settings --- .../web/components/templates/article/ArticleActionsMenu.tsx | 4 ++-- .../components/templates/article/DisplaySettingsModal.tsx | 5 ++--- .../{ReaderSettingsModal.tsx => ReaderSettingsControl.tsx} | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) rename packages/web/components/templates/article/{ReaderSettingsModal.tsx => ReaderSettingsControl.tsx} (98%) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index a1d3f951b..410ae3080 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -8,7 +8,7 @@ import { Box, SpanBox } from "../../elements/LayoutPrimitives" import { TooltipWrapped } from "../../elements/Tooltip" import { styled, theme } from "../../tokens/stitches.config" import { EditLabelsControl } from "./EditLabelsControl" -import { ReaderSettings } from "./ReaderSettingsModal" +import { ReaderSettingsControl } from "./ReaderSettingsControl" export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' @@ -80,7 +80,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } > - + diff --git a/packages/web/components/templates/article/DisplaySettingsModal.tsx b/packages/web/components/templates/article/DisplaySettingsModal.tsx index b2d3b40ed..c7e0623cb 100644 --- a/packages/web/components/templates/article/DisplaySettingsModal.tsx +++ b/packages/web/components/templates/article/DisplaySettingsModal.tsx @@ -11,8 +11,7 @@ import { } from '../../elements/ModalPrimitives' import { StyledText } from '../../elements/StyledText' import { theme } from '../../tokens/stitches.config' -import { EditLabelsControl } from './EditLabelsControl' -import { ReaderSettings } from './ReaderSettingsModal' +import { ReaderSettingsControl } from './ReaderSettingsControl' type DisplaySettingsModalProps = { onOpenChange: (open: boolean) => void @@ -51,7 +50,7 @@ export function DisplaySettingsModal(props: DisplaySettingsModalProps): JSX.Elem /> - + diff --git a/packages/web/components/templates/article/ReaderSettingsModal.tsx b/packages/web/components/templates/article/ReaderSettingsControl.tsx similarity index 98% rename from packages/web/components/templates/article/ReaderSettingsModal.tsx rename to packages/web/components/templates/article/ReaderSettingsControl.tsx index 1f435978d..fd1e74004 100644 --- a/packages/web/components/templates/article/ReaderSettingsModal.tsx +++ b/packages/web/components/templates/article/ReaderSettingsControl.tsx @@ -9,6 +9,7 @@ import { TickedRangeSlider } from '../../elements/TickedRangeSlider' import { UserPreferences } from '../../../lib/networking/queries/useGetUserPreferences' import { showSuccessToast } from '../../../lib/toastHelpers' + type ReaderSettingsProps = { userPreferences?: UserPreferences articleActionHandler: (action: string, arg?: number) => void @@ -20,7 +21,7 @@ const VerticalDivider = styled(SpanBox, { background: `${theme.colors.grayLine.toString()}`, }) -export function ReaderSettings(props: ReaderSettingsProps): JSX.Element { +export function ReaderSettingsControl(props: ReaderSettingsProps): JSX.Element { const [marginWidth, setMarginWidth] = useState(props.userPreferences?.margin ?? 0) const [lineHeight, setLineHeight] = useState(props.userPreferences?.lineHeight ?? 150) From 372cd6afe2df25968984d9f98f1caa3a18ee5f0d Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 13:16:25 -0700 Subject: [PATCH 71/91] More consistent boxshadows with themes --- packages/web/components/patterns/HighlightBar.tsx | 2 +- packages/web/components/tokens/stitches.config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/components/patterns/HighlightBar.tsx b/packages/web/components/patterns/HighlightBar.tsx index 444fb0f56..ead951168 100644 --- a/packages/web/components/patterns/HighlightBar.tsx +++ b/packages/web/components/patterns/HighlightBar.tsx @@ -44,7 +44,7 @@ export function HighlightBar(props: HighlightBarProps): JSX.Element { background: '$grayBg', borderRadius: '4px', border: '1px solid $grayBorder', - boxShadow: '0px 0px 9px -2px rgba(32, 31, 29, 0.09), 0px 7px 12px rgba(32, 31, 29, 0.07)', + boxShadow: theme.shadows.cardBoxShadow.toString(), bottom: 'calc(38px + env(safe-area-inset-bottom, 40px))', '@smDown': { maxWidth: '80%', diff --git a/packages/web/components/tokens/stitches.config.ts b/packages/web/components/tokens/stitches.config.ts index f9937aa33..80a87e59f 100644 --- a/packages/web/components/tokens/stitches.config.ts +++ b/packages/web/components/tokens/stitches.config.ts @@ -102,7 +102,7 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } = borderStyles: {}, shadows: { panelShadow: '0px 4px 18px rgba(120, 123, 134, 0.12)', - cardBoxShadow: '0px 0px 4px 0px rgb(255 255 255 / 10%)', + cardBoxShadow: '0px 0px 4px 0px rgba(0, 0, 0, 0.1)', }, zIndices: {}, transitions: {}, From d92b526583117d9ca7d115ae4dabe2d9c2c7a2c7 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 18:09:43 -0700 Subject: [PATCH 72/91] Give the labels control a max height --- packages/web/components/templates/article/EditLabelsControl.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index 77f56a526..ead74eb03 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -300,7 +300,7 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { css={{ p: '0', width: '100%', - maxHeight: '80%', + maxHeight: '380px', }}>
Date: Tue, 12 Apr 2022 18:10:43 -0700 Subject: [PATCH 73/91] Fix tooltip tags -> labels --- .../web/components/templates/article/ArticleActionsMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 410ae3080..64aa0b20c 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -95,7 +95,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element layout={props.layout} triggerElement={ From 11429dddc060d00c6539ae319ff7d0f494480075 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 20:08:18 -0700 Subject: [PATCH 74/91] Dont autofocus the text input on mobile On mobile we dont want to auto focus because the keyboard opens and takes up most of the screen space. --- .../web/components/templates/article/EditLabelsControl.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index ead74eb03..aa62b492e 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -50,14 +50,14 @@ function Header(props: HeaderProps): JSX.Element { const inputRef = useRef(null) useEffect(() => { - if (props.focused && inputRef.current) { + if (!isTouchScreenDevice() && props.focused && inputRef.current) { inputRef.current.focus() } }, [props.focused]) return ( - Date: Tue, 12 Apr 2022 20:09:03 -0700 Subject: [PATCH 75/91] Set the link colour. Safari needs this --- packages/web/components/templates/article/EditLabelsControl.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index aa62b492e..96e297242 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -167,6 +167,7 @@ function EditLabelsButtonFooter(props: EditLabelsButtonFooterProps): JSX.Element css={{ width: '100%', height: '42px', bg: props.focused ? '$grayBgActive' : 'unset', + color: theme.colors.grayText.toString(), 'a:link': { textDecoration: 'none', }, From a728bcf88699006d00a967691b20d0149d575b5c Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 20:36:00 -0700 Subject: [PATCH 76/91] Improve sizing of scrollable content area on mobile --- .../web/components/templates/article/EditLabelsControl.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/web/components/templates/article/EditLabelsControl.tsx b/packages/web/components/templates/article/EditLabelsControl.tsx index 96e297242..6eff4bacb 100644 --- a/packages/web/components/templates/article/EditLabelsControl.tsx +++ b/packages/web/components/templates/article/EditLabelsControl.tsx @@ -301,14 +301,17 @@ export function EditLabelsControl(props: EditLabelsControlProps): JSX.Element { css={{ p: '0', width: '100%', - maxHeight: '380px', }}>
setFocusedIndex(undefined)} setFilterText={setFilterText} filterText={filterText} /> - + {filteredLabels && filteredLabels.map((label, idx) => ( Date: Tue, 12 Apr 2022 20:50:06 -0700 Subject: [PATCH 77/91] Update to use pageId instead of linkId for SetLabels API --- packages/web/lib/networking/mutations/setLabelsMutation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/lib/networking/mutations/setLabelsMutation.ts b/packages/web/lib/networking/mutations/setLabelsMutation.ts index a7d3aa0bb..6953bcc45 100644 --- a/packages/web/lib/networking/mutations/setLabelsMutation.ts +++ b/packages/web/lib/networking/mutations/setLabelsMutation.ts @@ -12,7 +12,7 @@ type SetLabels = { } export async function setLabelsMutation( - linkId: string, + pageId: string, labelIds: string[] ): Promise { const mutation = gql` @@ -32,7 +32,7 @@ export async function setLabelsMutation( ` try { - const data = await gqlFetcher(mutation, { input: { linkId, labelIds } }) as SetLabelsResult + const data = await gqlFetcher(mutation, { input: { pageId, labelIds } }) as SetLabelsResult return data.errorCodes ? undefined : data.setLabels.labels } catch (error) { console.log('SetLabelsOutput error', error) From 5a4e4baae6e6a71163cced7b0314eb08bb036f97 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 12 Apr 2022 21:49:48 -0700 Subject: [PATCH 78/91] Handle changes to createLabel response. Trim label names --- packages/web/pages/settings/labels.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/web/pages/settings/labels.tsx b/packages/web/pages/settings/labels.tsx index 2c144f55a..d03e5eec9 100644 --- a/packages/web/pages/settings/labels.tsx +++ b/packages/web/pages/settings/labels.tsx @@ -183,18 +183,14 @@ export default function LabelsPage(): JSX.Element { async function createLabel(): Promise { const res = await createLabelMutation( - nameInputText, + nameInputText.trim(), labelColorHex.value, descriptionInputText ) if (res) { - if (res.createLabel.errorCodes && res.createLabel.errorCodes.length > 0) { - showErrorToast(res.createLabel.errorCodes[0]) - } else { - showSuccessToast('Label created', { position: 'bottom-right' }) - resetLabelState() - revalidate() - } + showSuccessToast('Label created', { position: 'bottom-right' }) + resetLabelState() + revalidate() } else { showErrorToast('Failed to create label') } From 8978ff68f7cfbcd2ad818a906a5806ecde719c22 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 13 Apr 2022 09:58:50 -0700 Subject: [PATCH 79/91] Use standard box shadow on modals --- packages/web/components/elements/ModalPrimitives.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/web/components/elements/ModalPrimitives.tsx b/packages/web/components/elements/ModalPrimitives.tsx index db9aec2e2..3827e020b 100644 --- a/packages/web/components/elements/ModalPrimitives.tsx +++ b/packages/web/components/elements/ModalPrimitives.tsx @@ -1,5 +1,5 @@ import { Root, Overlay, Content } from '@radix-ui/react-dialog' -import { styled, keyframes } from '../tokens/stitches.config' +import { styled, keyframes, theme } from '../tokens/stitches.config' export const ModalRoot = styled(Root, {}) @@ -25,8 +25,7 @@ const contentShow = keyframes({ const Modal = styled(Content, { backgroundColor: '$grayBg', borderRadius: 6, - boxShadow: - 'hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px', + boxShadow: theme.shadows.cardBoxShadow.toString(), position: 'fixed', '&:focus': { outline: 'none' }, }) From 049a5cf22f246b243ff25cb2fd2b32042889f5c8 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 13 Apr 2022 09:59:36 -0700 Subject: [PATCH 80/91] Close highlight modal on click/tap outside --- packages/web/components/templates/article/HighlightsModal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web/components/templates/article/HighlightsModal.tsx b/packages/web/components/templates/article/HighlightsModal.tsx index 750ef1636..92358b057 100644 --- a/packages/web/components/templates/article/HighlightsModal.tsx +++ b/packages/web/components/templates/article/HighlightsModal.tsx @@ -30,6 +30,7 @@ export function HighlightsModal(props: HighlightsModalProps): JSX.Element { { event.preventDefault() + props.onOpenChange(false) }} css={{ overflow: 'auto', p: '0' }} > From 86d6d03fe08e405f99c115985556280782502173 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 13 Apr 2022 10:25:01 -0700 Subject: [PATCH 81/91] Remove default button padding, on Safari this caused extra padding on dropdown triggers --- .../components/templates/article/ArticleActionsMenu.tsx | 7 +++---- packages/web/styles/globals.css | 5 +++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 64aa0b20c..39bef218c 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -63,9 +63,8 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element alignItems: 'center', flexDirection: props.layout == 'vertical' ? 'column' : 'row', justifyContent: props.layout == 'vertical' ? 'center' : 'flex-end', - gap: props.layout == 'vertical' ? '8px' : '20px', + gap: props.layout == 'vertical' ? '8px' : '24px', paddingTop: '6px', - m: '0px', }} > @@ -76,8 +75,8 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element tooltipContent="Adjust Display Settings" tooltipSide={props.layout == 'vertical' ? 'right' : 'bottom'} > - - + + } > diff --git a/packages/web/styles/globals.css b/packages/web/styles/globals.css index dda271556..151ad8a33 100644 --- a/packages/web/styles/globals.css +++ b/packages/web/styles/globals.css @@ -134,4 +134,9 @@ input[type=range]::-webkit-slider-thumb { width: 16px; border-radius: 50%; background: var(--colors-grayTextContrast); +} + +button { + padding: 0px; + margin: 0px; } \ No newline at end of file From 18cbe4a856eeeed01de7d41abe528f0ac2da116e Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 13 Apr 2022 10:28:33 -0700 Subject: [PATCH 82/91] Remove font stepper from dropdown --- .../web/components/patterns/DropdownMenu.tsx | 19 ------------------- .../web/components/patterns/PrimaryHeader.tsx | 4 ---- .../components/templates/PrimaryLayout.tsx | 2 -- .../web/pages/[username]/[slug]/index.tsx | 1 - 4 files changed, 26 deletions(-) diff --git a/packages/web/components/patterns/DropdownMenu.tsx b/packages/web/components/patterns/DropdownMenu.tsx index c63dca2ee..adf9f25ae 100644 --- a/packages/web/components/patterns/DropdownMenu.tsx +++ b/packages/web/components/patterns/DropdownMenu.tsx @@ -24,7 +24,6 @@ export type HeaderDropdownAction = type DropdownMenuProps = { username?: string triggerElement: ReactNode - displayFontStepper?: boolean actionHandler: (action: HeaderDropdownAction) => void } @@ -53,24 +52,6 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element { { isDark ? '✓' : '' } - - {props.displayFontStepper && ( - <> - - - - - - - )} - displayFontStepper?: boolean toolbarControl?: JSX.Element setShowLogoutConfirmation: (showShareModal: boolean) => void setShowKeyboardCommandsModal: (showShareModal: boolean) => void @@ -126,7 +125,6 @@ export function PrimaryHeader(props: HeaderProps): JSX.Element { isVisible={true} isFixedPosition={true} toolbarControl={props.toolbarControl} - displayFontStepper={props.displayFontStepper} /> ) @@ -141,7 +139,6 @@ type NavHeaderProps = { isDisplayingShadow?: boolean isVisible?: boolean isFixedPosition: boolean - displayFontStepper?: boolean toolbarControl?: JSX.Element } @@ -211,7 +208,6 @@ function NavHeader(props: NavHeaderProps): JSX.Element { /> } actionHandler={props.actionHandler} - displayFontStepper={props.displayFontStepper} /> ) : ( diff --git a/packages/web/components/templates/PrimaryLayout.tsx b/packages/web/components/templates/PrimaryLayout.tsx index c73a02ab2..56e85a419 100644 --- a/packages/web/components/templates/PrimaryLayout.tsx +++ b/packages/web/components/templates/PrimaryLayout.tsx @@ -22,7 +22,6 @@ type PrimaryLayoutProps = { hideHeader?: boolean pageMetaDataProps?: PageMetaDataProps scrollElementRef?: MutableRefObject - displayFontStepper?: boolean headerToolbarControl?: JSX.Element } @@ -78,7 +77,6 @@ export function PrimaryLayout(props: PrimaryLayoutProps): JSX.Element { isFixedPosition={true} toolbarControl={props.headerToolbarControl} scrollElementRef={props.scrollElementRef} - displayFontStepper={props.displayFontStepper} setShowLogoutConfirmation={setShowLogoutConfirmation} setShowKeyboardCommandsModal={setShowKeyboardCommandsModal} /> diff --git a/packages/web/pages/[username]/[slug]/index.tsx b/packages/web/pages/[username]/[slug]/index.tsx index c950b11b3..598f7e0cf 100644 --- a/packages/web/pages/[username]/[slug]/index.tsx +++ b/packages/web/pages/[username]/[slug]/index.tsx @@ -164,7 +164,6 @@ export default function Home(): JSX.Element { Date: Wed, 13 Apr 2022 10:34:46 -0700 Subject: [PATCH 83/91] Add dropdown link to labels --- packages/web/components/patterns/DropdownMenu.tsx | 5 +++++ packages/web/components/patterns/PrimaryHeader.tsx | 3 +++ 2 files changed, 8 insertions(+) diff --git a/packages/web/components/patterns/DropdownMenu.tsx b/packages/web/components/patterns/DropdownMenu.tsx index adf9f25ae..317af1ade 100644 --- a/packages/web/components/patterns/DropdownMenu.tsx +++ b/packages/web/components/patterns/DropdownMenu.tsx @@ -16,6 +16,7 @@ export type HeaderDropdownAction = | 'apply-lighter-theme' | 'navigate-to-install' | 'navigate-to-emails' + | 'navigate-to-labels' | 'navigate-to-profile' | 'increaseFontSize' | 'decreaseFontSize' @@ -62,6 +63,10 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element { onSelect={() => props.actionHandler('navigate-to-emails')} title="Emails" /> + props.actionHandler('navigate-to-labels')} + title="Labels" + /> window.Intercom('show')} title="Feedback" diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index 50c64844c..79294d02f 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -102,6 +102,9 @@ export function PrimaryHeader(props: HeaderProps): JSX.Element { case 'navigate-to-emails': router.push('/settings/emails') break + case 'navigate-to-labels': + router.push('/settings/labels') + break case 'navigate-to-profile': if (props.user) { router.push(`/${props.user.profile.username}`) From 4e4dae89d7776dbaaa245a473d5b11efd9fac308 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 13 Apr 2022 10:51:56 -0700 Subject: [PATCH 84/91] Consistent naming on label controls - Edit Labels: Edit all of a user's labels - Set Labels: Set the labels assigned to a link --- .../templates/article/ArticleActionsMenu.tsx | 6 +++--- ...EditLabelsControl.tsx => SetLabelsControl.tsx} | 11 +++++------ .../{EditLabelsModal.tsx => SetLabelsModal.tsx} | 11 +++++------ .../lib/keyboardShortcuts/navigationShortcuts.ts | 4 ++-- packages/web/pages/[username]/[slug]/index.tsx | 15 +++++++-------- 5 files changed, 22 insertions(+), 25 deletions(-) rename packages/web/components/templates/article/{EditLabelsControl.tsx => SetLabelsControl.tsx} (97%) rename packages/web/components/templates/article/{EditLabelsModal.tsx => SetLabelsModal.tsx} (83%) diff --git a/packages/web/components/templates/article/ArticleActionsMenu.tsx b/packages/web/components/templates/article/ArticleActionsMenu.tsx index 39bef218c..75be3afcc 100644 --- a/packages/web/components/templates/article/ArticleActionsMenu.tsx +++ b/packages/web/components/templates/article/ArticleActionsMenu.tsx @@ -7,7 +7,7 @@ import { Dropdown } from "../../elements/DropdownElements" import { Box, SpanBox } from "../../elements/LayoutPrimitives" import { TooltipWrapped } from "../../elements/Tooltip" import { styled, theme } from "../../tokens/stitches.config" -import { EditLabelsControl } from "./EditLabelsControl" +import { SetLabelsControl } from "./SetLabelsControl" import { ReaderSettingsControl } from "./ReaderSettingsControl" export type ArticleActionsMenuLayout = 'horizontal' | 'vertical' @@ -101,7 +101,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element } > - @@ -109,7 +109,7 @@ export function ArticleActionsMenu(props: ArticleActionsMenuProps): JSX.Element )} - +