Early production #15

Merged
innocuous-symmetry merged 4 commits from early-production into master 2022-02-18 00:22:05 +00:00
9 changed files with 44 additions and 132 deletions

View File

@@ -126,18 +126,13 @@
/* Feed */
.content-container {
display: inline-flex;
position: relative;
top: 5rem;
flex-direction: row;
}
.feed {
display: inline-flex;
flex-direction: column;
position: relative;
align-items: center;
width: 90vw;
top: 5rem;
}
/* Page handling */

View File

@@ -7,20 +7,9 @@ function App() {
return (
<div className="App">
<Navbar />
<div className="content-container">
<div className="feed">
<Feed />
</div>
<div className="about-the-site">
{/* To do: add mutable state to class name for this div, */}
{/* determining whether or not it's active based on the state of */}
{/* The action dispatched from the searchbar slice(?) */}
{/* Do I need a searchbar slice? */}
</div>
</div>
</div>
);
}

View File

@@ -1,19 +0,0 @@
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
test('renders text', () => {
const { getByText } = render(
<Provider store={store}>
<App />
</Provider>
);
expect(getByText(/Stuff/)).toBeInTheDocument();
});
test('store is not empty or falsy', () => {
expect(store).not.toBeNull();
})

View File

@@ -3,7 +3,8 @@
.post-body {
display: inline-flex;
flex-direction: column;
width: 75%;
align-items: center;
width: 85%;
padding: 1rem 2rem;
border-radius: 10px;
background-color: rgb(29, 4, 39);
@@ -28,6 +29,7 @@
img, video {
max-height: 45rem;
max-width: 95%;
object-fit: contain;
}
@@ -35,6 +37,7 @@ img, video {
.post-metadata {
display: inline-flex;
width: 90%;
margin-top: 1rem;
padding-top: 0.5rem;
border-top: 1px solid gray;
@@ -99,6 +102,7 @@ img, video {
display: inline-flex;
flex-direction: column;
align-items: center;
max-width: 80%;
}
#post-audio {

View File

@@ -91,11 +91,12 @@ export default function Post({data, key}) {
// before the fetch requests' promises are fulfilled.
return (
<>
<div className="post-body" key={key}>
{title ?
<a className="title" href={`https://reddit.com${permalink}`}>{title}</a>
: <p>[untitled]</p>}
{media ? <img alt={title} src={media} /> : null}
@@ -129,8 +130,6 @@ export default function Post({data, key}) {
<div className={commentStyle}>
<Discussion permalink={permalink} isVisible={visible} />
</div>
</div>
</>
);
}

View File

@@ -1,53 +0,0 @@
import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { searchByActive, /* selectSearchResults */ } from '../posts/postsSlice';
import { selectActive, /* selectAllSubs */ } from "../reddit/redditSlice";
export default function SearchBar() {
const dispatch = useDispatch();
// const selectedSubs = useSelector(selectAllSubs);
const activeSubs = useSelector(selectActive);
const [term, setTerm] = useState('');
const [results, setResults] = useState(null);
// const searchData = useSelector(selectSearchResults);
const handleChange = (e) => {
e.preventDefault();
setTerm(e.target.value);
}
const handleSubmit = () => {
if (term && activeSubs) {
let extracted = [];
for (let sub in activeSubs) {
extracted.push(sub);
}
console.log(extracted);
let mapped = extracted.map((sub) => dispatch(searchByActive({sub, term})));
Promise.all([...mapped]).then((data) => setResults(data));
}
}
useEffect(() => {
let active = true;
if (results && active) {
console.log(results);
}
return () => {
active = false;
}
}, [results, activeSubs]);
return (
<>
<input type="text" className="nav-searchbar" placeholder="Search posts" value={term ? term : ''} onChange={handleChange} />
<input type="submit" onClick={handleSubmit}></input>
</>
);
}

View File

@@ -1,5 +1,5 @@
import React, { useRef, useState } from "react";
import { useSelector, /* useDispatch */ } from "react-redux";
import React from "react";
import { useSelector } from "react-redux";
import { selectAllSubs } from "../reddit/redditSlice";
import { v4 } from 'uuid';
import SidebarItem from "./SidebarItem";
@@ -9,41 +9,17 @@ export default function Sidebar({isCollapsed}) {
const allSubs = useSelector(selectAllSubs);
let arrayOfSubs = Object.keys(allSubs);
// const [subs, setSubs] = useState(arrayOfSubs); // this piece of state to be used to modify state based on a dispatched action
const [searchSubs, setSearchSubs] = useState(''); // from sidebaritems when the visibility of a sub is toggled on/off
const searchWindowStyle = useRef('search-inactive'); // this ref allows us to access and modify the class of the search window container from another part of the render function
const handleChange = (e) => {
e.preventDefault();
if (e.target.value) { // this logic locally stores the search term in searchSubs,
searchWindowStyle.current = 'search-active'; // and will dispatch a search action from the reddit slice
setSearchSubs(e.target.value); // based on the provided term
} else if (e.target.value === '') {
searchWindowStyle.current = 'search-inactive';
setSearchSubs('');
}
}
return (
<>
{/* isCollapsed is passed from the parent component, and is mutable within the navbar */}
// isCollapsed is passed from the parent component, and is mutable within the navbar
<div className={isCollapsed ? 'sidebar-hidden' : 'sidebar'}>
{ // arrayOfSubs will become subs from useState on implementation of useState
arrayOfSubs.map((sub) => { // Maps each sub to its own line within the sidebar, along with a button that toggles its "isSelected" property
{
arrayOfSubs.map((sub) => {
return (
<SidebarItem sub={sub} key={v4()}/>
)
})
}
<input className="search-sub-input" type="text" onChange={handleChange} placeholder="Search Subs to Add"></input>
</div>
{/* displays subreddit search results */}
<div className={searchWindowStyle.current}>
<h2>Search Results for: {searchSubs}</h2>
<p>(results here)</p>
</div>
</>
);
}

View File

@@ -7,6 +7,7 @@ export default function VideoPlayer({data, src}) {
const [playing, setPlaying] = useState(false); // handles play/pause logic
const [audio, setAudio] = useState(null);
const [video, setVideo] = useState(null);
const crossPostSrc = src;
@@ -38,18 +39,34 @@ export default function VideoPlayer({data, src}) {
}
}
const checkForVideo = async(source) => {
try {
await fetch(source)
.then((response) => {
if (response.status > 400) {
setVideo(null);
} else {
setVideo(source);
}
});
} catch(e) {
console.log(e);
}
}
if (checking) {
checkForAudio();
checkForVideo(data.media.reddit_video.fallback_url);
checking = false;
}
return () => {
checking = false;
}
}, [url, audio]);
}, [url, video, data, audio]);
useEffect(() => { // this section handles simultaneous playback of audio and video
if (!audio) {
if (!audio || !video) {
return;
}
@@ -59,16 +76,18 @@ export default function VideoPlayer({data, src}) {
} else if (!playing) {
vid.current.pause();
}
}, [playing, audio, aud, vid]);
}, [playing, video, audio, aud, vid]);
return (
<>
{!video ? null :
<div className="video-player">
{
!audio ?
<>
<video id="post-video-no-audio" ref={vidControls} controls src={`${url}/DASH_1080.mp4` || `${url}/DASH_1080.mp4?source=fallback`}>
<video id="post-video-no-audio" ref={vidControls} controls src={video}>
This video is not supported by your browser.
</video>
</>
@@ -76,7 +95,7 @@ export default function VideoPlayer({data, src}) {
:
<>
<video id="post-video" ref={vid} autoPlay={playing ? true : false} src={`${url}/DASH_1080.mp4`}>
<video id="post-video" ref={vid} autoPlay={playing ? true : false} src={video}>
This video is not supported by your browser.
</video>
<video id="post-audio" ref={aud} controls onPlay={() => setPlaying(true)} onPause={() => setPlaying(false)} src={audio}>
@@ -86,5 +105,7 @@ export default function VideoPlayer({data, src}) {
}
</div>
}
</>
);
}