mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-08 03:18:36 +03:00
Add support for Twitter and Telegram
This commit is contained in:
@@ -80,6 +80,7 @@
|
||||
"react-redux": "^5.0.4",
|
||||
"react-refresh": "^0.8.3",
|
||||
"react-tabs": "3.0.0",
|
||||
"react-twitter-embed": "^4.0.4",
|
||||
"redux": "^3.6.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"reselect": "^3.0.1",
|
||||
|
||||
@@ -323,6 +323,13 @@ export function typeForPath(path) {
|
||||
case /\.(pdf)$/.test(path):
|
||||
type = "Document";
|
||||
break;
|
||||
case /.+(twitter\.com).+/.test(path):
|
||||
type = "Tweet";
|
||||
break;
|
||||
case /.+(t\.me).+/.test(path):
|
||||
type = "Telegram";
|
||||
break;
|
||||
|
||||
default:
|
||||
type = "Unknown";
|
||||
break;
|
||||
|
||||
@@ -58,14 +58,6 @@ export const generateCardLayout = {
|
||||
},
|
||||
],
|
||||
...event.sources.flatMap((source, idx) => [
|
||||
[
|
||||
{
|
||||
kind: "text",
|
||||
title: `Source ${idx}`,
|
||||
value: source.description || ``,
|
||||
scaleFont: 1.1,
|
||||
},
|
||||
],
|
||||
source.paths.map((p) => ({
|
||||
kind: "media",
|
||||
title: "Media",
|
||||
|
||||
@@ -67,7 +67,6 @@ class CardStack extends React.Component {
|
||||
return events.map((event, idx) => {
|
||||
const thisRef = React.createRef();
|
||||
this.refs[idx] = thisRef;
|
||||
console.log(event);
|
||||
|
||||
const content = generateTemplate({
|
||||
event,
|
||||
@@ -78,7 +77,6 @@ class CardStack extends React.Component {
|
||||
|
||||
return (
|
||||
<Card
|
||||
ref={thisRef}
|
||||
key={hash(content)}
|
||||
content={content}
|
||||
language={this.props.language}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { useRef } from "react";
|
||||
import { useCallback } from "react";
|
||||
import { typeForPath } from "../../../common/utilities";
|
||||
import { TwitterTweetEmbed } from "react-twitter-embed";
|
||||
import TelegramPostEmbed from "./TelegramEmbed";
|
||||
|
||||
const TITLE_LENGTH = 50;
|
||||
// TODO should videos
|
||||
@@ -53,6 +55,25 @@ const Media = ({ src, title }) => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
case "Telegram":
|
||||
return (
|
||||
<div className="card-cell media embedded">
|
||||
<TelegramPostEmbed src={src} />
|
||||
</div>
|
||||
);
|
||||
|
||||
case "Tweet":
|
||||
const tweetIdRegex =
|
||||
/https?:\/\/twitter.com\/[0-9a-zA-Z_]{1,20}\/status\/([0-9]*)/;
|
||||
const match = tweetIdRegex.exec(src);
|
||||
const tweetId = match[1];
|
||||
|
||||
return (
|
||||
<div className="card-cell media embedded">
|
||||
<TwitterTweetEmbed tweetId={tweetId} />
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
105
src/components/controls/atoms/TelegramEmbed.js
Normal file
105
src/components/controls/atoms/TelegramEmbed.js
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Adapted from https://github.com/cudr/react-telegram-embed
|
||||
*/
|
||||
import React, { Component } from "react";
|
||||
|
||||
const styles = {
|
||||
width: "100%",
|
||||
frameBorder: "0",
|
||||
scrolling: "no",
|
||||
border: "none",
|
||||
overflow: "hidden",
|
||||
};
|
||||
|
||||
const containerStyles = {
|
||||
marginLeft: -60,
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple Component for Telegram embedding
|
||||
* @extends Component
|
||||
*/
|
||||
|
||||
class TelegramEmbed extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
src: this.props.src,
|
||||
id: "",
|
||||
height: "80px",
|
||||
};
|
||||
this.messageHandler = this.messageHandler.bind(this);
|
||||
this.urlObj = document.createElement("a");
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("message", this.messageHandler);
|
||||
|
||||
this.iFrame.addEventListener("load", () => {
|
||||
this.checkFrame(this.state.id);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("message", this.messageHandler);
|
||||
}
|
||||
|
||||
messageHandler({ data, source }) {
|
||||
if (
|
||||
!data ||
|
||||
typeof data !== "string" ||
|
||||
source !== this.iFrame.contentWindow
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const action = JSON.parse(data);
|
||||
|
||||
if (action.event === "resize" && action.height) {
|
||||
this.setState({
|
||||
height: action.height + "px",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
checkFrame(id) {
|
||||
this.iFrame.contentWindow.postMessage(
|
||||
JSON.stringify({ event: "visible", frame: id }),
|
||||
"*"
|
||||
);
|
||||
}
|
||||
|
||||
componentWillReceiveProps({ src }) {
|
||||
if (this.state.src !== src) {
|
||||
this.urlObj.href = src;
|
||||
const id = `telegram-post${this.urlObj.pathname.replace(
|
||||
/[^a-z0-9_]/gi,
|
||||
"-"
|
||||
)}`;
|
||||
|
||||
this.setState({ src, id }, () => this.checkFrame(id));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { src, height } = this.state;
|
||||
const { container } = this.props;
|
||||
|
||||
return (
|
||||
<div data-sharing-id={container} style={containerStyles}>
|
||||
<iframe
|
||||
ref={(node) => (this.iFrame = node)}
|
||||
src={src + "?embed=1"}
|
||||
height={height}
|
||||
id={
|
||||
"telegram-post" + this.urlObj.pathname.replace(/[^a-z0-9_]/gi, "-")
|
||||
}
|
||||
style={styles}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TelegramEmbed;
|
||||
@@ -63,7 +63,7 @@ $timeline: 3;
|
||||
$infopopup-width: 400px;
|
||||
$infopopup-left: 122px;
|
||||
$infopopup-bottom: 180px;
|
||||
$card-width: 386px;
|
||||
$card-width: 600px;
|
||||
$card-right: 9px;
|
||||
$narrative-info-height: 205px;
|
||||
$narrative-info-desc-height: 153px;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
text-align: left;
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
max-width: 400px;
|
||||
max-width: $card-width;
|
||||
|
||||
&:hover {
|
||||
background: $lightwhite;
|
||||
@@ -53,6 +53,7 @@
|
||||
.card-col {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
.card-cell {
|
||||
flex: 1;
|
||||
@@ -182,7 +183,7 @@
|
||||
|
||||
.media {
|
||||
display: flex;
|
||||
max-height: 350px;
|
||||
// max-height: 350px;
|
||||
// justify-content: center;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
@@ -268,4 +269,8 @@
|
||||
.card-row {
|
||||
border-color: darkgray;
|
||||
}
|
||||
|
||||
.embedded {
|
||||
width: calc(#{$card-width} - 2px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user