mirror of
https://github.com/wassname/talk.git
synced 2026-07-02 23:39:20 +08:00
106a5d36ed
* Implement StreamEmbed instance and rename library to coral * Add article & articleButton.html, only show embed htmls in production * Respect assetURL * Add tests * Add parseHashQuery * Fix permalink query and integration tests * Fix permalink URL * Remove optionalparams from pym * Scroll when showing permalink view * Implement autoRender * AutoRender immediately when render permalink * Add test for `showPermalink` event * Add comment
128 lines
3.1 KiB
TypeScript
128 lines
3.1 KiB
TypeScript
import { EventEmitter2 } from "eventemitter2";
|
|
import qs from "query-string";
|
|
|
|
import {
|
|
Decorator,
|
|
withAutoHeight,
|
|
withClickEvent,
|
|
withEventEmitter,
|
|
withIOSSafariWidthWorkaround,
|
|
withPymStorage,
|
|
withSetCommentID,
|
|
} from "./decorators";
|
|
import onIntersect from "./onIntersect";
|
|
import PymControl, {
|
|
defaultPymControlFactory,
|
|
PymControlFactory,
|
|
} from "./PymControl";
|
|
import { ensureEndSlash } from "./utils";
|
|
|
|
export interface StreamEmbedConfig {
|
|
assetID?: string;
|
|
assetURL?: string;
|
|
commentID?: string;
|
|
autoRender?: boolean;
|
|
title: string;
|
|
eventEmitter: EventEmitter2;
|
|
id: string;
|
|
rootURL: string;
|
|
}
|
|
|
|
export class StreamEmbed {
|
|
private config: StreamEmbedConfig;
|
|
private pymControl?: PymControl;
|
|
private pymControlFactory: PymControlFactory;
|
|
|
|
constructor(
|
|
config: StreamEmbedConfig,
|
|
pymControlFactory = defaultPymControlFactory
|
|
) {
|
|
this.config = config;
|
|
this.pymControlFactory = pymControlFactory;
|
|
if (config.commentID) {
|
|
// Delay emit of `showPermalink` event to allow
|
|
// user enough time to setup event listeners.
|
|
setTimeout(() => config.eventEmitter.emit("showPermalink"), 0);
|
|
}
|
|
if (config.autoRender) {
|
|
if (config.commentID) {
|
|
this.render();
|
|
} else {
|
|
onIntersect(document.getElementById(config.id)!, () => {
|
|
if (!this.rendered) {
|
|
this.render();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
private assertRendered() {
|
|
if (!this.pymControl) {
|
|
throw new Error("Stream Embed must be rendered first");
|
|
}
|
|
}
|
|
|
|
public on(eventName: string, callback: (data: any) => void) {
|
|
return this.config.eventEmitter.on(eventName, callback);
|
|
}
|
|
|
|
public off(eventName: string, callback: (data: any) => void) {
|
|
return this.config.eventEmitter.off(eventName, callback);
|
|
}
|
|
|
|
public login(token: string) {
|
|
this.assertRendered();
|
|
this.pymControl!.sendMessage("login", token);
|
|
}
|
|
|
|
public logout() {
|
|
this.assertRendered();
|
|
this.pymControl!.sendMessage("logout");
|
|
}
|
|
|
|
public remove() {
|
|
this.assertRendered();
|
|
this.pymControl!.remove();
|
|
this.pymControl = undefined;
|
|
}
|
|
|
|
get rendered() {
|
|
return !!this.pymControl;
|
|
}
|
|
|
|
public render() {
|
|
if (this.pymControl) {
|
|
throw new Error("Stream Embed already rendered");
|
|
}
|
|
const streamDecorators: ReadonlyArray<Decorator> = [
|
|
withIOSSafariWidthWorkaround,
|
|
withAutoHeight,
|
|
withClickEvent,
|
|
withSetCommentID,
|
|
withEventEmitter(this.config.eventEmitter),
|
|
withPymStorage(localStorage, "localStorage"),
|
|
withPymStorage(sessionStorage, "sessionStorage"),
|
|
];
|
|
|
|
const query = qs.stringify({
|
|
assetID: this.config.assetID,
|
|
assetURL: this.config.assetURL,
|
|
commentID: this.config.commentID,
|
|
});
|
|
const url = `${ensureEndSlash(this.config.rootURL)}stream.html${
|
|
query ? `?${query}` : ""
|
|
}`;
|
|
this.pymControl = this.pymControlFactory({
|
|
id: this.config.id,
|
|
title: this.config.title,
|
|
decorators: streamDecorators,
|
|
url,
|
|
});
|
|
}
|
|
}
|
|
|
|
export default function createStreamEmbed(config: StreamEmbedConfig) {
|
|
return new StreamEmbed(config);
|
|
}
|