Compare commits
10 commits
master
...
watchman-p
Author | SHA1 | Date | |
---|---|---|---|
|
fa0e635d54 | ||
|
4dbb506e77 | ||
|
248bb406e9 | ||
|
816c7089c1 | ||
|
4ff0a2f916 | ||
|
69676b3de5 | ||
|
0468863daf | ||
|
d6c53b9389 | ||
|
148e6a0fa1 | ||
|
a2104318b6 |
25 changed files with 609 additions and 186 deletions
|
@ -9,6 +9,7 @@ const config = {
|
|||
WEBPACK_ELECTRON_PORT: process.env.WEBPACK_ELECTRON_PORT,
|
||||
WEB_SERVER_PORT: process.env.WEB_SERVER_PORT,
|
||||
LBRY_WEB_API: process.env.LBRY_WEB_API, //api.na-backend.odysee.com',
|
||||
LBRY_WEB_PUBLISH_API: process.env.LBRY_WEB_PUBLISH_API,
|
||||
LBRY_API_URL: process.env.LBRY_API_URL, //api.lbry.com',
|
||||
LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
|
||||
LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
|
||||
|
@ -41,7 +42,6 @@ const config = {
|
|||
DEFAULT_LANGUAGE: process.env.DEFAULT_LANGUAGE,
|
||||
AUTO_FOLLOW_CHANNELS: process.env.AUTO_FOLLOW_CHANNELS,
|
||||
UNSYNCED_SETTINGS: process.env.UNSYNCED_SETTINGS,
|
||||
AVATAR_DEFAULT: process.env.AVATAR_DEFAULT,
|
||||
|
||||
// ENABLE FEATURES
|
||||
ENABLE_COMMENT_REACTIONS: process.env.ENABLE_COMMENT_REACTIONS === 'true',
|
||||
|
@ -66,6 +66,7 @@ const config = {
|
|||
CUSTOM_HOMEPAGE: process.env.CUSTOM_HOMEPAGE === 'true',
|
||||
SHOW_TAGS_INTRO: process.env.SHOW_TAGS_INTRO === 'true',
|
||||
LIGHTHOUSE_DEFAULT_TYPES: process.env.LIGHTHOUSE_DEFAULT_TYPES,
|
||||
BRANDED_SITE: process.env.BRANDED_SITE,
|
||||
};
|
||||
|
||||
config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
|
||||
|
|
|
@ -42,7 +42,10 @@ type Props = {
|
|||
isReply: boolean,
|
||||
activeChannel: string,
|
||||
activeChannelClaim: ?ChannelClaim,
|
||||
livestream?: boolean,
|
||||
bottom: boolean,
|
||||
onSubmit: (string, string) => void,
|
||||
livestream: boolean,
|
||||
embed?: boolean,
|
||||
toast: (string) => void,
|
||||
claimIsMine: boolean,
|
||||
sendTip: ({}, (any) => void, (any) => void) => void,
|
||||
|
@ -63,7 +66,11 @@ export function CommentCreate(props: Props) {
|
|||
isReply,
|
||||
parentId,
|
||||
activeChannelClaim,
|
||||
onSubmit,
|
||||
bottom,
|
||||
livestream,
|
||||
embed,
|
||||
toast,
|
||||
claimIsMine,
|
||||
sendTip,
|
||||
doToast,
|
||||
|
@ -106,7 +113,7 @@ export function CommentCreate(props: Props) {
|
|||
|
||||
function altEnterListener(e: SyntheticKeyboardEvent<*>) {
|
||||
const KEYCODE_ENTER = 13;
|
||||
if ((e.ctrlKey || e.metaKey) && e.keyCode === KEYCODE_ENTER) {
|
||||
if ((livestream || e.ctrlKey || e.metaKey) && e.keyCode === KEYCODE_ENTER) {
|
||||
e.preventDefault();
|
||||
buttonref.current.click();
|
||||
}
|
||||
|
@ -256,6 +263,10 @@ export function CommentCreate(props: Props) {
|
|||
setIsSupportComment(false);
|
||||
setCommentFailure(false);
|
||||
|
||||
if (onSubmit) {
|
||||
onSubmit(commentValue, activeChannelClaim.name);
|
||||
}
|
||||
|
||||
if (onDoneReplying) {
|
||||
onDoneReplying();
|
||||
}
|
||||
|
@ -280,6 +291,11 @@ export function CommentCreate(props: Props) {
|
|||
<div
|
||||
role="button"
|
||||
onClick={() => {
|
||||
if (embed) {
|
||||
window.open(`https://odysee.com/$/${PAGES.AUTH}?redirect=/$/${PAGES.LIVESTREAM}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const pathPlusRedirect = `/$/${PAGES.CHANNEL_NEW}?redirect=${pathname}`;
|
||||
if (livestream) {
|
||||
window.open(pathPlusRedirect);
|
||||
|
@ -344,6 +360,7 @@ export function CommentCreate(props: Props) {
|
|||
className={classnames('comment__create', {
|
||||
'comment__create--reply': isReply,
|
||||
'comment__create--nested-reply': isNested,
|
||||
'comment__create--bottom': bottom,
|
||||
})}
|
||||
>
|
||||
<FormField
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// @flow
|
||||
import * as REACTION_TYPES from 'constants/reactions';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
@ -15,18 +16,44 @@ type Props = {
|
|||
likeCount: number,
|
||||
dislikeCount: number,
|
||||
myReaction: ?string,
|
||||
livestream?: boolean,
|
||||
};
|
||||
|
||||
function FileReactions(props: Props) {
|
||||
const { claim, uri, doFetchReactions, doReactionLike, doReactionDislike, likeCount, dislikeCount } = props;
|
||||
const {
|
||||
claim,
|
||||
uri,
|
||||
doFetchReactions,
|
||||
doReactionLike,
|
||||
doReactionDislike,
|
||||
myReaction,
|
||||
likeCount,
|
||||
dislikeCount,
|
||||
livestream,
|
||||
} = props;
|
||||
const claimId = claim && claim.claim_id;
|
||||
const channel = claim && claim.signing_channel && claim.signing_channel.name;
|
||||
const isCollection = claim && claim.value_type === 'collection'; // hack because nudge gets cut off by card on cols.
|
||||
React.useEffect(() => {
|
||||
if (claimId) {
|
||||
function fetchReactions() {
|
||||
doFetchReactions(claimId);
|
||||
}
|
||||
}, [claimId, doFetchReactions]);
|
||||
|
||||
let fetchInterval;
|
||||
if (claimId) {
|
||||
fetchReactions();
|
||||
|
||||
if (livestream) {
|
||||
fetchInterval = setInterval(fetchReactions, 45000);
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (fetchInterval) {
|
||||
clearInterval(fetchInterval);
|
||||
}
|
||||
};
|
||||
}, [claimId, doFetchReactions, livestream]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -41,20 +68,46 @@ function FileReactions(props: Props) {
|
|||
title={__('I like this')}
|
||||
requiresAuth={IS_WEB}
|
||||
authSrc="filereaction_like"
|
||||
className={classnames('button--file-action')}
|
||||
label={formatNumberWithCommas(likeCount, 0)}
|
||||
className={classnames('button--file-action', { 'button--fire': myReaction === REACTION_TYPES.LIKE })}
|
||||
label={
|
||||
<>
|
||||
{myReaction === REACTION_TYPES.LIKE && (
|
||||
<>
|
||||
<div className="button__fire-glow" />
|
||||
<div className="button__fire-particle1" />
|
||||
<div className="button__fire-particle2" />
|
||||
<div className="button__fire-particle3" />
|
||||
<div className="button__fire-particle4" />
|
||||
<div className="button__fire-particle5" />
|
||||
<div className="button__fire-particle6" />
|
||||
</>
|
||||
)}
|
||||
{formatNumberWithCommas(likeCount, 0)}
|
||||
</>
|
||||
}
|
||||
iconSize={18}
|
||||
icon={ICONS.UPVOTE}
|
||||
icon={myReaction === REACTION_TYPES.LIKE ? ICONS.FIRE_ACTIVE : ICONS.FIRE}
|
||||
onClick={() => doReactionLike(uri)}
|
||||
/>
|
||||
<Button
|
||||
requiresAuth={IS_WEB}
|
||||
authSrc={'filereaction_dislike'}
|
||||
title={__('I dislike this')}
|
||||
className={classnames('button--file-action')}
|
||||
label={formatNumberWithCommas(dislikeCount, 0)}
|
||||
className={classnames('button--file-action', { 'button--slime': myReaction === REACTION_TYPES.DISLIKE })}
|
||||
label={
|
||||
<>
|
||||
{myReaction === REACTION_TYPES.DISLIKE && (
|
||||
<>
|
||||
<div className="button__slime-stain" />
|
||||
<div className="button__slime-drop1" />
|
||||
<div className="button__slime-drop2" />
|
||||
</>
|
||||
)}
|
||||
{formatNumberWithCommas(dislikeCount, 0)}
|
||||
</>
|
||||
}
|
||||
iconSize={18}
|
||||
icon={ICONS.DOWNVOTE}
|
||||
icon={myReaction === REACTION_TYPES.DISLIKE ? ICONS.SLIME_ACTIVE : ICONS.SLIME}
|
||||
onClick={() => doReactionDislike(uri)}
|
||||
/>
|
||||
</>
|
||||
|
|
|
@ -7,15 +7,16 @@ import useLazyLoading from 'effects/use-lazy-loading';
|
|||
type Props = {
|
||||
thumb: string,
|
||||
children?: Node,
|
||||
className?: string,
|
||||
};
|
||||
|
||||
const Thumb = (props: Props) => {
|
||||
const { thumb, children } = props;
|
||||
const { thumb, children, className } = props;
|
||||
const thumbnailRef = React.useRef(null);
|
||||
useLazyLoading(thumbnailRef);
|
||||
|
||||
return (
|
||||
<div ref={thumbnailRef} data-background-image={thumb} className={classnames('media__thumb')}>
|
||||
<div ref={thumbnailRef} data-background-image={thumb} className={classnames('media__thumb', className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -53,7 +53,11 @@ function FileThumbnail(props: Props) {
|
|||
const thumbnailUrl = url ? url.replace(/'/g, "\\'") : '';
|
||||
|
||||
if (hasResolvedClaim || thumbnailUrl) {
|
||||
return <Thumb thumb={thumbnailUrl}>{children}</Thumb>;
|
||||
return (
|
||||
<Thumb thumb={thumbnailUrl} className={className}>
|
||||
{children}
|
||||
</Thumb>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { BITWAVE_EMBED_URL } from 'constants/livestream';
|
||||
import { LIVESTREAM_EMBED_URL } from 'constants/livestream';
|
||||
import React from 'react';
|
||||
import FileTitleSection from 'component/fileTitleSection';
|
||||
import LivestreamComments from 'component/livestreamComments';
|
||||
|
@ -29,7 +29,7 @@ export default function LivestreamLayout(props: Props) {
|
|||
<div className="file-render file-render--video livestream">
|
||||
<div className="file-viewer">
|
||||
<iframe
|
||||
src={`${BITWAVE_EMBED_URL}/${channelClaimId}?skin=odysee&autoplay=1`}
|
||||
src={`${LIVESTREAM_EMBED_URL}/${channelClaimId}?skin=odysee&autoplay=1`}
|
||||
scrolling="no"
|
||||
allowFullScreen
|
||||
/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { BITWAVE_LIVE_API } from 'constants/livestream';
|
||||
import { LIVESTREAM_LIVE_API } from 'constants/livestream';
|
||||
import * as CS from 'constants/claim_search';
|
||||
import React from 'react';
|
||||
import Card from 'component/common/card';
|
||||
|
@ -39,8 +39,8 @@ export default function LivestreamLink(props: Props) {
|
|||
|
||||
React.useEffect(() => {
|
||||
function fetchIsStreaming() {
|
||||
// $FlowFixMe Bitwave's API can handle garbage
|
||||
fetch(`${BITWAVE_LIVE_API}/${livestreamChannelId}`)
|
||||
// $FlowFixMe livestream API can handle garbage
|
||||
fetch(`${LIVESTREAM_LIVE_API}/${livestreamChannelId}`)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (res && res.success && res.data && res.data.live) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as ICONS from 'constants/icons';
|
||||
import { BITWAVE_LIVE_API } from 'constants/livestream';
|
||||
import { LIVESTREAM_LIVE_API } from 'constants/livestream';
|
||||
import React from 'react';
|
||||
import Icon from 'component/common/icon';
|
||||
import Spinner from 'component/spinner';
|
||||
|
@ -14,7 +14,7 @@ export default function LivestreamList() {
|
|||
|
||||
React.useEffect(() => {
|
||||
function checkCurrentLivestreams() {
|
||||
fetch(BITWAVE_LIVE_API)
|
||||
fetch(LIVESTREAM_LIVE_API)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
setLoading(false);
|
||||
|
|
|
@ -28,7 +28,7 @@ import * as PUBLISH_MODES from 'constants/publish_types';
|
|||
import { useHistory } from 'react-router';
|
||||
import Spinner from 'component/spinner';
|
||||
import { toHex } from 'util/hex';
|
||||
import { BITWAVE_REPLAY_API } from 'constants/livestream';
|
||||
import { LIVESTREAM_REPLAY_API } from 'constants/livestream';
|
||||
|
||||
// @if TARGET='app'
|
||||
import fs from 'fs';
|
||||
|
@ -274,7 +274,7 @@ function PublishForm(props: Props) {
|
|||
// move this to lbryinc OR to a file under ui, and/or provide a standardized livestreaming config.
|
||||
function fetchLivestreams(channelId, signature, timestamp) {
|
||||
setCheckingLivestreams(true);
|
||||
fetch(`${BITWAVE_REPLAY_API}/${channelId}?signature=${signature || ''}&signing_ts=${timestamp || ''}`) // claimChannelId
|
||||
fetch(`${LIVESTREAM_REPLAY_API}/${channelId}?signature=${signature || ''}&signing_ts=${timestamp || ''}`) // claimChannelId
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (!res || !res.data) {
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
// Created by xander on 7/10/2021
|
||||
import videojs from 'video.js';
|
||||
const VERSION = '0.0.1';
|
||||
|
||||
const watchmanEndpoint = 'https://watchman.na-backend.odysee.com/reports/playback';
|
||||
|
||||
let previousEventTime = Date.now();
|
||||
|
||||
/* Watchman */
|
||||
function createWatchmanData(
|
||||
url,
|
||||
duration,
|
||||
position,
|
||||
relPosition,
|
||||
rebufCount,
|
||||
rebufDuration,
|
||||
format,
|
||||
player,
|
||||
userId,
|
||||
device
|
||||
) {
|
||||
return {
|
||||
url: url,
|
||||
duration: duration,
|
||||
rel_position: relPosition,
|
||||
rebuf_count: rebufCount,
|
||||
rebuf_duration: rebufDuration,
|
||||
format: format,
|
||||
player: player,
|
||||
user_id: userId,
|
||||
device: device,
|
||||
};
|
||||
}
|
||||
|
||||
function sendWatchmanData(watchmanData) {
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' }, // application/json
|
||||
body: JSON.stringify(watchmanData),
|
||||
};
|
||||
|
||||
try {
|
||||
fetch(watchmanEndpoint, requestOptions)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log('it worked')
|
||||
// Response data
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('was an error');
|
||||
// Response error
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin default options
|
||||
const defaults = {
|
||||
endpoint: watchmanEndpoint,
|
||||
reportRate: 15,
|
||||
videoUrl: null,
|
||||
userId: 0,
|
||||
debug: false,
|
||||
};
|
||||
|
||||
const Component = videojs.getComponent('Component');
|
||||
const registerPlugin = videojs.registerPlugin || videojs.plugin;
|
||||
|
||||
class WatchmanPlugin extends Component {
|
||||
constructor(player, options) {
|
||||
super(player, options);
|
||||
|
||||
// Plugin started
|
||||
if (options.debug) {
|
||||
this.log(`Created watchman plugin for: videoUrl:${options.videoUrl}, userId:${options.userId}`);
|
||||
}
|
||||
|
||||
// Plugin variables
|
||||
this.player = player;
|
||||
this.loadedAt = Date.now();
|
||||
this.watchmanIntervalId = null;
|
||||
this.bufferEventData = [];
|
||||
this.poweredBy = '';
|
||||
|
||||
// Plugin event listeners
|
||||
player.on('tracking:firstplay', (event, data) => this.onTrackingFirstPlay(event, data));
|
||||
player.on('tracking:buffered', (event, data) => this.onTrackingBuffered(event, data));
|
||||
|
||||
// player.on('tracking:buffered', function(event, data){
|
||||
// console.log('here!');
|
||||
// console.log(event);
|
||||
// console.log(data);
|
||||
// })
|
||||
|
||||
// Event trigger to send recsys event
|
||||
player.on('dispose', (event) => this.onDispose(event));
|
||||
}
|
||||
|
||||
sendWatchmanData() {
|
||||
console.log('running once here');
|
||||
|
||||
const processedData = this.bufferEventData.reduce(
|
||||
(accumulator, current) => {
|
||||
// Always update with the most current player x-powered-by header
|
||||
if (current.hasOwnProperty('playerPoweredBy') && current.playerPoweredBy) {
|
||||
this.poweredBy = current.playerPoweredBy;
|
||||
}
|
||||
|
||||
return {
|
||||
secondsToLoad: accumulator.secondsToLoad + current.secondsToLoad,
|
||||
bufferCount: accumulator.bufferCount + current.bufferCount,
|
||||
};
|
||||
},
|
||||
{
|
||||
secondsToLoad: 0,
|
||||
bufferCount: 0,
|
||||
}
|
||||
);
|
||||
|
||||
const timeSinceLastEvent = Date.now() - previousEventTime;
|
||||
previousEventTime = Date.now();
|
||||
|
||||
const currentTime = this.player.currentTime();
|
||||
const totalTime = this.player.duration();
|
||||
|
||||
const event = createWatchmanData(
|
||||
this.options_.videoUrl,
|
||||
timeSinceLastEvent,
|
||||
currentTime,
|
||||
currentTime / totalTime,
|
||||
processedData.bufferCount,
|
||||
processedData.secondsToLoad * 1000,
|
||||
this.player.currentSource().type,
|
||||
this.poweredBy,
|
||||
this.options_.userId,
|
||||
navigator.userAgent
|
||||
);
|
||||
|
||||
if (this.options_.debug) {
|
||||
console.log('[watchman] Data Payload', event);
|
||||
}
|
||||
|
||||
sendWatchmanData(event);
|
||||
}
|
||||
|
||||
onTrackingFirstPlay(event, data) {
|
||||
// data attr: secondsToLoad
|
||||
if (this.options_.debug) {
|
||||
console.log(`[watchman] First Play Data:`, data);
|
||||
}
|
||||
|
||||
// Start analytics interval here
|
||||
this.watchmanIntervalId = setInterval(() => this.onWatchmanInterval(), this.options_.reportRate * 1000);
|
||||
}
|
||||
|
||||
onTrackingBuffered(event, data) {
|
||||
const duration = this.player.duration();
|
||||
|
||||
const reportData = {
|
||||
...data,
|
||||
relativePosition: data.currentTime / duration,
|
||||
};
|
||||
|
||||
// data attr: currentTime, readyState, secondsToLoad, bufferCount
|
||||
if (this.options_.debug) {
|
||||
console.log(`[watchman] Buffer Data:`, reportData);
|
||||
}
|
||||
|
||||
this.bufferEventData.push(data);
|
||||
}
|
||||
|
||||
onWatchmanInterval() {
|
||||
|
||||
console.log('player paused');
|
||||
console.log(this.player.paused())
|
||||
|
||||
// don't report while player is paused
|
||||
if (this.player.paused()) return;
|
||||
|
||||
// process and send watchman data here
|
||||
if (this.options_.debug) {
|
||||
console.log('[watchman] interval', this.bufferEventData);
|
||||
}
|
||||
|
||||
// this.sendWatchmanData();
|
||||
|
||||
// clear processed data
|
||||
this.bufferEventData = [];
|
||||
}
|
||||
|
||||
onDispose(event) {
|
||||
// Stop analytics interval
|
||||
clearInterval(this.watchmanIntervalId);
|
||||
}
|
||||
|
||||
log(...args) {
|
||||
if (this.options_.debug) {
|
||||
console.log(`[watchman] Debug:`, JSON.stringify(args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
videojs.registerComponent('watchman', WatchmanPlugin);
|
||||
|
||||
const onPlayerReady = (player, options) => {
|
||||
player.recsys = new WatchmanPlugin(player, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the plugin.
|
||||
*
|
||||
* @function plugin
|
||||
* @param {Object} [options={}]
|
||||
*/
|
||||
const plugin = function (options) {
|
||||
this.ready(() => {
|
||||
onPlayerReady(this, videojs.mergeOptions(defaults, options));
|
||||
});
|
||||
};
|
||||
|
||||
plugin.VERSION = VERSION;
|
||||
|
||||
registerPlugin('watchman', plugin);
|
||||
|
||||
export default plugin;
|
|
@ -11,6 +11,7 @@ import * as OVERLAY from './overlays';
|
|||
import './plugins/videojs-mobile-ui/plugin';
|
||||
import hlsQualitySelector from './plugins/videojs-hls-quality-selector/plugin';
|
||||
import recsys from './plugins/videojs-recsys/plugin';
|
||||
import './plugins/videojs-watchman/plugin';
|
||||
import qualityLevels from 'videojs-contrib-quality-levels';
|
||||
import isUserTyping from 'util/detect-typing';
|
||||
// import './plugins/videojs-aniview/plugin';
|
||||
|
@ -570,6 +571,13 @@ export default React.memo<Props>(function VideoJs(props: Props) {
|
|||
userId: userId,
|
||||
});
|
||||
|
||||
player.watchman({
|
||||
reportRate: 25,
|
||||
videoUrl: claimId,
|
||||
userId: userId,
|
||||
debug: true,
|
||||
});
|
||||
|
||||
// set playsinline for mobile
|
||||
// TODO: make this better
|
||||
player.children_[0].setAttribute('playsinline', '');
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export const BITWAVE_EMBED_URL = 'https://bitwave.tv/odysee';
|
||||
export const BITWAVE_LIVE_API = 'https://api.bitwave.tv/v1/odysee/live';
|
||||
export const BITWAVE_REPLAY_API = 'https://api.bitwave.tv/v1/replays/odysee';
|
||||
export const LIVESTREAM_EMBED_URL = 'https://player.live.odysee.com/odysee';
|
||||
export const LIVESTREAM_LIVE_API = 'https://api.live.odysee.com/v1/odysee/live';
|
||||
export const LIVESTREAM_REPLAY_API = 'https://api.live.odysee.com/v1/replays/odysee';
|
||||
export const LIVESTREAM_RTMP_URL = 'rtmp://stream.odysee.com/live';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { BITWAVE_LIVE_API } from 'constants/livestream';
|
||||
import { LIVESTREAM_LIVE_API } from 'constants/livestream';
|
||||
|
||||
/**
|
||||
* Gets latest livestream info list. Returns null (instead of a blank object)
|
||||
|
@ -16,7 +16,7 @@ export default function useGetLivestreams(minViewers: number = 0, refreshMs: num
|
|||
|
||||
React.useEffect(() => {
|
||||
function checkCurrentLivestreams() {
|
||||
fetch(BITWAVE_LIVE_API)
|
||||
fetch(LIVESTREAM_LIVE_API)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
setLoading(false);
|
||||
|
|
|
@ -35,7 +35,7 @@ import {
|
|||
doAuthTokenRefresh,
|
||||
} from 'util/saved-passwords';
|
||||
import { X_LBRY_AUTH_TOKEN } from 'constants/token';
|
||||
import { LBRY_WEB_API, DEFAULT_LANGUAGE, LBRY_API_URL } from 'config';
|
||||
import { LBRY_WEB_API, DEFAULT_LANGUAGE, LBRY_API_URL, LBRY_WEB_PUBLISH_API } from 'config';
|
||||
|
||||
// Import 3rd-party styles before ours for the current way we are code-splitting.
|
||||
import 'scss/third-party.scss';
|
||||
|
@ -65,12 +65,11 @@ if (process.env.SDK_API_URL) {
|
|||
}
|
||||
|
||||
let sdkAPIHost = process.env.SDK_API_HOST || process.env.SDK_API_URL;
|
||||
// @if TARGET='web'
|
||||
sdkAPIHost = LBRY_WEB_API;
|
||||
// @endif
|
||||
|
||||
export const SDK_API_PATH = `${sdkAPIHost}/api/v1`;
|
||||
const proxyURL = `${SDK_API_PATH}/proxy`;
|
||||
const publishURL = LBRY_WEB_PUBLISH_API; // || `${SDK_API_PATH}/proxy`;
|
||||
|
||||
Lbry.setDaemonConnectionString(proxyURL);
|
||||
|
||||
|
@ -80,7 +79,7 @@ Lbry.setOverride(
|
|||
new Promise((resolve, reject) => {
|
||||
apiPublishCallViaWeb(
|
||||
apiCall,
|
||||
proxyURL,
|
||||
publishURL,
|
||||
Lbry.getApiRequestHeaders() && Object.keys(Lbry.getApiRequestHeaders()).includes(X_LBRY_AUTH_TOKEN)
|
||||
? Lbry.getApiRequestHeaders()[X_LBRY_AUTH_TOKEN]
|
||||
: '',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { BITWAVE_LIVE_API } from 'constants/livestream';
|
||||
import { LIVESTREAM_LIVE_API } from 'constants/livestream';
|
||||
import React from 'react';
|
||||
import Page from 'component/page';
|
||||
import LivestreamLayout from 'component/livestreamLayout';
|
||||
|
@ -56,8 +56,9 @@ export default function LivestreamPage(props: Props) {
|
|||
React.useEffect(() => {
|
||||
let interval;
|
||||
function checkIsLive() {
|
||||
// $FlowFixMe Bitwave's API can handle garbage
|
||||
fetch(`${BITWAVE_LIVE_API}/${livestreamChannelId}`)
|
||||
// TODO: duplicate code below
|
||||
// $FlowFixMe livestream API can handle garbage
|
||||
fetch(`${LIVESTREAM_LIVE_API}/${livestreamChannelId}`)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (!res || !res.data) {
|
||||
|
@ -105,7 +106,7 @@ export default function LivestreamPage(props: Props) {
|
|||
|
||||
React.useEffect(() => {
|
||||
// Set playing uri to null so the popout player doesnt start playing the dummy claim if a user navigates back
|
||||
// This can be removed when we start using the app video player, not a bitwave iframe
|
||||
// This can be removed when we start using the app video player, not a LIVESTREAM iframe
|
||||
doSetPlayingUri({ uri: null });
|
||||
}, [doSetPlayingUri]);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import CopyableText from 'component/copyableText';
|
|||
import Card from 'component/common/card';
|
||||
import ClaimList from 'component/claimList';
|
||||
import usePersistedState from 'effects/use-persisted-state';
|
||||
import { LIVESTREAM_RTMP_URL } from 'constants/livestream';
|
||||
|
||||
type Props = {
|
||||
channels: Array<ChannelClaim>,
|
||||
|
@ -182,7 +183,7 @@ export default function LivestreamSetupPage(props: Props) {
|
|||
primaryButton
|
||||
name="stream-server"
|
||||
label={__('Stream server')}
|
||||
copyable="rtmp://stream.odysee.com/live"
|
||||
copyable={LIVESTREAM_RTMP_URL}
|
||||
snackMessage={__('Copied')}
|
||||
/>
|
||||
<CopyableText
|
||||
|
|
|
@ -230,13 +230,28 @@
|
|||
}
|
||||
|
||||
.file-viewer__overlay-logo {
|
||||
color: var(--color-white);
|
||||
font-weight: bold;
|
||||
height: 3.5rem;
|
||||
width: 12rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
height: 30px;
|
||||
stroke-width: 5px;
|
||||
&:hover {
|
||||
filter: drop-shadow(1px 2px 10px var(--color-gray-3));
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
margin-right: var(--spacing-m);
|
||||
width: 2.5rem;
|
||||
|
||||
.button__label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-viewer__overlay-logo--videoend {
|
||||
height: 3.5rem;
|
||||
width: 12rem;
|
||||
}
|
||||
|
||||
.file-viewer--is-playing:not(:hover) .file-viewer__embedded-header {
|
||||
|
@ -246,11 +261,15 @@
|
|||
.file-viewer__embedded-header {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
z-index: 2;
|
||||
height: 4rem;
|
||||
padding-left: var(--spacing-m);
|
||||
padding-right: var(--spacing-s);
|
||||
font-size: var(--font-large);
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
|
@ -260,7 +279,6 @@
|
|||
border-top-right-radius: var(--border-radius);
|
||||
|
||||
.button {
|
||||
padding: var(--spacing-s);
|
||||
color: var(--color-white);
|
||||
z-index: 2;
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ input-submit {
|
|||
height: var(--height-checkbox);
|
||||
width: var(--height-checkbox);
|
||||
border: 1px solid var(--color-input-border);
|
||||
border-radius: var(--border-radius);
|
||||
border-radius: 3px;
|
||||
left: 0px;
|
||||
top: -1px;
|
||||
}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
:root {
|
||||
// Generic colors
|
||||
--color-primary: #257761;
|
||||
--color-primary-alt: #e4f4ef;
|
||||
--color-primary-alt-2: #4b8576;
|
||||
--color-secondary: #295284;
|
||||
--color-secondary-alt: #d9eaff;
|
||||
--color-tertiary: #552470;
|
||||
--color-tertiary-alt: #f7e8ff;
|
||||
--color-danger: #9b2023;
|
||||
--color-danger-alt: #fccdce;
|
||||
--color-warning: #fff58c;
|
||||
--color-cost: #ffd580;
|
||||
--color-focus: #93cff2;
|
||||
--color-notification: #f02849;
|
||||
--color-live: #cc190f;
|
||||
|
||||
--color-black: #111;
|
||||
--color-white: #fdfdfd;
|
||||
--color-white-alt: #fafafa;
|
||||
--color-gray-1: #eff1f4;
|
||||
--color-gray-2: #d8dde1;
|
||||
--color-gray-3: #ced4da;
|
||||
--color-gray-4: #abb1b7;
|
||||
--color-gray-5: #666a6d;
|
||||
|
||||
// Text
|
||||
--color-text: var(--color-black);
|
||||
--color-text-subtitle: var(--color-gray-5);
|
||||
--color-text-inverse: #fdfdfd;
|
||||
|
||||
// Components
|
||||
|
||||
// Button
|
||||
--color-button-primary-bg: var(--color-primary);
|
||||
--color-button-primary-text: var(--color-primary-alt);
|
||||
--color-button-primary-bg-hover: var(--color-primary-alt-2);
|
||||
--color-button-primary-hover-text: var(--color-primary-alt);
|
||||
--color-button-secondary-bg: var(--color-secondary-alt);
|
||||
--color-button-secondary-border: var(--color-secondary-alt);
|
||||
--color-button-secondary-text: var(--color-secondary);
|
||||
--color-button-secondary-bg-hover: #b9d0e9;
|
||||
--color-button-alt-bg: var(--color-gray-1);
|
||||
--color-button-alt-text: var(--color-text);
|
||||
--color-button-alt-bg-hover: var(--color-gray-2);
|
||||
--color-link: var(--color-primary);
|
||||
--color-link-hover: var(--color-black);
|
||||
|
||||
// Table
|
||||
--color-table-highlight: var(--color-white-alt);
|
||||
|
||||
// Tag
|
||||
--color-tag: var(--color-gray-5);
|
||||
--color-tag-bg: var(--color-button-alt-bg);
|
||||
--color-tag-hover: var(--color-button-alt-text);
|
||||
--color-tag-bg-hover: var(--color-button-alt-bg-hover);
|
||||
}
|
|
@ -60,8 +60,12 @@ ol {
|
|||
position: relative;
|
||||
list-style-position: outside;
|
||||
margin: var(--spacing-xs) 0;
|
||||
margin-left: var(--spacing-xl);
|
||||
margin-left: var(--spacing-s);
|
||||
margin-bottom: 0;
|
||||
|
||||
@media (min-width: $breakpoint-small) {
|
||||
margin-left: var(--spacing-xl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,10 +271,10 @@ textarea {
|
|||
margin-top: var(--spacing-s);
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: var(--spacing-s);
|
||||
margin-bottom: var(--spacing-m);
|
||||
}
|
||||
|
||||
.button--link ~ .button--link {
|
||||
.button--link + .button--link {
|
||||
margin-left: var(--spacing-s);
|
||||
}
|
||||
|
||||
|
@ -282,7 +286,6 @@ textarea {
|
|||
.help--warning {
|
||||
@extend .help;
|
||||
padding: var(--spacing-s);
|
||||
color: var(--color-black);
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--color-help-warning-bg);
|
||||
color: var(--color-help-warning-text);
|
||||
|
@ -499,3 +502,16 @@ textarea {
|
|||
height: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.home__meme {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
font-size: 1rem;
|
||||
margin-bottom: var(--spacing-m);
|
||||
|
||||
@media (min-width: $breakpoint-small) {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: var(--spacing-l);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ $breakpoint-medium: 1150px;
|
|||
$breakpoint-large: 1600px;
|
||||
|
||||
:root {
|
||||
--border-radius: 5px;
|
||||
--border-radius: 10px;
|
||||
--height-input: 2.5rem;
|
||||
--height-button: 2.5rem;
|
||||
--height-checkbox: 24px;
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
[theme='dark'] {
|
||||
// Color overrides
|
||||
--color-primary: #2bbb90;
|
||||
--color-primary-alt: #3e675d;
|
||||
--color-primary-alt-2: #065f46;
|
||||
--color-primary-alt-3: #34e5b0;
|
||||
--color-secondary: #204166;
|
||||
--color-secondary-alt: #dbeafe;
|
||||
--color-secondary-alt-2: #bfdbfe;
|
||||
--color-secondary-alt-3: #2c5c8c;
|
||||
--color-primary: #e50054;
|
||||
--color-primary-alt: #66001880;
|
||||
--color-fire: #ff6635;
|
||||
--color-fire-outside: #ff9b20;
|
||||
|
||||
// Structure
|
||||
--color-background: var(--color-gray-9);
|
||||
--color-background-overlay: #21252999;
|
||||
--color-border: #333338;
|
||||
--color-card-background: var(--color-gray-8);
|
||||
--color-card-background-highlighted: var(--color-gray-7);
|
||||
--color-background: #140e1b;
|
||||
--color-background-overlay: #0c0d0e95;
|
||||
--color-border: #30243d;
|
||||
--color-card-background: #181021;
|
||||
--color-card-background-highlighted: #241c30;
|
||||
|
||||
// Text
|
||||
--color-text: var(--color-white);
|
||||
--color-text: var(--color-gray-1);
|
||||
--color-text-subtitle: var(--color-gray-4);
|
||||
--color-text-empty: var(--color-text-subtitle);
|
||||
--color-text-help: #bbbbbb;
|
||||
--color-text-warning: #212529;
|
||||
--color-text-warning--background: var(--lbry-yellow-1);
|
||||
--color-text-error: #f87171;
|
||||
--color-error: #61373f;
|
||||
--color-text-error: var(--color-danger);
|
||||
--color-error: var(--color-danger-alt);
|
||||
--color-blockquote: var(--color-gray-5);
|
||||
--color-blockquote-bg: var(--color-card-background-highlighted);
|
||||
--color-help-warning-text: var(--color-white-alt);
|
||||
--color-help-warning-bg: #fbbf2450;
|
||||
|
||||
// Tags (words)
|
||||
--color-tag-words: var(--color-text);
|
||||
|
@ -33,87 +33,73 @@
|
|||
--color-tag-words-bg-hover: var(--color-gray-4);
|
||||
|
||||
// Header
|
||||
--color-header-background: var(--color-gray-8);
|
||||
--color-header-button: var(--color-gray-6);
|
||||
--color-header-button-hover: var(--color-gray-6);
|
||||
--color-header-button-active: var(--color-gray-6);
|
||||
--color-header-button: #38274c;
|
||||
--color-header-background: #231830;
|
||||
|
||||
// Button
|
||||
--color-button-primary-bg: var(--color-primary-alt);
|
||||
--color-button-primary-bg-hover: var(--color-primary-alt-2);
|
||||
--color-button-primary-text: var(--color-gray-2);
|
||||
--color-button-primary-text: white;
|
||||
--color-button-primary-hover-text: var(--color-primary-alt);
|
||||
--color-button-secondary-bg: var(--color-secondary);
|
||||
--color-button-secondary-border: var(--color-secondary);
|
||||
--color-button-secondary-bg-hover: var(--color-secondary-alt-3);
|
||||
--color-button-secondary-text: var(--color-gray-2);
|
||||
--color-button-alt-bg: var(--color-gray-7);
|
||||
--color-button-alt-bg-hover: var(--color-gray-6);
|
||||
--color-button-alt-text: var(--color-gray-1);
|
||||
--color-button-border: var(--color-gray-5);
|
||||
--color-button-toggle-text: var(--color-gray-1);
|
||||
--color-link: var(--color-primary-alt-3);
|
||||
--color-link-hover: var(--color-text);
|
||||
--color-link-focus-bg: var(--color-gray-7);
|
||||
--color-button-secondary-bg: #2c1543;
|
||||
--color-button-secondary-border: #4f1c82;
|
||||
--color-button-secondary-bg-hover: #3b1c5b;
|
||||
--color-button-secondary-text: #efefef;
|
||||
--color-button-alt-bg: var(--color-header-button);
|
||||
--color-button-alt-bg-hover: #2b2037;
|
||||
--color-button-toggle-text: var(--color-text);
|
||||
--color-button-toggle-bg: var(--color-primary-alt);
|
||||
--color-button-toggle-bg-hover: var(--color-primary-alt);
|
||||
--color-button-alt-text: #e2e9f0;
|
||||
--color-button-border: #5b4475;
|
||||
--color-link: var(--color-primary);
|
||||
--color-link-hover: #d75673;
|
||||
--color-link-active: #ec1d4c;
|
||||
--color-link-focus-bg: #3d2d4e;
|
||||
|
||||
// Input
|
||||
--color-input: var(--color-white);
|
||||
--color-input-label: var(--color-gray-3);
|
||||
--color-input-placeholder: var(--color-gray-1);
|
||||
--color-input: #f4f4f5;
|
||||
--color-input-label: #a7a7a7;
|
||||
--color-input-placeholder: #f4f4f5;
|
||||
--color-input-bg: var(--color-header-button);
|
||||
--color-input-bg-copyable: var(--color-gray-6);
|
||||
--color-input-bg-copyable: #4c3861;
|
||||
--color-input-border: var(--color-border);
|
||||
--color-input-border-active: var(--color-secondary);
|
||||
--color-input-toggle: var(--color-primary-alt-3);
|
||||
--color-input-toggle-bg: var(--color-input-bg);
|
||||
--color-input-toggle-bg-hover: var(--color-secondary);
|
||||
--color-input-bg-selected: var(--color-primary-alt);
|
||||
--color-input-prefix-bg: var(--color-gray-5);
|
||||
--color-input-prefix-bg: var(--color-input-bg-copyable);
|
||||
--color-input-prefix-border: var(--color-gray-4);
|
||||
--select-toggle-background: url("data:image/svg+xml,%3Csvg viewBox='0 0 96 96' xmlns='http://www.w3.org/2000/svg' fill='%23ffffff'%3E%3Cpath d='M17.172, 31.172c1.562, -1.562 4.095, -1.562 5.656, 0l25.172, 25.171l25.172, -25.171c1.562, -1.562 4.095, -1.562 5.656, 0c1.562, 1.562 1.562, 4.095 0, 5.656l-28, 28c-1.562, 1.562 -4.095, 1.562 -5.656, 0l-28, -28c-0.781, -0.781 -1.172, -1.805 -1.172, -2.828c0, -1.023 0.391, -2.047 1.172, -2.828Z'/%3E%3C/svg%3E%0A");
|
||||
|
||||
// Navigation
|
||||
--color-navigation-icon: var(--color-gray-4);
|
||||
--color-navigation-link: var(--color-gray-4);
|
||||
--color-navigation-active: var(--color-gray-7);
|
||||
--color-navigation-active-text: var(--color-gray-3);
|
||||
--color-navigation-hover: var(--color-gray-6);
|
||||
--color-navigation-hover-text: var(--color-gray-3);
|
||||
--color-navigation-icon: #76808a;
|
||||
--color-navigation-link: #b9c3ce;
|
||||
--color-navigation-active: #2b2037;
|
||||
--color-navigation-active-text: #c6bcd2;
|
||||
--color-navigation-hover: #21182a;
|
||||
--color-navigation-hover-text: #c6bcd2;
|
||||
|
||||
// Tags
|
||||
--color-tag: var(--color-primary-alt-3);
|
||||
--color-tag-bg: var(--color-gray-7);
|
||||
--color-tag: #ff85b1;
|
||||
--color-tag-bg: var(--color-navigation-hover);
|
||||
--color-tag-hover: var(--color-white);
|
||||
--color-tag-bg-hover: var(--color-primary-alt);
|
||||
--color-tag-bg-hover: var(--color-primary-alt-2);
|
||||
--color-tag-mature-bg: var(--color-primary-alt-2);
|
||||
|
||||
// Menu
|
||||
--color-menu-background: var(--color-header-background);
|
||||
--color-menu-background--active: var(--color-gray-7);
|
||||
--color-menu-icon: var(--color-gray-4);
|
||||
--color-menu-background--active: var(--color-primary-alt);
|
||||
--color-menu-icon: #928b9b;
|
||||
--color-menu-icon-active: #d6d6d6;
|
||||
|
||||
// Comments
|
||||
--color-comment-menu: var(--color-gray-5);
|
||||
--color-comment-menu-hovering: var(--color-gray-2);
|
||||
--color-comment-threadline: #434b54;
|
||||
--color-comment-threadline-hover: var(--color-gray-4);
|
||||
--color-comment-menu: #6a6a6a;
|
||||
--color-comment-menu-hovering: #e0e0e0;
|
||||
--color-comment-highlighted: #484734;
|
||||
|
||||
// Snack
|
||||
--color-snack-bg: var(--color-secondary);
|
||||
|
||||
// Superchat
|
||||
--color-superchat-text: var(--color-black);
|
||||
--color-superchat-text__light: var(--color-text);
|
||||
--color-superchat: #fcd34d;
|
||||
--color-superchat__light: #ef4e1647;
|
||||
--color-superchat-2: #fde68a;
|
||||
--color-superchat-3: #fef3c7;
|
||||
--color-superchat-3__light: #58066087;
|
||||
--color-superchat-4: #fffbeb;
|
||||
--color-comment-threadline: #24192f;
|
||||
--color-comment-threadline-hover: var(--color-gray-4);
|
||||
|
||||
// Other
|
||||
--color-focus: #93c5fd50;
|
||||
--color-nag: var(--color-orange);
|
||||
--color-tab-text: var(--color-white);
|
||||
--color-tabs-background: var(--color-card-background);
|
||||
--color-tab-divider: var(--color-white);
|
||||
|
@ -121,14 +107,12 @@
|
|||
--color-notice: #58563b;
|
||||
--color-purchased: #ffd580;
|
||||
--color-purchased-alt: var(--color-purchased);
|
||||
--color-purchased-text: var(--color-gray-5);
|
||||
--color-purchased-text: black;
|
||||
--color-thumbnail-background: var(--color-gray-5);
|
||||
--color-tooltip-bg: #2f3337;
|
||||
--color-help-warning-bg: #d97706;
|
||||
--color-help-warning-text: white;
|
||||
--color-blockquote: var(--color-gray-5);
|
||||
--color-placeholder-background: #4e5862;
|
||||
--color-spinner-light: #5a6570;
|
||||
--color-focus: #e91e6329;
|
||||
--color-placeholder-background: #261a35;
|
||||
--color-spinner-light: white;
|
||||
--color-spinner-dark: #212529;
|
||||
--color-login-graphic-background: var(--color-background);
|
||||
|
||||
|
|
|
@ -1,2 +1,155 @@
|
|||
:root {
|
||||
// Color overrides
|
||||
--color-primary: #fa6165;
|
||||
--color-primary-alt: #fef1f6;
|
||||
--color-primary-alt-2: #fb7e82;
|
||||
--color-primary-alt-3: #fbcbdd;
|
||||
--color-secondary: #f9902a;
|
||||
--color-secondary-alt: #fee8d2;
|
||||
--color-secondary-alt-2: #fefcf6;
|
||||
|
||||
// Structure
|
||||
--color-border: #ededed;
|
||||
--color-background: #fafafa;
|
||||
--color-background-overlay: #21252980;
|
||||
--color-card-background: #ffffff;
|
||||
--color-card-background-highlighted: #fff5f5;
|
||||
|
||||
// Text
|
||||
--color-text-selection-bg: var(--color-primary-alt);
|
||||
--color-text-selection: var(--color-primary);
|
||||
--color-text-error: var(--color-danger);
|
||||
--color-text-empty: #999999;
|
||||
--color-text-help: #999999;
|
||||
--color-text-subtitle: #767676;
|
||||
--color-text-warning: #212529;
|
||||
--color-help-warning-bg: #fef3c7;
|
||||
--color-text-warning--background: var(--lbry-yellow-1);
|
||||
--color-blockquote: var(--color-gray-3);
|
||||
--color-blockquote-bg: var(--color-gray-1);
|
||||
--color-tooltip-bg: #222;
|
||||
--color-tooltip-text: #fafafa;
|
||||
|
||||
// Header
|
||||
--color-header-button: var(--color-button-alt-bg);
|
||||
--color-header-background: #ffffff;
|
||||
|
||||
// Button
|
||||
--color-button-alt-bg: var(--color-gray-1);
|
||||
--color-button-alt-bg-hover: var(--color-gray-2);
|
||||
--color-button-alt-text: black;
|
||||
--color-button-primary-bg: var(--color-primary);
|
||||
--color-button-primary-bg-hover: var(--color-primary-alt-2);
|
||||
--color-button-primary-text: var(--color-primary-alt);
|
||||
--color-button-primary-hover-text: var(--color-white);
|
||||
--color-button-secondary-bg: var(--color-primary-alt);
|
||||
--color-button-secondary-border: var(--color-primary-alt-3);
|
||||
--color-button-secondary-text: var(--color-primary);
|
||||
--color-button-secondary-bg-hover: var(--color-primary-alt-3);
|
||||
--color-button-toggle-text: var(--color-primary);
|
||||
--color-button-toggle-bg: var(--color-primary-alt);
|
||||
--color-button-toggle-bg-hover: var(--color-primary-alt);
|
||||
--color-button-border: var(--color-gray-3);
|
||||
--color-link-active: var(--color-primary);
|
||||
--color-link-focus-bg: #f1f1f1;
|
||||
--color-link: var(--color-primary);
|
||||
|
||||
// Input
|
||||
--color-input-bg-selected: var(--color-primary-alt);
|
||||
--color-input-color: #111111;
|
||||
--color-input-label: var(--color-gray-5);
|
||||
--color-input-placeholder: #212529;
|
||||
--color-input-bg: var(--color-gray-1);
|
||||
--color-input-border: var(--color-border);
|
||||
--color-input-border-active: var(--color-secondary);
|
||||
--color-input-toggle: var(--color-secondary);
|
||||
--color-input-toggle-bg: var(--color-gray-1);
|
||||
--color-input-toggle-bg-hover: var(--color-secondary-alt);
|
||||
--color-input-prefix-bg: var(--color-gray-2);
|
||||
--color-input-prefix-border: var(--color-gray-5);
|
||||
--select-toggle-background: url("data:image/svg+xml,%3Csvg viewBox='0 0 96 96' xmlns='http://www.w3.org/2000/svg' fill='%23212529'%3E%3Cpath d='M17.172, 31.172c1.562, -1.562 4.095, -1.562 5.656, 0l25.172, 25.171l25.172, -25.171c1.562, -1.562 4.095, -1.562 5.656, 0c1.562, 1.562 1.562, 4.095 0, 5.656l-28, 28c-1.562, 1.562 -4.095, 1.562 -5.656, 0l-28, -28c-0.781, -0.781 -1.172, -1.805 -1.172, -2.828c0, -1.023 0.391, -2.047 1.172, -2.828Z'/%3E%3C/svg%3E%0A");
|
||||
|
||||
// Navigation
|
||||
--color-navigation-icon: var(--color-gray-5);
|
||||
--color-navigation-link: var(--color-gray-5);
|
||||
--color-navigation-active: var(--color-primary-alt);
|
||||
--color-navigation-active-text: var(--color-primary);
|
||||
--color-navigation-hover: var(--color-gray-1);
|
||||
--color-navigation-hover-text: #3f3f3f;
|
||||
|
||||
// Tags
|
||||
--color-tag: var(--color-primary-alt-2);
|
||||
--color-tag-bg: #f9f6f7;
|
||||
--color-tag-hover: var(--color-button-alt-text);
|
||||
--color-tag-bg-hover: var(--color-button-alt-bg-hover);
|
||||
|
||||
// Menu
|
||||
--color-menu-background: var(--color-header-background);
|
||||
--color-menu-icon: var(--color-navigation-link);
|
||||
--color-menu-icon-active: var(--color-navigation-link);
|
||||
--color-menu-background--selected: var(--color-secondary-alt);
|
||||
--color-menu-background--active: var(--color-primary-alt);
|
||||
|
||||
// Comments
|
||||
--color-comment-menu: #e0e0e0;
|
||||
--color-comment-menu-hovering: #6a6a6a;
|
||||
--color-comment-highlighted: #fff2d9;
|
||||
--color-comment-threadline: var(--color-gray-1);
|
||||
--color-comment-threadline-hover: var(--color-gray-4);
|
||||
|
||||
// Superchat
|
||||
--color-superchat-text: var(--color-black);
|
||||
--color-superchat: #fcd34d;
|
||||
--color-superchat__light: #fcd34d50;
|
||||
--color-superchat-2: #fde68a;
|
||||
--color-superchat-3: #fef3c7;
|
||||
--color-superchat-3__light: #fef3c750;
|
||||
--color-superchat-4: #fffbeb;
|
||||
|
||||
// Color
|
||||
--color-focus: #8dbff0;
|
||||
--color-nag: #fa8700;
|
||||
--color-error: #fcafca;
|
||||
--color-notice: #fef3ca;
|
||||
--color-purchased: var(--color-cost);
|
||||
--color-purchased-alt: #ffebc2;
|
||||
--color-purchased-text: black;
|
||||
--color-thumbnail-background: var(--color-gray-1);
|
||||
--color-spinner-light: #ffffff;
|
||||
--color-spinner-dark: #212529;
|
||||
--color-placeholder-background: #f0f0f0;
|
||||
--color-file-viewer-background: var(--color-card-background);
|
||||
--color-tabs-background: var(--color-card-background);
|
||||
--color-tab-divider: var(--color-primary);
|
||||
--color-modal-background: var(--color-card-background);
|
||||
|
||||
// Icons
|
||||
--color-follow-bg: #ffd4da;
|
||||
--color-follow-icon: #e2495e;
|
||||
--color-view-bg: var(--color-secondary-alt);
|
||||
--color-view-icon: var(--color-secondary);
|
||||
|
||||
// Editor
|
||||
--color-editor-cursor: var(--color-text);
|
||||
--color-editor-quote: #707070;
|
||||
--color-editor-tag: #ea9400;
|
||||
--color-editor-attr: #04b0f4;
|
||||
--color-editor-string: #ff7451;
|
||||
--color-editor-inline-code-fg: var(--color-text);
|
||||
--color-editor-inline-code-fg-preview: #2e3439;
|
||||
--color-editor-inline-code-bg: rgba(157, 161, 165, 0.3);
|
||||
--color-editor-inline-code-bg-preview: #d0e8ff;
|
||||
--color-editor-selected: #add6ff;
|
||||
--color-editor-link: var(--color-link);
|
||||
--color-editor-url: var(--color-editor-string);
|
||||
--color-editor-hr: var(--color-editor-tag);
|
||||
--color-editor-hr-preview: #cccccc;
|
||||
|
||||
// Ads
|
||||
--color-ads-background: #fae5ff;
|
||||
--color-ads-link: var(--color-link);
|
||||
|
||||
// Scrollbar
|
||||
--color-scrollbar-thumb-bg: rgba(0, 0, 0, 0.2);
|
||||
--color-scrollbar-track-bg: transparent;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
"koa-logger": "^3.2.1",
|
||||
"koa-send": "^5.0.0",
|
||||
"koa-static": "^5.0.0",
|
||||
"lbry-redux": "lbryio/lbry-redux#508e8d36fd91106beb7d6b4edb9f726dae0e6264",
|
||||
"lbry-redux": "lbryio/lbry-redux#b075c103445a9355d617116fbb491496ecb473da",
|
||||
"lbryinc": "lbryio/lbryinc#8f9a58bfc8312a65614fd7327661cdcc502c4e59",
|
||||
"mysql": "^2.17.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
|
|
|
@ -3331,9 +3331,9 @@ latest-version@^3.0.0:
|
|||
dependencies:
|
||||
package-json "^4.0.0"
|
||||
|
||||
lbry-redux@lbryio/lbry-redux#508e8d36fd91106beb7d6b4edb9f726dae0e6264:
|
||||
lbry-redux@lbryio/lbry-redux#b075c103445a9355d617116fbb491496ecb473da:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/508e8d36fd91106beb7d6b4edb9f726dae0e6264"
|
||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/b075c103445a9355d617116fbb491496ecb473da"
|
||||
dependencies:
|
||||
proxy-polyfill "0.1.6"
|
||||
reselect "^3.0.0"
|
||||
|
|
Loading…
Reference in a new issue