mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-25 01:51:37 -04:00
Add option to view pics on profile cards
This commit is contained in:
@@ -362,6 +362,7 @@
|
||||
"filter.last_active.3months": "Letzte 3 Monate",
|
||||
"filter.reset": "Zurücksetzen",
|
||||
"filter.short_bio_toggle": "Kurze Bios einschließen",
|
||||
"filter.show_photos": "Profilfotos anzeigen",
|
||||
"filter.wants_kids.any_preference": "Alle Präferenzen",
|
||||
"filter.wants_kids.doesnt_want_kids": "Möchte keine Kinder",
|
||||
"filter.wants_kids.either": "Egal",
|
||||
@@ -1161,6 +1162,7 @@
|
||||
"stats.total": "Gesamt",
|
||||
"stats.votes": "Stimmen",
|
||||
"stats.with_bio": "Mit Bio",
|
||||
"stats.gender_ratio": "Geschlechterverteilung",
|
||||
"sticky_format_menu.add_embed": "Embed hinzufügen",
|
||||
"sticky_format_menu.add_emoji": "Emoji hinzufügen",
|
||||
"sticky_format_menu.upload_image": "Bild hochladen",
|
||||
|
||||
@@ -362,6 +362,7 @@
|
||||
"filter.last_active.3months": "3 derniers mois",
|
||||
"filter.reset": "Réinitialiser",
|
||||
"filter.short_bio_toggle": "Inclure les profils incomplets",
|
||||
"filter.show_photos": "Afficher les photos",
|
||||
"filter.wants_kids.any_preference": "N'importe",
|
||||
"filter.wants_kids.doesnt_want_kids": "Ne veut pas d'enfants",
|
||||
"filter.wants_kids.either": "N'importe",
|
||||
@@ -1160,6 +1161,7 @@
|
||||
"stats.total": "Total",
|
||||
"stats.votes": "Votes",
|
||||
"stats.with_bio": "Complétés",
|
||||
"stats.gender_ratio": "Répartition Hommes / Femmes",
|
||||
"sticky_format_menu.add_embed": "Ajouter un embed",
|
||||
"sticky_format_menu.add_emoji": "Ajouter un emoji",
|
||||
"sticky_format_menu.upload_image": "Ajouter une image",
|
||||
|
||||
7
common/src/profiles-rendering.ts
Normal file
7
common/src/profiles-rendering.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export type RenderingOptions = {
|
||||
showPhotos: boolean | null | undefined
|
||||
}
|
||||
|
||||
export const initialRenderingOptions: RenderingOptions = {
|
||||
showPhotos: false,
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {formatFilters, SKIPPED_FORMAT_FILTERS_KEYS} from 'common/filters-format'
|
||||
import {Gender} from 'common/gender'
|
||||
import {OptionTableKey} from 'common/profiles/constants'
|
||||
import {Profile} from 'common/profiles/profile'
|
||||
import {RenderingOptions} from 'common/profiles-rendering'
|
||||
import {nullifyDictValues, removeNullOrUndefinedProps, sampleDictByPrefix} from 'common/util/object'
|
||||
import {ReactNode, useState} from 'react'
|
||||
import {
|
||||
@@ -27,6 +28,7 @@ import {
|
||||
import {ReligionFilter, ReligionFilterText} from 'web/components/filters/religion-filter'
|
||||
import {RomanticFilter, RomanticFilterText} from 'web/components/filters/romantic-filter'
|
||||
import {ShortBioToggle} from 'web/components/filters/short-bio-toggle'
|
||||
import {ShowPhotosToggle} from 'web/components/filters/show-photos-toggle'
|
||||
import {KidsLabel, WantsKidsFilter} from 'web/components/filters/wants-kids-filter'
|
||||
import {FilterGuide} from 'web/components/guidance'
|
||||
import {Col} from 'web/components/layout/col'
|
||||
@@ -186,8 +188,8 @@ function SelectedFiltersSummary(props: {
|
||||
}
|
||||
|
||||
function Filters(props: {
|
||||
filters: Partial<FilterFields>
|
||||
youProfile: Profile | undefined | null
|
||||
filters: Partial<FilterFields>
|
||||
updateFilter: (newState: Partial<FilterFields>) => void
|
||||
clearFilters: () => void
|
||||
setYourFilters: (checked: boolean) => void
|
||||
@@ -196,6 +198,8 @@ function Filters(props: {
|
||||
raisedInLocationFilterProps: LocationFilterProps
|
||||
includeRelationshipFilters: boolean | undefined
|
||||
choices: Record<OptionTableKey, Record<string, string>>
|
||||
renderingOptions: Partial<RenderingOptions>
|
||||
updateRenderingOptions: (newState: Partial<RenderingOptions>) => void
|
||||
}) {
|
||||
const t = useT()
|
||||
const {
|
||||
@@ -208,6 +212,8 @@ function Filters(props: {
|
||||
locationFilterProps,
|
||||
raisedInLocationFilterProps,
|
||||
includeRelationshipFilters,
|
||||
renderingOptions,
|
||||
updateRenderingOptions,
|
||||
choices,
|
||||
} = props
|
||||
|
||||
@@ -247,6 +253,14 @@ function Filters(props: {
|
||||
<ShortBioToggle updateFilter={updateFilter} filters={filters} hidden={false} />
|
||||
</Col>
|
||||
|
||||
{/* Show Photos */}
|
||||
<Col className="p-4 pt-0">
|
||||
<ShowPhotosToggle
|
||||
updateRenderingOptions={updateRenderingOptions}
|
||||
renderingOptions={renderingOptions}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
{/* ALWAYS VISIBLE FILTERS */}
|
||||
|
||||
{/* CONNECTION - Always visible */}
|
||||
@@ -807,6 +821,8 @@ export function FiltersElement(props: {
|
||||
isYourFilters: boolean
|
||||
locationFilterProps: LocationFilterProps
|
||||
raisedInLocationFilterProps: LocationFilterProps
|
||||
renderingOptions: Partial<RenderingOptions>
|
||||
updateRenderingOptions: (newState: Partial<RenderingOptions>) => void
|
||||
}) {
|
||||
const {
|
||||
filters,
|
||||
@@ -817,6 +833,8 @@ export function FiltersElement(props: {
|
||||
isYourFilters,
|
||||
locationFilterProps,
|
||||
raisedInLocationFilterProps,
|
||||
renderingOptions,
|
||||
updateRenderingOptions,
|
||||
} = props
|
||||
const youSeekingRelationship = youProfile?.pref_relation_styles?.includes('relationship')
|
||||
const {choices: interestChoices} = useChoices('interests')
|
||||
@@ -839,6 +857,8 @@ export function FiltersElement(props: {
|
||||
raisedInLocationFilterProps={raisedInLocationFilterProps}
|
||||
includeRelationshipFilters={youSeekingRelationship}
|
||||
choices={choices}
|
||||
renderingOptions={renderingOptions}
|
||||
updateRenderingOptions={updateRenderingOptions}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
33
web/components/filters/show-photos-toggle.tsx
Normal file
33
web/components/filters/show-photos-toggle.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import clsx from 'clsx'
|
||||
import {RenderingOptions} from 'common/profiles-rendering'
|
||||
import {Row} from 'web/components/layout/row'
|
||||
import {useT} from 'web/lib/locale'
|
||||
|
||||
export function ShowPhotosToggle(props: {
|
||||
renderingOptions: Partial<RenderingOptions>
|
||||
updateRenderingOptions: (newState: Partial<RenderingOptions>) => void
|
||||
}) {
|
||||
const {renderingOptions, updateRenderingOptions} = props
|
||||
const t = useT()
|
||||
|
||||
const label = t('filter.show_photos', 'Show profile pictures')
|
||||
|
||||
const on = renderingOptions.showPhotos ?? true
|
||||
|
||||
return (
|
||||
<Row className={clsx('mr-2 items-center hover-bold', on && 'font-semibold')}>
|
||||
<input
|
||||
id={label}
|
||||
type="checkbox"
|
||||
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-4 w-4 rounded hover:bg-canvas-200 cursor-pointer"
|
||||
checked={on}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
updateRenderingOptions({showPhotos: e.target.checked})
|
||||
}
|
||||
/>
|
||||
<label htmlFor={label} className={clsx('text-ink-600 ml-2')}>
|
||||
{label}
|
||||
</label>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
@@ -23,10 +23,10 @@ export const useFilters = (you: Profile | undefined, fromSignup?: boolean) => {
|
||||
: {...initialFilters, orderBy: 'created_time' as const}
|
||||
|
||||
const getInitialFilters = (): Partial<FilterFields> => {
|
||||
if (fromSignup) {
|
||||
return {...baseFilters, languages: [LOCALE_TO_LANGUAGE[getLocale()]]}
|
||||
return {
|
||||
...baseFilters,
|
||||
languages: fromSignup ? [LOCALE_TO_LANGUAGE[getLocale()]] : undefined,
|
||||
}
|
||||
return baseFilters
|
||||
}
|
||||
|
||||
const [filters, setFilters] = usePersistentLocalState<Partial<FilterFields>>(
|
||||
|
||||
@@ -3,6 +3,7 @@ import clsx from 'clsx'
|
||||
import {CompatibilityScore} from 'common/profiles/compatibility-score'
|
||||
import {Profile} from 'common/profiles/profile'
|
||||
import {capitalize} from 'lodash'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import {Row} from 'web/components/layout/row'
|
||||
import {CompatibleBadge} from 'web/components/widgets/compatible-badge'
|
||||
@@ -28,6 +29,7 @@ export const ProfileGrid = (props: {
|
||||
onHide?: (userId: string) => void
|
||||
hiddenUserIds?: string[]
|
||||
onUndoHidden?: (userId: string) => void
|
||||
showPhotos?: boolean | null
|
||||
}) => {
|
||||
const {
|
||||
profiles,
|
||||
@@ -40,6 +42,7 @@ export const ProfileGrid = (props: {
|
||||
onHide,
|
||||
hiddenUserIds,
|
||||
onUndoHidden,
|
||||
showPhotos,
|
||||
} = props
|
||||
|
||||
const user = useUser()
|
||||
@@ -65,6 +68,7 @@ export const ProfileGrid = (props: {
|
||||
onHide={onHide}
|
||||
isHidden={hiddenUserIds?.includes(profile.user_id) ?? false}
|
||||
onUndoHidden={onUndoHidden}
|
||||
showPhotos={showPhotos}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -100,8 +104,9 @@ function ProfilePreview(props: {
|
||||
onHide?: (userId: string) => void
|
||||
isHidden?: boolean
|
||||
onUndoHidden?: (userId: string) => void
|
||||
showPhotos?: boolean | null
|
||||
}) {
|
||||
const {profile, compatibilityScore, onHide, isHidden, onUndoHidden} = props
|
||||
const {profile, compatibilityScore, onHide, isHidden, onUndoHidden, showPhotos} = props
|
||||
const {user} = profile
|
||||
const choicesIdsToLabels = useAllChoices()
|
||||
const t = useT()
|
||||
@@ -165,6 +170,7 @@ function ProfilePreview(props: {
|
||||
// return null
|
||||
// }
|
||||
|
||||
const isPhotoRendered = showPhotos !== false && profile.pinned_url
|
||||
return (
|
||||
<Link
|
||||
// onClick={() => track('click profile preview')}
|
||||
@@ -172,22 +178,6 @@ function ProfilePreview(props: {
|
||||
className="cursor-pointer group block rounded-lg overflow-hidden bg-transparent hover:bg-gray-50 dark:hover:bg-gray-800/50 h-full border border-canvas-300"
|
||||
>
|
||||
<Col className="relative h-40 w-full overflow-hidden rounded transition-all">
|
||||
{/*{pinned_url ? (*/}
|
||||
{/* <Image*/}
|
||||
{/* src={pinned_url}*/}
|
||||
{/* width={180}*/}
|
||||
{/* height={240}*/}
|
||||
{/* alt=""*/}
|
||||
{/* className="h-full w-full object-cover"*/}
|
||||
{/* loading="lazy"*/}
|
||||
{/* priority={false}*/}
|
||||
{/* />*/}
|
||||
{/*) : (*/}
|
||||
{/* <Col className="bg-ink-300 h-full w-full items-center justify-center">*/}
|
||||
{/* <UserIcon className="h-20 w-20" />*/}
|
||||
{/* </Col>*/}
|
||||
{/*)}*/}
|
||||
|
||||
<Row className="absolute top-2 right-2 items-start justify-end px-2 pb-3 z-10">
|
||||
{/* {currentUser ? (*/}
|
||||
{/* <StarButton*/}
|
||||
@@ -215,7 +205,12 @@ function ProfilePreview(props: {
|
||||
)}
|
||||
</Row>
|
||||
|
||||
<Col className="absolute inset-x-0 top-[-15px] bg-gradient-to-b to-transparent px-4 pt-0">
|
||||
<Col
|
||||
className={clsx(
|
||||
'absolute inset-x-0 top-[-15px] bg-gradient-to-b to-transparent px-4 pt-0',
|
||||
isPhotoRendered && 'mr-24',
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h3 className="text-lg font-medium text-gray-900 dark:text-white truncate">
|
||||
@@ -252,6 +247,21 @@ function ProfilePreview(props: {
|
||||
{/* {city} • {capitalize(convertGender(gender as Gender))}*/}
|
||||
{/*</Row>*/}
|
||||
</Col>
|
||||
|
||||
{/* Profile image moved to bottom right */}
|
||||
{isPhotoRendered && (
|
||||
<div className="absolute bottom-4 right-2 w-24 h-24 rounded-xl overflow-hidden shadow-lg">
|
||||
<Image
|
||||
src={profile.pinned_url!}
|
||||
width={128}
|
||||
height={128}
|
||||
alt=""
|
||||
className="h-full w-full object-cover"
|
||||
loading="lazy"
|
||||
priority={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Col>
|
||||
</Link>
|
||||
)
|
||||
|
||||
@@ -23,6 +23,7 @@ import {usePersistentInMemoryState} from 'web/hooks/use-persistent-in-memory-sta
|
||||
import {usePersistentLocalState} from 'web/hooks/use-persistent-local-state'
|
||||
import {useProfile} from 'web/hooks/use-profile'
|
||||
import {useCompatibleProfiles} from 'web/hooks/use-profiles'
|
||||
import {useRenderingOptions} from 'web/hooks/use-rendering-options'
|
||||
import {useUser} from 'web/hooks/use-user'
|
||||
import {api} from 'web/lib/api'
|
||||
import {useLocale, useT} from 'web/lib/locale'
|
||||
@@ -45,6 +46,8 @@ export function ProfilesHome() {
|
||||
raisedInLocationFilterProps,
|
||||
} = useFilters(you ?? undefined, fromSignup)
|
||||
|
||||
const {renderingOptions, updateRenderingOptions} = useRenderingOptions()
|
||||
|
||||
const [profiles, setProfiles] = usePersistentInMemoryState<Profile[] | undefined>(
|
||||
undefined,
|
||||
'profiles',
|
||||
@@ -196,6 +199,8 @@ export function ProfilesHome() {
|
||||
isYourFilters={isYourFilters}
|
||||
locationFilterProps={locationFilterProps}
|
||||
raisedInLocationFilterProps={raisedInLocationFilterProps}
|
||||
renderingOptions={renderingOptions}
|
||||
updateRenderingOptions={updateRenderingOptions}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -335,6 +340,7 @@ export function ProfilesHome() {
|
||||
onHide={onHide}
|
||||
hiddenUserIds={recentlyHiddenIds}
|
||||
onUndoHidden={onUndoHidden}
|
||||
showPhotos={renderingOptions.showPhotos}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
15
web/hooks/use-rendering-options.ts
Normal file
15
web/hooks/use-rendering-options.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import {initialRenderingOptions, RenderingOptions} from 'common/profiles-rendering'
|
||||
import {usePersistentLocalState} from 'web/hooks/use-persistent-local-state'
|
||||
|
||||
export function useRenderingOptions() {
|
||||
const [renderingOptions, setRenderingOptions] = usePersistentLocalState<RenderingOptions>(
|
||||
initialRenderingOptions,
|
||||
'rendering-options',
|
||||
)
|
||||
|
||||
const updateRenderingOptions = (newState: Partial<RenderingOptions>) => {
|
||||
const updatedState = {...newState}
|
||||
setRenderingOptions((prevState) => ({...prevState, ...updatedState}))
|
||||
}
|
||||
return {renderingOptions, updateRenderingOptions}
|
||||
}
|
||||
Reference in New Issue
Block a user