Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
DIYgod committed Jul 15, 2024
2 parents 66521c0 + c8dbd59 commit 1a7aa33
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 26 deletions.
1 change: 1 addition & 0 deletions icons/mgc/eye_2_cute_re.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/renderer/src/initialize/hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export const setHydrated = (v: boolean) => {
_isHydrated = v
}

/**
* @description Check if database data is hydrated to store, or current database is ready.
* If users disabled data persist, it's always false, that means you can't do operation with database.
*
*/
export const isHydrated = () => _isHydrated

export const hydrateDatabaseToStore = async () => {
Expand Down
10 changes: 10 additions & 0 deletions src/renderer/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,13 @@ export const pluralize = (
}
return postfix(noun, rule)
}

export const omitObjectUndefinedValue = (obj: Record<string, any>) => {
const newObj = {}
for (const key in obj) {
if (obj[key] !== undefined) {
newObj[key] = obj[key]
}
}
return newObj
}
49 changes: 26 additions & 23 deletions src/renderer/src/modules/entry-column/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,26 @@ export const useEntriesByView = () => {
view,
...(unreadOnly === true && { read: false }),
})
const entries = useEntryIdsByFeedIdOrView(isAllFeeds ? view : feedId!, {
unread: unreadOnly,
view,
})
const remoteEntryIds = query.data?.pages
?.map((page) => page.data?.map((entry) => entry.entries.id))
.flat() as string[]

const currentEntries = useEntryIdsByFeedIdOrView(
isAllFeeds ? view : feedId!,
{
unread: unreadOnly,
view,
},
)

// If remote data is not available, we use the local data, get the local data length
// FIXME: remote first, then local store data
// NOTE: We still can't use the store's data handling directly.
// Imagine that the local data may be persistent, and then if there are incremental updates to the data on the server side,
// then we have no way to incrementally update the data.
// We need to add an interface to incrementally update the data based on the version hash.

const entries = remoteEntryIds || currentEntries

useHotkeys(
shortcuts.entries.refetch.key,
Expand All @@ -93,7 +109,7 @@ export const useEntriesByView = () => {
useEffect(() => {
prevEntries.current = []
}, [routeParams.feedId, routeParams.view])
const localEntries = useMemo(() => {
const mergedEntries = useMemo(() => {
if (!unreadOnly) {
prevEntries.current = []
return entries
Expand All @@ -102,35 +118,22 @@ export const useEntriesByView = () => {
prevEntries.current = entries
return entries
}
if (entries.length > prevEntries.current.length) {
prevEntries.current = entries
return entries
}
// merge the new entries with the old entries, and unique them
const nextIds = [...new Set([...prevEntries.current, ...entries])]
prevEntries.current = nextIds
return nextIds
}, [entries, prevEntries, unreadOnly])

const sortLocalEntries = () =>
const sortEntries = () =>
isCollection ?
sortEntriesIdByStarAt(localEntries) :
sortEntriesIdByEntryPublishedAt(localEntries)
const remoteEntryIds = query.data?.pages
?.map((page) => page.data?.map((entry) => entry.entries.id))
.flat() as string[]
sortEntriesIdByStarAt(mergedEntries) :
sortEntriesIdByEntryPublishedAt(mergedEntries)

return {
...query,

// If remote data is not available, we use the local data, get the local data length
// FIXME: remote first, then local store data
// NOTE: We still can't use the store's data handling directly.
// Imagine that the local data may be persistent, and then if there are incremental updates to the data on the server side,
// then we have no way to incrementally update the data.
// We need to add an interface to incrementally update the data based on the version hash.
entriesIds: remoteEntryIds ?? sortLocalEntries(),
totalCount: query.data?.pages?.[0]?.total ?? localEntries.length,
entriesIds: sortEntries(),
totalCount: query.data?.pages?.[0]?.total ?? mergedEntries.length,
}
}

Expand Down
66 changes: 66 additions & 0 deletions src/renderer/src/modules/entry-content/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { useUISettingKey } from "@renderer/atoms/settings/ui"
import { useUser } from "@renderer/atoms/user"
import { m } from "@renderer/components/common/Motion"
import { Logo } from "@renderer/components/icons/logo"
import { AutoResizeHeight } from "@renderer/components/ui/auto-resize-height"
import { Avatar, AvatarFallback, AvatarImage } from "@renderer/components/ui/avatar"
import { Tooltip, TooltipContent, TooltipTrigger } from "@renderer/components/ui/tooltip"
import { useAuthQuery, useTitle } from "@renderer/hooks/common"
import { stopPropagation } from "@renderer/lib/dom"
import { parseHtml } from "@renderer/lib/parse-html"
Expand Down Expand Up @@ -42,6 +45,8 @@ export const EntryContent = ({ entryId }: { entryId: ActiveEntryId }) => {
}

function EntryContentRender({ entryId }: { entryId: string }) {
const user = useUser()

const { error, data } = useAuthQuery(Queries.entries.byId(entryId), {
staleTime: 300_000,
meta: {
Expand Down Expand Up @@ -143,6 +148,67 @@ function EntryContentRender({ entryId }: { entryId: string }) {
{entry.entries.publishedAt &&
new Date(entry.entries.publishedAt).toLocaleString()}
</div>
<div className="mt-2 flex items-center gap-2 text-[13px] text-zinc-500">
<div className="flex items-center gap-1 font-medium">
<i className="i-mgc-eye-2-cute-re" />
<span>
{(
(data?.entries.entryReadHistories.readCount ?? 0) +
(data?.entries.entryReadHistories.users.every((u) => u.id !== user?.id) ? 1 : 0) // if no me, +1
).toLocaleString()}
</span>
</div>
<div className="flex items-center">
{[
{
id: user?.id,
name: user?.name ?? null,
image: user?.image ?? null,
handle: user?.handle ?? null,
},
] // myself first
.concat(
data?.entries.entryReadHistories.users.filter(
(u) => u.id !== user?.id,
) ?? [],
) // then others
.slice(0, 10) // only show 10
.concat(
data?.entries.entryReadHistories.readCount &&
data.entries.entryReadHistories.readCount > 10 ?
[
{
id: "more",
name: `+${
data?.entries.entryReadHistories.readCount - 10
}`,
image: null,
handle: null,
},
] :
[],
) // show more count
.map((user, i) => (
<Tooltip key={user.id}>
<TooltipTrigger>
<div
style={{
transform: `translateX(-${i * 5}px)`,
}}
>
<Avatar className="aspect-square size-6 border border-black dark:border-white">
<AvatarImage src={user?.image || undefined} />
<AvatarFallback>
{user.name?.slice(0, 2)}
</AvatarFallback>
</Avatar>
</div>
</TooltipTrigger>
<TooltipContent side="top">{user.name}</TooltipContent>
</Tooltip>
))}
</div>
</div>
</a>
<WrappedElementProvider boundingDetection>
<TitleMetaHandler entryId={entry.entries.id} />
Expand Down
16 changes: 13 additions & 3 deletions src/renderer/src/store/entry/store.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { apiClient } from "@renderer/lib/api-fetch"
import { getEntriesParams } from "@renderer/lib/utils"
import {
getEntriesParams,
omitObjectUndefinedValue,
} from "@renderer/lib/utils"
import type {
CombinedEntryModel,
EntryModel,
FeedModel,
} from "@renderer/models"
import { EntryService } from "@renderer/services"
import { produce } from "immer"
import { merge, omit } from "lodash-es"
import { isNil, merge, omit } from "lodash-es"

import { isHydrated } from "../../initialize/hydrate"
import { feedActions } from "../feed"
Expand Down Expand Up @@ -98,7 +101,8 @@ class EntryActions {
produce(state, (draft) => {
const entry = draft.flatMapEntries[entryId]
if (!entry) return
Object.assign(entry, changed)
Object.assign(entry, omitObjectUndefinedValue(changed))

return draft
}),
)
Expand Down Expand Up @@ -204,6 +208,12 @@ class EntryActions {
this.patch(entryId, {
read,
})
if (!isHydrated()) return
if (!isNil(read)) {
EntryService.bulkStoreReadStatus({
[entryId]: read,
})
}
}

markReadByFeedId(feedId: string) {
Expand Down

0 comments on commit 1a7aa33

Please sign in to comment.