mirror of
https://github.com/wassname/talk.git
synced 2026-06-30 23:29:51 +08:00
Merge branch 'all-flag'
t push origin master
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import {Router, Route, IndexRoute, browserHistory} from 'react-router';
|
||||
import {Router, Route, IndexRoute, IndexRedirect, browserHistory} from 'react-router';
|
||||
|
||||
import Streams from 'containers/Streams/Streams';
|
||||
import Configure from 'containers/Configure/Configure';
|
||||
@@ -7,6 +7,8 @@ import LayoutContainer from 'containers/LayoutContainer';
|
||||
import CommentStream from 'containers/CommentStream/CommentStream';
|
||||
import InstallContainer from 'containers/Install/InstallContainer';
|
||||
import CommunityContainer from 'containers/Community/CommunityContainer';
|
||||
|
||||
import ModerationLayout from 'containers/ModerationQueue/ModerationLayout';
|
||||
import ModerationContainer from 'containers/ModerationQueue/ModerationContainer';
|
||||
|
||||
const routes = (
|
||||
@@ -19,8 +21,21 @@ const routes = (
|
||||
<Route path='configure' component={Configure} />
|
||||
<Route path='streams' component={Streams} />
|
||||
|
||||
<Route path='moderate' component={ModerationContainer} />
|
||||
<Route path='moderate/:id' component={ModerationContainer} />
|
||||
{/* Moderation Routes */}
|
||||
|
||||
<Route path='moderate' component={ModerationLayout}>
|
||||
<Route path='premod' components={ModerationContainer}>
|
||||
<Route path=':id' components={ModerationContainer} />
|
||||
</Route>
|
||||
<Route path='rejected' components={ModerationContainer}>
|
||||
<Route path=':id' components={ModerationContainer} />
|
||||
</Route>
|
||||
<Route path='flagged' components={ModerationContainer}>
|
||||
<Route path=':id' components={ModerationContainer} />
|
||||
</Route>
|
||||
<Route path=':id' components={ModerationContainer} />
|
||||
<IndexRedirect to='premod' />
|
||||
</Route>
|
||||
</Route>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import * as actions from 'constants/moderation';
|
||||
|
||||
export const setActiveTab = activeTab => ({type: actions.SET_ACTIVE_TAB, activeTab});
|
||||
export const toggleModal = open => ({type: actions.TOGGLE_MODAL, open});
|
||||
export const singleView = () => ({type: actions.SINGLE_VIEW});
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export const SET_ACTIVE_TAB = 'SET_ACTIVE_TAB';
|
||||
export const TOGGLE_MODAL = 'TOGGLE_MODAL';
|
||||
export const SINGLE_VIEW = 'SINGLE_VIEW';
|
||||
export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG';
|
||||
|
||||
@@ -51,6 +51,12 @@ const updateClosedMessage = (updateSettings) => (event) => {
|
||||
updateSettings({closedMessage});
|
||||
};
|
||||
|
||||
const updateCustomCssUrl = (updateSettings) => (event) => {
|
||||
console.log('updateCustomCssUrl', event.target.value);
|
||||
const customCssUrl = event.target.value;
|
||||
updateSettings({customCssUrl});
|
||||
};
|
||||
|
||||
// If we are changing the measure we need to recalculate using the old amount
|
||||
// Same thing if we are just changing the amount
|
||||
const updateClosedTimeout = (updateSettings, ts, isMeasure) => (event) => {
|
||||
@@ -165,7 +171,7 @@ const CommentSettings = ({fetchingSettings, title, updateSettings, settingsError
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card className={`${styles.configSettingInfoBox}`}>
|
||||
<Card className={styles.configSettingInfoBox}>
|
||||
<div className={styles.content}>
|
||||
{lang.t('configure.close-after')}
|
||||
<br />
|
||||
@@ -188,6 +194,18 @@ const CommentSettings = ({fetchingSettings, title, updateSettings, settingsError
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card className={styles.configSettingInfoBox}>
|
||||
<div className={styles.content}>
|
||||
{lang.t('configure.custom-css-url')}
|
||||
<p>{lang.t('configure.custom-css-url-desc')}</p>
|
||||
<br />
|
||||
<Textfield
|
||||
style={{width: '100%'}}
|
||||
label={lang.t('configure.custom-css-url')}
|
||||
value={settings.customCssUrl}
|
||||
onChange={updateCustomCssUrl(updateSettings)} />
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ import {banUser, setCommentStatus} from '../../graphql/mutations';
|
||||
|
||||
import {fetchSettings} from 'actions/settings';
|
||||
import {updateAssets} from 'actions/assets';
|
||||
import {setActiveTab, toggleModal, singleView, showBanUserDialog, hideBanUserDialog} from 'actions/moderation';
|
||||
import {toggleModal, singleView, showBanUserDialog, hideBanUserDialog} from 'actions/moderation';
|
||||
|
||||
import {Spinner} from 'coral-ui';
|
||||
import BanUserDialog from '../../components/BanUserDialog';
|
||||
@@ -19,7 +19,6 @@ import ModerationHeader from './components/ModerationHeader';
|
||||
import NotFoundAsset from './components/NotFoundAsset';
|
||||
|
||||
class ModerationContainer extends Component {
|
||||
|
||||
componentWillMount() {
|
||||
const {toggleModal, singleView} = this.props;
|
||||
|
||||
@@ -46,6 +45,8 @@ class ModerationContainer extends Component {
|
||||
render () {
|
||||
const {data, moderation, settings, assets, ...props} = this.props;
|
||||
const providedAssetId = this.props.params.id;
|
||||
const activeTab = this.props.route.path === ':id' ? 'premod' : this.props.route.path;
|
||||
|
||||
let asset;
|
||||
|
||||
if (data.loading) {
|
||||
@@ -65,20 +66,17 @@ class ModerationContainer extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const enablePremodTab = !!data.premod.length;
|
||||
return (
|
||||
<div>
|
||||
<ModerationHeader asset={asset} />
|
||||
<ModerationMenu
|
||||
onTabClick={props.onTabClick}
|
||||
enablePremodTab={enablePremodTab}
|
||||
activeTab={moderation.activeTab}
|
||||
activeTab={activeTab}
|
||||
asset={asset}
|
||||
/>
|
||||
<ModerationQueue
|
||||
data={data}
|
||||
currentAsset={asset}
|
||||
activeTab={moderation.activeTab}
|
||||
enablePremodTab={enablePremodTab}
|
||||
activeTab={activeTab}
|
||||
suspectWords={settings.wordlist.suspect}
|
||||
showBanUserDialog={props.showBanUserDialog}
|
||||
acceptComment={props.acceptComment}
|
||||
@@ -102,7 +100,6 @@ const mapStateToProps = state => ({
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onTabClick: activeTab => dispatch(setActiveTab(activeTab)),
|
||||
toggleModal: toggle => dispatch(toggleModal(toggle)),
|
||||
onClose: () => dispatch(toggleModal(false)),
|
||||
singleView: () => dispatch(singleView()),
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
|
||||
const ModerationLayout = props => (
|
||||
<div>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default ModerationLayout;
|
||||
@@ -3,12 +3,12 @@ import React, {PropTypes} from 'react';
|
||||
import Comment from './components/Comment';
|
||||
import {actionsMap} from './helpers/moderationQueueActionsMap';
|
||||
|
||||
const ModerationQueue = props => {
|
||||
const ModerationQueue = ({activeTab = 'premod', ...props}) => {
|
||||
return (
|
||||
<div id="moderationList">
|
||||
<ul>
|
||||
{
|
||||
props.data[props.activeTab].map((comment, i) => {
|
||||
props.data[activeTab].map((comment, i) => {
|
||||
return <Comment
|
||||
key={i}
|
||||
index={i}
|
||||
|
||||
@@ -63,10 +63,6 @@ const Comment = ({actions = [], ...props}) => {
|
||||
</p>
|
||||
</div>
|
||||
{actionSumaries && <FlagBox actionSumaries={actionSumaries} />}
|
||||
|
||||
{/* <span className={styles.context}>*/}
|
||||
{/* <a>View context</a>*/}
|
||||
{/* </span>*/}
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,59 +1,43 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import React from 'react';
|
||||
import styles from './styles.css';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from 'coral-admin/src/translations.json';
|
||||
import {Link} from 'react-router';
|
||||
|
||||
const lang = new I18n(translations);
|
||||
|
||||
const ModerationMenu = (props) => (
|
||||
<div className='mdl-tabs'>
|
||||
<div className={`mdl-tabs__tab-bar ${styles.tabBar}`}>
|
||||
<a href='#all'
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
props.onTabClick('all');
|
||||
}}
|
||||
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'all' ? styles.active : ''}`}
|
||||
>
|
||||
{lang.t('modqueue.all')}
|
||||
</a>
|
||||
{
|
||||
props.enablePremodTab
|
||||
? <a href='#premod'
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
props.onTabClick('premod');
|
||||
}}
|
||||
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'premod' ? styles.active : ''}`}>
|
||||
{lang.t('modqueue.premod')}
|
||||
</a>
|
||||
: null
|
||||
props.asset ? (
|
||||
<div>
|
||||
<Link to={`/admin/moderate/premod/${props.asset.id}`} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
|
||||
{lang.t('modqueue.premod')}
|
||||
</Link>
|
||||
<Link to={`/admin/moderate/rejected/${props.asset.id}`} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
|
||||
{lang.t('modqueue.rejected')}
|
||||
</Link>
|
||||
<Link to={`/admin/moderate/flagged/${props.asset.id}`} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
|
||||
{lang.t('modqueue.flagged')}
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<Link to='/admin/moderate/premod' className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
|
||||
{lang.t('modqueue.premod')}
|
||||
</Link>
|
||||
<Link to='/admin/moderate/rejected' className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
|
||||
{lang.t('modqueue.rejected')}
|
||||
</Link>
|
||||
<Link to='/admin/moderate/flagged' className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
|
||||
{lang.t('modqueue.flagged')}
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<a href='#rejected'
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
props.onTabClick('rejected');
|
||||
}}
|
||||
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'rejected' ? styles.active : ''}`}
|
||||
>
|
||||
{lang.t('modqueue.rejected')}
|
||||
</a>
|
||||
<a href='#flagged'
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
props.onTabClick('flagged');
|
||||
}}
|
||||
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'flagged' ? styles.active : ''}`}
|
||||
>
|
||||
{lang.t('modqueue.flagged')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
ModerationMenu.propTypes = {
|
||||
activeTab: PropTypes.string.isRequired,
|
||||
enablePremodTab: PropTypes.bool
|
||||
};
|
||||
|
||||
export default ModerationMenu;
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
#import "../fragments/commentView.graphql"
|
||||
|
||||
query ModQueue ($asset_id: ID!) {
|
||||
all: comments(query: {
|
||||
statuses: [REJECTED, PREMOD],
|
||||
asset_id: $asset_id
|
||||
}) {
|
||||
...commentView
|
||||
}
|
||||
premod: comments(query: {
|
||||
statuses: [PREMOD],
|
||||
asset_id: $asset_id
|
||||
|
||||
@@ -2,7 +2,6 @@ import {Map} from 'immutable';
|
||||
import * as actions from '../constants/moderation';
|
||||
|
||||
const initialState = Map({
|
||||
activeTab: 'all',
|
||||
singleView: false,
|
||||
modalOpen: false,
|
||||
user: Map({}),
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
"copy": "Copy to Clipboard"
|
||||
},
|
||||
"configure": {
|
||||
"custom-css-url": "Custom CSS URL",
|
||||
"custom-css-url-desc": "URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external.",
|
||||
"enable-pre-moderation": "Enable pre-moderation",
|
||||
"enable-pre-moderation-text": "Moderators must approve any comment before it is published.",
|
||||
"require-email-verification": "Require Email Verification",
|
||||
@@ -157,6 +159,8 @@
|
||||
"username_flags": ""
|
||||
},
|
||||
"configure": {
|
||||
"custom-css-url": "URL CSS a medida",
|
||||
"custom-css-url-desc": "URL de una hoja de estilo que va a sobrescribir los estilos por defecto de Embed Stream. Puede ser interna o externa.",
|
||||
"enable-pre-moderation": "Habilitar pre-moderación",
|
||||
"enable-pre-moderation-text": "Los moderadores deben aprobar cada comentario antes de que sea publicado.",
|
||||
"require-email-verification": "Necesita confirmación de correo",
|
||||
|
||||
@@ -24,6 +24,10 @@ const SettingSchema = new Schema({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
customCssUrl: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
infoBoxContent: {
|
||||
type: String,
|
||||
default: ''
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const SettingsService = require('../../services/settings');
|
||||
|
||||
router.use('/:embed', (req, res, next) => {
|
||||
switch (req.params.embed) {
|
||||
case 'stream':
|
||||
return res.render('embed/stream', {});
|
||||
return SettingsService.retrieve()
|
||||
.then(({customCssUrl}) => {
|
||||
return res.render('embed/stream', {customCssUrl});
|
||||
});
|
||||
default:
|
||||
|
||||
// will return a 404.
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
<link rel="stylesheet" type="text/css" href="/client/embed/stream/default.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato|Open+Sans" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<% if (locals.customCssUrl) { %>
|
||||
<link href="<%= customCssUrl %>" rel="stylesheet" type="text/css">
|
||||
<% } %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="coralStream"></div>
|
||||
|
||||
Reference in New Issue
Block a user