mirror of
https://github.com/wassname/talk.git
synced 2026-07-03 13:28:50 +08:00
Implement streamTabs and streamTabPanes slot
This commit is contained in:
@@ -13,4 +13,5 @@ plugins/*
|
||||
!plugins/coral-plugin-viewing-options
|
||||
!plugins/coral-plugin-comment-content
|
||||
!plugins/talk-plugin-permalink
|
||||
!plugins/talk-plugin-featured
|
||||
node_modules
|
||||
|
||||
@@ -26,5 +26,6 @@ plugins/*
|
||||
!plugins/coral-plugin-viewing-options
|
||||
!plugins/coral-plugin-comment-content
|
||||
!plugins/talk-plugin-permalink
|
||||
!plugins/talk-plugin-featured
|
||||
|
||||
**/node_modules/*
|
||||
|
||||
@@ -9,6 +9,7 @@ import {ModerationLink} from 'coral-plugin-moderation';
|
||||
import RestrictedMessageBox
|
||||
from 'coral-framework/components/RestrictedMessageBox';
|
||||
import t, {timeago} from 'coral-framework/services/i18n';
|
||||
import {getSlotComponents} from 'coral-framework/helpers/plugins';
|
||||
import CommentBox from 'coral-plugin-commentbox/CommentBox';
|
||||
import QuestionBox from 'coral-plugin-questionbox/QuestionBox';
|
||||
import {Button, TabBar, Tab, TabCount, TabContent, TabPane} from 'coral-ui';
|
||||
@@ -202,17 +203,30 @@ class Stream extends React.Component {
|
||||
<Slot fill="streamFilter" />
|
||||
</div>
|
||||
<TabBar activeTab={activeStreamTab} onTabClick={setActiveStreamTab} sub>
|
||||
<Tab tabId={'featured'}>
|
||||
Featured
|
||||
</Tab>
|
||||
{getSlotComponents('streamTabs').map((PluginComponent) => (
|
||||
<Tab tabId={PluginComponent.talkPluginName} key={PluginComponent.talkPluginName}>
|
||||
<PluginComponent
|
||||
active={activeStreamTab === PluginComponent.talkPluginName}
|
||||
data={data}
|
||||
root={root}
|
||||
asset={asset}
|
||||
/>
|
||||
</Tab>
|
||||
))}
|
||||
<Tab tabId={'all'}>
|
||||
All Comments <TabCount active={activeStreamTab === 'all'} sub>{totalCommentCount}</TabCount>
|
||||
</Tab>
|
||||
</TabBar>
|
||||
<TabContent activeTab={activeStreamTab} sub>
|
||||
<TabPane tabId={'featured'}>
|
||||
TODO
|
||||
</TabPane>
|
||||
{getSlotComponents('streamTabPanes').map((PluginComponent) => (
|
||||
<TabPane tabId={PluginComponent.talkPluginName} key={PluginComponent.talkPluginName}>
|
||||
<PluginComponent
|
||||
data={data}
|
||||
root={root}
|
||||
asset={asset}
|
||||
/>
|
||||
</TabPane>
|
||||
))}
|
||||
<TabPane tabId={'all'}>
|
||||
<AllCommentsPane
|
||||
data={data}
|
||||
|
||||
@@ -14,6 +14,7 @@ import {setActiveReplyBox, setActiveTab, viewAllComments} from '../actions/strea
|
||||
import Stream from '../components/Stream';
|
||||
import Comment from './Comment';
|
||||
import {withFragments} from 'coral-framework/hocs';
|
||||
import {getSlotsFragments} from 'coral-framework/helpers/plugins';
|
||||
import {Spinner} from 'coral-ui';
|
||||
import {getDefinitionName} from 'coral-framework/utils';
|
||||
import {
|
||||
@@ -240,6 +241,11 @@ const LOAD_MORE_QUERY = gql`
|
||||
${Comment.fragments.comment}
|
||||
`;
|
||||
|
||||
const pluginFragments = getSlotsFragments([
|
||||
'streamTabs',
|
||||
'streamTabPanes',
|
||||
]);
|
||||
|
||||
const fragments = {
|
||||
root: gql`
|
||||
fragment CoralEmbedStream_Stream_root on RootQuery {
|
||||
@@ -281,6 +287,7 @@ const fragments = {
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
${pluginFragments.spreads('asset')}
|
||||
}
|
||||
me {
|
||||
status
|
||||
@@ -291,8 +298,11 @@ const fragments = {
|
||||
settings {
|
||||
organizationName
|
||||
}
|
||||
${pluginFragments.spreads('root')}
|
||||
...${getDefinitionName(Comment.fragments.root)}
|
||||
}
|
||||
${pluginFragments.definitions('asset')}
|
||||
${pluginFragments.definitions('root')}
|
||||
${Comment.fragments.root}
|
||||
${commentFragment}
|
||||
`,
|
||||
|
||||
@@ -10,17 +10,16 @@ import {loadTranslations} from 'coral-framework/services/i18n';
|
||||
import {injectReducers, getStore} from 'coral-framework/services/store';
|
||||
import camelize from './camelize';
|
||||
|
||||
function getSlotComponents(slot) {
|
||||
export function getSlotComponents(slot) {
|
||||
const pluginConfig = getStore().getState().config.plugin_config;
|
||||
|
||||
// Filter out components that have been disabled in `plugin_config`
|
||||
return flatten(plugins
|
||||
|
||||
// Filter out components that have been disabled in `plugin_config`
|
||||
.filter((o) => !pluginConfig || !pluginConfig[o.plugin] || !pluginConfig[o.plugin].disable_components)
|
||||
|
||||
.filter((o) => !pluginConfig || !pluginConfig[o.name] || !pluginConfig[o.name].disable_components)
|
||||
.filter((o) => o.module.slots[slot])
|
||||
.map((o) => o.module.slots[slot]));
|
||||
.map((o) => o.module.slots[slot])
|
||||
);
|
||||
}
|
||||
|
||||
export function isSlotEmpty(slot) {
|
||||
@@ -113,7 +112,22 @@ export function injectPluginsReducers() {
|
||||
const reducers = merge(
|
||||
...plugins
|
||||
.filter((o) => o.module.reducer)
|
||||
.map((o) => ({[camelize(o.plugin)] : o.module.reducer}))
|
||||
.map((o) => ({[camelize(o.name)] : o.module.reducer}))
|
||||
);
|
||||
injectReducers(reducers);
|
||||
}
|
||||
|
||||
function addMetaDataToSlotComponents() {
|
||||
|
||||
// Add talkPluginName to Slot Components.
|
||||
plugins.forEach((plugin) => {
|
||||
const slots = plugin.module.slots;
|
||||
slots && Object.keys(slots).forEach((slot) => {
|
||||
slots[slot].forEach((component) => {
|
||||
component.talkPluginName = plugin.name;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
addMetaDataToSlotComponents();
|
||||
|
||||
@@ -22,7 +22,7 @@ module.exports = function(source) {
|
||||
const config = this.exec(source, this.resourcePath);
|
||||
const plugins = getPluginList(config).map((plugin) => `{
|
||||
module: require('${plugin}/client'),
|
||||
plugin: '${plugin}'
|
||||
name: '${plugin}'
|
||||
}`);
|
||||
|
||||
return stripIndent`
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
font-weight: bold;
|
||||
border-bottom: solid 3px #10589b;
|
||||
margin-bottom: 0px;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.root:only-child .button, .rootSub:only-child .buttonSub {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"presets": [
|
||||
"es2015"
|
||||
],
|
||||
"plugins": [
|
||||
"add-module-exports",
|
||||
"transform-class-properties",
|
||||
"transform-decorators-legacy",
|
||||
"transform-object-assign",
|
||||
"transform-object-rest-spread",
|
||||
"transform-async-to-generator",
|
||||
"transform-react-jsx"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"mocha": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true,
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"rules": {
|
||||
"react/jsx-uses-react": "error",
|
||||
"react/jsx-uses-vars": "error",
|
||||
"no-console": ["warn", { "allow": ["warn", "error"] }]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import {TabCount} from 'plugin-api/beta/client/components/ui';
|
||||
|
||||
export default ({active, asset: {recentComments}}) => (
|
||||
<span>
|
||||
Featured <TabCount active={active} sub>{recentComments.length}</TabCount>
|
||||
</span>
|
||||
);
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
export default ({asset: {recentComments}}) => (
|
||||
<div>
|
||||
{recentComments.map((comment) => (
|
||||
<p key={comment.id}>
|
||||
<div><strong>{comment.user.username}</strong></div>
|
||||
<div>
|
||||
{comment.body}
|
||||
</div>
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,16 @@
|
||||
import {compose, gql} from 'react-apollo';
|
||||
import withFragments from 'coral-framework/hocs/withFragments';
|
||||
import Tab from '../components/Tab';
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
asset: gql`
|
||||
fragment TalkFeatured_Tab_asset on Asset {
|
||||
recentComments {
|
||||
id
|
||||
}
|
||||
}`,
|
||||
}),
|
||||
);
|
||||
|
||||
export default enhance(Tab);
|
||||
@@ -0,0 +1,21 @@
|
||||
import {compose, gql} from 'react-apollo';
|
||||
import withFragments from 'coral-framework/hocs/withFragments';
|
||||
import TabPane from '../components/TabPane';
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
asset: gql`
|
||||
fragment TalkFeatured_TabPane_asset on Asset {
|
||||
recentComments {
|
||||
id
|
||||
body
|
||||
user {
|
||||
id
|
||||
username
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}),
|
||||
);
|
||||
|
||||
export default enhance(TabPane);
|
||||
@@ -0,0 +1,9 @@
|
||||
import Tab from './containers/Tab';
|
||||
import TabPane from './containers/TabPane';
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
streamTabs: [Tab],
|
||||
streamTabPanes: [TabPane],
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
module.exports = {};
|
||||
|
||||
Reference in New Issue
Block a user