Integrate notifications into the design system

This commit is contained in:
Paul Frazee 2022-12-30 13:34:10 -06:00
parent 9084e0e4a8
commit 58a591f314
3 changed files with 45 additions and 35 deletions

View file

@ -14,6 +14,7 @@ import {ErrorMessage} from '../util/error/ErrorMessage'
import {Post} from '../post/Post' import {Post} from '../post/Post'
import {Link} from '../util/Link' import {Link} from '../util/Link'
import {InviteAccepter} from './InviteAccepter' import {InviteAccepter} from './InviteAccepter'
import {usePalette} from '../../lib/hooks/usePalette'
const MAX_AUTHORS = 8 const MAX_AUTHORS = 8
@ -22,6 +23,7 @@ export const FeedItem = observer(function FeedItem({
}: { }: {
item: NotificationsViewItemModel item: NotificationsViewItemModel
}) { }) {
const pal = usePalette('default')
const itemHref = useMemo(() => { const itemHref = useMemo(() => {
if (item.isUpvote || item.isRepost || item.isTrend) { if (item.isUpvote || item.isRepost || item.isTrend) {
const urip = new AtUri(item.subjectUri) const urip = new AtUri(item.subjectUri)
@ -55,7 +57,14 @@ export const FeedItem = observer(function FeedItem({
<Post <Post
uri={item.uri} uri={item.uri}
initView={item.additionalPost} initView={item.additionalPost}
style={[item.isRead ? undefined : styles.outerUnread]} style={
item.isRead
? undefined
: [
styles.outerUnread,
{backgroundColor: pal.colors.unreadNotifBg},
]
}
/> />
</Link> </Link>
) )
@ -117,7 +126,14 @@ export const FeedItem = observer(function FeedItem({
return ( return (
<Link <Link
style={[styles.outer, item.isRead ? undefined : styles.outerUnread]} style={[
styles.outer,
pal.view,
pal.border,
item.isRead
? undefined
: [styles.outerUnread, {backgroundColor: pal.colors.unreadNotifBg}],
]}
href={itemHref} href={itemHref}
title={itemTitle} title={itemTitle}
noFeedback> noFeedback>
@ -150,36 +166,36 @@ export const FeedItem = observer(function FeedItem({
</Link> </Link>
))} ))}
{authors.length > MAX_AUTHORS ? ( {authors.length > MAX_AUTHORS ? (
<Text style={styles.aviExtraCount}> <Text style={[styles.aviExtraCount, pal.textLight]}>
+{authors.length - MAX_AUTHORS} +{authors.length - MAX_AUTHORS}
</Text> </Text>
) : undefined} ) : undefined}
</View> </View>
<View style={styles.meta}> <View style={styles.meta}>
{item.isTrend && ( {item.isTrend && (
<Text style={[styles.metaItem, s.f15]}>{action}</Text> <Text style={[styles.metaItem, pal.text]}>{action}</Text>
)} )}
<Link <Link
key={authors[0].href} key={authors[0].href}
style={styles.metaItem} style={styles.metaItem}
href={authors[0].href} href={authors[0].href}
title={`@${authors[0].handle}`}> title={`@${authors[0].handle}`}>
<Text style={[s.f15, s.bold, s.black]}> <Text style={[pal.text, s.bold]}>
{authors[0].displayName || authors[0].handle} {authors[0].displayName || authors[0].handle}
</Text> </Text>
</Link> </Link>
{authors.length > 1 ? ( {authors.length > 1 ? (
<> <>
<Text style={[styles.metaItem, s.f15]}>and</Text> <Text style={[styles.metaItem, pal.text]}>and</Text>
<Text style={[styles.metaItem, s.f15, s.bold]}> <Text style={[styles.metaItem, pal.text, s.bold]}>
{authors.length - 1} {pluralize(authors.length - 1, 'other')} {authors.length - 1} {pluralize(authors.length - 1, 'other')}
</Text> </Text>
</> </>
) : undefined} ) : undefined}
{!item.isTrend && ( {!item.isTrend && (
<Text style={[styles.metaItem, s.f15]}>{action}</Text> <Text style={[styles.metaItem, pal.text]}>{action}</Text>
)} )}
<Text style={[styles.metaItem, s.f15, s.gray5]}> <Text style={[styles.metaItem, pal.textLight]}>
{ago(item.indexedAt)} {ago(item.indexedAt)}
</Text> </Text>
</View> </View>
@ -204,6 +220,7 @@ function AdditionalPostText({
}: { }: {
additionalPost?: PostThreadViewModel additionalPost?: PostThreadViewModel
}) { }) {
const pal = usePalette('default')
if (!additionalPost) { if (!additionalPost) {
return <View /> return <View />
} }
@ -211,20 +228,16 @@ function AdditionalPostText({
return <ErrorMessage message={additionalPost.error} /> return <ErrorMessage message={additionalPost.error} />
} }
return ( return (
<Text style={[s.gray5]}>{additionalPost.thread?.post.record.text}</Text> <Text style={pal.textLight}>{additionalPost.thread?.post.record.text}</Text>
) )
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
outer: { outer: {
backgroundColor: colors.white,
padding: 10, padding: 10,
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: colors.gray2,
}, },
outerUnread: { outerUnread: {
backgroundColor: colors.unreadNotifBg,
borderWidth: 1,
borderColor: colors.blue1, borderColor: colors.blue1,
}, },
layout: { layout: {
@ -245,7 +258,6 @@ const styles = StyleSheet.create({
aviExtraCount: { aviExtraCount: {
fontWeight: 'bold', fontWeight: 'bold',
paddingLeft: 6, paddingLeft: 6,
color: colors.gray5,
}, },
layoutContent: { layoutContent: {
flex: 1, flex: 1,
@ -258,7 +270,6 @@ const styles = StyleSheet.create({
}, },
metaItem: { metaItem: {
paddingRight: 3, paddingRight: 3,
color: colors.black,
}, },
postText: { postText: {
paddingBottom: 5, paddingBottom: 5,

View file

@ -23,6 +23,7 @@ import * as Toast from '../util/Toast'
import {UserAvatar} from '../util/UserAvatar' import {UserAvatar} from '../util/UserAvatar'
import {useStores} from '../../../state' import {useStores} from '../../../state'
import {s, colors} from '../../lib/styles' import {s, colors} from '../../lib/styles'
import {usePalette} from '../../lib/hooks/usePalette'
export const Post = observer(function Post({ export const Post = observer(function Post({
uri, uri,
@ -35,6 +36,7 @@ export const Post = observer(function Post({
showReplyLine?: boolean showReplyLine?: boolean
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
}) { }) {
const pal = usePalette('default')
const store = useStores() const store = useStores()
const [view, setView] = useState<PostThreadViewModel | undefined>(initView) const [view, setView] = useState<PostThreadViewModel | undefined>(initView)
const [deleted, setDeleted] = useState(false) const [deleted, setDeleted] = useState(false)
@ -58,7 +60,7 @@ export const Post = observer(function Post({
// = // =
if (!view || view.isLoading || view.params.uri !== uri) { if (!view || view.isLoading || view.params.uri !== uri) {
return ( return (
<View> <View style={pal.view}>
<ActivityIndicator /> <ActivityIndicator />
</View> </View>
) )
@ -68,7 +70,7 @@ export const Post = observer(function Post({
// = // =
if (view.hasError || !view.thread) { if (view.hasError || !view.thread) {
return ( return (
<View> <View style={pal.view}>
<Text>{view.error || 'Thread not found'}</Text> <Text>{view.error || 'Thread not found'}</Text>
</View> </View>
) )
@ -134,7 +136,7 @@ export const Post = observer(function Post({
return ( return (
<Link <Link
style={[styles.outer, style]} style={[styles.outer, pal.view, pal.border, style]}
href={itemHref} href={itemHref}
title={itemTitle} title={itemTitle}
noFeedback> noFeedback>
@ -164,12 +166,19 @@ export const Post = observer(function Post({
/> />
{replyHref !== '' && ( {replyHref !== '' && (
<View style={[s.flexRow, s.mb2, {alignItems: 'center'}]}> <View style={[s.flexRow, s.mb2, {alignItems: 'center'}]}>
<FontAwesomeIcon icon="reply" size={9} style={[s.gray4, s.mr5]} /> <FontAwesomeIcon
<Text style={[s.gray4, s.f12, s.mr2]}>Reply to</Text> icon="reply"
size={9}
style={[pal.textLight, s.mr5]}
/>
<Text type="body2" style={[pal.textLight, s.mr2]}>
Reply to
</Text>
<Link href={replyHref} title="Parent post"> <Link href={replyHref} title="Parent post">
<UserInfoText <UserInfoText
type="body2"
did={replyAuthorDid} did={replyAuthorDid}
style={[s.f12, s.gray5]} style={[pal.textLight]}
prefix="@" prefix="@"
/> />
</Link> </Link>
@ -177,11 +186,7 @@ export const Post = observer(function Post({
)} )}
{record.text ? ( {record.text ? (
<View style={styles.postTextContainer}> <View style={styles.postTextContainer}>
<RichText <RichText text={record.text} entities={record.entities} />
text={record.text}
entities={record.entities}
style={styles.postText}
/>
</View> </View>
) : ( ) : (
<View style={{height: 5}} /> <View style={{height: 5}} />
@ -205,10 +210,8 @@ export const Post = observer(function Post({
const styles = StyleSheet.create({ const styles = StyleSheet.create({
outer: { outer: {
backgroundColor: colors.white,
padding: 10, padding: 10,
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: colors.gray2,
}, },
layout: { layout: {
flexDirection: 'row', flexDirection: 'row',
@ -225,12 +228,6 @@ const styles = StyleSheet.create({
flexWrap: 'wrap', flexWrap: 'wrap',
paddingBottom: 8, paddingBottom: 8,
}, },
postText: {
fontFamily: 'System',
fontSize: 16,
lineHeight: 20.8, // 1.3 of 16px
color: colors.black,
},
replyLine: { replyLine: {
position: 'absolute', position: 'absolute',
left: 36, left: 36,

View file

@ -18,6 +18,7 @@ export const defaultTheme: Theme = {
actionLabel: colors.gray4, actionLabel: colors.gray4,
replyLine: colors.gray2, replyLine: colors.gray2,
replyLineDot: colors.gray3, replyLineDot: colors.gray3,
unreadNotifBg: '#ebf6ff',
}, },
primary: { primary: {
background: colors.blue3, background: colors.blue3,
@ -157,6 +158,7 @@ export const darkTheme: Theme = {
actionLabel: colors.gray3, actionLabel: colors.gray3,
replyLine: colors.gray5, replyLine: colors.gray5,
replyLineDot: colors.gray6, replyLineDot: colors.gray6,
unreadNotifBg: colors.blue5,
}, },
primary: { primary: {
...defaultTheme.palette.primary, ...defaultTheme.palette.primary,