mirror of
https://github.com/zhigang1992/devhub.git
synced 2026-06-12 16:18:49 +08:00
Show message about private notification support on private notifications
Also disable private filter
This commit is contained in:
@@ -14,6 +14,8 @@ import {
|
||||
isNotificationPrivate,
|
||||
trimNewLinesAndSpaces,
|
||||
} from '@devhub/core'
|
||||
import { useReduxState } from '../../hooks/use-redux-state'
|
||||
import * as selectors from '../../redux/selectors'
|
||||
import { contentPadding } from '../../styles/variables'
|
||||
import {
|
||||
getIssueIconAndColor,
|
||||
@@ -46,6 +48,9 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => {
|
||||
const { notification, onlyOneRepository } = props
|
||||
|
||||
const springAnimatedTheme = useSpringAnimatedTheme()
|
||||
const hasPrivateAccess = useReduxState(
|
||||
selectors.githubHasPrivateAccessSelector,
|
||||
)
|
||||
|
||||
if (!notification) return null
|
||||
|
||||
@@ -351,6 +356,21 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => {
|
||||
username={comment.user.login}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!!(isPrivate && !hasPrivateAccess && !notification.enhanced) && (
|
||||
<CommentRow
|
||||
key={`notification-privacy-support-row-${notification.id}`}
|
||||
analyticsLabel="about_private_access_from_notification"
|
||||
avatarURL={undefined}
|
||||
body="Coming soon: support for private notifications. Click here and subscribe to this issue if you want to be notified."
|
||||
isRead
|
||||
smallLeftColumn={smallLeftColumn}
|
||||
url="https://github.com/devhubapp/devhub/issues/32"
|
||||
userLinkURL={undefined}
|
||||
username={undefined}
|
||||
textStyle={{ fontStyle: 'italic' }}
|
||||
/>
|
||||
)}
|
||||
</SpringAnimatedView>
|
||||
)
|
||||
})
|
||||
|
||||
@@ -6,36 +6,41 @@ import { useCSSVariablesOrSpringAnimatedTheme } from '../../../../hooks/use-css-
|
||||
import { Platform } from '../../../../libs/platform'
|
||||
import { parseTextWithEmojisToReactComponents } from '../../../../utils/helpers/github/emojis'
|
||||
import { fixURL } from '../../../../utils/helpers/github/url'
|
||||
import { SpringAnimatedText } from '../../../animated/spring/SpringAnimatedText'
|
||||
import {
|
||||
SpringAnimatedText,
|
||||
SpringAnimatedTextProps,
|
||||
} from '../../../animated/spring/SpringAnimatedText'
|
||||
import { Avatar } from '../../../common/Avatar'
|
||||
import { Link } from '../../../common/Link'
|
||||
import { Link, LinkProps } from '../../../common/Link'
|
||||
import { cardStyles, getCardStylesForTheme } from '../../styles'
|
||||
import { cardRowStyles } from './styles'
|
||||
|
||||
export interface CommentRowProps {
|
||||
addBottomAnchor?: boolean
|
||||
avatarURL: string
|
||||
analyticsLabel?: LinkProps['analyticsLabel']
|
||||
avatarURL: string | undefined
|
||||
body: string
|
||||
isRead: boolean
|
||||
numberOfLines?: number
|
||||
smallLeftColumn?: boolean
|
||||
textStyle?: SpringAnimatedTextProps['style']
|
||||
url?: string
|
||||
userLinkURL: string
|
||||
username: string
|
||||
userLinkURL: string | undefined
|
||||
username: string | undefined
|
||||
}
|
||||
|
||||
export interface CommentRowState {}
|
||||
|
||||
export const CommentRow = React.memo((props: CommentRowProps) => {
|
||||
const springAnimatedTheme = useCSSVariablesOrSpringAnimatedTheme()
|
||||
|
||||
const {
|
||||
addBottomAnchor,
|
||||
analyticsLabel,
|
||||
avatarURL,
|
||||
body: _body,
|
||||
isRead,
|
||||
numberOfLines = 3,
|
||||
smallLeftColumn,
|
||||
textStyle,
|
||||
url,
|
||||
userLinkURL,
|
||||
username,
|
||||
@@ -72,6 +77,7 @@ export const CommentRow = React.memo((props: CommentRowProps) => {
|
||||
|
||||
<View style={cardStyles.rightColumn}>
|
||||
<Link
|
||||
analyticsLabel={analyticsLabel}
|
||||
href={fixURL(url, { addBottomAnchor })}
|
||||
style={cardRowStyles.mainContentContainer}
|
||||
>
|
||||
@@ -79,6 +85,7 @@ export const CommentRow = React.memo((props: CommentRowProps) => {
|
||||
numberOfLines={numberOfLines}
|
||||
style={[
|
||||
getCardStylesForTheme(springAnimatedTheme).commentText,
|
||||
textStyle,
|
||||
isRead && getCardStylesForTheme(springAnimatedTheme).mutedText,
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -29,7 +29,7 @@ import { cardRowStyles } from './styles'
|
||||
|
||||
export interface IssueOrPullRequestRowProps {
|
||||
addBottomAnchor?: boolean
|
||||
avatarURL: string
|
||||
avatarURL: string | undefined
|
||||
commentsCount?: number
|
||||
createdAt: string | undefined
|
||||
iconColor?: string
|
||||
@@ -43,8 +43,8 @@ export interface IssueOrPullRequestRowProps {
|
||||
smallLeftColumn?: boolean
|
||||
title: string
|
||||
url: string
|
||||
userLinkURL: string
|
||||
username: string
|
||||
userLinkURL: string | undefined
|
||||
username: string | undefined
|
||||
}
|
||||
|
||||
export const IssueOrPullRequestRow = React.memo(
|
||||
@@ -75,7 +75,8 @@ export const IssueOrPullRequestRow = React.memo(
|
||||
if (!title) return null
|
||||
|
||||
const isBot = Boolean(_username && _username.indexOf('[bot]') >= 0)
|
||||
const username = isBot ? _username.replace('[bot]', '') : _username
|
||||
const username =
|
||||
isBot && _username ? _username.replace('[bot]', '') : _username
|
||||
|
||||
const byText = username ? `@${username}` : ''
|
||||
|
||||
@@ -165,87 +166,106 @@ export const IssueOrPullRequestRow = React.memo(
|
||||
</>
|
||||
)}
|
||||
|
||||
<Spacer height={contentPadding / 2} />
|
||||
{!!(
|
||||
byText ||
|
||||
createdAt ||
|
||||
commentsCount ||
|
||||
issueOrPullRequestNumber
|
||||
) && (
|
||||
<>
|
||||
<Spacer height={contentPadding / 2} />
|
||||
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
{!!byText && (
|
||||
<Link href={userLinkURL || getGitHubURLForUser(username)}>
|
||||
<SpringAnimatedText
|
||||
style={[
|
||||
getCardStylesForTheme(springAnimatedTheme).normalText,
|
||||
cardStyles.smallText,
|
||||
getCardStylesForTheme(springAnimatedTheme).mutedText,
|
||||
]}
|
||||
>
|
||||
{byText}
|
||||
</SpringAnimatedText>
|
||||
</Link>
|
||||
)}
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
{!!byText && (
|
||||
<Link
|
||||
href={
|
||||
userLinkURL ||
|
||||
(username && getGitHubURLForUser(username))
|
||||
}
|
||||
>
|
||||
<SpringAnimatedText
|
||||
style={[
|
||||
getCardStylesForTheme(springAnimatedTheme)
|
||||
.normalText,
|
||||
cardStyles.smallText,
|
||||
getCardStylesForTheme(springAnimatedTheme)
|
||||
.mutedText,
|
||||
]}
|
||||
>
|
||||
{byText}
|
||||
</SpringAnimatedText>
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{!!createdAt && (
|
||||
<IntervalRefresh date={createdAt}>
|
||||
{() => {
|
||||
const dateText = getDateSmallText(createdAt, false)
|
||||
if (!dateText) return null
|
||||
{!!createdAt && (
|
||||
<IntervalRefresh date={createdAt}>
|
||||
{() => {
|
||||
const dateText = getDateSmallText(createdAt, false)
|
||||
if (!dateText) return null
|
||||
|
||||
return (
|
||||
<>
|
||||
{!!byText && <Text children=" " />}
|
||||
return (
|
||||
<>
|
||||
{!!byText && <Text children=" " />}
|
||||
|
||||
<SpringAnimatedText
|
||||
numberOfLines={1}
|
||||
style={
|
||||
getCardStylesForTheme(springAnimatedTheme)
|
||||
.timestampText
|
||||
}
|
||||
{...Platform.select({
|
||||
web: { title: getFullDateText(createdAt) },
|
||||
})}
|
||||
>
|
||||
{!!byText && (
|
||||
<>
|
||||
<Text children="•" style={{ fontSize: 9 }} />
|
||||
<Text children=" " />
|
||||
</>
|
||||
)}
|
||||
<SpringAnimatedText
|
||||
numberOfLines={1}
|
||||
style={
|
||||
getCardStylesForTheme(springAnimatedTheme)
|
||||
.timestampText
|
||||
}
|
||||
{...Platform.select({
|
||||
web: { title: getFullDateText(createdAt) },
|
||||
})}
|
||||
>
|
||||
{!!byText && (
|
||||
<>
|
||||
<Text
|
||||
children="•"
|
||||
style={{ fontSize: 9 }}
|
||||
/>
|
||||
<Text children=" " />
|
||||
</>
|
||||
)}
|
||||
|
||||
{dateText}
|
||||
</SpringAnimatedText>
|
||||
</>
|
||||
)
|
||||
}}
|
||||
</IntervalRefresh>
|
||||
)}
|
||||
{dateText}
|
||||
</SpringAnimatedText>
|
||||
</>
|
||||
)
|
||||
}}
|
||||
</IntervalRefresh>
|
||||
)}
|
||||
|
||||
<Spacer flex={1} />
|
||||
<Spacer flex={1} />
|
||||
|
||||
{typeof commentsCount === 'number' && commentsCount >= 0 && (
|
||||
<>
|
||||
<Spacer width={contentPadding / 2} />
|
||||
|
||||
<CardSmallThing
|
||||
icon="comment"
|
||||
isRead={isRead}
|
||||
text={commentsCount}
|
||||
url={fixURL(url, {
|
||||
addBottomAnchor,
|
||||
issueOrPullRequestNumber,
|
||||
})}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{typeof commentsCount === 'number' && commentsCount >= 0 && (
|
||||
<>
|
||||
<Spacer width={contentPadding / 2} />
|
||||
|
||||
<CardSmallThing
|
||||
icon="comment"
|
||||
<CardItemId
|
||||
id={issueOrPullRequestNumber}
|
||||
isRead={isRead}
|
||||
text={commentsCount}
|
||||
url={fixURL(url, {
|
||||
addBottomAnchor,
|
||||
issueOrPullRequestNumber,
|
||||
})}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Spacer width={contentPadding / 2} />
|
||||
|
||||
<CardItemId
|
||||
id={issueOrPullRequestNumber}
|
||||
isRead={isRead}
|
||||
url={fixURL(url, {
|
||||
addBottomAnchor,
|
||||
issueOrPullRequestNumber,
|
||||
})}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -360,7 +360,7 @@ export const ColumnOptions = React.memo((props: ColumnOptionsProps) => {
|
||||
{(() => {
|
||||
const isPrivateChecked =
|
||||
column.type === 'notifications'
|
||||
? !(column.filters && column.filters.private === false)
|
||||
? column.filters && column.filters.private === true
|
||||
: hasPrivateAccess &&
|
||||
!(column.filters && column.filters.private === false)
|
||||
|
||||
@@ -368,8 +368,7 @@ export const ColumnOptions = React.memo((props: ColumnOptionsProps) => {
|
||||
column.filters && column.filters.private === true
|
||||
)
|
||||
|
||||
const canShowPrivateContent =
|
||||
hasPrivateAccess || column.type === 'notifications'
|
||||
const canShowPrivateContent = hasPrivateAccess // || column.type === 'notifications'
|
||||
|
||||
if (!canShowPrivateContent && !isPrivateChecked) return null
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ export function AddColumnModal(props: AddColumnModalProps) {
|
||||
<Spacer flex={1} minHeight={contentPadding} />
|
||||
|
||||
<Link
|
||||
analyticsLabel="about-private-access"
|
||||
analyticsLabel="about_private_access_from_addcolumn"
|
||||
href="https://github.com/devhubapp/devhub/issues/32"
|
||||
openOnNewTab
|
||||
>
|
||||
@@ -353,8 +353,8 @@ export function AddColumnModal(props: AddColumnModalProps) {
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
Support for private repositories is coming soon! Subscribe to this
|
||||
issue if you want to be notified.
|
||||
Coming soon: support for private repositories. Click here and
|
||||
subscribe to this issue if you want to be notified.
|
||||
</SpringAnimatedText>
|
||||
</Link>
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ export const appTokenSelector = (state: RootState) => s(state).appToken
|
||||
export const githubScopeSelector = (state: RootState) =>
|
||||
s(state).user && s(state).user!.github.scope
|
||||
|
||||
export const githubHasPrivateAccessSelector = (state: RootState) =>
|
||||
!!githubScopeSelector(state) && githubScopeSelector(state)!.includes('repo')
|
||||
// TODO: Support private repositories after migrating to GitHub App
|
||||
// @see https://github.com/devhubapp/devhub/issues/32
|
||||
export const githubHasPrivateAccessSelector = (_state: RootState) => false
|
||||
|
||||
export const githubTokenSelector = (state: RootState) =>
|
||||
s(state).user && s(state).user!.github.token
|
||||
|
||||
@@ -68,6 +68,7 @@ export async function getNotificationsEnhancementMap(
|
||||
throw new Error('Invalid response')
|
||||
|
||||
enhance[subjectField] = data
|
||||
enhance.enhanced = true
|
||||
cache.set(notification.subject.url, { data, timestamp: Date.now() })
|
||||
} catch (error) {
|
||||
console.error(
|
||||
@@ -80,6 +81,7 @@ export async function getNotificationsEnhancementMap(
|
||||
} else if (hasSubjectCache) {
|
||||
if (subjectCache && subjectCache.data)
|
||||
enhance[subjectField] = subjectCache.data
|
||||
enhance.enhanced = true
|
||||
}
|
||||
|
||||
if (commentId && !hasCommentCache) {
|
||||
@@ -92,6 +94,7 @@ export async function getNotificationsEnhancementMap(
|
||||
if (!(data && data.id)) throw new Error('Invalid response')
|
||||
|
||||
enhance.comment = data
|
||||
enhance.enhanced = true
|
||||
cache.set(notification.subject.latest_comment_url, {
|
||||
data,
|
||||
timestamp: Date.now(),
|
||||
@@ -106,7 +109,10 @@ export async function getNotificationsEnhancementMap(
|
||||
} else if (!commentId) {
|
||||
enhance.comment = undefined
|
||||
} else if (hasCommentCache) {
|
||||
if (commentCache && commentCache.data) enhance.comment = commentCache.data
|
||||
if (commentCache && commentCache.data) {
|
||||
enhance.comment = commentCache.data
|
||||
enhance.enhanced = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!Object.keys(enhance).length) return
|
||||
@@ -151,6 +157,7 @@ export function enhanceNotifications(
|
||||
'issue',
|
||||
'pullRequest',
|
||||
'release',
|
||||
'enhanced',
|
||||
]),
|
||||
...cen,
|
||||
...enhance,
|
||||
|
||||
@@ -35,6 +35,7 @@ export interface NotificationPayloadEnhancement {
|
||||
issue?: GitHubIssue
|
||||
pullRequest?: GitHubPullRequest
|
||||
release?: GitHubRelease
|
||||
enhanced?: boolean
|
||||
}
|
||||
|
||||
export interface EnhancedGitHubNotification
|
||||
|
||||
Reference in New Issue
Block a user