Skip to content

Commit 3eeda28

Browse files
wa0x6eSekhmet
andauthored
fix: fix empty voting period being overriden (#1014)
* fix: fix empty voting period being overriden * fix: set a default voting period when not set by the space * fix: use single source of truth for current time * fix: use custom proposal time only for offchain spaces * fix: use dynamix current timestamp * fix: make timestamp reactive * fix: make timestamp reactive * fix: use separate variable for max voting period * fix: fix offset in ms instead of seconds * docs: add notes about unix argument * Update apps/ui/src/views/Space/Editor.vue Co-authored-by: Wiktor Tkaczyński <[email protected]> --------- Co-authored-by: Wiktor Tkaczyński <[email protected]>
1 parent 3d53ddd commit 3eeda28

File tree

4 files changed

+55
-26
lines changed

4 files changed

+55
-26
lines changed

apps/ui/src/components/ProposalTimeline.vue

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,9 @@ const LABELS = {
2626
2727
const { getTsFromCurrent, getDurationFromCurrent } = useMetaStore();
2828
29-
const now = ref(parseInt((Date.now() / 1000).toFixed()));
29+
const timestamp = useTimestamp({ interval: 1000 });
3030
31-
onMounted(() => {
32-
const interval = setInterval(() => {
33-
now.value = parseInt((Date.now() / 1000).toFixed());
34-
}, 1000);
35-
36-
onUnmounted(() => {
37-
clearInterval(interval);
38-
});
39-
});
31+
const now = computed(() => Math.floor(timestamp.value / 1000));
4032
4133
function formatTimelineValues(): ProposalTimelineValues {
4234
const data = props.data;
@@ -94,6 +86,12 @@ const states: ComputedRef<State[]> = computed(() => {
9486
9587
return initial;
9688
});
89+
90+
// Use an offset to compare timestamps to avoid issues when comparing
91+
// timestamps that are not refreshed synchronously
92+
function isInThePast(timestamp: number): boolean {
93+
return timestamp <= now.value + 1;
94+
}
9795
</script>
9896

9997
<template>
@@ -106,12 +104,14 @@ const states: ComputedRef<State[]> = computed(() => {
106104
>
107105
<div
108106
class="absolute size-[15px] inline-block rounded-full left-[-7px] border-4 border-skin-bg"
109-
:class="state.value <= now ? 'bg-skin-heading' : 'bg-skin-border'"
107+
:class="
108+
isInThePast(state.value) ? 'bg-skin-heading' : 'bg-skin-border'
109+
"
110110
/>
111111
<div
112112
v-if="states[i + 1]"
113113
class="border-l pr-4 mt-3"
114-
:class="states[i + 1].value <= now && 'border-skin-heading'"
114+
:class="isInThePast(states[i + 1].value) && 'border-skin-heading'"
115115
/>
116116
</div>
117117
</div>

apps/ui/src/networks/offchain/api/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ import {
5656
ApiStrategy,
5757
ApiVote
5858
} from './types';
59-
import { DEFAULT_VOTING_DELAY } from '../constants';
6059

6160
const DEFAULT_AUTHENTICATOR = 'OffchainAuthenticator';
6261

@@ -175,8 +174,8 @@ function formatSpace(
175174
voting_types: space.voting.type
176175
? [space.voting.type]
177176
: constants.EDITOR_VOTING_TYPES,
178-
min_voting_period: space.voting.period ?? DEFAULT_VOTING_DELAY,
179-
max_voting_period: space.voting.period ?? DEFAULT_VOTING_DELAY,
177+
min_voting_period: space.voting.period ?? 0,
178+
max_voting_period: space.voting.period ?? 0,
180179
proposal_threshold: '1',
181180
treasuries,
182181
labels: space.labels,

apps/ui/src/networks/offchain/constants.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,3 @@ export const EDITOR_VOTING_TYPES: VoteType[] = [
2727
'weighted',
2828
'quadratic'
2929
];
30-
31-
export const DEFAULT_VOTING_DELAY = 60 * 60 * 24 * 7;

apps/ui/src/views/Space/Editor.vue

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { validateForm } from '@/helpers/validation';
1414
import { getNetwork, offchainNetworks } from '@/networks';
1515
import { Contact, Space, Transaction, VoteType } from '@/types';
1616
17+
const DEFAULT_VOTING_DELAY = 60 * 60 * 24 * 3;
18+
1719
const TITLE_DEFINITION = {
1820
type: 'string',
1921
title: 'Title',
@@ -54,6 +56,7 @@ const {
5456
} = usePropositionPower();
5557
const { strategiesWithTreasuries } = useTreasuries(props.space);
5658
const termsStore = useTermsStore();
59+
const timestamp = useTimestamp({ interval: 1000 });
5760
5861
const modalOpen = ref(false);
5962
const modalOpenTerms = ref(false);
@@ -173,6 +176,24 @@ const proposalLimitReached = computed(
173176
174177
const propositionPower = computed(() => getPropositionPower(props.space));
175178
179+
const unixTimestamp = computed(() => Math.floor(timestamp.value / 1000));
180+
181+
const proposalStart = computed(
182+
() => unixTimestamp.value + props.space.voting_delay
183+
);
184+
185+
const proposalMinEnd = computed(
186+
() =>
187+
proposalStart.value +
188+
(props.space.min_voting_period || DEFAULT_VOTING_DELAY)
189+
);
190+
191+
const proposalMaxEnd = computed(
192+
() =>
193+
proposalStart.value +
194+
(props.space.max_voting_period || DEFAULT_VOTING_DELAY)
195+
);
196+
176197
async function handleProposeClick() {
177198
if (!proposal.value) return;
178199
@@ -214,11 +235,10 @@ async function handleProposeClick() {
214235
);
215236
} else {
216237
const appName = (route.query.app as LocationQueryValue) || '';
217-
const currentTime = Math.floor(Date.now() / 1000);
218-
const start = currentTime + props.space.voting_delay;
219-
const minEnd = start + props.space.min_voting_period;
220-
const maxEnd = start + props.space.max_voting_period;
221238
239+
// Proposal start, min and end time are unix timestamp,
240+
// and are not compatible with onchain EMV spaces (those use blocks instead of timestamps)
241+
// (these args are ignored by onchain networks)
222242
result = await propose(
223243
props.space,
224244
proposal.value.title,
@@ -228,10 +248,10 @@ async function handleProposeClick() {
228248
choices,
229249
proposal.value.labels,
230250
appName.length <= 128 ? appName : '',
231-
currentTime,
232-
start,
233-
minEnd,
234-
maxEnd,
251+
unixTimestamp.value,
252+
proposalStart.value,
253+
proposalMinEnd.value,
254+
proposalMaxEnd.value,
235255
executions
236256
);
237257
}
@@ -567,7 +587,19 @@ watchEffect(() => {
567587
/>
568588
<div>
569589
<h4 class="eyebrow mb-2.5" v-text="'Timeline'" />
570-
<ProposalTimeline :data="space" />
590+
<ProposalTimeline
591+
:data="
592+
isOffchainSpace
593+
? {
594+
...space,
595+
created: unixTimestamp,
596+
start: proposalStart,
597+
min_end: proposalMinEnd,
598+
max_end: proposalMaxEnd
599+
}
600+
: space
601+
"
602+
/>
571603
</div>
572604
</div>
573605
</Affix>

0 commit comments

Comments
 (0)