From a4723563f51cc1bcfcf313871725c11a6d82291a Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Thu, 16 Oct 2025 13:41:03 +0200 Subject: [PATCH] Keep blue loading circle for buttons --- .../answers/other-profile-answers.tsx | 30 ++--- web/components/profile-grid.tsx | 4 +- web/components/profiles/profiles-home.tsx | 4 +- web/components/widgets/loading-indicator.tsx | 45 +++++-- web/pages/loading.tsx | 4 +- web/pages/messages/[channelId].tsx | 116 ++++++++---------- web/pages/notifications.tsx | 72 +++++------ web/pages/signup.tsx | 4 +- 8 files changed, 142 insertions(+), 137 deletions(-) diff --git a/web/components/answers/other-profile-answers.tsx b/web/components/answers/other-profile-answers.tsx index e1a5d906..322024e7 100644 --- a/web/components/answers/other-profile-answers.tsx +++ b/web/components/answers/other-profile-answers.tsx @@ -1,29 +1,29 @@ -import { User } from 'common/user' -import { useOtherAnswers } from 'web/hooks/use-other-answers' -import { QuestionWithCountType } from 'web/hooks/use-questions' -import { Col } from 'web/components/layout/col' -import { Row } from 'web/components/layout/row' -import { Avatar } from 'web/components/widgets/avatar' -import { Linkify } from 'web/components/widgets/linkify' -import { LoadingIndicator } from 'web/components/widgets/loading-indicator' -import { UserLink } from 'web/components/widgets/user-link' -import { Gender, convertGender } from 'common/gender' -import { capitalize } from 'lodash' +import {User} from 'common/user' +import {useOtherAnswers} from 'web/hooks/use-other-answers' +import {QuestionWithCountType} from 'web/hooks/use-questions' +import {Col} from 'web/components/layout/col' +import {Row} from 'web/components/layout/row' +import {Avatar} from 'web/components/widgets/avatar' +import {Linkify} from 'web/components/widgets/linkify' +import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' +import {UserLink} from 'web/components/widgets/user-link' +import {convertGender, Gender} from 'common/gender' +import {capitalize} from 'lodash' import clsx from 'clsx' -import { shortenedFromNow } from 'web/lib/util/shortenedFromNow' +import {shortenedFromNow} from 'web/lib/util/shortenedFromNow' export function OtherProfileAnswers(props: { question: QuestionWithCountType user?: User className?: string }) { - const { question, className } = props + const {question, className} = props const otherAnswers = useOtherAnswers(question.id) const shownAnswers = otherAnswers?.filter( (a) => a.multiple_choice != null || a.free_response || a.integer ) - if (otherAnswers === undefined) return + if (otherAnswers === undefined) return if ( (otherAnswers === null || otherAnswers.length || @@ -50,7 +50,7 @@ export function OtherProfileAnswers(props: { /> - , {otherAnswer.age} + , {otherAnswer.age} {otherAnswer.city} •{' '} diff --git a/web/components/profile-grid.tsx b/web/components/profile-grid.tsx index ad6e64f6..c3e8dc91 100644 --- a/web/components/profile-grid.tsx +++ b/web/components/profile-grid.tsx @@ -1,6 +1,6 @@ import {Profile} from 'common/love/profile' import {CompatibilityScore} from 'common/love/compatibility-score' -import {LoadingIndicator} from 'web/components/widgets/loading-indicator' +import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' import {LoadMoreUntilNotVisible} from 'web/components/widgets/visibility-observer' import {track} from 'web/lib/service/analytics' import {Col} from './layout/col' @@ -59,7 +59,7 @@ export const ProfileGrid = (props: { {isLoadingMore && (
- +
)} diff --git a/web/components/profiles/profiles-home.tsx b/web/components/profiles/profiles-home.tsx index 5cc67b19..81dde77a 100644 --- a/web/components/profiles/profiles-home.tsx +++ b/web/components/profiles/profiles-home.tsx @@ -6,7 +6,7 @@ import {useCompatibleProfiles} from 'web/hooks/use-profiles' import {getStars} from 'web/lib/supabase/stars' import {useCallback, useEffect, useRef, useState} from 'react' import {ProfileGrid} from 'web/components/profile-grid' -import {LoadingIndicator} from 'web/components/widgets/loading-indicator' +import {CompassLoadingIndicator, LoadingIndicator} from 'web/components/widgets/loading-indicator' import {Title} from 'web/components/widgets/title' import {useGetter} from 'web/hooks/use-getter' import {usePersistentInMemoryState} from 'web/hooks/use-persistent-in-memory-state' @@ -110,7 +110,7 @@ export function ProfilesHome() { refreshBookmarkedSearches={refreshBookmarkedSearches} /> {displayProfiles === undefined || compatibleProfiles === undefined ? ( - + ) : ( +
+
+ ) +} + + + +export function CompassLoadingIndicator(props: { className?: string spinnerClassName?: string size?: 'sm' | 'md' | 'lg' diff --git a/web/pages/loading.tsx b/web/pages/loading.tsx index 8f93552f..5b2e1c91 100644 --- a/web/pages/loading.tsx +++ b/web/pages/loading.tsx @@ -1,10 +1,10 @@ "use client"; -import {LoadingIndicator} from "web/components/widgets/loading-indicator"; +import {CompassLoadingIndicator} from "web/components/widgets/loading-indicator"; import {LovePage} from "web/components/love-page"; export default function Loading() { return - + ; } diff --git a/web/pages/messages/[channelId].tsx b/web/pages/messages/[channelId].tsx index 2ac1483f..93e7b267 100644 --- a/web/pages/messages/[channelId].tsx +++ b/web/pages/messages/[channelId].tsx @@ -1,65 +1,53 @@ -import { LovePage } from 'web/components/love-page' -import { useRouter } from 'next/router' -import { - usePrivateMessages, - useSortedPrivateMessageMemberships, -} from 'web/hooks/use-private-messages' -import { Col } from 'web/components/layout/col' -import { User } from 'common/user' -import { useEffect, useState } from 'react' -import { track } from 'web/lib/service/analytics' -import { firebaseLogin } from 'web/lib/firebase/users' -import { uniq } from 'lodash' -import { useUser } from 'web/hooks/use-user' -import { useTextEditor } from 'web/components/widgets/editor' -import { api } from 'web/lib/api' -import { - ChatMessageItem, - SystemChatMessageItem, -} from 'web/components/chat/chat-message' -import { CommentInputTextArea } from 'web/components/comments/comment-input' -import { LoadingIndicator } from 'web/components/widgets/loading-indicator' -import { DAY_MS, YEAR_MS } from 'common/util/time' -import { useUsersInStore } from 'web/hooks/use-user-supabase' -import { Row } from 'web/components/layout/row' +import {LovePage} from 'web/components/love-page' +import {useRouter} from 'next/router' +import {usePrivateMessages, useSortedPrivateMessageMemberships,} from 'web/hooks/use-private-messages' +import {Col} from 'web/components/layout/col' +import {User} from 'common/user' +import {useEffect, useState} from 'react' +import {track} from 'web/lib/service/analytics' +import {firebaseLogin} from 'web/lib/firebase/users' +import {uniq} from 'lodash' +import {useUser} from 'web/hooks/use-user' +import {useTextEditor} from 'web/components/widgets/editor' +import {api} from 'web/lib/api' +import {ChatMessageItem, SystemChatMessageItem,} from 'web/components/chat/chat-message' +import {CommentInputTextArea} from 'web/components/comments/comment-input' +import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' +import {DAY_MS, YEAR_MS} from 'common/util/time' +import {useUsersInStore} from 'web/hooks/use-user-supabase' +import {Row} from 'web/components/layout/row' import clsx from 'clsx' -import { useRedirectIfSignedOut } from 'web/hooks/use-redirect-if-signed-out' -import { MultipleOrSingleAvatars } from 'web/components/multiple-or-single-avatars' -import { Modal, MODAL_CLASS } from 'web/components/layout/modal' -import { - BannedBadge, - UserAvatarAndBadge, -} from 'web/components/widgets/user-link' +import {useRedirectIfSignedOut} from 'web/hooks/use-redirect-if-signed-out' +import {MultipleOrSingleAvatars} from 'web/components/multiple-or-single-avatars' +import {Modal, MODAL_CLASS} from 'web/components/layout/modal' +import {BannedBadge, UserAvatarAndBadge,} from 'web/components/widgets/user-link' import DropdownMenu from 'web/components/comments/dropdown-menu' -import { DotsVerticalIcon } from '@heroicons/react/solid' -import { FaUserFriends, FaUserMinus } from 'react-icons/fa' -import { buildArray, filterDefined } from 'common/util/array' -import { GiSpeakerOff } from 'react-icons/gi' +import {DotsVerticalIcon} from '@heroicons/react/solid' +import {FaUserFriends, FaUserMinus} from 'react-icons/fa' +import {buildArray, filterDefined} from 'common/util/array' +import {GiSpeakerOff} from 'react-icons/gi' import toast from 'react-hot-toast' -import { useIsMobile } from 'web/hooks/use-is-mobile' -import { - useGroupedMessages, - usePaginatedScrollingMessages, -} from 'web/lib/supabase/chat-messages' -import { PrivateMessageChannel } from 'common/supabase/private-messages' -import { ChatMessage } from 'common/chat-message' -import { BackButton } from 'web/components/back-button' +import {useIsMobile} from 'web/hooks/use-is-mobile' +import {useGroupedMessages, usePaginatedScrollingMessages,} from 'web/lib/supabase/chat-messages' +import {PrivateMessageChannel} from 'common/supabase/private-messages' +import {ChatMessage} from 'common/chat-message' +import {BackButton} from 'web/components/back-button' export default function PrivateMessagesPage() { const router = useRouter() - const { channelId: channelIdString } = router.query as { channelId: string } + const {channelId: channelIdString} = router.query as { channelId: string } const channelId = router.isReady ? parseInt(channelIdString) : undefined const user = useUser() if (user === null) { router.replace(`/signin?returnTo=${encodeURIComponent('/messages')}`) - return + return } return ( {router.isReady && channelId && user ? ( - + ) : ( - + )} ) @@ -71,13 +59,13 @@ export function PrivateMessagesContent(props: { }) { useRedirectIfSignedOut() - const { channelId, user } = props + const {channelId, user} = props const channelMembership = useSortedPrivateMessageMemberships( user.id, 1, channelId ) - const { channels, memberIdsByChannelId } = channelMembership + const {channels, memberIdsByChannelId} = channelMembership const thisChannel = channels?.find((c) => c.channel_id == channelId) const loaded = channels !== undefined && channelId const memberIds = thisChannel @@ -87,9 +75,9 @@ export function PrivateMessagesContent(props: { return ( <> {user && loaded && thisChannel && memberIds ? ( - + ) : ( - + )} ) @@ -100,7 +88,7 @@ export const PrivateChat = (props: { channel: PrivateMessageChannel memberIds: string[] }) => { - const { user, channel, memberIds } = props + const {user, channel, memberIds} = props const channelId = channel.channel_id const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) const isMobile = useIsMobile() @@ -132,7 +120,7 @@ export const PrivateChat = (props: { ) const router = useRouter() - const { topVisibleRef, showMessages, messages, innerDiv, outerDiv } = + const {topVisibleRef, showMessages, messages, innerDiv, outerDiv} = usePaginatedScrollingMessages( realtimeMessages?.map( (m) => @@ -193,7 +181,7 @@ export const PrivateChat = (props: { 'border-ink-200 bg-canvas-50 h-14 items-center gap-1 border-b' } > - + + )} } + icon={} items={buildArray( { - icon: , + icon: , name: 'See members', onClick: () => { setShowUsers(true) }, }, { - icon: , + icon: , name: 'Mute 1 day', onClick: async () => { await toast.promise( @@ -251,7 +239,7 @@ export const PrivateChat = (props: { }, }, { - icon: , + icon: , name: 'Mute forever', onClick: async () => { await toast.promise( @@ -268,7 +256,7 @@ export const PrivateChat = (props: { }, }, { - icon: , + icon: , name: 'Leave chat', onClick: async () => { await api('leave-private-user-message-channel', { @@ -287,7 +275,7 @@ export const PrivateChat = (props: { key={user.id} className={'w-full items-center justify-start gap-2'} > - +
))} @@ -311,13 +299,13 @@ export const PrivateChat = (props: { }} > {realtimeMessages === undefined ? ( - + ) : ( <>
{groupedMessages.map((messages, i) => { const firstMessage = messages[0] @@ -383,5 +371,5 @@ export const PrivateChat = (props: { } const setAsSeen = async (channelId: number) => { - return api('set-channel-seen-time', { channelId }) + return api('set-channel-seen-time', {channelId}) } diff --git a/web/pages/notifications.tsx b/web/pages/notifications.tsx index a5421846..0b600999 100644 --- a/web/pages/notifications.tsx +++ b/web/pages/notifications.tsx @@ -1,41 +1,37 @@ -import { - NOTIFICATIONS_PER_PAGE, - NOTIFICATION_TYPES_TO_SELECT, - type Notification, -} from 'common/notifications' -import { PrivateUser, type User } from 'common/src/user' +import {type Notification, NOTIFICATION_TYPES_TO_SELECT, NOTIFICATIONS_PER_PAGE,} from 'common/notifications' +import {PrivateUser, type User} from 'common/src/user' import { notification_destination_types, notification_preference, notification_preferences, } from 'common/user-notification-preferences' -import { Fragment, useCallback, useEffect, useMemo, useState } from 'react' -import { NoSEO } from 'web/components/NoSEO' -import { Col } from 'web/components/layout/col' -import { UncontrolledTabs } from 'web/components/layout/tabs' -import { LovePage } from 'web/components/love-page' -import { NotificationItem } from 'web/components/notification-items' -import { LoadingIndicator } from 'web/components/widgets/loading-indicator' -import { Pagination } from 'web/components/widgets/pagination' -import { Title } from 'web/components/widgets/title' -import { useGroupedNotifications } from 'web/hooks/use-notifications' -import { usePrivateUser, useUser } from 'web/hooks/use-user' -import { api } from 'web/lib/api' -import { MultiSelectAnswers } from 'web/components/answers/answer-compatibility-question-content' -import { usePersistentInMemoryState } from 'web/hooks/use-persistent-in-memory-state' -import { debounce } from 'lodash' +import {Fragment, useCallback, useEffect, useMemo, useState} from 'react' +import {NoSEO} from 'web/components/NoSEO' +import {Col} from 'web/components/layout/col' +import {UncontrolledTabs} from 'web/components/layout/tabs' +import {LovePage} from 'web/components/love-page' +import {NotificationItem} from 'web/components/notification-items' +import {CompassLoadingIndicator, LoadingIndicator} from 'web/components/widgets/loading-indicator' +import {Pagination} from 'web/components/widgets/pagination' +import {Title} from 'web/components/widgets/title' +import {useGroupedNotifications} from 'web/hooks/use-notifications' +import {usePrivateUser, useUser} from 'web/hooks/use-user' +import {api} from 'web/lib/api' +import {MultiSelectAnswers} from 'web/components/answers/answer-compatibility-question-content' +import {usePersistentInMemoryState} from 'web/hooks/use-persistent-in-memory-state' +import {debounce} from 'lodash' import {useRedirectIfSignedOut} from "web/hooks/use-redirect-if-signed-out"; export default function NotificationsPage() { useRedirectIfSignedOut() return ( - + Updates }, - { title: 'Settings', content: }, + {title: 'Notifications', content: }, + {title: 'Settings', content: }, ]} trackingName={'notifications page'} /> @@ -45,15 +41,15 @@ export default function NotificationsPage() { const NotificationsContent = () => { const user = useUser() - if (!user) return - return + if (!user) return + return } function LoadedNotificationsContent(props: { user: User }) { - const { user } = props + const {user} = props const privateUser = usePrivateUser() - const { groupedNotifications, mostRecentNotification } = + const {groupedNotifications, mostRecentNotification} = useGroupedNotifications(user, NOTIFICATION_TYPES_TO_SELECT) const [page, setPage] = useState(0) @@ -67,7 +63,7 @@ function LoadedNotificationsContent(props: { user: User }) { // Mark all notifications as seen. Rerun as new notifications come in. useEffect(() => { if (!privateUser) return - api('mark-all-notifs-read', { seen: true }) + api('mark-all-notifs-read', {seen: true}) groupedNotifications ?.map((ng) => ng.notifications) .flat() @@ -81,7 +77,7 @@ function LoadedNotificationsContent(props: { user: User }) { {groupedNotifications === undefined || paginatedGroupedNotifications === undefined ? ( - + ) : paginatedGroupedNotifications.length === 0 ? (
You don't have any notifications, yet.
) : ( @@ -109,15 +105,15 @@ function RenderNotificationGroups(props: { page: number setPage: (page: number) => void }) { - const { notificationGroups, page, setPage, totalItems } = props + const {notificationGroups, page, setPage, totalItems} = props return ( <> {notificationGroups.map((notification) => { return notification.notifications.map((notification: Notification) => ( - -
+ +
)) })} @@ -138,11 +134,11 @@ function RenderNotificationGroups(props: { const NotificationSettings = () => { const privateUser = usePrivateUser() if (!privateUser) return null - return + return } const LoadedNotificationSettings = (props: { privateUser: PrivateUser }) => { - const { privateUser } = props + const {privateUser} = props const [prefs, setPrefs] = usePersistentInMemoryState( @@ -197,14 +193,14 @@ const LoadedNotificationSettings = (props: { privateUser: PrivateUser }) => { return (
- {notificationTypes.map(({ type, question }) => ( + {notificationTypes.map(({type, question}) => ( { - setPrefs((prevPrefs) => ({ ...prevPrefs, [type]: selected })) + setPrefs((prevPrefs) => ({...prevPrefs, [type]: selected})) }} /> ))} @@ -219,7 +215,7 @@ const NotificationOption = (props: { selected: notification_destination_types[] onUpdate: (selected: notification_destination_types[]) => void }) => { - const { type, question, selected, onUpdate } = props + const {type, question, selected, onUpdate} = props const getSelectedValues = (destinations: string[]) => { const values: number[] = [] diff --git a/web/pages/signup.tsx b/web/pages/signup.tsx index 35e0392d..c9a322b2 100644 --- a/web/pages/signup.tsx +++ b/web/pages/signup.tsx @@ -3,7 +3,7 @@ import {Col} from 'web/components/layout/col' import {initialRequiredState, RequiredLoveUserForm,} from 'web/components/required-profile-form' import {OptionalLoveUserForm} from 'web/components/optional-profile-form' import {useUser} from 'web/hooks/use-user' -import {LoadingIndicator} from 'web/components/widgets/loading-indicator' +import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' import {CACHED_REFERRAL_USERNAME_KEY,} from 'web/lib/firebase/users' import {api} from 'web/lib/api' import Router, {useRouter} from 'next/router' @@ -114,7 +114,7 @@ export default function SignupPage() { ) : step === 1 ? ( <> ) : ( - + )} )}