Skip to content

Commit

Permalink
Work on reading progress editor
Browse files Browse the repository at this point in the history
  • Loading branch information
jacksonh committed Oct 11, 2023
1 parent 042606e commit 1673c2d
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 11 deletions.
1 change: 1 addition & 0 deletions packages/api/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,7 @@ export enum SaveArticleReadingProgressErrorCode {
}

export type SaveArticleReadingProgressInput = {
force?: InputMaybe<Scalars['Boolean']>;
id: Scalars['ID'];
readingProgressAnchorIndex?: InputMaybe<Scalars['Int']>;
readingProgressPercent: Scalars['Float'];
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/generated/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,7 @@ enum SaveArticleReadingProgressErrorCode {
}

input SaveArticleReadingProgressInput {
force: Boolean
id: ID!
readingProgressAnchorIndex: Int
readingProgressPercent: Float!
Expand Down
5 changes: 4 additions & 1 deletion packages/api/src/resolvers/article/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ export const saveArticleReadingProgressResolver = authorized<
readingProgressPercent,
readingProgressAnchorIndex,
readingProgressTopPercent,
force,
},
},
{ uid, pubsub }
Expand All @@ -592,7 +593,9 @@ export const saveArticleReadingProgressResolver = authorized<
}
// If we have a top percent, we only save it if it's greater than the current top percent
// or set to zero if the top percent is zero.
const readingProgressTopPercentToSave = readingProgressTopPercent
const readingProgressTopPercentToSave = force
? readingProgressTopPercent
: readingProgressTopPercent
? Math.max(
readingProgressTopPercent,
libraryItem.readingProgressTopPercent || 0
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ const schema = gql`
readingProgressTopPercent: Float
readingProgressPercent: Float!
readingProgressAnchorIndex: Int
force: Boolean
}
enum SaveArticleReadingProgressErrorCode {
NOT_FOUND
Expand Down
1 change: 1 addition & 0 deletions packages/web/components/templates/Inspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type InspectorProps = {
viewer: UserBasicData
item: ReadableItem
outline: OutlineItem | undefined
containerRef: React.RefObject<HTMLDivElement | null>

currentView: InspectorView
setCurrentView: (view: InspectorView) => void
Expand Down
10 changes: 4 additions & 6 deletions packages/web/components/templates/article/Article.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Box, SpanBox } from '../../elements/LayoutPrimitives'
import {
clampToPercent,
getTopOmnivoreAnchorElement,
parseDomTree,
} from '../../../lib/anchorElements'
Expand Down Expand Up @@ -40,10 +41,6 @@ export function Article(props: ArticleProps): JSX.Element {

const articleContentRef = useRef<HTMLDivElement | null>(null)

const clampToPercent = (float: number) => {
return Math.floor(Math.max(0, Math.min(100, float)))
}

const [lightboxOpen, setLightboxOpen] = useState(false)
const [imageSrcs, setImageSrcs] = useState<SlideImage[]>([])
const [lightboxIndex, setlightBoxIndex] = useState(0)
Expand All @@ -52,10 +49,10 @@ export function Article(props: ArticleProps): JSX.Element {
;(async () => {
if (!readingProgress) return
if (!articleContentRef.current) return
if (!window.document.scrollingElement) return
if (!props.containerRef?.current) return
const anchor = getTopOmnivoreAnchorElement(articleContentRef.current)
const topPositionPercent =
window.scrollY / window.document.scrollingElement.scrollHeight
window.scrollY / props.containerRef?.current.scrollHeight
const anchorIndex = Number(anchor)

await props.articleMutations.articleReadingProgressMutation({
Expand Down Expand Up @@ -284,6 +281,7 @@ export function Article(props: ArticleProps): JSX.Element {
href={`/static/highlightjs/${highlightTheme}.min.css`}
/>
<Box
id="article-content"
ref={articleContentRef}
css={{
maxWidth: '100%',
Expand Down
84 changes: 80 additions & 4 deletions packages/web/components/templates/inspectors/EditItemInfoView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@ import { FormInput } from '../../elements/FormElements'
import { HStack, VStack } from '../../elements/LayoutPrimitives'
import { StyledText } from '../../elements/StyledText'
import { styled } from '@stitches/react'
import { ChangeEvent, useState } from 'react'
import { articleReadingProgressMutation } from '../../../lib/networking/mutations/articleReadingProgressMutation'
import {
clampToPercent,
getTopOmnivoreAnchorElement,
} from '../../../lib/anchorElements'

type EditInfoProps = {
item: ReadableItem
containerRef: React.RefObject<HTMLDivElement | null>
}

export const EditItemInfoView = (props: EditInfoProps): JSX.Element => {
const [readingProgress, setReadingProgress] = useState(
props.item.readingProgressPercent
)

return (
<VStack
css={{
Expand Down Expand Up @@ -41,8 +52,67 @@ export const EditItemInfoView = (props: EditInfoProps): JSX.Element => {
<NumberSelectRow
title="Reading Progress"
type="number"
value={props.item.readingProgressPercent.toString()}
value={readingProgress}
max={100}
onChange={(event) => {
console.log('event: ', event)
if (
!('value' in event.target) ||
!props.containerRef.current?.scrollHeight ||
Number.isNaN(Number(event.target.value))
) {
return
}
const numberValue = Number(event.target.value)
setReadingProgress(numberValue)

const value = numberValue / 100.0
props.item.readingProgressPercent = value

const position = props.containerRef.current?.scrollHeight * value
console.log('position: ', position)

console.log(
'scrollHeight: ',
props.containerRef.current?.scrollHeight
)

console.log(
'scrolling container: ',
props.containerRef,
'tp',
position
)
props.containerRef?.current.scrollTo({
top: position,
behavior: 'instant',
})
;(async () => {
const articleContent = document.querySelector('#article-content')
if (!articleContent || !props.containerRef?.current) {
return
}
const anchor = getTopOmnivoreAnchorElement(
articleContent as HTMLElement
)
const topPositionPercent =
props.containerRef?.current.scrollTop /
props.containerRef?.current.scrollHeight
const anchorIndex = Number(anchor)

await articleReadingProgressMutation({
id: props.item.id,
readingProgressPercent: clampToPercent(readingProgress),
readingProgressTopPercent: clampToPercent(
topPositionPercent * 100
),
readingProgressAnchorIndex:
anchorIndex == Number.NaN ? undefined : anchorIndex,
})
})()

event.preventDefault()
}}
/>
</VStack>

Expand Down Expand Up @@ -225,8 +295,9 @@ const FullRowText = (props: FullRowTextProps): JSX.Element => {
type NumberSelectRowProps = {
title: string
type: string
value: string | undefined
value: number
max: number
onChange: (event: ChangeEvent) => void
}

const StyledSelect = styled('select', {
Expand All @@ -242,6 +313,11 @@ const StyledSelect = styled('select', {
width: '98px',
height: '35px',
border: 'unset',

backgroundImage: `linear-gradient(45deg, transparent 50%, gray 50%),linear-gradient: '(135deg, gray 50%, transparent 50%),linear-gradient: '(to right, #ccc, #ccc)`,
backgroundPosition: `calc(100% - 20px) calc(1em + 2px),calc(100% - 15px) calc(1em + 2px),calc(100% - 2.5em) 0.5em;`,
backgroundSize: `5px 5px,5px 5px,1px 1.5em`,
backgroundRepeat: 'no-repeat',
})

const NumberSelectRow = (props: NumberSelectRowProps): JSX.Element => {
Expand Down Expand Up @@ -270,11 +346,11 @@ const NumberSelectRow = (props: NumberSelectRowProps): JSX.Element => {
>
{props.title}
</StyledText>
<StyledSelect value={props.value}>
<StyledSelect value={props.value} onChange={props.onChange}>
{values.map((value) => {
return (
<option key={`option-${value}`} value={value}>
{value}
{value}%
</option>
)
})}
Expand Down
4 changes: 4 additions & 0 deletions packages/web/lib/anchorElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ const ANCHOR_ELEMENTS_BLOCKED_ATTRIBUTES = [
'data-instagram-id',
]

export const clampToPercent = (float: number) => {
return Math.floor(Math.max(0, Math.min(100, float)))
}

// We search in reverse so we can find the last element
// that is visible on the page
export const getTopOmnivoreAnchorElement = (
Expand Down
1 change: 1 addition & 0 deletions packages/web/pages/[username]/[slug]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ export default function Reader(): JSX.Element {
viewer={viewerData.me}
item={article}
outline={outline}
containerRef={containerRef}
closeInspector={inspector.closeInspector}
currentView={inspector.currentInspectorView}
setCurrentView={inspector.setCurrentInspectorView}
Expand Down

0 comments on commit 1673c2d

Please sign in to comment.