mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-07 19:08:37 +03:00
feat: adds graphic content protection
This commit is contained in:
27009
package-lock.json
generated
27009
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,7 @@ export const generateCardLayout = {
|
||||
source.paths.map((p) => ({
|
||||
kind: "media",
|
||||
title: "Media",
|
||||
value: [{ src: p, title: null }],
|
||||
value: [{ src: p, title: null, graphic: event.graphic === "TRUE" }],
|
||||
})),
|
||||
]),
|
||||
];
|
||||
@@ -81,6 +81,7 @@ export const generateCardLayout = {
|
||||
export const Card = ({
|
||||
content = [],
|
||||
isLoading = true,
|
||||
cardIdx = -1,
|
||||
onSelect = () => {},
|
||||
sources = [],
|
||||
isSelected = false,
|
||||
@@ -103,17 +104,25 @@ export const Card = ({
|
||||
<CardCaret toggle={() => toggle()} isOpen={isOpen} />
|
||||
);
|
||||
|
||||
const renderMedia = ({ media, idx }) => {
|
||||
return <CardMedia key={idx} src={media.src} title={media.title} />;
|
||||
const renderMedia = ({ media, idx, cardIdx }) => {
|
||||
return (
|
||||
<CardMedia
|
||||
key={idx}
|
||||
cardIdx={cardIdx}
|
||||
src={media.src}
|
||||
title={media.title}
|
||||
graphic={media.graphic}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
function renderField(field) {
|
||||
function renderField(field, cardIdx) {
|
||||
switch (field.kind) {
|
||||
case "media":
|
||||
return (
|
||||
<div className="card-cell">
|
||||
{field.value.map((media, idx) => {
|
||||
return renderMedia({ media, idx });
|
||||
return renderMedia({ media, idx, cardIdx });
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
@@ -201,11 +210,12 @@ export const Card = ({
|
||||
}
|
||||
}
|
||||
|
||||
function renderRow(row) {
|
||||
function renderRow(row, cardIdx) {
|
||||
return (
|
||||
<div className="card-row" key={hash(row)}>
|
||||
{row.map((field) => (
|
||||
<span key={hash(field)}>{renderField(field)}</span>
|
||||
// src by src meaning wrapGrahpic must be called around a map of renderField for sources
|
||||
<span key={hash(field)}>{renderField(field, cardIdx)}</span>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@@ -220,7 +230,7 @@ export const Card = ({
|
||||
className={`event-card ${isSelected ? "selected" : ""}`}
|
||||
onClick={onSelect}
|
||||
>
|
||||
{content.map((row) => renderRow(row))}
|
||||
{content.map((row) => renderRow(row, cardIdx))}
|
||||
{isOpen && (
|
||||
<div className="card-bottomhalf">
|
||||
{sources.map(() => (
|
||||
|
||||
@@ -77,7 +77,8 @@ class CardStack extends React.Component {
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={hash(content)}
|
||||
key={idx}
|
||||
cardIdx={idx}
|
||||
content={content}
|
||||
language={this.props.language}
|
||||
isLoading={this.props.isLoading}
|
||||
|
||||
@@ -11,7 +11,38 @@ const TITLE_LENGTH = 50;
|
||||
// - only show cover image and then lightbox when clicked
|
||||
// - show video control plane?
|
||||
// TODO landscape image doesn't fit in box properly
|
||||
const Media = ({ src, title }) => {
|
||||
const Media = ({ cardIdx, src, title, graphic }) => {
|
||||
const wrapGraphic = (content) => {
|
||||
if (!graphic) return content;
|
||||
|
||||
const contentId = `graphic${cardIdx}`;
|
||||
const overlayId = `overlay-${contentId}`;
|
||||
return (
|
||||
<div>
|
||||
<div className={`card-cell media source-graphic ${overlayId}`}>
|
||||
<h4
|
||||
onClick={() => {
|
||||
Array.from(document.querySelectorAll("." + contentId)).map(
|
||||
(o) => (o.style.display = "block")
|
||||
);
|
||||
// Array.from(document.querySelectorAll("." + overlayId)).map(o => o.remove())
|
||||
Array.from(document.querySelectorAll("." + overlayId)).map(
|
||||
(o) => (o.style.display = "none")
|
||||
);
|
||||
// document.getElementById(contentId).style.display = "block"
|
||||
}}
|
||||
>
|
||||
Graphic content
|
||||
<br />
|
||||
Click here to show
|
||||
</h4>
|
||||
</div>
|
||||
<span className={contentId} style={{ display: "none" }}>
|
||||
{content}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const videoRef = useRef();
|
||||
const onVideoStart = useCallback(() => {
|
||||
return videoRef.current?.play();
|
||||
@@ -28,7 +59,7 @@ const Media = ({ src, title }) => {
|
||||
|
||||
switch (type) {
|
||||
case "Video":
|
||||
return (
|
||||
return wrapGraphic(
|
||||
<div className="card-cell media">
|
||||
{title && <h4 title={title}>{formattedTitle}</h4>}
|
||||
<video
|
||||
@@ -44,7 +75,7 @@ const Media = ({ src, title }) => {
|
||||
</div>
|
||||
);
|
||||
case "Image":
|
||||
return (
|
||||
return wrapGraphic(
|
||||
<div className="card-cell media">
|
||||
{title && <h4 title={title}>{formattedTitle}</h4>}
|
||||
<div className="img-wrapper">
|
||||
@@ -57,7 +88,7 @@ const Media = ({ src, title }) => {
|
||||
);
|
||||
|
||||
case "Telegram":
|
||||
return (
|
||||
return wrapGraphic(
|
||||
<div className="card-cell media embedded">
|
||||
<TelegramPostEmbed src={src} />
|
||||
</div>
|
||||
@@ -72,7 +103,7 @@ const Media = ({ src, title }) => {
|
||||
}
|
||||
const tweetId = match[match.length - 1];
|
||||
|
||||
return (
|
||||
return wrapGraphic(
|
||||
<div className="card-cell media embedded">
|
||||
<TwitterTweetEmbed
|
||||
tweetId={tweetId}
|
||||
|
||||
@@ -19,6 +19,7 @@ function createEventSchema(custom) {
|
||||
id: Joi.string().allow(""),
|
||||
civId: Joi.string().allow(""),
|
||||
description: Joi.string().allow("").required(),
|
||||
graphic: Joi.string().allow(""),
|
||||
date: Joi.string().allow(""),
|
||||
time: Joi.string().allow(""),
|
||||
time_precision: Joi.string().allow(""),
|
||||
|
||||
@@ -266,7 +266,8 @@
|
||||
width: calc(#{$card-width} - 50px) !important;
|
||||
}
|
||||
|
||||
.source-hidden {
|
||||
.source-hidden,
|
||||
.source-graphic {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -282,3 +283,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.media.source-graphic {
|
||||
background-color: darken($red, 26%);
|
||||
h4 {
|
||||
color: white;
|
||||
}
|
||||
h4:hover {
|
||||
font-size: 103%;
|
||||
color: lighten(yellow, 20%);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user