Skip to content

Commit

Permalink
Merge pull request #74 from CaptainFact/staging
Browse files Browse the repository at this point in the history
Release 0.8.0 - Minor bug fixes, host image on DockerHub and add dev configs for 0.8 API
  • Loading branch information
Betree authored Jan 25, 2018
2 parents afa4bc9 + e3b014e commit 51a514c
Show file tree
Hide file tree
Showing 19 changed files with 101 additions and 102 deletions.
3 changes: 1 addition & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
.git
.gitignore
.gitlab-ci.yml
.idea
node_modules
public

rel/dev*
Dockerfile
README.md

6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ node_modules/
public/

# Ignore tests coverage
coverage
coverage

# API dev image resources
rel/dev_docker_api_resources/*
!rel/dev_docker_api_resources/.keep
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
stages:
- name: test
if: NOT (branch IN (master, staging) OR tag =~ ^v\d+)
if: NOT branch IN (master, staging)
- name: deploy
if: branch IN (master, staging) OR tag =~ ^v\d+

Expand All @@ -17,12 +17,12 @@ jobs:
sudo: required
services: [docker]
env:
- CF_FRONTEND_IMAGE=registry.gitlab.com/captainfact/captain-fact-frontend:$TRAVIS_BRANCH
- CF_FRONTEND_IMAGE=captainfact/frontend:$TRAVIS_BRANCH
script:
- docker build --build-arg BUILD_ENV=$TRAVIS_BRANCH -t $CF_FRONTEND_IMAGE . &&
docker run --rm -it $CF_FRONTEND_IMAGE test &&
if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" registry.gitlab.com;
docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD";
echo "Pushing $CF_FRONTEND_IMAGE";
docker push $CF_FRONTEND_IMAGE;
fi
Expand Down
76 changes: 20 additions & 56 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,31 +41,39 @@ comment on these tasks directly.

#### Starting the API

Starting the API is mandatory if you want to work on the debate platform, but you can skip this step
if you're just planning to translate some part of the interface or to work on help pages.

The quickest way to get the API running locally is by using its Docker image. This image
The quickest way to get the API running locally is by using Docker. This image
is currently stored on a private registry, and though we're planning to release it soon you can
contact us if you want to start working on this today.
contact us if you want to start working on this today and we'll invite you.

If you don't have it, install Docker:

A script will help you getting this API up and running (you must have docker installed):
```bash
$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
```

A script will then help you getting this API up and running:
Just execute `./rel/run_dev_docker_api.sh` from project's root, follow the instructions and you'll end up with
an Elixir console bind to the API and listening on port 4000(HTTP) + 4001(HTTPS).

Here are some useful commands you may type in:
```elixir
# Get current API version (also available in browser at localhost:4000)
iex> :application.get_key :captain_fact, :vsn
# {:ok, '0.6.1'}

iex> CaptainFact.Application.version
"0.7.7"
# This image ships with a factory to quickly create users, without worriying about invitations and emails
iex> CaptainFact.Factory.insert :user
iex> DB.Factory.insert :user
# %CaptainFact.Accounts.User{
# ...
# email: "[email protected]", <- Use this email to connect. Password is "password"
# ....}
# You can also set some properties directly, like:
iex> CaptainFact.Factory.insert :user, %{reputation: 5000, email: "[email protected]"}
# You can also set properties directly, like:
iex> DB.Factory.insert :user, %{reputation: 5000, email: "[email protected]"}

# If you need a full video with sources, speakers comments and all the goods, you can run the
# following command. It may take some time to run (30s-1min) cause it must fetch the speakers
# pictures from wikimedia.
iex> List.first(c(Path.join(:code.priv_dir(:captain_fact), "demos/demo_fr.ex"))).init_and_run

# Remove all videos
iex> CaptainFact.Repo.delete_all CaptainFact.Videos.Video
Expand All @@ -76,47 +84,3 @@ iex> CaptainFact.Repo.delete_all CaptainFact.Videos.Video
To start the frontend just run `npm install` to install dependencies then `npm start` and you'll
be able to access the site at [localhost:3333](http://localhost:3333).
A default account should have been created for you with email=`[email protected]` and password=`password`.

### Code style

*TODO: code style and conventions*

# Conduct

We are committed to providing a friendly, safe and welcoming environment for
all, regardless of gender, sexual orientation, disability, ethnicity, religion,
or similar personal characteristic.

On IRC, please avoid using overtly sexual nicknames or other nicknames that
might detract from a friendly, safe and welcoming environment for all.

Please be kind and courteous. There's no need to be mean or rude.
Respect that people have differences of opinion and that every design or
implementation choice carries a trade-off and numerous costs. There is seldom
a right answer, merely an optimal answer given a set of values and
circumstances.

Please keep unstructured critique to a minimum. If you have solid ideas you
want to experiment with, make a fork and see how it works.

We will exclude you from interaction if you insult, demean or harass anyone.
That is not welcome behaviour. We interpret the term "harassment" as
including the definition in the
[Citizen Code of Conduct](http://citizencodeofconduct.org/);
if you have any lack of clarity about what might be included in that concept,
please read their definition. In particular, we don't tolerate behavior that
excludes people in socially marginalized groups.

Private harassment is also unacceptable. No matter who you are, if you feel
you have been or are being harassed or made uncomfortable by a community
member, please contact one of the channel ops or any of the
[CaptainFact](https://github.com/CaptainFact) core team
immediately. Whether you're a regular contributor or a newcomer, we care about
making this community a safe place for you and we've got your back.

Likewise any spamming, trolling, flaming, baiting or other attention-stealing
behaviour is not welcome.

# Frequently Asked Questions

*TODO*
2 changes: 2 additions & 0 deletions app/assets/assets/locales/en/videoDebate.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
"titleFormat_FR": "French {{title}}"
},
"statement": {
"remove": "Remove statement",
"confirmRemove": "Do you really want to remove this statement ?",
"textPlaceholder": "Type a raw transcript of what the speaker says",
"noSpeakerTextPlaceholder": "Describe what you see or select a speaker",
"text": "Text",
Expand Down
2 changes: 2 additions & 0 deletions app/assets/assets/locales/fr/videoDebate.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
}
},
"statement": {
"remove": "Retirer la citation",
"confirmRemove": "Êtes-vous sûr·e ?",
"textPlaceholder": "Retranscrivez ici les propos de l'intervenant·e",
"noSpeakerTextPlaceholder": "Décrivez ce qui apparait à l'image ou ajoutez un intervenant",
"text": "Le texte",
Expand Down
10 changes: 6 additions & 4 deletions app/components/Modal/ModalConfirm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,19 @@ export class ModalConfirm extends React.PureComponent {
}

render() {
const { handleConfirm, content, message, ...props } = this.props
const { handleConfirm, className, content, message, ...props } = this.props
return (
<Modal className="modal-confirm" handleCloseClick={this.close} {...props}
footer={this.renderFormButtons()}>
<Modal className={classNames("modal-confirm", className)}
handleCloseClick={this.close}
footer={this.renderFormButtons()}
{...props}>
{content &&
<div>
{content}
{message && <hr/>}
</div>
}
<h3 className="title is-3">{message}</h3>
<h3 className="title is-4">{message}</h3>
</Modal>
)
}
Expand Down
7 changes: 4 additions & 3 deletions app/components/Statements/Statement.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class Statement extends React.PureComponent {

render() {
const { isDeleting } = this.state
const { statement, isFocused, isAuthenticated, speaker } = this.props
const { statement, isFocused, isAuthenticated, speaker, t } = this.props

return (
<div className={`statement-container${isFocused ? ' is-focused' : ''}`} ref="container">
Expand All @@ -62,10 +62,11 @@ export class Statement extends React.PureComponent {
{this.renderFactsAndComments()}
{isDeleting &&
<ModalConfirmDelete
title="Remove Statement"
title={t('statement.remove')}
className="is-small"
isAbsolute={true}
isRemove={true}
message="Do you really want to remove this statement ?"
message={t('statement.confirmRemove')}
handleAbort={() => this.setState({isDeleting: false})}
handleConfirm={() => this.props.deleteStatement({id: statement.id})}
/>
Expand Down
13 changes: 7 additions & 6 deletions app/components/Videos/AddVideoForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ const renderVideoField = (field) => {
const { meta: {error}, input: {value} } = field
const urlInput = FieldWithButton(field)

return (<div>
{!error && <DummyVideoPlayer url={value}/>}
{error && <div className="video"><div></div></div>}
{urlInput}
</div>)
return (
<div>
{!error && <DummyVideoPlayer url={value}/>}
{error && <div className="video"><div></div></div>}
{urlInput}
</div>
)
}

@withRouter
Expand Down Expand Up @@ -64,7 +66,6 @@ export class AddVideoForm extends React.PureComponent {
<Field component={renderVideoField} name="url" buttonLabel="Add Video" placeholder="Video URL"
buttonClassName="is-primary"
normalize={s => trim(s)}
meta={{submitting: this.props.isSubmitting}}
/>
</form>
<div id="col-debate" className="column">
Expand Down
4 changes: 2 additions & 2 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
<!-- Metadata -->
<title>CaptainFact</title>
<meta charset="utf-8">
<meta name="description" content="Collaborative, real-time fact checking and debate platform. Free and open source.">
<meta name="description" content="Collaborative, real-time fact checking. Free and open source.">
<meta name="keywords" content="fact checking,wiki,collaborative">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Opengraph -->
<meta property="og:title" content="CaptainFact.io"/>
<meta property="og:description" content="Collaborative, real-time fact checking and debate platform"/>
<meta property="og:description" content="Collaborative, real-time fact checking. Free and open source."/>
<meta property="og:image" content="https://captainfact.io/assets/img/banner.png"/>
<meta property="og:image:width" content="1200"/>
<meta property="og:image:height" content="627"/>
Expand Down
6 changes: 6 additions & 0 deletions app/lib/__tests__/url_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ describe('Youtube regex', () => {
expect(youtubeRegex.test("https://youtu.be/dQw4w9WgXcQ")).toBe(true)
// Short form with get params
expect(youtubeRegex.test("https://youtu.be/dQw4w9WgXcQ?t=42s")).toBe(true)
// Embedded form
expect(youtubeRegex.test("https://www.youtube.com/embed/LMRdn_MQWXM")).toBe(true)
})

it('should reject invalid urls', () => {
// Mising id
expect(youtubeRegex.test("https://youtu.be")).toBe(false)
// Channel
expect(youtubeRegex.test("https://www.youtube.com/channel/UCQgWpmt02UtJkyO32HGUASQ")).toBe(false)
// Empty string
expect(youtubeRegex.test("")).toBe(false)
// Random string
expect(youtubeRegex.test(Math.random().toString(36).substring(7))).toBe(false)
})
})

Expand Down
4 changes: 2 additions & 2 deletions app/lib/url_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const optionsToQueryString = (options) => (
)

export const youtubeRegex =
/^(http(s)?:\/\/)?(www\.)?((youtube\.com\/watch\?v=)|(youtu.be\/))([a-zA-Z0-9\-_]+)/
/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i

export const isExternal = (currentHref, url) =>
(url.indexOf(':') > -1 || url.indexOf('//') > -1) && checkDomain(currentHref) !== checkDomain(url)
Expand All @@ -16,7 +16,7 @@ export const isExternal = (currentHref, url) =>
// ---- Private ----

function checkDomain(url) {
if ( url.indexOf('//') === 0 )
if (url.indexOf('//') === 0 )
url = location.protocol + url
return url.toLowerCase().replace(/([a-z])?:\/\//,'$1').split('/')[0]
}
10 changes: 9 additions & 1 deletion app/state/user_actions/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { diffWordsWithSpace } from 'diff'
import parseDateTime from '../../lib/parse_datetime'
import formatSeconds from "../../lib/seconds_formatter"
import UserAction from "./record"
import { ACTION_DELETE, ACTION_REMOVE, ACTION_RESTORE, ENTITY_SPEAKER, ENTITY_STATEMENT } from '../../constants'
import {
ACTION_DELETE, ACTION_REMOVE, ACTION_RESTORE, ENTITY_SPEAKER, ENTITY_STATEMENT, ENTITY_VIDEO
} from '../../constants'
import { resetVideoDebate } from '../video_debate/actions'

export const setLoading = createAction('VIDEO_DEBATE_HISTORY/SET_LOADING')
Expand Down Expand Up @@ -137,6 +139,12 @@ function buildReferenceEntity(actions, base=null) {
return buildReferenceStatement(actions, base)
else if (entity === ENTITY_SPEAKER)
return buildReferenceSpeaker(actions, base)
else if (entity === ENTITY_VIDEO)
return buildReferenceVideo(actions, base)
}

function buildReferenceVideo(actions, base=null) {
return new Map()
}

function buildReferenceStatement(actions, base=null) {
Expand Down
25 changes: 17 additions & 8 deletions app/styles/_components/modal.sass
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,38 @@ $modal-background: rgba(10, 10, 10, 0.50)
width: 0

.modal
&.is-absolute
position: absolute
.modal-background
background-color: $modal-background
.modal-card-title
font-size: 1.5em
+mobile
font-size: 1.2em
.modal-card-body
font-size: 1em
.help-link
margin-right: 5px
color: #c6c6c6
&:hover
color: #aeaeae

.modal.is-small
font-size: 0.8em
.modal-card-head
padding: 1.2em
.modal-card-foot, .modal-card-body
padding: 1em

.modal-confirm, .modal-form
@extend .modal
@include animate(fadeIn, 0.2s)

.modal-confirm
&.is-absolute
position: absolute
.modal-card
border-radius: 5px
max-width: 98%
.modal-card-body
padding: 35px 20px
.modal-confirm .modal-card
border-radius: 5px
max-width: 98%
.modal-card-body
padding: 2em

.form-buttons
text-align: center
Expand Down
2 changes: 1 addition & 1 deletion app/styles/_components/statements.sass
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,5 @@ $statement-text-color: #e0e7f1
font-size: 1.45em
font-weight: bold
white-space: pre-line
text-shadow: 0px 0px 3px black
text-shadow: 0 0 1px black

1 change: 0 additions & 1 deletion app/styles/_global/icons.sass
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Icons generated with the help of https://icomoon.io/app/. Use config/icomoon_icons.json to load project
@include font-face(icomoon, "/assets/fonts/icomoon", normal, normal, eot svg ttf woff woff2)
@include font-face(icomoon, "/assets/fonts/icomoon", normal, normal, eot woff2 woff ttf svg)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "captain-fact-frontend",
"version": "0.7.9",
"version": "0.8.0",
"private": true,
"scripts": {
"start": "brunch watch --server",
Expand Down
Empty file.
Loading

0 comments on commit 51a514c

Please sign in to comment.