diff --git a/android/app/build.gradle b/android/app/build.gradle index 6b63858f..c39a0438 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -11,8 +11,8 @@ android { applicationId "com.compassconnections.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 117 - versionName "1.28.0" + versionCode 118 + versionName "1.29.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/web/components/answers/compatibility-questions-display.tsx b/web/components/answers/compatibility-questions-display.tsx index b32d4203..2743459f 100644 --- a/web/components/answers/compatibility-questions-display.tsx +++ b/web/components/answers/compatibility-questions-display.tsx @@ -11,7 +11,7 @@ import {Profile} from 'common/profiles/profile' import {Row as rowFor} from 'common/supabase/utils' import {User} from 'common/user' import {shortenNumber} from 'common/util/format' -import {keyBy, partition, sortBy} from 'lodash' +import {keyBy, sortBy} from 'lodash' import {PinIcon} from 'lucide-react' import {useCallback, useEffect, useMemo, useState} from 'react' import toast from 'react-hot-toast' @@ -31,15 +31,11 @@ import {Linkify} from 'web/components/widgets/linkify' import {Pagination} from 'web/components/widgets/pagination' import {Tooltip} from 'web/components/widgets/tooltip' import {shortenName} from 'web/components/widgets/user-link' -import {useIsLooking} from 'web/hooks/use-is-looking' import {usePersistentInMemoryState} from 'web/hooks/use-persistent-in-memory-state' import {usePinnedQuestionIds} from 'web/hooks/use-pinned-question-ids' import {useProfile} from 'web/hooks/use-profile' import {useCompatibleProfiles} from 'web/hooks/use-profiles' -import { - useCompatibilityQuestionsWithAnswerCount, - useUserCompatibilityAnswers, -} from 'web/hooks/use-questions' +import {useCompatibilityQuestionGroups, useUserCompatibilityAnswers} from 'web/hooks/use-questions' import {useUser} from 'web/hooks/use-user' import {useT} from 'web/lib/locale' import {db} from 'web/lib/supabase/db' @@ -65,29 +61,6 @@ import {PinQuestionButton} from './pin-question-button' const NUM_QUESTIONS_TO_SHOW = 8 const NUM_PINNED_QUESTIONS_TO_SHOW = 4 -export function separateQuestionsArray( - questions: QuestionWithStats[], - skippedAnswerQuestionIds: Set, - answeredQuestionIds: Set, -) { - debug('Refreshing questions array') - const skippedQuestions: QuestionWithStats[] = [] - const answeredQuestions: QuestionWithStats[] = [] - const otherQuestions: QuestionWithStats[] = [] - - questions.forEach((q) => { - if (skippedAnswerQuestionIds.has(q.id)) { - skippedQuestions.push(q) - } else if (answeredQuestionIds.has(q.id)) { - answeredQuestions.push(q) - } else { - otherQuestions.push(q) - } - }) - - return {skippedQuestions, answeredQuestions, otherQuestions} -} - export function CompatibilityQuestionsDisplay(props: { isCurrentUser: boolean user: User @@ -106,26 +79,15 @@ export function CompatibilityQuestionsDisplay(props: { const {pinnedQuestionIds, refreshPinnedQuestionIds} = usePinnedQuestionIds() - const {refreshCompatibilityQuestions, compatibilityQuestions} = - useCompatibilityQuestionsWithAnswerCount() - - const {refreshCompatibilityAnswers, compatibilityAnswers} = useUserCompatibilityAnswers(user.id) - - const {answers, skippedQuestions, answeredQuestions, otherQuestions} = useMemo(() => { - debug('Refreshing questions') - const [skippedAnswers, answers] = partition( - compatibilityAnswers, - (answer) => answer.importance == -1, - ) - const answeredQuestionIds = new Set(answers.map((answer) => answer.question_id)) - const skippedAnswerQuestionIds = new Set(skippedAnswers.map((answer) => answer.question_id)) - const {skippedQuestions, answeredQuestions, otherQuestions} = separateQuestionsArray( - compatibilityQuestions, - skippedAnswerQuestionIds, - answeredQuestionIds, - ) - return {answers, skippedQuestions, answeredQuestions, otherQuestions} - }, [compatibilityAnswers, compatibilityQuestions]) + const { + answers, + skippedQuestions, + answeredQuestions, + otherQuestions, + compatibilityQuestions, + refreshCompatibilityAnswers, + refreshCompatibilityQuestions, + } = useCompatibilityQuestionGroups(user.id) const refreshCompatibilityAll = useCallback(() => { refreshCompatibilityAnswers() @@ -133,9 +95,8 @@ export function CompatibilityQuestionsDisplay(props: { refreshPinnedQuestionIds() }, [refreshCompatibilityAnswers, refreshCompatibilityQuestions, refreshPinnedQuestionIds]) - const isLooking = useIsLooking() const [sort, setSort] = usePersistentInMemoryState( - !isLooking && !fromProfilePage ? 'their_important' : 'your_important', + isCurrentUser ? 'your_important' : 'their_important', `compatibility-sort-${user.id}`, ) const [searchTerm, setSearchTerm] = useState('') @@ -241,40 +202,42 @@ export function CompatibilityQuestionsDisplay(props: { )} {answeredQuestions.length > 0 && ( -
- {/* {*/} - {/* setSearchTerm(e.target.value)*/} - {/* setPage(0)*/} - {/* }}*/} - {/* className="h-8 pl-7 pr-2 text-sm border border-ink-300 rounded-xl bg-canvas-50 focus:outline-none focus:ring-1 focus:ring-primary-500 w-48 transition-all"*/} - {/*/>*/} - ) => { - setSearchTerm(e.target.value) - }} - searchIcon + <> +
+ {/* {*/} + {/* setSearchTerm(e.target.value)*/} + {/* setPage(0)*/} + {/* }}*/} + {/* className="h-8 pl-7 pr-2 text-sm border border-ink-300 rounded-xl bg-canvas-50 focus:outline-none focus:ring-1 focus:ring-primary-500 w-48 transition-all"*/} + {/*/>*/} + ) => { + setSearchTerm(e.target.value) + }} + searchIcon + /> +
+ -
+ )} - {compatibilityScore && ( )}
- {answeredQuestions.length <= 0 ? ( + {answeredQuestions.length == 0 ? ( {isCurrentUser ? t( diff --git a/web/components/profile/profile-info.tsx b/web/components/profile/profile-info.tsx index 82767388..a2506551 100644 --- a/web/components/profile/profile-info.tsx +++ b/web/components/profile/profile-info.tsx @@ -21,6 +21,7 @@ import {Subtitle} from 'web/components/widgets/subtitle' import {shortenName} from 'web/components/widgets/user-link' import {useGetter} from 'web/hooks/use-getter' import {useHiddenProfiles} from 'web/hooks/use-hidden-profiles' +import {useCompatibilityQuestionGroups} from 'web/hooks/use-questions' import {useUser} from 'web/hooks/use-user' import {useUserActivity} from 'web/hooks/use-user-activity' import {User} from 'web/lib/firebase/users' @@ -327,6 +328,9 @@ function ProfileContent(props: { const isCurrentUser = currentUser?.id === user.id const t = useT() + const {answeredQuestions} = useCompatibilityQuestionGroups(user.id) + const showCompatibilityPrompts = currentUser && (isCurrentUser || answeredQuestions.length > 0) + return ( <>
- {currentUser && ( + {showCompatibilityPrompts && ( { isLoading, } } + +export function separateQuestionsArray( + questions: QuestionWithStats[], + skippedAnswerQuestionIds: Set, + answeredQuestionIds: Set, +) { + debug('Refreshing questions array') + const skippedQuestions: QuestionWithStats[] = [] + const answeredQuestions: QuestionWithStats[] = [] + const otherQuestions: QuestionWithStats[] = [] + + questions.forEach((q) => { + if (skippedAnswerQuestionIds.has(q.id)) { + skippedQuestions.push(q) + } else if (answeredQuestionIds.has(q.id)) { + answeredQuestions.push(q) + } else { + otherQuestions.push(q) + } + }) + + return {skippedQuestions, answeredQuestions, otherQuestions} +} + +// Single source of truth for a user's compatibility answers split into +// answered / skipped / other groups. Both the display component and the +// profile-card visibility check read this (shared in-memory cache, no refetch). +export const useCompatibilityQuestionGroups = (userId: string | undefined) => { + const {refreshCompatibilityAnswers, compatibilityAnswers} = useUserCompatibilityAnswers(userId) + const {refreshCompatibilityQuestions, compatibilityQuestions} = + useCompatibilityQuestionsWithAnswerCount() + + const groups = useMemo(() => { + debug('Refreshing questions') + const [skippedAnswers, answers] = partition( + compatibilityAnswers, + (answer) => answer.importance == -1, + ) + return { + answers, + ...separateQuestionsArray( + compatibilityQuestions, + new Set(skippedAnswers.map((answer) => answer.question_id)), + new Set(answers.map((answer) => answer.question_id)), + ), + } + }, [compatibilityAnswers, compatibilityQuestions]) + + return { + ...groups, + compatibilityQuestions, + refreshCompatibilityAnswers, + refreshCompatibilityQuestions, + } +}