Publish api fix #191
|
@ -43,5 +43,7 @@ module.exports = {
|
|||
} else {
|
||||
return error;
|
||||
}
|
||||
useObjectPropertiesIfNoKeys (err) {
|
||||
return useObjectPropertiesIfNoKeys(err);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ module.exports = new PassportLocalStrategy(
|
|||
},
|
||||
(req, username, password, done) => {
|
||||
logger.debug(`verifying loggin attempt ${username} ${password}`);
|
||||
let userInfo = {};
|
||||
return db.User
|
||||
.findOne({where: {userName: username}})
|
||||
.then(user => {
|
||||
|
@ -23,9 +24,18 @@ module.exports = new PassportLocalStrategy(
|
|||
return done(null, false, {message: 'Incorrect username or password.'});
|
||||
}
|
||||
logger.debug('user found:', user.dataValues);
|
||||
return user.getChannel().then(channel => {
|
||||
return done(null, user);
|
||||
});
|
||||
userInfo['id'] = user.id;
|
||||
userInfo['userName'] = user.userName;
|
||||
return user.getChannel();
|
||||
})
|
||||
.then(channel => {
|
||||
userInfo['channelName'] = channel.channelName;
|
||||
userInfo['channelClaimId'] = channel.channelClaimId;
|
||||
return db.getShortChannelIdFromLongChannelId(channel.channelClaimId, channel.channelName);
|
||||
})
|
||||
.then(shortChannelId => {
|
||||
userInfo['shortChannelId'] = shortChannelId;
|
||||
return done(null, userInfo);
|
||||
})
|
||||
.catch(error => {
|
||||
return done(error);
|
||||
|
|
|
@ -11,7 +11,7 @@ module.exports = new PassportLocalStrategy(
|
|||
passReqToCallback: true, // we want to be able to read the post body message parameters in the callback
|
||||
},
|
||||
(req, username, password, done) => {
|
||||
logger.debug(`new channel signup request: ${username} ${password}`);
|
||||
logger.debug(`new channel signup request. user: ${username} pass: ${password} .`);
|
||||
let user;
|
||||
// server-side validaton of inputs (username, password)
|
||||
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
|
||||
/* GENERAL */
|
||||
|
||||
|
||||
/* TEXT */
|
||||
|
||||
body, button, input, textarea, label, select, option {
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
p {
|
||||
padding-left: 0.3em;
|
||||
}
|
||||
|
||||
.center-text {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.url-text {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
/* HEADERS */
|
||||
|
||||
h1 {
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: medium;
|
||||
margin-top: 1em;
|
||||
border-top: 1px #999 solid;
|
||||
background-color: lightgray;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: black;;
|
||||
}
|
||||
|
||||
.h3--secondary {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
h4 {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
/* CONTAINERS */
|
||||
|
||||
.wrapper {
|
||||
margin-left: 20%;
|
||||
width:60%;
|
||||
}
|
||||
|
||||
.full {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.main {
|
||||
float: left;
|
||||
width: 65%;
|
||||
|
||||
}
|
||||
|
||||
.panel {
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
float: right;
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
margin-bottom: 2px;
|
||||
padding-bottom: 2px;
|
||||
border-bottom: 1px lightgrey solid;
|
||||
margin-top: 2px;
|
||||
padding-top: 2px;
|
||||
border-top: 1px lightgrey solid;
|
||||
text-align: center;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
/* COLUMNS AND ROWS */
|
||||
|
||||
.col-left, .col-right {
|
||||
overflow: auto;
|
||||
margin: 0px;
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
.col-left {
|
||||
padding: 5px 10px 5px 0px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.col-right {
|
||||
padding: 5px 0px 5px 10px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 1em 2% 1em 2%;
|
||||
margin: 0px;
|
||||
|
||||
}
|
||||
|
||||
.row--wide {
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.row--thin {
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
margin: 2em 0px 2px 0px;
|
||||
padding: 0px 0px 2px 0px;
|
||||
border-bottom: 1px lightgrey solid;
|
||||
overflow: auto;
|
||||
text-align: right;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
|
||||
.column {
|
||||
display: inline-block;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.column--1 {
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
.column--2 {
|
||||
width: 16%;
|
||||
}
|
||||
|
||||
.column--3 {
|
||||
width: 24%;
|
||||
}
|
||||
|
||||
.column--4 {
|
||||
width: 32%;
|
||||
}
|
||||
|
||||
.column--5 {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.column--6 {
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
.column--7 {
|
||||
width: 56%;
|
||||
}
|
||||
|
||||
.column--8 {
|
||||
width: 64%;
|
||||
}
|
||||
|
||||
.column--9 {
|
||||
width: 72%;
|
||||
}
|
||||
|
||||
.column--10 {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.column--11 {
|
||||
width: 88%;
|
||||
}
|
||||
|
||||
.column--12 {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
/* LINKS */
|
||||
|
||||
a, a:visited {
|
||||
color: blue;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ERROR MESSAGES */
|
||||
|
||||
.info-message {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info-message--success {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.info-message--failure {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* INPUT FIELDS */
|
||||
|
||||
input:-webkit-autofill {
|
||||
-webkit-box-shadow: 0 0 0px 1000px white inset;
|
||||
}
|
||||
|
||||
.label, .input-text, .select, .textarea {
|
||||
font-size: medium;
|
||||
padding: 0.3em;
|
||||
outline: none;
|
||||
border: 0px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.input-text--primary, .select--primary, .textarea--primary {
|
||||
border-bottom: 1px solid blue;
|
||||
}
|
||||
|
||||
.input-text--primary:focus, .select--primary:focus, .textarea--primary:focus {
|
||||
border-bottom: 1px solid grey;
|
||||
}
|
||||
|
||||
.input-checkbox, .input-textarea {
|
||||
border: 1px solid grey;
|
||||
}
|
||||
|
||||
/* BUTTONS */
|
||||
|
||||
button {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin: 0.5em 0.3em 0.5em 0.3em;
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border: 1px solid blue;
|
||||
color: white;
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
button:active{
|
||||
border: 1px solid blue;
|
||||
color: white;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* TABLES */
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* other */
|
||||
|
||||
.stop-float {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.toggle-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.wrap-words {
|
||||
word-wrap: break-word;
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
|
||||
/* top bar */
|
||||
#logo, #title {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#logo {
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
#title {
|
||||
margin: 2px 5px 2px 5px;
|
||||
}
|
||||
|
||||
.top-bar-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.top-bar-tagline {
|
||||
font-style: italic;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.top-bar-right {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
/* publish */
|
||||
#drop-zone {
|
||||
border: 1px dashed lightgrey;
|
||||
padding: 1em;
|
||||
height: 13em;
|
||||
background: #F5F0EF;
|
||||
}
|
||||
|
||||
#asset-preview-holder {
|
||||
width: 100%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
/* show routes */
|
||||
.show-asset {
|
||||
width: 100%;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.show-asset-lite {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.panel.links {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
input.link {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
button.copy-button {
|
||||
padding: 4px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.share-option {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.metadata-table {
|
||||
font-size: small;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.metadata-row {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
width: 30%;
|
||||
font-weight: bold;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* trending claims */
|
||||
.grid-item {
|
||||
width: 23%;
|
||||
margin: 0px 1% 20px 1%;
|
||||
}
|
||||
|
||||
/* learn more */
|
||||
.learn-more {
|
||||
text-align: center;
|
||||
border-top: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
/* examples */
|
||||
.example {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.example-image, .example-code {
|
||||
float: left;
|
||||
margin: 2%;
|
||||
}
|
||||
|
||||
.example-image {
|
||||
width: 21%;
|
||||
}
|
||||
|
||||
.example-code {
|
||||
float: right;
|
||||
padding: 4%;
|
||||
width: 62%;
|
||||
background-color: lightgrey;
|
||||
font-family: monospace;
|
||||
color: #666;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* contribute */
|
||||
#github-logo {
|
||||
float: right;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
/* content lists */
|
||||
.content-list-card {
|
||||
margin-top: 2px;
|
||||
padding-top: 2px;
|
||||
border-top: 1px lightgrey solid;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content-list-card-link {
|
||||
position:absolute;
|
||||
width:100%;
|
||||
height:100%;
|
||||
top:0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.content-list-asset {
|
||||
width: 20%;
|
||||
float: left;
|
||||
margin: 5px 30px 5px 0px;
|
||||
}
|
||||
|
||||
.content-list-title {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.content-list-details {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.content-list-details > ul {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
list-style: none;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.content-list-card:hover {
|
||||
background-color: #F5F0EF;
|
||||
}
|
||||
|
||||
/* statistics */
|
||||
.totals-row {
|
||||
border-top: 1px solid grey;
|
||||
border-bottom: 1px solid grey;
|
||||
font-weight: bold;
|
||||
}
|
||||
.stats-table-url {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
|
516
public/assets/css/general.css
Normal file
|
@ -0,0 +1,516 @@
|
|||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
/* TEXT */
|
||||
|
||||
body, button, input, textarea, label, select, option {
|
||||
font-family: monospace;
|
||||
font-size: large;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
p {
|
||||
padding-left: 0.3em;
|
||||
}
|
||||
|
||||
.center-text {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.url-text {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.url-text--primary {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.url-text--secondary {
|
||||
color: lightgrey;
|
||||
}
|
||||
|
||||
.pull-quote {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
/* TOOL TIPS */
|
||||
/* Tooltip container */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
}
|
||||
/* Tooltip text */
|
||||
.tooltip > .tooltip-text {
|
||||
visibility: hidden;
|
||||
width: 15em;
|
||||
background-color: dodgerblue;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 0.5em;
|
||||
/* Position the tooltip text */
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 110%;
|
||||
left: 50%;
|
||||
margin-left: -8em; /* Use half of the width (120/2 = 60), to center the tooltip */
|
||||
}
|
||||
/* Show the tooltip text when you mouse over the tooltip container */
|
||||
.tooltip:hover > .tooltip-text {
|
||||
visibility: visible;
|
||||
}
|
||||
/* arrow at bottom of tooltip text */
|
||||
.tooltip > .tooltip-text::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: dodgerblue transparent transparent transparent;
|
||||
}
|
||||
|
||||
/* LINKS */
|
||||
|
||||
a, a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* HEADERS */
|
||||
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.h2--secondary {
|
||||
font-weight: normal;
|
||||
color: lightgrey;
|
||||
}
|
||||
|
||||
.h2--top {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* COLUMNS AND ROWS */
|
||||
|
||||
.row {
|
||||
clear: both;
|
||||
padding: 2rem 2rem 2rem 2rem;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.row--wide {
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.row--short {
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.row--full-height {
|
||||
height: calc(100% - 9rem);
|
||||
}
|
||||
|
||||
.column {
|
||||
display: inline-block;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.column--1 {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.column--2 {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.column--3 {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.column--4 {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.column--5 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.column--6 {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.column--7 {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.column--8 {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.column--9 {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.column--10 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ALIGNMENT */
|
||||
.align-content-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-content-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-content-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.align-content-top {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.align-content-right {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
/* ERROR MESSAGES */
|
||||
|
||||
.info-message {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info-message--success {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.info-message--failure {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* INPUT FIELDS */
|
||||
|
||||
/* blocks */
|
||||
input:-webkit-autofill {
|
||||
-webkit-box-shadow: 0 0 0px 1000px white inset;
|
||||
}
|
||||
|
||||
.label, .input-text, .select, .textarea {
|
||||
margin: 0px;
|
||||
padding: 0.3em;
|
||||
outline: none;
|
||||
border: 0px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.input-disabled {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin: 0px;
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
option {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
|
||||
.input-checkbox {
|
||||
border: 1px solid grey;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.input-file {
|
||||
width: 0.1px;
|
||||
height: 0.1px;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.input-file-label {
|
||||
color: dodgerblue;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select--no-arrow {
|
||||
-moz-appearance:none;
|
||||
-webkit-appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select--arrow {
|
||||
-moz-appearance:none;
|
||||
-webkit-appearance: none;
|
||||
background: url('../img/down_triangle.png') no-repeat right;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
/* modifiers */
|
||||
.input-text--primary, .select--primary, .textarea--primary {
|
||||
border-bottom: 1px solid dodgerblue;
|
||||
}
|
||||
|
||||
.input-text--primary:focus, .select--primary:focus, .textarea--primary:focus {
|
||||
border-bottom: 1px solid dodgerblue;
|
||||
}
|
||||
|
||||
.input-text--large, .select--large, .textarea--large {
|
||||
font-size: 1.5rem;
|
||||
border-left: 1px solid dodgerblue;
|
||||
}
|
||||
|
||||
.input-text--large:focus, .select--large:focus, .textarea--large:focus {
|
||||
border-left: 1px solid dodgerblue;
|
||||
}
|
||||
|
||||
.input-text--full-width, .textarea--full-width {
|
||||
width: calc(100% - 0.6em);
|
||||
}
|
||||
|
||||
.input-disabled--full-width {
|
||||
width: calc(100% - 1em - 2px);
|
||||
}
|
||||
|
||||
/* BUTTONS */
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button--primary {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin: 0.5em 0.3em 0.5em 0.3em;
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.button--primary:hover {
|
||||
border: 1px solid dodgerblue;
|
||||
color: white;
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
.button--primary:active{
|
||||
border: 1px solid dodgerblue;
|
||||
color: white;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.button--large{
|
||||
margin: 0px;
|
||||
width: calc(100% - 2px);
|
||||
padding: 2rem;
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
.button--cancel{
|
||||
border: 0px;
|
||||
background-color: white;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
/* TABLES */
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* NAV BAR */
|
||||
|
||||
.nav-bar {
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
.nav-bar-title-section, .nav-bar-link-section {
|
||||
padding: 0px 1em 0px 1em;
|
||||
}
|
||||
|
||||
.nav-bar-title-section {
|
||||
overflow: hidden;
|
||||
border-bottom: 2px solid #eaeaea;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-bar-link-section {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.nav-bar-logo, .nav-bar-title, .nav-bar-link {
|
||||
padding: 2rem 0.5rem 1.5rem 0.5rem;
|
||||
display: inline-block;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.nav-bar-title--superscript {
|
||||
font-size: small;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.nav-bar-link {
|
||||
border-bottom: 2px solid white;
|
||||
}
|
||||
.nav-bar-link--active {
|
||||
color: #1e90ff;
|
||||
border-bottom: 2px solid #1e90ff;
|
||||
}
|
||||
|
||||
/* PUBLISH FORM */
|
||||
|
||||
.dropzone {
|
||||
border: 2px dashed lightgrey;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dropzone:hover {
|
||||
border: 2px dashed #1e90ff;
|
||||
}
|
||||
|
||||
#primary-dropzone-wrapper, #publish-form-wrapper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#primary-dropzone {
|
||||
height: calc(100% - 4px);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#asset-preview-holder {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#primary-dropzone-instructions, #preview-dropzone-instructions {
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-40%);
|
||||
}
|
||||
|
||||
#asset-preview {
|
||||
display: block;
|
||||
padding: 0.5rem;
|
||||
width: calc(100% - 1rem);
|
||||
}
|
||||
|
||||
/* Show page */
|
||||
|
||||
.asset-display {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* item lists */
|
||||
|
||||
.content-list-item {
|
||||
|
||||
}
|
||||
|
||||
.content-list-item-asset {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.content-list-item-link {
|
||||
|
||||
}
|
||||
|
||||
/* other */
|
||||
|
||||
.toggle-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.wrap-words {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Social Sharing Icons */
|
||||
|
||||
.button {
|
||||
margin-right: 10px;
|
||||
max-width: 100px;
|
||||
display: inline;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
a.reddit-share.button img {
|
||||
width: 38px;
|
||||
height: 38px;}
|
||||
|
||||
.row--short img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.row--short img:hover {
|
||||
-webkit-animation: animation 20000ms linear both;
|
||||
animation: animation 20000ms linear both;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animation {
|
||||
0% { -webkit-transform: matrix3d(-0.5, -0.866, 0, 0, 0.866, -0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.5, -0.866, 0, 0, 0.866, -0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.16% { -webkit-transform: matrix3d(-0.493, -0.875, 0, 0, 0.769, -0.646, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.493, -0.875, 0, 0, 0.769, -0.646, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.32% { -webkit-transform: matrix3d(-0.546, -0.846, 0, 0, 0.699, -0.724, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.546, -0.846, 0, 0, 0.699, -0.724, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.64% { -webkit-transform: matrix3d(-0.703, -0.715, 0, 0, 0.603, -0.801, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.703, -0.715, 0, 0, 0.603, -0.801, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.95% { -webkit-transform: matrix3d(-0.836, -0.55, 0, 0, 0.509, -0.861, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.836, -0.55, 0, 0, 0.509, -0.861, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
1.26% { -webkit-transform: matrix3d(-0.924, -0.383, 0, 0, 0.384, -0.923, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.924, -0.383, 0, 0, 0.384, -0.923, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
1.57% { -webkit-transform: matrix3d(-0.974, -0.225, 0, 0, 0.236, -0.972, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.974, -0.225, 0, 0, 0.236, -0.972, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
2.82% { -webkit-transform: matrix3d(-0.919, 0.394, 0, 0, -0.394, -0.919, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.919, 0.394, 0, 0, -0.394, -0.919, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
4.07% { -webkit-transform: matrix3d(-0.538, 0.843, 0, 0, -0.843, -0.538, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.538, 0.843, 0, 0, -0.843, -0.538, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
4.3% { -webkit-transform: matrix3d(-0.447, 0.894, 0, 0, -0.894, -0.447, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.447, 0.894, 0, 0, -0.894, -0.447, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
5% { -webkit-transform: matrix3d(-0.161, 0.987, 0, 0, -0.987, -0.161, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.161, 0.987, 0, 0, -0.987, -0.161, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
8.61% { -webkit-transform: matrix3d(0.873, 0.487, 0, 0, -0.487, 0.873, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.873, 0.487, 0, 0, -0.487, 0.873, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
12.91% { -webkit-transform: matrix3d(0.976, -0.217, 0, 0, 0.217, 0.976, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.976, -0.217, 0, 0, 0.217, 0.976, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
17.22% { -webkit-transform: matrix3d(0.925, -0.381, 0, 0, 0.381, 0.925, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.925, -0.381, 0, 0, 0.381, 0.925, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
28.33% { -webkit-transform: matrix3d(0.996, -0.086, 0, 0, 0.086, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.996, -0.086, 0, 0, 0.086, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
39.44% { -webkit-transform: matrix3d(1, 0.026, 0, 0, -0.026, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0.026, 0, 0, -0.026, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
61.66% { -webkit-transform: matrix3d(1, -0.002, 0, 0, 0.002, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, -0.002, 0, 0, 0.002, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
83.98% { -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
100% { -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
}
|
||||
|
||||
@keyframes animation {
|
||||
0% { -webkit-transform: matrix3d(-0.5, -0.866, 0, 0, 0.866, -0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.5, -0.866, 0, 0, 0.866, -0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.16% { -webkit-transform: matrix3d(-0.493, -0.875, 0, 0, 0.769, -0.646, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.493, -0.875, 0, 0, 0.769, -0.646, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.32% { -webkit-transform: matrix3d(-0.546, -0.846, 0, 0, 0.699, -0.724, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.546, -0.846, 0, 0, 0.699, -0.724, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.64% { -webkit-transform: matrix3d(-0.703, -0.715, 0, 0, 0.603, -0.801, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.703, -0.715, 0, 0, 0.603, -0.801, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
0.95% { -webkit-transform: matrix3d(-0.836, -0.55, 0, 0, 0.509, -0.861, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.836, -0.55, 0, 0, 0.509, -0.861, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
1.26% { -webkit-transform: matrix3d(-0.924, -0.383, 0, 0, 0.384, -0.923, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.924, -0.383, 0, 0, 0.384, -0.923, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
1.57% { -webkit-transform: matrix3d(-0.974, -0.225, 0, 0, 0.236, -0.972, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.974, -0.225, 0, 0, 0.236, -0.972, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
2.82% { -webkit-transform: matrix3d(-0.919, 0.394, 0, 0, -0.394, -0.919, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.919, 0.394, 0, 0, -0.394, -0.919, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
4.07% { -webkit-transform: matrix3d(-0.538, 0.843, 0, 0, -0.843, -0.538, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.538, 0.843, 0, 0, -0.843, -0.538, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
4.3% { -webkit-transform: matrix3d(-0.447, 0.894, 0, 0, -0.894, -0.447, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.447, 0.894, 0, 0, -0.894, -0.447, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
5% { -webkit-transform: matrix3d(-0.161, 0.987, 0, 0, -0.987, -0.161, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(-0.161, 0.987, 0, 0, -0.987, -0.161, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
8.61% { -webkit-transform: matrix3d(0.873, 0.487, 0, 0, -0.487, 0.873, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.873, 0.487, 0, 0, -0.487, 0.873, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
12.91% { -webkit-transform: matrix3d(0.976, -0.217, 0, 0, 0.217, 0.976, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.976, -0.217, 0, 0, 0.217, 0.976, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
17.22% { -webkit-transform: matrix3d(0.925, -0.381, 0, 0, 0.381, 0.925, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.925, -0.381, 0, 0, 0.381, 0.925, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
28.33% { -webkit-transform: matrix3d(0.996, -0.086, 0, 0, 0.086, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.996, -0.086, 0, 0, 0.086, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
39.44% { -webkit-transform: matrix3d(1, 0.026, 0, 0, -0.026, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0.026, 0, 0, -0.026, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
61.66% { -webkit-transform: matrix3d(1, -0.002, 0, 0, 0.002, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, -0.002, 0, 0, 0.002, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
83.98% { -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
100% { -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
|
||||
}
|
|
@ -1,15 +1,5 @@
|
|||
@media (max-width: 1250px) {
|
||||
.wrapper {
|
||||
margin-left: 10%;
|
||||
width:80%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.wrapper {
|
||||
margin-left: 10%;
|
||||
width:80%;
|
||||
}
|
||||
|
||||
.main {
|
||||
float: none;
|
||||
|
@ -28,32 +18,50 @@
|
|||
}
|
||||
|
||||
@media (max-width: 750px ) {
|
||||
.col-left, .col-right {
|
||||
float: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
|
||||
.column--med-10 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.col-right {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.all-claims-asset {
|
||||
width:30%;
|
||||
}
|
||||
|
||||
.all-claims-details {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.show-asset-lite {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.top-bar-tagline {
|
||||
clear: both;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
.h2--top {
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 475px) {
|
||||
|
||||
.nav-bar {
|
||||
height: 8rem;
|
||||
}
|
||||
|
||||
.nav-bar-title {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.nav-bar-link-section {
|
||||
position: relative;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.row--full-height {
|
||||
|
||||
height: calc(100% - 11rem);
|
||||
}
|
||||
|
||||
.column--sml-10 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#publish-active-area > .row, #details-detail > .row, #channel-login-form > .row, #publish-channel-form > .row {
|
||||
padding: 1em 0px 1em 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 350px) {
|
||||
|
||||
body, button, input, textarea, label, select, option {
|
||||
font-size: medium;
|
||||
}
|
||||
|
||||
}
|
BIN
public/assets/img/black_video_play.jpg
Normal file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
BIN
public/assets/img/down_triangle.png
Normal file
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 184 B |
BIN
public/assets/img/upload_arrow.png
Normal file
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 195 B |
|
@ -6,10 +6,10 @@ function getRequest (url) {
|
|||
xhttp.responseType = 'json';
|
||||
xhttp.onreadystatechange = () => {
|
||||
if (xhttp.readyState == 4 ) {
|
||||
console.log(xhttp);
|
||||
if ( xhttp.status == 200) {
|
||||
console.log('response:', xhttp.response);
|
||||
resolve(xhttp.response);
|
||||
} else if (xhttp.status == 401) {
|
||||
reject('wrong username or password');
|
||||
} else {
|
||||
reject('request failed with status:' + xhttp.status);
|
||||
};
|
||||
|
@ -28,10 +28,10 @@ function postRequest (url, params) {
|
|||
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhttp.onreadystatechange = () => {
|
||||
if (xhttp.readyState == 4 ) {
|
||||
console.log(xhttp);
|
||||
if ( xhttp.status == 200) {
|
||||
console.log('response:', xhttp.response);
|
||||
resolve(xhttp.response);
|
||||
} else if (xhttp.status == 401) {
|
||||
reject('wrong username or password');
|
||||
} else {
|
||||
reject('request failed with status:' + xhttp.status);
|
||||
};
|
||||
|
@ -80,6 +80,31 @@ function createProgressBar(element, size){
|
|||
setInterval(addOne, 300);
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
const name = cname + "=";
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function checkCookie() {
|
||||
const channelName = getCookie("channel_name");
|
||||
if (channelName != "") {
|
||||
console.log(`cookie found for ${channelName}`);
|
||||
} else {
|
||||
console.log('no channel_name cookie found');
|
||||
}
|
||||
}
|
||||
|
||||
// Create new error objects, that prototypically inherit from the Error constructor
|
||||
function FileError(message) {
|
||||
this.name = 'FileError';
|
||||
|
|
|
@ -1,62 +1,43 @@
|
|||
/* drop zone functions */
|
||||
|
||||
function drop_handler(ev) {
|
||||
ev.preventDefault();
|
||||
// if dropped items aren't files, reject them
|
||||
var dt = ev.dataTransfer;
|
||||
if (dt.items) {
|
||||
if (dt.items[0].kind == 'file') {
|
||||
var droppedFile = dt.items[0].getAsFile();
|
||||
previewAndStageFile(droppedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dragover_handler(ev) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
function dragend_handler(ev) {
|
||||
var dt = ev.dataTransfer;
|
||||
if (dt.items) {
|
||||
for (var i = 0; i < dt.items.length; i++) {
|
||||
dt.items.remove(i);
|
||||
}
|
||||
} else {
|
||||
ev.dataTransfer.clearData();
|
||||
}
|
||||
}
|
||||
|
||||
/* publish functions */
|
||||
|
||||
// update the publish status
|
||||
function updatePublishStatus(msg){
|
||||
document.getElementById('publish-status').innerHTML = msg;
|
||||
function cancelPublish () {
|
||||
window.location.href = '/';
|
||||
}
|
||||
|
||||
// When a file is selected for publish, validate that file and
|
||||
// stage it so it will be ready when the publish button is clicked.
|
||||
function previewAndStageFile(selectedFile){
|
||||
var previewHolder = document.getElementById('asset-preview-holder');
|
||||
var dropzone = document.getElementById('drop-zone');
|
||||
var previewReader = new FileReader();
|
||||
var nameInput = document.getElementById('claim-name-input');
|
||||
const publishForm = document.getElementById('publish-form-wrapper');
|
||||
const assetPreview = document.getElementById('asset-preview-target');
|
||||
const primaryDropzone = document.getElementById('primary-dropzone-wrapper');
|
||||
const previewReader = new FileReader();
|
||||
const nameInput = document.getElementById('claim-name-input');
|
||||
const fileSelectionError = document.getElementById('input-error-file-selection');
|
||||
// validate the file's name, type, and size
|
||||
try {
|
||||
console.log('validating file');
|
||||
validateFile(selectedFile);
|
||||
} catch (error) {
|
||||
showError('input-error-file-selection', error.message);
|
||||
console.log('file validation failed with error:', error);
|
||||
showError(fileSelectionError, error.message);
|
||||
return;
|
||||
}
|
||||
// set the image preview, if an image was provided
|
||||
if (selectedFile.type !== 'video/mp4') {
|
||||
console.log('file type:', selectedFile.type)
|
||||
if (selectedFile.type !== 'video/mp4') {
|
||||
if (selectedFile.type === 'image/gif') {
|
||||
assetPreview.innerHTML = `<h2>loading preview...</h2>`
|
||||
}
|
||||
previewReader.readAsDataURL(selectedFile);
|
||||
previewReader.onloadend = function () {
|
||||
dropzone.style.display = 'none';
|
||||
previewHolder.style.display = 'block';
|
||||
previewHolder.innerHTML = '<img width="100%" src="' + previewReader.result + '" alt="image preview"/>';
|
||||
assetPreview.innerHTML = '<img id="asset-preview" src="' + previewReader.result + '" alt="image preview"/>';
|
||||
};
|
||||
} else {
|
||||
assetPreview.innerHTML = `<img id="asset-preview" src="/assets/img/black_video_play.jpg"/>`
|
||||
}
|
||||
// hide the drop zone
|
||||
primaryDropzone.hidden = true;
|
||||
publishForm.hidden = false;
|
||||
// set the name input value to the image name if none is set yet
|
||||
if (nameInput.value === "") {
|
||||
var filename = selectedFile.name.substring(0, selectedFile.name.indexOf('.'))
|
||||
|
@ -68,11 +49,29 @@ function previewAndStageFile(selectedFile){
|
|||
}
|
||||
|
||||
// Validate the publish submission and then trigger publishing.
|
||||
function publishSelectedImage(event) {
|
||||
var claimName = document.getElementById('claim-name-input').value;
|
||||
var channelName = document.getElementById('channel-name-select').value;
|
||||
function publishStagedFile(event) {
|
||||
// prevent default so this script can handle submission
|
||||
event.preventDefault();
|
||||
// declare variables
|
||||
const claimName = document.getElementById('claim-name-input').value;
|
||||
let channelName = document.getElementById('channel-name-select').value;
|
||||
const fileSelectionError = document.getElementById('input-error-file-selection');
|
||||
const claimNameError = document.getElementById('input-error-claim-name');
|
||||
const channelSelectError = document.getElementById('input-error-channel-select');
|
||||
const publishSubmitError = document.getElementById('input-error-publish-submit');
|
||||
let anonymousOrInChannel;
|
||||
// replace channelName with 'anonymous' if needed
|
||||
const radios = document.getElementsByName('anonymous-or-channel');
|
||||
for (let i = 0; i < radios.length; i++) {
|
||||
if (radios[i].checked) {
|
||||
// do whatever you want with the checked radio
|
||||
anonymousOrInChannel = radios[i].value;
|
||||
// only one radio can be logically checked, don't check the rest
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (anonymousOrInChannel === 'anonymous') {channelName = 'anonymous'};
|
||||
console.log('channel name:', channelName);
|
||||
// validate, submit, and handle response
|
||||
validateFilePublishSubmission(stagedFiles, claimName, channelName)
|
||||
.then(() => {
|
||||
|
@ -80,14 +79,14 @@ function publishSelectedImage(event) {
|
|||
})
|
||||
.catch(error => {
|
||||
if (error.name === 'FileError') {
|
||||
showError(document.getElementById('input-error-file-selection'), error.message);
|
||||
showError(fileSelectionError, error.message);
|
||||
} else if (error.name === 'NameError') {
|
||||
showError(document.getElementById('input-error-claim-name'), error.message);
|
||||
showError(claimNameError, error.message);
|
||||
} else if (error.name === 'ChannelNameError'){
|
||||
console.log(error);
|
||||
showError(document.getElementById('input-error-channel-select'), error.message);
|
||||
showError(channelSelectError, error.message);
|
||||
} else {
|
||||
showError(document.getElementById('input-error-publish-submit'), error.message);
|
||||
showError(publishSubmitError, error.message);
|
||||
}
|
||||
return;
|
||||
})
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
// validation function which checks the proposed file's type, size, and name
|
||||
function validateFile(file) {
|
||||
if (!file) {
|
||||
|
|
|
@ -9,7 +9,13 @@ module.exports = (app) => {
|
|||
});
|
||||
// route for log in
|
||||
app.post('/login', passport.authenticate('local-login'), (req, res) => {
|
||||
logger.debug(req.user);
|
||||
logger.debug('successful login');
|
||||
res.status(200).json(true);
|
||||
res.status(200).json({
|
||||
success : true,
|
||||
channelName : req.user.channelName,
|
||||
channelClaimId: req.user.channelClaimId,
|
||||
shortChannelId: req.user.shortChannelId,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ module.exports = (app) => {
|
|||
getTrendingClaims(dateTime)
|
||||
.then(result => {
|
||||
// logger.debug(result);
|
||||
res.status(200).render('trending', {
|
||||
res.status(200).render('popular', {
|
||||
trendingAssets: result,
|
||||
});
|
||||
})
|
||||
|
|
|
@ -48,17 +48,17 @@ module.exports = (app, siofu, hostedContentPath) => {
|
|||
// publish the file
|
||||
publish(publishParams, file.name, file.meta.type)
|
||||
.then(result => {
|
||||
postToStats('PUBLISH', '/', null, null, null, 'success');
|
||||
socket.emit('publish-complete', { name: publishParams.name, result });
|
||||
postToStats('PUBLISH', '/', null, null, null, 'success');
|
||||
})
|
||||
.catch(error => {
|
||||
error = errorHandlers.handlePublishError(error);
|
||||
postToStats('PUBLISH', '/', null, null, null, error);
|
||||
socket.emit('publish-failure', error);
|
||||
logger.error('Publish Error:', useObjectPropertiesIfNoKeys(error));
|
||||
postToStats('PUBLISH', '/', null, null, null, error);
|
||||
});
|
||||
} else {
|
||||
logger.error(`An error occurred in uploading the client's file`);
|
||||
socket.emit('publish-failure', 'File uploaded, but with errors');
|
||||
logger.error(`An error occurred in uploading the client's file`);
|
||||
postToStats('PUBLISH', '/', null, null, null, 'File uploaded, but with errors');
|
||||
// to-do: remove the file, if not done automatically
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ passport.deserializeUser((id, done) => { // this populates req.user
|
|||
.then(shortChannelId => {
|
||||
userInfo['shortChannelId'] = shortChannelId;
|
||||
done(null, userInfo);
|
||||
return null;
|
||||
return null; // note: why return null and not the done?
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('sequelize error', error);
|
||||
|
@ -85,7 +85,7 @@ app.set('view engine', 'handlebars');
|
|||
// middleware to pass user info back to client (for handlebars access), if user is logged in
|
||||
app.use((req, res, next) => {
|
||||
if (req.user) {
|
||||
logger.verbose(req.user);
|
||||
// logger.verbose(req.user);
|
||||
res.locals.user = {
|
||||
id : req.user.id,
|
||||
userName : req.user.userName,
|
||||
|
|
|
@ -1,17 +1,31 @@
|
|||
<div class="wrapper">
|
||||
{{> topBar}}
|
||||
<div class="main">
|
||||
<h2>About Spee.ch</h2>
|
||||
<p>Spee.ch is a single-serving site that reads and publishes images to and from the <a class="white-text" href="https://lbry.io">LBRY</a> blockchain.</p>
|
||||
<p>Spee.ch is an image hosting service, but with the added benefit that it stores your images on a decentralized network of computers -- the LBRY network. This means that your images are stored in multiple locations without a single point of failure.</p>
|
||||
{{> examples}}
|
||||
{{> documentation}}
|
||||
{{> bugs}}
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
{{> contribute}}
|
||||
</div>
|
||||
{{> footer}}
|
||||
</div>
|
||||
<div class="row row--full-height">
|
||||
<div class="column column--5 column--med-10 align-content-top">
|
||||
<div class="row row--short">
|
||||
<span class="pull-quote">Open-source, decentralized image and video hosting</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<p>
|
||||
<a href="#">GITHUB</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="#">SLACK CHANNEL</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="#">DOCUMENTATION</a>
|
||||
</p>
|
||||
</div>
|
||||
</div><div class="column column--5 column--med-10 align-content-top">
|
||||
<div class="row row--short">
|
||||
<p>Spee.ch is a media-hosting site that reads and publishes content from the <a class="white-text" href="https://lbry.io">LBRY</a> blockchain.</p>
|
||||
<p>Spee.ch is a hosting service, but with the added benefit that it stores your content on a decentralized network of computers -- the LBRY network. This means that your images are stored in multiple locations without a single point of failure.</p>
|
||||
<h3>[Contribute]</h3>
|
||||
<p>Spee.ch is an open source project. Please contribute to the existing site, or fork it and make your own!</p>
|
||||
<p>If you have an idea for your own spee.ch-like site on top of LBRY, fork our <a href="https://github.com/lbryio/spee.ch">github repo</a> and go to town!</p>
|
||||
<p>If you want to improve spee.ch, join our <a href="https://lbry.slack.com">slack channel</a> or solve one of our <a href="https://github.com/lbryio/spee.ch/issues">github issues</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
|
@ -1,11 +1,8 @@
|
|||
<div class="wrapper">
|
||||
{{> topBar}}
|
||||
<div>
|
||||
<h3>{{this.channelName}}<span class="h3--secondary">:{{this.longChannelId}}</span></h3>
|
||||
<p>Below is all the free content in this channel.</p>
|
||||
{{#each this.claims}}
|
||||
{{> contentListItem}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{> footer}}
|
||||
{{> topBar}}
|
||||
<div class="row row--full-height">
|
||||
<h2>{{this.channelName}}<span class="h2--secondary">:{{this.longChannelId}}</span></h2>
|
||||
<p>Below is all the free content in this channel.</p>
|
||||
{{#each this.claims}}
|
||||
{{> contentListItem}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<div class="wrapper">
|
||||
|
||||
{{> topBar}}
|
||||
<div>
|
||||
<h3>404: Not Found</h3>
|
||||
<p>That page does not exist. Return <a href="/">home</a>.</p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,25 +1,111 @@
|
|||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
|
||||
<div class="row">
|
||||
<div class="column column--2"></div>
|
||||
<div class="column column--8">
|
||||
{{> topBar}}
|
||||
{{> publishForm}}
|
||||
{{> learnMore}}
|
||||
{{> footer}}
|
||||
{{> topBar}}
|
||||
<div class="row row--full-height">
|
||||
<div id="primary-dropzone-wrapper">
|
||||
<div id="primary-dropzone" class="dropzone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)">
|
||||
<div id="primary-dropzone-instructions">
|
||||
<div class="row">
|
||||
<p>Drag & drop image or video here</p>
|
||||
<p>OR</p>
|
||||
<form>
|
||||
<label class="input-file-label" for="siofu_input">CHOOSE FILE</label>
|
||||
<input class=" input-file" type="file" id="siofu_input" name="siofu_input" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
|
||||
</form>
|
||||
</div>
|
||||
<div class="info-message info-message--failure" id="input-error-file-selection" hidden="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="publish-form-wrapper" hidden="true">
|
||||
<div class="column column--10">
|
||||
<!-- title input -->
|
||||
<input type="text" id="publish-title" class="input-text input-text--large input-text--full-width" placeholder="Title (optional)">
|
||||
</div>
|
||||
<div class="column column--5 column--med-10 align-content-top" >
|
||||
<!-- preview -->
|
||||
<div class="row">
|
||||
<div id="asset-preview-holder" class="dropzone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)" onmouseenter="showInstructions()" onmouseleave="hideInstructions()">
|
||||
<div id="asset-preview-target"></div>
|
||||
<div id="preview-dropzone-instructions" hidden="true">
|
||||
<div class="row">
|
||||
<p>Drag & drop image or video here</p>
|
||||
<p>OR</p>
|
||||
<form>
|
||||
<label class="input-file-label" for="siofu_input">CHOOSE FILE</label>
|
||||
<input class=" input-file" type="file" id="siofu_input" name="siofu_input" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- description input -->
|
||||
<textarea rows="2" id="publish-description" class="textarea textarea--large textarea--full-width" placeholder="Description (optional)"></textarea>
|
||||
</div><div class="column column--5 column--med-10 align-content-top">
|
||||
<div id="publish-status" class="row" hidden="true"></div>
|
||||
<div id="publish-progress-bar" class="row" hidden="true"></div>
|
||||
<div id="publish-active-area">
|
||||
{{> publishForm-Channel}}
|
||||
{{> publishForm-Url}}
|
||||
{{> publishForm-Details}}
|
||||
{{> publishForm-Submit}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script src="/siofu/client.js"></script>
|
||||
<script src="/assets/js/validationFunctions.js"></script>
|
||||
<script src="/assets/js/publishFileFunctions.js"></script>
|
||||
<script typ="text/javascript">
|
||||
// define variables
|
||||
var socket = io();
|
||||
var uploader = new SocketIOFileUpload(socket);
|
||||
var stagedFiles = null;
|
||||
|
||||
checkCookie();
|
||||
|
||||
var socket = io();
|
||||
var uploader = new SocketIOFileUpload(socket);
|
||||
var stagedFiles = null;
|
||||
|
||||
/* drop zone functions */
|
||||
|
||||
function showInstructions () {
|
||||
document.getElementById('preview-dropzone-instructions').hidden = false;
|
||||
document.getElementById('asset-preview').style.opacity = 0.3;
|
||||
}
|
||||
function hideInstructions () {
|
||||
document.getElementById('preview-dropzone-instructions').hidden = true;
|
||||
document.getElementById('asset-preview').style.opacity = 1;
|
||||
}
|
||||
function drop_handler(event) {
|
||||
event.preventDefault();
|
||||
// if dropped items aren't files, reject them
|
||||
var dt = event.dataTransfer;
|
||||
if (dt.items) {
|
||||
if (dt.items[0].kind == 'file') {
|
||||
var droppedFile = dt.items[0].getAsFile();
|
||||
previewAndStageFile(droppedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
function dragover_handler(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
function dragend_handler(event) {
|
||||
var dt = event.dataTransfer;
|
||||
if (dt.items) {
|
||||
for (var i = 0; i < dt.items.length; i++) {
|
||||
dt.items.remove(i);
|
||||
}
|
||||
} else {
|
||||
event.dataTransfer.clearData();
|
||||
}
|
||||
}
|
||||
|
||||
/* socketio-file-upload listeners */
|
||||
function updatePublishStatus(msg){
|
||||
document.getElementById('publish-status').innerHTML = msg;
|
||||
}
|
||||
uploader.addEventListener('start', function(event){
|
||||
var name = document.getElementById('claim-name-input').value;
|
||||
var title = document.getElementById('publish-title').value;
|
||||
|
@ -34,10 +120,12 @@
|
|||
event.file.meta.nsfw = nsfw;
|
||||
event.file.meta.type = stagedFiles[0].type;
|
||||
event.file.meta.channel = channel;
|
||||
// re-set the html in the publish area
|
||||
document.getElementById('publish-active-area').innerHTML = '<div id="publish-status"></div><div id="progress-bar"></div>';
|
||||
// start a progress animation
|
||||
createProgressBar(document.getElementById('progress-bar'), 12);
|
||||
// hide the submit area
|
||||
document.getElementById('publish-active-area').hidden = true;
|
||||
// show the progress status and animation
|
||||
document.getElementById('publish-status').hidden = false;
|
||||
document.getElementById('publish-progress-bar').hidden = false;
|
||||
createProgressBar(document.getElementById('publish-progress-bar'), 12);
|
||||
// google analytics
|
||||
ga('send', {
|
||||
hitType: 'event',
|
||||
|
@ -54,16 +142,15 @@
|
|||
updatePublishStatus(msg);
|
||||
});
|
||||
socket.on('publish-failure', function(msg){
|
||||
document.getElementById('publish-active-area').innerHTML = '<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a href="https://lbry.slack.com/" target="_blank">lbry slack</a></strong>';
|
||||
updatePublishStatus('<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a href="https://lbry.slack.com/" target="_blank">lbry slack</a></strong>');
|
||||
document.getElementById('publish-progress-bar').hidden = true;
|
||||
});
|
||||
socket.on('publish-complete', function(msg){
|
||||
var publishResults;
|
||||
var showUrl = msg.result.claim_id + "/" + msg.name;
|
||||
// build new publish area
|
||||
publishResults = '<p>Your publish is complete! You are being redirected to it now.</p>';
|
||||
publishResults += '<p><a target="_blank" href="' + showUrl + '">If you do not get redirected, click here.</a></p>';
|
||||
// update publish area
|
||||
document.getElementById('publish-active-area').innerHTML = publishResults;
|
||||
// update status
|
||||
updatePublishStatus('<p>Your publish is complete! You are being redirected to it now.</p><p><a target="_blank" href="' + showUrl + '">If you do not get redirected, click here.</a></p>');
|
||||
document.getElementById('publish-progress-bar').hidden = true;
|
||||
// redirect the user
|
||||
window.location.href = showUrl;
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Spee.ch</title>
|
||||
<link rel="stylesheet" href="/assets/css/reset.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/BEM.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/componentStyle.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/general.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/mediaQueries.css" type="text/css">
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@lbryio" />
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Spee.ch</title>
|
||||
<link rel="stylesheet" href="/assets/css/reset.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/BEM.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/componentStyle.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/general.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/mediaQueries.css" type="text/css">
|
||||
<meta property="fb:app_id" content="1371961932852223">
|
||||
{{#unless fileInfo.nsfw}}
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
<div class="wrapper">
|
||||
{{> topBar}}
|
||||
<h2>Log In</h2>
|
||||
<div class="row row--wide">
|
||||
{{> topBar}}
|
||||
|
||||
<div class="column column--6">
|
||||
<p>Log in to an existing channel:</p>
|
||||
{{>channelLoginForm}}
|
||||
</div>
|
||||
<div class="row row--full-height">
|
||||
<div class="column column--5 column--med-10 align-content-top">
|
||||
<p>Log in to an existing channel:</p>
|
||||
{{>channelLoginForm}}
|
||||
</div><div class="column column--5 column--med-10 align-content-top">
|
||||
<p>Create a brand new channel:</p>
|
||||
{{>channelCreationForm}}
|
||||
</div>
|
||||
<h2>Create New</h2>
|
||||
<div class="row row--wide">
|
||||
<div class="column column--6">
|
||||
<p>Create a brand new channel:</p>
|
||||
{{>channelCreationForm}}
|
||||
</div>
|
||||
</div>
|
||||
{{> footer}}
|
||||
</div>
|
||||
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="wrapper">
|
||||
|
||||
{{> topBar}}
|
||||
<div>
|
||||
<h2>New on Spee.ch</h2>
|
||||
|
@ -22,5 +22,3 @@
|
|||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{> footer}}
|
||||
</div>
|
|
@ -1,8 +1,7 @@
|
|||
<div class="wrapper">
|
||||
|
||||
{{> topBar}}
|
||||
<div>
|
||||
<h3>No Claims</h3>
|
||||
<p>There are no free assets on this channel.</p>
|
||||
<p><i>If you think this message is an error, contact us in the <a href="https://lbry.slack.com/" target="_blank">LBRY slack!</a></i></p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,8 +1,7 @@
|
|||
<div class="wrapper">
|
||||
|
||||
{{> topBar}}
|
||||
<div>
|
||||
<h3>No Claims</h3>
|
||||
<p>There are no free assets at that claim. You should publish one at <a href="/">spee.ch</a>.</p>
|
||||
<p>NOTE: it is possible your claim was published, but it is still being processed by the blockchain</p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,23 +1,19 @@
|
|||
<div class="row">
|
||||
<div id="asset-placeholder">
|
||||
<a href="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">
|
||||
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
|
||||
{{#ifConditional fileInfo.fileExt '===' 'gifv'}}
|
||||
<video class="show-asset" autoplay loop muted>
|
||||
<source src="/media/{{fileInfo.fileName}}">
|
||||
{{!--fallback--}}
|
||||
Your browser does not support the <code>video</code> element.
|
||||
</video>
|
||||
{{else}}
|
||||
<video class="show-asset" autoplay controls>
|
||||
<source src="/media/{{fileInfo.fileName}}">
|
||||
{{!--fallback--}}
|
||||
Your browser does not support the <code>video</code> element.
|
||||
</video>
|
||||
{{/ifConditional}}
|
||||
{{else}}
|
||||
<img class="show-asset" src="/media/{{fileInfo.fileName}}" />
|
||||
{{/ifConditional}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">
|
||||
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
|
||||
{{#ifConditional fileInfo.fileExt '===' 'gifv'}}
|
||||
<video class="asset-display" autoplay loop muted>
|
||||
<source src="/media/{{fileInfo.fileName}}">
|
||||
{{!--fallback--}}
|
||||
Your browser does not support the <code>video</code> element.
|
||||
</video>
|
||||
{{else}}
|
||||
<video class="asset-display" autoplay controls>
|
||||
<source src="/media/{{fileInfo.fileName}}">
|
||||
{{!--fallback--}}
|
||||
Your browser does not support the <code>video</code> element.
|
||||
</video>
|
||||
{{/ifConditional}}
|
||||
{{else}}
|
||||
<img class="asset-display" src="/media/{{fileInfo.fileName}}" />
|
||||
{{/ifConditional}}
|
||||
</a>
|
|
@ -1,76 +1,92 @@
|
|||
<div class="panel">
|
||||
<h2>Title</h2>
|
||||
<p>{{fileInfo.title}}</>
|
||||
<h2 class="h2--top">Title</h2>
|
||||
<div class="row row--short">
|
||||
{{fileInfo.title}}
|
||||
</div>
|
||||
<div class="panel links">
|
||||
<h2>Links</h2>
|
||||
{{!--short direct link to asset--}}
|
||||
<div class="share-option">
|
||||
<a href="/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">Permanent Short Link</a> (most convenient)
|
||||
<div class="input-error" id="input-error-copy-short-link" hidden="true"></div>
|
||||
<br/>
|
||||
<input type="text" id="short-link" class="link" readonly spellcheck="false" value="https://spee.ch/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" onclick="select()"/>
|
||||
<button class="copy-button" data-elementtocopy="short-link" onclick="copyToClipboard(event)">copy</button>
|
||||
</div>
|
||||
{{!-- link to show route for asset--}}
|
||||
<div class="share-option">
|
||||
<a href="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">Permanent Long Link</a> (fastest service)
|
||||
<div class="input-error" id="input-error-copy-long-link" hidden="true"></div>
|
||||
</br>
|
||||
<input type="text" id="long-link" class="link" readonly onclick="select()" spellcheck="false" value="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/>
|
||||
<button class="copy-button" data-elementtocopy="long-link" onclick="copyToClipboard(event)">copy</button>
|
||||
</div>
|
||||
{{!-- html text for embedding asset--}}
|
||||
<div class="share-option">
|
||||
Embed HTML
|
||||
<div class="input-error" id="input-error-copy-embed-text" hidden="true"></div>
|
||||
<br/>
|
||||
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
|
||||
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='<video width="100%" controls src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/></video>'/>
|
||||
{{else}}
|
||||
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='<img src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" />'/>
|
||||
{{/ifConditional}}
|
||||
<button class="copy-button" data-elementtocopy="embed-text" onclick="copyToClipboard(event)">copy</button>
|
||||
</div>
|
||||
{{!--markdown text using asset--}}
|
||||
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
|
||||
{{else}}
|
||||
<div class="share-option">
|
||||
Markdown
|
||||
<div class="input-error" id="input-error-copy-markdown-text" hidden="true"></div>
|
||||
<br/>
|
||||
<input type="text" id="markdown-text" class="link" readonly onclick="select()" spellcheck="false" value='![{{fileInfo.name}}](https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}})'/>
|
||||
<button class="copy-button" data-elementtocopy="markdown-text" onclick="copyToClipboard(event)">copy</button>
|
||||
</div>
|
||||
{{/ifConditional}}
|
||||
<h2>Share via Social Media</h2>
|
||||
<div class="row row--short">
|
||||
<a class="twitter-share button" target="_blank" href="https://twitter.com/intent/tweet?text=https://spee.ch/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">
|
||||
<img src="https://i.imgur.com/Vt1XU5f.png" />
|
||||
</a>
|
||||
<a class="fb-share button" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fspee.ch%2F{{fileInfo.shortId}}%2F{{fileInfo.name}}.{{fileInfo.fileExt}}&src=sdkpreparse">
|
||||
<img src="https://i.imgur.com/SpOUrdt.png" />
|
||||
</a>
|
||||
<a class="tumblr-share button" target="_blank" href="https://www.tumblr.com/widgets/share/tool?posttype=photo&title=Spee.ch%20%7C%20Share&caption=Shared%20From%20https://spee.ch%20A%20Decentralized%20Image%20Hosting%20Service%20Running%20On%20The%20LBRY%20Protocol%20&content=https://spee.ch/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}&tags=lbry%2C%20spee.ch%2C%20lbry.io&canonicalUrl=https%3A%2F%2Fspee.ch%2F{{fileInfo.shortId}}%2F{{fileInfo.name}}.{{fileInfo.fileExt}}&shareSource=tumblr_share_button">
|
||||
<img src="https://i.imgur.com/0g1xcRd.png" />
|
||||
</a>
|
||||
<a class="reddit-share button" target="_blank" href="https://www.reddit.com/submit?url=http%3A%2F%2Fspee.ch%2F{{fileInfo.shortId}}%2F{{fileInfo.name}}.{{fileInfo.fileExt}}&title={{fileInfo.name}}(Decentralized%20Hosting%20Provided%20By%20Spee.ch%20Using%20the%20LBRY%20Protocol)">
|
||||
<img src="https://i.imgur.com/I57laEJ.png" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<h2>Description</h2>
|
||||
<p>{{fileInfo.description}}</p>
|
||||
<h2>Links</h2>
|
||||
{{!-- short direct link to asset --}}
|
||||
<div class="row row--short">
|
||||
<div class="column column--7">
|
||||
<p><a href="/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">Short Link</a></p>
|
||||
<div class="input-error" id="input-error-copy-short-link" hidden="true"></div>
|
||||
<br/>
|
||||
<input type="text" id="short-link" class="input-disabled input-text--full-width" readonly spellcheck="false" value="https://spee.ch/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" onclick="select()"/>
|
||||
</div><div class="column column--1"></div><div class="column column--2">
|
||||
<button class="button--primary" data-elementtocopy="short-link" onclick="copyToClipboard(event)">copy</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<h2>Metadata</h2>
|
||||
<table class="metadata-table" style="table-layout: fixed">
|
||||
<tr class="metadata-row">
|
||||
<td class="left-column">Name</td>
|
||||
<td>{{fileInfo.name}}</td>
|
||||
</tr>
|
||||
<tr class="metadata-row">
|
||||
<td class="left-column">Claim Id</td>
|
||||
<td>{{fileInfo.claimId}}</td>
|
||||
</tr>
|
||||
<tr class="metadata-row">
|
||||
<td class="left-column">File Name</td>
|
||||
<td>{{fileInfo.fileName}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left-column">File Type</td>
|
||||
<td>{{#if fileInfo.fileType}}
|
||||
{{fileInfo.fileType}}
|
||||
{{else}}
|
||||
unknown
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{{!-- html text for embedding asset--}}
|
||||
<div class="row row--short">
|
||||
<div class="column column--7">
|
||||
<p>Embed HTML</p>
|
||||
<div class="input-error" id="input-error-copy-embed-text" hidden="true"></div>
|
||||
<br/>
|
||||
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
|
||||
<input type="text" id="embed-text" class="input-disabled input-text--full-width" readonly onclick="select()" spellcheck="false" value='<video width="100%" controls src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/></video>'/>
|
||||
{{else}}
|
||||
<input type="text" id="embed-text" class="input-disabled input-text--full-width" readonly onclick="select()" spellcheck="false" value='<img src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/>'/>
|
||||
{{/ifConditional}}
|
||||
</div><div class="column column--1"></div><div class="column column--2">
|
||||
<button class="button--primary" data-elementtocopy="embed-text" onclick="copyToClipboard(event)">copy</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Description</h2>
|
||||
<div class="row row--short">
|
||||
{{fileInfo.description}}
|
||||
</div>
|
||||
|
||||
<h2>Metadata</h2>
|
||||
<div class="row row--short">
|
||||
<table class="metadata-table" style="table-layout: fixed">
|
||||
<tr class="metadata-row">
|
||||
<td class="left-column">Name</td>
|
||||
<td>{{fileInfo.name}}</td>
|
||||
</tr>
|
||||
<tr class="metadata-row">
|
||||
<td class="left-column">Claim Id</td>
|
||||
<td class="wrap-words">{{fileInfo.claimId}}</td>
|
||||
</tr>
|
||||
<tr class="metadata-row">
|
||||
<td class="left-column">File Name</td>
|
||||
<td>{{fileInfo.fileName}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left-column">File Type</td>
|
||||
<td>{{#if fileInfo.fileType}}
|
||||
{{fileInfo.fileType}}
|
||||
{{else}}
|
||||
unknown
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script type ="text/javascript">
|
||||
function copyToClipboard(event){
|
||||
var elementToCopy = event.target.dataset.elementtocopy;
|
||||
var element = document.getElementById(elementToCopy);
|
||||
var errorElement = 'input-error-copy-text' + elementToCopy;
|
||||
element.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
} catch (err) {
|
||||
showError(errorElement, 'Oops, unable to copy');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
<form id="publish-channel-form">
|
||||
|
||||
<div class="column column--3">
|
||||
<label class="label" for="new-channel-name">Name:</label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<div class="row row--wide row--short">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label class="label" for="new-channel-name">Name:</label>
|
||||
</div><div class="column column--6 column--sml-10">
|
||||
<div id="input-error-channel-name" class="info-message info-message--failure"></div>
|
||||
<div class="input-text--primary">
|
||||
<span>@</span>
|
||||
|
@ -12,17 +11,18 @@
|
|||
<span id="input-success-channel-name" class="info-message info-message--success"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column column--3">
|
||||
<label class="label" for="new-channel-password">Password:</label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<div id="input-error-channel-password" class="info-message info-message--failure"></div>
|
||||
<input type="password" name="new-channel-password" id="new-channel-password" placeholder="" value="" class="input-text input-text--primary">
|
||||
<div class="row row--wide row--short">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label class="label" for="new-channel-password">Password:</label>
|
||||
</div><div class="column column--6 column--sml-10">
|
||||
<div id="input-error-channel-password" class="info-message info-message--failure"></div>
|
||||
<input type="password" name="new-channel-password" id="new-channel-password" placeholder="" value="" class="input-text input-text--primary">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row--wide">
|
||||
<button onclick="publishNewChannel(event)">Create Channel</button>
|
||||
<button class="button--primary" onclick="publishNewChannel(event)">Create Channel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
|||
|
||||
<script type="text/javascript">
|
||||
function publishNewChannel (event) {
|
||||
const channelName = document.getElementById('new-channel-name').value;
|
||||
const userName = document.getElementById('new-channel-name').value;
|
||||
const password = document.getElementById('new-channel-password').value;
|
||||
const channelNameErrorDisplayElement = document.getElementById('input-error-channel-name');
|
||||
const passwordErrorDisplayElement = document.getElementById('input-error-channel-password');
|
||||
|
@ -50,13 +50,13 @@
|
|||
// prevent default so this script can handle submission
|
||||
event.preventDefault();
|
||||
// validate submission
|
||||
validateNewChannelSubmission(channelName, password)
|
||||
validateNewChannelSubmission(userName, password)
|
||||
.then(() => {
|
||||
console.log('in progress');
|
||||
chanelCreateForm.hidden = true;
|
||||
inProgress.hidden = false;
|
||||
createProgressBar(document.getElementById('create-channel-progress-bar'), 12);
|
||||
return sendAuthRequest(channelName, password, '/signup') // post the request
|
||||
return sendAuthRequest(userName, password, '/signup') // post the request
|
||||
})
|
||||
.then(() => {
|
||||
console.log('success');
|
||||
|
|
|
@ -1,41 +1,65 @@
|
|||
|
||||
<form id="channel-login-form">
|
||||
|
||||
<div class="column column--3">
|
||||
<label class="label" for="login-channel-name">Name:</label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<div id="login-error-display-element" class="info-message info-message--failure"></div>
|
||||
<div class="input-text--primary">
|
||||
<span>@</span>
|
||||
<input type="text" name="login-channel-name" id="login-channel-name" class="input-text" placeholder="" value="">
|
||||
<div class="row row--wide row--short">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label class="label" for="login-channel-name">Name:</label>
|
||||
</div><div class="column column--6 column--sml-10">
|
||||
<div id="login-error-display-element" class="info-message info-message--failure"></div>
|
||||
<div class="input-text--primary">
|
||||
<span>@</span>
|
||||
<input type="text" name="login-channel-name" id="login-channel-name" class="input-text" placeholder="" value="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column column--3">
|
||||
<label class="label" for="login-channel-password" >Password:</label>
|
||||
<div class="row row--wide row--short">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label class="label" for="login-channel-password" >Password:</label>
|
||||
</div><div class="column column--6 column--sml-10">
|
||||
<input type="password" name="login-channel-password" id="login-channel-password" class="input-text input-text--primary" placeholder="" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<input type="password" name="login-channel-password" id="login-channel-password" class="input-text input-text--primary" placeholder="" value="">
|
||||
<div class="row row--wide">
|
||||
<button class="button--primary" onclick="loginToChannel(event)">Authenticate</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div class="row row--wide">
|
||||
<button onclick="loginToChannel(event)">Login</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function loginToChannel (event) {
|
||||
const channelName = document.getElementById('login-channel-name').value;
|
||||
const userName = document.getElementById('login-channel-name').value;
|
||||
const password = document.getElementById('login-channel-password').value;
|
||||
const loginErrorDisplayElement = document.getElementById('login-error-display-element');
|
||||
// prevent default
|
||||
event.preventDefault()
|
||||
// send request
|
||||
sendAuthRequest(channelName, password, '/login')
|
||||
.then(() => {
|
||||
console.log('login success');
|
||||
window.location.href = '/';
|
||||
sendAuthRequest(userName, password, '/login')
|
||||
// update session cookie with new channel name and ids
|
||||
.then(result => {
|
||||
console.log('login success', result);
|
||||
// replace the current cookies
|
||||
document.cookie = `channel_name=${result.channelName}`;
|
||||
document.cookie = `channel_claim_id=${result.channelClaimId}`;
|
||||
document.cookie = `short_channel_id=${result.shortChannelId}`;
|
||||
return result;
|
||||
})
|
||||
// update channel selection
|
||||
.then(result => {
|
||||
const channelSelect = document.getElementById('channel-name-select');
|
||||
// remove the old channel option
|
||||
const oldChannel = document.getElementById('channel-option')
|
||||
if (oldChannel){
|
||||
oldChannel.parentNode.removeChild(oldChannel);
|
||||
}
|
||||
// add new channel option & select it
|
||||
const newChannelOption = document.createElement('option');
|
||||
newChannelOption.setAttribute('value', result.channelName);
|
||||
newChannelOption.setAttribute('id', 'channel-option');
|
||||
newChannelOption.setAttribute('selected', '');
|
||||
newChannelOption.innerText = result.channelName;
|
||||
channelSelect.insertBefore(newChannelOption, channelSelect.firstChild);
|
||||
// update selection
|
||||
toggleSelectedChannel(result.channelName);
|
||||
})
|
||||
.catch(error => {
|
||||
showError(loginErrorDisplayElement, error);
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
<div class='content-list-card'>
|
||||
<a href="{{this.showUrlLong}}"><span class='content-list-card-link'></span></a>
|
||||
{{#ifConditional this.contentType '===' 'video/mp4'}}
|
||||
<img class="content-list-asset" src="{{this.thumbnail}}"/>
|
||||
{{else}}
|
||||
<img class="content-list-asset" src="{{this.directUrlLong}}" />
|
||||
{{/ifConditional}}
|
||||
<div class="content-list-details">
|
||||
<ul>
|
||||
<li class="content-list-title">{{this.title}}</li>
|
||||
<li><a href="{{this.directUrlShort}}">spee.ch{{this.directUrlShort}}</a></li>
|
||||
</ul>
|
||||
<div class='row row--wide'>
|
||||
<div class="column column--3 align-content-top">
|
||||
<a href="{{this.showUrlLong}}"><span class='content-list-card-link'></span></a>
|
||||
{{#ifConditional this.contentType '===' 'video/mp4'}}
|
||||
<img class="content-list-item-asset" src="{{this.thumbnail}}"/>
|
||||
{{else}}
|
||||
<img class="content-list-item-asset" src="{{this.directUrlLong}}" />
|
||||
{{/ifConditional}}
|
||||
</div><div class="column column--7 align-content-top">
|
||||
<p>{{this.title}}</p>
|
||||
<a href="{{this.directUrlShort}}">spee.ch{{this.directUrlShort}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<div>
|
||||
<h2>Contribute
|
||||
<a href="https://github.com/lbryio/spee.ch" target="_blank"><img id="github-logo" src="/assets/img/GitHub-Mark-32px.png"/></a>
|
||||
</h2>
|
||||
<p><strong>Spee.ch is an open source project. Please contribute to the existing site, or fork it and make your own!</strong></p>
|
||||
<p>If you have an idea for your own spee.ch-like site on top of LBRY, fork our <a href="https://github.com/lbryio/spee.ch">github repo</a> and go to town!</p>
|
||||
<p>If you want to improve spee.ch, join our <a href="https://lbry.slack.com">slack channel</a> or solve one of our <a href="https://github.com/lbryio/spee.ch/issues">github issues</a>.</p>
|
||||
</div>
|
|
@ -1,36 +0,0 @@
|
|||
<div class="panel">
|
||||
<h2>Documentation
|
||||
<a class="toggle-link" id="documentation-toggle" href="#" onclick="toggleSection(event)" data-open="false" data-openlabel="[ - ]" data-closedlabel="[ + ]" data-slaveelementid="documentation-detail">[ + ]</a>
|
||||
</h2>
|
||||
<div id="documentation-detail" hidden="true">
|
||||
<code>https://spee.ch/</code>
|
||||
<ul>
|
||||
<li>Learn about Spee.ch and publish your own media</li>
|
||||
</ul>
|
||||
<code>https://spee.ch/:name.ext</code>
|
||||
<ul>
|
||||
<li >Serves the winning free, public claim at this name directly</li>
|
||||
<li >E.g. <a href="/doitlive.png">spee.ch/doitlive.png</a></li>
|
||||
</ul>
|
||||
<code>https://spee.ch/:name</code>
|
||||
<ul>
|
||||
<li >Serves an HTML page which shows the winning claim at this name with additional details</li>
|
||||
<li >E.g. <a href="/doitlive">spee.ch/doitlive</a></li>
|
||||
</ul>
|
||||
<code>https://spee.ch/:name/:claim_id.ext</code>
|
||||
<ul>
|
||||
<li >Serves a specific image or video file directly</li>
|
||||
<li >E.g. <a href="/ca3023187e901df9e9aabd95d6ae09b6cc69b3f0/doitlive.jpg">spee.ch/doitlive/ca3023187e901df9e9aabd95d6ae09b6cc69b3f0.jpg</a></li>
|
||||
</ul>
|
||||
<code>https://spee.ch/:name/:claim_id</code>
|
||||
<ul>
|
||||
<li >Serves an HTML page with this specific claim and additional details</li>
|
||||
<li >E.g. <a href="/ca3023187e901df9e9aabd95d6ae09b6cc69b3f0/doitlive">spee.ch/doitlive/ca3023187e901df9e9aabd95d6ae09b6cc69b3f0</a></li>
|
||||
</ul>
|
||||
<code>https://spee.ch/:name/all</code>
|
||||
<ul>
|
||||
<li >Displays a list of all files at a claim</li>
|
||||
<li >E.g. <a href="/doitlive/all">spee.ch/doitlive/all</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
|
@ -1,17 +0,0 @@
|
|||
<div class="panel">
|
||||
<h2>Examples
|
||||
<a class="toggle-link" id="examples-toggle" href="#" onclick="toggleSection(event)" data-open="false" data-openlabel="[ - ]" data-closedlabel="[ + ]" data-slaveelementid="examples-detail">[ + ]</a>
|
||||
</h2>
|
||||
<div id="examples-detail" hidden="true">
|
||||
<div class="example">
|
||||
<h4>Use spee.ch to embed a specific image:</h4>
|
||||
<a href="/ca3023187e901df9e9aabd95d6ae09b6cc69b3f0/doitlive.jpg"><img class="example-image" src="/ca3023187e901df9e9aabd95d6ae09b6cc69b3f0/doitlive.jpg"/></a>
|
||||
<div class="example-code"><img src="https://spee.ch/ca3023187e901df9e9aabd95d6ae09b6cc69b3f0/doitlive.jpg"/></div>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h4>Use spee.ch to serve the top free image at a claim:</h4>
|
||||
<a href="/doitlive.png"><img class="example-image" src="/doitlive.png"/></a>
|
||||
<div class="example-code"><img src="https://spee.ch/doitlive.png"/></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,3 +0,0 @@
|
|||
<footer class="row">
|
||||
<p> thanks for visiting spee.ch </p>
|
||||
</footer>
|
|
@ -1,3 +0,0 @@
|
|||
<div class="row learn-more">
|
||||
<p><i>Spee.ch is an open-source project. You should <a href="https://github.com/lbryio/spee.ch/issues">contribute</a> on github, or <a href="https://github.com/lbryio/spee.ch">fork it</a> and make your own!</i></p>
|
||||
</div>
|
|
@ -1,66 +1,104 @@
|
|||
<!-- select whether to publish anonymously or in a channel -->
|
||||
<div class="row">
|
||||
<div class="column column--3">
|
||||
<label class="label" for="channel-name-select">Channel:</label>
|
||||
<div class="column column--10">
|
||||
<form>
|
||||
<input type="radio" name="anonymous-or-channel" id="anonymous-select" class="" value="anonymous" {{#unless user}}checked {{/unless}} onchange="toggleChannel(event.target.value)"/>
|
||||
<label class="label" for="anonymous-select">Anonymous</label>
|
||||
<input type="radio" name="anonymous-or-channel" id="in-a-channel-select" class="" value="in a channel" {{#if user}}checked {{/if}} onchange="toggleChannel(event.target.value)"/>
|
||||
<label class="label" for="in-a-channel-select">In a channel</label>
|
||||
</form>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<div id="input-error-channel-select" class="info-message info-message--failure"></div>
|
||||
<select type="text" id="channel-name-select" class="select select--primary" value="channel" onchange="toggleChannel(event)">
|
||||
<optgroup>
|
||||
</div>
|
||||
|
||||
<div id="channel-select-options" {{#unless user}}hidden="true"{{/unless}}>
|
||||
<!-- select whether to create new or log in to existing channel -->
|
||||
<div class="row">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label class="label" for="channel-name-select">Channel:</label>
|
||||
</div><div class="column column--7 column--sml-10">
|
||||
<div id="input-error-channel-select" class="info-message info-message--failure"></div>
|
||||
<select type="text" id="channel-name-select" class="select select--primary select--arrow" onchange="toggleSelectedChannel(event.target.selectedOptions[0].value)">
|
||||
{{#if user}}
|
||||
<option value="{{user.channelName}}" >@{{user.userName}}</option>
|
||||
<option value="{{user.channelName}}" id="channel-option">{{user.channelName}}</option>
|
||||
{{/if}}
|
||||
<option value="none" >None</option>
|
||||
</optgroup>
|
||||
<optgroup>
|
||||
<option value="login">Login</option>
|
||||
<option value="new" >New</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
<option value="login">Existing</option>
|
||||
<option value="new" >New</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- log into an existing channel -->
|
||||
<div id="channel-login-details" class="row row--short" {{#if user}}hidden="true"{{/if}}>
|
||||
{{> channelLoginForm}}
|
||||
</div>
|
||||
<!-- create a channel -->
|
||||
<div id="channel-create-details" class="row row--short" hidden="true">
|
||||
{{> channelCreationForm}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="channel-login-details" class="row" hidden="true">
|
||||
{{> channelLoginForm}}
|
||||
</div>
|
||||
|
||||
<div id="channel-create-details" class="row" hidden="true">
|
||||
{{> channelCreationForm}}
|
||||
</div>
|
||||
|
||||
<script src="/assets/js/authFunctions.js"></script>
|
||||
<script type="text/javascript">
|
||||
function toggleChannel (event) {
|
||||
// show or hide the channel selection tools
|
||||
function toggleChannel (selectedOption) {
|
||||
const channelSelectOptions = document.getElementById('channel-select-options');
|
||||
console.log('toggleChannel event triggered', selectedOption);
|
||||
// show/hide the login and new channel forms
|
||||
if (selectedOption === 'anonymous') {
|
||||
channelSelectOptions.hidden = true;
|
||||
channelSelectOptions.hidden = true;
|
||||
// update url
|
||||
updateUrl(selectedOption);
|
||||
} else if (selectedOption === 'in a channel') {
|
||||
channelSelectOptions.hidden = false;
|
||||
// update url
|
||||
let selectedChannel = document.getElementById('channel-name-select').selectedOptions[0].value
|
||||
toggleSelectedChannel(selectedChannel);
|
||||
} else {
|
||||
console.log('selected option was not recognized');
|
||||
}
|
||||
|
||||
}
|
||||
// show or hide the channel create/login tool
|
||||
function toggleSelectedChannel (selectedChannel) {
|
||||
const createChannelTool = document.getElementById('channel-create-details');
|
||||
const loginToChannelTool = document.getElementById('channel-login-details');
|
||||
const selectedOption = event.target.selectedOptions[0].value;
|
||||
const urlChannel = document.getElementById('url-channel');
|
||||
console.log('toggle event triggered');
|
||||
if (selectedOption === 'new') {
|
||||
// show/hide the login and new channel forms
|
||||
console.log('toggleSelectedChannel event triggered', selectedChannel);
|
||||
// show/hide the login and new channel forms
|
||||
if (selectedChannel === 'new') {
|
||||
createChannelTool.hidden = false;
|
||||
loginToChannelTool.hidden = true;
|
||||
// update URL
|
||||
urlChannel.innerText = '';
|
||||
} else if (selectedOption === 'login') {
|
||||
// show/hide the login and new channel forms
|
||||
} else if (selectedChannel === 'login') {
|
||||
loginToChannelTool.hidden = false;
|
||||
createChannelTool.hidden = true;
|
||||
// update URL
|
||||
urlChannel.innerText = '';
|
||||
} else {
|
||||
// hide the login and new channel forms
|
||||
loginToChannelTool.hidden = true;
|
||||
createChannelTool.hidden = true;
|
||||
hideError(document.getElementById('input-error-channel-select'));
|
||||
// update URL
|
||||
if (selectedOption === 'none'){
|
||||
console.log('selected option: none');
|
||||
urlChannel.innerText = '';
|
||||
} else {
|
||||
console.log('selected option:', selectedOption);
|
||||
// retrieve short url from db
|
||||
urlChannel.innerText = `{{user.channelName}}:{{user.shortChannelId}}/`;
|
||||
}
|
||||
}
|
||||
// update url
|
||||
updateUrl(selectedChannel);
|
||||
}
|
||||
function updateUrl (selectedOption) {
|
||||
const urlChannel = document.getElementById('url-channel');
|
||||
const urlNoChannelPlaceholder = document.getElementById('url-no-channel-placeholder');
|
||||
const urlChannelPlaceholder = document.getElementById('url-channel-placeholder');
|
||||
if (selectedOption === 'new' || selectedOption === 'login' || selectedOption === ''){
|
||||
urlChannel.hidden = true;
|
||||
urlNoChannelPlaceholder.hidden = true;
|
||||
urlChannelPlaceholder.hidden = false;
|
||||
} else if (selectedOption === 'anonymous'){
|
||||
urlChannel.hidden = true;
|
||||
urlNoChannelPlaceholder.hidden = false;
|
||||
urlChannelPlaceholder.hidden = true;
|
||||
} else {
|
||||
urlChannel.hidden = false;
|
||||
// show channel and short id
|
||||
const selectedChannel = getCookie('channel_name');
|
||||
const shortChannelId = getCookie('short_channel_id');
|
||||
urlChannel.innerText = `${selectedChannel}:${shortChannelId}`;
|
||||
urlNoChannelPlaceholder.hidden = true;
|
||||
urlChannelPlaceholder.hidden = true;
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,28 +1,9 @@
|
|||
<div id="details-detail" hidden="true">
|
||||
|
||||
<div class="row row--thin">
|
||||
<div class="column column--3">
|
||||
<label for="publish-title" class="label">Title: </label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<input type="text" id="publish-title" class="input-text input-text--primary">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row--thin">
|
||||
<div class="column column--3">
|
||||
<label for="publish-description" class="label">Description: </label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<textarea rows="2" id="publish-description" class="input-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row--thin">
|
||||
<div class="column column--3">
|
||||
<label for="publish-license" class="label">License:* </label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<div class="row row--short">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label for="publish-license" class="label">License:</label>
|
||||
</div><div class="column column--7 column--sml-10">
|
||||
<select type="text" id="publish-license" class="select select--primary">
|
||||
<option value="Public Domain">Public Domain</option>
|
||||
<option value="Creative Commons">Creative Commons</option>
|
||||
|
@ -30,18 +11,17 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row row--thin">
|
||||
<div class="column column--3">
|
||||
<label for="publish-nsfw" class="label">NSFW*</label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
<div class="row row--short">
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label for="publish-nsfw" class="label">NSFW:</label>
|
||||
</div><div class="column column--7 column--sml-10">
|
||||
<input class="input-checkbox" type="checkbox" id="publish-nsfw">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="column column--12">
|
||||
<div class="column column--10">
|
||||
<a class="label" id="details-toggle" href="#" onclick="toggleSection(event)" data-open="false" data-openlabel="[less]" data-closedlabel="[more]" data-slaveelementid="details-detail">[more]</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
11
views/partials/publishForm-Submit.handlebars
Normal file
|
@ -0,0 +1,11 @@
|
|||
<div class="row">
|
||||
<div class="input-error" id="input-error-publish-submit" hidden="true"></div>
|
||||
<button id="publish-submit" class="button--primary button--large" onclick="publishStagedFile(event)">Upload</button>
|
||||
</div>
|
||||
<div class="row row--short align-content-center">
|
||||
<button class="button--cancel" onclick="cancelPublish()">Cancel</button>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" >
|
||||
|
||||
</script>
|
|
@ -1,13 +1,18 @@
|
|||
<div class="row">
|
||||
<div class="column column--3">
|
||||
|
||||
<div class="column column--3 column--sml-10">
|
||||
<label class="label">URL:</label>
|
||||
</div>
|
||||
<div class="column column--9">
|
||||
</div><div class="column column--6 column--sml-10">
|
||||
<div id="input-error-claim-name" class="info-message info-message--failure" hidden="true"></div>
|
||||
<div class="input-text--primary">
|
||||
<span class="url-text">Spee.ch/</span><span id="url-channel" class="url-text">{{#if user}}{{user.channelName}}:{{user.shortChannelId}}/{{/if}}</span><input type="text" id="claim-name-input" class="input-text" placeholder="your-url-here" oninput="checkClaimName(event.target.value)">
|
||||
<span class="url-text">Spee.ch /</span>
|
||||
<span id="url-channel" class="url-text url-text--primary" {{#if user}}{{else}}hidden="true"{{/if}}>{{user.channelName}}:{{user.shortChannelId}}</span>
|
||||
<span id="url-no-channel-placeholder" class="url-text url-text--secondary tooltip" {{#if user}}hidden="true"{{else}}{{/if}}>xyz<span class="tooltip-text">This will be a random id</span></span>
|
||||
<span id="url-channel-placeholder" class="url-text url-text--secondary tooltip" hidden="true">@channel<span class="tooltip-text">Select a channel above</span></span>
|
||||
/
|
||||
<input type="text" id="claim-name-input" class="input-text" placeholder="your-url-here" oninput="checkClaimName(event.target.value)">
|
||||
<span id="input-success-claim-name" class="info-message info-message--success"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -1,62 +0,0 @@
|
|||
<div class="panel">
|
||||
<h2>Publish</h2>
|
||||
<div class="row">
|
||||
<div class="col-left">
|
||||
<div id="file-selection-area">
|
||||
|
||||
<div id="drop-zone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)">
|
||||
<div class="row">
|
||||
<p>Drag and drop your file here, or choose your file below.</p>
|
||||
<div class="info-message info-message--failure" id="input-error-file-selection" hidden="true"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<input type="file" id="siofu_input" name="file" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="asset-preview-holder"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-right">
|
||||
<div id="publish-active-area">
|
||||
|
||||
{{> publishForm-Channel}}
|
||||
|
||||
{{> publishForm-Url}}
|
||||
|
||||
{{> publishForm-Details}}
|
||||
|
||||
<div class="row">
|
||||
<div class="input-error" id="input-error-publish-submit" hidden="true"></div>
|
||||
<button id="publish-submit" onclick="publishSelectedImage(event)">Publish</button>
|
||||
<button onclick="resetPublishArea()">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" >
|
||||
function resetPublishArea (){
|
||||
// reset file selection area
|
||||
document.getElementById('file-selection-area').innerHTML = `<div id="drop-zone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)">
|
||||
<p>Drag and drop your file here, or choose your file below.</p>
|
||||
<div class="info-message info-message--failure" id="input-error-file-selection" hidden="true"></div>
|
||||
<input type="file" id="siofu_input" name="file" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
|
||||
</div>
|
||||
<div id="asset-preview-holder"></div>`;
|
||||
// reset inputs
|
||||
document.getElementById('claim-name-input').value = '';
|
||||
document.getElementById('publish-title').value = '';
|
||||
document.getElementById('publish-description').value = '';
|
||||
document.getElementById('publish-nsfw').checked = false;
|
||||
// remove staged files
|
||||
stagedFiles = null;
|
||||
// clear any errors
|
||||
document.getElementById('input-error-file-selection').innerHTML = '';
|
||||
document.getElementById('input-error-claim-name').innerHTML = '';
|
||||
document.getElementById('input-error-publish-submit').innerHTML = '';
|
||||
document.getElementById('input-success-claim-name').hidden = true;
|
||||
}
|
||||
</script>
|
|
@ -1,20 +1,23 @@
|
|||
<div class="row top-bar">
|
||||
<a href="https://en.wikipedia.org/wiki/Freedom_of_information" target="_blank"><img id="logo" src="/assets/img/content-freedom-64px.png"/></a>
|
||||
<h1 id="title"><a href="/">Spee.ch</a></h1><span class="top-bar-left">(beta)</span>
|
||||
<a href="/popular" class="top-bar-right">popular</a>
|
||||
<a href="https://github.com/lbryio/spee.ch" target="_blank" class="top-bar-right">source</a>
|
||||
<a href="/about" class="top-bar-right">help</a>
|
||||
<div class="row-wide nav-bar">
|
||||
<div class="nav-bar-title-section">
|
||||
<a href="/"><span class="nav-bar-title">spee<h</span></a><span class="nav-bar-title nav-bar-title--superscript">(beta)</span>
|
||||
<div class="nav-bar-link-section">
|
||||
<a class="nav-bar-link" href="/">Upload</a>
|
||||
<a class="nav-bar-link" href="/popular">Popular</a>
|
||||
<a class="nav-bar-link" href="/about">About</a>
|
||||
<!--{{#if user}}-->
|
||||
<!--<select type="text" class="select select--no-arrow nav-bar-link" onchange="toggleLogin(event)">-->
|
||||
<!--<option value="{{user.channelName}}:{{user.channelClaimId}}">@{{user.userName}}</option>-->
|
||||
<!--<option value="view">View</option>-->
|
||||
<!--<option value="logout">Logout</option>-->
|
||||
<!--</select>-->
|
||||
<!--{{else}}-->
|
||||
<!--<a class="nav-bar-link" href="/login">Login</a>-->
|
||||
<!--{{/if}}-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{#if user}}
|
||||
<select type="text" class="select" onchange="toggleLogin(event)">
|
||||
<option value="none">@{{user.userName}}</option>
|
||||
<option value="view">view</option>
|
||||
<option value="logout">logout</option>
|
||||
</select>
|
||||
{{else}}
|
||||
<a href="/login" class="top-bar-right">login</a>
|
||||
{{/if}}
|
||||
<div class="top-bar-tagline">Open-source, decentralized image and video hosting.</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -22,11 +25,24 @@
|
|||
console.log(event);
|
||||
const selectedOption = event.target.selectedOptions[0].value;
|
||||
if (selectedOption === 'logout') {
|
||||
console.log('login');
|
||||
console.log('log out');
|
||||
// remove session cookies
|
||||
|
||||
// send logout request to server
|
||||
window.location.href = '/logout';
|
||||
} else if (selectedOption === 'view') {
|
||||
console.log('view channel');
|
||||
window.location.href = '/{{user.channelName}}:{{user.channelClaimId}}';
|
||||
}
|
||||
}
|
||||
// highlight the link for the current page
|
||||
const navBarLinks = document.getElementsByClassName('nav-bar-link');
|
||||
for (let i = 0; i < navBarLinks.length; i++){
|
||||
const link = navBarLinks[i];
|
||||
if (link.href == window.location.href) {
|
||||
link.setAttribute('class', 'nav-bar-link nav-bar-link--active');
|
||||
} else if (`/${link.value}` === window.location.pathname) {
|
||||
link.setAttribute('class', 'select select--no-arrow nav-bar-link nav-bar-link--active');
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,5 +0,0 @@
|
|||
<h2>What Is Spee.ch?</h2>
|
||||
<h3>Spee.ch is for sharing</h3>
|
||||
<p>Spee.ch is a platform by which you can publish images to the Lbry blockchain. Just upload an image, title it, and send it off into the lbry blockchain.</p>
|
||||
<p>Spee.ch is also a platform to serve you those images. It's like have a personal chef that will serve you a meal anywhere in the world. All you have to do is ask for it, by using "spee.ch/" + the name of a claim.</p>
|
||||
<p>If you want a specific image, just ask for it with the claim_id by using "spee.ch/" + the name of the claim + "/" + the claim id.</p>
|
7
views/popular.handlebars
Normal file
|
@ -0,0 +1,7 @@
|
|||
{{> topBar}}
|
||||
<div class="row">
|
||||
{{#each trendingAssets}}
|
||||
{{> contentListItem}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
@ -1,24 +1,11 @@
|
|||
<div class="wrapper">
|
||||
{{> topBar}}
|
||||
<div class="main">
|
||||
{{> asset}}
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
{{> assetInfo}}
|
||||
</div>
|
||||
{{> footer}}
|
||||
</div>
|
||||
|
||||
<script type ="text/javascript">
|
||||
function copyToClipboard(event){
|
||||
var elementToCopy = event.target.dataset.elementtocopy;
|
||||
var element = document.getElementById(elementToCopy);
|
||||
var errorElement = 'input-error-copy-text' + elementToCopy;
|
||||
element.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
} catch (err) {
|
||||
showError(errorElement, 'Oops, unable to copy');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{{> topBar}}
|
||||
<div class="row">
|
||||
<div class="column column--6 column--med-10 align-content-top">
|
||||
{{> asset}}
|
||||
</div><div class="column column--4 column--med-10 align-content-top">
|
||||
<div class="row row--short">
|
||||
{{> assetInfo}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
<div class="wrapper">
|
||||
|
||||
<div class="top-bar">
|
||||
{{> topBar}}
|
||||
</div>
|
||||
|
@ -35,4 +35,3 @@
|
|||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -1,11 +0,0 @@
|
|||
<div class="wrapper">
|
||||
{{> topBar}}
|
||||
<div>
|
||||
<h3>Popular</h3>
|
||||
<p>Below are the 25 most popular items on spee.ch</p>
|
||||
{{#each trendingAssets}}
|
||||
{{> contentListItem}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{> footer}}
|
||||
</div>
|