diff --git a/packages/components/src/components/cards/EventCard.tsx b/packages/components/src/components/cards/EventCard.tsx index 606cb6f1..d70877a3 100644 --- a/packages/components/src/components/cards/EventCard.tsx +++ b/packages/components/src/components/cards/EventCard.tsx @@ -78,6 +78,7 @@ export interface EventCardProps { event: EnhancedGitHubEvent isFocused?: boolean repoIsKnown: boolean + swipeable: boolean } export const EventCard = React.memo((props: EventCardProps) => { @@ -85,8 +86,9 @@ export const EventCard = React.memo((props: EventCardProps) => { cardViewMode, enableCompactLabels, event, - repoIsKnown, isFocused, + repoIsKnown, + swipeable, } = props const itemRef = useRef(null) @@ -119,7 +121,10 @@ export const EventCard = React.memo((props: EventCardProps) => { let branchName = getBranchNameFromRef(branchOrTagRef) - const issueOrPullRequest = issue || pullRequest + const issueOrPullRequest = (issue || pullRequest) as + | typeof issue + | typeof pullRequest + | undefined const issueOrPullRequestNumber = issueOrPullRequest ? issueOrPullRequest.number || @@ -237,6 +242,8 @@ export const EventCard = React.memo((props: EventCardProps) => { const avatarUrl = (isBot && botAvatarURL) || actor.avatar_url + const showCardActions = cardViewMode !== 'compact' && !swipeable + let withTopMargin = cardViewMode !== 'compact' let withTopMarginCount = withTopMargin ? 1 : 0 function getWithTopMargin() { @@ -346,7 +353,9 @@ export const EventCard = React.memo((props: EventCardProps) => { } body={issueOrPullRequest.body} bold - commentsCount={issueOrPullRequest.comments} + commentsCount={ + showCardActions ? undefined : issueOrPullRequest.comments + } createdAt={issueOrPullRequest.created_at} hideIcon hideLabelText={false} @@ -604,7 +613,7 @@ export const EventCard = React.memo((props: EventCardProps) => { color: label.color && `#${label.color}`, name: label.name, }))} - // muted={isRead} + muted={isRead} style={{ alignSelf: 'center', justifyContent: 'flex-end', @@ -751,14 +760,27 @@ export const EventCard = React.memo((props: EventCardProps) => { - + {!!showCardActions && ( + <> + - + + + )} diff --git a/packages/components/src/components/cards/EventCards.tsx b/packages/components/src/components/cards/EventCards.tsx index 05eeecd3..95d5f9a4 100644 --- a/packages/components/src/components/cards/EventCards.tsx +++ b/packages/components/src/components/cards/EventCards.tsx @@ -45,7 +45,7 @@ export interface EventCardsProps pointerEvents: FlatListProps['pointerEvents'] refresh: EmptyCardsProps['refresh'] repoIsKnown: boolean - swipeable?: boolean + swipeable: boolean } function keyExtractor(item: EnhancedGitHubEvent, _index: number) { @@ -163,11 +163,12 @@ export const EventCards = React.memo((props: EventCardsProps) => { cardViewMode={cardViewMode} enableCompactLabels={enableCompactLabels} event={item} - repoIsKnown={props.repoIsKnown} isFocused={ column.id === focusedColumnId && item.id === selectedItemIdRef.current } + repoIsKnown={props.repoIsKnown} + swipeable={props.swipeable} /> ) } @@ -183,6 +184,7 @@ export const EventCards = React.memo((props: EventCardsProps) => { item.id === selectedItemIdRef.current } repoIsKnown={props.repoIsKnown} + swipeable={props.swipeable} /> ) diff --git a/packages/components/src/components/cards/IssueOrPullRequestCard.tsx b/packages/components/src/components/cards/IssueOrPullRequestCard.tsx index 2aad655d..e2d68b03 100644 --- a/packages/components/src/components/cards/IssueOrPullRequestCard.tsx +++ b/packages/components/src/components/cards/IssueOrPullRequestCard.tsx @@ -49,6 +49,7 @@ export interface IssueOrPullRequestCardProps { isPrivate?: boolean issueOrPullRequest: EnhancedGitHubIssueOrPullRequest repoIsKnown: boolean + swipeable: boolean type: GitHubIssueOrPullRequestSubjectType } @@ -61,6 +62,7 @@ export const IssueOrPullRequestCard = React.memo( isPrivate, issueOrPullRequest, repoIsKnown, + swipeable, type, } = props @@ -119,6 +121,8 @@ export const IssueOrPullRequestCard = React.memo( const cardIconName = cardIconDetails.icon const cardIconColor = cardIconDetails.color + const showCardActions = cardViewMode !== 'compact' && !swipeable + let withTopMargin = false let withTopMarginCount = withTopMargin ? 1 : 0 function getWithTopMargin() { @@ -158,17 +162,11 @@ export const IssueOrPullRequestCard = React.memo( } body={issueOrPullRequest.body} bold - commentsCount={issueOrPullRequest.comments} - createdAt={ - cardViewMode === 'compact' - ? issueOrPullRequest.created_at - : undefined - } - updatedAt={ - cardViewMode === 'compact' - ? undefined - : issueOrPullRequest.updated_at + commentsCount={ + showCardActions ? undefined : issueOrPullRequest.comments } + createdAt={issueOrPullRequest.created_at} + // updatedAt={issueOrPullRequest.updated_at} hideIcon hideLabelText={false} // iconColor={issueIconColor || pullRequestIconColor} @@ -180,6 +178,56 @@ export const IssueOrPullRequestCard = React.memo( labels={enableCompactLabels ? [] : issueOrPullRequest.labels} owner={repoOwnerName || ''} repo={repoName || ''} + rightTitle={ + !!issueOrPullRequest.updated_at && + cardViewMode !== 'compact' && ( + + + {() => { + const createdAt = issueOrPullRequest.created_at + const updatedAt = issueOrPullRequest.updated_at + + const dateText = getDateSmallText(updatedAt, false) + if (!dateText) return null + + return ( + <> + + {/* {' '} */} + {dateText} + + + ) + }} + + + + + ) + } showBodyRow={ false // issueOrPullRequest && @@ -188,7 +236,7 @@ export const IssueOrPullRequestCard = React.memo( // ? true // : false } - showCreationDetails={cardViewMode !== 'compact'} + showCreationDetails={false} title={issueOrPullRequest.title} url={issueOrPullRequest.url} userLinkURL={issueOrPullRequest.user.html_url || ''} @@ -526,14 +574,26 @@ export const IssueOrPullRequestCard = React.memo( - + {!!showCardActions && ( + <> + - + + + )} diff --git a/packages/components/src/components/cards/IssueOrPullRequestCards.tsx b/packages/components/src/components/cards/IssueOrPullRequestCards.tsx index f2754a25..0f6665e7 100644 --- a/packages/components/src/components/cards/IssueOrPullRequestCards.tsx +++ b/packages/components/src/components/cards/IssueOrPullRequestCards.tsx @@ -51,7 +51,7 @@ export interface IssueOrPullRequestCardsProps loadState: EnhancedLoadState pointerEvents: FlatListProps['pointerEvents'] refresh: EmptyCardsProps['refresh'] - swipeable?: boolean + swipeable: boolean } function keyExtractor(item: EnhancedGitHubIssueOrPullRequest) { @@ -178,6 +178,7 @@ export const IssueOrPullRequestCards = React.memo( } issueOrPullRequest={item} repoIsKnown={props.repoIsKnown} + swipeable={props.swipeable} type={getIssueOrPullRequestSubjectType(item) || 'Issue'} /> ) @@ -194,6 +195,7 @@ export const IssueOrPullRequestCards = React.memo( } issueOrPullRequest={item} repoIsKnown={props.repoIsKnown} + swipeable={props.swipeable} type={getIssueOrPullRequestSubjectType(item) || 'Issue'} /> diff --git a/packages/components/src/components/cards/NotificationCard.tsx b/packages/components/src/components/cards/NotificationCard.tsx index 6495ed03..34ac54b5 100644 --- a/packages/components/src/components/cards/NotificationCard.tsx +++ b/packages/components/src/components/cards/NotificationCard.tsx @@ -58,15 +58,17 @@ export interface NotificationCardProps { isFocused: boolean notification: EnhancedGitHubNotification repoIsKnown: boolean + swipeable: boolean } export const NotificationCard = React.memo((props: NotificationCardProps) => { const { cardViewMode, + enableCompactLabels, isFocused, notification, repoIsKnown, - enableCompactLabels, + swipeable, } = props const repoFullName = @@ -146,6 +148,7 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => { state: undefined, title: subject.title, url: subject.latest_comment_url || subject.url, + html_url: '', user: { avatar_url: '', login: '', html_url: '' }, }) || null @@ -163,6 +166,7 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => { state: undefined, title: subject.title, url: subject.latest_comment_url || subject.url, + html_url: '', user: { avatar_url: '', login: '', html_url: '' }, }) || null @@ -216,6 +220,8 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => { actor && actor.login && actor.login.indexOf('[bot]') >= 0, ) + const showCardActions = cardViewMode !== 'compact' && !swipeable + let withTopMargin = cardViewMode !== 'compact' let withTopMarginCount = withTopMargin ? 1 : 0 function getWithTopMargin() { @@ -293,7 +299,9 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => { } body={issueOrPullRequest.body} bold - commentsCount={issueOrPullRequest.comments} + commentsCount={ + showCardActions ? undefined : issueOrPullRequest.comments + } createdAt={issueOrPullRequest.created_at} hideIcon hideLabelText={false} @@ -608,7 +616,7 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => { backgroundThemeColor={theme => getCardBackgroundThemeColor(theme, { isRead }) } - // muted={isRead} + muted={isRead} reason={notification.reason as GitHubNotificationReason} /> @@ -703,14 +711,27 @@ export const NotificationCard = React.memo((props: NotificationCardProps) => { {/* */} - + {!!showCardActions && ( + <> + - + + + )} diff --git a/packages/components/src/components/cards/NotificationCards.tsx b/packages/components/src/components/cards/NotificationCards.tsx index 2ca29dc6..250b21d9 100644 --- a/packages/components/src/components/cards/NotificationCards.tsx +++ b/packages/components/src/components/cards/NotificationCards.tsx @@ -45,7 +45,7 @@ export interface NotificationCardsProps pointerEvents: FlatListProps['pointerEvents'] refresh: EmptyCardsProps['refresh'] repoIsKnown: boolean - swipeable?: boolean + swipeable: boolean } function keyExtractor(item: EnhancedGitHubNotification) { @@ -170,6 +170,7 @@ export const NotificationCards = React.memo((props: NotificationCardsProps) => { } notification={item} repoIsKnown={props.repoIsKnown} + swipeable={props.swipeable} /> ) } @@ -185,6 +186,7 @@ export const NotificationCards = React.memo((props: NotificationCardsProps) => { } notification={item} repoIsKnown={props.repoIsKnown} + swipeable={props.swipeable} /> ) diff --git a/packages/components/src/components/cards/partials/CardActions.tsx b/packages/components/src/components/cards/partials/CardActions.tsx index 4a8a9f26..304849d8 100644 --- a/packages/components/src/components/cards/partials/CardActions.tsx +++ b/packages/components/src/components/cards/partials/CardActions.tsx @@ -1,8 +1,9 @@ import React from 'react' import { View } from 'react-native' -import { ColumnSubscription } from '@devhub/core' +import { ColumnSubscription, fixURLForPlatform } from '@devhub/core' import { useReduxAction } from '../../../hooks/use-redux-action' +import { Platform } from '../../../libs/platform' import * as actions from '../../../redux/actions' import { sharedStyles } from '../../../styles/shared' import { @@ -15,6 +16,8 @@ import { Spacer } from '../../common/Spacer' import { spacingBetweenLeftAndRightColumn } from '../styles' export interface CardActionsProps { + commentsCount: number | undefined + commentsLink: string | (() => void) | undefined isRead: boolean isSaved: boolean itemIds: Array @@ -25,6 +28,8 @@ export interface CardActionsProps { export function CardActions(props: CardActionsProps) { const { + commentsCount, + commentsLink, isRead, isSaved, itemIds, @@ -45,11 +50,12 @@ export function CardActions(props: CardActionsProps) { {leftSpacing > 0 && } saveItemsForLater({ itemIds, save: !isSaved })} @@ -66,12 +72,13 @@ export function CardActions(props: CardActionsProps) { markItemsAsReadOrUnread({ type, itemIds, unread: !!isRead }) @@ -86,6 +93,46 @@ export function CardActions(props: CardActionsProps) { {isRead ? 'mark as unread' : 'mark as read'} + {typeof commentsCount === 'number' && + commentsCount >= 0 && + !!commentsLink && ( + <> + + + + {commentsCount === 1 + ? 'comment (1)' + : `comments (${commentsCount})`} + + + )} + {rightSpacing > 0 && } ) diff --git a/packages/components/src/components/cards/partials/NotificationCardHeader.tsx b/packages/components/src/components/cards/partials/NotificationCardHeader.tsx index f03a51e0..b7fab979 100644 --- a/packages/components/src/components/cards/partials/NotificationCardHeader.tsx +++ b/packages/components/src/components/cards/partials/NotificationCardHeader.tsx @@ -154,7 +154,7 @@ export function NotificationCardHeader(props: NotificationCardHeaderProps) { diff --git a/packages/components/src/components/cards/partials/rows/IssueOrPullRequestRow.tsx b/packages/components/src/components/cards/partials/rows/IssueOrPullRequestRow.tsx index e50db6e1..2829a321 100644 --- a/packages/components/src/components/cards/partials/rows/IssueOrPullRequestRow.tsx +++ b/packages/components/src/components/cards/partials/rows/IssueOrPullRequestRow.tsx @@ -16,6 +16,7 @@ import { sharedStyles } from '../../../../styles/shared' import { contentPadding, smallAvatarSize } from '../../../../styles/variables' import { fixURL } from '../../../../utils/helpers/github/url' import { Avatar } from '../../../common/Avatar' +import { ConditionalWrap } from '../../../common/ConditionalWrap' import { IntervalRefresh } from '../../../common/IntervalRefresh' import { LabelProps } from '../../../common/Label' import { Link } from '../../../common/Link' @@ -53,6 +54,7 @@ export interface IssueOrPullRequestRowProps labels?: GitHubLabel[] | undefined owner: string repo: string + rightTitle?: React.ReactNode showBodyRow: boolean showCreationDetails: boolean title: string @@ -84,6 +86,7 @@ export const IssueOrPullRequestRow = React.memo( labels, owner, repo, + rightTitle, showBodyRow, showCreationDetails, title: _title, @@ -149,50 +152,67 @@ export const IssueOrPullRequestRow = React.memo( inlineLabels && sharedStyles.flexWrap, ]} > - 0 && { marginRight: contentPadding / 2 }, - !inlineLabels && - labels && - labels.length > 0 && { marginBottom: innerCardSpacing }, - ]} - textProps={{ - color: isRead ? 'foregroundColorMuted50' : 'foregroundColor', - // color: 'foregroundColor', - numberOfLines, - style: [ - sharedStyles.flex, - cardStyles.normalText, - bold && cardStyles.boldText, - // isRead && { fontWeight: undefined }, - ], - }} - // tooltip={`${title}${_body ? `\n\n${_body}` : ''}`} - > - <> - {!hideIcon && ( - <> - {' '} - - )} - {title} + ( + + {c} - {/* {!!issueOrPullRequestNumber && + + + + {rightTitle} + + + )} + > + 0 && { marginRight: contentPadding / 2 }, + !inlineLabels && + labels && + labels.length > 0 && { marginBottom: innerCardSpacing }, + ]} + textProps={{ + color: isRead + ? 'foregroundColorMuted50' + : 'foregroundColor', + // color: 'foregroundColor', + numberOfLines, + style: [ + sharedStyles.flex, + cardStyles.normalText, + bold && cardStyles.boldText, + // isRead && { fontWeight: undefined }, + ], + }} + // tooltip={`${title}${_body ? `\n\n${_body}` : ''}`} + > + <> + {!hideIcon && ( + <> + {' '} + + )} + {title} + + {/* {!!issueOrPullRequestNumber && (viewMode === 'compact' || !showCreationDetails) && ` #${issueOrPullRequestNumber}`} */} - - + + + {!!labels && labels.length > 0 && ( )} diff --git a/packages/components/src/components/cards/partials/rows/LabelsView.tsx b/packages/components/src/components/cards/partials/rows/LabelsView.tsx index 1af4f0eb..5081143b 100644 --- a/packages/components/src/components/cards/partials/rows/LabelsView.tsx +++ b/packages/components/src/components/cards/partials/rows/LabelsView.tsx @@ -3,6 +3,7 @@ import { ScrollView, ViewProps } from 'react-native' import { GitHubLabel, Omit } from '@devhub/core' import { sharedStyles } from '../../../../styles/shared' +import { contentPadding } from '../../../../styles/variables' import { ConditionalWrap } from '../../../common/ConditionalWrap' import { hiddenLabelSize, Label, LabelProps } from '../../../common/Label' import { TouchableOpacity } from '../../../common/TouchableOpacity' @@ -37,7 +38,9 @@ export const LabelsView = (props: LabelsViewProps) => { scrollViewRef.current.scrollToEnd({ animated: false }) }, [scrollViewRef.current]) - const horizontalSpacing = hideText ? -hiddenLabelSize.width / 8 : 1 + const horizontalSpacing = hideText + ? -hiddenLabelSize.width / 8 + : contentPadding / 3 const verticalSpacing = 1 const texts = labels @@ -92,8 +95,8 @@ export const LabelsView = (props: LabelsViewProps) => { colorThemeColor={label.color} containerStyle={{ alignSelf: 'flex-start', - marginHorizontal: horizontalSpacing, - marginVertical: verticalSpacing, + paddingHorizontal: horizontalSpacing, + paddingVertical: verticalSpacing, }} hideText={hideText} outline={false} diff --git a/packages/components/src/components/cards/partials/rows/partials/NotificationReason.tsx b/packages/components/src/components/cards/partials/rows/partials/NotificationReason.tsx index 885fb700..8c114ae1 100644 --- a/packages/components/src/components/cards/partials/rows/partials/NotificationReason.tsx +++ b/packages/components/src/components/cards/partials/rows/partials/NotificationReason.tsx @@ -9,12 +9,12 @@ import { Label } from '../../../../common/Label' export interface NotificationReasonProps { backgroundThemeColor: keyof ThemeColors | ((theme: ThemeColors) => string) - muted?: boolean + muted: boolean reason: GitHubNotificationReason } export function NotificationReason(props: NotificationReasonProps) { - const { backgroundThemeColor, reason } = props + const { backgroundThemeColor, muted, reason } = props const reasonDetails = getNotificationReasonMetadata(reason) @@ -24,9 +24,10 @@ export function NotificationReason(props: NotificationReasonProps) { diff --git a/packages/components/src/components/common/Label.tsx b/packages/components/src/components/common/Label.tsx index 55c10292..9f82d4f9 100644 --- a/packages/components/src/components/common/Label.tsx +++ b/packages/components/src/components/common/Label.tsx @@ -107,7 +107,7 @@ export function Label(props: LabelProps) { alignItems: 'center', justifyContent: 'center', borderRadius: typeof radius === 'number' ? radius : height / 2, - borderWidth: StyleSheet.hairlineWidth, + borderWidth: outline ? StyleSheet.hairlineWidth : 0, }, containerProps && containerProps.style, containerStyle, @@ -116,7 +116,6 @@ export function Label(props: LabelProps) { backgroundColor, }, Boolean(radius) && { borderRadius: radius }, - muted && hideText && { opacity: mutedOpacity }, ]} > {!hideText && ( @@ -127,6 +126,7 @@ export function Label(props: LabelProps) { { width: 6, height: 6, + marginTop: 1, borderRadius: 6 / 2, backgroundColor: circleColor, }, @@ -143,10 +143,10 @@ export function Label(props: LabelProps) { hideText ? { width } : { minWidth: width }, { height, - lineHeight: hideText ? height : height - 2, + lineHeight: height, fontSize: hideText ? 0 : small ? 11 : 12, color: foregroundColor, - paddingHorizontal: hideText ? 0 : contentPadding / (small ? 3 : 2), + paddingLeft: hideText ? 0 : contentPadding / (small ? 3 : 2), }, textProps && !hideText && textProps.style, ]} diff --git a/packages/components/src/containers/ColumnContainer.tsx b/packages/components/src/containers/ColumnContainer.tsx index 93e9cb91..50e34818 100644 --- a/packages/components/src/containers/ColumnContainer.tsx +++ b/packages/components/src/containers/ColumnContainer.tsx @@ -11,7 +11,7 @@ export interface ColumnContainerProps { columnId: string disableColumnOptions?: boolean pagingEnabled?: boolean - swipeable?: boolean + swipeable: boolean pointerEvents: FlatListProps['pointerEvents'] } diff --git a/packages/core/src/helpers/github/shared.ts b/packages/core/src/helpers/github/shared.ts index e6874d0b..208cf467 100644 --- a/packages/core/src/helpers/github/shared.ts +++ b/packages/core/src/helpers/github/shared.ts @@ -7,9 +7,6 @@ import { Column, ColumnFilters, ColumnSubscription, - EnhancedGitHubEvent, - EnhancedGitHubIssueOrPullRequest, - EnhancedGitHubNotification, EnhancedItem, GitHubAPIHeaders, GitHubEventSubjectType,