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

fix index grid layout & disallow not-squared cover image uploading #29

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 44 additions & 12 deletions src/component/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,26 @@ import PodcastHtml from './podcast_html.jsx'
import { MESON_ENDPOINT } from '../utils/arweave.js'
/* make arbitrary change */
class Index extends Component {

constructor(props) {
super(props);
this.state = {
test: true,
podcasts: {}
podcasts: {},
// stores height passed by each podcast child
podcastsHeights: [],
// if loaded, change container visibility to true
isHeightsLoaded: false
}
}

// load height passed by each podcast child
loadPodcastHeight = (currentPodcastHeight) => {
this.setState({
podcastsHeights: [...this.state.podcastsHeights, currentPodcastHeight]
})
// console.log(this.state.podcastsHeights)
}

fetchAllSwcIds = async () => {
const response = await fetch("https://permacast-cache.herokuapp.com/feeds/podcasts", {
method: 'GET',
Expand All @@ -28,25 +39,30 @@ class Index extends Component {

return podcastList;
}
renderPodcasts = async (podcasts) => {

// First, render podcasts with auto height and hidden visibility.
// Then, calculate the max height.
// Then, render podcasts with max height and change visibility to visible.
renderPodcasts = async (podcasts, height = 'auto') => {
let html = []

for (let podcast of podcasts) {
console.log(podcast)
// console.log(podcast)
let p = podcast
if (p && p.pid !== 'aMixVLXScjjNUUcXBzHQsUPmMIqE3gxDxNAXdeCLAmQ') {
html.push(
<>
<div style={{height: height}}>
<PodcastHtml
loadPodcastHeight={this.loadPodcastHeight}
name={p.podcastName}
episodes={p.episodes.length}
link={p.pid}
description={p.description}
image={`${MESON_ENDPOINT}/${p.cover}`}
key={p.pid}
/>
</>
)
</div>
)
}
}
return html
Expand All @@ -55,20 +71,32 @@ class Index extends Component {
async componentDidMount() {
this.setState({loading: true})
this.setState({noPodcasts: false})
let pArrays = await this.loadPodcasts()
let pArrays = await this.loadPodcasts()
let p = pArrays.flat()
this.setState({podcasts: p})
this.setState({podcasts: p})
let podcasts = await this.renderPodcasts(this.state.podcasts)
this.setState({podcastHtml: podcasts})
this.setState({podcastHtml: podcasts})
if ( this.state.podcastHtml.length < 1 ) {
this.setState({noPodcasts: true})
}
this.setState({loading: false})
}

async componentDidUpdate(prevProps, prevState) {
// if for the last change of state, we get the final list of
// podcastsHeights, rerender with max height for podcast, not auto height
if (prevState.podcastsHeights.length + 1 === prevState.podcasts.length) {
let podcasts = await this.renderPodcasts(this.state.podcasts, Math.max(...this.state.podcastsHeights))
this.setState({
podcastHtml: podcasts,
isHeightsLoaded: true,
})
}
}

render() {
const podcasts = this.state.podcastHtml
return(
return(
<>
<Container className="mt-5">
<div className="">
Expand All @@ -77,7 +105,11 @@ class Index extends Component {
</div>
</Container>
<div>
<CardColumns>
{/*
hide container if load with podcasts of auto height
show container if load with podcasts of max height
*/}
<CardColumns style={{ visibility: this.state.isHeightsLoaded ? 'visible' : 'hidden' }}>
{podcasts}
</CardColumns>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/component/podcast.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Podcast extends Component {

return podcastList;
}

getPodcastEpisodes = async() => {
const pid = this.props.match.params.podcastId;

Expand Down Expand Up @@ -175,7 +175,7 @@ class Podcast extends Component {
const swcId = id
let res = await readContract(arweave, swcId)
return res
}
}
*/
truncatedDesc = (desc, maxLength) => {
if (desc.length < maxLength) {
Expand Down
37 changes: 31 additions & 6 deletions src/component/podcast_html.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@ import { arweave, smartweave, NEWS_CONTRACT } from '../utils/arweave.js'
import Swal from 'sweetalert2';

export default class PodcastHtml extends Component {
constructor(props) {
super(props)
this.state = {
podcastHeight: null
}
}

componentDidMount() {
setTimeout(() => {
this.loadPodcastHeight()
})
}

loadPodcastHeight() {
// if we receive loadPodcastHeight from props.
if (this.props.loadPodcastHeight) {
this.setState({
podcastHeight: this.container.offsetHeight
})
this.props.loadPodcastHeight(this.state.podcastHeight)
}
}

loadRss = () => {
console.log(this.props.rss)
Expand Down Expand Up @@ -84,17 +106,20 @@ export default class PodcastHtml extends Component {
}

render() {
console.log(this.props.rss)
return(
<Card className="text-center p-3 border-0">
<div className="image-item">
// console.log(this.props.rss)
const { podcastHeight } = this.state
return(
<Card className="text-center p-1 border-0" ref={ e => {this.container = e}}>
<div className="image-item" style={{ height: '300px'}}>
<a href={`/#/podcasts/${this.props.link}`}>
{/*!this.props.rss && <Badge className="episode-badge" bg="info">{this.episodeCount(this.props.episodes)}</Badge>*/} {/* TODO: stick badge to bounds of cover image, don't guess */}
<Image className="podcast-grid-cover" alt={`${this.props.name} cover`} src={this.props.image} />
</a>
</div>
<div className={this.props.titleClass || 'h3'}>{this.props.name} { this.props.rss ? <span><Button size="sm" className="rss-button" onClick={() => this.loadRss()}><FaRss/></Button> {this.tipButton()} </span> : null } </div>
<p>{this.props.description}</p>
<div>
<div className={this.props.titleClass || 'h3'}>{this.props.name} { this.props.rss ? <span><Button size="sm" className="rss-button" onClick={() => this.loadRss()}><FaRss/></Button> {this.tipButton()} </span> : null } </div>
<p>{this.props.description}</p>
</div>
</Card>
)
}
Expand Down
44 changes: 32 additions & 12 deletions src/component/upload_show.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { React, useState } from 'react';
import { React, useState, useRef } from 'react';
import { Button, Modal, Form } from 'react-bootstrap';
import ArDB from 'ardb';
import swal from 'sweetalert';
Expand All @@ -8,31 +8,32 @@ import Swal from 'sweetalert2';
const ardb = new ArDB(arweave)

export default function UploadShow() {
let finalShowObj = {}
let finalShowObj = {}
const [show, setShow] = useState(false);
const podcastCoverRef = useRef()

const deployContract = async () => {
const initialState = `{"podcasts": []}`
const tx = await arweave.createTransaction({data: initialState})

tx.addTag("Protocol", "permacast-testnet-v3")
tx.addTag("Action", "launchCreator")
tx.addTag("App-Name", "SmartWeaveAction")
tx.addTag("App-Version", "0.3.0")
tx.addTag("Contract-Src", CONTRACT_SRC)
tx.addTag("Content-Type", "application/json")
tx.addTag("Timestamp", Date.now())

await arweave.transactions.sign(tx)
await arweave.transactions.post(tx)
console.log(tx)
return tx.id
}

const handleUploadClick = () => {
setShow(true);
};

function readFileAsync(file) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
Expand Down Expand Up @@ -69,15 +70,15 @@ export default function UploadShow() {
await window.arweaveWallet.connect(["ACCESS_ADDRESS"]);
addr = await window.arweaveWallet.getActiveAddress()
}

tx = await ardb.search('transactions')
.from(addr)
.tag('App-Name', 'SmartWeaveAction')
.tag('Action', 'launchCreator')
.tag('Protocol', 'permacast-testnet-v3')
.tag('Contract-Src', CONTRACT_SRC)
.find();

console.log(tx)
if (tx.length !==0) {
contractId = tx[0].node.id
Expand Down Expand Up @@ -134,6 +135,25 @@ export default function UploadShow() {
});
}

const resetPodcastCover = () => {
podcastCoverRef.current.value = ""
Swal.fire({
text: 'Podcast cover image is not squared (1:1 aspect ratio)!',
icon: 'warning',
confirmButtonText: 'Continue'
})
}

const isPodcastCoverSquared = (event) => {
const podcastCoverImage = new Image()
podcastCoverImage.src = window.URL.createObjectURL(event.target.files[0])
podcastCoverImage.onload = () => {
if (podcastCoverImage.width !== podcastCoverImage.height) {
resetPodcastCover()
}
}
}

const handleShowUpload = async (event) => {
event.preventDefault()
// extract attrs from form
Expand Down Expand Up @@ -185,11 +205,11 @@ export default function UploadShow() {
return optionsArr
}

return(
<>
return(
<>
<span className="">
<Button variant="outline-primary" onClick={() => handleUploadClick()} style={{ marginRight: "1em" }}>+ Add a podcast</Button>
</span>
</span>
<Modal
show={show}
onClose={handleClose}
Expand All @@ -214,7 +234,7 @@ export default function UploadShow() {
</Form.Group>
<Form.Group className="mb-3" controlId="podcastCover">
<Form.Label>Cover image</Form.Label>
<Form.Control required type="file" /*onChange={(e) => readFile(e.target.files[0])*/ name="podcastCover"/>
<Form.Control required type="file" ref={podcastCoverRef} onChange={ e => isPodcastCoverSquared(e) } name="podcastCover"/>
</Form.Group>
<Form.Group className="mb-3" controlId="podcastAuthor">
<Form.Label>Author</Form.Label> {/* add tooltip */}
Expand Down