Skip to content
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

Nt/polls iteration #2870

Merged
merged 11 commits into from
May 14, 2024
15 changes: 10 additions & 5 deletions src/components/postPoll/children/pollChoices.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import EStyleSheet from 'react-native-extended-stylesheet';
import { PollChoice, PollVoter } from '../../../providers/polls/polls.types';
import { mapMetaChoicesToPollChoices } from '../../../providers/polls/converters';
import { CheckBox } from '../../checkbox';
import { PostMetadata } from '../../../providers/hive/hive.types';
import { PostMetadata, PollPreferredInterpretation } from '../../../providers/hive/hive.types';
import { PollModes } from '../container/postPoll';
import { TextButton } from '../../buttons';
import { useIntl } from 'react-intl';
import { get } from 'lodash';

interface PollChoicesProps {
loading: boolean;
Expand All @@ -21,6 +22,7 @@ interface PollChoicesProps {
selection: number;
voteDisabled: boolean;
hideVoters: boolean;
interpretationToken?: boolean
handleChoiceSelect: (optionNum: number) => void;
handleVotersPress: (optionNum: number) => void;
}
Expand All @@ -36,18 +38,20 @@ export const PollChoices = ({
selection,
voteDisabled,
hideVoters,
interpretationToken,
handleChoiceSelect,
handleVotersPress,
}: PollChoicesProps) => {
const intl = useIntl()

const [_choices, setChoices] = useState(
choices || mapMetaChoicesToPollChoices(metadata.choices));


const totalVotes = useMemo(
() => _choices.reduce(
(prevVal, option) => prevVal + (option?.votes?.total_votes) || 0, 0)
, [_choices]);
(prevVal, option) => prevVal + get(option.votes, interpretationToken ? 'hive_hp_incl_proxied':'total_votes', 0), 0)
, [_choices, interpretationToken]);


useEffect(() => {
Expand All @@ -69,7 +73,8 @@ export const PollChoices = ({
const _isVoted = !_isModeSelect && (userVote?.choice_num === option.choice_num)
const _isSelected = selection === option.choice_num

const votes = option.votes?.total_votes || 0;
const votes = Math.round(get(option.votes, interpretationToken ? 'hive_hp_incl_proxied':'total_votes', 0) * 1000 ) / 1000;

const percentage = (!_isModeSelect && !!totalVotes) ? (votes / totalVotes) * 100 : 0; //TODO: adjust logic here
const _barWidth = getWindowDimensions().width - 64;

Expand Down Expand Up @@ -103,7 +108,7 @@ export const PollChoices = ({
<TextButton
disabled={hideVoters}
textStyle={styles.count}
text={`${votes} ${intl.formatMessage({ id: 'post_poll.voted' })}`} onPress={_onVotersPress} />
text={`${votes} ${intl.formatMessage({ id: interpretationToken ? 'post_poll.hp':'post_poll.voted'})}`} onPress={_onVotersPress} />
}

</View>
Expand Down
17 changes: 11 additions & 6 deletions src/components/postPoll/children/pollHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Icon, PopoverWrapper } from '../../';
import { getTimeFromNow } from '../../../utils/time';
import EStyleSheet from 'react-native-extended-stylesheet';
import { useIntl } from 'react-intl';
import { PostMetadata } from '../../../providers/hive/hive.types';
import { PollPreferredInterpretation, PostMetadata } from '../../../providers/hive/hive.types';

interface PollHeaderProps {
metadata: PostMetadata
Expand All @@ -24,6 +24,14 @@ export const PollHeader = ({ metadata, expired }: PollHeaderProps) => {


const _ageLimit = metadata?.filters?.account_age || 0;
const _interpretationToken = metadata?.preferred_interpretation === PollPreferredInterpretation.TOKENS || false;


const _renderSubText = (text) => (
<Text style={styles.subText}>
{text}
</Text>
)

return (
<View>
Expand All @@ -43,11 +51,8 @@ export const PollHeader = ({ metadata, expired }: PollHeaderProps) => {

</PopoverWrapper>
</View>
{!!_ageLimit && (
<Text style={styles.subText}>
{intl.formatMessage({ id: "post_poll.age_limit" }, { days: _ageLimit })}
</Text>
)}
{!!_ageLimit && _renderSubText(intl.formatMessage({ id: "post_poll.age_limit" }, { days: _ageLimit }))}
{_interpretationToken && _renderSubText(intl.formatMessage({ id: "post_poll.interpretation_token" }))}
</View>

);
Expand Down
51 changes: 36 additions & 15 deletions src/components/postPoll/container/postPoll.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react'
import { View } from 'react-native'
import { ContentType, PostMetadata } from '../../../providers/hive/hive.types';
import { ContentType, PollPreferredInterpretation, PostMetadata } from '../../../providers/hive/hive.types';
import { PollChoices, PollHeader } from '../children';
import styles from '../styles/postPoll.styles';
import { pollQueries } from '../../../providers/queries';
Expand Down Expand Up @@ -44,33 +44,32 @@ export const PostPoll = ({

const [selection, setSelection] = useState(0);
const [mode, setMode] = useState(PollModes.LOADING)
const [interpretation, setInterpretation] = useState(metadata.preferred_interpretation || PollPreferredInterpretation.NUMBER_OF_VOTES);


const _isModeSelect = mode === PollModes.SELECT;
const _isInterpretationToken = interpretation === PollPreferredInterpretation.TOKENS;
const _isPollAuthor = author === currentAccount?.username;

const pollsQuery = pollQueries.useGetPollQuery(author, permlink, metadata)
const votePollMutation = pollQueries.useVotePollMutation(pollsQuery.data);
const _accAgeLimit = pollsQuery.data?.filter_account_age_days || metadata.filters?.account_age || 0;


const userVote = useMemo(() => {
const userVote = useMemo(() => {
if (pollsQuery.data) {
return pollsQuery.data.poll_voters.find(voter => voter.name === currentAccount.username)
}
}, [pollsQuery.data?.poll_voters, currentAccount.username])

const _expired = useMemo(
const _expired = useMemo(
() => new Date(metadata.end_time * 1000).getTime() < new Date().getTime(),
[metadata]);



const _hideStats = useMemo(() => !userVote && !_isPollAuthor, [metadata, userVote]);
const _hideVoters = useMemo(() => metadata.hide_votes && !_isPollAuthor, [metadata, _isPollAuthor]);
const _voteDisabled = useMemo(() => {

const _ageLimitApllies = currentAccount && _accAgeLimit
const _ageLimitApllies = currentAccount && _accAgeLimit
? getDaysPassedSince(currentAccount.created) < _accAgeLimit : false;

const _noVoteChange = metadata.vote_change !== undefined
Expand All @@ -86,6 +85,7 @@ export const PostPoll = ({
useEffect(() => {
if (pollsQuery.isSuccess) {
setMode(!!userVote || _expired ? PollModes.RESULT : PollModes.SELECT);
setInterpretation(pollsQuery.data?.preferred_interpretation || PollPreferredInterpretation.NUMBER_OF_VOTES)
}
}, [pollsQuery.isLoading, userVote])

Expand Down Expand Up @@ -122,6 +122,33 @@ export const PostPoll = ({
}


const _switchInterpretation = () => {
setInterpretation(_isInterpretationToken
? PollPreferredInterpretation.NUMBER_OF_VOTES
: PollPreferredInterpretation.TOKENS
)
}

const _authorPanel = _isPollAuthor && (
<View style={styles.authorPanel}>
<TextButton
text={intl.formatMessage({
id: _isModeSelect ? "post_poll.view_stats" : "post_poll.hide_stats"
})}
onPress={_handleModeToggle}
textStyle={styles.viewVotesBtn} />

{!_isModeSelect && (
<TextButton
text={intl.formatMessage({
id: _isInterpretationToken ? "post_poll.interpret_vote" : "post_poll.interpret_token"
})}
textStyle={styles.viewVotesBtn}
onPress={_switchInterpretation} />
)}

</View>
)

const _actionPanel = !_voteDisabled && (
<View style={styles.actionPanel}>
Expand All @@ -135,14 +162,6 @@ export const PostPoll = ({
text={"Vote"}
isDisable={!selection}
/>
{_isPollAuthor && (
<TextButton
text={intl.formatMessage({
id: _isModeSelect ? "post_poll.view_stats" : "post_poll.hide_stats"
})}
onPress={_handleModeToggle}
textStyle={styles.viewVotesBtn} />
)}

</View>
)
Expand All @@ -163,9 +182,11 @@ export const PostPoll = ({
mode={mode}
selection={selection}
hideVoters={_hideVoters}
interpretationToken={interpretation === PollPreferredInterpretation.TOKENS}
handleChoiceSelect={_handleChoiceSelect}
handleVotersPress={_handleVotersPress} />

{_authorPanel}
{_actionPanel}

</View>
Expand Down
7 changes: 6 additions & 1 deletion src/components/postPoll/styles/postPoll.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@ export default EStyleSheet.create({
alignItems: 'center',
justifyContent: 'space-between'
} as ViewStyle,
authorPanel:{
flexDirection:'row',
alignItems:'center',
justifyContent:'space-between',
marginBottom:8
} as ViewStyle,
actionPanel:{
flexDirection:'row-reverse',
alignItems:'center',

} as ViewStyle,
voteButton:{
width: 140,
Expand Down
4 changes: 4 additions & 0 deletions src/components/postView/view/postDisplayView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { PostComments } from '../../postComments';
import { UpvoteButton } from '../../postCard/children/upvoteButton';
import UpvotePopover from '../../upvotePopover';
import { PostPoll } from '../../postPoll';
import { useQueryClient } from '@tanstack/react-query';
import QUERIES from '../../../providers/queries/queryKeys';

const WIDTH = getWindowDimensions().width;

Expand All @@ -52,6 +54,7 @@ const PostDisplayView = ({
}) => {
const dispatch = useAppDispatch();
const insets = useSafeAreaInsets();
const queryClient = useQueryClient();
const userActivityMutation = useUserActivityMutation();

const postCommentsRef = useRef<PostComments>(null);
Expand Down Expand Up @@ -88,6 +91,7 @@ const PostDisplayView = ({
const onRefresh = useCallback(() => {
setRefreshing(true);
fetchPost().then(() => setRefreshing(false));
queryClient.resetQueries([QUERIES.POST.GET_POLL, author, permlink]);
}, [refreshing]);

const _scrollToComments = () => {
Expand Down
6 changes: 5 additions & 1 deletion src/config/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,15 @@
"post_poll":{
"voters":"Voters",
"voted":"voted",
"hp":"HP",
"view_stats":"View Stats",
"hide_stats":"Hide Stats",
"ended":"Ended",
"ends":"Ends {inTime}",
"age_limit":"\u2022 Only accounts older than {days} days allowed"
"age_limit":"\u2022 Only accounts older than {days} days allowed",
"interpretation_token":"\u2022 User HP based vote interpretation",
"interpret_token":"Interpret by Tokens",
"interpret_vote":"Interpret by Votes"
},
"editor": {
"title": "Title",
Expand Down
4 changes: 2 additions & 2 deletions src/providers/hive/hive.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export enum ContentType {
POLL = 'poll',
}

export enum PostPreferredInterpretation {
export enum PollPreferredInterpretation {
NUMBER_OF_VOTES = 'number_of_votes',
TOKENS = 'tokens'
}
Expand All @@ -24,7 +24,7 @@ export interface PostMetadata {

//POLL
question: string;
preferred_interpretation: PostPreferredInterpretation;
preferred_interpretation: PollPreferredInterpretation;
choices: string[];
filters: {
account_age: number
Expand Down
7 changes: 7 additions & 0 deletions src/providers/polls/polls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import { convertPoll } from "./converters";
import { getActiveKey, getDigitPinCode, sendHiveOperations } from "../hive/dhive";
import { Operation, PrivateKey } from "@esteemapp/dhive";


/**
* hive polls docs reference:
* https://gitlab.com/peakd/hive-open-polls
*
*/

const POLLS_BASE_URL = 'https://polls.ecency.com';

const PATH_RPC = 'rpc'
Expand Down
3 changes: 2 additions & 1 deletion src/providers/polls/polls.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PollPreferredInterpretation } from "../hive/hive.types";


//types generated by ChatGPT
Expand Down Expand Up @@ -38,7 +39,7 @@ export interface Poll {
image: any[]; // Adjust this type according to your data structure
protocol_version: number;
question: string;
preferred_interpretation: string;
preferred_interpretation: PollPreferredInterpretation;
token: string;
end_time: string;
status: string;
Expand Down
Loading