Skip to content

Commit

Permalink
improve styles and rm local entry store
Browse files Browse the repository at this point in the history
  • Loading branch information
zaknesler committed May 23, 2024
1 parent b197a10 commit 1ea839d
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 45 deletions.
28 changes: 22 additions & 6 deletions ui/src/components/entry/entry-item.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { A, AnchorProps } from '@solidjs/router';
import { A, AnchorProps, useMatch } from '@solidjs/router';
import { createQuery } from '@tanstack/solid-query';
import { cx } from 'class-variance-authority';
import { splitProps, type Component } from 'solid-js';
Expand Down Expand Up @@ -34,31 +34,47 @@ export const EntryItem: Component<EntryItemProps> = props => {

const getDate = () => local.entry.published_at || local.entry.updated_at;

const entryRouteMatch = useMatch(() => filter.getEntryUrl(local.entry.uuid, false));
const isActive = () => Boolean(entryRouteMatch());

return (
<A
{...{ [DATA_ATTRIBUTES.ENTRY_ITEM_UUID]: local.entry.uuid }}
href={filter.getEntryUrl(local.entry.uuid)}
activeClass="bg-gray-100 dark:bg-gray-950"
activeClass="bg-gray-600 dark:bg-gray-950 text-white"
inactiveClass={cx(
'hover:bg-gray-100 dark:hover:bg-gray-950',
'focus:bg-gray-100 focus:dark:bg-gray-950',
filter.getView() === 'unread' && isRead() && 'opacity-50',
)}
class={cx(
'-mx-2 flex flex-col gap-1 rounded-lg px-2 py-1.5 ring-gray-300 transition dark:ring-gray-700',
'focus:bg-gray-100 focus:outline-none focus:ring focus:dark:bg-gray-950',
'focus:outline-none focus:ring',
local.class,
)}
{...rest}
>
<h4 class="text-pretty text-base/5 md:text-sm xl:text-base/5">{local.entry.title}</h4>

<small class="flex w-full gap-1 overflow-hidden text-xs text-gray-500 dark:text-gray-400">
{!isRead() && <span class="h-2 w-2 shrink-0 self-center rounded-full bg-gray-500 dark:bg-gray-300" />}
<small
class={cx(
'flex w-full gap-1 overflow-hidden text-xs transition',
isActive() ? 'text-gray-300' : 'text-gray-500 dark:text-gray-400',
)}
>
{!isRead() && (
<span
class={cx(
'h-2 w-2 shrink-0 self-center rounded-full transition',
isActive() ? 'bg-gray-400' : 'bg-gray-500 dark:bg-gray-300',
)}
/>
)}

{!filter.params.feed_uuid && (
<>
<span class="truncate break-all font-medium">{feed()?.title}</span>
{!!getDate() && <span class="text-gray-400 dark:text-gray-600">&ndash;</span>}
{!!getDate() && <span class="opacity-50">&ndash;</span>}
</>
)}

Expand Down
8 changes: 4 additions & 4 deletions ui/src/components/entry/entry-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const EntryList: Component<EntryListProps> = props => {
const entries = useInfiniteEntries();

// Handle arrow navigation
useListNav(() => ({ enabled: !!props.containsActiveElement, entries: entries.localEntries() }));
useListNav(() => ({ enabled: !!props.containsActiveElement, entries: entries.getAllEntries() }));

createEffect(() => {
if (!listBounds.bottom || !props.containerBounds?.bottom) return;
Expand All @@ -46,9 +46,9 @@ export const EntryList: Component<EntryListProps> = props => {
</Match>

<Match when={entries.query.isSuccess && feeds.data}>
{entries.localEntries().length ? (
<div class="-mt-2 flex flex-col gap-1 px-4 pb-2">
<For each={entries.localEntries()}>
{entries.getAllEntries().length ? (
<div class="-mt-2 flex flex-col gap-2 px-4 pb-2">
<For each={entries.getAllEntries()}>
{(entry, index) => (
<EntryItem
tabIndex={index() === 0 ? 0 : -1} // Disable tabindex so we can override it with arrow keys
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/feed/feed-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const BaseFeedItem: Component<BaseFeedItemProps> = props => (
<span class="flex-1 overflow-x-hidden truncate">{props.title}</span>

<Show when={props.unread_count}>
<span class="-mx-1 -my-0.5 w-6 shrink-0 rounded bg-white py-0.5 text-center text-xs/4 text-gray-500 dark:bg-gray-800 dark:text-gray-300">
<span class="mr-1 w-6 shrink-0 rounded bg-white py-0.5 text-center text-xs/4 text-gray-500 md:-mx-1 md:-my-0.5 dark:bg-gray-800 dark:text-gray-300">
{props.unread_count}
</span>
</Show>
Expand Down
31 changes: 0 additions & 31 deletions ui/src/hooks/queries/use-infinite-entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { QUERY_KEYS } from '~/constants/query';
import { type Entry } from '~/types/bindings';
import { useFilterParams } from '../use-filter-params';
import { debounce, leading } from '@solid-primitives/scheduled';
import { createEffect, createSignal } from 'solid-js';
import { getEntryComparator } from '~/utils/entries';

export const useInfiniteEntries = () => {
const filter = useFilterParams();
Expand All @@ -28,34 +26,6 @@ export const useInfiniteEntries = () => {

const getAllEntries = () => query.data?.pages.flatMap(page => page.data) || [];

// Maintain local state of entries to prevent entries just marked as read from being removed
const [localEntries, setLocalEntries] = createSignal(getAllEntries());

// Associate the local entries with the feed we're viewing, so we know when to reset the data
const [localFeedKey, setLocalFeedKey] = createSignal(filter.getFeedUrl());

createEffect(() => {
const currentIds = localEntries().map(entry => entry.id);
const newEntries = getAllEntries().filter(entry => !currentIds.includes(entry.id));

// Don't bother updating local state if we've got nothing to add
if (!newEntries.length) return;

// Add new entries and sort to maintain order
setLocalEntries([...localEntries(), ...newEntries].sort(getEntryComparator(filter.getSort())));
});

createEffect(() => {
const feedKey = filter.getFeedUrl();

// Only reset the local cache if we look at a new feed
if (localFeedKey() === feedKey) return;

// Reset the local cache
setLocalFeedKey(feedKey);
setLocalEntries(getAllEntries());
});

const fetchMore = leading(
debounce,
() => {
Expand All @@ -69,7 +39,6 @@ export const useInfiniteEntries = () => {

return {
query,
localEntries,
getAllEntries,
fetchMore,
};
Expand Down
7 changes: 4 additions & 3 deletions ui/src/hooks/use-filter-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ export const useFilterParams = () => {
return `?${builder.toString()}`;
};

const getFeedUrl = (append?: string) => {
const getFeedUrl = (append?: string, withQuery = true) => {
const path = params.feed_uuid ? `/feeds/${params.feed_uuid}` : `/`;
const withAppended = append ? path.concat(append) : path;
return withAppended.replace(/\/\//g, '/').concat(getQueryString());
const trimmed = withAppended.replace(/\/\//g, '/');
return withQuery ? trimmed.concat(getQueryString()) : trimmed;
};

const getEntryUrl = (entry_uuid: string) => getFeedUrl(`/entries/${entry_uuid}`);
const getEntryUrl = (entry_uuid: string, withQuery = true) => getFeedUrl(`/entries/${entry_uuid}`, withQuery);

return {
params,
Expand Down

0 comments on commit 1ea839d

Please sign in to comment.