cut master to staging #726
121 changed files with 1378 additions and 881 deletions
.gitignoreREADME.md
cli
client
scss
_asset-display.scss_asset-preview.scss_body.scss_button-primary.scss_button-secondary.scss_button.scss_channel-claims-display.scss_click-to-copy.scss_dropzone.scss_form-feedback.scss_form.scss_horizontal-split.scss_html.scss_input.scss_label.scss_link.scss_media-queries.scss_nav-bar.scss_page-content.scss_page-layout-show-lite.scss_page-layout.scss_progress-bar.scss_publish-disabled-message.scss_publish-preview.scss_publish-status.scss_publish-url-input.scss_react-app.scss_reset.scss_row.scss_select.scss_share-buttons.scss_social-share-link.scss_space-around.scss_space-between.scss_text.scss_textarea.scss_tooltip.scss_variables.scss_video.scssall.scss
asset-display
button-primary
button-secondary
button-tertiary
button
click-to-copy
column
font
horizontal-quad-split
horizontal-split
icon
link
media-queries
page-layout
progress-bar
publish-preview
reset
select
text
textarea
vertical-split
src
components
AboutSpeechDetails
AboutSpeechOverview
AssetInfoFooter
AssetShareButtons
ButtonPrimary
ButtonPrimaryJumbo
ButtonTertiary
ChannelAbout
ChannelSelectDropdown
ClickToCopy
Column
DropzoneDropItDisplay
DropzoneInstructionsDisplay
FormFeedbackDisplay
HorizontalQuadSplit
HorizontalSplit
NavBar
NavBarChannelOptionsDropdown
ProgressBar
PublishLicenseInput
PublishPreview
containers
AssetDisplay
AssetInfo
AssetTitle
ChannelCreateForm
ChannelLoginForm
ChannelSelect
ChannelTools
Dropzone
PublishDetails
PublishMetadataInputs
PublishThumbnailInput
pages/AboutPage
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -17,3 +17,7 @@ public/bundle/Lekton-*
|
|||
public/bundle/style.css
|
||||
|
||||
uploads
|
||||
|
||||
config/
|
||||
|
||||
deployment-config.json
|
||||
|
|
109
README.md
109
README.md
|
@ -1,21 +1,97 @@
|
|||
# Spee.ch
|
||||
Spee.ch is a web app that reads and publishes images and videos to and from the [LBRY](https://lbry.io/) blockchain. You are encouraged to contribute to the shared code base, or fork it and make it your own.
|
||||
Spee.ch is a web app that reads and publishes images and videos to and from the [LBRY](https://lbry.io/) blockchain. We encourage you to contribute to the shared code base, or fork it and make it your own.
|
||||
|
||||
You can create your own custom version of spee.ch by installing this code base and then creating your own custom components and styles to override the defaults. (More details/guide on how to do that coming soon.)
|
||||
|
||||
## Quickstart
|
||||
## Technology Overview
|
||||
Spee.ch is a react web app that depends on MySQL for local content, and on two other lbry technologies:
|
||||
* [chainquery](https://github.com/lbryio/chainquery) - a normalized database of the blockchain data. We've provided credentials to use a public chainquery service. You can also install it on your own server to avoid being affected by the commons.
|
||||
* [lbrynet](https://github.com/lbryio/lbry) - a daemon that handles your wallet and transactions.
|
||||
|
||||
### Ubuntu
|
||||
[Ubuntu VPS Setup](./docs/ubuntu16vpspersonal.md)
|
||||
## Installation
|
||||
|
||||
_Note: This is our new setup. For our old setup see the [fullstart guide](./fullstart.md)._
|
||||
### Ubuntu Step by Step
|
||||
[Ubuntu Install Guide](./docs/ubuntuinstall.md)
|
||||
|
||||
#### System Dependencies:
|
||||
* [node](https://nodejs.org)
|
||||
### Quickstart Overview
|
||||
|
||||
#### Get some information ready:
|
||||
* mysqlusername
|
||||
* mysqlpassword
|
||||
* domainname or 'http://localhost'
|
||||
* speechport = 3000
|
||||
|
||||
#### Install and Set Up System Dependencies:
|
||||
* [NodeJS](https://nodejs.org)
|
||||
* [MySQL](https://dev.mysql.com/doc/refman/8.0/en/installing.html)
|
||||
* [`lbry`](https://github.com/lbryio/lbry) daemon
|
||||
* note: retrieve an address from the daemon and send your wallet a few credits (or join us in the [#speech discord channel](https://discord.gg/YjYbwhS) and we will send you a few)
|
||||
* localhost port 3306
|
||||
* mysqlusername or root
|
||||
* mysqlpassword
|
||||
* You may need
|
||||
```
|
||||
mysql> `ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword';`
|
||||
```
|
||||
* [lbrynet](https://github.com/lbryio/lbry) daemon
|
||||
* run this as a service exposing ports 3333 and 4444
|
||||
* _note_: once the daemon is running, issue commands in another terminal session (tmux) to retrieve an address for your wallet to recieve 5+ LBC credits (or join us in the [#speech discord channel](https://discord.gg/YjYbwhS) and we will send you a few)
|
||||
* `./lbrynet commands` gets a list of commands
|
||||
* `./lbrynet account_balance` gets your balance (initially 0.0)
|
||||
* `./lbrynet address_list` gets addresses you can use to recieve LBC
|
||||
* [FFmpeg](https://www.ffmpeg.org/download.html)
|
||||
* [Spee.ch] (below)
|
||||
* [pm2] (optional) process manager such as pm2 to run speech server.js
|
||||
* [http proxy server] caddy, nginx, traefik, etc to forward 443 to speech port 3000
|
||||
|
||||
|
||||
#### Clone this repo
|
||||
* release version for stable production
|
||||
```
|
||||
$ git clone -b release https://github.com/lbryio/spee.ch.git
|
||||
```
|
||||
* master version for development
|
||||
```
|
||||
$ git clone https://github.com/lbryio/spee.ch.git
|
||||
```
|
||||
* your own fork for customization
|
||||
|
||||
#### Change directory into your project
|
||||
```
|
||||
$ cd spee.ch
|
||||
```
|
||||
|
||||
#### Install node dependencies
|
||||
```
|
||||
$ npm install
|
||||
```
|
||||
|
||||
#### Create the config files using the built-in CLI
|
||||
_note: make sure lbrynet is running in the background before proceeding_
|
||||
|
||||
```
|
||||
$ npm run configure
|
||||
```
|
||||
|
||||
* _note: At the moment, you will have to copy chainqueryConfig.json from:_
|
||||
```
|
||||
~/spee.ch/docs/setup/conf/speech/chainqueryConfig.json
|
||||
```
|
||||
|
||||
_to:_
|
||||
```
|
||||
~/spee.ch/site/config/chainqueryConfig.json
|
||||
```
|
||||
|
||||
* _note: The domain name in this part must be prefixed with http:// or https://_
|
||||
|
||||
#### Build & start the app
|
||||
|
||||
_note: make sure lbrynet is running in the background before proceeding_
|
||||
```
|
||||
$ npm run start
|
||||
```
|
||||
|
||||
#### View in browser
|
||||
* Visit [http://localhost:3000](http://localhost:3000) in your browser
|
||||
|
||||
#### Customize your app
|
||||
|
||||
|
@ -23,12 +99,11 @@ Check out the [customization guide](https://github.com/lbryio/spee.ch/blob/readm
|
|||
|
||||
#### (optional) add custom components and update the styles
|
||||
|
||||
* Create custom components by creating React components in `src/views/` (further instructions coming soon)
|
||||
* Update the CSS by changing the files in `public/assets/css/` (further instructions and refactor coming soon)
|
||||
* Create custom components by creating React components in `site/custom/src/` (further instructions coming soon)
|
||||
* Update the CSS by changing the files in `site/custom/scss` (further instructions and refactor coming soon)
|
||||
|
||||
#### (optional) Syncing the full blockchain
|
||||
* Start the `spee.ch-sync` tool available at [billbitt/spee.ch-sync](https://github.com/billbitt/spee.ch-sync)
|
||||
* This is not necessary, but highly recommended. It will decode the blocks of the `LBRY` blockchain and add the claims information to your database's tables
|
||||
#### (optional) install your own chainquery
|
||||
Instructions are coming at [lbry-docker] to install your own chainquery instance using docker-compose. This will require 50GB of preferably SSD space and at least 10 minutes to download, possibly much longer.
|
||||
|
||||
## API
|
||||
#### /api/claim/publish
|
||||
|
@ -112,7 +187,7 @@ Spee.ch also runs a sync tool, which decodes blocks from the `LBRY` blockchain a
|
|||
|
||||
|
||||
### Architecture
|
||||
* `cli/` contains the code for the CLI tool. Running the tool will create `.json` config files and place them in the `config/` folder
|
||||
* `cli/` contains the code for the CLI tool. Running the tool will create `.json` config files and place them in the `site/config/` folder
|
||||
* `configure.js` is the entry point for the CLI tool
|
||||
* `cli/defaults/` holds default config files
|
||||
* `cli/questions/` holds the questions that the CLI tool asks to build the config files
|
||||
|
@ -128,9 +203,9 @@ Spee.ch also runs a sync tool, which decodes blocks from the `LBRY` blockchain a
|
|||
* `client/scss/` contains the CSS for the project
|
||||
*
|
||||
|
||||
* `config/custom` is a folder which can be used to override the default components in `client/`
|
||||
* `site/custom` is a folder which can be used to override the default components in `client/`
|
||||
* The folder structure mimics that of the `client/` folder
|
||||
* to customize spee.ch, place your own components and scss in the `config/custom/src/` and `config/custom/scss` folders.
|
||||
* to customize spee.ch, place your own components and scss in the `site/custom/src/` and `site/custom/scss` folders.
|
||||
|
||||
* `server/` contains all of the server code
|
||||
* `index.js` is the entry point for the server. It creates the [express app](https://expressjs.com/), requires the routes, syncs the database, and starts the server listening on the `PORT` designated in the config files.
|
||||
|
|
|
@ -67,6 +67,13 @@ try {
|
|||
slackConfig = require('./defaults/slackConfig.json');
|
||||
}
|
||||
|
||||
let chainqueryConfig;
|
||||
try {
|
||||
chainqueryConfig = require('../site/config/chainqueryConfig.json');
|
||||
} catch (error) {
|
||||
chainqueryConfig = require('./defaults/chainqueryConfig.json');
|
||||
}
|
||||
|
||||
// ask user questions and create config files
|
||||
inquirer
|
||||
.prompt(mysqlQuestions(mysqlDatabase, mysqlUsername, mysqlPassword))
|
||||
|
@ -196,6 +203,7 @@ inquirer
|
|||
createConfigFile('lbryConfig.json', lbryConfig);
|
||||
createConfigFile('loggerConfig.json', loggerConfig);
|
||||
createConfigFile('slackConfig.json', slackConfig);
|
||||
createConfigFile('chainqueryConfig.json', chainqueryConfig);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('\nYou\'re all done!');
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"host": "localhost",
|
||||
"host": "public.chainquery.lbry.io",
|
||||
"port": "3306",
|
||||
"timeout": 30,
|
||||
"database": "chainquery",
|
||||
"username": "lbry",
|
||||
"password": "root"
|
||||
"username": "speechpublic",
|
||||
"password": "7uITJLwZRvHBZYS3JZDykD1-7hLVkVA1jDWfcgqi6QnC"
|
||||
}
|
||||
|
|
129
client/scss/_asset-display.scss
Normal file
129
client/scss/_asset-display.scss
Normal file
|
@ -0,0 +1,129 @@
|
|||
.asset-main {
|
||||
height: 75vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.asset-display {
|
||||
display: flex;
|
||||
min-height: 50vh
|
||||
}
|
||||
|
||||
.asset-title {
|
||||
padding-bottom: $thin-padding;
|
||||
text-align: center;
|
||||
|
||||
@media (min-width: $break-point-mobile) {
|
||||
padding-top: $secondary-padding;
|
||||
}
|
||||
}
|
||||
|
||||
.asset-image, .asset-video {
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
/*below must die if this is intended to be shareable component! it also probably doesn't need to be*/
|
||||
|
||||
.visible-content {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
&.closed {
|
||||
box-shadow: none;
|
||||
|
||||
&:after {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
box-shadow: 0px 2px 3px 2px $shadow-color;
|
||||
content: '';
|
||||
height: 0;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.vertical-split, .visible-content {
|
||||
flex : 1 0 auto;
|
||||
display : flex;
|
||||
flex-direction : column;
|
||||
justify-content: space-between;
|
||||
align-items : center;
|
||||
};
|
||||
|
||||
.collapse-content {
|
||||
flex-grow: 0;
|
||||
@media (max-width: $break-point-tablet) {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-content.closed{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: block;
|
||||
margin: 15px auto 0;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
text-align: center;
|
||||
padding: 0px;
|
||||
|
||||
@media (max-width: $break-point-tablet) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
svg {
|
||||
stroke: $primary-color;
|
||||
&.plus-icon {
|
||||
transform: rotate(0);
|
||||
transition: all 0.4s ease;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.plus-icon {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.asset-info {
|
||||
$asset-info-width: 1000px;
|
||||
max-width: $asset-info-width;
|
||||
margin: $primary-padding;
|
||||
max-width: 100%;
|
||||
|
||||
@media (max-width: $break-point-tablet) {
|
||||
margin: $primary-padding $secondary-padding;
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-mobile) {
|
||||
margin: $primary-padding 0;
|
||||
}
|
||||
}
|
||||
|
||||
.asset-footer {
|
||||
border-top: 1px solid $grey-border;
|
||||
padding-top: $primary-padding;
|
||||
margin-top: $primary-padding;
|
||||
color: $grey;
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
word-wrap: break-word;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
16
client/scss/_button-primary.scss
Normal file
16
client/scss/_button-primary.scss
Normal file
|
@ -0,0 +1,16 @@
|
|||
.button--primary, .button--primary:focus, .button--primary:active {
|
||||
border-color: $primary-color;
|
||||
color: $primary-color;
|
||||
background-color: $background-color;
|
||||
}
|
||||
|
||||
.button--primary:hover {
|
||||
color: $background-color;
|
||||
background-color: $primary-color;
|
||||
}
|
||||
|
||||
.button--primary:active {
|
||||
$color: darken($primary-color, 10%);
|
||||
border-color: $color;
|
||||
background-color: $color;
|
||||
}
|
11
client/scss/_button-secondary.scss
Normal file
11
client/scss/_button-secondary.scss
Normal file
|
@ -0,0 +1,11 @@
|
|||
.button--secondary, .button--secondary:focus, .button--secondary:active {
|
||||
border-bottom-color: $secondary-color;
|
||||
color: $secondary-color;
|
||||
background-color: $background-color;
|
||||
}
|
||||
|
||||
.button--secondary:active {
|
||||
$color: darken($secondary-color, 10%);
|
||||
color: $color;
|
||||
border-bottom-color: $color;
|
||||
}
|
21
client/scss/_button.scss
Normal file
21
client/scss/_button.scss
Normal file
|
@ -0,0 +1,21 @@
|
|||
button {
|
||||
cursor: pointer;
|
||||
&:active
|
||||
{
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.button--primary, .button--secondary
|
||||
{
|
||||
border-width: $button-border-width;
|
||||
border-style: $button-border-strength;
|
||||
border-color: transparent;
|
||||
padding: $thin-padding;
|
||||
}
|
||||
|
||||
|
||||
.button--jumbo, .button--jumbo:focus, .button--jumbo:active {
|
||||
width: $button-full-width;
|
||||
font-size: x-large;
|
||||
}
|
33
client/scss/_click-to-copy.scss
Normal file
33
client/scss/_click-to-copy.scss
Normal file
|
@ -0,0 +1,33 @@
|
|||
.click-to-copy-wrap {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border: 1px solid $grey-border;
|
||||
border-radius: 6px;
|
||||
.click-to-copy {
|
||||
border: none;
|
||||
padding: 0.36em 0.5em;
|
||||
margin: 0;
|
||||
background-color: transparent;
|
||||
width: calc(100% - 1em - 2px);
|
||||
font-size: 14px;
|
||||
letter-spacing: -0.6px;
|
||||
line-height: 20px;
|
||||
letter-spacing: 0;
|
||||
font-family: monospace;
|
||||
border-right: 1px solid $grey-border;
|
||||
}
|
||||
.icon-wrap {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
svg {
|
||||
stroke: $primary-color;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.dropzone:hover, .dropzone--active {
|
||||
|
@ -28,6 +29,11 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.dropzone-dropit-display
|
||||
{
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.dropzone-preview-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
@ -49,3 +55,7 @@
|
|||
padding: 1em;
|
||||
width: calc(100% - 2em);
|
||||
}
|
||||
|
||||
.dropzone-instructions-display__chooser-label {
|
||||
text-decoration: underline;
|
||||
}
|
7
client/scss/_form.scss
Normal file
7
client/scss/_form.scss
Normal file
|
@ -0,0 +1,7 @@
|
|||
.form-group {
|
||||
padding-bottom: $secondary-padding;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
padding-bottom: $secondary-padding;
|
||||
}
|
62
client/scss/_horizontal-split.scss
Normal file
62
client/scss/_horizontal-split.scss
Normal file
|
@ -0,0 +1,62 @@
|
|||
.horizontal-split {
|
||||
max-width: $width-content-constrained;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display : flex;
|
||||
flex-direction : row;
|
||||
justify-content: space-between;
|
||||
|
||||
&.horizontal-split--mobile-collapse {
|
||||
@media (max-width: $break-point-mobile) {
|
||||
flex-direction: column;
|
||||
|
||||
.horizontal-split__column {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.horizontal-split__column--right {
|
||||
padding-left: 0;
|
||||
padding-top: $secondary-padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
.horizontal-split__column {
|
||||
width: 50%;
|
||||
flex: 1 0 auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.horizontal-split__column--left {
|
||||
padding-right: $primary-padding;
|
||||
|
||||
@media (max-width: $break-point-mobile) {
|
||||
padding-right: $thin-padding;
|
||||
}
|
||||
}
|
||||
|
||||
.horizontal-split__column--right {
|
||||
padding-left: $primary-padding;
|
||||
|
||||
@media (max-width: $break-point-mobile) {
|
||||
padding-left: $thin-padding;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-tablet) {
|
||||
|
||||
.horizontal-split__column {
|
||||
display : flex;
|
||||
flex-direction : column;
|
||||
justify-content: space-between;
|
||||
};
|
||||
|
||||
.column {
|
||||
width: 100%;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: $secondary-padding;
|
||||
}
|
||||
}
|
|
@ -4,17 +4,12 @@ input:-webkit-autofill {
|
|||
|
||||
input {
|
||||
margin: 0;
|
||||
outline: none;
|
||||
padding: $input-padding;
|
||||
border: 0;
|
||||
background-color: $background-color;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.input-text {
|
||||
|
||||
}
|
||||
|
||||
.input-slider {
|
||||
width: 100%
|
||||
}
|
||||
|
@ -43,6 +38,10 @@ input {
|
|||
border-bottom: 1px solid $secondary-color;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
padding-bottom: $secondary-padding;
|
||||
}
|
||||
|
||||
// modifiers
|
||||
|
||||
.input--full-width {
|
|
@ -2,6 +2,7 @@
|
|||
padding-top: $thin-padding;
|
||||
padding-bottom: $thin-padding;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.label-radio {
|
||||
|
@ -10,7 +11,7 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-medium ) {
|
||||
@media (max-width: $break-point-tablet ) {
|
||||
|
||||
// note: bolding break point lines up with row-label break point
|
||||
.label, .label-radio {
|
21
client/scss/_link.scss
Normal file
21
client/scss/_link.scss
Normal file
|
@ -0,0 +1,21 @@
|
|||
a, a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link--primary, .link--primary:visited {
|
||||
color: $primary-color;
|
||||
&:hover { text-decoration: underline; }
|
||||
}
|
||||
|
||||
.link--nav {
|
||||
color: $text-color;
|
||||
border-bottom: 2px solid white;
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.link--nav-active {
|
||||
border-bottom: 2px solid $primary-color;
|
||||
}
|
7
client/scss/_media-queries.scss
Normal file
7
client/scss/_media-queries.scss
Normal file
|
@ -0,0 +1,7 @@
|
|||
@media (max-width: $break-point-x-large) {
|
||||
// hide site description in nav bar
|
||||
.site-description {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,31 +1,37 @@
|
|||
.nav-bar {
|
||||
padding-left: $primary-padding;
|
||||
padding-right: $primary-padding;
|
||||
border-bottom: 0.5px solid $tertiary-color;
|
||||
.select--arrow {
|
||||
padding: 0 1.5em 0 $input-padding;
|
||||
margin-top: $thin-padding;
|
||||
margin-left: $primary-padding;
|
||||
margin-right: $primary-padding;
|
||||
|
||||
@media (max-width: $break-point-mobile) {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-bar-link {
|
||||
padding: calc(1em - 2px);
|
||||
display: inline-block;
|
||||
font-size: $text-medium;
|
||||
letter-spacing: 0.4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.nav-bar-logo {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-medium ) {
|
||||
@media (max-width: $break-point-tablet ) {
|
||||
.nav-bar-link {
|
||||
padding-top: calc(1em - 2px);
|
||||
padding-right: 1em;
|
||||
padding-bottom: calc(1em - 2px);
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-small ) {
|
||||
@media (max-width: $break-point-mobile ) {
|
||||
.nav-bar-link {
|
||||
padding-top: calc(0.5em - 2px);
|
||||
padding-right: 0.5em;
|
27
client/scss/_page-layout.scss
Normal file
27
client/scss/_page-layout.scss
Normal file
|
@ -0,0 +1,27 @@
|
|||
.page-layout {
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.content {
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
margin: $secondary-padding;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-tablet) {
|
||||
.page-layout .content { margin: $tertiary-padding; }
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-mobile) {
|
||||
max-width: calc(100% - 30px);
|
||||
}
|
||||
|
||||
//below should take some styles from _text.scss and probably elsewhere and become "markdown" or "rich" styles
|
||||
.page-layout {
|
||||
p {
|
||||
margin-bottom: $tertiary-padding;
|
||||
}
|
||||
}
|
12
client/scss/_progress-bar.scss
Normal file
12
client/scss/_progress-bar.scss
Normal file
|
@ -0,0 +1,12 @@
|
|||
.progress-bar__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.progress-bar--inactive {
|
||||
color: $grey;
|
||||
}
|
||||
|
||||
.progress-bar--active {
|
||||
color: $primary-color;
|
||||
}
|
13
client/scss/_publish-preview.scss
Normal file
13
client/scss/_publish-preview.scss
Normal file
|
@ -0,0 +1,13 @@
|
|||
.publish-form__title {
|
||||
max-width: $width-content-constrained;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
@media (max-width: $break-point-mobile) {
|
||||
font-size: .8em;
|
||||
}
|
||||
}
|
||||
|
||||
.publish-preview-dim {
|
||||
opacity: 0.2;
|
||||
}
|
|
@ -17,5 +17,5 @@
|
|||
.publish-url-text {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: $secondary-color;
|
||||
color: $help-color;
|
||||
}
|
4
client/scss/_reset.scss
Normal file
4
client/scss/_reset.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
button, input, textarea, label, select, option {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
.row {
|
||||
padding-bottom: 2em;
|
||||
margin-bottom: 1.2em;
|
||||
}
|
||||
|
||||
.row-labeled {
|
||||
|
@ -7,29 +7,28 @@
|
|||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
padding-bottom: $tertiary-padding;
|
||||
}
|
||||
|
||||
.row-labeled-label {
|
||||
align-self: flex-start;
|
||||
width: 30%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
.row-labeled-content {
|
||||
align-self: center;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: $break-point-medium ) {
|
||||
|
||||
@media (max-width: $break-point-tablet ) {
|
||||
.row-labeled {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.row-labeled-label {
|
||||
width: 100%;
|
||||
}
|
||||
.row-labeled-content {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
4
client/scss/_select.scss
Normal file
4
client/scss/_select.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
select {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
51
client/scss/_share-buttons.scss
Normal file
51
client/scss/_share-buttons.scss
Normal file
|
@ -0,0 +1,51 @@
|
|||
.share-buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 0 7px;
|
||||
border-radius: 100%;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
transition: all 0.2s ease;
|
||||
&.twitter {
|
||||
background:#4DC2FE;
|
||||
img {
|
||||
margin-top: 8px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&.facebook {
|
||||
background: #5487DE;
|
||||
img {
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&.tumblr {
|
||||
background: #274061;
|
||||
img {
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
&.reddit {
|
||||
background: #FF4500;
|
||||
img {
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child{
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,5 +7,4 @@
|
|||
.social-share-link > a{
|
||||
padding-right:0.5em;
|
||||
padding-left:0.5em;
|
||||
padding-bottom:0.3em;
|
||||
}
|
59
client/scss/_text.scss
Normal file
59
client/scss/_text.scss
Normal file
|
@ -0,0 +1,59 @@
|
|||
// set defaults
|
||||
|
||||
h1, h2, h3, h4, p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
color: $text-color;
|
||||
font-family: 'Circular', serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: $text-xx-large;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $text-x-large;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $text-large;
|
||||
}
|
||||
|
||||
.text--extra-large {
|
||||
font-size: $text-xx-large;
|
||||
}
|
||||
|
||||
.text--large {
|
||||
font-size: $text-large;
|
||||
}
|
||||
|
||||
.text--medium {
|
||||
font-size: $text-medium;
|
||||
}
|
||||
|
||||
.text--small {
|
||||
font-size: $text-small;
|
||||
}
|
||||
|
||||
.text--extra-small {
|
||||
font-size: $text-x-small;
|
||||
}
|
||||
|
||||
.text--secondary {
|
||||
color: $help-color;
|
||||
}
|
||||
|
||||
.text--interactive {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.text--failure {
|
||||
color: $failure-color;
|
||||
}
|
||||
|
||||
.text--success {
|
||||
color: $success-color;
|
||||
}
|
6
client/scss/_textarea.scss
Normal file
6
client/scss/_textarea.scss
Normal file
|
@ -0,0 +1,6 @@
|
|||
textarea {
|
||||
margin: 0;
|
||||
padding: $input-padding;
|
||||
display: inline-block;
|
||||
width: $input-full-width;
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
$base-color: white;
|
||||
$primary-color: black;
|
||||
$secondary-color: #9b9b9b;
|
||||
$tertiary-color: #ccccc0;
|
||||
$interactive-color: blue;
|
||||
$primary-color: #005da0;
|
||||
$secondary-color: $primary-color;
|
||||
$success-color: green;
|
||||
$failure-color: red;
|
||||
$grey: #9095A5;
|
||||
$help-color: $grey;
|
||||
$grey-border: #DDDFE4;
|
||||
$shadow-color: rgba(169, 173, 186, 0.2);
|
||||
|
||||
$primary-padding: 3em;
|
||||
$secondary-padding: 2em;
|
||||
|
@ -12,8 +14,10 @@ $tertiary-padding: 1em;
|
|||
$thin-padding: 0.3em;
|
||||
$full-width-thin-padding: calc(100% - 0.6em);
|
||||
|
||||
$width-content-constrained: 1000px;
|
||||
|
||||
$background-color: $base-color;
|
||||
$font-color: $primary-color;
|
||||
$text-color: #333;
|
||||
|
||||
$button-border-width: 1px;
|
||||
$button-border-strength: solid;
|
||||
|
@ -23,16 +27,14 @@ $input-padding: 0.3em;
|
|||
$input-full-width: calc(100% - 0.6em);
|
||||
|
||||
$text-xx-large: 2.5em;
|
||||
$text-x-large: xx-large;
|
||||
$text-large: x-large;
|
||||
$text-medium: large;
|
||||
$text-small: medium;
|
||||
$text-x-small: small;
|
||||
$text-x-large: 2.0em;
|
||||
$text-large: 1.5em;
|
||||
$text-medium: 1.0em;
|
||||
$text-small: 0.9em;
|
||||
$text-x-small: 0.8em;
|
||||
|
||||
$break-point-xx-large: 1400px;
|
||||
$break-point-x-large: 1290px;
|
||||
$break-point-large: 1000px;
|
||||
$break-point-medium: 800px;
|
||||
$break-point-small: 500px;
|
||||
$break-point-x-small: 400px;
|
||||
|
||||
$break-point-tablet: 800px;
|
||||
$break-point-mobile: 500px;
|
|
@ -1,48 +1,44 @@
|
|||
@import '~variables/_variables';
|
||||
@import '~reset/_reset';
|
||||
@import '~font/_font';
|
||||
@import '~html/_html';
|
||||
@import '~body/_body';
|
||||
@import '~react-app/_react-app';
|
||||
@import '~text/_text';
|
||||
@import '_variables';
|
||||
@import '_reset';
|
||||
@import 'font/_font.scss';
|
||||
@import '_html';
|
||||
@import '_body';
|
||||
@import '_react-app';
|
||||
@import '_text';
|
||||
|
||||
@import '~link/_link';
|
||||
@import '~input/_input';
|
||||
@import '~select/_select';
|
||||
@import '~textarea/_textarea';
|
||||
@import '~video/_video';
|
||||
@import '_link';
|
||||
@import '_input';
|
||||
@import '_select';
|
||||
@import '_textarea';
|
||||
@import '_video';
|
||||
@import '_form';
|
||||
|
||||
@import '~asset-display/_asset-display';
|
||||
@import '~asset-preview/_asset-preview';
|
||||
@import '~button/_button';
|
||||
@import '~button-primary/_button-primary';
|
||||
@import '~button-secondary/_button-secondary';
|
||||
@import '~button-tertiary/_button-tertiary';
|
||||
@import '~click-to-copy/_click-to-copy';
|
||||
@import '~column/_column';
|
||||
@import '~form-feedback/_form-feedback';
|
||||
@import '~horizontal-quad-split/_horizontal-quad-split';
|
||||
@import '~horizontal-split/_horizontal-split';
|
||||
@import '~label/_label';
|
||||
@import '~nav-bar/_nav-bar';
|
||||
@import '~page-layout/_page-layout';
|
||||
@import '~page-layout-show-lite/_page-layout-show-lite';
|
||||
@import '~page-content/_page-content';
|
||||
@import '~progress-bar/_progress-bar';
|
||||
@import '~publish-preview/_publish-preview';
|
||||
@import '~space-between/_space-between';
|
||||
@import '~space-around/_space-around';
|
||||
@import '~row/_row';
|
||||
@import '~vertical-split/_vertical-split';
|
||||
@import '~tooltip/_tooltip';
|
||||
@import '~social-share-link/_social-share-link';
|
||||
|
||||
@import '~channel-claims-display/_channel-claims-display';
|
||||
@import '~dropzone/_dropzone';
|
||||
@import '~publish-url-input/_publish-url-input';
|
||||
@import '~publish-status/_publish-status';
|
||||
@import '~publish-disabled-message/_publish-disabled-message';
|
||||
|
||||
@import '~media-queries/_media-queries';
|
||||
@import '_asset-display';
|
||||
@import '_asset-preview';
|
||||
@import '_button';
|
||||
@import '_button-primary';
|
||||
@import '_button-secondary';
|
||||
@import '_click-to-copy';
|
||||
@import '_form-feedback';
|
||||
@import '_horizontal-split';
|
||||
@import '_label';
|
||||
@import '_nav-bar';
|
||||
@import '_page-layout';
|
||||
@import '_page-layout-show-lite';
|
||||
@import '_page-content';
|
||||
@import '_progress-bar';
|
||||
@import '_publish-preview';
|
||||
@import '_share-buttons';
|
||||
@import '_space-between';
|
||||
@import '_space-around';
|
||||
@import '_row';
|
||||
@import '_tooltip';
|
||||
@import '_social-share-link';
|
||||
|
||||
@import '_channel-claims-display';
|
||||
@import '_dropzone';
|
||||
@import '_publish-url-input';
|
||||
@import '_publish-status';
|
||||
@import '_publish-disabled-message';
|
||||
|
||||
@import '_media-queries';
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
.asset-display {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.asset-image, .asset-video {
|
||||
margin : 0;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
}
|
||||
.asset-video {
|
||||
border: 1px solid #d0d0d0;
|
||||
margin: 16px;
|
||||
padding: 6px;
|
||||
}
|
||||
.vertical-split .asset-display {
|
||||
height: 90vh;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
.button-primary, .button-primary:focus, .button-primary:active {
|
||||
border: $button-border-width $button-border-strength $primary-color;
|
||||
margin-top: $thin-padding;
|
||||
margin-bottom: $thin-padding;
|
||||
padding: $thin-padding;
|
||||
color: $primary-color;
|
||||
background-color: $background-color;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.button-primary:focus {
|
||||
border-color: $secondary-color;
|
||||
background-color: $tertiary-color;
|
||||
}
|
||||
|
||||
|
||||
.button-primary:hover {
|
||||
border-color: $interactive-color;
|
||||
color: $background-color;
|
||||
background-color: $interactive-color;
|
||||
}
|
||||
|
||||
.button-primary:active{
|
||||
border-color: $background-color;
|
||||
color: $secondary-color;
|
||||
background-color: $tertiary-color;
|
||||
}
|
||||
|
||||
.button-primary--jumbo, .button-primary--jumbo:focus, .button-primary--jumbo:active {
|
||||
width: $button-full-width;
|
||||
padding-top: $secondary-padding;
|
||||
padding-bottom: $secondary-padding;
|
||||
font-size: x-large;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
.button--secondary, .button--secondary:focus {
|
||||
border: 0;
|
||||
border-bottom: $button-border-width $button-border-strength $primary-color;
|
||||
padding: 0.5em;
|
||||
color: $primary-color;
|
||||
background-color: $background-color;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.button--secondary:focus{
|
||||
border-color: $secondary-color;
|
||||
background-color: $tertiary-color;
|
||||
}
|
||||
|
||||
.button--secondary:hover {
|
||||
color: $interactive-color;
|
||||
}
|
||||
|
||||
.button--secondary:active {
|
||||
color: $background-color;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
.button--tertiary, .button--tertiary:focus, .button--tertiary:active {
|
||||
border: 0;
|
||||
color: $secondary-color;
|
||||
background-color: $background-color;
|
||||
}
|
||||
|
||||
.button--tertiary:hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.button--tertiary:active, .button--tertiary:focus {
|
||||
color: $secondary-color;
|
||||
background-color: $tertiary-color;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
button {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
.click-to-copy {
|
||||
cursor: pointer;
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
color: black;
|
||||
background-color: white;
|
||||
width: calc(100% - 1em - 2px);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
.column {
|
||||
padding-left: $primary-padding;
|
||||
padding-right: $primary-padding;
|
||||
}
|
BIN
client/scss/font/Circular/CircularStd-Bold.ttf
Normal file
BIN
client/scss/font/Circular/CircularStd-Bold.ttf
Normal file
Binary file not shown.
BIN
client/scss/font/Circular/CircularStd-Book.ttf
Normal file
BIN
client/scss/font/Circular/CircularStd-Book.ttf
Normal file
Binary file not shown.
|
@ -16,3 +16,16 @@
|
|||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Circular';
|
||||
src: url('./font/Circular/CircularStd-Book.ttf');
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Circular';
|
||||
src: url('./font/Circular/CircularStd-Bold.ttf');
|
||||
font-weight: bold;
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
.horizontal-quad-split {
|
||||
display : flex;
|
||||
flex-direction : row;
|
||||
justify-content: space-between;
|
||||
align-items : flex-start;
|
||||
.left-side, .right-side {
|
||||
width : 50%;
|
||||
display : flex;
|
||||
flex-direction : row;
|
||||
justify-content: space-between;
|
||||
align-items : flex-start;
|
||||
.column-a, .column-b, .column-c, .column-d {
|
||||
width: 50%;
|
||||
};
|
||||
.column-a, .column-b, .column-c {
|
||||
padding-right: $secondary-padding;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@media (max-width: $break-point-large ) {
|
||||
|
||||
.horizontal-quad-split {
|
||||
flex-direction : column;
|
||||
.left-side, .right-side {
|
||||
width : 100%;
|
||||
.column-a, .column-b, .column-c, .column-d {
|
||||
width: 50%;
|
||||
};
|
||||
.column-b {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-medium ) {
|
||||
|
||||
.horizontal-quad-split {
|
||||
flex-direction : column;
|
||||
.left-side, .right-side {
|
||||
flex-direction : column;
|
||||
.column-a, .column-b, .column-c, .column-d {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
.horizontal-split {
|
||||
display : flex;
|
||||
flex-direction : row;
|
||||
justify-content: space-between;
|
||||
align-items : flex-start;
|
||||
.column {
|
||||
width: 50%;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@media (max-width: $break-point-large ) {
|
||||
|
||||
.horizontal-split {
|
||||
display : flex;
|
||||
flex-direction : column;
|
||||
justify-content: space-between;
|
||||
align-items : flex-start;
|
||||
.column {
|
||||
width: 100%;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: $secondary-padding;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
9
client/scss/icon/chevron-down.svg
Normal file
9
client/scss/icon/chevron-down.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="8px" viewBox="0 0 14 8" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>chevron-down</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
|
||||
<polyline id="chevron-down" stroke="#000000" stroke-width="1.2" fill-rule="nonzero" points="13 1 7 7 1 1"></polyline>
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 582 B |
|
@ -1,27 +0,0 @@
|
|||
a, a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link--primary, .link--primary:visited {
|
||||
color: $interactive-color;
|
||||
}
|
||||
|
||||
.link--secondary, .link--secondary:visited {
|
||||
margin: 0px;
|
||||
padding: 0.3em;
|
||||
color: $secondary-color;
|
||||
}
|
||||
|
||||
.link--nav {
|
||||
color: $primary-color;
|
||||
border-bottom: 2px solid white;
|
||||
}
|
||||
|
||||
.link--nav:hover {
|
||||
color: $interactive-color;
|
||||
}
|
||||
|
||||
.link--nav-active {
|
||||
color: $interactive-color;
|
||||
border-bottom: 2px solid $interactive-color;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
@media (max-width: $break-point-x-large) {
|
||||
// hide site description in nav bar
|
||||
.site-description {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-large ) {
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-medium) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-small) {
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-x-small ) {
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
.page-layout {
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.content {
|
||||
flex: 1 0 auto;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
margin: $primary-padding;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
.progress-bar--inactive {
|
||||
color: $secondary-color;
|
||||
}
|
||||
|
||||
.progress-bar--active {
|
||||
color: $primary-color;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
.publish-preview-dim {
|
||||
opacity: 0.2;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
select {
|
||||
margin: 0;
|
||||
outline: none;
|
||||
padding: $input-padding;
|
||||
border: 0;
|
||||
background-color: $background-color;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.select--arrow {
|
||||
-moz-appearance:none;
|
||||
-webkit-appearance: none;
|
||||
background: url('./icon/downArrow.svg') no-repeat right;
|
||||
cursor: pointer;
|
||||
padding-right: 1.5em;
|
||||
padding-left: $input-padding
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
// set defaults
|
||||
|
||||
h1, h2, h3, h4, p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: $text-xx-large;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $text-x-large;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $text-large;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p, body, button, input, textarea, label, select, option {
|
||||
font-family: 'Lekton', monospace;
|
||||
font-size: $text-large;
|
||||
}
|
||||
|
||||
.text--extra-large {
|
||||
font-size: $text-xx-large;
|
||||
}
|
||||
|
||||
.text--large {
|
||||
font-size: $text-large;
|
||||
}
|
||||
|
||||
.text--medium {
|
||||
font-size: $text-medium;
|
||||
}
|
||||
|
||||
.text--small {
|
||||
font-size: $text-small;
|
||||
}
|
||||
|
||||
.text--extra-small {
|
||||
font-size: $text-x-small;
|
||||
}
|
||||
|
||||
.text--underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.text--primary {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.text--secondary {
|
||||
color: $secondary-color;
|
||||
}
|
||||
|
||||
.text--tertiary {
|
||||
color: $tertiary-color;
|
||||
}
|
||||
|
||||
.text--interactive {
|
||||
color: $interactive-color;
|
||||
}
|
||||
|
||||
.text--failure {
|
||||
color: $failure-color;
|
||||
}
|
||||
|
||||
.text--success {
|
||||
color: $success-color;
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-x-large ) {
|
||||
h1 {
|
||||
font-size: $text-x-large;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $text-large;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $text-medium;
|
||||
}
|
||||
|
||||
p, body, button, input, textarea, label, select, option {
|
||||
font-size: $text-medium;
|
||||
}
|
||||
|
||||
.text--extra-large {
|
||||
font-size: $text-x-large;
|
||||
}
|
||||
|
||||
.text--large {
|
||||
font-size: $text-medium;
|
||||
}
|
||||
|
||||
.text--medium {
|
||||
font-size: $text-small;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-medium) {
|
||||
|
||||
h1 {
|
||||
font-size: $text-large;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $text-medium;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $text-small;
|
||||
}
|
||||
|
||||
p, body, button, input, textarea, label, select, option {
|
||||
font-size: $text-small;
|
||||
}
|
||||
|
||||
.text--extra-large {
|
||||
font-size: $text-large;
|
||||
}
|
||||
|
||||
.text--large {
|
||||
font-size: $text-medium;
|
||||
}
|
||||
|
||||
.text--small {
|
||||
font-size: $text-x-small;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: $break-point-x-small) {
|
||||
|
||||
h1 {
|
||||
font-size: $text-medium;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $text-small;
|
||||
}
|
||||
|
||||
p, body, button, input, textarea, label, select, option {
|
||||
font-size: $text-x-small;
|
||||
}
|
||||
|
||||
.text--extra-large {
|
||||
font-size: $text-x-small;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text--large {
|
||||
font-size: $text-x-small;
|
||||
}
|
||||
|
||||
.text--medium {
|
||||
font-size: $text-x-small;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
textarea {
|
||||
margin: 0;
|
||||
outline: none;
|
||||
padding: $input-padding;
|
||||
border: 0;
|
||||
border-bottom: 1px solid $secondary-color;
|
||||
background-color: $background-color;
|
||||
display: inline-block;
|
||||
width: $input-full-width;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
.vertical-split {
|
||||
flex : 1 0 auto;
|
||||
display : flex;
|
||||
flex-direction : column;
|
||||
justify-content: space-between;
|
||||
align-items : center;
|
||||
};
|
|
@ -7,9 +7,9 @@ const AboutSpeechDetails = () => {
|
|||
<div>
|
||||
<Row>
|
||||
<p className={'text--large'}>
|
||||
<Link to='/tos'>Terms of Service</Link>
|
||||
<Link className={'link--primary'} to='/tos'>Terms of Service</Link>
|
||||
<br />
|
||||
<Link to='/faq'>Frequently Asked Questions</Link>
|
||||
<Link className={'link--primary'} to='/faq'>Frequently Asked Questions</Link>
|
||||
</p>
|
||||
</Row>
|
||||
<Row>
|
||||
|
|
|
@ -8,18 +8,12 @@ const AboutSpeechOverview = () => {
|
|||
<p className={'text--extra-large'}>Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.</p>
|
||||
</Row>
|
||||
<Row>
|
||||
<p className={'text--large'}>
|
||||
<a className='link--primary' target='_blank' href='https://twitter.com/spee_ch'>TWITTER</a>
|
||||
</p>
|
||||
<p className={'text--large'}>
|
||||
<a className='link--primary' target='_blank' href='https://github.com/lbryio/spee.ch'>GITHUB</a>
|
||||
</p>
|
||||
<p className={'text--large'}>
|
||||
<a className='link--primary' target='_blank' href='https://discord.gg/YjYbwhS'>DISCORD CHANNEL</a>
|
||||
</p>
|
||||
<p className={'text--large'}>
|
||||
<a className='link--primary' target='_blank' href='https://github.com/lbryio/spee.ch/blob/master/README.md'>DOCUMENTATION</a>
|
||||
</p>
|
||||
<div className={'text--large'}>
|
||||
<a className='link--primary' target='_blank' href='https://twitter.com/spee_ch'>TWITTER</a><br/>
|
||||
<a className='link--primary' target='_blank' href='https://github.com/lbryio/spee.ch'>GITHUB</a><br/>
|
||||
<a className='link--primary' target='_blank' href='https://discord.gg/YjYbwhS'>DISCORD CHANNEL</a><br/>
|
||||
<a className='link--primary' target='_blank' href='https://github.com/lbryio/spee.ch/blob/master/README.md'>DOCUMENTATION</a><br/>
|
||||
</div>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
|
|
14
client/src/components/AssetInfoFooter/index.js
Normal file
14
client/src/components/AssetInfoFooter/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
import Row from '@components/Row';
|
||||
|
||||
const AssetInfoFooter = ({ assetUrl, name }) => {
|
||||
return (
|
||||
<div className='asset-footer'>
|
||||
<p>
|
||||
Hosted via the <a className={'link--primary'} href={'https://lbry.io/get'} target={'_blank'}>LBRY</a> blockchain
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AssetInfoFooter;
|
|
@ -5,49 +5,53 @@ const AssetShareButtons = ({ assetUrl, name }) => {
|
|||
return (
|
||||
<SocialShareLink >
|
||||
<a
|
||||
className='link--primary'
|
||||
className='link--primary twitter'
|
||||
target='_blank'
|
||||
href={`https://twitter.com/intent/tweet?text=${assetUrl}`}
|
||||
>
|
||||
twitter
|
||||
<img src='/assets/img/icn_twitter.svg' />
|
||||
</a>
|
||||
<a
|
||||
className='link--primary'
|
||||
className='link--primary facebook'
|
||||
target='_blank'
|
||||
href={`https://www.facebook.com/sharer/sharer.php?u=${assetUrl}`}
|
||||
>
|
||||
facebook
|
||||
<img src='/assets/img/icn_facebook.svg' />
|
||||
</a>
|
||||
<a
|
||||
className='link--primary'
|
||||
className='link--primary tumblr'
|
||||
target='_blank'
|
||||
href={`https://tumblr.com/widgets/share/tool?canonicalUrl=${assetUrl}`}
|
||||
>
|
||||
tumblr
|
||||
<img src='/assets/img/icn_tumblr.svg' />
|
||||
</a>
|
||||
<a
|
||||
className='link--primary'
|
||||
className='link--primary reddit'
|
||||
target='_blank'
|
||||
href={`https://www.reddit.com/submit?url=${assetUrl}&title=${name}`}
|
||||
>
|
||||
reddit
|
||||
</a>
|
||||
<a
|
||||
className='link--primary'
|
||||
target='_blank'
|
||||
href={`https://sharetomastodon.github.io/?title=${name}&url=${assetUrl}`}
|
||||
>
|
||||
mastodon
|
||||
</a>
|
||||
<a
|
||||
className='link--primary'
|
||||
target='_blank'
|
||||
href={`https://share.diasporafoundation.org/?title=${name}&url=${assetUrl}`}
|
||||
>
|
||||
diaspora
|
||||
<img src='/assets/img/icn_reddit.svg' />
|
||||
</a>
|
||||
</SocialShareLink>
|
||||
);
|
||||
};
|
||||
//
|
||||
// Additional icons disabled. If you want to add additional icons, you have to solve
|
||||
// https://github.com/lbryio/spee.ch/issues/687
|
||||
//
|
||||
// <a
|
||||
// className='link--primary'
|
||||
// target='_blank'
|
||||
// href={`https://sharetomastodon.github.io/?title=${name}&url=${assetUrl}`}
|
||||
// >
|
||||
// mastodon
|
||||
// </a>
|
||||
// <a
|
||||
// className='link--primary'
|
||||
// target='_blank'
|
||||
// href={`https://share.diasporafoundation.org/?title=${name}&url=${assetUrl}`}
|
||||
// >
|
||||
// diaspora
|
||||
// </a>
|
||||
|
||||
export default AssetShareButtons;
|
||||
|
|
|
@ -4,7 +4,7 @@ const ButtonPrimary = ({ value, onClickHandler, type = 'button' }) => {
|
|||
return (
|
||||
<button
|
||||
type={type}
|
||||
className={'button button-primary'}
|
||||
className={'button button--primary'}
|
||||
onClick={onClickHandler}
|
||||
>
|
||||
{value}
|
||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
|||
const ButtonPrimaryJumbo = ({ value, onClickHandler }) => {
|
||||
return (
|
||||
<button
|
||||
className={'button button-primary button-primary--jumbo'}
|
||||
className={'button button--primary button--jumbo'}
|
||||
onClick={onClickHandler}
|
||||
>
|
||||
{value}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
const ButtonTertiary = ({ value, onClickHandler }) => {
|
||||
return (
|
||||
<button
|
||||
className={'button button--tertiary'}
|
||||
onClick={onClickHandler}
|
||||
>
|
||||
{value}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default ButtonTertiary;
|
|
@ -2,8 +2,9 @@ import React from 'react';
|
|||
|
||||
const ChannelAbout = () => {
|
||||
return (
|
||||
<div>
|
||||
<p className={'text--large'}>Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends. You can create 1 channel, or 100, so whether you're <a className='link--primary' target='_blank' href='/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8'>documenting important events</a>, or making a public repository for <a className='link--primary' target='_blank' href='/@catGifs'>cat gifs</a> (password: '1234'), try creating a channel for it!</p>
|
||||
<div className={'text--large'}>
|
||||
<p>Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends.</p>
|
||||
<p>You can create 1 channel, or 100, so whether you're <a className='link--primary' target='_blank' href='/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8'>documenting important events</a>, or making a public repository for <a className='link--primary' target='_blank' href='/@catGifs'>cat gifs</a> (password: '1234'), try creating a channel for it!</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,7 +5,6 @@ const ChannelSelectDropdown = ({ selectedChannel, handleSelection, loggedInChann
|
|||
return (
|
||||
<select
|
||||
id='channel-name-select'
|
||||
className='select select--arrow'
|
||||
value={selectedChannel}
|
||||
onChange={handleSelection}>
|
||||
{ loggedInChannelName && (
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import React from 'react';
|
||||
import * as Icon from 'react-feather';
|
||||
|
||||
class ClickToCopy extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.copyToClipboard = this.copyToClipboard.bind(this);
|
||||
}
|
||||
copyToClipboard (event) {
|
||||
const elementToCopy = event.target.id;
|
||||
copyToClipboard () {
|
||||
const elementToCopy = this.props.id;
|
||||
const element = document.getElementById(elementToCopy);
|
||||
console.log(elementToCopy);
|
||||
element.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
|
@ -18,15 +20,22 @@ class ClickToCopy extends React.Component {
|
|||
render () {
|
||||
const {id, value} = this.props;
|
||||
return (
|
||||
<input
|
||||
id={id}
|
||||
value={value}
|
||||
<div
|
||||
className='click-to-copy-wrap'
|
||||
onClick={this.copyToClipboard}
|
||||
type='text'
|
||||
className='click-to-copy'
|
||||
readOnly
|
||||
spellCheck='false'
|
||||
/>
|
||||
>
|
||||
<input
|
||||
id={id}
|
||||
value={value}
|
||||
type='text'
|
||||
className='click-to-copy'
|
||||
readOnly
|
||||
spellCheck='false'
|
||||
/>
|
||||
<div className='icon-wrap'>
|
||||
<Icon.Copy />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
class Column extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div className={'column'}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Column;
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
|||
const DropzoneDropItDisplay = () => {
|
||||
return (
|
||||
<div className={'dropzone-dropit-display'}>
|
||||
<p className={'text--interactive'}>Drop it.</p>
|
||||
Drop it.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,15 +9,15 @@ const DropzoneInstructionsDisplay = ({fileError, message}) => {
|
|||
return (
|
||||
<div className={'dropzone-instructions-display'}>
|
||||
<Row>
|
||||
<p className={'text--large'}>{message}</p>
|
||||
<span className={'text--large'}>{message}</span>
|
||||
</Row>
|
||||
<Row>
|
||||
<p className={'text--small'}>OR</p>
|
||||
<span className={'text--small text--secondary'}>OR</span>
|
||||
</Row>
|
||||
{ fileError ? (
|
||||
<div>
|
||||
<Row>
|
||||
<p className={'text--large text--underline'}>CHOOSE FILE</p>
|
||||
<span className={'text--large dropzone-instructions-display__chooser-label'}>CHOOSE FILE</span>
|
||||
</Row>
|
||||
<FormFeedbackDisplay
|
||||
errorMessage={fileError}
|
||||
|
@ -25,7 +25,7 @@ const DropzoneInstructionsDisplay = ({fileError, message}) => {
|
|||
/>
|
||||
</div>
|
||||
) : (
|
||||
<p className={'text--large text--underline'}>CHOOSE FILE</p>
|
||||
<span className={'text--large dropzone-instructions-display__chooser-label'}>CHOOSE FILE</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import React from 'react';
|
||||
|
||||
const FormFeedbackDisplay = ({ errorMessage, defaultMessage }) => {
|
||||
return (
|
||||
return (errorMessage || defaultMessage) ? (
|
||||
<div className={'form-feedback'}>
|
||||
{ errorMessage ? (
|
||||
<p className={'text--small text--failure'}>{errorMessage}</p>
|
||||
<span className={'text--small text--failure'}>{errorMessage}</span>
|
||||
) : (
|
||||
<div>
|
||||
{ defaultMessage ? (
|
||||
<p className={'text--small text--secondary'}>{defaultMessage}</p>
|
||||
<span className={'text--small text--secondary'}>{defaultMessage}</span>
|
||||
) : (
|
||||
<p className={'text--small'}> </p>
|
||||
<span className={'text--small'}> </span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
) : null;
|
||||
};
|
||||
|
||||
export default FormFeedbackDisplay;
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
import React from 'react';
|
||||
import Row from '@components/Row';
|
||||
|
||||
class HorizontalTriSplit extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div className={'horizontal-quad-split'}>
|
||||
<div className={'left-side'}>
|
||||
<div className={'column-a'}>
|
||||
<Row>
|
||||
{this.props.columnA}
|
||||
</Row>
|
||||
</div>
|
||||
<div className={'column-b'}>
|
||||
<Row>
|
||||
{this.props.columnB}
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'right-side'}>
|
||||
<div className={'column-c'}>
|
||||
<Row>
|
||||
{this.props.columnC}
|
||||
</Row>
|
||||
</div>
|
||||
<div className={'column-d'}>
|
||||
<Row>
|
||||
{this.props.columnD}
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HorizontalTriSplit;
|
|
@ -2,13 +2,26 @@ import React from 'react';
|
|||
|
||||
class HorizontalSplit extends React.Component {
|
||||
render () {
|
||||
const { leftSide, rightSide, collapseOnMobile } = this.props;
|
||||
|
||||
let className = 'horizontal-split';
|
||||
if (collapseOnMobile) {
|
||||
className += " horizontal-split--mobile-collapse";
|
||||
}
|
||||
|
||||
// If there is no left side, move the right side to the left
|
||||
// This is mostly for content with no description
|
||||
// It doesn't need to be on the right side with nothing next to it.
|
||||
const leftComponent = leftSide || rightSide;
|
||||
const rightComponent = leftSide ? rightSide : null;
|
||||
|
||||
return (
|
||||
<div className={'horizontal-split'}>
|
||||
<div className={'column'}>
|
||||
{this.props.leftSide}
|
||||
<div className={className}>
|
||||
<div className={'horizontal-split__column horizontal-split__column--left'}>
|
||||
{leftComponent}
|
||||
</div>
|
||||
<div className={'column'}>
|
||||
{this.props.rightSide}
|
||||
<div className={'horizontal-split__column horizontal-split__column--right'}>
|
||||
{rightComponent}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -10,7 +10,6 @@ class NavBar extends React.Component {
|
|||
<div className={'nav-bar'}>
|
||||
<SpaceBetween >
|
||||
<Logo />
|
||||
<SiteDescription />
|
||||
<NavigationLinks />
|
||||
</SpaceBetween>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,6 @@ function NavBarChannelDropdown ({ channelName, handleSelection, defaultSelection
|
|||
<select
|
||||
type='text'
|
||||
id='nav-bar-channel-select'
|
||||
className='select select--arrow'
|
||||
onChange={handleSelection}
|
||||
value={defaultSelection}
|
||||
>
|
||||
|
|
|
@ -62,7 +62,7 @@ class ProgressBar extends React.Component {
|
|||
};
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<div className="progress-bar__wrapper">
|
||||
{this.state.bars.map((bar, index) => bar.isActive ? <ActiveStatusBar key={index} /> : <InactiveStatusBar key={index}/>)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -13,7 +13,6 @@ const PublishLicenseInput = ({ handleSelect }) => {
|
|||
type='text'
|
||||
name='license'
|
||||
id='publish-license'
|
||||
className='select select--primary'
|
||||
onChange={handleSelect}
|
||||
>
|
||||
<option value=''>Unspecified</option>
|
||||
|
|
|
@ -5,16 +5,21 @@ import PublishDetails from '@containers/PublishDetails';
|
|||
import PublishTitleInput from '@containers/PublishTitleInput';
|
||||
import Row from '@components/Row';
|
||||
|
||||
// this class seems more like PublishForm and should probably be renamed
|
||||
|
||||
class PublishPreview extends React.Component {
|
||||
render () {
|
||||
const { isUpdate, uri } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
{isUpdate && uri && (<p className='text--extra-small'>{`Editing ${uri}`}</p>)}
|
||||
<PublishTitleInput />
|
||||
</Row>
|
||||
<div className={'publish-form'}>
|
||||
<div className={'publish-form__title'}>
|
||||
<Row>
|
||||
{isUpdate && uri && (<p className='text--secondary'>{`Editing ${uri}`}</p>)}
|
||||
<PublishTitleInput />
|
||||
</Row>
|
||||
</div>
|
||||
<HorizontalSplit
|
||||
collapseOnMobile
|
||||
leftSide={<Dropzone />}
|
||||
rightSide={<PublishDetails />}
|
||||
/>
|
||||
|
|
|
@ -79,12 +79,12 @@ class AssetDisplay extends React.Component {
|
|||
</div>
|
||||
}
|
||||
{(status === AVAILABLE) &&
|
||||
<AvailableContent
|
||||
contentType={contentType}
|
||||
sourceUrl={sourceUrl}
|
||||
name={name}
|
||||
thumbnail={thumbnail}
|
||||
/>
|
||||
<AvailableContent
|
||||
contentType={contentType}
|
||||
sourceUrl={sourceUrl}
|
||||
name={name}
|
||||
thumbnail={thumbnail}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -6,10 +6,12 @@ import Row from '@components/Row';
|
|||
import SpaceBetween from '@components/SpaceBetween';
|
||||
import AssetShareButtons from '@components/AssetShareButtons';
|
||||
import ClickToCopy from '@components/ClickToCopy';
|
||||
import HorizontalSplit from '@components/HorizontalSplit';
|
||||
|
||||
import siteConfig from '@config/siteConfig.json';
|
||||
const { details: { host } } = siteConfig;
|
||||
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
||||
import AssetInfoFooter from '../../components/AssetInfoFooter/index';
|
||||
|
||||
class AssetInfo extends React.Component {
|
||||
render () {
|
||||
|
@ -29,137 +31,119 @@ class AssetInfo extends React.Component {
|
|||
channelCanonicalUrl = `${createCanonicalLink({channel})}`;
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{editable && (
|
||||
<Row>
|
||||
<RowLabeled
|
||||
label={<Label value={'Edit:'} />}
|
||||
content={<Link to={`/edit${canonicalUrl}`}>{name}</Link>}
|
||||
/>
|
||||
</Row>
|
||||
)}
|
||||
<div className='asset-info'>
|
||||
<HorizontalSplit
|
||||
leftSide={
|
||||
description && (
|
||||
<p className='asset-info__description'>{description}</p>
|
||||
)
|
||||
}
|
||||
rightSide={
|
||||
<div>
|
||||
{editable && (
|
||||
<RowLabeled
|
||||
label={<Label value={'Edit:'} />}
|
||||
content={<Link to={`/edit${canonicalUrl}`}>{name}</Link>}
|
||||
/>
|
||||
)}
|
||||
{channelName && (
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Channel'} />
|
||||
}
|
||||
content={
|
||||
<span className='text'>
|
||||
<Link className='link--primary' to={channelCanonicalUrl}>{channelName}</Link>
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{claimViews ? (
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Views'} />
|
||||
}
|
||||
content={
|
||||
<span className='text'>
|
||||
{claimViews}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{channelName && (
|
||||
<Row>
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Channel:'} />
|
||||
}
|
||||
content={
|
||||
<span className='text'>
|
||||
<Link to={channelCanonicalUrl}>{channelName}</Link>
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
</Row>
|
||||
)}
|
||||
|
||||
{claimViews ? (
|
||||
<Row>
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Views:'} />
|
||||
}
|
||||
content={
|
||||
<span className='text'>
|
||||
{claimViews}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
</Row>
|
||||
) : null}
|
||||
|
||||
<Row>
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Share:'} />
|
||||
}
|
||||
content={
|
||||
<AssetShareButtons
|
||||
name={name}
|
||||
assetUrl={assetCanonicalUrl}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Link:'} />
|
||||
}
|
||||
content={
|
||||
<ClickToCopy
|
||||
id={'short-link'}
|
||||
value={assetCanonicalUrl}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Embed:'} />
|
||||
}
|
||||
content={
|
||||
<div>
|
||||
{(contentType === 'video/mp4') ? (
|
||||
<ClickToCopy
|
||||
id={'embed-text-video'}
|
||||
value={`<iframe src="${host}/video-embed${canonicalUrl}" allowfullscreen="true" style="border:0" /></iframe>`}
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Share'} />
|
||||
}
|
||||
content={
|
||||
<AssetShareButtons
|
||||
name={name}
|
||||
assetUrl={assetCanonicalUrl}
|
||||
/>
|
||||
) : (
|
||||
}
|
||||
/>
|
||||
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Link'} />
|
||||
}
|
||||
content={
|
||||
<ClickToCopy
|
||||
id={'embed-text-image'}
|
||||
value={`<img src="${assetCanonicalUrl}.${fileExt}"/>`}
|
||||
id={'short-link'}
|
||||
value={assetCanonicalUrl}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</Row>
|
||||
}
|
||||
/>
|
||||
|
||||
<Row>
|
||||
<SpaceBetween>
|
||||
<a
|
||||
className='link--primary'
|
||||
href={`${assetCanonicalUrl}.${fileExt}`}
|
||||
>
|
||||
Direct Link
|
||||
</a>
|
||||
<a
|
||||
className={'link--primary'}
|
||||
href={`${assetCanonicalUrl}.${fileExt}`}
|
||||
download={name}
|
||||
>
|
||||
Download
|
||||
</a>
|
||||
<a
|
||||
className={'link--primary'}
|
||||
target='_blank'
|
||||
href='https://lbry.io/dmca'
|
||||
>
|
||||
Report
|
||||
</a>
|
||||
</SpaceBetween>
|
||||
</Row>
|
||||
|
||||
{description && (
|
||||
<Row>
|
||||
<p>{description}</p>
|
||||
</Row>
|
||||
)}
|
||||
|
||||
<Row>
|
||||
<p>
|
||||
Hosted via the <a className={'link--primary'} href={'https://lbry.io/get'} target={'_blank'}>LBRY</a> blockchain
|
||||
</p>
|
||||
</Row>
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Embed'} />
|
||||
}
|
||||
content={
|
||||
<div>
|
||||
{(contentType === 'video/mp4') ? (
|
||||
<ClickToCopy
|
||||
id={'embed-text-video'}
|
||||
value={`<iframe src="${host}/video-embed${canonicalUrl}" allowfullscreen="true" style="border:0" /></iframe>`}
|
||||
/>
|
||||
) : (
|
||||
<ClickToCopy
|
||||
id={'embed-text-image'}
|
||||
value={`<img src="${assetCanonicalUrl}.${fileExt}"/>`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
||||
<SpaceBetween>
|
||||
<a
|
||||
className='link--primary'
|
||||
href={`${assetCanonicalUrl}.${fileExt}`}
|
||||
>
|
||||
Direct Link
|
||||
</a>
|
||||
<a
|
||||
className={'link--primary'}
|
||||
href={`${assetCanonicalUrl}.${fileExt}`}
|
||||
download={name}
|
||||
>
|
||||
Download
|
||||
</a>
|
||||
<a
|
||||
className={'link--primary'}
|
||||
target='_blank'
|
||||
href='https://lbry.io/dmca'
|
||||
>
|
||||
Report
|
||||
</a>
|
||||
</SpaceBetween>
|
||||
</div>
|
||||
} />
|
||||
<AssetInfoFooter/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default AssetInfo;
|
||||
export default AssetInfo;
|
|
@ -1,12 +1,8 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Row from '@components/Row';
|
||||
|
||||
const AssetTitle = ({ title }) => {
|
||||
return (
|
||||
<Row>
|
||||
<h3>{title}</h3>
|
||||
</Row>
|
||||
<h1 className='asset-title'>{title}</h1>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class ChannelCreateForm extends React.Component {
|
|||
return (
|
||||
<div>
|
||||
{ !status ? (
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<form className="form-group" onSubmit={this.handleSubmit}>
|
||||
<ChannelCreateNameInput
|
||||
value={name.value}
|
||||
error={name.error}
|
||||
|
@ -69,10 +69,7 @@ class ChannelCreateForm extends React.Component {
|
|||
value={password.value}
|
||||
handlePasswordInput={this.handlePasswordInput}
|
||||
/>
|
||||
<FormFeedbackDisplay
|
||||
errorMessage={formError}
|
||||
defaultMessage={'Choose a name and password for your channel'}
|
||||
/>
|
||||
<FormFeedbackDisplay errorMessage={formError} />
|
||||
<ButtonPrimary
|
||||
type={'submit'}
|
||||
value={'Create Channel'}
|
||||
|
@ -81,7 +78,7 @@ class ChannelCreateForm extends React.Component {
|
|||
</form>
|
||||
) : (
|
||||
<div>
|
||||
<p className={'text--small text--secondary'}>{status}</p>
|
||||
<span className={'text--small text--secondary'}>{status}</span>
|
||||
<ProgressBar size={12} />
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -49,7 +49,7 @@ class ChannelLoginForm extends React.Component {
|
|||
}
|
||||
render () {
|
||||
return (
|
||||
<form onSubmit={this.loginToChannel}>
|
||||
<form className="form-group" onSubmit={this.loginToChannel}>
|
||||
<ChannelLoginNameInput
|
||||
channelName={this.state.channelName}
|
||||
handleInput={this.handleInput}
|
||||
|
@ -58,10 +58,7 @@ class ChannelLoginForm extends React.Component {
|
|||
channelPassword={this.state.channelPassword}
|
||||
handleInput={this.handleInput}
|
||||
/>
|
||||
<FormFeedbackDisplay
|
||||
errorMessage={this.state.error}
|
||||
defaultMessage={'Enter the name and password for your channel'}
|
||||
/>
|
||||
<FormFeedbackDisplay errorMessage={this.state.error} />
|
||||
<ButtonPrimary
|
||||
type={'submit'}
|
||||
value={'Authenticate'}
|
||||
|
|
|
@ -40,16 +40,16 @@ class ChannelSelect extends React.Component {
|
|||
const { publishInChannel, channelError, selectedChannel, loggedInChannelName, publishOnlyApproved } = this.props;
|
||||
if (publishOnlyApproved) {
|
||||
return (
|
||||
<div>
|
||||
<React.Fragment>
|
||||
<RowLabeled
|
||||
label={<Label value={'Channel:'} />}
|
||||
content={<span>{loggedInChannelName}</span>}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<React.Fragment>
|
||||
<RowLabeled
|
||||
label={
|
||||
<ChooseAnonymousPublishRadio
|
||||
|
@ -87,7 +87,7 @@ class ChannelSelect extends React.Component {
|
|||
{ (selectedChannel === CREATE) && <ChannelCreateForm /> }
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ class ChannelTools extends React.Component {
|
|||
render () {
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<h3>Log in to an existing channel:</h3>
|
||||
<ChannelLoginForm />
|
||||
</Row>
|
||||
{!this.props.closedRegistration && (<Row>
|
||||
<h3>Create a brand new channel:</h3>
|
||||
<ChannelCreateForm />
|
||||
</Row>)}
|
||||
<h3 className="form-title">Log in to existing channel</h3>
|
||||
<ChannelLoginForm />
|
||||
{!this.props.closedRegistration && (
|
||||
<React.Fragment>
|
||||
<h3 className="form-title">Create new channel</h3>
|
||||
<ChannelCreateForm />
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ class Dropzone extends React.Component {
|
|||
const { dragOver, mouseOver, dimPreview } = this.state;
|
||||
const { file, thumbnail, fileError, isUpdate, sourceUrl, fileExt } = this.props;
|
||||
return (
|
||||
<div className="dropzone-wrapper">
|
||||
<React.Fragment>
|
||||
{isUpdate && fileExt === 'mp4' ? (
|
||||
<p>Video updates are currently disabled. This feature will be available soon. You can edit metadata.</p>
|
||||
) : (
|
||||
|
@ -145,7 +145,7 @@ class Dropzone extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@ import Row from '@components/Row';
|
|||
import Label from '@components/Label';
|
||||
import RowLabeled from '@components/RowLabeled';
|
||||
import ButtonPrimaryJumbo from '@components/ButtonPrimaryJumbo';
|
||||
import ButtonTertiary from '@components/ButtonTertiary';
|
||||
import ButtonSecondary from '@components/ButtonSecondary';
|
||||
import SpaceAround from '@components/SpaceAround';
|
||||
import PublishFinePrint from '@components/PublishFinePrint';
|
||||
|
@ -46,7 +45,7 @@ class PublishDetails extends React.Component {
|
|||
return (
|
||||
<div>
|
||||
{isUpdate ? (asset && (
|
||||
<Row>
|
||||
<React.Fragment>
|
||||
<RowLabeled
|
||||
label={
|
||||
<Label value={'Channel:'} />
|
||||
|
@ -57,16 +56,14 @@ class PublishDetails extends React.Component {
|
|||
</span>
|
||||
}
|
||||
/>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)) : (
|
||||
<React.Fragment>
|
||||
<Row>
|
||||
<PublishUrlInput />
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<ChannelSelect />
|
||||
</Row>
|
||||
<ChannelSelect />
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
|
@ -100,7 +97,7 @@ class PublishDetails extends React.Component {
|
|||
|
||||
<Row>
|
||||
<SpaceAround>
|
||||
<ButtonTertiary
|
||||
<ButtonSecondary
|
||||
value={'Cancel'}
|
||||
onClickHandler={this.onCancel}
|
||||
/>
|
||||
|
|
|
@ -3,6 +3,7 @@ import PublishDescriptionInput from '@components/PublishDescriptionInput';
|
|||
import PublishLicenseInput from '@components/PublishLicenseInput';
|
||||
import PublishNsfwInput from '@components/PublishNsfwInput';
|
||||
import ButtonSecondary from '@components/ButtonSecondary';
|
||||
import Row from '@components/Row';
|
||||
|
||||
class PublishMetadataInputs extends React.Component {
|
||||
constructor (props) {
|
||||
|
@ -29,20 +30,20 @@ class PublishMetadataInputs extends React.Component {
|
|||
const { showMetadataInputs, description, isUpdate, nsfw } = this.props;
|
||||
return (
|
||||
<div>
|
||||
{(showMetadataInputs || isUpdate) && (
|
||||
<div>
|
||||
{(showMetadataInputs || isUpdate) && (
|
||||
<React.Fragment>
|
||||
<PublishDescriptionInput
|
||||
description={description}
|
||||
description={this.props.description}
|
||||
handleInput={this.handleInput}
|
||||
/>
|
||||
<PublishLicenseInput
|
||||
handleSelect={this.handleSelect}
|
||||
/>
|
||||
<PublishNsfwInput
|
||||
nsfw={nsfw}
|
||||
nsfw={this.props.nsfw}
|
||||
handleInput={this.handleInput}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{!isUpdate && (
|
||||
<ButtonSecondary
|
||||
|
|
|
@ -126,7 +126,7 @@ class PublishThumbnailInput extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className={'text--small text--secondary'}>loading... </p>
|
||||
<span className={'text--small text--secondary'}>loading... </span>
|
||||
)
|
||||
}
|
||||
<FormFeedbackDisplay
|
||||
|
|
|
@ -13,6 +13,7 @@ class AboutPage extends React.Component {
|
|||
pageUri={'about'}
|
||||
>
|
||||
<HorizontalSplit
|
||||
collapseOnMobile
|
||||
leftSide={<AboutSpeechOverview />}
|
||||
rightSide={<AboutSpeechDetails />}
|
||||
/>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue