Skip to content

Nt/asking for vote #2927

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { SearchInput } from './searchInput';
import { SearchModal } from './searchModal';
import { SettingsItem } from './settingsItem';
import { SideMenu } from './sideMenu';
import { ProposalVoteRequest } from './proposalVoteRequest';

import CommunityCard from './communityCard';

Expand Down Expand Up @@ -272,4 +273,6 @@ export {
PostTranslationModal,
ImageViewer,
WalkthroughMarker,
ProposalVoteRequest

};
133 changes: 133 additions & 0 deletions src/components/proposalVoteRequest/container/proposalVoteRequest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import React, { useMemo, useState } from 'react';
import { Image, Text, View } from "react-native";
import styles from "../styles/ProposalVoteRequest.styles";
import { TextButton } from "../../../components/buttons";
import { MainButton } from "../../../components/mainButton";
import { useDispatch, useSelector } from "react-redux";
import { showActionModal } from "../../../redux/actions/uiAction";
import { ButtonTypes } from "../../../components/actionModal/container/actionModalContainer";
import { useProposalVotedQuery, useProposalVoteMutation } from '../../../providers/queries';
import { updateProposalVoteMeta } from '../../../redux/actions/cacheActions';
import { useIntl } from 'react-intl';

const ECENCY_PROPOSAL_ID = 283;
const RE_REQUEST_INTERVAL = 259200000; //3 days;

export const ProposalVoteRequest = () => {
const intl = useIntl();
const dispatch = useDispatch();

const proposalVotedQuery = useProposalVotedQuery(ECENCY_PROPOSAL_ID);
const proposalVoteMutation = useProposalVoteMutation();

const currentAccount = useSelector(state => state.account.currentAccount);

//assess if user should be promopted to vote proposal
//makes sure this logic is only calculated once on launch
const [skipOnLaunch] = useState(!currentAccount ||
proposalVotedQuery.data ||
proposalVotedQuery.meta?.processed);


//render or no render based on dimiss action performed
const skipRender = useMemo(() => {
if (!skipOnLaunch && proposalVotedQuery.meta) {
const curTime = new Date().getTime();
const nextRequestTime = proposalVotedQuery.meta.dismissedAt + RE_REQUEST_INTERVAL
return nextRequestTime > curTime;
}
return skipOnLaunch;
}, [proposalVotedQuery.meta])


if (skipRender) {
return null;
}

const voteCasted = proposalVoteMutation.isSuccess;

const _voteAction = () => {
proposalVoteMutation.mutate({ proposalId: ECENCY_PROPOSAL_ID })
}


const _remindLater = () => {
dispatch(showActionModal({
title: intl.formatMessage({id:'proposal.title-action-dismiss'}) ,// "Dismiss Vote Request",
buttons: [
{
text: intl.formatMessage({id:'proposal.btn-ignore'}),
type: ButtonTypes.CANCEL,
onPress: () => {
console.log('Ignore');
dispatch(updateProposalVoteMeta(
ECENCY_PROPOSAL_ID,
currentAccount.username,
true,
new Date().getTime()
))
},
},
{
text: intl.formatMessage({id:'proposal.btn-later'}),
onPress: () => {
dispatch(updateProposalVoteMeta(
ECENCY_PROPOSAL_ID,
currentAccount.username,
false,
new Date().getTime()
))
},
},
],
}))
};


const _actionPanel = () => {
return (
<View style={styles.actionPanel}>
<MainButton
onPress={_voteAction}
style={{ height: 40 }}
textStyle={styles.voteBtnTitle}
text={intl.formatMessage({id:'proposal.btn-vote'})}
isLoading={proposalVoteMutation.isLoading}

/>
<TextButton
onPress={_remindLater}
style={{ marginLeft: 8 }}
text={intl.formatMessage({id:'proposal.btn-dismiss'})}
/>
</View>
);
}

const titleTextId = voteCasted ? "proposal.title-voted" : "proposal.title";
const descTextId = voteCasted ? "proposal.desc-voted" : "proposal.desc"

return (
<View style={styles.container}>
<View style={styles.content} >
<View style={{ flex: 1 }}>
<Text style={styles.title} >
{intl.formatMessage({id:titleTextId})}
</Text>

<Text style={styles.description} >
{intl.formatMessage({id:descTextId})}
</Text>
</View>

<Image
resizeMode="contain"
style={{ width: 56, marginHorizontal: 12 }}
source={require('../../../assets/ecency_logo_transparent.png')}
/>

</View>
{!voteCasted && _actionPanel()}
</View>
)
};
1 change: 1 addition & 0 deletions src/components/proposalVoteRequest/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './container/proposalVoteRequest';
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { TextStyle, ViewStyle } from "react-native";
import EStyleSheet from "react-native-extended-stylesheet";

export default EStyleSheet.create({
container:{
backgroundColor:"$primaryLightBackground",
marginTop:16,
marginBottom:8,
padding:16,
flex: 1
} as ViewStyle,
content:{
flexDirection:'row',
alignItems:'center',
} as ViewStyle,
title:{
color:'$primaryDarkText',
fontSize: 18,
fontWeight: '600'
} as TextStyle,
description:{
color:'$primaryDarkText',
marginVertical:8
} as TextStyle,
actionPanel:{
flexDirection:'row',
alignItems:'center',
marginTop:8
} as ViewStyle,
voteBtnTitle:{
// color: '$primaryBlue'
} as TextStyle
})
11 changes: 11 additions & 0 deletions src/components/tabbedPosts/view/postsTabContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
usePromotedPostsQuery,
} from '../../../providers/queries/postQueries/feedQueries';
import { NewPostsPopup, ScrollTopPopup } from '../../atoms';
import { ProposalVoteRequest } from '../..';

let scrollOffset = 0;
let blockPopup = false;
Expand Down Expand Up @@ -137,6 +138,15 @@ const PostsTabContent = ({
}
};


const _renderHeader = () => {
if (pageType === 'main' && isInitialTab) {
return (
<ProposalVoteRequest />
)
}

}
// view rendereres
const _renderEmptyContent = () => {
const _isNoPost = !feedQuery.isLoading && feedQuery.data.length == 0;
Expand Down Expand Up @@ -194,6 +204,7 @@ const PostsTabContent = ({
ListEmptyComponent={_renderEmptyContent}
pageType={pageType}
showQuickReplyModal={_showQuickReplyModal}
ListHeaderComponent={_renderHeader}
/>
<NewPostsPopup
popupAvatars={feedQuery.latestPosts.map((post) => post.avatar || '')}
Expand Down
12 changes: 12 additions & 0 deletions src/config/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@
"continue": "Continue",
"okay": "Okay",
"done": "Done",
"thankyou": "Thank You!",
"notice": "Notice!",
"close": "CLOSE",
"later": "Later",
Expand Down Expand Up @@ -1148,5 +1149,16 @@
"missing-authority": "This operation requires Active private key or authority.",
"missing-owner-authority": "This operation requires Owner private key or authority.",
"insufficient_fund": "Insufficient Funds"
},
"proposal":{
"title":"Enjoying Ecency!",
"title-voted":"We are grateful!",
"desc":"Support proposal by voting, be part of our continuous efforts to improve experience on Ecency.",
"desc-voted":"Your support means everything to us",
"title-action-dismiss":"Dismiss Vote Request",
"btn-vote":"Cast My Vote",
"btn-dismiss":"Dismiss",
"btn-later":"Remind Later",
"btn-ignore":"Forever"
}
}
85 changes: 85 additions & 0 deletions src/providers/hive/dhive.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,33 @@ export const ignoreUser = async (currentAccount, pin, data) => {
);
};

export const getProposalsVoted = async (username) => {
try {
if (!username) {
throw new Error('invalid parameters');
}

console.log('Getting proposals voted:', username);

const votedProposals = await client.call(
'condenser_api',
'list_proposal_votes',
[[username], 100, "by_voter_proposal", "ascending", "active"]);

if (!Array.isArray(votedProposals)) {
throw new Error('invalid data');
}

const filteredProposals = votedProposals.filter(item => item.voter === username);

console.log(`Returning filtered proposals`, filteredProposals);
return filteredProposals;
} catch (error) {
bugsnapInstance.notify(error);
return [];
}
}

export const getActiveVotes = (author, permlink) =>
new Promise((resolve, reject) => {
try {
Expand Down Expand Up @@ -978,6 +1005,64 @@ const _vote = (currentAccount, pin, author, permlink, weight) => {
);
};


/**
* Update Hive Proposal Vote with current account as voter
* @param {*} currentAccount
* @param {*} pin
* @param {*} proposalId
* @returns
*/
export const voteProposal = (currentAccount, pinHash, proposalId) => {
const digitPinCode = getDigitPinCode(pinHash);
const key = getAnyPrivateKey(currentAccount.local, digitPinCode);

const voter = currentAccount.name;
const opArray = [
[
"update_proposal_votes",
{
voter: voter,
proposal_ids: [proposalId],
approve: true,
extensions: []
}
],
];

if (currentAccount.local.authType === AUTH_TYPE.STEEM_CONNECT) {
const token = decryptKey(currentAccount.local.accessToken, digitPinCode);
const api = new hsClient({
accessToken: token,
});

return api.broadcast(opArray).then((resp) => resp.result);
}

if (key) {
const privateKey = PrivateKey.fromString(key);

return new Promise((resolve, reject) => {
sendHiveOperations(opArray, privateKey)
.then((result) => {
console.log('vote result', result);
resolve(result);
})
.catch((err) => {
if (err && get(err, 'jse_info.code') === 4030100) {
err.message = getDsteemDateErrorMessage(err);
}
bugsnagInstance.notify(err);
reject(err);
});
});
}

return Promise.reject(
new Error('Check private key permission! Required private posting key or above.'),
);
};

/**
* @method upvoteAmount estimate upvote amount
*/
Expand Down
1 change: 1 addition & 0 deletions src/providers/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ export * from './walletQueries';
export * from './leaderboardQueries';
export * from './settingsQueries';
export * from './announcementsQueries';
export * from './proposalQueries';
Loading