mirror of
https://github.com/acid-info/Kurate.git
synced 2025-01-12 17:04:07 +00:00
feat: post message to existing or draft persona (#229)
This commit is contained in:
parent
b32ab38593
commit
8a952af3f5
2
package-lock.json
generated
2
package-lock.json
generated
@ -40231,7 +40231,7 @@
|
||||
"tslib": "^2.5.0",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^4.1.1",
|
||||
"vitest": "*"
|
||||
"vitest": "^0.28.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/source-sans-pro": {
|
||||
|
60
packages/ui/src/lib/components/token-info.svelte
Normal file
60
packages/ui/src/lib/components/token-info.svelte
Normal file
@ -0,0 +1,60 @@
|
||||
<script lang="ts">
|
||||
import LearnMore from '$lib/components/learn-more.svelte'
|
||||
|
||||
export let title: string
|
||||
export let amount: string
|
||||
export let tokenName: string
|
||||
export let explanation: string
|
||||
export let link = '' // FIXME: make this required when we have FAQ build
|
||||
export let error = false
|
||||
</script>
|
||||
|
||||
<div class={`box ${error ? 'error' : ''}`}>
|
||||
<div class="h3">{title}</div>
|
||||
<div class="token-amt">{amount}</div>
|
||||
<div class="token">{tokenName}</div>
|
||||
<p>{explanation}</p>
|
||||
<LearnMore href={link} />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.box {
|
||||
border: 1px solid var(--grey-200);
|
||||
padding: var(--spacing-24);
|
||||
margin-top: var(--spacing-48);
|
||||
flex-basis: 100%;
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
|
||||
&.first-child {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
&.last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.token-amt {
|
||||
font-size: 40px;
|
||||
line-height: 1;
|
||||
font-weight: var(--font-weight-sb);
|
||||
margin-top: var(--spacing-12);
|
||||
}
|
||||
|
||||
.token {
|
||||
text-transform: uppercase;
|
||||
font-weight: var(--font-weight-sb);
|
||||
margin-bottom: var(--spacing-12);
|
||||
}
|
||||
|
||||
&.error {
|
||||
border: 1px solid var(--color-red);
|
||||
background-color: rgba(var(--color-red-rgb), 0.05);
|
||||
|
||||
.token-amt,
|
||||
.token {
|
||||
color: var(--color-red);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -2,14 +2,15 @@ import { writable, type Writable } from 'svelte/store'
|
||||
|
||||
export interface TokenData {
|
||||
go: number
|
||||
rep: number
|
||||
repTotal: number
|
||||
repStaked: number
|
||||
loading: boolean
|
||||
}
|
||||
|
||||
export type TokenStore = Writable<TokenData>
|
||||
|
||||
function createTokenStore(): TokenStore {
|
||||
const store = writable<TokenData>({ go: 30, rep: 0, loading: false })
|
||||
const store = writable<TokenData>({ go: 30, repTotal: 10, repStaked: 5, loading: false })
|
||||
|
||||
return store
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { profile } from '$lib/stores/profile'
|
||||
import { goto } from '$app/navigation'
|
||||
import { ROUTES } from '$lib/routes'
|
||||
import {
|
||||
createIdentity,
|
||||
generateGroupProof,
|
||||
@ -11,10 +9,28 @@
|
||||
joinGroupOffChain,
|
||||
joinGroupOnChain,
|
||||
} from '$lib/services/index'
|
||||
|
||||
import Checkmark from '$lib/components/icons/checkmark.svelte'
|
||||
import Close from '$lib/components/icons/close.svelte'
|
||||
|
||||
import { posts } from '$lib/stores/post'
|
||||
import { hashPost, createPost } from '$lib/services/posts'
|
||||
import { getWaku } from '$lib/services/waku'
|
||||
import PostNew from '$lib/components/post_new.svelte'
|
||||
import InfoScreen from '$lib/components/info_screen.svelte'
|
||||
import Info from '$lib/components/icons/information.svelte'
|
||||
import LearnMore from '$lib/components/learn-more.svelte'
|
||||
import Button from '$lib/components/button.svelte'
|
||||
import { tokens } from '$lib/stores/tokens'
|
||||
import TokenInfo from '$lib/components/token-info.svelte'
|
||||
import Undo from '$lib/components/icons/undo.svelte'
|
||||
|
||||
// FIXME: These should come from some constants
|
||||
const TOKEN_POST_COST_REP = 5
|
||||
const TOKEN_POST_COST_GO = 5
|
||||
|
||||
// FIXME: This should be stored in persona and loaded
|
||||
const TOKEN_POST_MIN_REP = 5
|
||||
|
||||
async function submit(postText: string) {
|
||||
try {
|
||||
@ -32,8 +48,7 @@
|
||||
|
||||
if (!group.members.includes(commitment)) {
|
||||
joinGroupOffChain(group, commitment)
|
||||
const txres = await joinGroupOnChain(globalAnonymousFeed, commitment)
|
||||
console.log(txres)
|
||||
await joinGroupOnChain(globalAnonymousFeed, commitment)
|
||||
}
|
||||
|
||||
const post = { text: postText }
|
||||
@ -49,11 +64,184 @@
|
||||
timestamp: Date.now(),
|
||||
text: postText,
|
||||
})
|
||||
goto(ROUTES.HOME)
|
||||
state = 'post_submitted'
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
function onBack() {
|
||||
history.back()
|
||||
}
|
||||
|
||||
let state: 'price_varning' | 'edit' | 'post_submitted' = 'price_varning'
|
||||
</script>
|
||||
|
||||
<PostNew {submit} />
|
||||
{#if state === 'price_varning'}
|
||||
{#if $tokens.repTotal < TOKEN_POST_MIN_REP}
|
||||
<InfoScreen title="Not enough REP" {onBack}>
|
||||
<div class="token-info">
|
||||
<div>
|
||||
<div class="icon">
|
||||
<Info size={32} />
|
||||
</div>
|
||||
<h2>Sorry, you can't submit a post now</h2>
|
||||
<p>You need at least {TOKEN_POST_MIN_REP} REP to submit a post through this Persona.</p>
|
||||
<LearnMore href="/" />
|
||||
</div>
|
||||
<TokenInfo
|
||||
title="Available to stake"
|
||||
amount={$tokens.repTotal.toFixed()}
|
||||
tokenName="REP"
|
||||
explanation={`Including staked`}
|
||||
error
|
||||
/>
|
||||
</div>
|
||||
<svelte:fragment slot="buttons">
|
||||
<Button label="Back" icon={Undo} on:click={onBack} />
|
||||
</svelte:fragment>
|
||||
</InfoScreen>
|
||||
{:else if $tokens.go < TOKEN_POST_COST_GO || $tokens.repTotal - $tokens.repStaked < TOKEN_POST_COST_REP}
|
||||
<InfoScreen title="Not enough token" {onBack}>
|
||||
<div class="token-info">
|
||||
<div>
|
||||
<div class="icon">
|
||||
<Info size={32} />
|
||||
</div>
|
||||
<h2>Sorry, you can't submit a post now</h2>
|
||||
<p>
|
||||
You need {TOKEN_POST_COST_REP} REP to stake and {TOKEN_POST_COST_GO} GO to submit a post.
|
||||
</p>
|
||||
<LearnMore href="/" />
|
||||
</div>
|
||||
<div class="side-by-side">
|
||||
<TokenInfo
|
||||
title="Available to stake"
|
||||
amount={($tokens.repTotal - $tokens.repStaked).toFixed()}
|
||||
tokenName="REP"
|
||||
explanation={`${$tokens.repStaked} out of ${$tokens.repTotal} staked`}
|
||||
error={$tokens.repTotal - $tokens.repStaked < TOKEN_POST_COST_REP}
|
||||
/>
|
||||
<TokenInfo
|
||||
title="Currently available"
|
||||
amount={$tokens.go.toFixed()}
|
||||
tokenName="GO"
|
||||
explanation="Until new cycle begins"
|
||||
error={$tokens.go < TOKEN_POST_COST_GO}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="buttons">
|
||||
<Button label="Back" icon={Undo} on:click={onBack} />
|
||||
</svelte:fragment>
|
||||
</InfoScreen>
|
||||
{:else}
|
||||
<InfoScreen title="Submit Post" {onBack}>
|
||||
<div class="token-info">
|
||||
<div>
|
||||
<div class="icon">
|
||||
<Info size={32} />
|
||||
</div>
|
||||
<h2>This will stake {TOKEN_POST_COST_REP} REP and use {TOKEN_POST_COST_GO} GO</h2>
|
||||
<p>
|
||||
Your post will be submitted to a community vote, and will be published if the majority
|
||||
votes to promote it. If promoted, you will earn {TOKEN_POST_COST_REP} REP. If demoted, you
|
||||
will lose your staked REP.
|
||||
</p>
|
||||
<p><LearnMore href="/" /></p>
|
||||
</div>
|
||||
<div class="side-by-side">
|
||||
<TokenInfo
|
||||
title="Available to stake"
|
||||
amount={($tokens.repTotal - $tokens.repStaked).toFixed()}
|
||||
tokenName="REP"
|
||||
explanation={`${$tokens.repStaked} out of ${$tokens.repTotal} staked`}
|
||||
/>
|
||||
<TokenInfo
|
||||
title="Currently available"
|
||||
amount={$tokens.go.toFixed()}
|
||||
tokenName="GO"
|
||||
explanation="Until new cycle begins"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<svelte:fragment slot="buttons">
|
||||
<Button
|
||||
label="I agree"
|
||||
variant="primary"
|
||||
icon={Checkmark}
|
||||
on:click={() => (state = 'edit')}
|
||||
/>
|
||||
<Button label="Nope" icon={Close} on:click={onBack} />
|
||||
</svelte:fragment>
|
||||
</InfoScreen>
|
||||
{/if}
|
||||
{:else if state === 'edit'}
|
||||
<PostNew {submit} {onBack} />
|
||||
{:else}
|
||||
<InfoScreen title="Post submitted">
|
||||
<div class="token-info">
|
||||
<div class="icon-success">
|
||||
<Checkmark />
|
||||
</div>
|
||||
<h2>Your post is now pending review</h2>
|
||||
<p>
|
||||
Your post has been added to "Persona name's" pending list for community review. If it gets
|
||||
promoted it will be automatically published to "Persona name's" page when the new epoch
|
||||
begins.
|
||||
</p>
|
||||
<LearnMore href="/" />
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="buttons">
|
||||
<Button icon={Checkmark} variant="primary" label="Done" on:click={() => history.back()} />
|
||||
</svelte:fragment>
|
||||
</InfoScreen>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
.side-by-side {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.token-info {
|
||||
text-align: center;
|
||||
|
||||
.icon {
|
||||
margin-bottom: var(--spacing-12);
|
||||
}
|
||||
|
||||
p,
|
||||
h2 {
|
||||
margin-bottom: var(--spacing-6);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-success {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-bottom: var(--spacing-12);
|
||||
|
||||
:global(svg) {
|
||||
fill: var(--color-body-bg);
|
||||
}
|
||||
|
||||
:global(polygon) {
|
||||
stroke: #fff;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
inset: -4px auto auto -6px;
|
||||
background-color: var(--color-success);
|
||||
border-radius: 50%;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
transform: translateX(2px);
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -23,6 +23,7 @@
|
||||
import { personas } from '$lib/stores/persona'
|
||||
import { tokens } from '$lib/stores/tokens'
|
||||
import { page } from '$app/stores'
|
||||
import TokenInfo from '$lib/components/token-info.svelte'
|
||||
|
||||
const PERSONA_LIMIT = 5
|
||||
const TOKEN_POST_COST = 10
|
||||
@ -155,15 +156,12 @@
|
||||
<p>This Persona will be live, and everyone will be able to post with it.</p>
|
||||
<p><LearnMore href="/" /></p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="h3">Currently available</div>
|
||||
<div class="go-amt">
|
||||
{$tokens.go}
|
||||
</div>
|
||||
<div class="go">GO</div>
|
||||
<p>Until new cycle begins</p>
|
||||
<LearnMore href="/" />
|
||||
</div>
|
||||
<TokenInfo
|
||||
title="Currently available"
|
||||
amount={$tokens.go.toFixed()}
|
||||
tokenName="GO"
|
||||
explanation="Until new cycle begins"
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="token-info">
|
||||
@ -175,15 +173,13 @@
|
||||
<p>You need {TOKEN_POST_COST} GO to publish a Persona.</p>
|
||||
<LearnMore href="/" />
|
||||
</div>
|
||||
<div class="box error">
|
||||
<div class="h3">Currently available</div>
|
||||
<div class="go-amt">
|
||||
{$tokens.go}
|
||||
</div>
|
||||
<div class="go">GO</div>
|
||||
<p>Until new cycle begins</p>
|
||||
<LearnMore href="/" />
|
||||
</div>
|
||||
<TokenInfo
|
||||
title="Currently available"
|
||||
amount={$tokens.go.toFixed()}
|
||||
tokenName="GO"
|
||||
explanation="Until new cycle begins"
|
||||
error
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@ -242,35 +238,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.box {
|
||||
border: 1px solid var(--grey-200);
|
||||
padding: var(--spacing-24);
|
||||
margin-top: var(--spacing-48);
|
||||
|
||||
.go-amt {
|
||||
font-size: 40px;
|
||||
line-height: 1;
|
||||
font-weight: var(--font-weight-sb);
|
||||
margin-top: var(--spacing-12);
|
||||
}
|
||||
|
||||
.go {
|
||||
text-transform: uppercase;
|
||||
font-weight: var(--font-weight-sb);
|
||||
margin-bottom: var(--spacing-12);
|
||||
}
|
||||
|
||||
&.error {
|
||||
border: 1px solid var(--color-red);
|
||||
background-color: rgba(var(--color-red-rgb), 0.05);
|
||||
|
||||
.go-amt,
|
||||
.go {
|
||||
color: var(--color-red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-success {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
Loading…
x
Reference in New Issue
Block a user