squeaknode/frontend/src/features/squeaks/MakeResqueak.js
Jonathan Zernik 7658a4d95c
Upgrade squeaklib to v013 (#2165)
* Upgrade to squeaklib v0.13

* Allow different squeak types in server reponse

* Add core method for create resqueak.

* Add make resqueak method for squeak store

* Update db migration to include resqueak hash

* Add db method to insert and get resqueak

* Return resqueak as squeak entry in db query method

* Add RPC method for make resqueak

* Got make resqueak modal working in frontend

* Show different content for resqueak in frontend

* Show resqueaed squeak in display

* Show resqueak correctly

* Got resqueak display working on squeak card component

* Fix display for missing resqueaked squeak.

* Fix display for missing resqueaked squeak in squeak card.

* Got resqueak from squeak card working

* Fix prevent default action on resqueak unlock click

* Fix prevent default on make reply squeak in squeak card

* Got number of replies to resqueaked squeak working

* Fix click on squeak card

* Fix too many characters warning message

* Fix click on squeak card image and name and pubkey

* Rename set reply modal state function

* Fix toggle modals for resqueaked squeak

* Fix form submit action for squeak modals

* Include num resqueaks and num resqueaked resqueaks in get squeak entry db query

* Show number of resqueaks in frontend

* Fix distinct count in query for num replies and num resqueaks

* Update resqueaked squeak in slice state

* Update frontend build
2022-04-24 17:54:07 -07:00

165 lines
5.3 KiB
JavaScript

import React, { useEffect, useState, useContext, useRef } from 'react'
import { withRouter } from 'react-router-dom'
import { unwrapResult } from '@reduxjs/toolkit'
import moment from 'moment'
import ContentEditable from 'react-contenteditable'
import { Link } from 'react-router-dom'
import { getProfileImageSrcString } from '../../squeakimages/images';
import Loader from '../../components/Loader'
import { Form, Input, Select, Checkbox, Relevant, Debug, TextArea, Option, FormStateAccessor, useFormApi } from 'informed';
import { useSelector } from 'react-redux'
import { useDispatch } from 'react-redux'
import {
setMakeResqueak,
selectMakeResqueakStatus,
selectMakeSqueakStatus,
} from '../squeaks/squeaksSlice'
import {
selectSigningProfiles,
fetchSigningProfiles,
} from '../../features/profiles/profilesSlice'
const MakeResqueak = (props) => {
const signingProfiles = useSelector(selectSigningProfiles);
const makeSqueakStatus = useSelector(selectMakeSqueakStatus);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchSigningProfiles());
}, [])
const submitSqueak = ({ values }) => {
// TODO: toggle modal off here.
console.log(values);
console.log(values.signingProfileId);
if (!values.signingProfileId) {
alert('Signing Profile must be selected.');
return;
}
if (!props.resqueakedSqueak) {
alert('Resqueaked squeak cannot be empty.');
return;
}
const makeValues = {
signingProfile: values.signingProfileId,
resqueakedHash: props.resqueakedSqueak.getSqueakHash(),
replyTo: props.replyToSqueak ? props.replyToSqueak.getSqueakHash() : null,
}
console.log('makeResqueak');
dispatch(setMakeResqueak(makeValues))
.then(unwrapResult)
.then((squeakHash) => {
props.history.push(`/app/squeak/${squeakHash}`);
})
.catch((err) => {
alert(err.message);
});
if (props.submittedCallback) {
props.submittedCallback();
}
}
// TODO: Show profile image for selected signing profile.
// <div className="Squeak-profile-wrapper">
// {signingProfile && <img alt="" style={{ borderRadius: '50%', minWidth: '49px' }} width="100%" height="49px" src={`${getProfileImageSrcString(signingProfile)}`} />}
// </div>
const author = props.resqueakedSqueak && props.resqueakedSqueak.getAuthor();
const validateContent = value => {
if (!value || value.length > 280)
return 'Content must be less than 280 characters';
};
const SubmitButton = () => {
const formApi = useFormApi();
return <button
type="submit"
className={'squeak-btn-side squeak-btn-active'}
onClick={formApi.submitForm}>
Resqueak
</button>
};
const MakeResqueakForm = () => (
<Form onSubmit={submitSqueak} className="Squeak-input-side">
<Select class="informed-select" name="signingProfileId" initialValue="">
<Option value="" disabled>
Select Signing Profile...
</Option>
{signingProfiles.map(p => {
return <option value={p.getProfileId()}>{p.getProfileName()}</option>
})}
</Select>
<div className="inner-input-links">
<div className="input-links-side">
</div>
<div className="squeak-btn-holder">
<SubmitButton />
</div>
</div>
</Form>
);
return (
<>
{/* Squeak being resqueaked. */}
{props.resqueakedSqueak ?
<div className="reply-content-wrapper">
<div className="card-userPic-wrapper">
<Link onClick={(e)=>e.stopPropagation()} to={`/app/profile/${props.resqueakedSqueak.getAuthorPubkey()}`}>
<img alt="" style={{borderRadius:'50%', minWidth:'49px'}} width="100%" height="49px" src={author ? `${getProfileImageSrcString(props.resqueakedSqueak.getAuthor())}`: null}/>
</Link>
</div>
<div className="card-content-wrapper">
<div className="card-content-header">
<div className="card-header-detail">
<span className="card-header-user">
<Link onClick={(e)=>e.stopPropagation()} to={`/app/profile/${props.resqueakedSqueak.getAuthorPubkey()}`}>{author ? author.getProfileName(): 'Unknown Author'}</Link>
</span>
<span className="card-header-username">
<Link onClick={(e)=>e.stopPropagation()} to={`/app/profile/${props.resqueakedSqueak.getAuthorPubkey()}`}>{'@'+props.resqueakedSqueak.getAuthorPubkey()}</Link>
</span>
<span className="card-header-dot">·</span>
<span className="card-header-date">
{moment(props.resqueakedSqueak.getBlockTime() * 1000).fromNow()}
</span>
</div>
</div>
<div className="card-content-info">
{props.resqueakedSqueak.getContentStr()}
</div>
<div className="reply-to-user">
<span className="reply-squeak-username">
Replying to
</span>
<span className="main-squeak-user">
@{props.resqueakedSqueak.getAuthorPubkey()}
</span>
</div>
</div>
</div> : null }
{/* New squeak content input. */}
<div className="Squeak-input-wrapper">
<MakeResqueakForm />
</div>
</>
)
}
export default withRouter(MakeResqueak)