From b7cb7f57706288a388aa54a60e5312a6a6ee994e Mon Sep 17 00:00:00 2001 From: Kevin Burton Date: Tue, 6 Aug 2024 11:34:14 -0700 Subject: [PATCH 1/6] download the given content as a file. --- .../scripts/utils/downloadDataAsFile.ts | 19 +++++++++++++++++++ .../views/pages/view_proposal/JSONDisplay.tsx | 16 +++------------- 2 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts diff --git a/packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts b/packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts new file mode 100644 index 00000000000..508a031baf7 --- /dev/null +++ b/packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts @@ -0,0 +1,19 @@ +/** + * Save the content locally and use the `filename` as the suggested name for the + * file. + */ +export function downloadDataAsFile(content: string, filename: string) { + const blob = new Blob([content], { type: 'text/markdown' }); + + const link = document.createElement('a'); + link.href = URL.createObjectURL(blob); + link.download = filename; + + document.body.appendChild(link); + + link.click(); + + document.body.removeChild(link); + + URL.revokeObjectURL(link.href); +} diff --git a/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx b/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx index 255f4be9bc4..dcfaf02c820 100644 --- a/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx +++ b/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx @@ -3,6 +3,7 @@ import 'components/proposals/json_display.scss'; import { CoinObject } from 'controllers/chain/cosmos/types'; import React from 'react'; import app from 'state'; +import { downloadDataAsFile } from 'utils/downloadDataAsFile'; import { CWDivider } from '../../components/component_kit/cw_divider'; import { CWText } from '../../components/component_kit/cw_text'; import { CWButton } from '../../components/component_kit/new_designs/CWButton'; @@ -25,21 +26,10 @@ export const JSONDisplay = ({ data, title }: JSONDisplayProps) => { const isKYVE = app.chain.network === ChainNetwork.Kyve; const handleExport = () => { const dataTitle = data.title || 'Proposal'; + const filename = `${dataTitle}.md`; const proposalDetails = data.details || ''; - const blob = new Blob([proposalDetails], { type: 'text/markdown' }); - - const link = document.createElement('a'); - link.href = URL.createObjectURL(blob); - link.download = `${dataTitle}.md`; - - document.body.appendChild(link); - - link.click(); - - document.body.removeChild(link); - - URL.revokeObjectURL(link.href); + downloadDataAsFile(proposalDetails, filename); }; return ( From 5f9a824e0e02c3f2f178263c492ece9702a14009 Mon Sep 17 00:00:00 2001 From: Kevin Burton Date: Tue, 6 Aug 2024 11:57:53 -0700 Subject: [PATCH 2/6] download should start to work next. --- .../ThreadOptions/AdminActions/AdminActions.tsx | 8 ++++++++ .../views/pages/view_proposal/JSONDisplay.tsx | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx index e27142782e0..08b284a4720 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx @@ -357,6 +357,14 @@ export const AdminActions = ({ }, ] : []), + ...[ + { + onClick: handleDeleteThread, + label: 'Download as Markdown', + iconLeft: 'trash' as const, + iconLeftWeight: 'bold' as const, + }, + ], ...(isThreadAuthor || hasAdminPermissions ? [ ...(app.chain?.meta.snapshot.length diff --git a/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx b/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx index dcfaf02c820..255f4be9bc4 100644 --- a/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx +++ b/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx @@ -3,7 +3,6 @@ import 'components/proposals/json_display.scss'; import { CoinObject } from 'controllers/chain/cosmos/types'; import React from 'react'; import app from 'state'; -import { downloadDataAsFile } from 'utils/downloadDataAsFile'; import { CWDivider } from '../../components/component_kit/cw_divider'; import { CWText } from '../../components/component_kit/cw_text'; import { CWButton } from '../../components/component_kit/new_designs/CWButton'; @@ -26,10 +25,21 @@ export const JSONDisplay = ({ data, title }: JSONDisplayProps) => { const isKYVE = app.chain.network === ChainNetwork.Kyve; const handleExport = () => { const dataTitle = data.title || 'Proposal'; - const filename = `${dataTitle}.md`; const proposalDetails = data.details || ''; - downloadDataAsFile(proposalDetails, filename); + const blob = new Blob([proposalDetails], { type: 'text/markdown' }); + + const link = document.createElement('a'); + link.href = URL.createObjectURL(blob); + link.download = `${dataTitle}.md`; + + document.body.appendChild(link); + + link.click(); + + document.body.removeChild(link); + + URL.revokeObjectURL(link.href); }; return ( From 0b26057c4b55490bf34177840ad09ddf3535a549 Mon Sep 17 00:00:00 2001 From: Kevin Burton Date: Tue, 6 Aug 2024 13:41:44 -0700 Subject: [PATCH 3/6] Download icon and changes needed for downloading content. --- .../components/component_kit/cw_icons/cw_icon_lookup.ts | 2 ++ .../ThreadOptions/AdminActions/AdminActions.tsx | 6 ++++-- .../ThreadCard/ThreadOptions/ThreadOptions.tsx | 8 +++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts b/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts index 54d7b2c0796..5eb9137b57a 100644 --- a/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts +++ b/packages/commonwealth/client/scripts/views/components/component_kit/cw_icons/cw_icon_lookup.ts @@ -30,6 +30,7 @@ import { Compass, Copy, DotsThreeVertical, + Download, Export, Eye, Flag, @@ -240,6 +241,7 @@ export const iconLookup = { website: Icons.CWWebsite, write: Icons.CWWrite, members: Icons.CWMembers, + download: withPhosphorIcon(Download), }; export const customIconLookup = { diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx index 08b284a4720..d538ca71478 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx @@ -36,6 +36,7 @@ export type AdminActionsProps = { onEditStart?: () => any; onEditConfirm?: () => any; onEditCancel?: () => any; + onDownloadMarkdown?: () => void; hasPendingEdits?: boolean; editingDisabled?: boolean; }; @@ -54,6 +55,7 @@ export const AdminActions = ({ onEditConfirm, hasPendingEdits, editingDisabled, + onDownloadMarkdown, }: AdminActionsProps) => { const navigate = useCommonNavigate(); const [isEditCollaboratorsModalOpen, setIsEditCollaboratorsModalOpen] = @@ -359,9 +361,9 @@ export const AdminActions = ({ : []), ...[ { - onClick: handleDeleteThread, + onClick: () => onDownloadMarkdown?.(), label: 'Download as Markdown', - iconLeft: 'trash' as const, + iconLeft: 'download' as const, iconLeftWeight: 'bold' as const, }, ], diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx index 3eaf4799f5f..f19dac0f13e 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx @@ -12,6 +12,7 @@ import React, { import { useCreateThreadSubscriptionMutation } from 'state/api/trpc/subscription/useCreateThreadSubscriptionMutation'; import { useDeleteThreadSubscriptionMutation } from 'state/api/trpc/subscription/useDeleteThreadSubscriptionMutation'; import Permissions from 'utils/Permissions'; +import { downloadDataAsFile } from 'utils/downloadDataAsFile'; import { SharePopover } from 'views/components/SharePopover'; import { ViewUpvotesDrawerTrigger } from 'views/components/UpvoteDrawer'; import { CWThreadAction } from 'views/components/component_kit/new_designs/cw_thread_action'; @@ -93,6 +94,10 @@ export const ThreadOptions = ({ ); }, [isSubscribed, thread]); + const handleDownloadMarkdown = () => { + downloadDataAsFile(thread.plaintext, thread.title + '.md'); + }; + const createThreadSubscriptionMutation = useCreateThreadSubscriptionMutation(); const deleteThreadSubscriptionMutation = @@ -226,7 +231,7 @@ export const ThreadOptions = ({ /> )} - {canUpdateThread && thread && ( + {thread && ( From e26b549c29a38bb2e5fb1849fc24c3f23c2768d3 Mon Sep 17 00:00:00 2001 From: Kevin Burton Date: Tue, 6 Aug 2024 13:57:25 -0700 Subject: [PATCH 4/6] yield to canUpdateThread. --- .../ThreadOptions/AdminActions/AdminActions.tsx | 9 ++++++--- .../ThreadCard/ThreadOptions/ThreadOptions.tsx | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx index d538ca71478..a09ad51ac08 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx @@ -26,6 +26,7 @@ import './AdminActions.scss'; export type AdminActionsProps = { thread: Thread; + canUpdateThread: boolean; onDelete?: () => any; onSpamToggle?: (thread: Thread) => any; onLockToggle?: (isLocked: boolean) => any; @@ -56,6 +57,7 @@ export const AdminActions = ({ hasPendingEdits, editingDisabled, onDownloadMarkdown, + canUpdateThread, }: AdminActionsProps) => { const navigate = useCommonNavigate(); const [isEditCollaboratorsModalOpen, setIsEditCollaboratorsModalOpen] = @@ -298,7 +300,8 @@ export const AdminActions = ({ Date: Tue, 6 Aug 2024 14:01:55 -0700 Subject: [PATCH 5/6] fixed compilation issues. --- .../ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx index a09ad51ac08..764b5c04960 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/AdminActions/AdminActions.tsx @@ -26,7 +26,7 @@ import './AdminActions.scss'; export type AdminActionsProps = { thread: Thread; - canUpdateThread: boolean; + canUpdateThread?: boolean; onDelete?: () => any; onSpamToggle?: (thread: Thread) => any; onLockToggle?: (isLocked: boolean) => any; From 32af54105f3bd3f779d32a85dc3132f4d943426a Mon Sep 17 00:00:00 2001 From: Kevin Burton Date: Wed, 7 Aug 2024 10:34:04 -0700 Subject: [PATCH 6/6] reuse code... require the content type. --- .../client/scripts/utils/downloadDataAsFile.ts | 8 ++++++-- .../ThreadCard/ThreadOptions/ThreadOptions.tsx | 2 +- .../views/pages/view_proposal/JSONDisplay.tsx | 16 ++-------------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts b/packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts index 508a031baf7..2e2ca309f04 100644 --- a/packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts +++ b/packages/commonwealth/client/scripts/utils/downloadDataAsFile.ts @@ -2,8 +2,12 @@ * Save the content locally and use the `filename` as the suggested name for the * file. */ -export function downloadDataAsFile(content: string, filename: string) { - const blob = new Blob([content], { type: 'text/markdown' }); +export function downloadDataAsFile( + content: string, + type: string, + filename: string, +) { + const blob = new Blob([content], { type }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); diff --git a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx index b362c6da83c..697384a662c 100644 --- a/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx +++ b/packages/commonwealth/client/scripts/views/pages/discussions/ThreadCard/ThreadOptions/ThreadOptions.tsx @@ -95,7 +95,7 @@ export const ThreadOptions = ({ }, [isSubscribed, thread]); const handleDownloadMarkdown = () => { - downloadDataAsFile(thread.plaintext, thread.title + '.md'); + downloadDataAsFile(thread.plaintext, 'text/markdown', thread.title + '.md'); }; const createThreadSubscriptionMutation = diff --git a/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx b/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx index 255f4be9bc4..20e977e9364 100644 --- a/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx +++ b/packages/commonwealth/client/scripts/views/pages/view_proposal/JSONDisplay.tsx @@ -3,6 +3,7 @@ import 'components/proposals/json_display.scss'; import { CoinObject } from 'controllers/chain/cosmos/types'; import React from 'react'; import app from 'state'; +import { downloadDataAsFile } from 'utils/downloadDataAsFile'; import { CWDivider } from '../../components/component_kit/cw_divider'; import { CWText } from '../../components/component_kit/cw_text'; import { CWButton } from '../../components/component_kit/new_designs/CWButton'; @@ -26,20 +27,7 @@ export const JSONDisplay = ({ data, title }: JSONDisplayProps) => { const handleExport = () => { const dataTitle = data.title || 'Proposal'; const proposalDetails = data.details || ''; - - const blob = new Blob([proposalDetails], { type: 'text/markdown' }); - - const link = document.createElement('a'); - link.href = URL.createObjectURL(blob); - link.download = `${dataTitle}.md`; - - document.body.appendChild(link); - - link.click(); - - document.body.removeChild(link); - - URL.revokeObjectURL(link.href); + downloadDataAsFile(proposalDetails, 'text/markdown', `${dataTitle}.md`); }; return (