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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.7.2 馃殕 #41

Merged
merged 18 commits into from
Nov 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ See [CONTRIBUTING.md](CONTRIBUTING.md)

* [Extension](https://github.com/CaptainFact/captain-fact-extension)

## Dependencies

Many thanks to [adorable.io](http://avatars.adorable.io/) for their great consistent avatar service (the funny faces
you see if you don't set your own profile picture).

## License

GNU AFFERO GENERAL PUBLIC LICENSE Version 3
Expand Down
26 changes: 18 additions & 8 deletions app/API/http_api.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import "isomorphic-fetch"
import trimRight from 'voca/trim_right'
import fetch from 'isomorphic-fetch'

import { SocketApi } from "./socket_api"
import { HTTP_API_URL } from "../config.jsenv"
import { parseServerError } from './server_error'
import flashNoInternetError from './no_internet_error'
import { optionsToQueryString } from '../lib/url_utils'


class CaptainFactHttpApi {
constructor(baseUrl, token) {
this.baseUrl = trimRight(baseUrl, '/') + '/'
this.hasToken = !!token
this.headers = {
'authorization': token ? `Bearer ${token}` : "",
'Content-Type': "application/json"
}
this.headers = {'Content-Type': 'application/json'}
if (token)
this.headers['authorization'] = `Bearer ${token}`
}

setAuthorizationToken(token) {
this.hasToken = true
localStorage.token = token
this.headers['authorization'] = token ? `Bearer ${token}` : ""
if (token)
this.headers['authorization'] = `Bearer ${token}`
SocketApi.setAuthorizationToken(token)
}

Expand All @@ -41,7 +43,8 @@ class CaptainFactHttpApi {
else
fulfill(body)
})
}).catch(() => {
}).catch(e => {
console.error(e)
// Special case when no internet connection
reject('noInternet')
flashNoInternetError()
Expand All @@ -58,8 +61,15 @@ class CaptainFactHttpApi {
return this.prepareResponse(response)
}

get(resourceUrl) {
const response = fetch(this.baseUrl + resourceUrl, {headers: this.headers})
/**
* Send a get request against the given `resourceUrl`.
* @param {string} resourceUrl
* @param {object} [options] - A map of options to convert to query string http://url?option1=xxx&option2=yyy
* @returns {Promise}
*/
get(resourceUrl, options) {
const queryString = optionsToQueryString(options)
const response = fetch(this.baseUrl + resourceUrl + queryString, {headers: this.headers})
return this.prepareResponse(response)
}

Expand Down
2 changes: 2 additions & 0 deletions app/assets/assets/help/en/credits.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ CaptainFact has grown on upon the soil of many great open source projects such a
* [React](https://facebook.github.io/react/)
* [Bulma](http://bulma.io/)
* [Redux](http://redux.js.org/)
* [adorable.io](http://avatars.adorable.io/) for their great consistent avatar service (the funny faces
you see if you don't set your own profile picture)


And the Wikimedia foundation for all the speakers pictures and other metadata. You
Expand Down
2 changes: 2 additions & 0 deletions app/assets/assets/help/fr/credits.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ CaptainFact a grandit sur le sol fertile de nombreux projets open source tels qu
* [React](https://facebook.github.io/react/)
* [Bulma](http://bulma.io/)
* [Redux](http://redux.js.org/)
* [adorable.io](http://avatars.adorable.io/) for their great consistent avatar service (the funny faces
you see if you don't set your own profile picture)


Ainsi qu'脿 la fondation Wikimedia pour les images d'intervenants et d'autres m茅tadon茅es associ茅es. Vous
Expand Down
3 changes: 3 additions & 0 deletions app/assets/assets/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,8 @@
"clipboardFail": "Cannot copy to clipboard",
"all": "All",
"unknown": "Unknown"
},
"videos": {
"add": "Add Video"
}
}
11 changes: 8 additions & 3 deletions app/assets/assets/locales/en/videoDebate.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"debate": "Debate",
"history": "History",
"approve": "Approve",
"approve": "Confirm",
"refute": "Refute",
"flagForm": {
"title": "Why do you want to flag this comment ?",
Expand All @@ -14,14 +14,19 @@
"comment": {
"writeComment": "Write a comment...",
"addSource": "Add a source to turn this comment into a fact",
"postComment": "Post Comment",
"post": "Post Comment",
"post_reply": "Post reply",
"deleteThread": "Delete comment",
"deleteThread_plural": "Delete thread",
"replies_hide": "Hide replies",
"replies_show": "Show replies ({{count}})",
"loadMore_replies": "Load more replies ({{count}})",
"loadMore_comments": "Load more comments ({{count}})",
"replyingTo": "Replying to"
"replyingTo": "Replying to",
"approve": "Confirm",
"approve_reply": "Confirm this comment",
"refute": "Refute",
"refute_reply": "Refute this comment"
},
"video": {
"added": "Added",
Expand Down
5 changes: 4 additions & 1 deletion app/assets/assets/locales/fr/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"remove": "Retirer",
"delete": "Supprimer",
"reply": "R茅pondre",
"approve": "Approuver",
"approve": "Confirmer",
"refute": "R茅futer",
"edit": "脡diter",
"loading": "Chargement",
Expand All @@ -52,5 +52,8 @@
"clipboardFail": "Impossible d'enregistrer l'adresse dans le presse papier",
"all": "Tous",
"unknown": "Inconnu"
},
"videos": {
"add": "Ajouter une vid茅o"
}
}
14 changes: 9 additions & 5 deletions app/assets/assets/locales/fr/videoDebate.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"debate": "D茅bat",
"history": "Historique",
"approve": "Approuve",
"approve": "Confirme",
"refute": "R茅fute",
"flagForm": {
"title": "Pourquoi signaler ce commentaire ?",
Expand All @@ -14,14 +14,19 @@
"comment": {
"writeComment": "脡crire un commentaire...",
"addSource": "Ajouter une source",
"postComment": "Poster ce commentaire",
"post": "Ajouter en commentaire",
"post_reply": "Ajouter en r茅ponse",
"deleteThread": "Supprimer le commentaire",
"deleteThread_plural": "Supprimer le fil de discussion",
"replies_hide": "Cacher les r茅ponses",
"replies_show": "Montrer les r茅ponses ({{count}})",
"loadMore_replies": "Charger plus de r茅ponses ({{count}})",
"loadMore_comments": "Charger plus de commentaires ({{count}})",
"replyingTo": "En r茅ponse 脿"
"replyingTo": "En r茅ponse 脿",
"approve": "Confirmer",
"approve_reply": "Confirmer ce commentaire",
"refute": "R茅futer",
"refute_reply": "R茅futer ce commentaire"
},
"video": {
"added": "Ajout茅e",
Expand All @@ -38,9 +43,8 @@
"title": "Titre",
"titlePlaceholder": "Politicien, docteur, journaliste...",
"titleFormat": "{{title}}",
"titleFormat_FR": "{{title}} fran莽ais",
"titles": {
"Politician": "Politicien",
"Politician": "Personnalit茅 politique",
"Journalist": "Journaliste"
}
},
Expand Down
2 changes: 1 addition & 1 deletion app/components/App/LanguageSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const defaultLocales = new Map({
fr: 'Fran莽ais'
})

@translate([]) // Force waiting for translations to be loaded
@translate() // Force waiting for translations to be loaded
export default class LanguageSelector extends React.PureComponent {
render() {
return (
Expand Down
5 changes: 3 additions & 2 deletions app/components/Comments/CommentDisplay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,13 @@ export class CommentDisplay extends React.PureComponent {
}

render() {
const { user, text, source, score, inserted_at } = this.props.comment
const { user, text, source, score, inserted_at, approve } = this.props.comment
const { t, withoutActions, withoutHeader, replyingTo, nesting, replies, myVote, isVoting, hideThread, className, richMedias=true } = this.props
const approveClass = approve !== null && (approve ? 'approve' : 'refute')
return (
<div>
<MediaLayout
className={classNames('comment', className, {isBlurred: this.state.isBlurred, hasSource: !!source})}
className={classNames('comment', className, approveClass, {isBlurred: this.state.isBlurred, hasSource: !!source})}
ContainerType="article"
left={
<figure>
Expand Down
58 changes: 31 additions & 27 deletions app/components/Comments/CommentForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import isURL from 'validator/lib/isURL'
import classNames from 'classnames'

import { renderField, validateLength, cleanStrMultiline } from "../FormUtils"
import { COMMENT_LENGTH, USER_PICTURE_MEDIUM } from "../../constants"
import { COMMENT_LENGTH, USER_PICTURE_LARGE } from "../../constants"
import TextareaAutosize from "../FormUtils/TextareaAutosize"
import { Icon } from '../Utils/Icon'
import Tag from '../Utils/Tag'
Expand All @@ -33,7 +33,7 @@ const validate = ({ source, text }) => {

class CommentField extends React.PureComponent {
render() {
const { input, label, placeholder, isReply, meta: { submitting } } = this.props
const { input, label, placeholder, isReply, meta: { submitting, error } } = this.props
return (
<p className="control">
<TextareaAutosize {...input}
Expand All @@ -46,6 +46,7 @@ class CommentField extends React.PureComponent {
</span>
&nbsp;/ {COMMENT_LENGTH[1]}
</span>
{error && <span className="help is-danger">{typeof(error) === 'string' ? error : error[0]}</span>}
</p>
)
}
Expand All @@ -70,28 +71,27 @@ export class CommentForm extends React.PureComponent {
})
}

getSubmit(valid, sourceUrl) {
getSubmit(valid, sourceUrl, isReply) {
const commonClasses = ['button', {'is-disabled': !valid}]
if (!sourceUrl) return (
<button type="submit" className={classNames(commonClasses, 'is-info')}>
{this.props.t('comment.postComment')}
const i18nParams = isReply ? {context: 'reply'} : null
if (!sourceUrl) return ([
<button key="comment" type="submit" className={classNames(commonClasses)}>
{this.props.t('comment.post', i18nParams)}
</button>
)
else return (
<div>
<button type="submit" className={classNames(commonClasses, 'is-success')}
onClick={this.postAndReset(values => this.props.postComment({...values, approve: true}))}>
{this.props.t('main:actions.approve')}
</button>
<button type="submit" className={classNames(commonClasses, 'is-danger')}
onClick={this.postAndReset(values => this.props.postComment({...values, approve: false}))}>
{this.props.t('main:actions.refute')}
</button>
<button type="submit" className={classNames(commonClasses)}>
{this.props.t('comment.postComment')}
</button>
</div>
)
])
else return ([
<button key="comment" type="submit" className={classNames(commonClasses)}>
{this.props.t('comment.post', i18nParams)}
</button>,
<button key="approve" type="submit" className={classNames(commonClasses, 'is-success')}
onClick={this.postAndReset(values => this.props.postComment({...values, approve: true}))}>
{this.props.t('comment.approve', i18nParams)}
</button>,
<button key="refute" type="submit" className={classNames(commonClasses, 'is-danger')}
onClick={this.postAndReset(values => this.props.postComment({...values, approve: false}))}>
{this.props.t('comment.refute', i18nParams)}
</button>
])
}

render() {
Expand All @@ -103,7 +103,7 @@ export class CommentForm extends React.PureComponent {
ContainerType="form"
containerProps={{onSubmit: this.postAndReset(c => this.props.postComment(c))}}
className="comment-form"
left={<UserPicture user={currentUser} size={USER_PICTURE_MEDIUM}/>}
left={<UserPicture user={currentUser} size={USER_PICTURE_LARGE}/>}
content={
<div>
{formValues && formValues.reply_to &&
Expand All @@ -125,10 +125,14 @@ export class CommentForm extends React.PureComponent {
isReply={formValues && !!formValues.reply_to}
normalize={ cleanStrMultiline }
placeholder={t('comment.writeComment')}/>
<Field component={ renderField } name="source.url"
label={t('comment.addSource')}
normalize={s => s.trim()}/>
{ this.getSubmit(valid, sourceUrl) }
<div className="level">
<Field component={ renderField } name="source.url"
label={t('comment.addSource')}
normalize={s => s.trim()}/>
<div className="submit-btns">
{ this.getSubmit(valid, sourceUrl, formValues && formValues.reply_to) }
</div>
</div>
</div>
}
/>
Expand Down
17 changes: 9 additions & 8 deletions app/components/Comments/Source.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ const isPlayer = url => {
export const Source = ({ source: { url, title, site_name }, withoutPlayer }) => {
if (!withoutPlayer && isPlayer(url)) {
return <ReactPlayer className="video" controls={true} height={180} width={320} url={url}
youtubeConfig={{playerVars: { showinfo: 1 }}}
/>
config={{youtube: {playerVars: { showinfo: 1 }}}}/>
} else {
return <a href={url} target="_BLANK" className="fact-source">
<span className="site-name">
{upperCase(site_name) || getDisplayableHostname(url)}
</span>
<span className="article-title">{title}</span>
</a>
return (
<a href={url} target="_BLANK" className="fact-source">
<span className="site-name">
{upperCase(site_name) || getDisplayableHostname(url)}
</span>
<span className="article-title">{title}</span>
</a>
)
}
}
6 changes: 3 additions & 3 deletions app/components/Pages/BrowserExtensionsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ const BrowserExtensionsPage = ({t}) => (
buttonLabel="Get on Chrome Web Store"
url="https://chrome.google.com/webstore/detail/captainfact-beta/fnnhlmbnlbgomamcolcpgncflofhjckm"/>
<BrowserExtension browser="Mozilla Firefox" image="/assets/img/firefox.png"
buttonLabel="Download for Firefox (Coming soon)" disabled={true}
url="https://addons.mozilla.org/en-US/firefox/"/>
buttonLabel="Download for Firefox"
url="https://addons.mozilla.org/addon/captainfact/"/>
<BrowserExtension browser="Internet Explorer" image="/assets/img/internet_explorer.png"
buttonLabel="Just kidding" disabled={true}
url="https://www.mozilla.org/fr/firefox/new/"/>
url="https://www.mozilla.org/fr/firefox/"/>
</div>
</div>
</section>
Expand Down
2 changes: 1 addition & 1 deletion app/components/Pages/Help.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class Help extends React.PureComponent {
}
return (
<div className="help-page">
<section className="hero is-info">
<section className="hero is-info is-bold">
<div className="hero-body">
<div className="container">
{ header }
Expand Down
Loading