Skip to content

Commit

Permalink
fix: context menu crashing, closes #413
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Jan 14, 2021
1 parent cab22ba commit 619c88e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/debug-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
- uses: lucasmotta/pull-request-sticky-header@1.0.0
if: (!contains(needs.*.result, 'failure'))
with:
header: '> [Download the latest builds](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).'
header: '> [Download the latest build](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Remove header if build failed
Expand Down
7 changes: 6 additions & 1 deletion app/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ export class Api {

async getAddressTransactions(address: string) {
return axios.get<TransactionResults>(
urljoin(this.baseUrl, `/extended/v1/address/${address}/transactions`)
urljoin(this.baseUrl, `/extended/v1/address/${address}/transactions`),
{
params: {
limit: 50,
},
}
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useClipboard } from '@blockstack/ui';
import { Transaction } from '@blockstack/stacks-blockchain-api-types';

import { hasMemo, getRecipientAddress } from '@utils/tx-utils';
Expand All @@ -12,54 +11,65 @@ export function deregisterHandler(el: HTMLButtonElement | null, handler: (e: Eve
if (el === null) return;
el.removeEventListener('contextmenu', handler);
}

type UiClipboard = ReturnType<typeof useClipboard>;

interface TxListContextMenu {
tx: Transaction;
copy: {
txid: UiClipboard;
recipientAddress: UiClipboard;
memo: UiClipboard;
date: UiClipboard;
txDetails: UiClipboard;
explorerLink: UiClipboard;
txid: string;
recipientAddress: string;
memo: string;
date: string;
txDetails: string;
explorerLink: string;
};
}

export function createTxListContextMenu(event: Event, { tx, copy }: TxListContextMenu) {
event.preventDefault();
const menuItems: Electron.MenuItemConstructorOptions[] = [
const menuItems: { menu: Electron.MenuItemConstructorOptions; textToCopy?: string }[] = [
{
label: 'Copy to clipboard',
enabled: false,
menu: {
label: 'Copy to clipboard',
enabled: false,
},
},
{ type: 'separator' },
{ menu: { type: 'separator' } },
{
label: 'Transaction ID',
click: () => copy.txid.onCopy(),
textToCopy: copy.txid,
menu: {
label: 'Transaction ID',
},
},
{
label: 'Recipient address',
visible: !!getRecipientAddress(tx),
click: () => copy.recipientAddress.onCopy(),
textToCopy: copy.recipientAddress,
menu: {
label: 'Recipient address',
visible: !!getRecipientAddress(tx),
},
},
{
label: 'Memo',
visible: hasMemo(tx),
click: () => copy.memo.onCopy(),
textToCopy: copy.memo,
menu: {
label: 'Memo',
visible: hasMemo(tx),
},
},
{
label: 'Timestamp',
click: () => copy.date.onCopy(),
textToCopy: copy.date,
menu: {
label: 'Timestamp',
},
},
{
label: 'Transaction (as JSON)',
click: () => copy.txDetails.onCopy(),
textToCopy: copy.txDetails,
menu: {
label: 'Transaction (as JSON)',
},
},
{
label: 'Explorer link',
click: () => copy.explorerLink.onCopy(),
textToCopy: copy.explorerLink,
menu: {
label: 'Explorer link',
},
},
];
api.contextMenu(menuItems);
Expand Down
14 changes: 7 additions & 7 deletions app/components/home/transaction-list/transaction-list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React, {
} from 'react';
import { useSelector } from 'react-redux';
import { useHover, useFocus } from 'use-events';
import { Box, Text, useClipboard } from '@blockstack/ui';
import { Box, Text } from '@blockstack/ui';
import { Transaction } from '@blockstack/stacks-blockchain-api-types';

import { RootState } from '@store/index';
Expand Down Expand Up @@ -104,12 +104,12 @@ export const TransactionListItem: FC<TransactionListItemProps> = props => {
}

const { current: copy } = useRef({
txid: useClipboard(tx.tx_id),
recipientAddress: useClipboard(getRecipientAddress(tx) || ''),
memo: useClipboard(memo || ''),
date: useClipboard(txDate.toISOString()),
txDetails: useClipboard(JSON.stringify(tx, null, 2)),
explorerLink: useClipboard(makeExplorerLink(tx.tx_id)),
txid: tx.tx_id,
recipientAddress: getRecipientAddress(tx) || '',
memo: memo || '',
date: txDate.toISOString(),
txDetails: JSON.stringify(tx, null, 2),
explorerLink: makeExplorerLink(tx.tx_id),
});

useLayoutEffect(() => {
Expand Down
40 changes: 30 additions & 10 deletions app/main.dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import path from 'path';
import { app, BrowserWindow, ipcMain, Menu, MenuItem, session } from 'electron';
import { app, BrowserWindow, clipboard, ipcMain, Menu, session } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import windowState from 'electron-window-state';
Expand Down Expand Up @@ -192,12 +192,32 @@ ipcMain.handle('reload-app', () => {
mainWindow?.reload();
});

ipcMain.on('context-menu-open', (_e, { menuItems }) => {
const menu = new Menu();
menuItems.forEach((item: Electron.MenuItemConstructorOptions) => menu.append(new MenuItem(item)));
menu.popup({ window: mainWindow?.getParentWindow() });
menu.once('menu-will-close', () => {
// `destroy` call untyped
(menu as any).destroy();
});
});
//
// TODO: refactor to be more generic
// There's a bug where click handler doesn't fire for the top-level menu
ipcMain.on(
'context-menu-open',
(
_e,
args: { menuItems: { menu: Electron.MenuItemConstructorOptions; textToCopy?: string }[] }
) => {
const copyMenu = args.menuItems.map(item => {
const newItem = { ...item };
if (newItem.textToCopy) {
newItem.menu.click = () => clipboard.writeText(newItem.textToCopy as any);
}
return newItem.menu;
});
const contextMenu = Menu.buildFromTemplate([
{
label: 'Copy',
submenu: copyMenu,
},
]);
contextMenu.popup({ window: mainWindow?.getParentWindow() });
contextMenu.once('menu-will-close', () => {
// `destroy` call untyped
(contextMenu as any).destroy();
});
}
);

0 comments on commit 619c88e

Please sign in to comment.