Implement 'Go to conversation'

This commit is contained in:
Chi Vinh Le
2017-07-19 00:33:01 +07:00
parent 760d078705
commit 3b10aa3945
10 changed files with 109 additions and 42 deletions
+31 -20
View File
@@ -1,35 +1,24 @@
import pym from 'coral-framework/services/pym';
import * as actions from '../constants/stream';
import {buildUrl} from 'coral-framework/utils';
import queryString from 'query-string';
export const setActiveReplyBox = (id) => ({type: actions.SET_ACTIVE_REPLY_BOX, id});
function removeParam(key, sourceURL) {
let rtn = sourceURL.split('?')[0];
let param;
let params_arr = [];
let queryString = (sourceURL.indexOf('?') !== -1) ? sourceURL.split('?')[1] : '';
if (queryString !== '') {
params_arr = queryString.split('&');
for (let i = params_arr.length - 1; i >= 0; i -= 1) {
param = params_arr[i].split('=')[0];
if (param === key) {
params_arr.splice(i, 1);
}
}
rtn = `${rtn}?${params_arr.join('&')}`;
}
return rtn;
}
export const viewAllComments = () => {
const search = queryString.stringify({
...queryString.parse(location.search),
comment_id: undefined,
});
// remove the comment_id url param
const modifiedUrl = removeParam('comment_id', location.href);
const url = buildUrl({...location, search});
try {
// "window" here refers to the embedded iframe
window.history.replaceState({}, document.title, modifiedUrl);
window.history.replaceState({}, document.title, url);
// also change the parent url
pym.sendMessage('coral-view-all-comments');
@@ -38,6 +27,28 @@ export const viewAllComments = () => {
return {type: actions.VIEW_ALL_COMMENTS};
};
export const viewComment = (id) => {
const search = queryString.stringify({
...queryString.parse(location.search),
comment_id: id,
});
// remove the comment_id url param
const url = buildUrl({...location, search});
try {
// "window" here refers to the embedded iframe
window.history.replaceState({}, document.title, url);
// also change the parent url
pym.sendMessage('coral-view-comment', id);
} catch (e) { /* not sure if we're worried about old browsers */ }
return {type: actions.VIEW_COMMENT, id};
};
export const addCommentClassName = (className) => ({
type: actions.ADD_COMMENT_CLASSNAME,
className
@@ -1,6 +1,7 @@
export const SET_ACTIVE_REPLY_BOX = 'SET_ACTIVE_REPLY_BOX';
export const ADDTL_COMMENTS_ON_LOAD_MORE = 10;
export const VIEW_ALL_COMMENTS = 'VIEW_ALL_COMMENTS';
export const VIEW_COMMENT = 'VIEW_COMMENT';
export const ADD_COMMENT_CLASSNAME = 'ADD_COMMENT_CLASSNAME';
export const REMOVE_COMMENT_CLASSNAME = 'REMOVE_COMMENT_CLASSNAME';
export const THREADING_LEVEL = process.env.TALK_THREADING_LEVEL;
@@ -17,9 +17,9 @@ function getQueryVariable(variable) {
const initialState = {
activeReplyBox: '',
assetId: getQueryVariable('asset_id'),
assetUrl: getQueryVariable('asset_url'),
commentId: getQueryVariable('comment_id'),
assetId: getQueryVariable('asset_id') || '',
assetUrl: getQueryVariable('asset_url') || '',
commentId: getQueryVariable('comment_id') || '',
commentClassNames: [],
activeTab: 'all',
previousTab: '',
@@ -48,6 +48,11 @@ export default function stream(state = initialState, action) {
...state,
commentId: '',
};
case actions.VIEW_COMMENT:
return {
...state,
commentId: action.id,
};
case actions.ADD_COMMENT_CLASSNAME :
return {
...state,
+41 -7
View File
@@ -1,7 +1,8 @@
import pym from 'pym.js';
import URLSearchParams from 'url-search-params';
import {stringify} from 'querystring';
import {buildUrl} from 'coral-framework/utils';
import queryString from 'query-string';
// TODO: Styles should live in a separate file
const snackbarStyles = {
@@ -39,7 +40,7 @@ function buildStreamIframeUrl(talkBaseUrl, query) {
'embed/stream?'
].join('');
url += stringify(query);
url += queryString.stringify(query);
return url;
}
@@ -98,10 +99,37 @@ function configurePymParent(pymParent, opts) {
// remove the permalink comment id from the hash
pymParent.onMessage('coral-view-all-comments', function() {
const search = queryString.stringify({
...queryString.parse(location.search),
commentId: undefined,
});
// remove the commentId url param
const url = buildUrl({...location, search});
window.history.replaceState(
{},
document.title,
location.origin + location.pathname + location.search
url,
);
});
// remove the permalink comment id from the hash
pymParent.onMessage('coral-view-comment', function(id) {
const search = queryString.stringify({
...queryString.parse(location.search),
commentId: id,
});
// remove the commentId url param
const url = buildUrl({...location, search});
window.history.replaceState(
{},
document.title,
url,
);
});
@@ -193,12 +221,18 @@ Talk.render = function(el, opts) {
let urlParams = new URLSearchParams(window.location.search);
query.comment_id = urlParams.get('commentId');
if (urlParams.get('commentId')) {
query.comment_id = urlParams.get('commentId');
}
query.asset_id = opts.asset_id;
if (opts.asset_id) {
query.asset_id = opts.asset_id;
}
query.asset_url = opts.asset_url;
if (!query.asset_url) {
if (opts.asset_url) {
query.asset_url = opts.asset_url;
}
else {
try {
query.asset_url = document.querySelector('link[rel="canonical"]').href;
} catch (e) {
+9
View File
@@ -167,3 +167,12 @@ export function insertCommentsSorted(nodes, comments, sortOrder = 'CHRONOLOGICAL
}
export const isTagged = (tags, which) => tags.some((t) => t.tag.name === which);
export function buildUrl({protocol, hostname, port, pathname, search, hash} = window.location) {
if (search && search[0] !== '?') {
search = `?${search}`;
} else if (search === '?') {
search = '';
}
return `${protocol}//${hostname}${port ? `:${port}` : ''}${pathname}${search}${hash}`;
}
+1
View File
@@ -111,6 +111,7 @@
"passport-jwt": "^2.2.1",
"passport-local": "^1.0.0",
"prop-types": "^15.5.10",
"query-strings": "^0.0.1",
"react-apollo": "^1.1.0",
"react-input-autosize": "^1.1.4",
"react-recaptcha": "^2.2.6",
@@ -6,7 +6,7 @@ import {timeago} from 'coral-framework/services/i18n';
import {Slot} from 'plugin-api/beta/client/components';
import {Icon} from 'plugin-api/beta/client/components/ui';
const FeaturedComment = ({comment, asset, setActiveTab}) => {
const FeaturedComment = ({comment, asset, viewComment}) => {
return (
<div className={cn(styles.featuredComment, `${name}__featured-comment`)}>
@@ -36,7 +36,7 @@ const FeaturedComment = ({comment, asset, setActiveTab}) => {
</div>
<div className={cn(styles.actionsContainer, `${name}__featured-comment__actions`)}>
<a className={cn(styles.goTo, `${name}__featured-comment__go-to`)}
onClick={() => setActiveTab('all')} >
onClick={() => viewComment(comment.id)} >
<Icon name="forum" className={styles.repliesIcon} /> {comment.replyCount} |
Go to conversation<Icon name="keyboard_arrow_right" className={styles.goToIcon} />
</a>
@@ -1,14 +1,14 @@
import React from 'react';
import FeaturedComment from './FeaturedComment';
export default ({asset: {featuredComments, ...asset}, setActiveTab}) => (
export default ({asset: {featuredComments, ...asset}, viewComment}) => (
<div>
{featuredComments.nodes.map((comment) =>
<FeaturedComment
{featuredComments.nodes.map((comment) =>
<FeaturedComment
key={comment.id}
comment={comment}
asset={asset}
setActiveTab={setActiveTab} />
viewComment={viewComment} />
)}
</div>
);
@@ -3,11 +3,11 @@ import {bindActionCreators} from 'redux';
import {compose, gql} from 'react-apollo';
import TabPane from '../components/TabPane';
import {withFragments} from 'plugin-api/beta/client/hocs';
import {setActiveTab} from 'coral-embed-stream/src/actions/stream';
import {viewComment} from 'coral-embed-stream/src/actions/stream';
const mapDispatchToProps = (dispatch) =>
bindActionCreators({
setActiveTab,
viewComment,
}, dispatch);
const enhance = compose(
+10 -4
View File
@@ -1560,6 +1560,10 @@ check-types@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/check-types/-/check-types-1.4.0.tgz#eed63bbac9ea49a0e26a096314058b03b08dd62b"
check-valid-url@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/check-valid-url/-/check-valid-url-0.0.2.tgz#938fc545fc90b71edf800f7345bfd36f3aa0a057"
cheerio@^0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.20.0.tgz#5c710f2bab95653272842ba01c6ea61b3545ec35"
@@ -4628,10 +4632,6 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
dependencies:
jsonify "~0.0.0"
json-stringify-pretty-compact@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.0.4.tgz#d5161131be27fd9748391360597fcca250c6c5ce"
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
@@ -6806,6 +6806,12 @@ query-string@^4.1.0, query-string@^4.2.2:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
query-strings@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/query-strings/-/query-strings-0.0.1.tgz#d22bab97c9d39e2267b3b8e5f78592424b3e58cd"
dependencies:
check-valid-url "0.0.2"
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"