From 1aadc1843431a9b6bdb2ea1159b790f1a4caf086 Mon Sep 17 00:00:00 2001 From: thoreyjona Date: Mon, 16 Sep 2024 11:01:06 +0000 Subject: [PATCH 01/24] feat: add urgent tag to inbox --- apps/native/app/src/messages/en.ts | 2 +- apps/native/app/src/messages/is.ts | 1 + apps/native/app/src/ui/lib/alert/alert.tsx | 42 +++++++++---------- .../native/app/src/ui/lib/card/inbox-card.tsx | 3 ++ apps/native/app/src/ui/lib/list/list-item.tsx | 22 ++++++++-- 5 files changed, 45 insertions(+), 25 deletions(-) diff --git a/apps/native/app/src/messages/en.ts b/apps/native/app/src/messages/en.ts index 845661117191..3f8ad63b22fb 100644 --- a/apps/native/app/src/messages/en.ts +++ b/apps/native/app/src/messages/en.ts @@ -207,13 +207,13 @@ export const en: TranslatedMessages = { 'inbox.emptyListTitle': 'There are currently no documents', 'inbox.emptyListDescription': 'When you receive electronic documents from the government, they will appear here.', - 'inbox.markAllAsReadPromptTitle': 'Do you want to mark all as read?', 'inbox.markAllAsReadPromptDescription': 'This action cannot be undone', 'inbox.markAllAsReadPromptCancel': 'Cancel', 'inbox.markAllAsReadPromptConfirm': 'Mark all as read', 'inbox.cardNoInboxDocuments': 'When you receive mail in your mailbox, it will appear here.', + 'inbox.urgent': 'Urgent', // inbox filters 'inboxFilters.screenTitle': 'Filter documents', diff --git a/apps/native/app/src/messages/is.ts b/apps/native/app/src/messages/is.ts index 303d26dfa3e0..1545e086a0a6 100644 --- a/apps/native/app/src/messages/is.ts +++ b/apps/native/app/src/messages/is.ts @@ -213,6 +213,7 @@ export const is = { 'inbox.markAllAsReadPromptConfirm': 'Merkja lesið', 'inbox.cardNoInboxDocuments': 'Þegar þú færð sendan póst í pósthólfið þá birtist hann hér.', + 'inbox.urgent': 'Áríðandi', // inbox filters 'inboxFilters.screenTitle': 'Sía skjöl', diff --git a/apps/native/app/src/ui/lib/alert/alert.tsx b/apps/native/app/src/ui/lib/alert/alert.tsx index 6efaf7302b97..dfccc0f02666 100644 --- a/apps/native/app/src/ui/lib/alert/alert.tsx +++ b/apps/native/app/src/ui/lib/alert/alert.tsx @@ -14,8 +14,8 @@ import warning from '../../assets/alert/warning.png' import check from '../../assets/icons/check.png' import error from '../../assets/icons/error.png' import { dynamicColor } from '../../utils' -import { font } from '../../utils/font' import { Colors } from '../../utils/theme' +import { Typography } from '../typography/typography' export type AlertType = 'error' | 'info' | 'success' | 'warning' @@ -34,6 +34,7 @@ interface AlertProps { sharedAnimatedValue?: any hasBorder?: boolean hasBottomBorder?: boolean + small?: boolean } interface HostProps { @@ -41,6 +42,7 @@ interface HostProps { borderColor: Colors hasBorder?: boolean hasBottomBorder?: boolean + small?: boolean } type VariantStyle = { @@ -66,7 +68,8 @@ const darkBackgroundColor = (color: string, colors: any) => { } const Host = styled.View` - padding: ${({ theme }) => theme.spacing[2]}px; + padding: ${({ theme, small }) => + small ? theme.spacing[1] : theme.spacing[2]}px; border-style: solid; border-color: ${dynamicColor((props) => ({ @@ -100,27 +103,16 @@ const Icon = styled.View` align-self: flex-start; ` -const Content = styled.View` - padding-right: ${({ theme }) => theme.spacing[2]}px; +const Content = styled.View<{ small: boolean }>` + padding-right: ${({ theme, small }) => + small ? theme.spacing.smallGutter : theme.spacing[2]}px; flex: 1; ` -const Title = styled.Text` - ${font({ - fontSize: 16, - lineHeight: 20, - fontWeight: '600', - })} +const Title = styled(Typography)` margin-bottom: 4px; ` -const Message = styled.Text` - ${font({ - fontSize: 13, - lineHeight: 16, - })} -` - const Close = styled(TouchableOpacity)` padding: 10px; justify-content: center; @@ -167,6 +159,7 @@ export function Alert({ sharedAnimatedValue, hasBorder, hasBottomBorder, + small = false, ...rest }: AlertProps) { const theme = useTheme() @@ -196,6 +189,7 @@ export function Alert({ borderColor={variant.borderColor} hasBorder={hasBorder} hasBottomBorder={hasBottomBorder} + small={small} {...rest} > @@ -203,15 +197,21 @@ export function Alert({ )} {message && ( - - {title && {title}} - {message} + + {title && {title}} + + {message} + )} diff --git a/apps/native/app/src/ui/lib/card/inbox-card.tsx b/apps/native/app/src/ui/lib/card/inbox-card.tsx index c98d54681c93..8c1688bbc894 100644 --- a/apps/native/app/src/ui/lib/card/inbox-card.tsx +++ b/apps/native/app/src/ui/lib/card/inbox-card.tsx @@ -13,6 +13,7 @@ interface InboxCardProps { unread?: boolean senderName?: string | null bookmarked?: boolean | null + urgent?: boolean testID?: string onPress(id: string): void } @@ -26,6 +27,7 @@ export function InboxCard({ unread, bookmarked, senderName, + urgent = false, }: InboxCardProps) { const theme = useTheme() const [starred, setStarred] = useState(false) @@ -45,6 +47,7 @@ export function InboxCard({ toggleAction(!bookmarked ? 'bookmark' : 'unbookmark', id) setStarred(!bookmarked) }} + urgent={urgent} icon={icon} /> diff --git a/apps/native/app/src/ui/lib/list/list-item.tsx b/apps/native/app/src/ui/lib/list/list-item.tsx index 5454e1172994..730871e2d72f 100644 --- a/apps/native/app/src/ui/lib/list/list-item.tsx +++ b/apps/native/app/src/ui/lib/list/list-item.tsx @@ -1,8 +1,8 @@ -import { Typography } from '@ui' +import { Alert, Typography } from '@ui' import React, { isValidElement } from 'react' -import { FormattedDate } from 'react-intl' +import { FormattedDate, useIntl } from 'react-intl' import { Image, ImageSourcePropType, Pressable } from 'react-native' -import styled from 'styled-components/native' +import styled, { useTheme } from 'styled-components/native' import StarFilled from '../../../assets/icons/star-filled.png' import Star from '../../../assets/icons/star.png' @@ -86,6 +86,7 @@ interface ListItemProps { icon?: ImageSourcePropType | React.ReactNode onStarPress?(): void starred?: boolean + urgent?: boolean } export function ListItem({ @@ -96,7 +97,10 @@ export function ListItem({ onStarPress, starred = false, unread = false, + urgent = false, }: ListItemProps) { + const intl = useIntl() + const theme = useTheme() return ( @@ -135,6 +139,18 @@ export function ListItem({ > {subtitle} + {urgent && ( + + )} Date: Tue, 17 Sep 2024 09:42:33 +0000 Subject: [PATCH 02/24] feat: add urgent tag to urgent documents in list --- .../src/graphql/fragments/document.fragment.graphql | 7 +++++++ .../src/screens/document-detail/document-detail.tsx | 10 +++++++++- apps/native/app/src/screens/home/inbox-module.tsx | 1 + apps/native/app/src/screens/inbox/inbox.tsx | 2 ++ apps/native/app/src/ui/lib/card/inbox-card.tsx | 6 +++--- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/native/app/src/graphql/fragments/document.fragment.graphql b/apps/native/app/src/graphql/fragments/document.fragment.graphql index e074389e3a53..c9ab9802176d 100644 --- a/apps/native/app/src/graphql/fragments/document.fragment.graphql +++ b/apps/native/app/src/graphql/fragments/document.fragment.graphql @@ -8,6 +8,13 @@ fragment ListDocument on DocumentV2 { opened categoryId bookmarked + isUrgent + actions { + type + title + icon + data + } sender { id name diff --git a/apps/native/app/src/screens/document-detail/document-detail.tsx b/apps/native/app/src/screens/document-detail/document-detail.tsx index 0dbd13a225f1..fc3594ec997d 100644 --- a/apps/native/app/src/screens/document-detail/document-detail.tsx +++ b/apps/native/app/src/screens/document-detail/document-detail.tsx @@ -200,7 +200,8 @@ const PdfViewer = React.memo( export const DocumentDetailScreen: NavigationFunctionComponent<{ docId: string -}> = ({ componentId, docId }) => { + isUrgent: boolean +}> = ({ componentId, docId, isUrgent }) => { useNavigationOptions(componentId) const client = useApolloClient() @@ -225,6 +226,7 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ variables: { input: { id: docId, + includeDocument: !isUrgent, }, }, fetchPolicy: 'no-cache', @@ -285,6 +287,12 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ setVisible(true) }) + useEffect(() => { + if (isUrgent) { + // open modal + } + }, [isUrgent]) + useEffect(() => { if (Document.opened) { return diff --git a/apps/native/app/src/screens/home/inbox-module.tsx b/apps/native/app/src/screens/home/inbox-module.tsx index 2d2c32bae705..f28d17f5468e 100644 --- a/apps/native/app/src/screens/home/inbox-module.tsx +++ b/apps/native/app/src/screens/home/inbox-module.tsx @@ -129,6 +129,7 @@ const InboxModule = React.memo(({ data, loading, error }: InboxModuleProps) => { icon={ item.sender.name && getOrganizationLogoUrl(item.sender.name, 75) } + isUrgent={item.isUrgent} onPress={() => navigateTo(`/inbox/${item.id}`, { title: item.sender.name, diff --git a/apps/native/app/src/screens/inbox/inbox.tsx b/apps/native/app/src/screens/inbox/inbox.tsx index 6356e3f4c626..015ab1249bd0 100644 --- a/apps/native/app/src/screens/inbox/inbox.tsx +++ b/apps/native/app/src/screens/inbox/inbox.tsx @@ -125,9 +125,11 @@ const PressableListItem = React.memo( bookmarked={item.bookmarked} senderName={item.sender.name} icon={item.sender.name && getOrganizationLogoUrl(item.sender.name, 75)} + isUrgent={item.isUrgent} onPress={() => navigateTo(`/inbox/${item.id}`, { title: item.sender.name, + isUrgent: item.isUrgent, listParams, }) } diff --git a/apps/native/app/src/ui/lib/card/inbox-card.tsx b/apps/native/app/src/ui/lib/card/inbox-card.tsx index 8c1688bbc894..870fc31a189a 100644 --- a/apps/native/app/src/ui/lib/card/inbox-card.tsx +++ b/apps/native/app/src/ui/lib/card/inbox-card.tsx @@ -13,7 +13,7 @@ interface InboxCardProps { unread?: boolean senderName?: string | null bookmarked?: boolean | null - urgent?: boolean + isUrgent?: boolean | null testID?: string onPress(id: string): void } @@ -27,7 +27,7 @@ export function InboxCard({ unread, bookmarked, senderName, - urgent = false, + isUrgent = false, }: InboxCardProps) { const theme = useTheme() const [starred, setStarred] = useState(false) @@ -47,7 +47,7 @@ export function InboxCard({ toggleAction(!bookmarked ? 'bookmark' : 'unbookmark', id) setStarred(!bookmarked) }} - urgent={urgent} + urgent={!!isUrgent} icon={icon} /> From b60c477f00a08f4e0198a094acc674225ac470df Mon Sep 17 00:00:00 2001 From: thoreyjona Date: Tue, 17 Sep 2024 13:46:12 +0000 Subject: [PATCH 03/24] fix: undo small variant for alert --- apps/native/app/src/ui/lib/alert/alert.tsx | 24 ++++++++-------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/apps/native/app/src/ui/lib/alert/alert.tsx b/apps/native/app/src/ui/lib/alert/alert.tsx index dfccc0f02666..54903d763dbd 100644 --- a/apps/native/app/src/ui/lib/alert/alert.tsx +++ b/apps/native/app/src/ui/lib/alert/alert.tsx @@ -34,7 +34,6 @@ interface AlertProps { sharedAnimatedValue?: any hasBorder?: boolean hasBottomBorder?: boolean - small?: boolean } interface HostProps { @@ -42,7 +41,6 @@ interface HostProps { borderColor: Colors hasBorder?: boolean hasBottomBorder?: boolean - small?: boolean } type VariantStyle = { @@ -68,8 +66,7 @@ const darkBackgroundColor = (color: string, colors: any) => { } const Host = styled.View` - padding: ${({ theme, small }) => - small ? theme.spacing[1] : theme.spacing[2]}px; + padding: ${({ theme }) => theme.spacing[2]}px; border-style: solid; border-color: ${dynamicColor((props) => ({ @@ -103,9 +100,8 @@ const Icon = styled.View` align-self: flex-start; ` -const Content = styled.View<{ small: boolean }>` - padding-right: ${({ theme, small }) => - small ? theme.spacing.smallGutter : theme.spacing[2]}px; +const Content = styled.View` + padding-right: ${({ theme }) => theme.spacing[2]}px; flex: 1; ` @@ -159,7 +155,6 @@ export function Alert({ sharedAnimatedValue, hasBorder, hasBottomBorder, - small = false, ...rest }: AlertProps) { const theme = useTheme() @@ -189,7 +184,6 @@ export function Alert({ borderColor={variant.borderColor} hasBorder={hasBorder} hasBottomBorder={hasBottomBorder} - small={small} {...rest} > @@ -198,20 +192,18 @@ export function Alert({ )} {message && ( - + {title && {title}} - - {message} - + {message} )} From ef3f056420440d672232713ab4cefd32239333ba Mon Sep 17 00:00:00 2001 From: thoreyjona Date: Mon, 23 Sep 2024 10:13:27 +0000 Subject: [PATCH 04/24] feat: use label component instead of alert --- .../app/src/assets/icons/external-open.png | Bin 313 -> 0 bytes .../app/src/assets/icons/external-open@2x.png | Bin 380 -> 0 bytes .../app/src/assets/icons/external-open@3x.png | Bin 601 -> 0 bytes apps/native/app/src/messages/en.ts | 1 + apps/native/app/src/messages/is.ts | 1 + .../document-detail/document-detail.tsx | 60 +++++++++++++++--- .../app/src/screens/finance/finance.tsx | 4 +- .../app/src/screens/home/inbox-module.tsx | 1 + apps/native/app/src/ui/lib/detail/header.tsx | 32 +++++++--- apps/native/app/src/ui/lib/list/list-item.tsx | 15 ++--- 10 files changed, 85 insertions(+), 29 deletions(-) delete mode 100644 apps/native/app/src/assets/icons/external-open.png delete mode 100644 apps/native/app/src/assets/icons/external-open@2x.png delete mode 100644 apps/native/app/src/assets/icons/external-open@3x.png diff --git a/apps/native/app/src/assets/icons/external-open.png b/apps/native/app/src/assets/icons/external-open.png deleted file mode 100644 index 2dcf43c851bd1537db330c11bc77b5f247952ee1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eB{y9$<$B+ufy}^yVO$Gvc%=jK~u28Jz@%4KPAi4D|+$6NlfSe|NU#v|3TTM=t} zvv7iQ*?GUFxu<5Beio3k=ngLD+M0A$dfqLo)cCkYb+7etx9{`*^!jSLc6aG*F0qoh z6-6J^3QxY7-89ozX8yr|n>TjNb>!AeS*x@A;nTbhAGLmk7{``1hIY*yhHINNg=UCF znaD((d@tP>cE_o8@$XlkjYaRcoowZDGpwAdQUHx3vIVCg! E0N#jmKL7v# diff --git a/apps/native/app/src/assets/icons/external-open@2x.png b/apps/native/app/src/assets/icons/external-open@2x.png deleted file mode 100644 index dd8c57026d39e7eb222b6a06f2dbaa802cbc7ea9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcmV-?0fYXDP) zO^5|+J;?|P8QIsJ4a|?%?AXshn*cqgau6LuUY zU6!~HI0MeWx((2>jqnVn{N{MdhKaZ002B7+1~x$mS+UCdK8qR1Nm>RdTn~g-%9Bjo au?pV9X>?xzkKN(`0000Vv5j1Y)~V^i%82C`v`@=CkT;A70d`_6Fr<3QTal+5g=UGP9ee+ zI6Ok(45T9CW1=jZ(Hv+ty^e1RN%6F2EUUY{egt9~u*Dm|aIvXaAzk;np0aqtQ{Kgd zxvq-dz#ZN5Lldq%fDHsDd>m=ZRpL{T@b#pw*}kT+n8hz(7kx+Q#5bU7Ku(+eA5A*UwXcHcUdjrj_CF;& z3IFBP;zAWV1EJ{*gr+kPnlm?GE3D`cm4R$0KglC?t|_8{)6Mw`UrnnDWn%*0*v2xm zJiz6SOBTNy0XK>Us(() const [error, setError] = useState(false) + const [showConfirmedAlert, setShowConfirmedAlert] = useState(false) // Check if we have the document in the cache const doc = useFragment_experimental({ @@ -226,10 +234,43 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ variables: { input: { id: docId, + // If the document is marked at urgent we first need to fetch actions before the content includeDocument: !isUrgent, }, }, fetchPolicy: 'no-cache', + onCompleted: () => { + if (isUrgent && !showConfirmedAlert) { + const confirmationAction = Document.actions?.find( + (action) => action.type === 'confirmation', + ) + if (confirmationAction) { + RNAlert.alert( + confirmationAction.title ?? '', + confirmationAction.data ?? '', + [ + { + text: intl.formatMessage({ + id: 'inbox.markAllAsReadPromptCancel', + }), + style: 'cancel', + }, + { + text: intl.formatMessage({ + id: 'inbox.openDocument', + }), + onPress: async () => { + docRes.refetch({ + input: { id: docId, includeDocument: true }, + }) + setShowConfirmedAlert(true) + }, + }, + ], + ) + } + } + }, }) const Document = { @@ -287,12 +328,6 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ setVisible(true) }) - useEffect(() => { - if (isUrgent) { - // open modal - } - }, [isUrgent]) - useEffect(() => { if (Document.opened) { return @@ -363,12 +398,14 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ isLoading={loading && !Document.subject} hasBorder={false} logo={getOrganizationLogoUrl(Document.sender?.name ?? '', 75)} + label={isUrgent ? intl.formatMessage({ id: 'inbox.urgent' }) : ''} /> + {showConfirmedAlert && ( // TODO: this will come from the server + + )} {fileTypeLoaded && !error && (isHtml ? ( diff --git a/apps/native/app/src/screens/finance/finance.tsx b/apps/native/app/src/screens/finance/finance.tsx index b015d9ec9fc5..0e29701ecf42 100644 --- a/apps/native/app/src/screens/finance/finance.tsx +++ b/apps/native/app/src/screens/finance/finance.tsx @@ -3,7 +3,7 @@ import { FormattedMessage, useIntl } from 'react-intl' import { SafeAreaView, ScrollView } from 'react-native' import { NavigationFunctionComponent } from 'react-native-navigation' import { useTheme } from 'styled-components/native' -import externalOpen from '../../assets/icons/external-open.png' +import externalLink from '../../assets/icons/external-link.png' import { getConfig } from '../../config' import { GetFinanceStatus } from '../../graphql/types/finance.types' import { useGetFinanceStatusQuery } from '../../graphql/types/schema' @@ -162,7 +162,7 @@ export const FinanceScreen: NavigationFunctionComponent = ({ componentId }) => { /> } disabled={!scheduleButtonVisible} - icon={externalOpen} + icon={externalLink} onPress={() => { openBrowser( `${getConfig().apiUrl.replace( diff --git a/apps/native/app/src/screens/home/inbox-module.tsx b/apps/native/app/src/screens/home/inbox-module.tsx index f28d17f5468e..b0b4ce872f33 100644 --- a/apps/native/app/src/screens/home/inbox-module.tsx +++ b/apps/native/app/src/screens/home/inbox-module.tsx @@ -133,6 +133,7 @@ const InboxModule = React.memo(({ data, loading, error }: InboxModuleProps) => { onPress={() => navigateTo(`/inbox/${item.id}`, { title: item.sender.name, + isUrgent: item.isUrgent, }) } /> diff --git a/apps/native/app/src/ui/lib/detail/header.tsx b/apps/native/app/src/ui/lib/detail/header.tsx index 3265d46c3030..ecba70077d3c 100644 --- a/apps/native/app/src/ui/lib/detail/header.tsx +++ b/apps/native/app/src/ui/lib/detail/header.tsx @@ -1,9 +1,10 @@ import React from 'react' import { ImageSourcePropType } from 'react-native' -import styled from 'styled-components/native' +import styled, { useTheme } from 'styled-components/native' import { dynamicColor } from '../../utils/dynamic-color' import { Skeleton } from '../skeleton/skeleton' import { Typography } from '../typography/typography' +import { Label } from '@ui' const Host = styled.View<{ hasBorder?: boolean }>` padding-bottom: ${({ theme }) => theme.spacing[2]}px; @@ -43,6 +44,7 @@ const LogoBackground = styled.View` const Row = styled.View` flex-direction: row; justify-content: space-between; + align-items: center; padding-bottom: ${({ theme }) => theme.spacing[1]}px; ` @@ -60,6 +62,7 @@ interface HeaderProps { message?: string isLoading?: boolean hasBorder?: boolean + label?: string } export function Header({ @@ -69,7 +72,9 @@ export function Header({ message, isLoading, hasBorder = true, + label = '', }: HeaderProps) { + const theme = useTheme() return ( @@ -97,13 +102,24 @@ export function Header({ )} - {message && isLoading ? ( - - ) : message && !isLoading ? ( - - {message} - - ) : null} + + {message && isLoading ? ( + + ) : message && !isLoading ? ( + + {message} + + ) : null} + {label && ( + + )} + ) } diff --git a/apps/native/app/src/ui/lib/list/list-item.tsx b/apps/native/app/src/ui/lib/list/list-item.tsx index 730871e2d72f..e6ed9e0e2a40 100644 --- a/apps/native/app/src/ui/lib/list/list-item.tsx +++ b/apps/native/app/src/ui/lib/list/list-item.tsx @@ -1,4 +1,4 @@ -import { Alert, Typography } from '@ui' +import { Label, Typography } from '@ui' import React, { isValidElement } from 'react' import { FormattedDate, useIntl } from 'react-intl' import { Image, ImageSourcePropType, Pressable } from 'react-native' @@ -140,16 +140,9 @@ export function ListItem({ {subtitle} {urgent && ( - + )} Date: Tue, 24 Sep 2024 08:22:32 +0000 Subject: [PATCH 05/24] feat: add download icon --- apps/native/app/src/assets/icons/download.png | Bin 0 -> 304 bytes apps/native/app/src/assets/icons/download@2x.png | Bin 0 -> 460 bytes apps/native/app/src/assets/icons/download@3x.png | Bin 0 -> 643 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/native/app/src/assets/icons/download.png create mode 100644 apps/native/app/src/assets/icons/download@2x.png create mode 100644 apps/native/app/src/assets/icons/download@3x.png diff --git a/apps/native/app/src/assets/icons/download.png b/apps/native/app/src/assets/icons/download.png new file mode 100644 index 0000000000000000000000000000000000000000..44b12a8b518f4e0f27f3c42a0d0da133e7d6808d GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^fkrr7srqa#=R2*1rHerxO|_%<=~{+z+BMK zBEq_WL1h6$5GxOt*21X`EmjfV63wd_K%w=IrpH z+(XgN#(H66_Wvf~wN1Of?NgU2SduIA(&>&%R`-HyzY>ohdpRMTU;m9#R^i(Di5qIJ zT}w+pUu>8pv}on#1-~Zx=ZCXRVS4rQ^ZSfjx81ki{rHA&!OLILPgqw4F@!bFF?l)1 ywam%r>xwB4e+Su3X8W$)_|kXIRJB&cQszl_Y-$cV#CHKb#Ng@b=d#Wzp$PyS>~ux| literal 0 HcmV?d00001 diff --git a/apps/native/app/src/assets/icons/download@2x.png b/apps/native/app/src/assets/icons/download@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1fdfcc7a6bfffb46bd7e156bd14b8358d5a245ff GIT binary patch literal 460 zcmV;-0WTJA@8s8Ys#49a1Sj$g_13b-*ASi9K zq<7!PjLLvo9`^FUhFB)Z{sfYZk0gM3C}ZP{YJGE^9ZqQw|2yXTM7wp$&YA|{s-DmX zLFB#I_uF3-LaLs4u7^PO0m!Zi8fR#MRB6@ol#^NGIy6(K&v2DL0`%vG%qvXkz-7cg z)FcArLmY!37oZHn2gw8wrPst92&Q7pR9!KhZXUwetIU7dic2K^<2oX%=&x^95yytD zKPdQ9Gb4kIy7ym(GojUB4>PdmfB|I^|L-YYRZxF&ntB@SSgwKq0000UBFtl2zGaT?WEPUC2nS77qA9paEgttQv%ucTH8Qb z;zmLRtPOo5k)6PXrFEbzaU&rCi*R2#(=1XaK)6Or+&$Pj5jx0=bOI*?Pq%NUIuZ52 zSL<1&ezJhz{uO&H5^Mf;A|UvQ6UQQlI1>>31v|ZnQvtzm#6A{rE+F_%JCw*ZmnRP7B8y}TImP)|mD|=_*TL?=p7BRBl}0S!A6dRrzTZ{b d9bX{Of^S)2!X0H`NE`qF002ovPDHLkV1f?73DE!m literal 0 HcmV?d00001 From 4c08b57a870657b784b2ceb987741f0edbfbdbc6 Mon Sep 17 00:00:00 2001 From: thoreyjona Date: Tue, 24 Sep 2024 14:08:54 +0000 Subject: [PATCH 06/24] feat: add actions mapper --- .../document-detail/document-detail.tsx | 61 ++++++++++------ .../utils/getButtonsForActions.tsx | 71 +++++++++++++++++++ .../document-detail/utils/shareFile.tsx | 34 +++++++++ apps/native/app/src/ui/lib/detail/header.tsx | 5 +- apps/native/app/src/ui/lib/link/link.tsx | 11 +-- 5 files changed, 150 insertions(+), 32 deletions(-) create mode 100644 apps/native/app/src/screens/document-detail/utils/getButtonsForActions.tsx create mode 100644 apps/native/app/src/screens/document-detail/utils/shareFile.tsx diff --git a/apps/native/app/src/screens/document-detail/document-detail.tsx b/apps/native/app/src/screens/document-detail/document-detail.tsx index ed15de5365a9..33b59ddb1bc2 100644 --- a/apps/native/app/src/screens/document-detail/document-detail.tsx +++ b/apps/native/app/src/screens/document-detail/document-detail.tsx @@ -19,7 +19,6 @@ import { useNavigationComponentDidAppear, } from 'react-native-navigation-hooks/dist' import Pdf, { Source } from 'react-native-pdf' -import Share from 'react-native-share' import WebView from 'react-native-webview' import styled, { useTheme } from 'styled-components/native' import { @@ -33,10 +32,13 @@ import { toggleAction } from '../../lib/post-mail-action' import { authStore } from '../../stores/auth-store' import { useOrganizationsStore } from '../../stores/organizations-store' import { ButtonRegistry } from '../../utils/component-registry' +import { getButtonsForActions } from './utils/getButtonsForActions' +import { useBrowser } from '../../lib/use-browser' +import { shareFile } from './utils/shareFile' const Host = styled.SafeAreaView` - margin-left: 24px; - margin-right: 24px; + margin-left: ${({ theme }) => theme.spacing[2]}px; + margin-right: ${({ theme }) => theme.spacing[2]}px; ` const Border = styled.View` @@ -47,6 +49,12 @@ const Border = styled.View` }))}; ` +const ActionsWrapper = styled.View` + margin-bottom: ${({ theme }) => theme.spacing[2]}px; + margin-horizontal: ${({ theme }) => theme.spacing[2]}px; + gap: ${({ theme }) => theme.spacing[2]}px; +` + const PdfWrapper = styled.View` flex: 1; background-color: ${dynamicColor('background')}; @@ -214,6 +222,7 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ const intl = useIntl() const theme = useTheme() const htmlStyles = useHtmlStyles() + const { openBrowser } = useBrowser() const { getOrganizationLogoUrl } = useOrganizationsStore() const [accessToken, setAccessToken] = useState() const [error, setError] = useState(false) @@ -291,6 +300,9 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ Document?.content?.type.toLocaleLowerCase() === 'html' && Document.content?.value !== '' + const onShare = () => + shareFile({ document: Document as DocumentV2, hasPdf, pdfUrl }) + useConnectivityIndicator({ componentId, rightButtons: getRightButtonsForDocumentDetail({ @@ -311,16 +323,7 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ ) } if (buttonId === ButtonRegistry.ShareButton && loaded) { - if (Platform.OS === 'android') { - authStore.setState({ noLockScreenUntilNextAppStateActive: true }) - } - Share.open({ - title: Document.subject!, - subject: Document.subject!, - message: `${Document.sender!.name!} \n ${Document.subject!}`, - type: hasPdf ? 'application/pdf' : undefined, - url: hasPdf ? `file://${pdfUrl}` : Document.downloadUrl!, - }) + onShare() } }, componentId) @@ -384,6 +387,10 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ } }, [loaded]) + const hasAdditionalActions = Document.actions?.filter( + (action) => action.type !== 'confirmation', + ) + return ( <> @@ -401,11 +408,32 @@ export const DocumentDetailScreen: NavigationFunctionComponent<{ label={isUrgent ? intl.formatMessage({ id: 'inbox.urgent' }) : ''} /> + {showConfirmedAlert && ( + + {showConfirmedAlert && ( // TODO: this will come from the server + + )} + {hasAdditionalActions && + showConfirmedAlert && + getButtonsForActions( + openBrowser, + onShare, + componentId, + Document.actions, + )} + + )} - {showConfirmedAlert && ( // TODO: this will come from the server - - )} {fileTypeLoaded && !error && (isHtml ? ( diff --git a/apps/native/app/src/screens/document-detail/utils/getButtonsForActions.tsx b/apps/native/app/src/screens/document-detail/utils/getButtonsForActions.tsx new file mode 100644 index 000000000000..dfcce7f60349 --- /dev/null +++ b/apps/native/app/src/screens/document-detail/utils/getButtonsForActions.tsx @@ -0,0 +1,71 @@ +import { Button } from '@ui' +import styled from 'styled-components' +import { View } from 'react-native' + +import openIcon from '../../../assets/icons/external-link.png' +import downloadIcon from '../../../assets/icons/download.png' +import { DocumentV2Actions } from '../../../graphql/types/schema' + +const Host = styled(View)` + flex-direction: row; + align-items: center; + justify-content: center; + gap: ${({ theme }) => theme.spacing[2]}px; +` + +const Action = styled(View)` + flex: 1; +` + +const getIcons = (icon: string) => { + switch (icon) { + case 'open': + return openIcon + case 'download': + return downloadIcon + default: + return null + } +} + +export const getButtonsForActions = ( + openBrowser: (link: string, componentId?: string) => void, + onShare: () => void, + componentId: string, + actions?: DocumentV2Actions[] | null, +) => { + if (!actions) { + return + } + const buttons = actions.map((action) => { + const icon = getIcons(action.icon ?? '') + if (action.type === 'url' && action.data && action.title) { + return ( + +