Notifications reverted ux (#386)

* Revert "Revert "Notifications ux fixes - wip (#383)""

This reverts commit 699b03eb42.

* <p>=><div>
This commit is contained in:
Ian Philips 2022-06-01 12:26:41 -06:00 committed by GitHub
parent 699b03eb42
commit 78a359407d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 34 deletions

View File

@ -65,7 +65,8 @@ export const createNotification = async (
// TODO: Update for liquidity. // TODO: Update for liquidity.
// TODO: Find tagged users. // TODO: Find tagged users.
// TODO: Find replies to comments. // TODO: Find replies to comments.
// TODO: Filter bets for only open bets // TODO: Filter bets for only open bets.
// TODO: Notify users of their own closed but not resolved contracts.
if ( if (
sourceType === 'comment' || sourceType === 'comment' ||
sourceType === 'answer' || sourceType === 'answer' ||

View File

@ -8,13 +8,15 @@ import Link from 'next/link'
import { fromNow } from 'web/lib/util/time' import { fromNow } from 'web/lib/util/time'
import { ToastClipboard } from 'web/components/toast-clipboard' import { ToastClipboard } from 'web/components/toast-clipboard'
import { LinkIcon } from '@heroicons/react/outline' import { LinkIcon } from '@heroicons/react/outline'
import clsx from 'clsx'
export function CopyLinkDateTimeComponent(props: { export function CopyLinkDateTimeComponent(props: {
contract: Contract contract: Contract
createdTime: number createdTime: number
elementId: string elementId: string
className?: string
}) { }) {
const { contract, elementId, createdTime } = props const { contract, elementId, createdTime, className } = props
const [showToast, setShowToast] = useState(false) const [showToast, setShowToast] = useState(false)
function copyLinkToComment( function copyLinkToComment(
@ -30,7 +32,7 @@ export function CopyLinkDateTimeComponent(props: {
setTimeout(() => setShowToast(false), 2000) setTimeout(() => setShowToast(false), 2000)
} }
return ( return (
<> <div className={clsx('inline', className)}>
<DateTimeTooltip time={createdTime}> <DateTimeTooltip time={createdTime}>
<Link <Link
href={`/${contract.creatorUsername}/${contract.slug}#${elementId}`} href={`/${contract.creatorUsername}/${contract.slug}#${elementId}`}
@ -53,6 +55,6 @@ export function CopyLinkDateTimeComponent(props: {
</a> </a>
</Link> </Link>
</DateTimeTooltip> </DateTimeTooltip>
</> </div>
) )
} }

View File

@ -166,7 +166,7 @@ export function FeedComment(props: {
avatarUrl={userAvatarUrl} avatarUrl={userAvatarUrl}
/> />
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<p className="mt-0.5 pl-0.5 text-sm text-gray-500"> <div className="mt-0.5 pl-0.5 text-sm text-gray-500">
<UserLink <UserLink
className="text-gray-500" className="text-gray-500"
username={userUsername} username={userUsername}
@ -204,7 +204,7 @@ export function FeedComment(props: {
createdTime={createdTime} createdTime={createdTime}
elementId={comment.id} elementId={comment.id}
/> />
</p> </div>
<TruncatedComment <TruncatedComment
comment={text} comment={text}
moreHref={contractPath(contract)} moreHref={contractPath(contract)}

View File

@ -1,7 +1,11 @@
import { Tabs } from 'web/components/layout/tabs' import { Tabs } from 'web/components/layout/tabs'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { Notification } from 'common/notification' import {
Notification,
notification_reason_types,
notification_source_types,
} from 'common/notification'
import { listenForNotifications } from 'web/lib/firebase/notifications' import { listenForNotifications } from 'web/lib/firebase/notifications'
import { Avatar } from 'web/components/avatar' import { Avatar } from 'web/components/avatar'
import { Row } from 'web/components/layout/row' import { Row } from 'web/components/layout/row'
@ -15,9 +19,9 @@ import { Comment } from 'web/lib/firebase/comments'
import { getValue } from 'web/lib/firebase/utils' import { getValue } from 'web/lib/firebase/utils'
import Custom404 from 'web/pages/404' import Custom404 from 'web/pages/404'
import { UserLink } from 'web/components/user-page' import { UserLink } from 'web/components/user-page'
import { Linkify } from 'web/components/linkify'
import { User } from 'common/user' import { User } from 'common/user'
import { useContract } from 'web/hooks/use-contract' import { useContract } from 'web/hooks/use-contract'
import { Contract } from 'common/contract'
export default function Notifications() { export default function Notifications() {
const user = useUser() const user = useUser()
@ -37,8 +41,8 @@ export default function Notifications() {
// TODO: use infinite scroll // TODO: use infinite scroll
return ( return (
<Page> <Page>
<div className={'p-4'}> <div className={'p-2 sm:p-4'}>
<Title text={'Notifications'} /> <Title text={'Notifications'} className={'hidden md:block'} />
<Tabs <Tabs
className={'pb-2 pt-1 '} className={'pb-2 pt-1 '}
defaultIndex={0} defaultIndex={0}
@ -79,6 +83,7 @@ function Notification(props: {
sourceUserName, sourceUserName,
sourceUserAvatarUrl, sourceUserAvatarUrl,
reasonText, reasonText,
reason,
sourceUserUsername, sourceUserUsername,
createdTime, createdTime,
} = notification } = notification
@ -140,7 +145,7 @@ function Notification(props: {
} }
return ( return (
<div className={' bg-white px-4 pt-6'}> <div className={'bg-white px-1 pt-6 text-sm sm:px-4'}>
<Row className={'items-center text-gray-500 sm:justify-start'}> <Row className={'items-center text-gray-500 sm:justify-start'}>
<Avatar <Avatar
avatarUrl={sourceUserAvatarUrl} avatarUrl={sourceUserAvatarUrl}
@ -148,35 +153,47 @@ function Notification(props: {
className={'mr-2'} className={'mr-2'}
username={sourceUserName} username={sourceUserName}
/> />
<div className={'flex-1'}> <div className={'flex-1 overflow-hidden sm:flex'}>
<UserLink <div
name={sourceUserName || ''} className={
username={sourceUserUsername || ''} 'flex max-w-sm shrink overflow-hidden text-ellipsis sm:max-w-md'
className={'mr-0 flex-shrink-0'} }
/> >
<a href={getSourceUrl(sourceId)} className={'flex-1 pl-1'}> <UserLink
{reasonText} name={sourceUserName || ''}
{contract && sourceId && ( username={sourceUserUsername || ''}
<div className={'inline'}> className={'mr-0 flex-shrink-0'}
<CopyLinkDateTimeComponent />
contract={contract} <a
createdTime={createdTime} href={getSourceUrl(sourceId)}
elementId={getSourceIdForLinkComponent(sourceId)} className={'inline-flex overflow-hidden text-ellipsis pl-1'}
/> >
</div> {sourceType && reason ? (
)} <div className={'inline truncate'}>
</a> {getReasonTextFromReason(sourceType, reason, contract)}
</div>
) : (
reasonText
)}
</a>
</div>
{contract && sourceId && (
<CopyLinkDateTimeComponent
contract={contract}
createdTime={createdTime}
elementId={getSourceIdForLinkComponent(sourceId)}
className={'-mx-1 inline-flex sm:inline-block'}
/>
)}
</div> </div>
</Row> </Row>
<a href={getSourceUrl(sourceId)}> <a href={getSourceUrl(sourceId)}>
<div className={'ml-4 mt-1'}> <div className={'mt-1 md:text-base'}>
{' '} {' '}
{contract && subText === contract.question ? ( {contract && subText === contract.question ? (
<div className={'text-md text-indigo-700 hover:underline'}> <div className={'text-indigo-700 hover:underline'}>{subText}</div>
{subText}
</div>
) : ( ) : (
<Linkify text={subText} /> <div className={'line-clamp-4 whitespace-pre-line'}>{subText}</div>
)} )}
</div> </div>
@ -185,3 +202,20 @@ function Notification(props: {
</div> </div>
) )
} }
function getReasonTextFromReason(
source: notification_source_types,
reason: notification_reason_types,
contract: Contract | undefined
) {
switch (source) {
case 'comment':
return `commented on ${contract?.question}`
case 'contract':
return `${reason} ${contract?.question}`
case 'answer':
return `answered ${contract?.question}`
default:
return ''
}
}