added channel select to publish tool
This commit is contained in:
parent
0e9147d9d6
commit
f64961446f
16 changed files with 282 additions and 153 deletions
|
@ -130,4 +130,34 @@ module.exports = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
checkChannelAvailability (name) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// find any records where the name is used
|
||||||
|
db.Certificate.findAll({ where: { name } })
|
||||||
|
.then(result => {
|
||||||
|
if (result.length >= 1) {
|
||||||
|
// filter out any results that were not published from a spee.ch wallet address
|
||||||
|
getWalletList()
|
||||||
|
.then((walletList) => {
|
||||||
|
const filteredResult = result.filter((claim) => {
|
||||||
|
return walletList.includes(claim.address);
|
||||||
|
});
|
||||||
|
if (filteredResult.length >= 1) {
|
||||||
|
resolve(false);
|
||||||
|
} else {
|
||||||
|
resolve(true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve(true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = new PassportLocalStrategy(
|
||||||
if (!user.validPassword(password, user.password)) {
|
if (!user.validPassword(password, user.password)) {
|
||||||
return done(null, false, {message: 'Incorrect username or password.'});
|
return done(null, false, {message: 'Incorrect username or password.'});
|
||||||
}
|
}
|
||||||
return done(null, user.dataValues);
|
return done(null, user); // user.dataValues?
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
return done(error);
|
return done(error);
|
||||||
|
|
|
@ -26,7 +26,7 @@ module.exports = new PassportLocalStrategy(
|
||||||
})
|
})
|
||||||
.then(user => {
|
.then(user => {
|
||||||
logger.debug('User record was created successfully');
|
logger.debug('User record was created successfully');
|
||||||
return done(null);
|
return done(null, user); // user.datavalues?
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
logger.debug(error);
|
logger.debug(error);
|
||||||
|
|
|
@ -54,12 +54,15 @@
|
||||||
width: 90%
|
width: 90%
|
||||||
}
|
}
|
||||||
|
|
||||||
#claim-name-input {
|
.input-text--primary {
|
||||||
border: 0px;
|
border: 0px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-bottom: 1px solid grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
#claim-name-input:focus {
|
.input-text--primary:focus {
|
||||||
outline: none
|
outline: none;
|
||||||
|
border-bottom: 1px solid blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* show routes */
|
/* show routes */
|
||||||
|
|
|
@ -27,6 +27,31 @@ function validateFile(file) {
|
||||||
throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.')
|
throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// validation function that checks to make sure the claim name is not already claimed
|
||||||
|
function isChannelAvailable (name) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
// make sure the claim name is still available
|
||||||
|
var xhttp;
|
||||||
|
xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.open('GET', '/api/isChannelAvailable/' + name, true);
|
||||||
|
xhttp.responseType = 'json';
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 ) {
|
||||||
|
if ( this.status == 200) {
|
||||||
|
if (this.response == true) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject( new NameError("That name has already been claimed by another user. Please choose a different name."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject("request to check claim name failed with status:" + this.status);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhttp.send();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// validation function that checks to make sure the claim name is not already claimed
|
// validation function that checks to make sure the claim name is not already claimed
|
||||||
function isNameAvailable (name) {
|
function isNameAvailable (name) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -51,6 +76,7 @@ function isNameAvailable (name) {
|
||||||
xhttp.send();
|
xhttp.send();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// validation function that checks to make sure the claim name is valid
|
// validation function that checks to make sure the claim name is valid
|
||||||
function validateClaimName (name) {
|
function validateClaimName (name) {
|
||||||
// ensure a name was entered
|
// ensure a name was entered
|
||||||
|
@ -89,6 +115,31 @@ function checkClaimName(name){
|
||||||
document.getElementById('claim-name-available').hidden = true;
|
document.getElementById('claim-name-available').hidden = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// validaiton function to check claim name as the input changes
|
||||||
|
function checkChannelName(event){
|
||||||
|
console.log(event);
|
||||||
|
const name = event.target.value;
|
||||||
|
const target = document.getElementById(event.target.id);
|
||||||
|
const errorDisplay = target.parentNode.firstChild;
|
||||||
|
console.log('error display:', errorDisplay)
|
||||||
|
try {
|
||||||
|
// check to make sure it is available
|
||||||
|
isChannelAvailable(name)
|
||||||
|
.then(function() {
|
||||||
|
errorDisplay.hidden = false;
|
||||||
|
})
|
||||||
|
.catch(function(error) {
|
||||||
|
errorDisplay.hidden = false;
|
||||||
|
showError(errorDisplay.getAttribute('id'), error.message);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error.message);
|
||||||
|
document.getElementById(errorDisplay.getAttribute('id')).hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// validation function which checks all aspects of the publish submission
|
// validation function which checks all aspects of the publish submission
|
||||||
function validateSubmission(stagedFiles, name){
|
function validateSubmission(stagedFiles, name){
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ const multipart = require('connect-multiparty');
|
||||||
const multipartMiddleware = multipart();
|
const multipartMiddleware = multipart();
|
||||||
const { publish } = require('../controllers/publishController.js');
|
const { publish } = require('../controllers/publishController.js');
|
||||||
const { getClaimList, resolveUri } = require('../helpers/lbryApi.js');
|
const { getClaimList, resolveUri } = require('../helpers/lbryApi.js');
|
||||||
const { createPublishParams, validateFile, checkNameAvailability } = require('../helpers/publishHelpers.js');
|
const { createPublishParams, validateFile, checkNameAvailability, checkChannelAvailability } = require('../helpers/publishHelpers.js');
|
||||||
const errorHandlers = require('../helpers/errorHandlers.js');
|
const errorHandlers = require('../helpers/errorHandlers.js');
|
||||||
const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
|
const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
|
||||||
|
|
||||||
|
@ -38,6 +38,22 @@ module.exports = (app, hostedContentPath) => {
|
||||||
res.status(500).json(error);
|
res.status(500).json(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// route to check whether spee.ch has published to a channel
|
||||||
|
app.get('/api/isChannelAvailable/:name', ({ ip, originalUrl, params }, res) => {
|
||||||
|
// send response
|
||||||
|
checkChannelAvailability(params.name)
|
||||||
|
.then(result => {
|
||||||
|
if (result === true) {
|
||||||
|
res.status(200).json(true);
|
||||||
|
} else {
|
||||||
|
logger.debug(`Rejecting publish request because ${params.name} has already been published via spee.ch`);
|
||||||
|
res.status(200).json(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
res.status(500).json(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
// route to run a resolve request on the daemon
|
// route to run a resolve request on the daemon
|
||||||
app.get('/api/resolve/:uri', ({ headers, ip, originalUrl, params }, res) => {
|
app.get('/api/resolve/:uri', ({ headers, ip, originalUrl, params }, res) => {
|
||||||
// google analytics
|
// google analytics
|
||||||
|
|
|
@ -1,30 +1,35 @@
|
||||||
const errorHandlers = require('../helpers/errorHandlers.js');
|
const errorHandlers = require('../helpers/errorHandlers.js');
|
||||||
const db = require('../models');
|
|
||||||
const { postToStats, getStatsSummary, getTrendingClaims, getRecentClaims } = require('../controllers/statsController.js');
|
const { postToStats, getStatsSummary, getTrendingClaims, getRecentClaims } = require('../controllers/statsController.js');
|
||||||
const passport = require('passport');
|
const passport = require('passport');
|
||||||
// const { deAuthenticate } = require('../auth/authentication.js');
|
const logger = require('winston');
|
||||||
|
|
||||||
module.exports = (app) => {
|
module.exports = (app) => {
|
||||||
// route for auth
|
// route for auth
|
||||||
app.post('/signup', passport.authenticate('local-signup'), (req, res) => {
|
app.post('/signup', passport.authenticate('local-signup'), (req, res) => {
|
||||||
console.log('redirecting to user channel');
|
logger.debug('redirecting to user channel');
|
||||||
// If this function gets called, authentication was successful.
|
// If this function gets called, signup was successful.
|
||||||
// `req.user` contains the authenticated user.
|
// `req.user` contains the authenticated user.
|
||||||
res.redirect('/@' + req.user.channelName);
|
res.redirect('/@' + req.user.channelName);
|
||||||
});
|
});
|
||||||
app.post('/login', passport.authenticate('local-login'), (req, res) => {
|
app.post('/login', passport.authenticate('local-login'), (req, res) => {
|
||||||
console.log('redirecting to user channel');
|
logger.debug('redirecting to user channel');
|
||||||
// If this function gets called, authentication was successful.
|
// If this function gets called, login was successful.
|
||||||
// `req.user` contains the authenticated user.
|
// `req.user` contains the authenticated user.
|
||||||
res.redirect('/@' + req.user.channelName);
|
res.redirect('/@' + req.user.channelName);
|
||||||
});
|
});
|
||||||
|
// route to log out
|
||||||
|
app.get('/logout', (req, res) => {
|
||||||
|
req.logout();
|
||||||
|
res.redirect('/login');
|
||||||
|
});
|
||||||
|
|
||||||
// route to display login page
|
// route to display login page
|
||||||
app.get('/login', (req, res) => {
|
app.get('/login', (req, res) => {
|
||||||
|
if (req.user) {
|
||||||
|
res.status(200).redirect(`/@${req.user.channelName}`);
|
||||||
|
} else {
|
||||||
res.status(200).render('login');
|
res.status(200).render('login');
|
||||||
});
|
}
|
||||||
app.get('/signup', (req, res) => {
|
|
||||||
res.status(200).render('signup');
|
|
||||||
});
|
});
|
||||||
// route to display login page
|
// route to display login page
|
||||||
// app.get('/users/:name', isAuthenticated, (req, res) => {
|
// app.get('/users/:name', isAuthenticated, (req, res) => {
|
||||||
|
@ -50,7 +55,9 @@ module.exports = (app) => {
|
||||||
getTrendingClaims(dateTime)
|
getTrendingClaims(dateTime)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
// logger.debug(result);
|
// logger.debug(result);
|
||||||
res.status(200).render('trending', { trendingAssets: result });
|
res.status(200).render('trending', {
|
||||||
|
trendingAssets: result,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
errorHandlers.handleRequestError(error, res);
|
errorHandlers.handleRequestError(error, res);
|
||||||
|
@ -61,21 +68,26 @@ module.exports = (app) => {
|
||||||
getRecentClaims()
|
getRecentClaims()
|
||||||
.then(result => {
|
.then(result => {
|
||||||
// logger.debug(result);
|
// logger.debug(result);
|
||||||
res.status(200).render('new', { newClaims: result });
|
res.status(200).render('new', {
|
||||||
|
newClaims: result,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
errorHandlers.handleRequestError(error, res);
|
errorHandlers.handleRequestError(error, res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// route to show statistics for spee.ch
|
// route to show statistics for spee.ch
|
||||||
app.get('/stats', ({ ip, originalUrl }, res) => {
|
app.get('/stats', ({ ip, originalUrl, user }, res) => {
|
||||||
// get and render the content
|
// get and render the content
|
||||||
const startDate = new Date();
|
const startDate = new Date();
|
||||||
startDate.setDate(startDate.getDate() - 1);
|
startDate.setDate(startDate.getDate() - 1);
|
||||||
getStatsSummary(startDate)
|
getStatsSummary(startDate)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
postToStats('show', originalUrl, ip, null, null, 'success');
|
postToStats('show', originalUrl, ip, null, null, 'success');
|
||||||
res.status(200).render('statistics', result);
|
res.status(200).render('statistics', {
|
||||||
|
user,
|
||||||
|
result,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
errorHandlers.handleRequestError(error, res);
|
errorHandlers.handleRequestError(error, res);
|
||||||
|
@ -91,20 +103,8 @@ module.exports = (app) => {
|
||||||
res.status(200).render('embed', { layout: 'embed', claimId, name });
|
res.status(200).render('embed', { layout: 'embed', claimId, name });
|
||||||
});
|
});
|
||||||
// route to display all free public claims at a given name
|
// route to display all free public claims at a given name
|
||||||
app.get('/:name/all', ({ ip, originalUrl, params }, res) => {
|
app.get('/:name/all', (req, res) => {
|
||||||
// get and render the content
|
// get and render the content
|
||||||
db
|
res.status(410).send('/:name/all is no longer supported');
|
||||||
.getAllFreeClaims(params.name)
|
|
||||||
.then(orderedFreeClaims => {
|
|
||||||
if (!orderedFreeClaims) {
|
|
||||||
res.status(307).render('noClaims');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
postToStats('show', originalUrl, ip, null, null, 'success');
|
|
||||||
res.status(200).render('allClaims', { claims: orderedFreeClaims });
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
errorHandlers.handleRequestError('show', originalUrl, ip, error, res);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
24
speech.js
24
speech.js
|
@ -22,35 +22,35 @@ require('./config/slackLoggerConfig.js')(logger);
|
||||||
|
|
||||||
// trust the proxy to get ip address for us
|
// trust the proxy to get ip address for us
|
||||||
app.enable('trust proxy');
|
app.enable('trust proxy');
|
||||||
|
|
||||||
// add middleware
|
// add middleware
|
||||||
app.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties
|
app.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties
|
||||||
app.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory
|
app.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory
|
||||||
app.use(bodyParser.json()); // 'body parser' for parsing application/json
|
app.use(bodyParser.json()); // 'body parser' for parsing application/json
|
||||||
app.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded
|
app.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded
|
||||||
app.use(siofu.router); // 'socketio-file-upload' router for uploading with socket.io
|
app.use(siofu.router); // 'socketio-file-upload' router for uploading with socket.io
|
||||||
app.use((req, res, next) => { // custom logging middleware to log all incomming http requests
|
app.use((req, res, next) => { // custom logging middleware to log all incoming http requests
|
||||||
logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`);
|
logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
// initialize passport
|
// initialize passport
|
||||||
app.use(session({ secret: 'cats' }));
|
app.use(session({ secret: 'cats' }));
|
||||||
app.use(passport.initialize());
|
app.use(passport.initialize());
|
||||||
app.use(passport.session());
|
app.use(passport.session());
|
||||||
passport.serializeUser(function (user, done) {
|
passport.serializeUser((user, done) => {
|
||||||
done(null, user.id);
|
done(null, user.id);
|
||||||
});
|
});
|
||||||
|
passport.deserializeUser((id, done) => {
|
||||||
passport.deserializeUser(function (id, done) {
|
|
||||||
db.User.findOne({ where: { id } })
|
db.User.findOne({ where: { id } })
|
||||||
.then(user => {
|
.then(user => {
|
||||||
done(null, user.dataValues);
|
done(null, user); // user.dataValues?
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
logger.error('sequelize error', error);
|
logger.error('sequelize error', error);
|
||||||
|
done(error, null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load passport strategies
|
|
||||||
const localSignupStrategy = require('./passport/local-signup.js');
|
const localSignupStrategy = require('./passport/local-signup.js');
|
||||||
const localLoginStrategy = require('./passport/local-login.js');
|
const localLoginStrategy = require('./passport/local-login.js');
|
||||||
passport.use('local-signup', localSignupStrategy);
|
passport.use('local-signup', localSignupStrategy);
|
||||||
|
@ -65,6 +65,16 @@ const hbs = expressHandlebars.create({
|
||||||
app.engine('handlebars', hbs.engine);
|
app.engine('handlebars', hbs.engine);
|
||||||
app.set('view engine', 'handlebars');
|
app.set('view engine', 'handlebars');
|
||||||
|
|
||||||
|
// middleware to pass user info back to client, if user is logged in
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
if (req.user) {
|
||||||
|
res.locals.user = {
|
||||||
|
id : req.user.id,
|
||||||
|
channelName: req.user.channelName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
// start the server
|
// start the server
|
||||||
db.sequelize
|
db.sequelize
|
||||||
.sync() // sync sequelize
|
.sync() // sync sequelize
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<div class="wrapper">
|
|
||||||
{{> topBar}}
|
|
||||||
<div>
|
|
||||||
<h3>All Claims</h3>
|
|
||||||
<p>These are all the free, public assets at that claim. You can publish more at <a href="/">spee.ch</a>.</p>
|
|
||||||
{{#each claims}}
|
|
||||||
<div class="all-claims-item">
|
|
||||||
<img class="all-claims-asset" src="/{{this.claimId}}/{{this.name}}.test" />
|
|
||||||
<div class="all-claims-details">
|
|
||||||
<ul style="list-style-type:none">
|
|
||||||
<li>claim: {{this.name}}</li>
|
|
||||||
<li>claim_id: {{this.claim_id}}</li>
|
|
||||||
<li>link: <a href="/{{this.claimId}}/{{this.name}}">spee.ch/{{this.name}}/{{this.claimId}}</a></li>
|
|
||||||
<li>author: {{this.value.stream.metadata.author}}</li>
|
|
||||||
<li>description: {{this.value.stream.metadata.description}}</li>
|
|
||||||
<li>license: {{this.value.stream.metadata.license}}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
{{> footer}}
|
|
||||||
</div>
|
|
|
@ -1,20 +1,39 @@
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
{{> topBar}}
|
{{> topBar}}
|
||||||
<div class="full">
|
<div class="full">
|
||||||
|
|
||||||
<h2>Log In</h2>
|
<h2>Log In</h2>
|
||||||
|
<p>Log in to an existing channel</p>
|
||||||
<form id="login-form" action="/login" method="post">
|
<form id="login-form" action="/login" method="post">
|
||||||
<div>
|
<div>
|
||||||
<label>Username:</label>
|
<label>Username:</label>
|
||||||
<input type="text" name="username"/>
|
@ <input type="text" name="username" class="input-text--primary"/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Password:</label>
|
<label>Password:</label>
|
||||||
<input type="password" name="password"/>
|
<input type="password" name="password" class="input-text--primary"/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="submit" value="Log In"/>
|
<input type="submit" value="Log In"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<h2>Create New</h2>
|
||||||
|
<p>Create a brand new channel</p>
|
||||||
|
<form action="/signup" method="post">
|
||||||
|
<div>
|
||||||
|
<label>Channel name:</label>
|
||||||
|
@ <input type="text" name="username" class="input-text--primary"/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Password:</label>
|
||||||
|
<input type="password" name="password" class="input-text--primary"/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="submit" value="Create"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{> footer}}
|
{{> footer}}
|
||||||
</div>
|
</div>
|
||||||
|
|
38
views/partials/publishChannel.handlebars
Normal file
38
views/partials/publishChannel.handlebars
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<div id="claim-channel-input-area">
|
||||||
|
<label for="publish-channel">Channel:</label></td>
|
||||||
|
<select type="text" id="publish-channel" name="channel" value="channel" onclick="check(event)">
|
||||||
|
{{#if user}}
|
||||||
|
<option value="@{{user.channelName}}" >@{{user.channelName}}</option>
|
||||||
|
{{/if}}
|
||||||
|
<option value="@speech" >Anonymous</option>
|
||||||
|
<option value="new" >New</option>
|
||||||
|
</select>
|
||||||
|
<div id="channel-create-details" hidden="true"><p id="test" style="color: red;"></p>
|
||||||
|
<label for="channelName">Channel Name: </label>
|
||||||
|
@<input type="text" id="channel-name-input" class="input-text--primary" oninput="checkChannelName(event)">
|
||||||
|
<br/>
|
||||||
|
<label for="password" >Password: </label>
|
||||||
|
<input type="text" id="password" class="input-text--primary">
|
||||||
|
<br/>
|
||||||
|
<button >create</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
// toggle channel creation tool
|
||||||
|
const createChannelTool = document.getElementById('channel-create-details');
|
||||||
|
function check(event) {
|
||||||
|
const selectedOption = event.target.selectedOptions[0].value;
|
||||||
|
console.log(selectedOption);
|
||||||
|
if (selectedOption === 'new') {
|
||||||
|
createChannelTool.hidden = false;
|
||||||
|
} else {
|
||||||
|
createChannelTool.hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createChannel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
28
views/partials/publishDetails.handlebars
Normal file
28
views/partials/publishDetails.handlebars
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<p>Details
|
||||||
|
<a class="toggle-link" id="details-toggle" href="#" onclick="toggleSection(event)" data-open="false" data-slaveelementid="details-detail">[open]</a>
|
||||||
|
</p>
|
||||||
|
<div id="details-detail" hidden="true">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><label for="publish-title">Title: </label></td>
|
||||||
|
<td><input type="text" id="publish-title" class="input-text--primary"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="publish-description">Description: </label></td>
|
||||||
|
<td><textarea rows="2" id="publish-description"> </textarea></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="publish-license">License:* </label></td>
|
||||||
|
<td>
|
||||||
|
<select type="text" id="publish-license" name="license" value="license">
|
||||||
|
<option value="Public Domain">Public Domain</option>
|
||||||
|
<option value="Creative Commons">Creative Commons</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="publish-nsfw">NSFW*</label></td>
|
||||||
|
<td><input type="checkbox" id="publish-nsfw"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
|
@ -12,41 +12,24 @@
|
||||||
<div class="col-right">
|
<div class="col-right">
|
||||||
<div id="publish-active-area">
|
<div id="publish-active-area">
|
||||||
<div class="input-error" id="input-error-claim-name" hidden="true"></div>
|
<div class="input-error" id="input-error-claim-name" hidden="true"></div>
|
||||||
<div id="claim-name-input-area">
|
<div class="stop-float">
|
||||||
Spee.ch/<input type="text" id="claim-name-input" placeholder="your-url-here" oninput="checkClaimName(event.target.value)">
|
<p>
|
||||||
|
Spee.ch/
|
||||||
|
<input type="text" id="claim-name-input" class="input-text--primary" placeholder="your-url-here" oninput="checkClaimName(event.target.value)">
|
||||||
<span id="claim-name-available" hidden="true" style="color: green">✔</span>
|
<span id="claim-name-available" hidden="true" style="color: green">✔</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="stop-float">
|
<div class="stop-float">
|
||||||
<table>
|
{{> publishChannel}}
|
||||||
<tr>
|
</div>
|
||||||
<td><label for="publish-title">Title: </label></td>
|
<div class="stop-float">
|
||||||
<td><input type="text" id="publish-title" class="publish-input"></td>
|
{{> publishDetails}}
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><label for="publish-description">Description: </label></td>
|
|
||||||
<td><textarea rows="2" id="publish-description" class="publish-input"> </textarea></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><label for="publish-license">License:* </label></td>
|
|
||||||
<td>
|
|
||||||
<select type="text" id="publish-license" name="license" value="license">
|
|
||||||
<option value="Public Domain">Public Domain</option>
|
|
||||||
<option value="Creative Commons">Creative Commons</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><label for="publish-nsfw">NSFW*</label></td>
|
|
||||||
<td><input type="checkbox" id="publish-nsfw"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<div class="input-error" id="input-error-publish-submit" hidden="true"></div>
|
<div class="input-error" id="input-error-publish-submit" hidden="true"></div>
|
||||||
<button id="publish-submit" onclick="publishSelectedImage(event)">Publish</button>
|
<button id="publish-submit" onclick="publishSelectedImage(event)">Publish</button>
|
||||||
<button onclick="resetPublishArea()">Reset</button>
|
<button onclick="resetPublishArea()">Reset</button>
|
||||||
</p>
|
</p>
|
||||||
<p><i>By clicking 'Publish' I attest that I have read and agree to the <a href="https://lbry.io/termsofservice" target="_blank">LBRY terms of service</a>.</i></p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,7 +56,5 @@
|
||||||
document.getElementById('input-error-claim-name').innerHTML = '';
|
document.getElementById('input-error-claim-name').innerHTML = '';
|
||||||
document.getElementById('input-error-publish-submit').innerHTML = '';
|
document.getElementById('input-error-publish-submit').innerHTML = '';
|
||||||
document.getElementById('claim-name-available').hidden = true;
|
document.getElementById('claim-name-available').hidden = true;
|
||||||
// remove nsfw check
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,5 +4,12 @@
|
||||||
<a href="/popular" class="top-bar-right">popular</a>
|
<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="https://github.com/lbryio/spee.ch" target="_blank" class="top-bar-right">source</a>
|
||||||
<a href="/about" class="top-bar-right">help</a>
|
<a href="/about" class="top-bar-right">help</a>
|
||||||
|
|
||||||
|
{{#if user}}
|
||||||
|
<a href="/@{{user.channelName}}" class="top-bar-right">@{{user.channelName}}</a>
|
||||||
|
<a href="/logout" class="top-bar-right">logout</a>
|
||||||
|
{{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 class="top-bar-tagline">Open-source, decentralized image and video hosting.</div>
|
||||||
</div>
|
</div>
|
|
@ -1,11 +0,0 @@
|
||||||
<div class="wrapper">
|
|
||||||
{{> topBar}}
|
|
||||||
<div class="full">
|
|
||||||
{{#if isAuthenticated}}
|
|
||||||
{{> profile }}
|
|
||||||
{{else}}
|
|
||||||
{{> loginForm}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{> footer}}
|
|
||||||
</div>
|
|
|
@ -1,20 +0,0 @@
|
||||||
<div class="wrapper">
|
|
||||||
{{> topBar}}
|
|
||||||
<div class="full">
|
|
||||||
<h2>Sign up</h2>
|
|
||||||
<form action="/signup" method="post">
|
|
||||||
<div>
|
|
||||||
<label>Username:</label>
|
|
||||||
<input type="text" name="username"/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label>Password:</label>
|
|
||||||
<input type="password" name="password"/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<input type="submit" value="Log In"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{{> footer}}
|
|
||||||
</div>
|
|
Loading…
Reference in a new issue