diff --git a/packages/web/components/elements/Button.tsx b/packages/web/components/elements/Button.tsx
index dbd64c75a..e9085ad81 100644
--- a/packages/web/components/elements/Button.tsx
+++ b/packages/web/components/elements/Button.tsx
@@ -263,6 +263,7 @@ export const Button = styled('button', {
padding: '4px',
height: '100%',
pt: '6px',
+ minWidth: '25px',
'&:hover': {
bg: '$grayBgHover',
diff --git a/packages/web/components/patterns/HighlightHoverActions.tsx b/packages/web/components/patterns/HighlightHoverActions.tsx
new file mode 100644
index 000000000..4d3c9ae5e
--- /dev/null
+++ b/packages/web/components/patterns/HighlightHoverActions.tsx
@@ -0,0 +1,113 @@
+import { useState } from 'react'
+import { Box, SpanBox } from '../elements/LayoutPrimitives'
+import { LibraryItemNode } from '../../lib/networking/queries/useGetLibraryItemsQuery'
+import { Button } from '../elements/Button'
+import { theme } from '../tokens/stitches.config'
+import {
+ ArchiveBox,
+ Book,
+ BookOpen,
+ Copy,
+ DotsThree,
+ Notebook,
+ Tag,
+ Trash,
+ Tray,
+} from 'phosphor-react'
+//import { CardMenu } from '../CardMenu'
+import { UserBasicData } from '../../lib/networking/queries/useGetViewerQuery'
+import { Highlight } from '../../lib/networking/fragments/highlightFragment'
+import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
+
+type HighlightHoverActionsProps = {
+ viewer: UserBasicData
+ highlight: Highlight
+
+ isHovered: boolean
+
+ viewInReader: (highlightId: string) => void
+
+ setLabelsTarget: (target: Highlight) => void
+ setShowConfirmDeleteHighlightId: (set: string) => void
+}
+
+export const HighlightHoverActions = (props: HighlightHoverActionsProps) => {
+ const [menuOpen, setMenuOpen] = useState(false)
+
+ return (
+
+
+
+
+
+
+ )
+}
diff --git a/packages/web/components/patterns/HighlightNotes.tsx b/packages/web/components/patterns/HighlightNotes.tsx
index 298437d16..c24df1193 100644
--- a/packages/web/components/patterns/HighlightNotes.tsx
+++ b/packages/web/components/patterns/HighlightNotes.tsx
@@ -145,6 +145,7 @@ export function MarkdownNote(props: MarkdownNote): JSX.Element {
{props.mode == 'edit' ? (
('preview')
+ const [isHovered, setIsHovered] = useState(false)
+ const [isOpen, setIsOpen] = useState(false)
+
+ const { refs, floatingStyles, context } = useFloating({
+ open: isOpen,
+ onOpenChange: setIsOpen,
+ middleware: [
+ offset({
+ mainAxis: -25,
+ }),
+ size(),
+ ],
+ placement: 'top-end',
+ whileElementsMounted: autoUpdate,
+ })
+
+ const hover = useHover(context)
+
+ const { getReferenceProps, getFloatingProps } = useInteractions([hover])
+
+ console.log(
+ 'ref={refs.setFloating, style={floatingStyles}',
+ refs.setFloating,
+ floatingStyles
+ )
return (
-
- {props.highlight.annotation ? (
-
- ) : (
-
- )}
-
-
-
-
-
- {/*
-
- */}
-
+
*': {
m: '0px',
+ display: 'inline',
+ padding: '2px',
+ backgroundColor:
+ 'rgba(var(--colors-highlightBackground), 0.35)',
+ boxShadow:
+ '1px 0 0 rgba(var(--colors-highlightBackground), 0.35), -1px 0 0 rgba(var(--colors-highlightBackground), 0.35)',
+ boxDecorationBreak: 'clone',
+ borderRadius: '2px',
},
fontSize: '15px',
lineHeight: 1.5,
diff --git a/packages/web/components/patterns/RcEditorStyles.tsx b/packages/web/components/patterns/RcEditorStyles.tsx
index 058cc6bbe..b53cba22a 100644
--- a/packages/web/components/patterns/RcEditorStyles.tsx
+++ b/packages/web/components/patterns/RcEditorStyles.tsx
@@ -8,7 +8,6 @@ export const RcEditorStyles = (isDark: boolean, shadow: boolean) => {
borderRadius: '5px',
backgroundColor: isDark ? '#2A2A2A' : 'white',
border: '1px solid $thBorderSubtle',
- boxShadow: shadow ? '0px 4px 4px rgba(33, 33, 33, 0.1)' : 'unset',
},
'.rc-md-navigation': {
borderRadius: '5px',
diff --git a/packages/web/components/templates/article/HighlightViewItem.tsx b/packages/web/components/templates/article/HighlightViewItem.tsx
index ac3cfab5c..df2440929 100644
--- a/packages/web/components/templates/article/HighlightViewItem.tsx
+++ b/packages/web/components/templates/article/HighlightViewItem.tsx
@@ -4,7 +4,6 @@ import { ReadableItem } from '../../../lib/networking/queries/useGetLibraryItems
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
import { HighlightView } from '../../patterns/HighlightView'
-import { HighlightsMenu } from '../homeFeed/HighlightItem'
type HighlightViewItemProps = {
viewer: UserBasicData
@@ -27,8 +26,8 @@ export function HighlightViewItem(props: HighlightViewItemProps): JSX.Element {
setHover(true)}
onMouseLeave={() => setHover(false)}
diff --git a/packages/web/components/templates/article/HighlightsLayer.tsx b/packages/web/components/templates/article/HighlightsLayer.tsx
index 8d147f362..2914a08c0 100644
--- a/packages/web/components/templates/article/HighlightsLayer.tsx
+++ b/packages/web/components/templates/article/HighlightsLayer.tsx
@@ -26,6 +26,10 @@ import { isTouchScreenDevice } from '../../../lib/deviceType'
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
import { ReadableItem } from '../../../lib/networking/queries/useGetLibraryItemsQuery'
import { SetHighlightLabelsModalPresenter } from './SetLabelsModalPresenter'
+import SlidingPane from 'react-sliding-pane'
+import 'react-sliding-pane/dist/react-sliding-pane.css'
+import { NotebookContent } from './Notebook'
+import { NotebookHeader } from './NotebookHeader'
type HighlightsLayerProps = {
viewer: UserBasicData
@@ -74,15 +78,13 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
const focusedHighlightMousePos = useRef({ pageX: 0, pageY: 0 })
const [currentHighlightIdx, setCurrentHighlightIdx] = useState(0)
- const [focusedHighlight, setFocusedHighlight] = useState<
- Highlight | undefined
- >(undefined)
+ const [focusedHighlight, setFocusedHighlight] =
+ useState(undefined)
const [selectionData, setSelectionData] = useSelection(highlightLocations)
- const [labelsTarget, setLabelsTarget] = useState(
- undefined
- )
+ const [labelsTarget, setLabelsTarget] =
+ useState(undefined)
const createHighlightFromSelection = useCallback(
async (
@@ -746,6 +748,50 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element {
if (props.showHighlightsModal) {
return (
+ {
+ props.setShowHighlightsModal(false)
+ }}
+ >
+ <>
+
+ {
+ // The timeout here is a bit of a hack to work around rerendering
+ setTimeout(() => {
+ const target = document.querySelector(
+ `[omnivore-highlight-id="${highlightId}"]`
+ )
+ target?.scrollIntoView({
+ block: 'center',
+ behavior: 'auto',
+ })
+ }, 1)
+ history.replaceState(
+ undefined,
+ window.location.href,
+ `#${highlightId}`
+ )
+
+ // props.setShowHighlightsModal(false)
+ }}
+ />
+ >
+
+ )
+
+ {
+ /* return (
- )
+ ) */
+ }
}
return <>>
diff --git a/packages/web/components/templates/article/Notebook.tsx b/packages/web/components/templates/article/Notebook.tsx
index 118b1d050..86cf96573 100644
--- a/packages/web/components/templates/article/Notebook.tsx
+++ b/packages/web/components/templates/article/Notebook.tsx
@@ -60,9 +60,8 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
const [noteText, setNoteText] = useState('')
const [showConfirmDeleteHighlightId, setShowConfirmDeleteHighlightId] =
useState(undefined)
- const [labelsTarget, setLabelsTarget] = useState(
- undefined
- )
+ const [labelsTarget, setLabelsTarget] =
+ useState(undefined)
const noteState = useRef({
isCreating: false,
note: undefined,
@@ -174,12 +173,9 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
return
}
if (noteState.current.isCreating) {
- console.log('note is being created, deferring')
-
if (noteState.current.createStarted) {
const timeSinceStart =
new Date().getTime() - noteState.current.createStarted.getTime()
- console.log(' -- timeSinceStart: ', timeSinceStart)
if (timeSinceStart > 4000) {
createNote(text)
@@ -208,8 +204,8 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
setNoteText('')
}, [noteState, highlights])
- const [articleNotesCollapsed, setArticleNotesCollapsed] = useState(false)
- const [highlightsCollapsed, setHighlightsCollapsed] = useState(false)
+ const [tabSelected, setTabSelected] = useState<'note' | 'highlights'>('note')
+
const [errorSaving, setErrorSaving] = useState(undefined)
const [lastChanged, setLastChanged] = useState(undefined)
const [lastSaved, setLastSaved] = useState(undefined)
@@ -221,120 +217,118 @@ export function NotebookContent(props: NotebookContentProps): JSX.Element {
height: '100%',
width: '100%',
p: '20px',
+
+ bg: '$thLibrarySearchbox',
'@mdDown': { p: '15px' },
}}
>
-
- {!articleNotesCollapsed && (
- <>
-
-
-
-
- {errorSaving && (
-
- {errorSaving}
-
- )}
- {lastSaved !== undefined ? (
- <>
- {lastChanged === lastSaved
- ? 'Saved'
- : `Last saved ${formattedShortTime(lastSaved.toISOString())}`}
- >
- ) : null}
-
- >
- )}
-
-
-
+ {/*
+ setTabSelected('note')}
+ />
setTabSelected('highlights')}
/>
+ */}
- {!highlightsCollapsed && (
- <>
- {sortedHighlights.map((highlight) => (
- {
- mutate()
- }}
- />
- ))}
- {sortedHighlights.length === 0 && (
-
- You have not added any highlights to this document.
-
- )}
- >
- )}
- {/*
+
+
+
+ */}
-
+ alignment="start"
+ distribution="start"
+ >
+ {errorSaving && (
+
+ {errorSaving}
+
+ )}
+ {lastSaved !== undefined ? (
+ <>
+ {lastChanged === lastSaved
+ ? 'Saved'
+ : `Last saved ${formattedShortTime(lastSaved.toISOString())}`}
+ >
+ ) : null}
+
+ >
+ {/* )} */}
+
+ {/* {tabSelected == 'highlights' && ( */}
+
+ {sortedHighlights.map((highlight) => (
+ {
+ mutate()
+ }}
+ />
+ ))}
+ {sortedHighlights.length === 0 && (
+
+ You have not added any highlights to this document.
+
+ )}
+
+ {/* )} */}
{showConfirmDeleteHighlightId && (
void
+ selected: boolean
+ setSelected: (set: boolean) => void
}
function SectionTitle(props: SectionTitleProps): JSX.Element {
@@ -408,30 +402,25 @@ function SectionTitle(props: SectionTitleProps): JSX.Element {
display: 'flex',
alignItems: 'center',
gap: '5px',
+ color: props.selected ? '$thTextContrast' : '$thTextSubtle',
+ borderBottom: props.selected
+ ? '1px solid $thTextContrast'
+ : '1px solid transparent',
}}
onClick={(event) => {
- props.setCollapsed(!props.collapsed)
+ props.setSelected(true)
event.stopPropagation()
}}
>
- {props.collapsed ? (
-
- ) : (
-
- )}
diff --git a/packages/web/components/templates/article/NotebookHeader.tsx b/packages/web/components/templates/article/NotebookHeader.tsx
index 0b19bbf3d..187664f5a 100644
--- a/packages/web/components/templates/article/NotebookHeader.tsx
+++ b/packages/web/components/templates/article/NotebookHeader.tsx
@@ -31,7 +31,9 @@ export const NotebookHeader = (props: NotebookHeaderProps) => {
top: '0px',
height: '50px',
p: '20px',
- background: '#F8FAFB',
+ borderTopLeftRadius: '10px',
+ overflow: 'clip',
+ background: '$thLibrarySearchbox',
zIndex: 10,
}}
>
@@ -49,18 +51,18 @@ export const NotebookHeader = (props: NotebookHeaderProps) => {
alignment="center"
>
}>
- {/* {
- exportHighlights()
+ // exportHighlights()
}}
title="Export Notebook"
/>
{
- setShowConfirmDeleteNote(true)
+ // setShowConfirmDeleteNote(true)
}}
title="Delete Article Note"
- /> */}
+ />
diff --git a/packages/web/components/templates/article/SetLabelsModal.tsx b/packages/web/components/templates/article/SetLabelsModal.tsx
index 9b484e015..06f021591 100644
--- a/packages/web/components/templates/article/SetLabelsModal.tsx
+++ b/packages/web/components/templates/article/SetLabelsModal.tsx
@@ -14,6 +14,7 @@ import { useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQ
import { v4 as uuidv4 } from 'uuid'
import { randomLabelColorHex } from '../../../utils/settings-page/labels/labelColorObjects'
import { LabelsDispatcher } from '../../../lib/hooks/useSetPageLabels'
+import * as Dialog from '@radix-ui/react-dialog'
type SetLabelsModalProps = {
provider: LabelsProvider
@@ -30,9 +31,8 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
const availableLabels = useGetLabelsQuery()
const [tabCount, setTabCount] = useState(-1)
const [tabStartValue, setTabStartValue] = useState('')
- const [errorMessage, setErrorMessage] = useState(
- undefined
- )
+ const [errorMessage, setErrorMessage] =
+ useState(undefined)
const errorTimeoutRef = useRef()
const [highlightLastLabel, setHighlightLastLabel] = useState(false)
@@ -171,44 +171,46 @@ export function SetLabelsModal(props: SetLabelsModalProps): JSX.Element {
return (
-
- {
- event.preventDefault()
- props.onOpenChange(false)
- }}
- onEscapeKeyDown={(event) => {
- props.onOpenChange(false)
- event.preventDefault()
- }}
- >
-
-
-
-
-
-
-
+
+
+ {
+ event.preventDefault()
+ props.onOpenChange(false)
+ }}
+ onEscapeKeyDown={(event) => {
+ props.onOpenChange(false)
+ event.preventDefault()
+ }}
+ >
+
+
+
+
+
+
+
+
)
}
diff --git a/packages/web/package.json b/packages/web/package.json
index bbce82d83..92050b88b 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -62,6 +62,7 @@
"react-markdown-editor-lite": "^1.3.4",
"react-masonry-css": "^1.0.16",
"react-pro-sidebar": "^0.7.1",
+ "react-sliding-pane": "^7.3.0",
"react-spinners": "^0.13.7",
"react-super-responsive-table": "^5.2.1",
"react-topbar-progress-indicator": "^4.1.1",
diff --git a/packages/web/styles/globals.css b/packages/web/styles/globals.css
index 569bddf90..df1934426 100644
--- a/packages/web/styles/globals.css
+++ b/packages/web/styles/globals.css
@@ -419,20 +419,22 @@ button {
margin: 0px;
}
-.omnivore-masonry-grid {
- display: -webkit-box; /* Not needed if autoprefixing */
- display: -ms-flexbox; /* Not needed if autoprefixing */
- display: flex;
- margin-left: -16px; /* gutter size offset */
- margin-right: 14px;
- width: auto;
+.slide-panel-overlay {
+ z-index: 100 !important;
+ background: transparent !important;
+ pointer-events: none;
}
-.omnivore-masonry-grid_column {
- padding-left: 16px; /* gutter size */
- background-clip: padding-box;
+
+.slide-pane__content {
+ padding: 0px !important;
+ pointer-events: all;
+ border-top-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ border-left: 1px solid var(--colors-thNotebookSubtle);
+ background: var(--colors-thLibrarySearchbox);
}
-/* .omnivore-masonry-grid_column > div {
- background: grey;
- margin-bottom: 16px;
-} */
+.slide-pane {
+ background: transparent !important;
+ box-shadow: 0px 4px 4px rgba(33, 33, 33, 0.1) !important;
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 36db67d18..eb21f53dd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -14467,6 +14467,11 @@ executable@^4.1.1:
dependencies:
pify "^2.2.0"
+exenv@^1.2.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
+ integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==
+
exit@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -23841,6 +23846,11 @@ react-is@^18.0.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
+react-lifecycles-compat@^3.0.0:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
+ integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
+
react-markdown-editor-lite@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/react-markdown-editor-lite/-/react-markdown-editor-lite-1.3.4.tgz#77992d2389b9427a06595c63d95f52be66e5fea9"
@@ -23877,6 +23887,16 @@ react-masonry-css@^1.0.16:
resolved "https://registry.yarnpkg.com/react-masonry-css/-/react-masonry-css-1.0.16.tgz#72b28b4ae3484e250534700860597553a10f1a2c"
integrity sha512-KSW0hR2VQmltt/qAa3eXOctQDyOu7+ZBevtKgpNDSzT7k5LA/0XntNa9z9HKCdz3QlxmJHglTZ18e4sX4V8zZQ==
+react-modal@^3.14.3:
+ version "3.16.1"
+ resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.1.tgz#34018528fc206561b1a5467fc3beeaddafb39b2b"
+ integrity sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==
+ dependencies:
+ exenv "^1.2.0"
+ prop-types "^15.7.2"
+ react-lifecycles-compat "^3.0.0"
+ warning "^4.0.3"
+
react-popper-tooltip@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-3.1.1.tgz#329569eb7b287008f04fcbddb6370452ad3f9eac"
@@ -23960,6 +23980,14 @@ react-slidedown@^2.4.5:
dependencies:
tslib "^2.0.0"
+react-sliding-pane@^7.3.0:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/react-sliding-pane/-/react-sliding-pane-7.3.0.tgz#a6a03b90db216e7ec6f746c7e649d19ba03ff4e0"
+ integrity sha512-KCyxw2BBvXjwYm1UX83Vk67D4kxec2icJxrSPidNus8voh1yB1K6bluwShAe3OvN5zk8H9InL22jGomTUOOudw==
+ dependencies:
+ prop-types "^15.7.2"
+ react-modal "^3.14.3"
+
react-spinners@^0.13.7:
version "0.13.7"
resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.13.7.tgz#0f423c415bfa56765ce9fb36ff604e52a92b37a9"
@@ -27779,7 +27807,7 @@ walker@~1.0.5:
dependencies:
makeerror "1.0.12"
-warning@^4.0.2:
+warning@^4.0.2, warning@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==