diff --git a/src/App.jsx b/src/App.jsx
index 8b90704d2..1e5e9d2a5 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -411,6 +411,7 @@ class App extends Component {
} />
} />
+ } />
} />
} />
} />
@@ -737,14 +738,14 @@ class App extends Component {
}
const WeVoteBody = styled('div')`
- background-color: #fff; // rgb(235, 236, 238); // #fafafa;
- color: #000;
+ // We rely on many of these from the body from main.css, including:
+ //background-color: #fff; // rgb(235, 236, 238); // #fafafa;
+ //color: #000;
+ //font-family: "Poppins", "Helvetica Neue Light", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+ //line-height: 1.4;
+ // margin: 0 auto;
+
display: block;
- font-family: "Poppins", "Helvetica Neue Light", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
- line-height: 1.4;
- margin: 0 auto;
- // max-width: 960px;
- //height: 100vw;
position: relative;
z-index: 0;
// this debug technique works! ${() => console.log('-----------------------------')}
diff --git a/src/css/main.css b/src/css/main.css
index 24af97cba..df8233bf4 100644
--- a/src/css/main.css
+++ b/src/css/main.css
@@ -59,8 +59,8 @@ body {
font-style:normal;
font-weight:normal;
letter-spacing:.15px;
- line-height:24px;
- margin:0;
+ line-height: 1.4;
+ margin:0 auto;
text-align:left
}
diff --git a/src/img/global/svg-icons/issues/rocket-ship.svg b/src/img/global/svg-icons/rocket-ship.svg
similarity index 100%
rename from src/img/global/svg-icons/issues/rocket-ship.svg
rename to src/img/global/svg-icons/rocket-ship.svg
diff --git a/src/js/actions/ReadyActions.js b/src/js/actions/ReadyActions.js
index 6f68edb45..b5b77a2e3 100644
--- a/src/js/actions/ReadyActions.js
+++ b/src/js/actions/ReadyActions.js
@@ -2,7 +2,7 @@ import Dispatcher from '../common/dispatcher/Dispatcher';
export default {
voterPlansForVoterRetrieve (year = 0, month = 0, googleCivicElectionId = 0, stateCode = '') {
- // Retrieve the click statistics for all of the items you have shared
+ // Retrieve the click statistics for all the items you have shared
return Dispatcher.loadEndpoint('voterPlansForVoterRetrieve', {
google_civic_election_id: googleCivicElectionId,
month,
diff --git a/src/js/common/actions/ChallengeInviteeActions.js b/src/js/common/actions/ChallengeInviteeActions.js
index 0f768833c..faccac9ce 100644
--- a/src/js/common/actions/ChallengeInviteeActions.js
+++ b/src/js/common/actions/ChallengeInviteeActions.js
@@ -16,11 +16,13 @@ export default {
});
},
- challengeInviteeSave (challengeWeVoteId, inviteeId = 0, inviteeName = '', inviteeNameChanged = false, inviteTextFromInviter = '', inviteTextFromInviterChanged = false, inviteeUrlCode = '', inviteeUrlCodeChanged = false) {
+ challengeInviteeSave (challengeWeVoteId, destinationFullURL = '', googleCivicElectionId = 0, inviteeId = 0, inviteeName = '', inviteeNameChanged = false, inviteTextFromInviter = '', inviteTextFromInviterChanged = false, inviteeUrlCode = '', inviteeUrlCodeChanged = false) {
// console.log('challengeInviteeSave called with challengeWeVoteId: ', challengeWeVoteId, ' and inviteeName: ', inviteeName);
Dispatcher.loadEndpoint('challengeInviteeSave',
{
challenge_we_vote_id: challengeWeVoteId,
+ destination_full_url: destinationFullURL,
+ google_civic_election_id: googleCivicElectionId,
invitee_id: inviteeId,
invitee_name: inviteeName,
invitee_name_changed: inviteeNameChanged,
diff --git a/src/js/common/actions/ShareActions.js b/src/js/common/actions/ShareActions.js
index c8a1d72d1..19bd11c18 100644
--- a/src/js/common/actions/ShareActions.js
+++ b/src/js/common/actions/ShareActions.js
@@ -28,7 +28,7 @@ export default {
},
sharedItemListRetrieve (year = 0, month = 0, googleCivicElectionId = 0, stateCode = '') {
- // Retrieve the click statistics for all of the items you have shared
+ // Retrieve the click statistics for all the items you have shared
return Dispatcher.loadEndpoint('sharedItemListRetrieve', {
google_civic_election_id: googleCivicElectionId,
month,
diff --git a/src/js/common/components/Challenge/ThanksForViewingChallenge.jsx b/src/js/common/components/Challenge/ThanksForViewingChallenge.jsx
index 441345393..73f866b2a 100644
--- a/src/js/common/components/Challenge/ThanksForViewingChallenge.jsx
+++ b/src/js/common/components/Challenge/ThanksForViewingChallenge.jsx
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
import Confetti from 'react-confetti';
import React, { useState, useEffect } from 'react';
-const ThanksForViewingChallenge = ({ challengeOwner }) => {
+const ThanksForViewingChallenge = ({ sharedByDisplayName }) => {
const [isClosing, setIsClosing] = useState(false);
const [showConfetti, setShowConfetti] = useState(false);
@@ -33,10 +33,18 @@ const ThanksForViewingChallenge = ({ challengeOwner }) => {
{showConfetti && }
- Thanks for confirming
- the link from
- {challengeOwner}
- !
+ Thanks for checking out this challenge
+ {sharedByDisplayName && (
+ <>
+ {' '}
+ your friend
+ {' '}
+ {sharedByDisplayName}
+ {' '}
+ has shared with you
+ >
+ )}
+ ! Join the challenge below.
{
);
};
ThanksForViewingChallenge.propTypes = {
- challengeOwner: PropTypes.string.isRequired,
+ sharedByDisplayName: PropTypes.string,
};
const CloseMessageIconWrapper = styled.div`
diff --git a/src/js/common/components/ChallengeInviteFriends/InviteFriendToChallengeInput.jsx b/src/js/common/components/ChallengeInviteFriends/InviteFriendToChallengeInput.jsx
index 83330ac0c..7f31894e8 100755
--- a/src/js/common/components/ChallengeInviteFriends/InviteFriendToChallengeInput.jsx
+++ b/src/js/common/components/ChallengeInviteFriends/InviteFriendToChallengeInput.jsx
@@ -17,6 +17,8 @@ const InviteFriendToChallengeInput = ({ classes, challengeWeVoteId, externalUniq
renderLog('InviteFriendToChallengeInputBox'); // Set LOG_RENDER_EVENTS to log all renders
const [challengeInviteTextDefault, setChallengeInviteTextDefault] = React.useState('');
const [challengeTitle, setChallengeTitle] = React.useState('');
+ const [destinationFullURL, setDestinationFullURL] = React.useState('');
+ const [googleCivicElectionId, setGoogleCivicElectionId] = React.useState(0);
const [inviteCopiedMessageOn, setInviteCopiedMessageOn] = React.useState(false);
const [inviteeName, setInviteeName] = React.useState('');
const [inviterName, setInviterName] = React.useState('');
@@ -31,9 +33,11 @@ const InviteFriendToChallengeInput = ({ classes, challengeWeVoteId, externalUniq
inviteTextToSendTemp1 += inviterFirstName ? `, this is ${inviterFirstName}. ` : ', ';
const inviteTextToSendTemp2 = inviteTextForFriends || challengeInviteTextDefault;
const inviteeUrlCode = ChallengeInviteeStore.getNextInviteeUrlCode();
- const urlToSendTemp = `${ChallengeStore.getSiteUrl(challengeWeVoteId)}/++/${inviteeUrlCode}`;
+ const urlToSendTemp = `${ChallengeStore.getSiteUrl(challengeWeVoteId)}/-${inviteeUrlCode}`;
const inviteTextToSendTemp3 = `${inviteTextToSendTemp1}${inviteTextToSendTemp2} ${urlToSendTemp}`;
setInviteTextToSend(inviteTextToSendTemp3);
+ const SEOFriendlyPath = ChallengeStore.getChallengeSEOFriendlyPathByWeVoteId(challengeWeVoteId);
+ setDestinationFullURL(`${ChallengeStore.getSiteUrl(challengeWeVoteId)}/${SEOFriendlyPath}/+/`);
// setUrlToSend(urlToSendTemp);
}
@@ -46,13 +50,21 @@ const InviteFriendToChallengeInput = ({ classes, challengeWeVoteId, externalUniq
const handleShare = async () => {
const inviteeUrlCode = ChallengeInviteeStore.getNextInviteeUrlCode();
- ChallengeInviteeActions.challengeInviteeSave(challengeWeVoteId, 0, inviteeName, true, inviteTextToSend, true, inviteeUrlCode, true);
+ ChallengeInviteeActions.challengeInviteeSave(
+ challengeWeVoteId,
+ destinationFullURL,
+ googleCivicElectionId,
+ 0,
+ inviteeName, true,
+ inviteTextToSend, true,
+ inviteeUrlCode, true,
+ );
setInviteCopiedMessageOn(true);
setTimeout(() => {
console.log('handleShare setTimeout fired');
setInviteCopiedMessageOn(false);
resetForm();
- }, 1000);
+ }, 2000);
if (navigator.share) {
try {
await navigator.share({
@@ -84,18 +96,22 @@ const InviteFriendToChallengeInput = ({ classes, challengeWeVoteId, externalUniq
};
const onChallengeParticipantStoreChange = () => {
- setInviterName(VoterStore.getFirstName());
setInviteTextForFriends(ChallengeParticipantStore.getInviteTextForFriends(challengeWeVoteId));
prepareInviteTextToSend();
};
const onChallengeStoreChange = () => {
- setInviterName(VoterStore.getFirstName());
setChallengeInviteTextDefault(ChallengeStore.getChallengeInviteTextDefaultByWeVoteId(challengeWeVoteId));
setChallengeTitle(ChallengeStore.getChallengeTitleByWeVoteId(challengeWeVoteId));
prepareInviteTextToSend();
};
+ const onVoterStoreChange = () => {
+ setGoogleCivicElectionId(VoterStore.electionId());
+ setInviterName(VoterStore.getFirstName());
+ prepareInviteTextToSend();
+ };
+
// console.log('Fetching participants for:', challengeWeVoteId);
const challengeInviteeStoreListener = ChallengeInviteeStore.addListener(onChallengeInviteeStoreChange);
onChallengeParticipantStoreChange();
@@ -103,11 +119,14 @@ const InviteFriendToChallengeInput = ({ classes, challengeWeVoteId, externalUniq
onChallengeParticipantStoreChange();
const challengeStoreListener = ChallengeStore.addListener(onChallengeStoreChange);
onChallengeStoreChange();
+ const voterStoreListener = VoterStore.addListener(onVoterStoreChange);
+ onVoterStoreChange();
return () => {
challengeInviteeStoreListener.remove();
challengeParticipantStoreListener.remove();
challengeStoreListener.remove();
+ voterStoreListener.remove();
};
}, [challengeWeVoteId]);
diff --git a/src/js/common/components/ChallengeInviteeListRoot/ChallengeInviteeListRoot.jsx b/src/js/common/components/ChallengeInviteeListRoot/ChallengeInviteeListRoot.jsx
index 233e93187..e300d155d 100644
--- a/src/js/common/components/ChallengeInviteeListRoot/ChallengeInviteeListRoot.jsx
+++ b/src/js/common/components/ChallengeInviteeListRoot/ChallengeInviteeListRoot.jsx
@@ -7,7 +7,7 @@ import FirstChallengeInviteeListController from './FirstChallengeInviteeListCont
import AppObservableStore, { messageService } from '../../stores/AppObservableStore';
import ChallengeInviteeStore from '../../stores/ChallengeInviteeStore';
import DesignTokenColors from '../Style/DesignTokenColors';
-import ChallengeParticipantStore from "../../stores/ChallengeParticipantStore";
+import ChallengeParticipantStore from '../../stores/ChallengeParticipantStore';
const ChallengeParticipantFirstRetrieveController = React.lazy(() => import(/* webpackChunkName: 'ChallengeParticipantFirstRetrieveController' */ '../ChallengeParticipant/ChallengeParticipantFirstRetrieveController'));
diff --git a/src/js/common/components/ChallengeInviteeListRoot/InviteAgainButton.jsx b/src/js/common/components/ChallengeInviteeListRoot/InviteAgainButton.jsx
index 0651e46b2..6fbcf626e 100755
--- a/src/js/common/components/ChallengeInviteeListRoot/InviteAgainButton.jsx
+++ b/src/js/common/components/ChallengeInviteeListRoot/InviteAgainButton.jsx
@@ -107,7 +107,7 @@ const InviteAgainButton = ({ classes, challengeWeVoteId, challengeInviteeId }) =
}
// console.log('challengeInviteTextDefault: ', challengeInviteTextDefault);
const inviteeUrlCode = ChallengeInviteeStore.getNextInviteeUrlCode();
- const urlToSendTemp = `${ChallengeStore.getSiteUrl(challengeWeVoteId)}/++/${inviteeUrlCode}`;
+ const urlToSendTemp = `${ChallengeStore.getSiteUrl(challengeWeVoteId)}/-${inviteeUrlCode}`;
const inviteTextToSendTemp3 = `${inviteTextToSendTemp1}${inviteTextToSendTemp2} ${urlToSendTemp}`;
setInviteTextToSend(inviteTextToSendTemp3);
// setUrlToSend(urlToSendTemp);
diff --git a/src/js/common/components/Navigation/ChallengeInviteSteps.jsx b/src/js/common/components/Navigation/ChallengeInviteSteps.jsx
index e1e20dd65..812de0fc2 100644
--- a/src/js/common/components/Navigation/ChallengeInviteSteps.jsx
+++ b/src/js/common/components/Navigation/ChallengeInviteSteps.jsx
@@ -39,6 +39,12 @@ class ChallengeInviteSteps extends React.Component {
return 1;
};
+ // Check if a step is active based on the current step number
+ // isStepActive = (stepNumber) => this.props.currentStep === stepNumber;
+
+ // Set a step as active when clicked
+ isStepActive = (stepNumber) => this.state.activeStep === stepNumber;
+
// Get the path for the challenge
getChallengeBasePath = () => {
const { challengeSEOFriendlyPath, challengeWeVoteId } = this.props;
@@ -51,9 +57,6 @@ class ChallengeInviteSteps extends React.Component {
return challengeBasePath;
};
- // Set a step as active when clicked
- isStepActive = (stepNumber) => this.state.activeStep === stepNumber;
-
// Update the active step when the link is clicked
handleStepClick = (stepNumber) => {
this.setState({ activeStep: stepNumber });
@@ -146,6 +149,7 @@ class ChallengeInviteSteps extends React.Component {
}
ChallengeInviteSteps.propTypes = {
+ currentStep: PropTypes.number.isRequired,
challengeSEOFriendlyPath: PropTypes.string,
challengeWeVoteId: PropTypes.string,
location: PropTypes.object.isRequired,
diff --git a/src/js/common/components/PrivacyBody.jsx b/src/js/common/components/PrivacyBody.jsx
index 568fc9e33..f410439ad 100755
--- a/src/js/common/components/PrivacyBody.jsx
+++ b/src/js/common/components/PrivacyBody.jsx
@@ -171,7 +171,7 @@ export default class PrivacyBody extends Component {
Who you Follow on Twitter
- When you sign in with Twitter, all of the Twitter accounts you follow on Twitter which have endorsements stored in WeVote, are displayed on your profile
+ When you sign in with Twitter, all the Twitter accounts you follow on Twitter which have endorsements stored in WeVote, are displayed on your profile
Yes
No
diff --git a/src/js/common/components/Settings/CompleteYourProfile.jsx b/src/js/common/components/Settings/CompleteYourProfile.jsx
index fc8f0dc0d..672ca865c 100644
--- a/src/js/common/components/Settings/CompleteYourProfile.jsx
+++ b/src/js/common/components/Settings/CompleteYourProfile.jsx
@@ -296,7 +296,7 @@ class CompleteYourProfile extends Component {
} else {
buttonText = 'Help them win';
}
- introductionText = Leading up to election day, WeVote.US will remind you to vote for all of the candidates you support. We keep your email secure and confidential.;
+ introductionText = Leading up to election day, WeVote.US will remind you to vote for all the candidates you support. We keep your email secure and confidential.;
} else if (supportCampaignOnCampaignHome) {
if (voterCanVoteForPoliticianInCampaign) {
buttonText = 'Support with my vote';
diff --git a/src/js/common/pages/Challenge/ChallengeHomePage.jsx b/src/js/common/pages/Challenge/ChallengeHomePage.jsx
index 9c68e960b..e4cc94581 100644
--- a/src/js/common/pages/Challenge/ChallengeHomePage.jsx
+++ b/src/js/common/pages/Challenge/ChallengeHomePage.jsx
@@ -44,6 +44,7 @@ import ChallengeAbout from '../../components/Challenge/ChallengeAbout';
import ChallengeParticipantListRoot from '../../components/ChallengeParticipantListRoot/ChallengeParticipantListRoot';
import ChallengeInviteeListRoot from '../../components/ChallengeInviteeListRoot/ChallengeInviteeListRoot';
import ThanksForViewingChallenge from '../../components/Challenge/ThanksForViewingChallenge'
+import ShareStore from '../../stores/ShareStore';
const ChallengeCardForList = React.lazy(() => import(/* webpackChunkName: 'ChallengeCardForList' */ '../../components/ChallengeListRoot/ChallengeCardForList'));
// const ChallengeCommentsList = React.lazy(() => import(/* webpackChunkName: 'ChallengeCommentsList' */ '../../components/Challenge/ChallengeCommentsList'));
@@ -108,6 +109,7 @@ class ChallengeHomePage extends Component {
challengeWeVoteIdForDisplay: '', // Value for challenge already received
sharingStepCompleted: false,
step2Completed: false,
+ thanksForViewingChallengeOn: false,
voterCanEditThisChallenge: false,
};
// this.onScroll = this.onScroll.bind(this);
@@ -116,7 +118,11 @@ class ChallengeHomePage extends Component {
componentDidMount () {
// console.log('ChallengeHomePage componentDidMount');
const { match: { params } } = this.props;
- const { challengeSEOFriendlyPath: challengeSEOFriendlyPathFromUrl, challengeWeVoteId } = params;
+ const {
+ challengeSEOFriendlyPath: challengeSEOFriendlyPathFromUrl,
+ challengeWeVoteId,
+ shared_item_code: sharedItemCodeIncoming,
+ } = params;
// console.log('ChallengeHomePage componentDidMount tabSelected: ', tabSelected);
// console.log('componentDidMount challengeSEOFriendlyPathFromUrl: ', challengeSEOFriendlyPathFromUrl, ', challengeWeVoteId: ', challengeWeVoteId);
this.onAppObservableStoreChange();
@@ -162,6 +168,20 @@ class ChallengeHomePage extends Component {
}
}, 5000); // April 19, 2021: Tuned to keep performance above 83. LCP at 597ms
+ // If we came in through a sharedItem link and then redirected to this page, fetch the shared item details
+ const sharedItem = ShareStore.getSharedItemByCode(sharedItemCodeIncoming);
+ // console.log('sharedItem:', sharedItem);
+ if (sharedItem && sharedItem.shared_by_display_name) {
+ const {
+ shared_by_display_name: sharedByDisplayName,
+ // shared_by_first_name: sharedByFirstName,
+ } = sharedItem;
+ this.setState({
+ sharedByDisplayName,
+ thanksForViewingChallengeOn: true,
+ });
+ }
+
// console.log('componentDidMount triggerSEOPathRedirect: ', triggerSEOPathRedirect, ', challengeSEOFriendlyPathFromObject: ', challengeSEOFriendlyPathFromObject);
if (triggerSEOPathRedirect && challengeSEOFriendlyPathFromObject) {
historyPush(`/${challengeSEOFriendlyPathFromObject}/+/`, true);
@@ -453,12 +473,9 @@ class ChallengeHomePage extends Component {
challengeDataFound, challengeDataNotFound,
challengeDescription, challengeDescriptionLimited, challengeImageUrlLarge,
challengeSEOFriendlyPath, challengeSEOFriendlyPathForDisplay,
- challengeTitle,
- challengeWeVoteIdForDisplay,
- scrolledDown,
- voterCanEditThisChallenge,
- voterIsChallengeParticipant,
- voterWeVoteId,
+ challengeTitle, challengeWeVoteIdForDisplay,
+ scrolledDown, sharedByDisplayName, thanksForViewingChallengeOn,
+ voterCanEditThisChallenge, voterIsChallengeParticipant, voterWeVoteId,
} = this.state;
// console.log('ChallengeHomePage render challengeSEOFriendlyPath: ', challengeSEOFriendlyPath, ', challengeSEOFriendlyPathForDisplay: ', challengeSEOFriendlyPathForDisplay);
const challengeAdminEditUrl = `${webAppConfig.WE_VOTE_SERVER_ROOT_URL}challenge/${challengeWeVoteId}/summary`;
@@ -520,10 +537,11 @@ class ChallengeHomePage extends Component {
);
return (
-
+ {thanksForViewingChallengeOn && (
+
+ )}
}>
@@ -200,7 +201,15 @@ class ChallengeInviteCustomizeMessage extends Component {
- Hi [your friend's name], it's David.
+ Hi [your friend's name]
+ {voterFirstName && (
+ <>
+ , it's
+ {' '}
+ {voterFirstName}
+ >
+ )}
+ .
diff --git a/src/js/common/pages/ChallengeInviteFriends/ChallengeInviteFriends.jsx b/src/js/common/pages/ChallengeInviteFriends/ChallengeInviteFriends.jsx
index 987bc91b6..be43f6f00 100644
--- a/src/js/common/pages/ChallengeInviteFriends/ChallengeInviteFriends.jsx
+++ b/src/js/common/pages/ChallengeInviteFriends/ChallengeInviteFriends.jsx
@@ -18,10 +18,12 @@ import { renderLog } from '../../utils/logging';
import DesignTokenColors from '../../components/Style/DesignTokenColors';
import ChallengeInviteSteps from '../../components/Navigation/ChallengeInviteSteps';
import ChallengeInviteeListRoot from '../../components/ChallengeInviteeListRoot/ChallengeInviteeListRoot';
+import ChallengeInviteeStore from '../../stores/ChallengeInviteeStore';
import InviteFriendToChallengeInput from '../../components/ChallengeInviteFriends/InviteFriendToChallengeInput';
import YourRank from '../../components/Challenge/YourRank';
const ChallengeRetrieveController = React.lazy(() => import(/* webpackChunkName: 'ChallengeRetrieveController' */ '../../components/Challenge/ChallengeRetrieveController'));
+const FirstChallengeInviteeListController = React.lazy(() => import(/* webpackChunkName: 'ChallengeRetrieveController' */ '../../components/ChallengeInviteeListRoot/FirstChallengeInviteeListController'));
const VoterFirstRetrieveController = loadable(() => import(/* webpackChunkName: 'VoterFirstRetrieveController' */ '../../components/Settings/VoterFirstRetrieveController'));
@@ -34,6 +36,7 @@ class ChallengeInviteFriends extends Component {
challengeTitle: '',
challengeWeVoteId: '',
chosenWebsiteName: '',
+ inviteeList: [],
};
}
@@ -42,6 +45,8 @@ class ChallengeInviteFriends extends Component {
this.props.setShowHeaderFooter(false);
this.onAppObservableStoreChange();
this.appStateSubscription = messageService.getMessage().subscribe(() => this.onAppObservableStoreChange());
+ this.onChallengeInviteeStoreChange();
+ this.challengeInviteeStoreListener = ChallengeInviteeStore.addListener(this.onChallengeInviteeStoreChange.bind(this));
this.onChallengeStoreChange();
this.challengeStoreListener = ChallengeStore.addListener(this.onChallengeStoreChange.bind(this));
const { match: { params } } = this.props;
@@ -85,6 +90,7 @@ class ChallengeInviteFriends extends Component {
componentWillUnmount () {
this.props.setShowHeaderFooter(true);
this.appStateSubscription.unsubscribe();
+ this.challengeInviteeStoreListener.remove();
this.challengeStoreListener.remove();
}
@@ -96,6 +102,16 @@ class ChallengeInviteFriends extends Component {
});
}
+ onChallengeInviteeStoreChange () {
+ const { challengeWeVoteId } = this.state;
+ if (challengeWeVoteId) {
+ const inviteeList = ChallengeInviteeStore.getChallengeInviteeList(challengeWeVoteId);
+ this.setState({
+ inviteeList,
+ });
+ }
+ }
+
onChallengeStoreChange () {
const { match: { params } } = this.props;
const { challengeSEOFriendlyPath: challengeSEOFriendlyPathFromParams, challengeWeVoteId: challengeWeVoteIdFromParams } = params;
@@ -153,7 +169,7 @@ class ChallengeInviteFriends extends Component {
renderLog('ChallengeInviteFriends'); // Set LOG_RENDER_EVENTS to log all renders
const {
challengePhotoLargeUrl, challengeSEOFriendlyPath, challengeTitle,
- challengeWeVoteId, chosenWebsiteName,
+ challengeWeVoteId, chosenWebsiteName, inviteeList,
} = this.state;
const htmlTitle = `Invite your friends - ${chosenWebsiteName}`;
return (
@@ -197,16 +213,21 @@ class ChallengeInviteFriends extends Component {
-
-
-
-
+ {inviteeList.length > 0 && (
+
+
+
+
+ )}
}>
}>
+ >}>
+
+
);
}
diff --git a/src/js/common/stores/ChallengeParticipantStore.js b/src/js/common/stores/ChallengeParticipantStore.js
index 5673ca1cf..9871bec13 100644
--- a/src/js/common/stores/ChallengeParticipantStore.js
+++ b/src/js/common/stores/ChallengeParticipantStore.js
@@ -6,7 +6,7 @@ import AppObservableStore from './AppObservableStore';
const orderByDateJoined = (firstEntry, secondEntry) => new Date(secondEntry.date_joined) - new Date(firstEntry.date_joined);
-const orderByParticipantsCount = (firstEntry, secondEntry) => secondEntry.points - firstEntry.points;
+const orderByPoints = (firstEntry, secondEntry) => secondEntry.points - firstEntry.points;
class ChallengeParticipantStore extends ReduceStore {
getInitialState () {
@@ -196,7 +196,7 @@ class ChallengeParticipantStore extends ReduceStore {
if (!action.res || !action.res.success) return state;
revisedState = state;
challengeParticipantList = action.res.challenge_participant_list || [];
- // A little filtering to keep data clean and avoid duplicates
+ // A little filtering to keep data clean and avoid duplicate participant entries tied to the same voter
challengeParticipantList.forEach((oneParticipant) => {
if (!(oneParticipant.voter_we_vote_id in voterWeVoteIdList) && oneParticipant.challenge_we_vote_id === action.res.challenge_we_vote_id) {
challengeParticipantListModified.push(oneParticipant);
@@ -204,7 +204,7 @@ class ChallengeParticipantStore extends ReduceStore {
voterWeVoteIdList.push(oneParticipant.voter_we_vote_id);
});
challengeParticipantListModified = challengeParticipantListModified.sort(orderByDateJoined);
- challengeParticipantListModified = challengeParticipantListModified.sort(orderByParticipantsCount);
+ challengeParticipantListModified = challengeParticipantListModified.sort(orderByPoints);
challengeParticipantListModified = challengeParticipantListModified.map((participant, index) => ({ ...participant, rank: index + 1 }));
challengeParticipantListModified.forEach((participant, index) => {
if (index === 0) {
diff --git a/src/js/common/stores/ChallengeStore.js b/src/js/common/stores/ChallengeStore.js
index 0d2162bfe..8a522c32c 100644
--- a/src/js/common/stores/ChallengeStore.js
+++ b/src/js/common/stores/ChallengeStore.js
@@ -2,6 +2,7 @@ import { ReduceStore } from 'flux/utils';
import { avatarGeneric } from '../../utils/applicationUtils';
import Dispatcher from '../dispatcher/Dispatcher';
import arrayContains from '../utils/arrayContains';
+import AppObservableStore from './AppObservableStore';
import VoterStore from '../../stores/VoterStore';
import daysUntil from '../utils/daysUntil'; // eslint-disable-line import/no-cycle
@@ -249,6 +250,14 @@ class ChallengeStore extends ReduceStore {
return SUPPORTERS_COUNT_NEXT_GOAL_DEFAULT;
}
+ getChallengeSEOFriendlyPathByWeVoteId (challengeWeVoteId) {
+ const challenge = this.getState().allCachedChallengeDicts[challengeWeVoteId];
+ if (challenge === undefined || challenge.seo_friendly_path === undefined) {
+ return '';
+ }
+ return challenge.seo_friendly_path;
+ }
+
getChallengeTitleByWeVoteId (challengeWeVoteId) {
const challenge = this.getState().allCachedChallengeDicts[challengeWeVoteId];
if (challenge === undefined || challenge.challenge_title === undefined) {
@@ -340,7 +349,7 @@ class ChallengeStore extends ReduceStore {
if (challenge && challenge.site_url) {
return challenge.site_url;
} else {
- return 'https://wevote.us';
+ return AppObservableStore.getWeVoteRootURL();
}
}
diff --git a/src/js/common/stores/ShareStore.js b/src/js/common/stores/ShareStore.js
index 824442cba..109ac635e 100644
--- a/src/js/common/stores/ShareStore.js
+++ b/src/js/common/stores/ShareStore.js
@@ -226,6 +226,9 @@ class ShareStore extends ReduceStore {
if (action.res.shared_item_code_all_opinions) {
allCachedSharedItemsBySharedItemCode[action.res.shared_item_code_all_opinions] = sharedItem;
}
+ if (action.res.shared_item_code_challenge) {
+ allCachedSharedItemsBySharedItemCode[action.res.shared_item_code_challenge] = sharedItem;
+ }
if (action.res.shared_item_code_ready) {
allCachedSharedItemsBySharedItemCode[action.res.shared_item_code_ready] = sharedItem;
}
diff --git a/src/js/components/Ballot/BallotScrollingContainer.jsx b/src/js/components/Ballot/BallotScrollingContainer.jsx
index 4deffbfe9..05a77ae22 100644
--- a/src/js/components/Ballot/BallotScrollingContainer.jsx
+++ b/src/js/components/Ballot/BallotScrollingContainer.jsx
@@ -100,7 +100,7 @@ class BallotScrollingContainer extends Component {
};
handleContainerClick = (e, weVoteId) => {
- console.log(e.target);
+ // console.log(e.target);
const candidateContainer = document.getElementById(`candidateContainer-${weVoteId}`);
const positionRowListOuterWrapper = document.getElementById(`positionRowListOuterWrapper-${weVoteId}`);
const candidateDiv = document.getElementById(`candidateDiv-${weVoteId}`);
@@ -116,7 +116,7 @@ class BallotScrollingContainer extends Component {
const buttonWrapper = document.getElementById(`buttonWrapper-${weVoteId}`);
// EAW VERIFY - might not need this one
const candidateParty = document.getElementById(`candidateParty-${weVoteId}`);
- console.log(buttonWrapper);
+ // console.log(buttonWrapper);
if (e.target === candidateDiv ||
e.target === candidateContainer ||
e.target === positionRowListOuterWrapper ||
diff --git a/src/js/components/Ballot/PositionDrawer.jsx b/src/js/components/Ballot/PositionDrawer.jsx
index ffd660604..a5c8b9222 100644
--- a/src/js/components/Ballot/PositionDrawer.jsx
+++ b/src/js/components/Ballot/PositionDrawer.jsx
@@ -120,7 +120,7 @@ class PositionDrawer extends Component {
}
// 2022-04-28 This slows down rendering too much
- // // We want to make sure we have all of the position information so that comments show up
+ // // We want to make sure we have all the position information so that comments show up
// const voterGuidesForThisBallotItem = VoterGuideStore.getVoterGuidesToFollowForBallotItemId(ballotItemWeVoteId);
//
// if (voterGuidesForThisBallotItem) {
diff --git a/src/js/components/Ballot/PositionItem.jsx b/src/js/components/Ballot/PositionItem.jsx
index ff05e0fe4..db5ec88cb 100644
--- a/src/js/components/Ballot/PositionItem.jsx
+++ b/src/js/components/Ballot/PositionItem.jsx
@@ -47,7 +47,7 @@ class PositionItem extends Component {
this.voterGuideStoreListener = VoterGuideStore.addListener(this.onVoterGuideStoreChange.bind(this));
// This creates too much load on the browser
- // // We want to make sure we have all of the position information so that comments show up
+ // // We want to make sure we have all the position information so that comments show up
// if (ballotItemWeVoteId) {
// const voterGuidesForThisBallotItem = VoterGuideStore.getVoterGuidesToFollowForBallotItemId(ballotItemWeVoteId);
//
@@ -105,7 +105,7 @@ class PositionItem extends Component {
// const { ballot_item_we_vote_id: ballotItemWeVoteId, speaker_we_vote_id: organizationWeVoteId } = position;
// This puts too much strain on the browser since PositionItems are in a list
- // // We want to make sure we have all of the position information so that comments show up
+ // // We want to make sure we have all the position information so that comments show up
// if (ballotItemWeVoteId) {
// const voterGuidesForThisBallotItem = VoterGuideStore.getVoterGuidesToFollowForBallotItemId(ballotItemWeVoteId);
//
diff --git a/src/js/components/Ballot/PositionItemSquare.jsx b/src/js/components/Ballot/PositionItemSquare.jsx
index b9f068e9e..a0c567812 100644
--- a/src/js/components/Ballot/PositionItemSquare.jsx
+++ b/src/js/components/Ballot/PositionItemSquare.jsx
@@ -31,7 +31,7 @@ class PositionItemSquare extends Component {
this.voterGuideStoreListener = VoterGuideStore.addListener(this.onVoterGuideStoreChange.bind(this));
// Creates too much load on the browser
- // // We want to make sure we have all of the position information so that comments show up
+ // // We want to make sure we have all the position information so that comments show up
// if (ballotItemWeVoteId) {
// const voterGuidesForThisBallotItem = VoterGuideStore.getVoterGuidesToFollowForBallotItemId(ballotItemWeVoteId);
//
@@ -89,7 +89,7 @@ class PositionItemSquare extends Component {
// const { position } = this.props;
// const { ballot_item_we_vote_id: ballotItemWeVoteId, speaker_we_vote_id: organizationWeVoteId } = position;
//
- // // We want to make sure we have all of the position information so that comments show up
+ // // We want to make sure we have all the position information so that comments show up
// if (ballotItemWeVoteId) {
// const voterGuidesForThisBallotItem = VoterGuideStore.getVoterGuidesToFollowForBallotItemId(ballotItemWeVoteId);
//
diff --git a/src/js/components/Ballot/PositionRowItem.jsx b/src/js/components/Ballot/PositionRowItem.jsx
index 2d7ba7033..513d8f34c 100644
--- a/src/js/components/Ballot/PositionRowItem.jsx
+++ b/src/js/components/Ballot/PositionRowItem.jsx
@@ -66,7 +66,7 @@ class PositionRowItem extends Component {
const { position } = this.props;
const { ballot_item_we_vote_id: ballotItemWeVoteId, speaker_we_vote_id: organizationWeVoteId } = position;
- // We want to make sure we have all of the position information so that comments show up
+ // We want to make sure we have all the position information so that comments show up
if (ballotItemWeVoteId) {
const voterGuidesForThisBallotItem = VoterGuideStore.getVoterGuidesToFollowForBallotItemId(ballotItemWeVoteId);
diff --git a/src/js/components/Ready/ReadyTaskBallot.jsx b/src/js/components/Ready/ReadyTaskBallot.jsx
index 85852c13c..13d674e47 100644
--- a/src/js/components/Ready/ReadyTaskBallot.jsx
+++ b/src/js/components/Ready/ReadyTaskBallot.jsx
@@ -32,7 +32,7 @@ class ReadyTaskBallot extends React.Component {
allCandidatesButtonNeeded: false, // Are there candidates on this ballot?
allCandidatesAllCompleted: false,
allCandidatesNumberCompleted: 0,
- allCandidatesShowButton: false, // Given all of the buttons we need to show, should this one be "unfurled"?
+ allCandidatesShowButton: false, // Given all the buttons we need to show, should this one be "unfurled"?
allCandidatesTotalNumber: 0,
federalButtonNeeded: false, // Are there Federal candidates on this ballot?
federalAllCompleted: false,
@@ -256,7 +256,7 @@ class ReadyTaskBallot extends React.Component {
// If there are measures, measureShowButton is always true
measureShowButton = (measureButtonNeeded);
// console.log('measureButtonNeeded:', measureButtonNeeded, ', measureShowButton:', measureShowButton);
- // If all of the possible decisions have been made
+ // If all the possible decisions have been made
allDecisionsMadeCount += federalAllCompleted ? 1 : 0;
allDecisionsMadeCount += localAllCompleted ? 1 : 0;
allDecisionsMadeCount += measureAllCompleted ? 1 : 0;
diff --git a/src/js/components/Ready/VoterPlanModal.jsx b/src/js/components/Ready/VoterPlanModal.jsx
index 78a91c667..431203e31 100644
--- a/src/js/components/Ready/VoterPlanModal.jsx
+++ b/src/js/components/Ready/VoterPlanModal.jsx
@@ -70,7 +70,7 @@ class VoterPlanModal extends Component {
}
componentDidUpdate (prevProps, prevState) {
- // Update the Json that we save with all of the settings
+ // Update the Json that we save with all the settings
const {
approximateTime, electionDateMonthYear, locationToDeliverBallot,
modeOfTransport, showToPublic, voterPlanDataSerializedCalculatedFirstTime,
diff --git a/src/js/components/Values/IssuesByBallotItemDisplayList.jsx b/src/js/components/Values/IssuesByBallotItemDisplayList.jsx
index faf50101d..991d4eac8 100644
--- a/src/js/components/Values/IssuesByBallotItemDisplayList.jsx
+++ b/src/js/components/Values/IssuesByBallotItemDisplayList.jsx
@@ -7,7 +7,7 @@ import VoterGuideStore from '../../stores/VoterGuideStore';
import signInModalGlobalState from '../../common/components/Widgets/signInModalGlobalState';
import ValueNameWithPopoverDisplay from './ValueNameWithPopoverDisplay';
-// Show a voter a horizontal list of all of the issues they are following that relate to this ballot item
+// Show a voter a horizontal list of all the issues they are following that relate to this ballot item
class IssuesByBallotItemDisplayList extends Component {
static closePopover () {
document.body.click();
diff --git a/src/js/components/Values/IssuesByOrganizationDisplayList.jsx b/src/js/components/Values/IssuesByOrganizationDisplayList.jsx
index 4943d7315..f7d873532 100644
--- a/src/js/components/Values/IssuesByOrganizationDisplayList.jsx
+++ b/src/js/components/Values/IssuesByOrganizationDisplayList.jsx
@@ -14,7 +14,7 @@ import IssueFollowToggleButton from './IssueFollowToggleButton';
const ReadMore = React.lazy(() => import(/* webpackChunkName: 'ReadMore' */ '../../common/components/Widgets/ReadMore'));
-// Show a voter a horizontal list of all of the issues they are following that relate to this ballot item
+// Show a voter a horizontal list of all the issues they are following that relate to this ballot item
class IssuesByOrganizationDisplayList extends Component {
static closePopover () {
document.body.click();
diff --git a/src/js/pages/SharedItemLanding.jsx b/src/js/pages/SharedItemLanding.jsx
index 5b1aa3098..dfd8e2802 100644
--- a/src/js/pages/SharedItemLanding.jsx
+++ b/src/js/pages/SharedItemLanding.jsx
@@ -18,6 +18,8 @@ export default class SharedItemLanding extends Component {
customLinkString: '',
destinationFullUrl: '',
destinationFullUrlOverride: '',
+ isBallotShare: false,
+ isChallengeShare: false,
sharedItemCodeIncoming: '',
sharedItemCodeRetrieved: false,
waitForVoterDeviceId: false,
@@ -59,41 +61,48 @@ export default class SharedItemLanding extends Component {
// destinationFullUrl,
// });
}
+ // console.log('sharedItemCodeIncoming:', sharedItemCodeIncoming);
if (sharedItemCodeIncoming) {
const sharedItem = ShareStore.getSharedItemByCode(sharedItemCodeIncoming);
// console.log('sharedItem:', sharedItem);
- const {
- destination_full_url: destinationFullUrl,
- destination_full_url_override: destinationFullUrlOverride,
- email_secret_key: emailSecretKey,
- is_ballot_share: isBallotShare,
- shared_item_code_all_opinions: sharedItemCodeAllOpinions,
- other_voter_display_name: voterDisplayName,
- other_voter_first_name: voterFirstName,
- other_voter_last_name: voterLastName,
- } = sharedItem;
- // console.log('SharedItemLanding emailSecretKey:', emailSecretKey);
- let waitForVoterDeviceId = false;
- if (emailSecretKey) {
- if (VoterStore.voterDeviceId()) {
- // We trigger this here (instead of on the API server with ShareActions.sharedItemRetrieveByCode)
- // to reduce delay around first page display
- // If the email hasn't been previously verified, this verifies it and attaches it to this account
- // console.log('SharedItemLanding firstName:', voterFirstName, ', lastName:', voterLastName, ', fullName:', voterDisplayName);
- VoterActions.voterEmailAddressVerify(emailSecretKey, voterFirstName, voterLastName, voterDisplayName);
- // VoterActions.voterFullNameSoftSave(voterFirstName, voterLastName, voterDisplayName);
- } else {
- waitForVoterDeviceId = true;
+ if (sharedItem && sharedItem.destination_full_url) {
+ const {
+ destination_full_url: destinationFullUrl,
+ destination_full_url_override: destinationFullUrlOverride,
+ email_secret_key: emailSecretKey,
+ is_ballot_share: isBallotShare,
+ is_challenge_share: isChallengeShare,
+ shared_item_code_all_opinions: sharedItemCodeAllOpinions,
+ other_voter_display_name: voterDisplayName,
+ other_voter_first_name: voterFirstName,
+ other_voter_last_name: voterLastName,
+ } = sharedItem;
+ // console.log('SharedItemLanding emailSecretKey:', emailSecretKey);
+ let waitForVoterDeviceId = false;
+ if (emailSecretKey) {
+ if (VoterStore.voterDeviceId()) {
+ // We trigger this here (instead of on the API server with ShareActions.sharedItemRetrieveByCode)
+ // to reduce delay around first page display
+ // If the email hasn't been previously verified, this verifies it and attaches it to this account
+ // console.log('SharedItemLanding firstName:', voterFirstName, ', lastName:', voterLastName, ', fullName:', voterDisplayName);
+ VoterActions.voterEmailAddressVerify(emailSecretKey, voterFirstName, voterLastName, voterDisplayName);
+ // VoterActions.voterFullNameSoftSave(voterFirstName, voterLastName, voterDisplayName);
+ } else {
+ waitForVoterDeviceId = true;
+ }
}
+ this.setState({
+ destinationFullUrl,
+ destinationFullUrlOverride,
+ isBallotShare,
+ isChallengeShare,
+ sharedItemCodeAllOpinions,
+ sharedItemCodeRetrieved: true,
+ waitForVoterDeviceId,
+ });
+ } else {
+ console.log('SharedItemLanding destination_full_url not found');
}
- this.setState({
- destinationFullUrl,
- destinationFullUrlOverride,
- isBallotShare,
- sharedItemCodeAllOpinions,
- sharedItemCodeRetrieved: true,
- waitForVoterDeviceId,
- });
}
}
@@ -110,7 +119,11 @@ export default class SharedItemLanding extends Component {
render () {
renderLog('SharedItemLanding'); // Set LOG_RENDER_EVENTS to log all renders
- const { componentDidMount, isBallotShare, destinationFullUrlOverride, sharedItemCodeAllOpinions, sharedItemCodeIncoming, sharedItemCodeRetrieved } = this.state;
+ const {
+ componentDidMount, destinationFullUrlOverride,
+ isBallotShare, isChallengeShare,
+ sharedItemCodeAllOpinions, sharedItemCodeIncoming, sharedItemCodeRetrieved,
+ } = this.state;
let { destinationFullUrl } = this.state;
// console.log('sharedItemCodeIncoming:', sharedItemCodeIncoming, 'sharedItemCodeAllOpinions:', sharedItemCodeAllOpinions);
// console.log('destinationFullUrl:', destinationFullUrl, 'destinationFullUrlOverride:', destinationFullUrlOverride);
@@ -124,7 +137,7 @@ export default class SharedItemLanding extends Component {
// console.log('SharedItemLanding sharedItemCodeRetrieved not retrieved');
return LoadingWheel;
} else if (sharedItemCodeRetrieved && (destinationFullUrl === undefined || destinationFullUrl === '')) {
- // console.log('SharedItemLanding destinationFullUrl undefined');
+ // console.log('SharedItemLanding destinationFullUrl undefined, directing to /ready');
this.localHistoryPush('/ready');
return LoadingWheel;
} else {
@@ -138,14 +151,20 @@ export default class SharedItemLanding extends Component {
// console.log('Ballot Share AllOpinions');
return ;
} else if (destinationFullUrl && destinationFullUrl.startsWith(hrefHostname)) {
- let destinationLocalUrl = destinationFullUrl.replace(hrefHostname, '');
- destinationLocalUrl = destinationLocalUrl.replace(':3000', ''); // For local development machines
- this.localHistoryPush(destinationLocalUrl);
- // const destinationLocalUrlWithModal = `${destinationLocalUrl}/modal/sic/${sharedItemCodeIncoming}`;
- // // console.log('*** WILL Direct to LOCAL destinationLocalUrlWithModal:', destinationLocalUrlWithModal);
- // historyPush(destinationLocalUrlWithModal);
+ let destinationPath = destinationFullUrl.replace(hrefHostname, '');
+ destinationPath = destinationPath.replace(':3000', ''); // For local development machines
+ if (isChallengeShare) {
+ // Add the sharedItemCode to the end of the URL so we have access to the sharedItem data on the next page
+ destinationPath += `-${sharedItemCodeIncoming}`;
+ }
+ // console.log('SharedItemLanding destinationPath:', destinationPath);
+ this.localHistoryPush(destinationPath);
+ // const destinationPathWithModal = `${destinationPath}/modal/sic/${sharedItemCodeIncoming}`;
+ // // console.log('*** WILL Direct to LOCAL destinationPathWithModal:', destinationPathWithModal);
+ // historyPush(destinationPathWithModal);
return LoadingWheel;
} else {
+ // console.log('SharedItemLanding destinationFullUrl:', destinationFullUrl);
this.localHistoryPush(destinationFullUrl);
// const destinationFullUrlWithModal = `${destinationFullUrl}/modal/sic/${sharedItemCodeIncoming}`;
// // console.log('*** WILL Direct to EXTERNAL destinationFullUrlWithModal:', destinationFullUrlWithModal);
diff --git a/src/js/stores/FriendStore.js b/src/js/stores/FriendStore.js
index 685a55db1..5ba54e882 100644
--- a/src/js/stores/FriendStore.js
+++ b/src/js/stores/FriendStore.js
@@ -459,7 +459,7 @@ class FriendStore extends ReduceStore {
if (!action.res.success) {
return state;
} else {
- // Firing all of these "just in case" api queries is slow, and firing queries from Stores should bed avoidd
+ // Firing all these "just in case" api queries is slow, and firing queries from Stores should bed avoidd
// console.log('resetting FriendStore from voterSignOut');
if (apiCalming('friendListsAll', 1500)) {
FriendActions.friendListsAll();
diff --git a/src/js/stores/IssueStore.js b/src/js/stores/IssueStore.js
index d92b81d7e..95cea01ff 100644
--- a/src/js/stores/IssueStore.js
+++ b/src/js/stores/IssueStore.js
@@ -237,7 +237,7 @@ class IssueStore extends ReduceStore {
// if (!ballotItemWeVoteId) {
// return 0;
// }
- // // These are scores based on all of the organizations under all of the issues a voter follows
+ // // These are scores based on all the organizations under all the issues a voter follows
// const issueScore = this.getState().issueScoreForEachBallotItem[ballotItemWeVoteId];
// if (issueScore === undefined) {
// return 0;
@@ -876,7 +876,7 @@ class IssueStore extends ReduceStore {
};
case 'voterGuidesUpcomingRetrieve': // List of all public voter guides from CDN
- // Collect all of the issues an organization is tagged with
+ // Collect all the issues an organization is tagged with
// console.log('IssueStore, case voterGuidesToFollowRetrieve');
voterGuides = action.res.voter_guides;
if (!voterGuides || voterGuides.length === 0) {