mirror of
https://github.com/wassname/talk.git
synced 2026-06-27 19:17:09 +08:00
[CORL-436] Embed Code (#2398)
* feat: initial implementation * fix: moved embed configuration to advanced * feat: added copy button to embed code * fix: removing unused line
This commit is contained in:
Generated
+7
-2
@@ -3541,6 +3541,12 @@
|
||||
"commander": "*"
|
||||
}
|
||||
},
|
||||
"@types/common-tags": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.0.tgz",
|
||||
"integrity": "sha512-htRqZr5qn8EzMelhX/Xmx142z218lLyGaeZ3YR8jlze4TATRU9huKKvuBmAJEW4LCC4pnY1N6JAm6p85fMHjhg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/compression-webpack-plugin": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/compression-webpack-plugin/-/compression-webpack-plugin-2.0.0.tgz",
|
||||
@@ -7992,8 +7998,7 @@
|
||||
"common-tags": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
|
||||
"integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw=="
|
||||
},
|
||||
"commondir": {
|
||||
"version": "1.0.1",
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"bull": "^3.8.1",
|
||||
"bunyan": "^1.8.12",
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"common-tags": "^1.8.0",
|
||||
"consolidate": "0.14.0",
|
||||
"content-security-policy-builder": "^2.0.0",
|
||||
"convict": "^4.3.1",
|
||||
@@ -152,6 +153,7 @@
|
||||
"@types/cheerio": "^0.22.8",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/commander": "^2.12.2",
|
||||
"@types/common-tags": "^1.8.0",
|
||||
"@types/compression-webpack-plugin": "^2.0.0",
|
||||
"@types/consolidate": "0.0.34",
|
||||
"@types/convict": "^4.2.0",
|
||||
|
||||
@@ -5,6 +5,7 @@ import { HorizontalGutter } from "coral-ui/components";
|
||||
|
||||
import CommentStreamLiveUpdatesContainer from "./CommentStreamLiveUpdatesContainer";
|
||||
import CustomCSSConfigContainer from "./CustomCSSConfigContainer";
|
||||
import EmbedCodeContainer from "./EmbedCodeContainer";
|
||||
import PermittedDomainsConfigContainer from "./PermittedDomainsConfigContainer";
|
||||
|
||||
interface Props {
|
||||
@@ -12,7 +13,8 @@ interface Props {
|
||||
settings: PropTypesOf<typeof CustomCSSConfigContainer>["settings"] &
|
||||
PropTypesOf<typeof PermittedDomainsConfigContainer>["settings"] &
|
||||
PropTypesOf<typeof CommentStreamLiveUpdatesContainer>["settings"] &
|
||||
PropTypesOf<typeof CommentStreamLiveUpdatesContainer>["settingsReadOnly"];
|
||||
PropTypesOf<typeof CommentStreamLiveUpdatesContainer>["settingsReadOnly"] &
|
||||
PropTypesOf<typeof EmbedCodeContainer>["settings"];
|
||||
onInitValues: (values: any) => void;
|
||||
}
|
||||
|
||||
@@ -22,6 +24,7 @@ const AdvancedConfig: FunctionComponent<Props> = ({
|
||||
onInitValues,
|
||||
}) => (
|
||||
<HorizontalGutter size="double" data-testid="configure-advancedContainer">
|
||||
<EmbedCodeContainer settings={settings} />
|
||||
<CustomCSSConfigContainer
|
||||
disabled={disabled}
|
||||
settings={settings}
|
||||
|
||||
@@ -45,6 +45,7 @@ class AdvancedConfigContainer extends React.Component<Props> {
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
settings: graphql`
|
||||
fragment AdvancedConfigContainer_settings on Settings {
|
||||
...EmbedCodeContainer_settings
|
||||
...CustomCSSConfigContainer_settings
|
||||
...PermittedDomainsConfigContainer_settings
|
||||
...CommentStreamLiveUpdatesContainer_settings
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
.textArea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: calc(0.5 * var(--mini-unit));
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.copyArea {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { stripIndent } from "common-tags";
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { FunctionComponent, useMemo } from "react";
|
||||
|
||||
import { getLocationOrigin } from "coral-common/utils";
|
||||
import { CopyButton } from "coral-framework/components";
|
||||
import { HorizontalGutter, Typography } from "coral-ui/components";
|
||||
|
||||
import Header from "../../Header";
|
||||
|
||||
import styles from "./EmbedCode.css";
|
||||
|
||||
interface Props {
|
||||
staticURI: string | null;
|
||||
}
|
||||
|
||||
const EmbedCode: FunctionComponent<Props> = ({ staticURI }) => {
|
||||
const embed = useMemo(() => {
|
||||
// Get the origin of the current page.
|
||||
const origin = getLocationOrigin();
|
||||
|
||||
// Optionally use the staticURI for configuration.
|
||||
const script = staticURI || origin;
|
||||
|
||||
// Return the HTML template.
|
||||
const text = stripIndent`
|
||||
<div id="coral_thread"></div>
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = '${script}/assets/js/embed.js';
|
||||
s.onload = function() {
|
||||
Coral.createStreamEmbed({
|
||||
id: "coral_thread",
|
||||
autoRender: true,
|
||||
rootURL: '${origin}',
|
||||
// Comment these out and replace with the ID of the
|
||||
// story's ID and URL from your CMS to provide the
|
||||
// tightest integration. Refer to our documentation at
|
||||
// https://docs.coralproject.net for all the configuration
|
||||
// options.
|
||||
// storyID: '\${storyID}',
|
||||
// storyURL: '\${storyURL}',
|
||||
});
|
||||
};
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
</script>`;
|
||||
|
||||
// Count the number of rows in the embed code.
|
||||
const rows = text.split(/\r\n|\r|\n/).length;
|
||||
|
||||
return { text, rows };
|
||||
}, [staticURI]);
|
||||
|
||||
return (
|
||||
<HorizontalGutter size="oneAndAHalf" container="fieldset">
|
||||
<Localized id="configure-advanced-embedCode-title">
|
||||
<Header container="legend">Embed Code</Header>
|
||||
</Localized>
|
||||
<Localized id="configure-advanced-embedCode-explanation">
|
||||
<Typography variant="detail">
|
||||
Copy and paste the code below into your CMS to embed Coral comment
|
||||
streams in each of your site’s stories.
|
||||
</Typography>
|
||||
</Localized>
|
||||
<textarea
|
||||
rows={embed.rows}
|
||||
className={styles.textArea}
|
||||
readOnly
|
||||
value={embed.text}
|
||||
/>
|
||||
<HorizontalGutter className={styles.copyArea}>
|
||||
<CopyButton size="regular" text={embed.text} />
|
||||
</HorizontalGutter>
|
||||
</HorizontalGutter>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmbedCode;
|
||||
@@ -0,0 +1,25 @@
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { graphql } from "react-relay";
|
||||
|
||||
import { EmbedCodeContainer_settings } from "coral-admin/__generated__/EmbedCodeContainer_settings.graphql";
|
||||
import { withFragmentContainer } from "coral-framework/lib/relay";
|
||||
|
||||
import EmbedCode from "./EmbedCode";
|
||||
|
||||
interface Props {
|
||||
settings: EmbedCodeContainer_settings;
|
||||
}
|
||||
|
||||
const EmbedCodeContainer: FunctionComponent<Props> = ({ settings }) => {
|
||||
return <EmbedCode staticURI={settings.staticURI} />;
|
||||
};
|
||||
|
||||
const enhanced = withFragmentContainer<Props>({
|
||||
settings: graphql`
|
||||
fragment EmbedCodeContainer_settings on Settings {
|
||||
staticURI
|
||||
}
|
||||
`,
|
||||
})(EmbedCodeContainer);
|
||||
|
||||
export default enhanced;
|
||||
@@ -107,6 +107,66 @@ exports[`renders configure advanced 1`] = `
|
||||
className="Box-root HorizontalGutter-root HorizontalGutter-double"
|
||||
data-testid="configure-advancedContainer"
|
||||
>
|
||||
<fieldset
|
||||
className="Box-root HorizontalGutter-root HorizontalGutter-oneAndAHalf"
|
||||
>
|
||||
<legend
|
||||
className="Box-root Typography-root Typography-heading1 Typography-colorTextPrimary Header-root"
|
||||
>
|
||||
Embed Code
|
||||
</legend>
|
||||
<p
|
||||
className="Box-root Typography-root Typography-detail Typography-colorTextPrimary"
|
||||
>
|
||||
Copy and paste the code below into your CMS to embed Coral comment streams in
|
||||
each of your site’s stories.
|
||||
</p>
|
||||
<textarea
|
||||
className="EmbedCode-textArea"
|
||||
readOnly={true}
|
||||
rows={22}
|
||||
value="<div id=\\"coral_thread\\"></div>
|
||||
<script type=\\"text/javascript\\">
|
||||
(function() {
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'http://localhost/assets/js/embed.js';
|
||||
s.onload = function() {
|
||||
Coral.createStreamEmbed({
|
||||
id: \\"coral_thread\\",
|
||||
autoRender: true,
|
||||
rootURL: 'http://localhost',
|
||||
// Comment these out and replace with the ID of the
|
||||
// story's ID and URL from your CMS to provide the
|
||||
// tightest integration. Refer to our documentation at
|
||||
// https://docs.coralproject.net for all the configuration
|
||||
// options.
|
||||
// storyID: '\${storyID}',
|
||||
// storyURL: '\${storyURL}',
|
||||
});
|
||||
};
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
</script>"
|
||||
/>
|
||||
<div
|
||||
className="Box-root HorizontalGutter-root EmbedCode-copyArea HorizontalGutter-full"
|
||||
>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeRegular Button-colorPrimary Button-variantFilled"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Copy
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div
|
||||
className="Box-root HorizontalGutter-root FormField-root HorizontalGutter-half"
|
||||
>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { EventEmitter2 } from "eventemitter2";
|
||||
|
||||
import { parseQuery } from "coral-common/utils";
|
||||
import { getLocationOrigin, parseQuery } from "coral-common/utils";
|
||||
|
||||
import { default as create, StreamEmbed } from "./StreamEmbed";
|
||||
|
||||
@@ -15,15 +15,6 @@ export interface Config {
|
||||
accessToken?: string;
|
||||
}
|
||||
|
||||
function getLocationOrigin() {
|
||||
return (
|
||||
location.origin ||
|
||||
`${window.location.protocol}//${window.location.hostname}${
|
||||
window.location.port ? `:${window.location.port}` : ""
|
||||
}`
|
||||
);
|
||||
}
|
||||
|
||||
function resolveStoryURL() {
|
||||
const canonical = document.querySelector(
|
||||
'link[rel="canonical"]'
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export default function getLocationOrigin() {
|
||||
return (
|
||||
location.origin || `${window.location.protocol}//${window.location.host}`
|
||||
);
|
||||
}
|
||||
@@ -8,3 +8,4 @@ export { default as ensureNoEndSlash } from "./ensureNoEndSlash";
|
||||
export { default as parseQuery } from "./parseQuery";
|
||||
export { default as stringifyQuery } from "./stringifyQuery";
|
||||
export { default as pureMerge } from "./pureMerge";
|
||||
export { default as getLocationOrigin } from "./getLocationOrigin";
|
||||
|
||||
@@ -170,7 +170,7 @@ const config = convict({
|
||||
format: "optional-url",
|
||||
default: "",
|
||||
env: "STATIC_URI",
|
||||
arg: "staticUri",
|
||||
arg: "staticURI",
|
||||
},
|
||||
websocket_keep_alive_timeout: {
|
||||
doc:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { GQLSettingsTypeResolver } from "coral-server/graph/tenant/schema/__generated__/types";
|
||||
import { Tenant } from "coral-server/models/tenant";
|
||||
|
||||
export const Settings: GQLSettingsTypeResolver<Tenant> = {
|
||||
staticURI: (tenant, args, ctx) => ctx.config.get("static_uri") || null,
|
||||
};
|
||||
@@ -1076,6 +1076,11 @@ type Settings {
|
||||
"""
|
||||
domain: String! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
staticURI if configured, is the static URI used to serve static files from.
|
||||
"""
|
||||
staticURI: String @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
allowedDomains is the list of domains that stories can come from.
|
||||
"""
|
||||
|
||||
@@ -296,6 +296,7 @@ configure-wordList-suspect-wordListDetail =
|
||||
configure-advanced-customCSS = Custom CSS
|
||||
configure-advanced-customCSS-explanation =
|
||||
URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external.
|
||||
|
||||
configure-advanced-permittedDomains = Permitted Domains
|
||||
configure-advanced-permittedDomains-explanation =
|
||||
Domains where your { -product-name } instance is allowed to be embedded.
|
||||
@@ -306,6 +307,11 @@ configure-advanced-liveUpdates = Comment Stream Live Updates
|
||||
configure-advanced-liveUpdates-explanation =
|
||||
When enabled, there will be real-time loading and updating of comments as new comments and replies are published
|
||||
|
||||
configure-advanced-embedCode-title = Embed Code
|
||||
configure-advanced-embedCode-explanation =
|
||||
Copy and paste the code below into your CMS to embed Coral comment streams in
|
||||
each of your site’s stories.
|
||||
|
||||
## Decision History
|
||||
decisionHistory-popover =
|
||||
.description = A dialog showing the decision history
|
||||
|
||||
Reference in New Issue
Block a user