minor-ref

This commit is contained in:
Untone 2024-08-30 16:45:17 +03:00
parent cd436dd34d
commit 7c614c66d9
19 changed files with 84 additions and 86 deletions

View File

@ -6,8 +6,8 @@ import { useLocalize } from '~/context/localize'
import { useReactions } from '~/context/reactions'
import { useSession } from '~/context/session'
import { Author, Reaction, ReactionKind, ReactionSort } from '~/graphql/schema/core.gen'
import { byCreated, byStat } from '~/lib/sort'
import { SortFunction } from '~/types/common'
import { byCreated, byStat } from '~/utils/sort'
import { Button } from '../_shared/Button'
import { ShowIfAuthenticated } from '../_shared/ShowIfAuthenticated'
import styles from './Article.module.scss'

View File

@ -5,8 +5,8 @@ import { Icon } from '~/components/_shared/Icon'
import { useFeed } from '~/context/feed'
import { useLocalize } from '~/context/localize'
import type { Shout } from '~/graphql/schema/core.gen'
import { byScore } from '~/lib/sort'
import { restoreScrollPosition, saveScrollPosition } from '~/utils/scroll'
import { byScore } from '~/utils/sort'
import { FEED_PAGE_SIZE } from '../Views/Feed/Feed'
import styles from './SearchModal.module.scss'
import { SearchResultItem } from './SearchResultItem'
@ -23,7 +23,7 @@ const getSearchCoincidences = ({ str, intersection }: { str: string; intersectio
)}</span>`
const prepareSearchResults = (list: Shout[], searchValue: string) =>
list.sort(byScore() as (a: Shout, b: Shout) => number).map((article, index) => ({
list.sort(byScore as (a: Shout, b: Shout) => number).map((article, index) => ({
...article,
id: index,
title: article.title

View File

@ -5,7 +5,7 @@ import { Icon } from '~/components/_shared/Icon'
import { useLocalize } from '~/context/localize'
import { useTopics } from '~/context/topics'
import type { Topic } from '~/graphql/schema/core.gen'
import { getRandomTopicsFromArray } from '~/lib/getRandomTopicsFromArray'
import { getRandomItemsFromArray } from '~/utils/random'
import styles from './TopicsNav.module.scss'
export const RandomTopics = () => {
@ -17,11 +17,11 @@ export const RandomTopics = () => {
createEffect(
on(sortedTopics, (ttt: Topic[]) => {
if (ttt?.length) {
setRandomTopics(getRandomTopicsFromArray(ttt))
setRandomTopics(getRandomItemsFromArray(ttt))
}
})
)
onMount(() => sortedTopics() && getRandomTopicsFromArray(sortedTopics()))
onMount(() => sortedTopics() && getRandomItemsFromArray(sortedTopics()))
return (
<ul class="nodash">
<Show when={randomTopics().length > 0}>

View File

@ -9,8 +9,8 @@ import { SearchField } from '~/components/_shared/SearchField'
import { useAuthors } from '~/context/authors'
import { useLocalize } from '~/context/localize'
import type { Author } from '~/graphql/schema/core.gen'
import { dummyFilter } from '~/intl/dummyFilter'
import { authorLetterReduce, translateAuthor } from '~/intl/translate'
import { dummyFilter } from '~/lib/dummyFilter'
// import { byFirstChar, byStat } from '~/lib/sort'
import { scrollHandler } from '~/utils/scroll'
import styles from './AllAuthors.module.scss'

View File

@ -6,7 +6,7 @@ import { SearchField } from '~/components/_shared/SearchField'
import { useLocalize } from '~/context/localize'
import { useTopics } from '~/context/topics'
import type { Topic } from '~/graphql/schema/core.gen'
import { dummyFilter } from '~/lib/dummyFilter'
import { dummyFilter } from '~/intl/dummyFilter'
import { scrollHandler } from '~/utils/scroll'
import { TopicBadge } from '../../Topic/TopicBadge'
import styles from './AllTopics.module.scss'

View File

@ -11,7 +11,7 @@ import { graphqlClientCreate } from '~/graphql/client'
import getAuthorFollowersQuery from '~/graphql/query/core/author-followers'
import getAuthorFollowsQuery from '~/graphql/query/core/author-follows'
import type { Author, Reaction, Shout, Topic } from '~/graphql/schema/core.gen'
import { byCreated } from '~/lib/sort'
import { byCreated } from '~/utils/sort'
import stylesArticle from '../../Article/Article.module.scss'
import { Comment } from '../../Article/Comment'
import { AuthorCard } from '../../Author/AuthorCard'

View File

@ -17,8 +17,8 @@ import { useUI } from '~/context/ui'
import { loadUnratedShouts } from '~/graphql/api/private'
import { graphqlClientCreate } from '~/graphql/client'
import type { Author, Reaction, Shout } from '~/graphql/schema/core.gen'
import { byCreated } from '~/lib/sort'
import { FeedSearchParams } from '~/routes/feed/[...order]'
import { byCreated } from '~/utils/sort'
import { CommentDate } from '../../Article/CommentDate'
import { getShareUrl } from '../../Article/SharePopup'
import { AuthorBadge } from '../../Author/AuthorBadge'

View File

@ -21,7 +21,6 @@ import { useSnackbar, useUI } from '~/context/ui'
import { InputMaybe, ProfileInput } from '~/graphql/schema/core.gen'
import { getImageUrl } from '~/lib/getThumbUrl'
import { handleImageUpload } from '~/lib/handleImageUpload'
import { profileSocialLinks } from '~/lib/profileSocialLinks'
import { clone } from '~/utils/clone'
import { validateUrl } from '~/utils/validate'
import { ProfileSettingsNavigation } from '../../ProfileNav'
@ -33,6 +32,7 @@ import { Modal } from '../../_shared/Modal'
import { Popover } from '../../_shared/Popover'
import { SocialNetworkInput } from '../../_shared/SocialNetworkInput'
import styles from './Settings.module.scss'
import { profileSocialLinks } from './profileSocialLinks'
const SimplifiedEditor = lazy(() => import('~/components/Editor/SimplifiedEditor'))
const GrowingTextarea = lazy(() => import('~/components/_shared/GrowingTextarea/GrowingTextarea'))

View File

@ -5,7 +5,7 @@ import { SearchField } from '~/components/_shared/SearchField'
import { FollowsFilter, useFollowing } from '~/context/following'
import { useLocalize } from '~/context/localize'
import { Author, Topic } from '~/graphql/schema/core.gen'
import { dummyFilter } from '~/lib/dummyFilter'
import { dummyFilter } from '~/intl/dummyFilter'
import stylesSettings from '../../../styles/FeedSettings.module.scss'
import { AuthorBadge } from '../../Author/AuthorBadge'
import { ProfileSettingsNavigation } from '../../ProfileNav'

View File

@ -2,9 +2,9 @@ import { JSX, Show, createEffect, createSignal, on, onMount } from 'solid-js'
import { Button } from '~/components/_shared/Button'
import { useLocalize } from '~/context/localize'
import { Author, Reaction, Shout } from '~/graphql/schema/core.gen'
import { byCreated } from '~/lib/sort'
import { SortFunction } from '~/types/common'
import { restoreScrollPosition, saveScrollPosition } from '~/utils/scroll'
import { byCreated } from '~/utils/sort'
export type LoadMoreItems = Shout[] | Author[] | Reaction[]

View File

@ -17,8 +17,8 @@ import {
Shout,
Topic
} from '~/graphql/schema/core.gen'
import { byStat } from '~/lib/sort'
import { FilterFunction, SortFunction } from '~/types/common'
import { byStat } from '~/utils/sort'
import { useFeed } from './feed'
const TOP_AUTHORS_COUNT = 5

View File

@ -12,7 +12,7 @@ import {
Topic
} from '~/graphql/schema/core.gen'
import { graphqlClientCreate } from '../graphql/client'
import { byStat } from '../lib/sort'
import { byStat } from '../utils/sort'
import { useSession } from './session'
export const PRERENDERED_ARTICLES_COUNT = 5

View File

@ -12,8 +12,8 @@ import {
} from 'solid-js'
import { loadTopics } from '~/graphql/api/public'
import { Topic } from '~/graphql/schema/core.gen'
import { getRandomTopicsFromArray } from '~/lib/getRandomTopicsFromArray'
import { byTopicStatDesc } from '../lib/sort'
import { getRandomItemsFromArray } from '~/utils/random'
import { byTopicStatDesc } from '../utils/sort'
type TopicsContextType = {
topicEntities: Accessor<{ [topicSlug: string]: Topic }>
@ -198,7 +198,7 @@ export const TopicsProvider = (props: { children: JSX.Element }) => {
const topics = isCacheValid ? req : await loadAllTopics()
console.info(`[context.topics] got ${(topics as Topic[]).length || 0} topics from idb`)
addTopics(topics as Topic[])
setRandomTopic(getRandomTopicsFromArray(topics || [], 1).pop())
setRandomTopic(getRandomItemsFromArray(topics || [], 1).pop())
}
},
{ defer: true }

View File

@ -1,5 +1,5 @@
import type { Author, Topic } from '~/graphql/schema/core.gen'
import { translit } from '../intl/translit'
import { translit } from './translit'
const prepareQuery = (searchQuery: string, lang: string) => {
const q = searchQuery.toLowerCase()

View File

@ -1,8 +0,0 @@
import { Topic } from '~/graphql/schema/core.gen'
import { RANDOM_TOPICS_COUNT } from '../components/Views/Home'
export const getRandomTopicsFromArray = (topics: Topic[], count: number = RANDOM_TOPICS_COUNT): Topic[] => {
if (!Array.isArray(topics)) return [] as Topic[]
const shuffledTopics = [...topics].sort(() => 0.5 - Math.random())
return shuffledTopics.slice(0, count)
}

View File

@ -1,59 +0,0 @@
import type { Author, Maybe, Reaction, Shout, Topic, TopicStat } from '~/graphql/schema/core.gen'
export const byFirstChar = (a: Author | Topic, b: Author | Topic) =>
((a as Author).name || (a as Topic).title || '').localeCompare(
(b as Author).name || (b as Topic).title || ''
)
export const byCreated = (a: { created_at?: number }, b: { created_at?: number }) => {
return (a?.created_at || 0) - (b?.created_at || 0)
}
export const byPublished = (a: Shout, b: Shout) => {
return (a?.published_at || 0) - (b?.published_at || 0)
}
export const byLength = (
a: (Shout | Reaction | Topic | Author)[],
b: (Shout | Reaction | Topic | Author)[]
) => {
const x = a.length
const y = b.length
if (x > y) return -1
if (x < y) return 1
return 0
}
export type SomeStat = { [x: string]: Maybe<number> } | undefined | null
export const byStat = (metric: string) => {
if (metric === 'name' || metric === 'title') return byFirstChar
return (a: { stat?: SomeStat }, b: { stat?: SomeStat }) => {
const aStat = a.stat?.[metric] ?? 0
const bStat = b.stat?.[metric] ?? 0
return aStat - bStat
}
}
export const byTopicStatDesc = (metric: keyof TopicStat) => {
return (a: Topic, b: Topic) => {
const x = a.stat?.[metric] || 0
const y = b.stat?.[metric] || 0
if (x > y) return -1
if (x < y) return 1
return 0
}
}
export const byScore = () => {
return (a: { score: number }, b: { score: number }) => {
const x = a?.score || 0
const y = b?.score || 0
if (x > y) return -1
if (x < y) return 1
return 0
}
}

8
src/utils/random.ts Normal file
View File

@ -0,0 +1,8 @@
export const getRandomItemsFromArray = <T>(items: T[], count = 10): T[] => {
if (!Array.isArray(items)) {
return []
}
const shuffledItems = [...items].sort(() => 0.5 - Math.random())
return shuffledItems.slice(0, count)
}

57
src/utils/sort.ts Normal file
View File

@ -0,0 +1,57 @@
import { Maybe } from 'graphql/jsutils/Maybe'
type WithNameOrTitle = { name?: string } | { title?: string }
type WithCreatedAt = { created_at?: number }
type WithPublishedAt = { published_at?: number }
type WithStat = { stat?: { [key: string]: Maybe<number> } | undefined | null }
type WithScore = { score: number }
export const byFirstChar = <T extends WithNameOrTitle>(a: T, b: T) => {
const aValue = 'name' in a ? a.name : (a as { title?: string }).title || ''
const bValue = 'name' in b ? b.name : (b as { title?: string }).title || ''
return aValue?.localeCompare(bValue || '')
}
export const byCreated = <T extends WithCreatedAt>(a: T, b: T) => {
return (a?.created_at || 0) - (b?.created_at || 0)
}
export const byPublished = <T extends WithPublishedAt>(a: T, b: T) => {
return (a?.published_at || 0) - (b?.published_at || 0)
}
export const byLength = <T>(a: T[], b: T[]) => {
const x = a.length
const y = b.length
if (x > y) return -1
if (x < y) return 1
return 0
}
export const byStat = (metric: string) => {
if (metric === 'name' || metric === 'title') return byFirstChar
return <T extends WithStat>(a: T, b: T) => {
const aStat = a.stat?.[metric] ?? 0
const bStat = b.stat?.[metric] ?? 0
return aStat - bStat
}
}
export const byTopicStatDesc = <T extends WithStat>(metric: string) => {
return (a: T, b: T) => {
const x = a.stat?.[metric] || 0
const y = b.stat?.[metric] || 0
if (x > y) return -1
if (x < y) return 1
return 0
}
}
export const byScore = <T extends WithScore>(a: T, b: T) => {
const x = a?.score || 0
const y = b?.score || 0
if (x > y) return -1
if (x < y) return 1
return 0
}