Skip to content

Commit 6e58a87

Browse files
committed
feat: show lnurl-pay comment in activity detail
1 parent 041d676 commit 6e58a87

File tree

9 files changed

+77
-4
lines changed

9 files changed

+77
-4
lines changed

e2e/lnurl.e2e.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ d('LNURL', () => {
199199
.toBeVisible()
200200
.withTimeout(10000);
201201
await element(by.id('Close')).tap();
202+
// check if comment is displayed
203+
await element(by.id('WalletsScrollView')).scrollTo('bottom', NaN, 0.85);
204+
await element(by.id('ActivityShort-1')).tap();
205+
await expect(element(by.id('InvoiceComment'))).toHaveText('test comment');
206+
await element(by.id('NavigationClose')).tap();
202207

203208
// test lnurl-pay, with min == max amount, no comment
204209
const payRequest2 = await lnurl.generateNewUrl('payRequest', {

src/screens/Activity/ActivityDetail.tsx

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ import {
7272
} from '../../store/slices/metadata';
7373
import { getTransactions } from '../../utils/wallet/electrum';
7474
import { ITransaction, ITxHash } from '../../utils/wallet';
75-
import { ellipsis, getDurationForBlocks, openURL } from '../../utils/helpers';
75+
import {
76+
ellipsis,
77+
getDurationForBlocks,
78+
openURL,
79+
vibrate,
80+
} from '../../utils/helpers';
7681
import { getBoostedTransactionParents } from '../../utils/boost';
7782
import { showToast } from '../../utils/notifications';
7883
import {
@@ -81,6 +86,7 @@ import {
8186
transferSelector,
8287
} from '../../store/reselect/wallet';
8388
import {
89+
commentSelector,
8490
slashTagsUrlSelector,
8591
tagSelector,
8692
} from '../../store/reselect/metadata';
@@ -684,6 +690,7 @@ const LightningActivityDetail = ({
684690

685691
const dispatch = useAppDispatch();
686692
const tags = useAppSelector((state) => tagSelector(state, id));
693+
const comment = useAppSelector((state) => commentSelector(state, id));
687694
const slashTagsUrl = useAppSelector((state) => {
688695
return slashTagsUrlSelector(state, id);
689696
});
@@ -717,6 +724,7 @@ const LightningActivityDetail = ({
717724

718725
const onCopy = (text: string): void => {
719726
Clipboard.setString(text);
727+
vibrate();
720728
showToast({
721729
type: 'success',
722730
title: t('copied'),
@@ -910,7 +918,9 @@ const LightningActivityDetail = ({
910918
)}
911919

912920
{message ? (
913-
<View style={styles.invoiceNote}>
921+
<TouchableOpacity
922+
style={styles.invoiceNote}
923+
onPress={(): void => onCopy(message)}>
914924
<Caption13Up style={styles.sText} color="secondary">
915925
{t('activity_invoice_note')}
916926
</Caption13Up>
@@ -922,7 +932,25 @@ const LightningActivityDetail = ({
922932
<Title testID="InvoiceNote">{message}</Title>
923933
</View>
924934
</ThemedView>
925-
</View>
935+
</TouchableOpacity>
936+
) : null}
937+
938+
{comment ? (
939+
<TouchableOpacity
940+
style={styles.invoiceNote}
941+
onPress={(): void => onCopy(comment)}>
942+
<Caption13Up style={styles.sText} color="secondary">
943+
{t('activity_invoice_comment')}
944+
</Caption13Up>
945+
<ThemedView color="white10">
946+
<Canvas style={styles.zRoot}>
947+
<ZigZag color={colors.background} />
948+
</Canvas>
949+
<View style={styles.note}>
950+
<Title testID="InvoiceComment">{comment}</Title>
951+
</View>
952+
</ThemedView>
953+
</TouchableOpacity>
926954
) : null}
927955

928956
<View>

src/screens/Wallets/LNURLPay/Confirm.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
settingsSelector,
2727
} from '../../../store/reselect/settings';
2828
import { addPendingPayment } from '../../../store/slices/lightning';
29+
import { updateMetaTxComment } from '../../../store/slices/metadata';
2930
import { EActivityType } from '../../../store/types/activity';
3031
import { AnimatedView, BottomSheetTextInput } from '../../../styles/components';
3132
import { Checkmark, LightningHollow } from '../../../styles/icons';
@@ -111,6 +112,15 @@ const LNURLConfirm = ({
111112

112113
setIsLoading(false);
113114

115+
if (comment) {
116+
dispatch(
117+
updateMetaTxComment({
118+
txId: decodedInvoice.payment_hash,
119+
comment,
120+
}),
121+
);
122+
}
123+
114124
if (payInvoiceResponse.isErr()) {
115125
const errorMessage = payInvoiceResponse.error.message;
116126
if (errorMessage === 'Timed Out.') {

src/store/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const persistConfig = {
3232
key: 'root',
3333
storage: reduxStorage,
3434
// increase version after store shape changes
35-
version: 46,
35+
version: 47,
3636
stateReconciler: autoMergeLevel2,
3737
blacklist: ['receive', 'ui'],
3838
migrate: createMigrate(migrations, { debug: __ENABLE_MIGRATION_DEBUG__ }),

src/store/migrations/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ const migrations = {
4545
},
4646
};
4747
},
48+
47: (state): PersistedState => {
49+
return {
50+
...state,
51+
metadata: {
52+
...state.metadata,
53+
comments: {},
54+
},
55+
};
56+
},
4857
};
4958

5059
export default migrations;

src/store/reselect/metadata.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,7 @@ export const slashTagsUrlSelector = createSelector(
3333
return metadata.slashTagsUrls[id];
3434
},
3535
);
36+
export const commentSelector = createSelector(
37+
[metadataState, (_state, txId: string): string => txId],
38+
(metadata, txId): string => metadata.comments[txId] ?? '',
39+
);

src/store/slices/metadata.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const initialMetadataState: TMetadataState = {
77
lastUsedTags: [],
88
pendingInvoices: [],
99
slashTagsUrls: {},
10+
comments: {},
1011
};
1112

1213
export const metadataSlice = createSlice({
@@ -26,6 +27,16 @@ export const metadataSlice = createSlice({
2627
state.tags[action.payload.txId] = action.payload.tags;
2728
}
2829
},
30+
updateMetaTxComment: (
31+
state,
32+
action: PayloadAction<{ txId: string; comment: string }>,
33+
) => {
34+
if (action.payload.comment.length === 0) {
35+
delete state.comments[action.payload.txId];
36+
} else {
37+
state.comments[action.payload.txId] = action.payload.comment;
38+
}
39+
},
2940
addMetaTxTag: (
3041
state,
3142
action: PayloadAction<{ txId: string; tag: string }>,
@@ -120,6 +131,7 @@ const { actions, reducer } = metadataSlice;
120131
export const {
121132
updateMetadata,
122133
updateMetaTxTags,
134+
updateMetaTxComment,
123135
addMetaTxTag,
124136
deleteMetaTxTag,
125137
updatePendingInvoice,

src/store/types/metadata.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export type TTags = { [txId: string]: string[] };
22
export type TLastUsedTags = string[];
33
export type TSlashTagsUrls = { [txId: string]: string | undefined };
4+
export type TTxComments = { [txId: string]: string };
45

56
export type TPendingInvoice = {
67
id: string; // uuid used to identify the invoice 'session'
@@ -16,4 +17,5 @@ export type TMetadataState = {
1617
// Keep track of pending invoices, right now this is only used to map tags to incoming transactions
1718
pendingInvoices: TPendingInvoice[];
1819
slashTagsUrls: TSlashTagsUrls;
20+
comments: TTxComments;
1921
};

src/utils/i18n/locales/en/wallet.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,9 @@
506506
"activity_invoice_note": {
507507
"string": "Invoice note"
508508
},
509+
"activity_invoice_comment": {
510+
"string": "Comment"
511+
},
509512
"activity_invoice": {
510513
"string": "Invoice"
511514
},

0 commit comments

Comments
 (0)