mirror of
https://github.com/filecoin-project/slate.git
synced 2024-12-28 11:32:46 +03:00
cleanup: fixes video playing if its quicktime/mov, accurately catches string cases, updates CID field to show full URL instead
This commit is contained in:
parent
6e034f3ec2
commit
59c6e4e2b8
@ -7,22 +7,6 @@ const WEEK = DAY * 7;
|
||||
const MONTH = (DAY * 365) / 12;
|
||||
const YEAR = DAY * 365;
|
||||
|
||||
export const copyText = (str) => {
|
||||
const el = document.createElement("textarea");
|
||||
el.value = str;
|
||||
el.setAttribute("readonly", "");
|
||||
el.style.position = "absolute";
|
||||
el.style.left = "-9999px";
|
||||
el.style.visibility = "hidden";
|
||||
el.style.opacity = "0";
|
||||
document.body.appendChild(el);
|
||||
el.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(el);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export const getKey = (text) => {
|
||||
if (isEmpty(text)) {
|
||||
return null;
|
||||
@ -56,6 +40,144 @@ export const getCIDGatewayURL = (cid) => {
|
||||
return `${Constants.gateways.ipfs}/${cid}`;
|
||||
};
|
||||
|
||||
export const getCIDGatewayURLWithExtension = (cid, name) => {
|
||||
const url = getCIDGatewayURL(cid);
|
||||
const extension = getFileExtension(name);
|
||||
if (!isEmpty(extension)) {
|
||||
return `${url}.${getFileExtension(name)}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
export const getFileExtension = (name) => {
|
||||
return name.slice(((name.lastIndexOf(".") - 1) >>> 0) + 2);
|
||||
};
|
||||
|
||||
export const formatAsFilecoin = (number) => {
|
||||
return `${number} FIL`;
|
||||
};
|
||||
|
||||
export const pluralize = (text, count) => {
|
||||
return count > 1 || count === 0 ? `${text}s` : text;
|
||||
};
|
||||
|
||||
export const toDate = (data) => {
|
||||
const date = new Date(data);
|
||||
return `${date.getMonth() + 1}-${date.getDate()}-${date.getFullYear()}`;
|
||||
};
|
||||
|
||||
export const formatNumber = (x) => {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
};
|
||||
|
||||
export const elide = (string, length = 140, emptyState = "...") => {
|
||||
if (isEmpty(string)) {
|
||||
return emptyState;
|
||||
}
|
||||
|
||||
if (string.length < length) {
|
||||
return string.trim();
|
||||
}
|
||||
|
||||
return `${string.substring(0, length)}...`;
|
||||
};
|
||||
|
||||
export const isEmpty = (string) => {
|
||||
// NOTE(jim): This is not empty when its coerced into a string.
|
||||
if (string === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof string === "object") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string = string.toString();
|
||||
|
||||
return !string.trim();
|
||||
};
|
||||
|
||||
export const bytesToSize = (bytes, decimals = 2) => {
|
||||
if (bytes === 0) return "0 Bytes";
|
||||
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return `${(bytes / Math.pow(k, i)).toFixed(dm)} ${sizes[i]}`;
|
||||
};
|
||||
|
||||
export const getRemainingTime = (seconds) => {
|
||||
seconds = seconds > 0 ? seconds : 1;
|
||||
|
||||
let [value, unit] =
|
||||
seconds < MINUTE
|
||||
? [Math.round(seconds), "second"]
|
||||
: seconds < HOUR
|
||||
? [Math.round(seconds / MINUTE), "minute"]
|
||||
: seconds < DAY
|
||||
? [Math.round(seconds / HOUR), "hour"]
|
||||
: seconds < WEEK
|
||||
? [Math.round(seconds / DAY), "day"]
|
||||
: seconds < MONTH
|
||||
? [Math.round(seconds / WEEK), "week"]
|
||||
: seconds < YEAR
|
||||
? [Math.round(seconds / MONTH), "month"]
|
||||
: [Math.round(seconds / YEAR), "year"];
|
||||
|
||||
unit = pluralize(unit, value);
|
||||
|
||||
return `${value} ${unit} remaining`;
|
||||
};
|
||||
|
||||
export const hexToRGBA = (hex, alpha = 1) => {
|
||||
hex = hex.replace("#", "");
|
||||
var r = parseInt(
|
||||
hex.length == 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2),
|
||||
16
|
||||
);
|
||||
var g = parseInt(
|
||||
hex.length == 3 ? hex.slice(1, 2).repeat(2) : hex.slice(2, 4),
|
||||
16
|
||||
);
|
||||
var b = parseInt(
|
||||
hex.length == 3 ? hex.slice(2, 3).repeat(2) : hex.slice(4, 6),
|
||||
16
|
||||
);
|
||||
if (alpha) {
|
||||
return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
|
||||
} else {
|
||||
return "rgb(" + r + ", " + g + ", " + b + ")";
|
||||
}
|
||||
};
|
||||
|
||||
export const copyText = (str) => {
|
||||
const el = document.createElement("textarea");
|
||||
el.value = str;
|
||||
el.setAttribute("readonly", "");
|
||||
el.style.position = "absolute";
|
||||
el.style.left = "-9999px";
|
||||
el.style.visibility = "hidden";
|
||||
el.style.opacity = "0";
|
||||
document.body.appendChild(el);
|
||||
el.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(el);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// SOURCE(jim):
|
||||
// https://gist.github.com/mathewbyrne/1280286
|
||||
// modified to support chinese characters, base case, and german.
|
||||
@ -116,133 +238,3 @@ export const createSlug = (text, base = "untitled") => {
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
/*
|
||||
export const createSlug = (text, base = "untitled") => {
|
||||
if (isEmpty(text)) {
|
||||
return base;
|
||||
}
|
||||
|
||||
return text
|
||||
.toString()
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/[^\w-]+/g, "")
|
||||
.replace(/--+/g, "-");
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
export const createSlug = (text, base = "untitled") => {
|
||||
if (isEmpty(text)) {
|
||||
return base;
|
||||
}
|
||||
|
||||
const a = "æøåàáäâèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;";
|
||||
const b = "aoaaaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------";
|
||||
const p = new RegExp(a.split("").join("|"), "g");
|
||||
|
||||
return text
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, "-") // Replace spaces with -
|
||||
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special chars
|
||||
.replace(/&/g, "-and-") // Replace & with 'and'
|
||||
.replace(/[^\w\-]+/g, "") // Remove all non-word chars
|
||||
.replace(/\-\-+/g, "-") // Replace multiple - with single -
|
||||
.replace(/^-+/, "") // Trim - from start of text
|
||||
.replace(/-+$/, ""); // Trim - from end of text
|
||||
};
|
||||
*/
|
||||
|
||||
export const hexToRGBA = (hex, alpha = 1) => {
|
||||
hex = hex.replace("#", "");
|
||||
var r = parseInt(
|
||||
hex.length == 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2),
|
||||
16
|
||||
);
|
||||
var g = parseInt(
|
||||
hex.length == 3 ? hex.slice(1, 2).repeat(2) : hex.slice(2, 4),
|
||||
16
|
||||
);
|
||||
var b = parseInt(
|
||||
hex.length == 3 ? hex.slice(2, 3).repeat(2) : hex.slice(4, 6),
|
||||
16
|
||||
);
|
||||
if (alpha) {
|
||||
return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
|
||||
} else {
|
||||
return "rgb(" + r + ", " + g + ", " + b + ")";
|
||||
}
|
||||
};
|
||||
|
||||
export const bytesToSize = (bytes, decimals = 2) => {
|
||||
if (bytes === 0) return "0 Bytes";
|
||||
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return `${(bytes / Math.pow(k, i)).toFixed(dm)} ${sizes[i]}`;
|
||||
};
|
||||
|
||||
export const getRemainingTime = (seconds) => {
|
||||
seconds = seconds > 0 ? seconds : 1;
|
||||
|
||||
let [value, unit] =
|
||||
seconds < MINUTE
|
||||
? [Math.round(seconds), "second"]
|
||||
: seconds < HOUR
|
||||
? [Math.round(seconds / MINUTE), "minute"]
|
||||
: seconds < DAY
|
||||
? [Math.round(seconds / HOUR), "hour"]
|
||||
: seconds < WEEK
|
||||
? [Math.round(seconds / DAY), "day"]
|
||||
: seconds < MONTH
|
||||
? [Math.round(seconds / WEEK), "week"]
|
||||
: seconds < YEAR
|
||||
? [Math.round(seconds / MONTH), "month"]
|
||||
: [Math.round(seconds / YEAR), "year"];
|
||||
|
||||
unit = pluralize(unit, value);
|
||||
|
||||
return `${value} ${unit} remaining`;
|
||||
};
|
||||
|
||||
export const formatAsFilecoin = (number) => {
|
||||
return `${number} FIL`;
|
||||
};
|
||||
|
||||
export const isEmpty = (string) => {
|
||||
return !string || !string.toString().trim();
|
||||
};
|
||||
|
||||
export const pluralize = (text, count) => {
|
||||
return count > 1 || count === 0 ? `${text}s` : text;
|
||||
};
|
||||
|
||||
export const elide = (string, length = 140, emptyState = "...") => {
|
||||
if (isEmpty(string)) {
|
||||
return emptyState;
|
||||
}
|
||||
|
||||
if (string.length < length) {
|
||||
return string.trim();
|
||||
}
|
||||
|
||||
return `${string.substring(0, length)}...`;
|
||||
};
|
||||
|
||||
export const toDate = (data) => {
|
||||
const date = new Date(data);
|
||||
return `${date.getMonth() + 1}-${date.getDate()}-${date.getFullYear()}`;
|
||||
};
|
||||
|
||||
export const formatNumber = (x) => {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
};
|
||||
|
@ -63,9 +63,21 @@ export default class SlateMediaObject extends React.Component {
|
||||
}
|
||||
|
||||
if (type.startsWith("video/")) {
|
||||
let videoType = type;
|
||||
if (videoType === "video/quicktime") {
|
||||
videoType = "video/mp4";
|
||||
}
|
||||
|
||||
element = (
|
||||
<video autoPlay playsInline controls name="media" css={STYLES_OBJECT}>
|
||||
<source src={url} type={type} />
|
||||
<video
|
||||
autoPlay
|
||||
playsInline
|
||||
controls
|
||||
name="media"
|
||||
type={videoType}
|
||||
css={STYLES_OBJECT}
|
||||
>
|
||||
<source src={url} type={videoType} />
|
||||
</video>
|
||||
);
|
||||
}
|
||||
|
@ -80,66 +80,6 @@ const STYLES_BODY = css`
|
||||
white-space: pre-wrap;
|
||||
`;
|
||||
|
||||
const STYLES_SIDEBAR_INPUT = css`
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const STYLES_SIDEBAR_TEXTAREA = css`
|
||||
resize: none;
|
||||
box-sizing: border-box;
|
||||
line-height: 1.255;
|
||||
font-size: 16px;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
white-space: pre-wrap;
|
||||
padding: 48px 24px 24px 24px;
|
||||
color: ${Constants.system.white};
|
||||
font-family: ${Constants.font.text};
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const STYLES_SIDEBAR_INPUT_LABEL = css`
|
||||
font-family: ${Constants.font.code};
|
||||
letter-spacing: 0.1px;
|
||||
color: #999;
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
padding: 16px 24px 0px 24px;
|
||||
`;
|
||||
|
||||
class SidebarInput extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div css={STYLES_SIDEBAR_INPUT}>
|
||||
<label
|
||||
htmlFor={`sidebar-label-${this.props.name}`}
|
||||
css={STYLES_SIDEBAR_INPUT_LABEL}
|
||||
>
|
||||
{this.props.name}
|
||||
</label>
|
||||
<TextareaAutoSize
|
||||
value={this.props.value}
|
||||
name={this.props.name}
|
||||
onChange={this.props.onChange}
|
||||
id={`sidebar-label-${this.props.name}`}
|
||||
placeholder="..."
|
||||
style={this.props.style}
|
||||
css={STYLES_SIDEBAR_TEXTAREA}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default class GlobalViewerCIDSidebar extends React.Component {
|
||||
render() {
|
||||
const elements = [];
|
||||
|
@ -26,7 +26,18 @@ const STYLES_META = css`
|
||||
|
||||
const STYLES_META_TITLE = css`
|
||||
font-family: ${Constants.font.code};
|
||||
font-size: 14px;
|
||||
color: ${Constants.system.pitchBlack};
|
||||
font-size: 12px;
|
||||
text-decoration: none;
|
||||
transition: 200ms ease all;
|
||||
|
||||
:visited {
|
||||
color: ${Constants.system.pitchBlack};
|
||||
}
|
||||
|
||||
:hover {
|
||||
color: ${Constants.system.blue};
|
||||
}
|
||||
`;
|
||||
|
||||
const STYLES_META_ITEM = css`
|
||||
@ -182,7 +193,13 @@ export default class GlobalViewerCIDSidebarSlates extends React.Component {
|
||||
return (
|
||||
<div css={STYLES_CONTAINER}>
|
||||
<div css={STYLES_META}>
|
||||
<div css={STYLES_META_TITLE}>{cid}</div>
|
||||
<a
|
||||
css={STYLES_META_TITLE}
|
||||
target="_blank"
|
||||
href={Strings.getCIDGatewayURL(cid)}
|
||||
>
|
||||
{Strings.getCIDGatewayURL(cid)}
|
||||
</a>
|
||||
<div css={STYLES_META_DETAILS}>
|
||||
<span css={STYLES_META_ITEM}>{file}</span>{" "}
|
||||
<span css={STYLES_META_ITEM}>{type}</span>{" "}
|
||||
|
Loading…
Reference in New Issue
Block a user