Skip to content

Commit

Permalink
0.6.4
Browse files Browse the repository at this point in the history
  • Loading branch information
indeyets committed Feb 25, 2016
2 parents e54a7ca + 46df5e5 commit a9ddf62
Show file tree
Hide file tree
Showing 31 changed files with 572 additions and 200 deletions.
Binary file added assets/images/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reactive-pepyatka",
"version": "1.0.0",
"version": "0.6.4",
"description": "",
"main": "index.js",
"dependencies": {
Expand Down
66 changes: 56 additions & 10 deletions src/components/about.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,62 @@
import React from 'react'
import {Link} from 'react-router'

import screenshot from 'assets/images/screenshot.png'

export default (props) => (
<div className='box'>
<div className='box-header-timeline'>
Other page
</div>
<div className='box-body'>
<div>
Here be more dragons
</div>
</div>
<div className='box-footer'>
<div className="box">
<div className="box-header-timeline"></div>
<div className="box-body">
<h3>What is FreeFeed?</h3>

<p>FreeFeed is a social network that enables you to discover and discuss
the interesting stuff your friends find on the web.</p>

<p><b><Link to="/signup">Sign up</Link></b> now or <Link to="/signin">sign in</Link> if
you already have an account.</p>

<p><img src={screenshot} width="450" height="431" style={{border: '1px solid #ccc'}}/></p>

<h3>Why FreeFeed?</h3>

<p>FreeFeed is being built as a replacement
for <a href="https://en.wikipedia.org/wiki/FriendFeed" target="_blank">FriendFeed</a>,
the real-time aggregator and social network where "likes" for user
generated content were implemented for the first time.</p>

<p>After Facebook had acquired FriendFeed and announced its plan to shut
down the website on April 9, 2015, a small group of Russian-speaking
FriendFeed users decided to build an open-source free-for-all replacement.</p>

<h3>Help us build better FreeFeed</h3>

<p>FreeFeed is an open-source project. We are <Link to="/dev">looking
for volunteers</Link> to help us with the development of FreeFeed.net.</p>

<h3>Important pages</h3>

<p><Link to="/support">https://freefeed.net/support</Link>
Tech support (we speak English, Russian as well as some other languages :))</p>

<p><Link to="/freefeed">https://freefeed.net/freefeed</Link> -
Important service announcements</p>

<h3>The team behind FreeFeed</h3>

<p>A team of volunteers registered a non-profit organization, FreeFeed.net MTÜ,
in Tallinn, Estonia to fund and coordinate open-source development of the
platform.</p>

<p>After launching a <a href="https://www.indiegogo.com/projects/freefeed-v-1" target="_blank">successful
crowdfunding campaign</a> in December 2015, the platform is now being
actively developed. It is being used by hundreds of people now, even
though the work is still underway.</p>

<p>FreeFeed v.1 is scheduled for release in spring 2016. This version will
include search and hashtag support.</p>

<p>You can <b><Link to="/signup">sign up</Link></b> now and use the beta
version today.</p>
</div>
</div>
)
39 changes: 39 additions & 0 deletions src/components/dev.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import {Link} from 'react-router'

export default (props) => (
<div className="box">
<div className="box-header-timeline"></div>
<div className="box-body">
<h3>Help us build FreeFeed</h3>

<p>We are looking for volunteers to help us build FreeFeed, an open-source
social network, replacement of FriendFeed.com.</p>

<p>We need help with both development and testing.</p>

<p>FreeFeed is open-source: <a href="https://github.com/FreeFeed/" target="_blank">https://github.com/FreeFeed/</a></p>

<p>The <a href="https://github.com/FreeFeed/freefeed-server" target="_blank">backend</a> is
built with Node.js and Redis. It is now being re-written to use PostgreSQL instead of Redis.</p>

<p>The <a href="https://github.com/FreeFeed/freefeed-react-client" target="_blank">frontend</a> is built
with React.</p>

<h3>Roadmap</h3>

<p>[x] v 0.6 React frontend<br/>
[ &nbsp;] v 0.7 Add real-time updates to the frontend<br/>
[ &nbsp;] v 0.8 Add support for private groups<br/>
[ &nbsp;] v 0.9 Migrate to Postgres<br/>
[ &nbsp;] v 1.0 Support for search and #hashtags</p>

<p>Please <a href="mailto:[email protected]">contact us</a> to join
our team of volunteers.</p>

<p>P.S. We welcome contributions of features outside of the core ones
outlined above, however we feel that the core has higher priority
(especially switching the primary data store).</p>
</div>
</div>
)
7 changes: 4 additions & 3 deletions src/components/footer.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react'
import {Link} from 'react-router'

export default (props) => (
<footer className='footer p-footer'>
&copy; FreeFeed 0.6.3 (February 8, 2016)<br/>
<a href="https://about.freefeed.net" target="_blank">About</a> | <a href="http://news.freefeed.net" target="_blank">Public News</a> | <a href="https://twitter.com/freefeednet" target="_blank">Twitter</a> | <a href="http://freefeed.reformal.ru/" target="_blank">Reformal: suggest new features</a>
<footer className="footer">
&copy; FreeFeed 0.6.4 (February 25, 2016)<br/>
<Link to="/about">About</Link> | <Link to="/freefeed">News</Link> | <a href="https://twitter.com/freefeednet" target="_blank">Twitter</a> | <a href="https://status.freefeed.net/" target="_blank">Status</a>
</footer>
)
4 changes: 3 additions & 1 deletion src/components/more-comments-wrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export default (props) => (
<img width="16" height="16" src={throbber16}/>
) : false}
</span>
<a className="more-comments-link" onClick={preventDefault(()=>props.showMoreComments())}>
<a className="more-comments-link"
href={props.entryUrl}
onClick={preventDefault(()=>props.showMoreComments())}>
{`${props.omittedComments}`} more comments
</a>
</div>
Expand Down
4 changes: 3 additions & 1 deletion src/components/post-comment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ export default class PostComment extends React.Component{
<div className="comment">
<a className="comment-icon fa fa-comment-o"
title={createdAgo}
onClick={this.openAnsweringComment}></a>
id={`comment-${this.props.id}`}
href={`${this.props.entryUrl}#comment-${this.props.id}`}
onClick={preventDefault(this.openAnsweringComment)}></a>
{this.props.isEditing ? (
<div className="comment-body">
<div>
Expand Down
8 changes: 6 additions & 2 deletions src/components/post-comments.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import PostComment from './post-comment'
import MoreCommentsWrapper from './more-comments-wrapper'
import {preventDefault} from '../utils'

const renderComment = (openAnsweringComment, isModeratingComments, commentEdit) => comment => (
const renderComment = (entryUrl, openAnsweringComment, isModeratingComments, commentEdit) => comment => (
<PostComment
key={comment.id}
{...comment}
entryUrl={entryUrl}
openAnsweringComment={openAnsweringComment}
isModeratingComments={isModeratingComments}
{...commentEdit}/>
Expand Down Expand Up @@ -48,6 +49,8 @@ const renderAddCommentLink = (props, disabledForOthers) => {
}

export default (props) => {
const entryUrl = `/${props.post.createdBy.username}/${props.post.id}`

const openAnsweringComment = (username) => {
if (!props.post.isCommenting && !props.post.isSinglePost) {
props.toggleCommenting(props.post.id)
Expand All @@ -57,7 +60,7 @@ export default (props) => {
props.updateCommentingText(props.post.id, updatedCommentText)
}

const commentMapper = renderComment(openAnsweringComment, props.post.isModeratingComments, props.commentEdit)
const commentMapper = renderComment(entryUrl, openAnsweringComment, props.post.isModeratingComments, props.commentEdit)
const first = props.comments[0]
const last = props.comments.length > 1 && props.comments[props.comments.length - 1]
const middle = props.comments.slice(1, props.comments.length - 1).map(commentMapper)
Expand All @@ -74,6 +77,7 @@ export default (props) => {
? <MoreCommentsWrapper
omittedComments={props.post.omittedComments}
showMoreComments={showMoreComments}
entryUrl={entryUrl}
isLoading={props.post.isLoadingComments}/>
: false}
{last ? commentMapper(last) : false}
Expand Down
24 changes: 20 additions & 4 deletions src/components/post.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ export default class Post extends React.Component {
</span>
))

// "Lock icon": check if the post is truly private, "partly private" or public.
// Truly private:
// - posted to author's own private feed and/or
// - sent to users as a direct message and/or
// - posted into private groups
// Public:
// - posted to author's own public feed and/or
// - posted into public groups
// "Partly private":
// - has mix of private and public recipients
const publicRecipients = props.recipients.filter((recipient) => (
recipient.isPrivate === '0' &&
(recipient.id === props.createdBy.id || recipient.type === 'group')
))
const isReallyPrivate = (publicRecipients.length === 0)

// DropzoneJS configuration
const dropzoneComponentConfig = {
postUrl: `${apiConfig.host}/v1/attachments`
Expand Down Expand Up @@ -180,7 +196,7 @@ export default class Post extends React.Component {

// "Like" / "Un-like"
const didILikePost = _.find(props.usersLikedPost, {id: props.user.id})
const likeLink = (
const likeLink = (!props.isEditable ? (
<span>
{' - '}
<a onClick={didILikePost ? unlikePost : likePost}>{didILikePost ? 'Un-like' : 'Like'}</a>
Expand All @@ -190,7 +206,7 @@ export default class Post extends React.Component {
</span>
) : false}
</span>
)
) : false)

// "Hide" / "Un-hide"
const hideLink = (props.isInHomeFeed ? (
Expand Down Expand Up @@ -295,8 +311,8 @@ export default class Post extends React.Component {
<div className="dropzone-previews"></div>

<div className="post-footer">
{props.createdBy.isPrivate === '1' ? (
<i className="post-lock-icon fa fa-lock"></i>
{isReallyPrivate ? (
<i className="post-lock-icon fa fa-lock" title="This entry is private"></i>
) : false}
{props.isDirect ? (<span>»&nbsp;</span>) : false}
<Link to={`/${props.createdBy.username}/${props.id}`} className="post-timestamp">
Expand Down
2 changes: 2 additions & 0 deletions src/components/select-utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
// User actions
subscribe, unsubscribe,
sendSubscriptionRequest,
ban, unban,

// Post actions
Expand Down Expand Up @@ -125,5 +126,6 @@ export function userActions(dispatch) {
unban: username => dispatch(unban(username)),
subscribe: username => dispatch(subscribe(username)),
unsubscribe: username => dispatch(unsubscribe(username)),
sendSubscriptionRequest: username => dispatch(sendSubscriptionRequest(username))
}
}
45 changes: 35 additions & 10 deletions src/components/settings.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,55 @@
import React from 'react'
import {connect} from 'react-redux'
import {updateUser, userSettingsChange, updatePassword, updateUserPhoto} from '../redux/action-creators'
import {updateUser, userSettingsChange, updateFrontendPreferences, updatePassword, updateUserPhoto} from '../redux/action-creators'
import UserSettingsForm from './user-settings-form'
import ChangePasswordForm from './change-password-form'
import UserFrontendPreferencesForm from './user-frontend-preferences-form'
import UserChangePasswordForm from './user-change-password-form'
import UserPhotoForm from './user-photo-form'

const Settings = (props) => (
<div className='content'>
<div className='box'>
<div className='box-header-timeline'>
<div className="content">
<div className="box">
<div className="box-header-timeline">
Settings
</div>
<div className='box-body'>
<UserSettingsForm user={props.user} updateUser={props.updateUser} userSettingsChange={props.userSettingsChange} {...props.userSettingsForm}/>
<div className="box-body">
<UserSettingsForm
user={props.user}
updateUser={props.updateUser}
userSettingsChange={props.userSettingsChange}
{...props.userSettingsForm}/>

<hr/>
<ChangePasswordForm {...props.passwordForm} updatePassword={props.updatePassword} />

<UserFrontendPreferencesForm
userId={props.user.id}
preferences={props.user.frontendPreferences}
updateFrontendPreferences={props.updateFrontendPreferences}
{...props.frontendPreferencesForm}/>

<hr/>

<UserChangePasswordForm
updatePassword={props.updatePassword}
{...props.passwordForm}/>

<hr/>

<UserPhotoForm
updateUserPhoto={props.updateUserPhoto}
{...props.userPhotoForm}/>

<hr/>
<UserPhotoForm {...props.userPhotoForm} updateUserPhoto={props.updateUserPhoto}/>
</div>
</div>
</div>
</div>
)

function mapStateToProps(state){
return {
user: state.user,
userSettingsForm: state.userSettingsForm,
frontendPreferencesForm: state.frontendPreferencesForm,
passwordForm: state.passwordForm,
userPhotoForm: state.userPhotoForm,
}
Expand All @@ -35,6 +59,7 @@ function mapDispatchToProps(dispatch){
return {
updateUser: (...args) => dispatch(updateUser(...args)),
userSettingsChange: (...args) => dispatch(userSettingsChange(...args)),
updateFrontendPreferences: (...args) => dispatch(updateFrontendPreferences(...args)),
updatePassword: (...args) => dispatch(updatePassword(...args)),
updateUserPhoto: (...args) => dispatch(updateUserPhoto(...args)),
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default ({user, signOut, recentGroups}) => (

<div className='user'>
<div className='author'>
<UserName user={user} />
<UserName user={user} display={user.screenName}/>
</div>
<div>
<Link to='/settings'>settings</Link>
Expand Down
2 changes: 1 addition & 1 deletion src/components/signup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function validate(props) {
errorMessages.push('invalid email')
}

if(!props.captcha) {
if (captchaConfig.siteKey !== '' && !props.captcha) {
errorMessages.push('captcha is not filled')
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'
import {preventDefault} from '../utils'

export default class ChangePasswordForm extends React.Component {
export default class UserChangePasswordForm extends React.Component {
render(){
return (
<form onSubmit={preventDefault(this.updatePassword)}>
<h2 className='p-settings-changepassword-header'>Change password</h2>
<h3>Change password</h3>
<div className='form-group p-settings-currentpassword'>
<label htmlFor='currentPassword'>Current password:</label>
<input id='currentPassword' className='form-control' ref='currentPassword' type='password'/>
Expand Down
Loading

0 comments on commit a9ddf62

Please sign in to comment.