From 49bbd5f840ccf8af7f2e8b7e7012a252305e11d2 Mon Sep 17 00:00:00 2001 From: Top Gun <6207747+yakovkaravelov@users.noreply.github.com> Date: Wed, 3 Mar 2021 10:29:31 -0500 Subject: [PATCH] [DDW-566] Implement "Voting registration is over" screen (#2428) * [DDW-566] Implement voting registration end screen * [DDW-566] Update changelog * [DDW-566] Update date time formatting * [DDW-566] Update learn more link for ended registration * [DDW-566] Update voting registration end date config value --- CHANGELOG.md | 2 +- .../app/components/voting/VotingInfo.js | 191 +++++++++++++++--- .../app/components/voting/VotingInfo.scss | 49 +++++ source/renderer/app/config/votingConfig.js | 11 + .../voting/VotingRegistrationPage.js | 8 +- .../app/i18n/locales/defaultMessages.json | 146 ++++++++++--- source/renderer/app/i18n/locales/en-US.json | 7 + source/renderer/app/i18n/locales/ja-JP.json | 7 + source/renderer/app/stores/VotingStore.js | 19 ++ source/renderer/app/utils/formatters.js | 27 ++- storybook/stories/voting/Voting.stories.js | 10 +- 11 files changed, 417 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e858033c30..ada1112dc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ Changelog ### Features -- TBD +- Implemented "Voting registration is over" screen ([PR 2428](https://github.com/input-output-hk/daedalus/pull/2428)) ## 3.3.1 diff --git a/source/renderer/app/components/voting/VotingInfo.js b/source/renderer/app/components/voting/VotingInfo.js index fccc4ae7e8..dbe1401ca9 100644 --- a/source/renderer/app/components/voting/VotingInfo.js +++ b/source/renderer/app/components/voting/VotingInfo.js @@ -8,6 +8,14 @@ import { Link } from 'react-polymorph/lib/components/Link'; import { Checkbox } from 'react-polymorph/lib/components/Checkbox'; import SVGInline from 'react-svg-inline'; import BorderedBox from '../widgets/BorderedBox'; +import { + VOTING_REGISTRATION_END_DATE, + VOTING_REGISTRATION_CAST_START_DATE, + VOTING_REGISTRATION_CAST_END_DATE, + VOTING_REGISTRATION_NEW_START_DATE, +} from '../../config/votingConfig'; +import { formattedDateTime } from '../../utils/formatters'; +import type { Locale } from '../../../../common/types/locales.types'; import styles from './VotingInfo.scss'; import downloadAppStoreIcon from '../../assets/images/voting/download-app-store-icon-ic.inline.svg'; import downloadPlayStoreIcon from '../../assets/images/voting/download-play-store-icon-ic.inline.svg'; @@ -18,6 +26,17 @@ const messages = defineMessages({ defaultMessage: '!!!Register to vote on Fund3', description: 'Headline for voting registration steps', }, + headingForEndedRegistration: { + id: 'voting.info.headingForEndedRegistration', + defaultMessage: '!!!Fund3 Voting Registration Ended', + description: 'Headline for ended voting registration', + }, + descriptionForEndedRegistration: { + id: 'voting.info.descriptionForEndedRegistration', + defaultMessage: + '!!!
Voting registration for Project Catalyst Fund3 has been completed. The voting snapshot took place on {snapshotDate}.
If you have registered to vote on Fund3, you can cast your vote using the Catalyst Voting mobile app between {castStartDate} and {castEndDate}.
Fund4 registration will start on {newRegistrationStartDate}.
', + description: 'Description for ended voting registration', + }, stepTitle1: { id: 'voting.info.stepTitle1', defaultMessage: @@ -30,15 +49,36 @@ const messages = defineMessages({ '!!!$70.000 worth of ada rewards will be distributed between ada holders who register their vote.', description: 'Info step title 2 for voting registration steps', }, + learnMorePreviousLabel: { + id: 'voting.info.learnMorePreviousLabel', + defaultMessage: '!!!Please read the', + description: 'Learn more link previous label', + }, + learnMoreNextLabel: { + id: 'voting.info.learnMoreNextLabel', + defaultMessage: '!!!for more information.', + description: 'Learn more link next label', + }, learnMoreLinkLabel: { id: 'voting.info.learnMoreLinkLabel', defaultMessage: '!!!Learn more', - description: 'learnMoreLinkLabel for voting registration steps', + description: 'Learn more link label for registration steps', + }, + learnMoreLinkLabelForEndedRegistration: { + id: 'voting.info.learnMoreLinkLabelForEndedRegistration', + defaultMessage: '!!!Fund3 FAQs', + description: 'Learn more link label for ended registration', }, learnMoreLinkUrl: { id: 'voting.info.learnMoreLinkUrl', defaultMessage: '!!!https://cardano.ideascale.com/a/index', - description: 'learnMoreLinkUrl for voting registration steps', + description: 'Learn more link url for registration steps', + }, + learnMoreLinkUrlForEndedRegistration: { + id: 'voting.info.learnMoreLinkUrlForEndedRegistration', + defaultMessage: + '!!!https://iohk.zendesk.com/hc/en-us/articles/900004448046', + description: 'Learn more link url for ended registration', }, bottomContentTitle: { id: 'voting.info.bottomContentTitle', @@ -51,6 +91,12 @@ const messages = defineMessages({ '!!!To register to vote for Catalyst Fund3 you first need to download the Catalyst Voting app on your Android or iOS smartphone.', description: 'bottomContentDescription for voting registration steps', }, + bottomContentDescriptionForEndedRegistration: { + id: 'voting.info.bottomContentDescriptionForEndedRegistration', + defaultMessage: + '!!!To cast your vote on Project Catalyst Fund3 proposals, you need to download the Catalyst Voting app on your Android or iOS smartphone.', + description: 'bottomContentDescription for ended registration', + }, checkboxLabel: { id: 'voting.info.checkboxLabel', defaultMessage: '!!!I have installed the Catalyst Voting app', @@ -76,6 +122,10 @@ const messages = defineMessages({ }); type Props = { + currentLocale: Locale, + currentDateFormat: string, + currentTimeFormat: string, + isRegistrationEnded: boolean, onRegisterToVoteClick: Function, onExternalLinkClick: Function, }; @@ -102,53 +152,128 @@ export default class VotingInfo extends Component{stepTitle1}
-{stepTitle2}
+ {isRegistrationEnded ? ( +{stepTitle1}
+{stepTitle2}
+{bottomContentTitle}
-Voting registration for Project Catalyst Fund3 has been completed. The voting snapshot took place on {snapshotDate}.
If you have registered to vote on Fund3, you can cast your vote using the Catalyst Voting mobile app between {castStartDate} and {castEndDate}.
Fund4 registration will start on {newRegistrationStartDate}.
", + "description": "Description for ended voting registration", + "end": { + "column": 3, + "line": 39 + }, + "file": "source/renderer/app/components/voting/VotingInfo.js", + "id": "voting.info.descriptionForEndedRegistration", + "start": { + "column": 35, + "line": 34 } }, { @@ -8204,13 +8232,13 @@ "description": "Info step title 2 for voting registration steps", "end": { "column": 3, - "line": 26 + "line": 45 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.stepTitle1", "start": { "column": 14, - "line": 21 + "line": 40 } }, { @@ -8218,41 +8246,97 @@ "description": "Info step title 2 for voting registration steps", "end": { "column": 3, - "line": 32 + "line": 51 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.stepTitle2", "start": { "column": 14, - "line": 27 + "line": 46 + } + }, + { + "defaultMessage": "!!!Please read the", + "description": "Learn more link previous label", + "end": { + "column": 3, + "line": 56 + }, + "file": "source/renderer/app/components/voting/VotingInfo.js", + "id": "voting.info.learnMorePreviousLabel", + "start": { + "column": 26, + "line": 52 + } + }, + { + "defaultMessage": "!!!for more information.", + "description": "Learn more link next label", + "end": { + "column": 3, + "line": 61 + }, + "file": "source/renderer/app/components/voting/VotingInfo.js", + "id": "voting.info.learnMoreNextLabel", + "start": { + "column": 22, + "line": 57 } }, { "defaultMessage": "!!!Learn more", - "description": "learnMoreLinkLabel for voting registration steps", + "description": "Learn more link label for registration steps", "end": { "column": 3, - "line": 37 + "line": 66 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.learnMoreLinkLabel", "start": { "column": 22, - "line": 33 + "line": 62 + } + }, + { + "defaultMessage": "!!!Fund3 FAQs", + "description": "Learn more link label for ended registration", + "end": { + "column": 3, + "line": 71 + }, + "file": "source/renderer/app/components/voting/VotingInfo.js", + "id": "voting.info.learnMoreLinkLabelForEndedRegistration", + "start": { + "column": 42, + "line": 67 } }, { "defaultMessage": "!!!https://cardano.ideascale.com/a/index", - "description": "learnMoreLinkUrl for voting registration steps", + "description": "Learn more link url for registration steps", "end": { "column": 3, - "line": 42 + "line": 76 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.learnMoreLinkUrl", "start": { "column": 20, - "line": 38 + "line": 72 + } + }, + { + "defaultMessage": "!!!https://iohk.zendesk.com/hc/en-us/articles/900004448046", + "description": "Learn more link url for ended registration", + "end": { + "column": 3, + "line": 82 + }, + "file": "source/renderer/app/components/voting/VotingInfo.js", + "id": "voting.info.learnMoreLinkUrlForEndedRegistration", + "start": { + "column": 40, + "line": 77 } }, { @@ -8260,13 +8344,13 @@ "description": "bottomContentTitle for voting registration steps", "end": { "column": 3, - "line": 47 + "line": 87 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.bottomContentTitle", "start": { "column": 22, - "line": 43 + "line": 83 } }, { @@ -8274,13 +8358,27 @@ "description": "bottomContentDescription for voting registration steps", "end": { "column": 3, - "line": 53 + "line": 93 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.bottomContentDescription", "start": { "column": 28, - "line": 48 + "line": 88 + } + }, + { + "defaultMessage": "!!!To cast your vote on Project Catalyst Fund3 proposals, you need to download the Catalyst Voting app on your Android or iOS smartphone.", + "description": "bottomContentDescription for ended registration", + "end": { + "column": 3, + "line": 99 + }, + "file": "source/renderer/app/components/voting/VotingInfo.js", + "id": "voting.info.bottomContentDescriptionForEndedRegistration", + "start": { + "column": 48, + "line": 94 } }, { @@ -8288,13 +8386,13 @@ "description": "checkboxLabel for voting registration steps", "end": { "column": 3, - "line": 58 + "line": 104 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.checkboxLabel", "start": { "column": 17, - "line": 54 + "line": 100 } }, { @@ -8302,13 +8400,13 @@ "description": "Button Label for voting registration steps", "end": { "column": 3, - "line": 63 + "line": 109 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.buttonLabel", "start": { "column": 15, - "line": 59 + "line": 105 } }, { @@ -8316,13 +8414,13 @@ "description": "\"androidAppButtonUrl\" for the Catalyst voting app", "end": { "column": 3, - "line": 69 + "line": 115 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.androidAppButtonUrl", "start": { "column": 23, - "line": 64 + "line": 110 } }, { @@ -8330,13 +8428,13 @@ "description": "\"appleAppButtonUrl\" for the Catalyst voting app", "end": { "column": 3, - "line": 75 + "line": 121 }, "file": "source/renderer/app/components/voting/VotingInfo.js", "id": "voting.info.appleAppButtonUrl", "start": { "column": 21, - "line": 70 + "line": 116 } } ], diff --git a/source/renderer/app/i18n/locales/en-US.json b/source/renderer/app/i18n/locales/en-US.json index 6cdaca1e68..868f02bc9e 100755 --- a/source/renderer/app/i18n/locales/en-US.json +++ b/source/renderer/app/i18n/locales/en-US.json @@ -602,12 +602,19 @@ "voting.info.androidAppButtonUrl": "https://play.google.com/store/apps/details?id=io.iohk.vitvoting", "voting.info.appleAppButtonUrl": "https://apps.apple.com/in/app/catalyst-voting/id1517473397", "voting.info.bottomContentDescription": "To register to vote for Catalyst Fund3 you first need to download the Catalyst Voting app on your Android or iOS smartphone.", + "voting.info.bottomContentDescriptionForEndedRegistration": "To cast your vote on Project Catalyst Fund3 proposals, you need to download the Catalyst Voting app on your Android or iOS smartphone.", "voting.info.bottomContentTitle": "Download the Catalyst Voting app on your smartphone", "voting.info.buttonLabel": "Register to vote", "voting.info.checkboxLabel": "I have installed the Catalyst Voting app", + "voting.info.descriptionForEndedRegistration": "Voting registration for Project Catalyst Fund3 has been completed. The voting snapshot took place on {snapshotDate}.
If you have registered to vote on Fund3, you can cast your vote using the Catalyst Voting mobile app between {castStartDate} and {castEndDate}.
Fund4 registration will start on {newRegistrationStartDate}.
", "voting.info.heading": "Register to vote on Fund3", + "voting.info.headingForEndedRegistration": "Fund3 Voting Registration Ended", "voting.info.learnMoreLinkLabel": "Learn more", + "voting.info.learnMoreLinkLabelForEndedRegistration": "Fund3 FAQs", "voting.info.learnMoreLinkUrl": "https://cardano.ideascale.com/a/index", + "voting.info.learnMoreLinkUrlForEndedRegistration": "https://iohk.zendesk.com/hc/en-us/articles/900004448046", + "voting.info.learnMoreNextLabel": "for more information.", + "voting.info.learnMorePreviousLabel": "Please read the", "voting.info.noWallets.createWalletButtonLabel": "Create wallet", "voting.info.noWallets.headLine": "Voting registration for Fund3 is not available as you currently do not have any Shelley-compatible wallets.", "voting.info.noWallets.instructions": "Create a new wallet and transfer a minimum of {minVotingFunds} ADA (or restore an existing wallet with funds), then return here to register for voting.", diff --git a/source/renderer/app/i18n/locales/ja-JP.json b/source/renderer/app/i18n/locales/ja-JP.json index 470b7fb31f..ba5edc71e5 100755 --- a/source/renderer/app/i18n/locales/ja-JP.json +++ b/source/renderer/app/i18n/locales/ja-JP.json @@ -602,12 +602,19 @@ "voting.info.androidAppButtonUrl": "https://play.google.com/store/apps/details?id=io.iohk.vitvoting", "voting.info.appleAppButtonUrl": "https://apps.apple.com/in/app/catalyst-voting/id1517473397", "voting.info.bottomContentDescription": "Catalyst Fund3に有権者登録を行うためには、まずAndroidまたはiOSのスマートフォンにCatalyst Votingアプリをダウンロードする必要があります。", + "voting.info.bottomContentDescriptionForEndedRegistration": "Project Catalyst Fund3の提案に投票するには、AndroidまたはiOSのスマートフォンにCatalyst Votingアプリをダウンロードする必要があります。", "voting.info.bottomContentTitle": "スマートフォンにCatalyst Votingアプリをダウンロードします", "voting.info.buttonLabel": "有権者登録をする", "voting.info.checkboxLabel": "Catalyst Votingアプリをインストールしました", + "voting.info.descriptionForEndedRegistration": "Project Catalyst Fund3の有権者登録は完了しました。投票スナップショットは日本時間{snapshotDate}に実施されます。
Fund3への有権者登録を済ませている場合は、日本時間{castStartDate}から{castEndDate}の間に、携帯デバイスのCatalyst Votingアプリを使用して投票することができます。
Fund4の登録は日本時間{newRegistrationStartDate}に開始されます。
", "voting.info.heading": "Fund3の有権者登録をする", + "voting.info.headingForEndedRegistration": "Fund3の有権者登録は終了しました", "voting.info.learnMoreLinkLabel": "もっと知る", + "voting.info.learnMoreLinkLabelForEndedRegistration": "Fund3についてよくある質問", "voting.info.learnMoreLinkUrl": "https://cardano.ideascale.com/a/index", + "voting.info.learnMoreLinkUrlForEndedRegistration": "https://iohk.zendesk.com/hc/ja/articles/900004448046", + "voting.info.learnMoreNextLabel": "をご覧ください。", + "voting.info.learnMorePreviousLabel": "詳細は", "voting.info.noWallets.createWalletButtonLabel": "ウォレットを作成する", "voting.info.noWallets.headLine": "現在Shelley対応のウォレットがないため、Fund3の有権者登録はできません。", "voting.info.noWallets.instructions": "ウォレットを作成し、そこに{minVotingFunds} ADA以上を移してから(または既存の資金入りウォレットを復元してから)、改めてここで有権者登録を行ってください。", diff --git a/source/renderer/app/stores/VotingStore.js b/source/renderer/app/stores/VotingStore.js index b9836ddc34..b0ecb37de4 100644 --- a/source/renderer/app/stores/VotingStore.js +++ b/source/renderer/app/stores/VotingStore.js @@ -13,6 +13,8 @@ import { VOTING_REGISTRATION_TRANSACTION_POLLING_INTERVAL, VOTING_REGISTRATION_MIN_TRANSACTION_CONFIRMATIONS, VOTING_FUND_NUMBER, + VOTING_REGISTRATION_END_DATE, + VOTING_REGISTRATION_END_CHECK_INTERVAL, } from '../config/votingConfig'; import { votingPDFGenerator } from '../utils/votingPDFGenerator'; import { i18nContext } from '../utils/i18nContext'; @@ -29,8 +31,10 @@ export default class VotingStore extends Store { @observable votingRegistrationKey: ?VotingRegistrationKeyType = null; @observable qrCode: ?string = null; @observable isConfirmationDialogOpen: boolean = false; + @observable isRegistrationEnded: boolean = false; transactionPollingInterval: ?IntervalID = null; + registrationEndCheckInterval: ?IntervalID = null; setup() { const { voting: votingActions } = this.actions; @@ -45,6 +49,7 @@ export default class VotingStore extends Store { votingActions.resetRegistration.listen(this._resetRegistration); votingActions.showConfirmationDialog.listen(this._showConfirmationDialog); votingActions.closeConfirmationDialog.listen(this._closeConfirmationDialog); + this._initializeRegistrationEndCheckInterval(); } // REQUESTS @@ -100,6 +105,8 @@ export default class VotingStore extends Store { this.signMetadataRequest.reset(); if (this.transactionPollingInterval) clearInterval(this.transactionPollingInterval); + if (this.registrationEndCheckInterval) + clearInterval(this.registrationEndCheckInterval); }; @action _startTransactionPolling = () => { @@ -110,6 +117,14 @@ export default class VotingStore extends Store { }, VOTING_REGISTRATION_TRANSACTION_POLLING_INTERVAL); }; + @action _initializeRegistrationEndCheckInterval = () => { + if (this.registrationEndCheckInterval) + clearInterval(this.registrationEndCheckInterval); + this.registrationEndCheckInterval = setInterval(() => { + this._checkVotingRegistrationEnd(); + }, VOTING_REGISTRATION_END_CHECK_INTERVAL); + }; + @action _setVotingRegistrationKey = (value: VotingRegistrationKeyType) => { this.votingRegistrationKey = value; }; @@ -302,6 +317,10 @@ export default class VotingStore extends Store { } }; + @action _checkVotingRegistrationEnd = () => { + this.isRegistrationEnded = new Date() >= VOTING_REGISTRATION_END_DATE; + }; + _generateVotingRegistrationKey = async () => { const { Ed25519ExtendedPrivate: extendedPrivateKey } = await walletUtils; this._setVotingRegistrationKey(extendedPrivateKey.generate()); diff --git a/source/renderer/app/utils/formatters.js b/source/renderer/app/utils/formatters.js index cf886aff63..7da5e1d189 100644 --- a/source/renderer/app/utils/formatters.js +++ b/source/renderer/app/utils/formatters.js @@ -5,7 +5,7 @@ import { DECIMAL_PLACES_IN_ADA, LOVELACES_PER_ADA, } from '../config/numbersConfig'; -import { momentLocales } from '../../../common/types/locales.types'; +import { momentLocales, LOCALES } from '../../../common/types/locales.types'; import type { DownloadData } from '../../../common/types/downloadManager.types'; import type { Locale } from '../../../common/types/locales.types'; @@ -214,3 +214,28 @@ export const formattedSize = (size: string): string => { return formattedResult; }; + +export const formattedDateTime = ( + dateTime: Date, + { + currentLocale, + currentDateFormat, + currentTimeFormat, + }: { + currentLocale: Locale, + currentDateFormat: string, + currentTimeFormat: string, + } +) => { + moment.locale(momentLocales[currentLocale]); + + const dateTimeMoment = moment(dateTime); + const dateFormatted = dateTimeMoment.format(currentDateFormat); + const timeFormatted = dateTimeMoment.format(currentTimeFormat); + + if (currentLocale === LOCALES.english) { + return `${dateFormatted}, ${timeFormatted}`; + } + + return `${dateFormatted}${timeFormatted}`; +}; diff --git a/storybook/stories/voting/Voting.stories.js b/storybook/stories/voting/Voting.stories.js index dde39246a3..87588deecb 100644 --- a/storybook/stories/voting/Voting.stories.js +++ b/storybook/stories/voting/Voting.stories.js @@ -11,7 +11,11 @@ import VotingRegistrationStepsConfirm from '../../../source/renderer/app/compone import VotingRegistrationStepsEnterPinCode from '../../../source/renderer/app/components/voting/voting-registration-wizard-steps/VotingRegistrationStepsEnterPinCode'; import VotingRegistrationStepsQrCode from '../../../source/renderer/app/components/voting/voting-registration-wizard-steps/VotingRegistrationStepsQrCode'; import VotingInfo from '../../../source/renderer/app/components/voting/VotingInfo'; - +import { + LANGUAGE_OPTIONS, + DATE_ENGLISH_OPTIONS, + TIME_OPTIONS, +} from '../../../source/renderer/app/config/profileConfig'; import { VOTING_REGISTRATION_MIN_TRANSACTION_CONFIRMATIONS, VOTING_REGISTRATION_MIN_WALLET_FUNDS, @@ -110,6 +114,10 @@ storiesOf('Voting|Voting Info', module) .add('Voting Info', () => (