React router #343
20
README.md
|
@ -29,20 +29,20 @@ spee.ch is a single-serving site that reads and publishes images and videos to a
|
||||||
## API
|
## API
|
||||||
|
|
||||||
#### GET
|
#### GET
|
||||||
* /api/claim-resolve/:name
|
* /api/claim/resolve/:name/:claimId
|
||||||
* example: `curl https://spee.ch/api/claim-resolve/doitlive`
|
* example: `curl https://spee.ch/api/claim/resolve/doitlive/xyz`
|
||||||
* /api/claim-list/:name
|
* /api/claim/list/:name
|
||||||
* example: `curl https://spee.ch/api/claim-list/doitlive`
|
* example: `curl https://spee.ch/api/claim/list/doitlive`
|
||||||
* /api/claim-is-available/:name (
|
* /api/claim/availability/:name (
|
||||||
* returns `true`/`false` for whether a name is available through spee.ch
|
* returns `true`/`false` for whether a name is available through spee.ch
|
||||||
* example: `curl https://spee.ch/api/claim-is-available/doitlive`
|
* example: `curl https://spee.ch/api/claim/availability/doitlive`
|
||||||
* /api/channel-is-available/:name (
|
* /api/channel/availability/:name (
|
||||||
* returns `true`/`false` for whether a channel is available through spee.ch
|
* returns `true`/`false` for whether a channel is available through spee.ch
|
||||||
* example: `curl https://spee.ch/api/channel-is-available/@CoolChannel`
|
* example: `curl https://spee.ch/api/channel/availability/@CoolChannel`
|
||||||
|
|
||||||
#### POST
|
#### POST
|
||||||
* /api/claim-publish
|
* /api/claim/publish
|
||||||
* example: `curl -X POST -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg' https://spee.ch/api/claim-publish`
|
* example: `curl -X POST -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg' https://spee.ch/api/claim/publish`
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* `name`
|
* `name`
|
||||||
* `file` (must be type .mp4, .jpeg, .jpg, .gif, or .png)
|
* `file` (must be type .mp4, .jpeg, .jpg, .gif, or .png)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const db = require('../models');
|
const db = require('../models');
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
const { returnPaginatedChannelViewData } = require('../helpers/channelPagination.js');
|
const { returnPaginatedChannelClaims } = require('../helpers/channelPagination.js');
|
||||||
|
|
||||||
const NO_CHANNEL = 'NO_CHANNEL';
|
const NO_CHANNEL = 'NO_CHANNEL';
|
||||||
const NO_CLAIM = 'NO_CLAIM';
|
const NO_CLAIM = 'NO_CLAIM';
|
||||||
|
@ -53,7 +53,7 @@ module.exports = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getChannelViewData (channelName, channelClaimId, query) {
|
getChannelData (channelName, channelClaimId, page) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 1. get the long channel Id (make sure channel exists)
|
// 1. get the long channel Id (make sure channel exists)
|
||||||
db.Certificate.getLongChannelId(channelName, channelClaimId)
|
db.Certificate.getLongChannelId(channelName, channelClaimId)
|
||||||
|
@ -62,14 +62,41 @@ module.exports = {
|
||||||
return [null, null, null];
|
return [null, null, null];
|
||||||
}
|
}
|
||||||
// 2. get the short ID and all claims for that channel
|
// 2. get the short ID and all claims for that channel
|
||||||
return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName), db.Claim.getAllChannelClaims(longChannelClaimId)]);
|
return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);
|
||||||
})
|
})
|
||||||
.then(([longChannelClaimId, shortChannelClaimId, channelClaimsArray]) => {
|
.then(([longChannelClaimId, shortChannelClaimId]) => {
|
||||||
|
if (!longChannelClaimId) {
|
||||||
|
return resolve(NO_CHANNEL);
|
||||||
|
}
|
||||||
|
// 3. return all the channel information
|
||||||
|
resolve({
|
||||||
|
channelName,
|
||||||
|
longChannelClaimId,
|
||||||
|
shortChannelClaimId,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getChannelClaims (channelName, channelClaimId, page) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 1. get the long channel Id (make sure channel exists)
|
||||||
|
db.Certificate.getLongChannelId(channelName, channelClaimId)
|
||||||
|
.then(longChannelClaimId => {
|
||||||
|
if (!longChannelClaimId) {
|
||||||
|
return [null, null, null];
|
||||||
|
}
|
||||||
|
// 2. get the short ID and all claims for that channel
|
||||||
|
return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);
|
||||||
|
})
|
||||||
|
.then(([longChannelClaimId, channelClaimsArray]) => {
|
||||||
if (!longChannelClaimId) {
|
if (!longChannelClaimId) {
|
||||||
return resolve(NO_CHANNEL);
|
return resolve(NO_CHANNEL);
|
||||||
}
|
}
|
||||||
// 3. format the data for the view, including pagination
|
// 3. format the data for the view, including pagination
|
||||||
let paginatedChannelViewData = returnPaginatedChannelViewData(channelName, longChannelClaimId, shortChannelClaimId, channelClaimsArray, query);
|
let paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);
|
||||||
// 4. return all the channel information and contents
|
// 4. return all the channel information and contents
|
||||||
resolve(paginatedChannelViewData);
|
resolve(paginatedChannelViewData);
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,25 +1,24 @@
|
||||||
const CLAIMS_PER_PAGE = 10;
|
const CLAIMS_PER_PAGE = 12;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
returnPaginatedChannelViewData (channelName, longChannelClaimId, shortChannelClaimId, claims, query) {
|
returnPaginatedChannelClaims (channelName, longChannelClaimId, claims, page) {
|
||||||
const totalPages = module.exports.determineTotalPages(claims);
|
const totalPages = module.exports.determineTotalPages(claims);
|
||||||
const paginationPage = module.exports.getPageFromQuery(query);
|
const paginationPage = module.exports.getPageFromQuery(page);
|
||||||
const viewData = {
|
const viewData = {
|
||||||
channelName : channelName,
|
channelName : channelName,
|
||||||
longChannelClaimId : longChannelClaimId,
|
longChannelClaimId: longChannelClaimId,
|
||||||
shortChannelClaimId: shortChannelClaimId,
|
claims : module.exports.extractPageFromClaims(claims, paginationPage),
|
||||||
claims : module.exports.extractPageFromClaims(claims, paginationPage),
|
previousPage : module.exports.determinePreviousPage(paginationPage),
|
||||||
previousPage : module.exports.determinePreviousPage(paginationPage),
|
currentPage : paginationPage,
|
||||||
currentPage : paginationPage,
|
nextPage : module.exports.determineNextPage(totalPages, paginationPage),
|
||||||
nextPage : module.exports.determineNextPage(totalPages, paginationPage),
|
totalPages : totalPages,
|
||||||
totalPages : totalPages,
|
totalResults : module.exports.determineTotalClaims(claims),
|
||||||
totalResults : module.exports.determineTotalClaims(claims),
|
|
||||||
};
|
};
|
||||||
return viewData;
|
return viewData;
|
||||||
},
|
},
|
||||||
getPageFromQuery (query) {
|
getPageFromQuery (page) {
|
||||||
if (query.p) {
|
if (page) {
|
||||||
return parseInt(query.p);
|
return parseInt(page);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
|
@ -30,7 +29,7 @@ module.exports = {
|
||||||
// logger.debug('claims is array?', Array.isArray(claims));
|
// logger.debug('claims is array?', Array.isArray(claims));
|
||||||
// logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));
|
// logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));
|
||||||
const claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;
|
const claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;
|
||||||
const claimEndIndex = claimStartIndex + 10;
|
const claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;
|
||||||
const pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);
|
const pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);
|
||||||
return pageOfClaims;
|
return pageOfClaims;
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,51 +1,30 @@
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
handleErrorResponse: function (originalUrl, ip, error, res) {
|
||||||
I am trying to create a pattern where the server responds with a 200 as long as it processed the request correctly, and then responds with a I am trying to create a pattern where the server responds with a 200 as long as it processed the request correctly, and then responds with a `success` and a `message` or `data` field. I.e. `{"success": "false", "message": "connection refused. The daemon may not be running"}`. This way, if the client wanted some data but the daemon was off, it would get a `200` response that the request was completed, and then the client could check the response to see if it was successful or not and whether the data is present. My goal was to help myself (and api users) to distinguish between an error where something was unavailable but the request was handled properly (resulting in a `200`) vs a request that I thought would be handled but wasn't, resulting in some other error. Thoughts?
I think proper error codes would still be preferable. Even if the request is handled properly, there is still an error. If I see a 200 response, I assume my request was successful. The
In my opinion it doesn't really matter if a request was handled successfully. If the data doesn't make it, it still fails. You can still add info with the error message and code. I think proper error codes would still be preferable. Even if the request is handled properly, there is still an error. If I see a 200 response, I assume my request was successful. The `fetch` api handles errors really nicely too, so I think if anything you are creating more work.
```
fetch('spee.ch/xxx')
.then((data) => ...) // successful
.catch((error) => ...) // not successful
fetch('spee.ch/xxx')
.then((data) => { // maybe successful?
if (!data.success) {
throw new Error()
}
... // ok now I know it was successful
})
.catch((err) => ... ) // not successful
```
In my opinion it doesn't really matter if a request was handled successfully. If the data doesn't make it, it still fails. You can still add info with the error message and code.
That makes a lot of sense, and I was running into a lot of the latter situation where I had to check That makes a lot of sense, and I was running into a lot of the latter situation where I had to check `success` in addition to checking for errors. I updated it and that cleaned up the response handling a lot.
|
|||||||
|
logger.error(`Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
|
||||||
|
const [status, message] = module.exports.returnErrorMessageAndStatus(error);
|
||||||
|
res
|
||||||
|
.status(status)
|
||||||
|
.json(module.exports.createErrorResponsePayload(status, message));
|
||||||
|
},
|
||||||
returnErrorMessageAndStatus: function (error) {
|
returnErrorMessageAndStatus: function (error) {
|
||||||
let status, message;
|
let status, message;
|
||||||
// check for daemon being turned off
|
// check for daemon being turned off
|
||||||
if (error.code === 'ECONNREFUSED') {
|
if (error.code === 'ECONNREFUSED') {
|
||||||
status = 503;
|
status = 503;
|
||||||
message = 'Connection refused. The daemon may not be running.';
|
message = 'Connection refused. The daemon may not be running.';
|
||||||
// check for errors from the daemon
|
// fallback for everything else
|
||||||
} else if (error.response) {
|
|
||||||
status = error.response.status || 500;
|
|
||||||
if (error.response.data) {
|
|
||||||
if (error.response.data.message) {
|
|
||||||
message = error.response.data.message;
|
|
||||||
} else if (error.response.data.error) {
|
|
||||||
message = error.response.data.error.message;
|
|
||||||
} else {
|
|
||||||
message = error.response.data;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message = error.response;
|
|
||||||
}
|
|
||||||
// check for thrown errors
|
|
||||||
} else if (error.message) {
|
|
||||||
status = 400;
|
|
||||||
message = error.message;
|
|
||||||
// fallback for everything else
|
|
||||||
} else {
|
} else {
|
||||||
status = 400;
|
status = 400;
|
||||||
message = error;
|
if (error.message) {
|
||||||
}
|
message = error.message;
|
||||||
|
} else {
|
||||||
|
message = error;
|
||||||
|
};
|
||||||
|
};
|
||||||
return [status, message];
|
return [status, message];
|
||||||
},
|
},
|
||||||
handleRequestError: function (originalUrl, ip, error, res) {
|
|
||||||
logger.error(`Request Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
|
|
||||||
const [status, message] = module.exports.returnErrorMessageAndStatus(error);
|
|
||||||
res
|
|
||||||
.status(status)
|
|
||||||
.render('requestError', module.exports.createErrorResponsePayload(status, message));
|
|
||||||
},
|
|
||||||
handleApiError: function (originalUrl, ip, error, res) {
|
|
||||||
logger.error(`Api Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
|
|
||||||
const [status, message] = module.exports.returnErrorMessageAndStatus(error);
|
|
||||||
res
|
|
||||||
.status(status)
|
|
||||||
.json(module.exports.createErrorResponsePayload(status, message));
|
|
||||||
},
|
|
||||||
useObjectPropertiesIfNoKeys: function (err) {
|
useObjectPropertiesIfNoKeys: function (err) {
|
||||||
if (Object.keys(err).length === 0) {
|
if (Object.keys(err).length === 0) {
|
||||||
let newErrorObject = {};
|
let newErrorObject = {};
|
||||||
|
|
|
@ -10,13 +10,13 @@ function handleLbrynetResponse ({ data }, resolve, reject) {
|
||||||
// check for an error
|
// check for an error
|
||||||
if (data.result.error) {
|
if (data.result.error) {
|
||||||
logger.debug('Lbrynet api error:', data.result.error);
|
logger.debug('Lbrynet api error:', data.result.error);
|
||||||
reject(data.result.error);
|
reject(new Error(data.result.error));
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
resolve(data.result);
|
resolve(data.result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// fallback in case the just timed out
|
// fallback in case it just timed out
|
||||||
reject(JSON.stringify(data));
|
reject(JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,14 +55,14 @@ module.exports = {
|
||||||
claimId,
|
claimId,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
parseName: function (name) {
|
parseClaim: function (claim) {
|
||||||
logger.debug('parsing name:', name);
|
logger.debug('parsing name:', claim);
|
||||||
const componentsRegex = new RegExp(
|
const componentsRegex = new RegExp(
|
||||||
'([^:$#/.]*)' + // name (stops at the first modifier)
|
'([^:$#/.]*)' + // name (stops at the first modifier)
|
||||||
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
|
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
|
||||||
);
|
);
|
||||||
const [proto, claimName, modifierSeperator, modifier] = componentsRegex
|
const [proto, claimName, modifierSeperator, modifier] = componentsRegex
|
||||||
.exec(name)
|
.exec(claim)
|
||||||
.map(match => match || null);
|
.map(match => match || null);
|
||||||
logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);
|
logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);
|
||||||
|
|
||||||
|
@ -75,7 +75,6 @@ module.exports = {
|
||||||
throw new Error(`Invalid characters in claim name: ${nameBadChars.join(', ')}.`);
|
throw new Error(`Invalid characters in claim name: ${nameBadChars.join(', ')}.`);
|
||||||
}
|
}
|
||||||
// Validate and process modifier
|
// Validate and process modifier
|
||||||
let isServeRequest = false;
|
|
||||||
if (modifierSeperator) {
|
if (modifierSeperator) {
|
||||||
if (!modifier) {
|
if (!modifier) {
|
||||||
throw new Error(`No file extension provided after separator ${modifierSeperator}.`);
|
throw new Error(`No file extension provided after separator ${modifierSeperator}.`);
|
||||||
|
@ -83,11 +82,29 @@ module.exports = {
|
||||||
if (modifierSeperator !== '.') {
|
if (modifierSeperator !== '.') {
|
||||||
throw new Error(`The ${modifierSeperator} modifier is not supported in the claim name`);
|
throw new Error(`The ${modifierSeperator} modifier is not supported in the claim name`);
|
||||||
}
|
}
|
||||||
isServeRequest = true;
|
|
||||||
}
|
}
|
||||||
|
// return results
|
||||||
return {
|
return {
|
||||||
claimName,
|
claimName,
|
||||||
isServeRequest,
|
};
|
||||||
|
},
|
||||||
|
parseModifier: function (claim) {
|
||||||
|
logger.debug('parsing modifier:', claim);
|
||||||
|
const componentsRegex = new RegExp(
|
||||||
|
'([^:$#/.]*)' + // name (stops at the first modifier)
|
||||||
|
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
|
||||||
|
);
|
||||||
|
const [proto, claimName, modifierSeperator, modifier] = componentsRegex
|
||||||
|
.exec(claim)
|
||||||
|
.map(match => match || null);
|
||||||
|
logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);
|
||||||
|
// Validate and process modifier
|
||||||
|
let hasFileExtension = false;
|
||||||
|
if (modifierSeperator) {
|
||||||
|
hasFileExtension = true;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
hasFileExtension,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,10 +16,10 @@ module.exports = {
|
||||||
},
|
},
|
||||||
showFile (claimInfo, shortId, res) {
|
showFile (claimInfo, shortId, res) {
|
||||||
logger.verbose(`showing claim: ${claimInfo.name}#${claimInfo.claimId}`);
|
logger.verbose(`showing claim: ${claimInfo.name}#${claimInfo.claimId}`);
|
||||||
res.status(200).render('show', { layout: 'show', claimInfo, shortId });
|
res.status(200).render('index');
|
||||||
},
|
},
|
||||||
showFileLite (claimInfo, shortId, res) {
|
showFileLite (claimInfo, shortId, res) {
|
||||||
logger.verbose(`showlite claim: ${claimInfo.name}#${claimInfo.claimId}`);
|
logger.verbose(`showlite claim: ${claimInfo.name}#${claimInfo.claimId}`);
|
||||||
res.status(200).render('showLite', { layout: 'showlite', claimInfo, shortId });
|
res.status(200).render('index');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,7 +100,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {
|
Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {
|
||||||
logger.debug(`finding short channel id for ${channelName}:${longChannelId}`);
|
logger.debug(`getShortChannelIdFromLongChannelId ${channelName}:${longChannelId}`);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this
|
this
|
||||||
.findAll({
|
.findAll({
|
||||||
|
@ -122,6 +122,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {
|
Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {
|
||||||
|
logger.debug(`getLongChannelIdFromShortChannelId(${channelName}, ${channelClaimId})`);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this
|
this
|
||||||
.findAll({
|
.findAll({
|
||||||
|
@ -170,6 +171,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
Certificate.validateLongChannelId = function (name, claimId) {
|
Certificate.validateLongChannelId = function (name, claimId) {
|
||||||
|
logger.debug(`validateLongChannelId(${name}, ${claimId})`);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.findOne({
|
this.findOne({
|
||||||
where: {name, claimId},
|
where: {name, claimId},
|
||||||
|
|
|
@ -342,6 +342,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
Claim.resolveClaim = function (name, claimId) {
|
Claim.resolveClaim = function (name, claimId) {
|
||||||
|
logger.debug(`Claim.resolveClaim: ${name} ${claimId}`);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this
|
this
|
||||||
.findAll({
|
.findAll({
|
||||||
|
|
|
@ -47,7 +47,9 @@
|
||||||
"react": "^16.2.0",
|
"react": "^16.2.0",
|
||||||
"react-dom": "^16.2.0",
|
"react-dom": "^16.2.0",
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
|
"react-router-dom": "^4.2.2",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
|
"redux-saga": "^0.16.0",
|
||||||
"request": "^2.83.0",
|
"request": "^2.83.0",
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"sequelize": "^4.1.0",
|
"sequelize": "^4.1.0",
|
||||||
|
@ -61,6 +63,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
"babel-loader": "^7.1.2",
|
"babel-loader": "^7.1.2",
|
||||||
|
"babel-polyfill": "^6.26.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"babel-preset-stage-2": "^6.24.1",
|
"babel-preset-stage-2": "^6.24.1",
|
||||||
|
|
|
@ -276,7 +276,7 @@ a, a:visited {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.align-content-right {
|
.align-content-bottom {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,12 +407,13 @@ button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button--primary {
|
.button--primary, .button--primary:focus {
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
margin: 0.5em 0.3em 0.5em 0.3em;
|
margin: 0.5em 0.3em 0.5em 0.3em;
|
||||||
color: black;
|
color: black;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
outline: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button--primary:hover {
|
.button--primary:hover {
|
||||||
|
@ -422,9 +423,28 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.button--primary:active{
|
.button--primary:active{
|
||||||
border: 1px solid #4156C5;
|
border: 1px solid #ffffff;
|
||||||
color: white;
|
color: #d0d0d0;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--secondary, .button--secondary:focus {
|
||||||
|
border: 0px;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
padding: 0.5em;
|
||||||
|
margin: 0.5em 0.3em 0.5em 0.3em;
|
||||||
|
color: black;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
outline: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--secondary:hover {
|
||||||
|
border-bottom: 1px solid #9b9b9b;
|
||||||
|
color: #4156C5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--secondary:active {
|
||||||
|
color: #ffffff;;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button--large{
|
.button--large{
|
||||||
|
@ -495,7 +515,7 @@ table {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#asset-preview {
|
#dropzone-preview {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -506,6 +526,20 @@ table {
|
||||||
|
|
||||||
/* Assets */
|
/* Assets */
|
||||||
|
|
||||||
|
.asset-holder {
|
||||||
|
clear : both;
|
||||||
|
display: inline-block;
|
||||||
|
width : 31%;
|
||||||
|
padding: 0px;
|
||||||
|
margin : 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-preview {
|
||||||
|
width : 100%;
|
||||||
|
padding: 0px;
|
||||||
|
margin : 0px
|
||||||
|
}
|
||||||
|
|
||||||
.asset {
|
.asset {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 9 KiB |
|
@ -1,139 +0,0 @@
|
||||||
const Asset = function () {
|
|
||||||
this.data = {};
|
|
||||||
this.addPlayPauseToVideo = function () {
|
|
||||||
const that = this;
|
|
||||||
const video = document.getElementById('video-asset');
|
|
||||||
if (video) {
|
|
||||||
// add event listener for click
|
|
||||||
video.addEventListener('click', ()=> {
|
|
||||||
that.playOrPause(video);
|
|
||||||
});
|
|
||||||
// add event listener for space bar
|
|
||||||
document.body.onkeyup = (event) => {
|
|
||||||
if (event.keyCode == 32) {
|
|
||||||
that.playOrPause(video);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.playOrPause = function(video){
|
|
||||||
if (video.paused == true) {
|
|
||||||
video.play();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
video.pause();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.showAsset = function () {
|
|
||||||
this.hideAssetStatus();
|
|
||||||
this.showAssetHolder();
|
|
||||||
if (!this.data.src) {
|
|
||||||
return console.log('error: src is not set')
|
|
||||||
}
|
|
||||||
if (!this.data.contentType) {
|
|
||||||
return console.log('error: contentType is not set')
|
|
||||||
}
|
|
||||||
if (this.data.contentType === 'video/mp4') {
|
|
||||||
this.showVideo();
|
|
||||||
} else {
|
|
||||||
this.showImage();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.showVideo = function () {
|
|
||||||
console.log('showing video', this.data.src);
|
|
||||||
const video = document.getElementById('video-asset');
|
|
||||||
const source = document.createElement('source');
|
|
||||||
source.setAttribute('src', this.data.src);
|
|
||||||
video.appendChild(source);
|
|
||||||
video.play();
|
|
||||||
};
|
|
||||||
this.showImage = function () {
|
|
||||||
console.log('showing image', this.data.src);
|
|
||||||
const asset = document.getElementById('image-asset');
|
|
||||||
asset.setAttribute('src', this.data.src);
|
|
||||||
};
|
|
||||||
this.hideAssetStatus = function () {
|
|
||||||
const assetStatus = document.getElementById('asset-status');
|
|
||||||
assetStatus.hidden = true;
|
|
||||||
};
|
|
||||||
this.showAssetHolder =function () {
|
|
||||||
const assetHolder = document.getElementById('asset-holder');
|
|
||||||
assetHolder.hidden = false;
|
|
||||||
};
|
|
||||||
this.showSearchMessage = function () {
|
|
||||||
const searchMessage = document.getElementById('searching-message');
|
|
||||||
searchMessage.hidden = false;
|
|
||||||
};
|
|
||||||
this.showFailureMessage = function (msg) {
|
|
||||||
console.log(msg);
|
|
||||||
const searchMessage = document.getElementById('searching-message');
|
|
||||||
const failureMessage = document.getElementById('failure-message');
|
|
||||||
const errorMessage = document.getElementById('error-message');
|
|
||||||
searchMessage.hidden = true;
|
|
||||||
failureMessage.hidden = false;
|
|
||||||
errorMessage.innerText = msg;
|
|
||||||
};
|
|
||||||
this.checkFileAndRenderAsset = function () {
|
|
||||||
const that = this;
|
|
||||||
this.isFileAvailable()
|
|
||||||
.then(isAvailable => {
|
|
||||||
if (!isAvailable) {
|
|
||||||
console.log('file is not yet available');
|
|
||||||
that.showSearchMessage();
|
|
||||||
return that.getAssetOnSpeech();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
that.showAsset();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
that.showFailureMessage(error);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
this.isFileAvailable = function () {
|
|
||||||
console.log(`checking if file is available for ${this.data.claimName}#${this.data.claimId}`)
|
|
||||||
const uri = `/api/file-is-available/${this.data.claimName}/${this.data.claimId}`;
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
xhr.open("GET", uri, true);
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
if (xhr.readyState == 4) {
|
|
||||||
const response = JSON.parse(xhr.response);
|
|
||||||
if (xhr.status == 200) {
|
|
||||||
console.log('isFileAvailable succeeded:', response);
|
|
||||||
if (response.message === true) {
|
|
||||||
resolve(true);
|
|
||||||
} else {
|
|
||||||
resolve(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('isFileAvailable failed:', response);
|
|
||||||
reject('Well this sucks, but we can\'t seem to phone home');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.send();
|
|
||||||
})
|
|
||||||
};
|
|
||||||
this.getAssetOnSpeech = function() {
|
|
||||||
console.log(`getting claim for ${this.data.claimName}#${this.data.claimId}`)
|
|
||||||
const uri = `/api/claim-get/${this.data.claimName}/${this.data.claimId}`;
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
xhr.open("GET", uri, true);
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
if (xhr.readyState == 4) {
|
|
||||||
const response = JSON.parse(xhr.response);
|
|
||||||
if (xhr.status == 200) {
|
|
||||||
console.log('getAssetOnSpeech succeeded:', response)
|
|
||||||
resolve(true);
|
|
||||||
} else {
|
|
||||||
console.log('getAssetOnSpeech failed:', response);
|
|
||||||
reject(response.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.send();
|
|
||||||
})
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,65 +0,0 @@
|
||||||
// display the content that shows channel creation has started
|
|
||||||
function showChannelCreateInProgressDisplay () {
|
|
||||||
const publishChannelForm = document.getElementById('publish-channel-form');
|
|
||||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
|
||||||
publishChannelForm.hidden = true;
|
|
||||||
inProgress.hidden = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the content that shows channel creation is done
|
|
||||||
function showChannelCreateDoneDisplay() {
|
|
||||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
|
||||||
inProgress.hidden=true;
|
|
||||||
const done = document.getElementById('channel-publish-done');
|
|
||||||
done.hidden = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showChannelCreationError(msg) {
|
|
||||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
|
||||||
inProgress.innerText = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
function publishNewChannel (event) {
|
|
||||||
const username = document.getElementById('new-channel-name').value;
|
|
||||||
const password = document.getElementById('new-channel-password').value;
|
|
||||||
// prevent default so this script can handle submission
|
|
||||||
event.preventDefault();
|
|
||||||
// validate submission
|
|
||||||
validationFunctions.validateNewChannelSubmission(username, password)
|
|
||||||
.then(() => {
|
|
||||||
showChannelCreateInProgressDisplay();
|
|
||||||
// return sendAuthRequest(userName, password, '/signup') // post the request
|
|
||||||
return fetch('/signup', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({username, password}),
|
|
||||||
headers: new Headers({
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}),
|
|
||||||
credentials: 'include',
|
|
||||||
})
|
|
||||||
.then(function(response) {
|
|
||||||
if (response.ok){
|
|
||||||
return response.json();
|
|
||||||
} else {
|
|
||||||
throw response;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
throw error;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(signupResult => {
|
|
||||||
console.log('signup success:', signupResult);
|
|
||||||
showChannelCreateDoneDisplay();
|
|
||||||
window.location = '/';
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
if (error.name === 'ChannelNameError' || error.name === 'ChannelPasswordError'){
|
|
||||||
const channelNameErrorDisplayElement = document.getElementById('input-error-channel-name');
|
|
||||||
validationFunctions.showError(channelNameErrorDisplayElement, error.message);
|
|
||||||
} else {
|
|
||||||
console.log('signup failure:', error);
|
|
||||||
showChannelCreationError('Unfortunately, we encountered an error while creating your channel. Please let us know in slack!', error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
// Create new error objects, that prototypically inherit from the Error constructor
|
|
||||||
function FileError(message) {
|
|
||||||
this.name = 'FileError';
|
|
||||||
this.message = message || 'Default Message';
|
|
||||||
this.stack = (new Error()).stack;
|
|
||||||
}
|
|
||||||
FileError.prototype = Object.create(Error.prototype);
|
|
||||||
FileError.prototype.constructor = FileError;
|
|
||||||
|
|
||||||
function NameError(message) {
|
|
||||||
this.name = 'NameError';
|
|
||||||
this.message = message || 'Default Message';
|
|
||||||
this.stack = (new Error()).stack;
|
|
||||||
}
|
|
||||||
NameError.prototype = Object.create(Error.prototype);
|
|
||||||
NameError.prototype.constructor = NameError;
|
|
||||||
|
|
||||||
function ChannelNameError(message) {
|
|
||||||
this.name = 'ChannelNameError';
|
|
||||||
this.message = message || 'Default Message';
|
|
||||||
this.stack = (new Error()).stack;
|
|
||||||
}
|
|
||||||
ChannelNameError.prototype = Object.create(Error.prototype);
|
|
||||||
ChannelNameError.prototype.constructor = ChannelNameError;
|
|
||||||
|
|
||||||
function ChannelPasswordError(message) {
|
|
||||||
this.name = 'ChannelPasswordError';
|
|
||||||
this.message = message || 'Default Message';
|
|
||||||
this.stack = (new Error()).stack;
|
|
||||||
}
|
|
||||||
ChannelPasswordError.prototype = Object.create(Error.prototype);
|
|
||||||
ChannelPasswordError.prototype.constructor = ChannelPasswordError;
|
|
||||||
|
|
||||||
function AuthenticationError(message) {
|
|
||||||
this.name = 'AuthenticationError';
|
|
||||||
this.message = message || 'Default Message';
|
|
||||||
this.stack = (new Error()).stack;
|
|
||||||
}
|
|
||||||
AuthenticationError.prototype = Object.create(Error.prototype);
|
|
||||||
AuthenticationError.prototype.constructor = AuthenticationError;
|
|
||||||
|
|
||||||
function showAssetDetails(event) {
|
|
||||||
var thisAssetHolder = document.getElementById(event.target.id);
|
|
||||||
var thisAssetImage = thisAssetHolder.firstElementChild;
|
|
||||||
var thisAssetDetails = thisAssetHolder.lastElementChild;
|
|
||||||
thisAssetImage.style.opacity = 0.2;
|
|
||||||
thisAssetDetails.setAttribute('class', 'grid-item-details flex-container--column flex-container--center-center');
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideAssetDetails(event) {
|
|
||||||
var thisAssetHolder = document.getElementById(event.target.id);
|
|
||||||
var thisAssetImage = thisAssetHolder.firstElementChild;
|
|
||||||
var thisAssetDetails = thisAssetHolder.lastElementChild;
|
|
||||||
thisAssetImage.style.opacity = 1;
|
|
||||||
thisAssetDetails.setAttribute('class', 'hidden');
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
function loginToChannel (event) {
|
|
||||||
const username = document.getElementById('channel-login-name-input').value;
|
|
||||||
const password = document.getElementById('channel-login-password-input').value;
|
|
||||||
// prevent default
|
|
||||||
event.preventDefault()
|
|
||||||
validationFunctions.validateNewChannelLogin(username, password)
|
|
||||||
.then(() => {
|
|
||||||
return fetch('/login', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({username, password}),
|
|
||||||
headers: new Headers({
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}),
|
|
||||||
credentials: 'include',
|
|
||||||
})
|
|
||||||
.then(function(response) {
|
|
||||||
console.log(response);
|
|
||||||
if (response.ok){
|
|
||||||
return response.json();
|
|
||||||
} else {
|
|
||||||
throw response;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
throw error;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(function({success, message}) {
|
|
||||||
if (success) {
|
|
||||||
window.location = '/';
|
|
||||||
} else {
|
|
||||||
throw new Error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
const loginErrorDisplayElement = document.getElementById('login-error-display-element');
|
|
||||||
if (error.message){
|
|
||||||
validationFunctions.showError(loginErrorDisplayElement, error.message);
|
|
||||||
} else {
|
|
||||||
validationFunctions.showError(loginErrorDisplayElement, 'There was an error logging into your channel');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
const ProgressBar = function() {
|
|
||||||
this.data = {
|
|
||||||
x: 0,
|
|
||||||
adder: 1,
|
|
||||||
bars: [],
|
|
||||||
};
|
|
||||||
this.barHolder = document.getElementById('bar-holder');
|
|
||||||
this.createProgressBar = function (size) {
|
|
||||||
this.data['size'] = size;
|
|
||||||
for (var i = 0; i < size; i++) {
|
|
||||||
const bar = document.createElement('span');
|
|
||||||
bar.innerText = '| ';
|
|
||||||
bar.setAttribute('class', 'progress-bar progress-bar--inactive');
|
|
||||||
this.barHolder.appendChild(bar);
|
|
||||||
this.data.bars.push(bar);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.startProgressBar = function () {
|
|
||||||
this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300);
|
|
||||||
};
|
|
||||||
this.updateProgressBar = function () {
|
|
||||||
const x = this.data.x;
|
|
||||||
const adder = this.data.adder;
|
|
||||||
const size = this.data.size;
|
|
||||||
// update the appropriate bar
|
|
||||||
if (x > -1 && x < size){
|
|
||||||
if (adder === 1){
|
|
||||||
this.data.bars[x].setAttribute('class', 'progress-bar progress-bar--active');
|
|
||||||
} else {
|
|
||||||
this.data.bars[x].setAttribute('class', 'progress-bar progress-bar--inactive');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// update adder
|
|
||||||
if (x === size){
|
|
||||||
this.data['adder'] = -1;
|
|
||||||
} else if ( x === -1){
|
|
||||||
this.data['adder'] = 1;
|
|
||||||
}
|
|
||||||
// update x
|
|
||||||
this.data['x'] = x + adder;
|
|
||||||
};
|
|
||||||
this.stopProgressBar = function () {
|
|
||||||
clearInterval(this.updateInterval);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,132 +0,0 @@
|
||||||
// validation function which checks the proposed file's type, size, and name
|
|
||||||
const validationFunctions = {
|
|
||||||
validateChannelName: function (name) {
|
|
||||||
name = name.substring(name.indexOf('@') + 1);
|
|
||||||
// ensure a name was entered
|
|
||||||
if (name.length < 1) {
|
|
||||||
throw new ChannelNameError("You must enter a name for your channel");
|
|
||||||
}
|
|
||||||
// validate the characters in the 'name' field
|
|
||||||
const invalidCharacters = /[^A-Za-z0-9,-,@]/g.exec(name);
|
|
||||||
if (invalidCharacters) {
|
|
||||||
throw new ChannelNameError('"' + invalidCharacters + '" characters are not allowed');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
validatePassword: function (password) {
|
|
||||||
if (password.length < 1) {
|
|
||||||
throw new ChannelPasswordError("You must enter a password for you channel");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// validation functions to check claim & channel name eligibility as the inputs change
|
|
||||||
isChannelNameAvailable: function (name) {
|
|
||||||
return this.isNameAvailable(name, '/api/channel-is-available/');
|
|
||||||
},
|
|
||||||
isNameAvailable: function (name, apiUrl) {
|
|
||||||
console.log('isNameAvailable?', name);
|
|
||||||
const url = apiUrl + name;
|
|
||||||
return fetch(url)
|
|
||||||
.then(function (response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log('isNameAvailable error', error);
|
|
||||||
throw error;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showError: function (errorDisplay, errorMsg) {
|
|
||||||
errorDisplay.hidden = false;
|
|
||||||
errorDisplay.innerText = errorMsg;
|
|
||||||
},
|
|
||||||
hideError: function (errorDisplay) {
|
|
||||||
errorDisplay.hidden = true;
|
|
||||||
errorDisplay.innerText = '';
|
|
||||||
},
|
|
||||||
showSuccess: function (successElement) {
|
|
||||||
successElement.hidden = false;
|
|
||||||
successElement.innerHTML = "✔";
|
|
||||||
},
|
|
||||||
hideSuccess: function (successElement) {
|
|
||||||
successElement.hidden = true;
|
|
||||||
successElement.innerHTML = "";
|
|
||||||
},
|
|
||||||
checkChannelName: function (name) {
|
|
||||||
var successDisplayElement = document.getElementById('input-success-channel-name');
|
|
||||||
var errorDisplayElement = document.getElementById('input-error-channel-name');
|
|
||||||
var channelName = `@${name}`;
|
|
||||||
var that = this;
|
|
||||||
try {
|
|
||||||
// check to make sure the characters are valid
|
|
||||||
that.validateChannelName(channelName);
|
|
||||||
// check to make sure it is available
|
|
||||||
that.isChannelNameAvailable(channelName)
|
|
||||||
.then(function(isAvailable){
|
|
||||||
console.log('isChannelNameAvailable:', isAvailable);
|
|
||||||
if (isAvailable) {
|
|
||||||
that.hideError(errorDisplayElement);
|
|
||||||
that.showSuccess(successDisplayElement)
|
|
||||||
} else {
|
|
||||||
that.hideSuccess(successDisplayElement);
|
|
||||||
that.showError(errorDisplayElement, 'Sorry, that name is already taken');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
that.hideSuccess(successDisplayElement);
|
|
||||||
that.showError(errorDisplayElement, error.message);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
that.hideSuccess(successDisplayElement);
|
|
||||||
that.showError(errorDisplayElement, error.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// validation function which checks all aspects of a new channel submission
|
|
||||||
validateNewChannelSubmission: function (userName, password) {
|
|
||||||
const channelName = `@${userName}`;
|
|
||||||
var that = this;
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
// 1. validate name
|
|
||||||
try {
|
|
||||||
that.validateChannelName(channelName);
|
|
||||||
} catch (error) {
|
|
||||||
return reject(error);
|
|
||||||
}
|
|
||||||
// 2. validate password
|
|
||||||
try {
|
|
||||||
that.validatePassword(password);
|
|
||||||
} catch (error) {
|
|
||||||
return reject(error);
|
|
||||||
}
|
|
||||||
// 3. if all validation passes, check availability of the name
|
|
||||||
that.isChannelNameAvailable(channelName)
|
|
||||||
.then(function(isAvailable) {
|
|
||||||
if (isAvailable) {
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
reject(new ChannelNameError('Sorry, that name is already taken'));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// validation function which checks all aspects of a new channel login
|
|
||||||
validateNewChannelLogin: function (userName, password) {
|
|
||||||
const channelName = `@${userName}`;
|
|
||||||
var that = this;
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
// 1. validate name
|
|
||||||
try {
|
|
||||||
that.validateChannelName(channelName);
|
|
||||||
} catch (error) {
|
|
||||||
return reject(error);
|
|
||||||
}
|
|
||||||
// 2. validate password
|
|
||||||
try {
|
|
||||||
that.validatePassword(password);
|
|
||||||
} catch (error) {
|
|
||||||
return reject(error);
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -5,8 +5,10 @@ import * as actions from 'constants/channel_action_types';
|
||||||
export function updateLoggedInChannel (name, shortId, longId) {
|
export function updateLoggedInChannel (name, shortId, longId) {
|
||||||
return {
|
return {
|
||||||
type: actions.CHANNEL_UPDATE,
|
type: actions.CHANNEL_UPDATE,
|
||||||
name,
|
data: {
|
||||||
shortId,
|
name,
|
||||||
longId,
|
shortId,
|
||||||
|
longId,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as actions from 'constants/publish_action_types';
|
||||||
export function selectFile (file) {
|
export function selectFile (file) {
|
||||||
return {
|
return {
|
||||||
type: actions.FILE_SELECTED,
|
type: actions.FILE_SELECTED,
|
||||||
file: file,
|
data: file,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,15 +17,17 @@ export function clearFile () {
|
||||||
export function updateMetadata (name, value) {
|
export function updateMetadata (name, value) {
|
||||||
return {
|
return {
|
||||||
type: actions.METADATA_UPDATE,
|
type: actions.METADATA_UPDATE,
|
||||||
name,
|
data: {
|
||||||
value,
|
name,
|
||||||
|
value,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function updateClaim (value) {
|
export function updateClaim (value) {
|
||||||
return {
|
return {
|
||||||
type: actions.CLAIM_UPDATE,
|
type: actions.CLAIM_UPDATE,
|
||||||
value,
|
data: value,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,29 +41,33 @@ export function setPublishInChannel (channel) {
|
||||||
export function updatePublishStatus (status, message) {
|
export function updatePublishStatus (status, message) {
|
||||||
return {
|
return {
|
||||||
type: actions.PUBLISH_STATUS_UPDATE,
|
type: actions.PUBLISH_STATUS_UPDATE,
|
||||||
status,
|
data: {
|
||||||
message,
|
status,
|
||||||
|
message,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function updateError (name, value) {
|
export function updateError (name, value) {
|
||||||
return {
|
return {
|
||||||
type: actions.ERROR_UPDATE,
|
type: actions.ERROR_UPDATE,
|
||||||
name,
|
data: {
|
||||||
value,
|
name,
|
||||||
|
value,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function updateSelectedChannel (value) {
|
export function updateSelectedChannel (channelName) {
|
||||||
return {
|
return {
|
||||||
type: actions.SELECTED_CHANNEL_UPDATE,
|
type: actions.SELECTED_CHANNEL_UPDATE,
|
||||||
value,
|
data: channelName,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function toggleMetadataInputs (value) {
|
export function toggleMetadataInputs (showMetadataInputs) {
|
||||||
return {
|
return {
|
||||||
type: actions.TOGGLE_METADATA_INPUTS,
|
type: actions.TOGGLE_METADATA_INPUTS,
|
||||||
value,
|
data: showMetadataInputs,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
109
react/actions/show.js
Normal file
|
@ -0,0 +1,109 @@
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
import * as actions from 'constants/show_action_types';
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
import { CHANNEL, ASSET_LITE, ASSET_DETAILS } from 'constants/show_request_types';
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
// basic request parsing
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function handleShowPageUri (params) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.HANDLE_SHOW_URI,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: params,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function onRequestError (error) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.REQUEST_UPDATE_ERROR,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: error,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function onNewChannelRequest (channelName, channelId) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
const requestType = CHANNEL;
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
const requestId = `cr#${channelName}#${channelId}`;
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.CHANNEL_REQUEST_NEW,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: { requestType, requestId, channelName, channelId },
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function onNewAssetRequest (name, id, channelName, channelId, extension) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
const requestType = extension ? ASSET_LITE : ASSET_DETAILS;
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
const requestId = `ar#${name}#${id}#${channelName}#${channelId}`;
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.ASSET_REQUEST_NEW,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
requestType,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
requestId,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
name,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
modifier: {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
id,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
channel: {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
name: channelName,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
id : channelId,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
},
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
},
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
},
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function addRequestToRequestList (id, error, key) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.REQUEST_LIST_ADD,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: { id, error, key },
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
// asset actions
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function addAssetToAssetList (id, error, name, claimId, shortId, claimData) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.ASSET_ADD,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: { id, error, name, claimId, shortId, claimData },
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
}
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
// channel actions
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function addNewChannelToChannelList (id, name, shortId, longId, claimsData) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.CHANNEL_ADD,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: { id, name, shortId, longId, claimsData },
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function onUpdateChannelClaims (channelKey, name, longId, page) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.CHANNEL_CLAIMS_UPDATE_ASYNC,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: {channelKey, name, longId, page},
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function updateChannelClaims (channelListId, claimsData) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.CHANNEL_CLAIMS_UPDATE_SUCCESS,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: {channelListId, claimsData},
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
// display a file
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function fileRequested (name, claimId) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.FILE_REQUESTED,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: { name, claimId },
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function updateFileAvailability (status) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.FILE_AVAILABILITY_UPDATE,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: status,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
export function updateDisplayAssetError (error) {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
return {
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
type: actions.DISPLAY_ASSET_ERROR,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
data: error,
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
|||||||
|
};
|
||||||
I think generally the pattern is that an action is I think generally the pattern is that an action is `{ type: "some string", data: { name, id... } }` just to keep things consistent. `data` can be an object or a string, but I think it's helpful to put everything inside of that
This probably shouldn't be called This probably shouldn't be called `XXX_ASYNC` since it isn't async
|
39
react/api/assetApi.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import Request from 'utils/request';
|
||||||
|
|
||||||
|
export function getLongClaimId (name, modifier) {
|
||||||
|
// console.log('getting long claim id for asset:', name, modifier);
|
||||||
|
let body = {};
|
||||||
|
// create request params
|
||||||
|
if (modifier) {
|
||||||
|
if (modifier.id) {
|
||||||
|
body['claimId'] = modifier.id;
|
||||||
|
} else {
|
||||||
|
body['channelName'] = modifier.channel.name;
|
||||||
|
body['channelClaimId'] = modifier.channel.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body['claimName'] = name;
|
||||||
|
const params = {
|
||||||
|
method : 'POST',
|
||||||
|
headers: new Headers({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}),
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
}
|
||||||
|
// create url
|
||||||
|
const url = `/api/claim/long-id`;
|
||||||
|
// return the request promise
|
||||||
|
return Request(url, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getShortId (name, claimId) {
|
||||||
|
// console.log('getting short id for asset:', name, claimId);
|
||||||
|
const url = `/api/claim/short-id/${claimId}/${name}`;
|
||||||
|
return Request(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getClaimData (name, claimId) {
|
||||||
|
// console.log('getting claim data for asset:', name, claimId);
|
||||||
|
const url = `/api/claim/data/${name}/${claimId}`;
|
||||||
|
return Request(url);
|
||||||
|
};
|
16
react/api/channelApi.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import Request from 'utils/request';
|
||||||
|
import request from '../utils/request';
|
||||||
|
|
||||||
|
export function getChannelData (name, id) {
|
||||||
|
console.log('getting channel data for channel:', name, id);
|
||||||
|
if (!id) id = 'none';
|
||||||
|
const url = `/api/channel/data/${name}/${id}`;
|
||||||
|
return request(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getChannelClaims (name, longId, page) {
|
||||||
|
console.log('getting channel claims for channel:', name, longId);
|
||||||
|
if (!page) page = 1;
|
||||||
|
const url = `/api/channel/claims/${name}/${longId}/${page}`;
|
||||||
|
return Request(url);
|
||||||
|
};
|
11
react/api/fileApi.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import Request from 'utils/request';
|
||||||
|
|
||||||
|
export function checkFileAvailability (name, claimId) {
|
||||||
|
const url = `/api/file/availability/${name}/${claimId}`;
|
||||||
|
return Request(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function triggerClaimGet (name, claimId) {
|
||||||
|
const url = `/api/claim/get/${name}/${claimId}`;
|
||||||
|
return Request(url);
|
||||||
|
}
|
26
react/app.js
|
@ -1,26 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import {Provider} from 'react-redux';
|
|
||||||
import {createStore} from 'redux';
|
|
||||||
import Reducer from 'reducers';
|
|
||||||
import Publish from 'containers/PublishTool';
|
|
||||||
import NavBar from 'containers/NavBar';
|
|
||||||
|
|
||||||
let store = createStore(
|
|
||||||
Reducer,
|
|
||||||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
|
||||||
);
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<Provider store={store}>
|
|
||||||
<NavBar />
|
|
||||||
</Provider>,
|
|
||||||
document.getElementById('react-nav-bar')
|
|
||||||
)
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<Provider store={store}>
|
|
||||||
<Publish />
|
|
||||||
</Provider>,
|
|
||||||
document.getElementById('react-publish-tool')
|
|
||||||
)
|
|
33
react/components/AboutPage/index.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react';
|
||||||
|
import NavBar from 'containers/NavBar';
|
||||||
|
|
||||||
|
class AboutPage extends React.Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<NavBar/>
|
||||||
|
<div className="row row--padded">
|
||||||
|
<div className="column column--5 column--med-10 align-content-top">
|
||||||
|
<div className="column column--8 column--med-10">
|
||||||
|
<p className="pull-quote">Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.</p>
|
||||||
|
<p><a className="link--primary" target="_blank" href="https://twitter.com/spee_ch">TWITTER</a></p>
|
||||||
|
<p><a className="link--primary" target="_blank" href="https://github.com/lbryio/spee.ch">GITHUB</a></p>
|
||||||
|
<p><a className="link--primary" target="_blank" href="https://discord.gg/YjYbwhS">DISCORD CHANNEL</a></p>
|
||||||
|
<p><a className="link--primary" target="_blank" href="https://github.com/lbryio/spee.ch/blob/master/README.md">DOCUMENTATION</a></p>
|
||||||
|
</div>
|
||||||
|
</div><div className="column column--5 column--med-10 align-content-top">
|
||||||
|
<div className="column column--8 column--med-10">
|
||||||
|
<p>Spee.ch is a media-hosting site that reads from and publishes content to the <a className="link--primary" 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>If you have an idea for your own spee.ch-like site on top of LBRY, fork our <a className="link--primary" 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 className="link--primary" href="https://discord.gg/YjYbwhS">discord channel</a> or solve one of our <a className="link--primary" href="https://github.com/lbryio/spee.ch/issues">github issues</a>.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AboutPage;
|
28
react/components/AssetDisplay/index.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
import View from './view';
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
import { fileRequested } from 'actions/show';
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
import { selectAsset } from 'selectors/show';
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
// select error and status
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
const error = show.displayAsset.error;
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
const status = show.displayAsset.status;
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
// select asset
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
const asset = selectAsset(show);
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
// return props
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
return {
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
error,
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
status,
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
asset,
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
};
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
};
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
return {
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
onFileRequest: (name, claimId) => {
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
dispatch(fileRequested(name, claimId));
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
},
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
};
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
};
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
|||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(View);
|
||||||
Why do you do Why do you do `const that = this`?
I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same I think this is another piece you can move entirely into redux. Currently if this component is rendered, then a user navigates away and comes back to the same `<AssetDisplay />` it will make these requests again, even if you just made them a second ago
I had a misunderstanding of how the I had a misunderstanding of how the `this` context works and when I needed to pass this in to a function manually. I was able to remove it from the app in multiple places where it isn't necessary.
|
74
react/components/AssetDisplay/view.jsx
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ProgressBar from 'components/ProgressBar';
|
||||||
|
import { LOCAL_CHECK, UNAVAILABLE, ERROR, AVAILABLE } from 'constants/asset_display_states';
|
||||||
|
|
||||||
|
class AssetDisplay extends React.Component {
|
||||||
|
componentDidMount () {
|
||||||
|
const { asset: { claimData: { name, claimId } } } = this.props;
|
||||||
|
this.props.onFileRequest(name, claimId);
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
console.log('rendering assetdisplay', this.props);
|
||||||
|
const { status, error, asset: { claimData: { name, claimId, contentType, fileExt, thumbnail } } } = this.props;
|
||||||
|
return (
|
||||||
|
<div id="asset-display-component">
|
||||||
|
{(status === LOCAL_CHECK) &&
|
||||||
|
<div>
|
||||||
|
<p>Checking to see if Spee.ch has your asset locally...</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{(status === UNAVAILABLE) &&
|
||||||
|
<div>
|
||||||
|
<p>Sit tight, we're searching the LBRY blockchain for your asset!</p>
|
||||||
|
<ProgressBar size={12}/>
|
||||||
|
<p>Curious what magic is happening here? <a className="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{(status === ERROR) &&
|
||||||
|
<div>
|
||||||
|
<p>Unfortunately, we couldn't download your asset from LBRY. You can help us out by sharing the below error message in the <a className="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY discord</a>.</p>
|
||||||
|
<i><p id="error-message">{error}</p></i>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{(status === AVAILABLE) &&
|
||||||
|
(() => {
|
||||||
|
switch (contentType) {
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/jpg':
|
||||||
|
case 'image/png':
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
className="asset"
|
||||||
|
src={`/${claimId}/${name}.${fileExt}`}
|
||||||
|
alt={name}/>
|
||||||
|
);
|
||||||
|
case 'image/gif':
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
className="asset"
|
||||||
|
src={`/${claimId}/${name}.${fileExt}`}
|
||||||
|
alt={name}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case 'video/mp4':
|
||||||
|
return (
|
||||||
|
<video id="video" className="asset" controls poster={thumbnail}>
|
||||||
|
<source
|
||||||
|
src={`/${claimId}/${name}.${fileExt}`}
|
||||||
|
/>
|
||||||
|
<p>Your browser does not support the <code>video</code> element.</p>
|
||||||
|
</video>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<p>Unsupported file type</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AssetDisplay;
|
14
react/components/AssetInfo/index.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
import View from './view';
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
import { selectAsset } from 'selectors/show';
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
// select asset
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
const asset = selectAsset(show);
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
// return props
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
return {
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
asset,
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
};
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
};
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
|||||||
|
export default connect(mapStateToProps, null)(View);
|
||||||
This should be a This should be a `button` if it isn't linking anywhere.
|
165
react/components/AssetInfo/view.jsx
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
class AssetInfo extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
showDetails: false,
|
||||||
|
};
|
||||||
|
this.toggleDetails = this.toggleDetails.bind(this);
|
||||||
|
this.copyToClipboard = this.copyToClipboard.bind(this);
|
||||||
|
}
|
||||||
|
toggleDetails () {
|
||||||
|
if (this.state.showDetails) {
|
||||||
|
return this.setState({showDetails: false});
|
||||||
|
}
|
||||||
|
this.setState({showDetails: true});
|
||||||
|
}
|
||||||
|
copyToClipboard (event) {
|
||||||
|
var elementToCopy = event.target.dataset.elementtocopy;
|
||||||
|
var element = document.getElementById(elementToCopy);
|
||||||
|
element.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
} catch (err) {
|
||||||
|
this.setState({error: 'Oops, unable to copy'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
const { asset: { shortId, claimData : { channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host } } } = this.props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{channelName &&
|
||||||
|
<div className="row row--padded row--wide row--no-top">
|
||||||
|
<div className="column column--2 column--med-10">
|
||||||
|
<span className="text">Channel:</span>
|
||||||
|
</div>
|
||||||
|
<div className="column column--8 column--med-10">
|
||||||
|
<span className="text"><Link to={`/${channelName}:${certificateId}`}>{channelName}</Link></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{description &&
|
||||||
|
<div className="row row--padded row--wide row--no-top">
|
||||||
|
<span className="text">{description}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div className="row row--padded row--wide row--no-top">
|
||||||
|
<div id="show-short-link">
|
||||||
|
<div className="column column--2 column--med-10">
|
||||||
|
<Link className="link--primary" to={`/${shortId}/${name}.${fileExt}`}><span
|
||||||
|
className="text">Link:</span></Link>
|
||||||
|
</div>
|
||||||
|
<div className="column column--8 column--med-10">
|
||||||
|
<div className="row row--short row--wide">
|
||||||
|
<div className="column column--7">
|
||||||
|
<div className="input-error" id="input-error-copy-short-link" hidden="true">error here</div>
|
||||||
|
<input type="text" id="short-link" className="input-disabled input-text--full-width" readOnly
|
||||||
|
spellCheck="false"
|
||||||
|
value={`${host}/${shortId}/${name}.${fileExt}`}
|
||||||
|
onClick={this.select}/>
|
||||||
|
</div>
|
||||||
|
<div className="column column--1"> </div>
|
||||||
|
<div className="column column--2">
|
||||||
|
<button className="button--primary" data-elementtocopy="short-link"
|
||||||
|
onClick={this.copyToClipboard}>copy
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="show-embed-code">
|
||||||
|
<div className="column column--2 column--med-10">
|
||||||
|
<span className="text">Embed:</span>
|
||||||
|
</div>
|
||||||
|
<div className="column column--8 column--med-10">
|
||||||
|
<div className="row row--short row--wide">
|
||||||
|
<div className="column column--7">
|
||||||
|
<div className="input-error" id="input-error-copy-embed-text" hidden="true">error here</div>
|
||||||
|
{(contentType === 'video/mp4') ? (
|
||||||
|
<input type="text" id="embed-text" className="input-disabled input-text--full-width" readOnly
|
||||||
|
onClick={this.select} spellCheck="false"
|
||||||
|
value={`<video width="100%" controls poster="${thumbnail}" src="${host}/${claimId}/${name}.${fileExt}"/></video>`}/>
|
||||||
|
) : (
|
||||||
|
<input type="text" id="embed-text" className="input-disabled input-text--full-width" readOnly
|
||||||
|
onClick={this.select} spellCheck="false"
|
||||||
|
value={`<img src="${host}/${claimId}/${name}.${fileExt}"/>`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="column column--1"> </div>
|
||||||
|
<div className="column column--2">
|
||||||
|
<button className="button--primary" data-elementtocopy="embed-text"
|
||||||
|
onClick={this.copyToClipboard}>copy
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="show-share-buttons">
|
||||||
|
<div className="row row--padded row--wide row--no-top">
|
||||||
|
<div className="column column--2 column--med-10">
|
||||||
|
<span className="text">Share:</span>
|
||||||
|
</div>
|
||||||
|
<div className="column column--7 column--med-10">
|
||||||
|
<div
|
||||||
|
className="row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap">
|
||||||
|
<a className="link--primary" target="_blank"
|
||||||
|
href={`https://twitter.com/intent/tweet?text=${host}/${shortId}/${name}`}>twitter</a>
|
||||||
|
<a className="link--primary" target="_blank"
|
||||||
|
href={`https://www.facebook.com/sharer/sharer.php?u=${host}/${shortId}/${name}`}>facebook</a>
|
||||||
|
<a className="link--primary" target="_blank"
|
||||||
|
href={`http://tumblr.com/widgets/share/tool?canonicalUrl=${host}/${shortId}/${name}`}>tumblr</a>
|
||||||
|
<a className="link--primary" target="_blank"
|
||||||
|
href={`https://www.reddit.com/submit?url=${host}/${shortId}/${name}&title=${name}`}>reddit</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ this.state.showDetails &&
|
||||||
|
<div>
|
||||||
|
<div className="row--padded row--wide row--no-top">
|
||||||
|
<div>
|
||||||
|
<div className="column column--2 column--med-10">
|
||||||
|
<span className="text">Claim Name:</span>
|
||||||
|
</div><div className="column column--8 column--med-10">
|
||||||
|
{name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="column column--2 column--med-10">
|
||||||
|
<span className="text">Claim Id:</span>
|
||||||
|
</div><div className="column column--8 column--med-10">
|
||||||
|
{claimId}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="column column--2 column--med-10">
|
||||||
|
<span className="text">File Type:</span>
|
||||||
|
</div><div className="column column--8 column--med-10">
|
||||||
|
{contentType ? `${contentType}` : 'unknown'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row--padded row--wide row--no-top">
|
||||||
|
<div className="column column--10">
|
||||||
|
<a target="_blank" href="https://lbry.io/dmca">Report</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div className="row row--wide">
|
||||||
|
<button className="button--secondary" onClick={this.toggleDetails}>{this.state.showDetails ? 'less' : 'more'}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AssetInfo;
|
39
react/components/AssetPreview/index.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
import React from 'react';
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
import { Link } from 'react-router-dom';
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
const AssetPreview = ({ name, claimId, fileExt, contentType }) => {
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
const directSourceLink = `${claimId}/${name}.${fileExt}`;
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
const showUrlLink = `${claimId}/${name}`;
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
return (
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
<div className="asset-holder">
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
<Link to={showUrlLink} >
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
{(() => {
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
switch (contentType) {
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
case 'image/jpeg':
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
case 'image/jpg':
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
case 'image/png':
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
return (
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
<img className={'asset-preview'} src={directSourceLink} alt={name}/>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
);
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
case 'image/gif':
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
return (
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
<img className={'asset-preview'} src={directSourceLink} alt={name}/>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
);
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
case 'video/mp4':
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
return (
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
<video className={'asset-preview'}>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
<source src={directSourceLink} type={contentType}/>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
</video>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
);
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
default:
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
return (
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
<p>unsupported file type</p>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
);
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
}
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
})()}
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
</Link>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
</div>
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
);
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
};
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
|||||||
|
export default AssetPreview;
|
||||||
Any reason these aren't just css? Any reason these aren't just css?
oops oops
|
14
react/components/AssetTitle/index.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import View from './view';
|
||||||
|
import { selectAsset } from 'selectors/show';
|
||||||
|
|
||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
|
// select title
|
||||||
|
const { claimData: { title } } = selectAsset(show);
|
||||||
|
// return props
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, null)(View);
|
11
react/components/AssetTitle/view.jsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const AssetTitle = ({ title }) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span className="text--large">{title}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AssetTitle;
|
23
react/components/ErrorPage/index.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import NavBar from 'containers/NavBar';
|
||||||
|
|
||||||
|
class ErrorPage extends React.Component {
|
||||||
|
render () {
|
||||||
|
const { error } = this.props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<NavBar/>
|
||||||
|
<div className="row row--padded">
|
||||||
|
<p>{error}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ErrorPage.propTypes = {
|
||||||
|
error: PropTypes.string.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ErrorPage;
|
18
react/components/FourOhFourPage/index.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react';
|
||||||
|
import NavBar from 'containers/NavBar';
|
||||||
|
|
||||||
|
class FourOhForPage extends React.Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<NavBar/>
|
||||||
|
<div className="row row--padded">
|
||||||
|
<h2>404</h2>
|
||||||
|
<p>That page does not exist</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FourOhForPage;
|
|
@ -1,9 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
function Logo () {
|
function Logo () {
|
||||||
return (
|
return (
|
||||||
<svg version="1.1" id="Layer_1" x="0px" y="0px" height="24px" viewBox="0 0 80 31" enableBackground="new 0 0 80 31" className="nav-bar-logo">
|
<svg version="1.1" id="Layer_1" x="0px" y="0px" height="24px" viewBox="0 0 80 31" enableBackground="new 0 0 80 31" className="nav-bar-logo">
|
||||||
<a href="/">
|
<Link to="/">
|
||||||
<title>Logo</title>
|
<title>Logo</title>
|
||||||
<desc>Spee.ch logo</desc>
|
<desc>Spee.ch logo</desc>
|
||||||
<g id="About">
|
<g id="About">
|
||||||
|
@ -20,7 +21,7 @@ function Logo () {
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</a>
|
</Link>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
function NavBarChannelOptionsDropdown ({ channelName, handleSelection, VIEW, LOGOUT }) {
|
function NavBarChannelDropdown ({ channelName, handleSelection, defaultSelection, VIEW, LOGOUT }) {
|
||||||
return (
|
return (
|
||||||
<select type="text" id="nav-bar-channel-select" className="select select--arrow link--nav" onChange={handleSelection}>
|
<select type="text" id="nav-bar-channel-select" className="select select--arrow link--nav" onChange={handleSelection} value={defaultSelection}>
|
||||||
<option id="nav-bar-channel-select-channel-option">{channelName}</option>
|
<option id="nav-bar-channel-select-channel-option">{channelName}</option>
|
||||||
<option value={VIEW}>View</option>
|
<option value={VIEW}>View</option>
|
||||||
<option value={LOGOUT}>Logout</option>
|
<option value={LOGOUT}>Logout</option>
|
||||||
|
@ -10,4 +10,4 @@ function NavBarChannelOptionsDropdown ({ channelName, handleSelection, VIEW, LOG
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NavBarChannelOptionsDropdown;
|
export default NavBarChannelDropdown;
|
||||||
|
|
|
@ -8,7 +8,6 @@ class Preview extends React.Component {
|
||||||
imgSource : '',
|
imgSource : '',
|
||||||
defaultThumbnail: '/assets/img/video_thumb_default.png',
|
defaultThumbnail: '/assets/img/video_thumb_default.png',
|
||||||
};
|
};
|
||||||
this.previewFile = this.previewFile.bind(this);
|
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.previewFile(this.props.file);
|
this.previewFile(this.props.file);
|
||||||
|
@ -22,21 +21,20 @@ class Preview extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
previewFile (file) {
|
previewFile (file) {
|
||||||
const that = this;
|
|
||||||
if (file.type !== 'video/mp4') {
|
if (file.type !== 'video/mp4') {
|
||||||
const previewReader = new FileReader();
|
const previewReader = new FileReader();
|
||||||
previewReader.readAsDataURL(file);
|
previewReader.readAsDataURL(file);
|
||||||
previewReader.onloadend = function () {
|
previewReader.onloadend = () => {
|
||||||
that.setState({imgSource: previewReader.result});
|
this.setState({imgSource: previewReader.result});
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
that.setState({imgSource: (this.props.thumbnail || this.state.defaultThumbnail)});
|
this.setState({imgSource: (this.props.thumbnail || this.state.defaultThumbnail)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
id="asset-preview"
|
id="dropzone-preview"
|
||||||
src={this.state.imgSource}
|
src={this.state.imgSource}
|
||||||
className={this.props.dimPreview ? 'dim' : ''}
|
className={this.props.dimPreview ? 'dim' : ''}
|
||||||
alt="publish preview"
|
alt="publish preview"
|
||||||
|
|
18
react/components/PublishPage/index.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react';
|
||||||
|
import NavBar from 'containers/NavBar';
|
||||||
|
import PublishTool from 'containers/PublishTool';
|
||||||
|
|
||||||
|
class PublishPage extends React.Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div className={'row row--tall flex-container--column'}>
|
||||||
|
<NavBar/>
|
||||||
|
<div className={'row row--tall row--padded flex-container--column'}>
|
||||||
|
<PublishTool/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PublishPage;
|
|
@ -30,7 +30,7 @@ function PublishStatus ({ status, message }) {
|
||||||
{(status === publishStates.SUCCESS) &&
|
{(status === publishStates.SUCCESS) &&
|
||||||
<div className="row align-content-center">
|
<div className="row align-content-center">
|
||||||
<p>Your publish is complete! You are being redirected to it now.</p>
|
<p>Your publish is complete! You are being redirected to it now.</p>
|
||||||
<p>If you are not automatically redirected, <a class="link--primary" target="_blank" href={message}>click here.</a></p>
|
<p>If you are not automatically redirected, <a className="link--primary" target="_blank" href={message}>click here.</a></p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{(status === publishStates.FAILED) &&
|
{(status === publishStates.FAILED) &&
|
||||||
|
|
21
react/components/ShowAssetDetails/index.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import View from './view';
|
||||||
|
|
||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
|
// select request info
|
||||||
|
const requestId = show.request.id;
|
||||||
|
// select asset info
|
||||||
|
let asset;
|
||||||
|
const request = show.requestList[requestId] || null;
|
||||||
|
const assetList = show.assetList;
|
||||||
|
if (request && assetList) {
|
||||||
|
const assetKey = request.key; // note: just store this in the request
|
||||||
|
asset = assetList[assetKey] || null;
|
||||||
|
};
|
||||||
|
// return props
|
||||||
|
return {
|
||||||
|
asset,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, null)(View);
|
39
react/components/ShowAssetDetails/view.jsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import React from 'react';
|
||||||
|
import NavBar from 'containers/NavBar';
|
||||||
|
import ErrorPage from 'components/ErrorPage';
|
||||||
|
import AssetTitle from 'components/AssetTitle';
|
||||||
|
import AssetDisplay from 'components/AssetDisplay';
|
||||||
|
import AssetInfo from 'components/AssetInfo';
|
||||||
|
|
||||||
|
class ShowAssetDetails extends React.Component {
|
||||||
|
render () {
|
||||||
|
const { asset } = this.props;
|
||||||
|
if (asset) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<NavBar/>
|
||||||
|
<div className="row row--tall row--padded">
|
||||||
|
<div className="column column--10">
|
||||||
|
<AssetTitle />
|
||||||
|
</div>
|
||||||
|
<div className="column column--5 column--sml-10 align-content-top">
|
||||||
|
<div className="row row--padded">
|
||||||
|
<AssetDisplay />
|
||||||
|
</div>
|
||||||
|
</div><div className="column column--5 column--sml-10 align-content-top">
|
||||||
|
<div className="row row--padded">
|
||||||
|
<AssetInfo />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<ErrorPage error={'loading asset data...'}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShowAssetDetails;
|
21
react/components/ShowAssetLite/index.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
import View from './view';
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
// select request info
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
const requestId = show.request.id;
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
// select asset info
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
let asset;
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
const request = show.requestList[requestId] || null;
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
const assetList = show.assetList;
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
if (request && assetList) {
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
const assetKey = request.key; // note: just store this in the request
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
asset = assetList[assetKey] || null;
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
};
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
// return props
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
return {
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
asset,
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
};
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
};
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
|||||||
|
export default connect(mapStateToProps, null)(View);
|
||||||
You can use destructuring twice to avoid all the repeated
Then you can just use You can use destructuring twice to avoid all the repeated `this.props.claimData`
`const { claimData: { name, claimId... } } = this.props`
Then you can just use `name={name}`
|
21
react/components/ShowAssetLite/view.jsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import AssetDisplay from 'components/AssetDisplay';
|
||||||
|
|
||||||
|
class ShowLite extends React.Component {
|
||||||
|
render () {
|
||||||
|
const { asset } = this.props;
|
||||||
|
return (
|
||||||
|
<div className="row row--tall flex-container--column flex-container--center-center">
|
||||||
|
{ (asset) &&
|
||||||
|
<div>
|
||||||
|
<AssetDisplay />
|
||||||
|
<Link id="asset-boilerpate" className="link--primary fine-print" to={`/${asset.claimId}/${asset.name}`}>hosted via Spee.ch</Link>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShowLite;
|
20
react/components/ShowChannel/index.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import View from './view';
|
||||||
|
|
||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
|
// select request info
|
||||||
|
const requestId = show.request.id;
|
||||||
|
// select request
|
||||||
|
const previousRequest = show.requestList[requestId] || null;
|
||||||
|
// select channel
|
||||||
|
let channel;
|
||||||
|
if (previousRequest) {
|
||||||
|
const channelKey = previousRequest.key;
|
||||||
|
channel = show.channelList[channelKey] || null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
channel,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, null)(View);
|
33
react/components/ShowChannel/view.jsx
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ErrorPage from 'components/ErrorPage';
|
||||||
|
import NavBar from 'containers/NavBar';
|
||||||
|
import ChannelClaimsDisplay from 'containers/ChannelClaimsDisplay';
|
||||||
|
|
||||||
|
class ShowChannel extends React.Component {
|
||||||
|
render () {
|
||||||
|
const { channel } = this.props;
|
||||||
|
if (channel) {
|
||||||
|
const { name, longId, shortId } = channel;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<NavBar/>
|
||||||
|
<div className="row row--tall row--padded">
|
||||||
|
<div className="column column--10">
|
||||||
|
<h2>channel name: {name || 'loading...'}</h2>
|
||||||
|
<p className={'fine-print'}>full channel id: {longId || 'loading...'}</p>
|
||||||
|
<p className={'fine-print'}>short channel id: {shortId || 'loading...'}</p>
|
||||||
|
</div>
|
||||||
|
<div className="column column--10">
|
||||||
|
<ChannelClaimsDisplay />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<ErrorPage error={'loading channel data...'}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShowChannel;
|
4
react/constants/asset_display_states.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export const LOCAL_CHECK = 'LOCAL_CHECK';
|
||||||
|
export const UNAVAILABLE = 'UNAVAILABLE';
|
||||||
|
export const ERROR = 'ERROR';
|
||||||
|
export const AVAILABLE = 'AVAILABLE';
|
20
react/constants/show_action_types.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// request actions
|
||||||
|
export const HANDLE_SHOW_URI = 'HANDLE_SHOW_URI';
|
||||||
|
export const REQUEST_UPDATE_ERROR = 'REQUEST_UPDATE_ERROR';
|
||||||
|
export const ASSET_REQUEST_NEW = 'ASSET_REQUEST_NEW';
|
||||||
|
export const CHANNEL_REQUEST_NEW = 'CHANNEL_REQUEST_NEW';
|
||||||
|
export const REQUEST_LIST_ADD = 'REQUEST_LIST_ADD';
|
||||||
|
|
||||||
|
// asset actions
|
||||||
|
export const ASSET_ADD = `ASSET_ADD`;
|
||||||
|
|
||||||
|
// channel actions
|
||||||
|
export const CHANNEL_ADD = 'CHANNEL_ADD';
|
||||||
|
|
||||||
|
export const CHANNEL_CLAIMS_UPDATE_ASYNC = 'CHANNEL_CLAIMS_UPDATE_ASYNC';
|
||||||
|
export const CHANNEL_CLAIMS_UPDATE_SUCCESS = 'CHANNEL_CLAIMS_UPDATE_SUCCESS';
|
||||||
|
|
||||||
|
// asset/file display actions
|
||||||
|
export const FILE_REQUESTED = 'FILE_REQUESTED';
|
||||||
|
export const FILE_AVAILABILITY_UPDATE = 'FILE_AVAILABILITY_UPDATE';
|
||||||
|
export const DISPLAY_ASSET_ERROR = 'DISPLAY_ASSET_ERROR';
|
3
react/constants/show_request_types.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export const CHANNEL = 'CHANNEL';
|
||||||
|
export const ASSET_LITE = 'ASSET_LITE';
|
||||||
|
export const ASSET_DETAILS = 'ASSET_DETAILS';
|
22
react/containers/ChannelClaimsDisplay/index.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
import { onUpdateChannelClaims } from 'actions/show';
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
import View from './view';
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
// select channel key
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
const request = show.requestList[show.request.id];
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
const channelKey = request.key;
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
// select channel claims
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
const channel = show.channelList[channelKey] || null;
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
// return props
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
return {
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
channelKey,
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
channel,
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
};
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
};
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
const mapDispatchToProps = {
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
onUpdateChannelClaims,
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
};
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
|||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(View);
|
||||||
Will these nested values always exist? Will these nested values always exist?
They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking? They will always exist when ChannelClaimsDisplay is rendered, unless that should change... I am updated it to be destructured, is that what you were thinking?
I was just wondering if there would ever be a case when Or if any of those children would be undefined which would throw an error I was just wondering if there would ever be a case when `show` is undefined. Which would cause an errror. `cannot read property 'showChannel` of undefined`.
Or if any of those children would be undefined which would throw an error
|
54
react/containers/ChannelClaimsDisplay/view.jsx
Normal file
|
@ -0,0 +1,54 @@
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
import React from 'react';
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
import AssetPreview from 'components/AssetPreview';
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
class ChannelClaimsDisplay extends React.Component {
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
constructor (props) {
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
super(props);
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
this.showNextResultsPage = this.showNextResultsPage.bind(this);
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
this.showPreviousResultsPage = this.showPreviousResultsPage.bind(this);
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
showPreviousResultsPage () {
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
const { channel: { claimsData: { currentPage } } } = this.props;
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
const previousPage = parseInt(currentPage) - 1;
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
this.showNewPage(previousPage);
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
showNextResultsPage () {
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
const { channel: { claimsData: { currentPage } } } = this.props;
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
const nextPage = parseInt(currentPage) + 1;
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
this.showNewPage(nextPage);
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
showNewPage (page) {
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
const { channelKey, channel: { name, longId } } = this.props;
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
this.props.onUpdateChannelClaims(channelKey, name, longId, page);
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
render () {
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
const { channel: { claimsData: { claims, currentPage, totalPages } } } = this.props;
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
return (
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
<div className="row row--tall">
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
{(claims.length > 0) ? (
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
<div>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
{claims.map((claim, index) => <AssetPreview
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
name={claim.name}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
claimId={claim.claimId}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
fileExt={claim.fileExt}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
contentType={claim.contentType}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
key={`${claim.name}-${index}`}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
/>)}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
<div>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
{(currentPage > 1) &&
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
<button className={'button--secondary'} onClick={this.showPreviousResultsPage}>Previous Page</button>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
{(currentPage < totalPages) &&
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
<button className={'button--secondary'} onClick={this.showNextResultsPage}>Next Page</button>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
</div>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
</div>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
) : (
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
<p>There are no claims in this channel</p>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
)}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
</div>
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
);
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
}
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
};
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|||||||
|
export default ChannelClaimsDisplay;
|
||||||
This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch This might be what you were thinking of doing, but instead of doing the request here, then calling an action to update the data or set an error, just dispatch `updateClaimsData` action which makes the call, then updates the redux state accordingly. I think making an effort to keep all data logic inside of redux files can simplify a lot of components (for the most part)
|
|
@ -11,13 +11,8 @@ class ChannelCreateForm extends React.Component {
|
||||||
password: '',
|
password: '',
|
||||||
status : null,
|
status : null,
|
||||||
};
|
};
|
||||||
this.cleanseChannelInput = this.cleanseChannelInput.bind(this);
|
|
||||||
this.handleChannelInput = this.handleChannelInput.bind(this);
|
this.handleChannelInput = this.handleChannelInput.bind(this);
|
||||||
this.handleInput = this.handleInput.bind(this);
|
this.handleInput = this.handleInput.bind(this);
|
||||||
this.updateIsChannelAvailable = this.updateIsChannelAvailable.bind(this);
|
|
||||||
this.checkIsChannelAvailable = this.checkIsChannelAvailable.bind(this);
|
|
||||||
this.checkIsPasswordProvided = this.checkIsPasswordProvided.bind(this);
|
|
||||||
this.makePublishChannelRequest = this.makePublishChannelRequest.bind(this);
|
|
||||||
this.createChannel = this.createChannel.bind(this);
|
this.createChannel = this.createChannel.bind(this);
|
||||||
}
|
}
|
||||||
cleanseChannelInput (input) {
|
cleanseChannelInput (input) {
|
||||||
|
@ -41,24 +36,23 @@ class ChannelCreateForm extends React.Component {
|
||||||
this.setState({[name]: value});
|
this.setState({[name]: value});
|
||||||
}
|
}
|
||||||
updateIsChannelAvailable (channel) {
|
updateIsChannelAvailable (channel) {
|
||||||
const that = this;
|
|
||||||
const channelWithAtSymbol = `@${channel}`;
|
const channelWithAtSymbol = `@${channel}`;
|
||||||
request(`/api/channel-is-available/${channelWithAtSymbol}`)
|
request(`/api/channel/availability/${channelWithAtSymbol}`)
|
||||||
.then(isAvailable => {
|
.then(isAvailable => {
|
||||||
if (isAvailable) {
|
if (isAvailable) {
|
||||||
that.setState({'error': null});
|
this.setState({'error': null});
|
||||||
} else {
|
} else {
|
||||||
that.setState({'error': 'That channel has already been claimed'});
|
this.setState({'error': 'That channel has already been claimed'});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
that.setState({'error': error.message});
|
this.setState({'error': error.message});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
checkIsChannelAvailable (channel) {
|
checkIsChannelAvailable (channel) {
|
||||||
const channelWithAtSymbol = `@${channel}`;
|
const channelWithAtSymbol = `@${channel}`;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request(`/api/channel-is-available/${channelWithAtSymbol}`)
|
request(`/api/channel/availability/${channelWithAtSymbol}`)
|
||||||
.then(isAvailable => {
|
.then(isAvailable => {
|
||||||
console.log('checkIsChannelAvailable result:', isAvailable);
|
console.log('checkIsChannelAvailable result:', isAvailable);
|
||||||
if (!isAvailable) {
|
if (!isAvailable) {
|
||||||
|
@ -105,21 +99,20 @@ class ChannelCreateForm extends React.Component {
|
||||||
}
|
}
|
||||||
createChannel (event) {
|
createChannel (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const that = this;
|
|
||||||
this.checkIsPasswordProvided()
|
this.checkIsPasswordProvided()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return that.checkIsChannelAvailable(that.state.channel, that.state.password);
|
return this.checkIsChannelAvailable(this.state.channel, this.state.password);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
that.setState({status: 'We are publishing your new channel. Sit tight...'});
|
this.setState({status: 'We are publishing your new channel. Sit tight...'});
|
||||||
return that.makePublishChannelRequest(that.state.channel, that.state.password);
|
return this.makePublishChannelRequest(this.state.channel, this.state.password);
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
that.setState({status: null});
|
this.setState({status: null});
|
||||||
that.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);
|
this.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
that.setState({'error': error.message, status: null});
|
this.setState({'error': error.message, status: null});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -27,22 +27,21 @@ class ChannelLoginForm extends React.Component {
|
||||||
}),
|
}),
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
}
|
}
|
||||||
const that = this;
|
|
||||||
request('login', params)
|
request('login', params)
|
||||||
.then(({success, channelName, shortChannelId, channelClaimId, message}) => {
|
.then(({success, channelName, shortChannelId, channelClaimId, message}) => {
|
||||||
console.log('loginToChannel success:', success);
|
console.log('loginToChannel success:', success);
|
||||||
if (success) {
|
if (success) {
|
||||||
that.props.onChannelLogin(channelName, shortChannelId, channelClaimId);
|
this.props.onChannelLogin(channelName, shortChannelId, channelClaimId);
|
||||||
} else {
|
} else {
|
||||||
that.setState({'error': message});
|
this.setState({'error': message});
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log('login error', error);
|
console.log('login error', error);
|
||||||
if (error.message) {
|
if (error.message) {
|
||||||
that.setState({'error': error.message});
|
this.setState({'error': error.message});
|
||||||
} else {
|
} else {
|
||||||
that.setState({'error': error});
|
this.setState({'error': error});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {setPublishInChannel, updateSelectedChannel, updateError} from 'actions/publish';
|
import {setPublishInChannel, updateSelectedChannel, updateError} from 'actions/publish';
|
||||||
import View from './view.jsx';
|
import View from './view';
|
||||||
|
|
||||||
const mapStateToProps = ({ channel, publish }) => {
|
const mapStateToProps = ({ channel, publish }) => {
|
||||||
return {
|
return {
|
||||||
|
|
10
react/containers/LoginPage/index.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import View from './view';
|
||||||
|
|
||||||
|
const mapStateToProps = ({ channel }) => {
|
||||||
|
return {
|
||||||
|
loggedInChannelName: channel.loggedInChannel.name,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, null)(View);
|
38
react/containers/LoginPage/view.jsx
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { withRouter } from 'react-router-dom';
|
||||||
|
import NavBar from 'containers/NavBar';
|
||||||
|
import ChannelLoginForm from 'containers/ChannelLoginForm';
|
||||||
|
import ChannelCreateForm from 'containers/ChannelCreateForm';
|
||||||
|
|
||||||
|
class PublishPage extends React.Component {
|
||||||
|
componentWillReceiveProps (newProps) {
|
||||||
|
// re-route the user to the homepage if the user is logged in
|
||||||
|
if (newProps.loggedInChannelName !== this.props.loggedInChannelName) {
|
||||||
|
console.log('user logged into new channel:', newProps.loggedInChannelName);
|
||||||
|
this.props.history.push(`/`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<NavBar/>
|
||||||
|
<div className="row row--padded">
|
||||||
|
<div className="column column--5 column--med-10 align-content-top">
|
||||||
|
<div className="column column--8 column--med-10">
|
||||||
|
<p>Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends. You can create 1 channel, or 100, so whether you're <a className="link--primary" target="_blank" href="/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8">documenting important events</a>, or making a public repository for <a className="link--primary" target="_blank" href="/@catGifs">cat gifs</a> (password: '1234'), try creating a channel for it!</p>
|
||||||
|
</div>
|
||||||
|
</div><div className="column column--5 column--med-10 align-content-top">
|
||||||
|
<div className="column column--8 column--med-10">
|
||||||
|
<h3 className="h3--no-bottom">Log in to an existing channel:</h3>
|
||||||
|
<ChannelLoginForm />
|
||||||
|
<h3 className="h3--no-bottom">Create a brand new channel:</h3>
|
||||||
|
<ChannelCreateForm />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withRouter(PublishPage);
|
|
@ -17,6 +17,9 @@ const mapDispatchToProps = dispatch => {
|
||||||
dispatch(updateLoggedInChannel(name, shortId, longId));
|
dispatch(updateLoggedInChannel(name, shortId, longId));
|
||||||
dispatch(updateSelectedChannel(name));
|
dispatch(updateSelectedChannel(name));
|
||||||
},
|
},
|
||||||
|
onChannelLogout: () => {
|
||||||
|
dispatch(updateLoggedInChannel(null, null, null));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import request from 'utils/request';
|
import { NavLink, withRouter } from 'react-router-dom';
|
||||||
import Logo from 'components/Logo';
|
import Logo from 'components/Logo';
|
||||||
import NavBarChannelDropdown from 'components/NavBarChannelOptionsDropdown';
|
import NavBarChannelDropdown from 'components/NavBarChannelOptionsDropdown';
|
||||||
|
import request from 'utils/request';
|
||||||
|
|
||||||
const VIEW = 'VIEW';
|
const VIEW = 'VIEW';
|
||||||
const LOGOUT = 'LOGOUT';
|
const LOGOUT = 'LOGOUT';
|
||||||
|
@ -18,25 +19,24 @@ class NavBar extends React.Component {
|
||||||
this.checkForLoggedInUser();
|
this.checkForLoggedInUser();
|
||||||
}
|
}
|
||||||
checkForLoggedInUser () {
|
checkForLoggedInUser () {
|
||||||
// check for whether a channel is already logged in
|
const params = {credentials: 'include'};
|
||||||
const params = {
|
|
||||||
credentials: 'include',
|
|
||||||
}
|
|
||||||
request('/user', params)
|
request('/user', params)
|
||||||
.then(({success, message}) => {
|
.then(({ data }) => {
|
||||||
if (success) {
|
this.props.onChannelLogin(data.channelName, data.shortChannelId, data.channelClaimId);
|
||||||
this.props.onChannelLogin(message.channelName, message.shortChannelId, message.channelClaimId);
|
|
||||||
} else {
|
|
||||||
console.log('user was not logged in');
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log('authenticate user errored:', error);
|
console.log('/user error:', error.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
logoutUser () {
|
logoutUser () {
|
||||||
// send logout request to server
|
const params = {credentials: 'include'};
|
||||||
window.location.href = '/logout'; // NOTE: replace with a call to the server
|
request('/logout', params)
|
||||||
|
.then(() => {
|
||||||
|
this.props.onChannelLogout();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log('/logout error', error.message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
handleSelection (event) {
|
handleSelection (event) {
|
||||||
console.log('handling selection', event);
|
console.log('handling selection', event);
|
||||||
|
@ -48,7 +48,7 @@ class NavBar extends React.Component {
|
||||||
break;
|
break;
|
||||||
case VIEW:
|
case VIEW:
|
||||||
// redirect to channel page
|
// redirect to channel page
|
||||||
window.location.href = `/${this.props.channelName}:${this.props.channelLongId}`;
|
this.props.history.push(`/${this.props.channelName}:${this.props.channelLongId}`);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -63,17 +63,18 @@ class NavBar extends React.Component {
|
||||||
<span className="nav-bar-tagline">Open-source, decentralized image and video sharing.</span>
|
<span className="nav-bar-tagline">Open-source, decentralized image and video sharing.</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="nav-bar--right">
|
<div className="nav-bar--right">
|
||||||
<a className="nav-bar-link link--nav-active" href="/">Publish</a>
|
<NavLink className="nav-bar-link link--nav" activeClassName="link--nav-active" to="/" exact={true}>Publish</NavLink>
|
||||||
<a className="nav-bar-link link--nav" href="/about">About</a>
|
<NavLink className="nav-bar-link link--nav" activeClassName="link--nav-active" to="/about">About</NavLink>
|
||||||
{ this.props.channelName ? (
|
{ this.props.channelName ? (
|
||||||
<NavBarChannelDropdown
|
<NavBarChannelDropdown
|
||||||
channelName={this.props.channelName}
|
channelName={this.props.channelName}
|
||||||
handleSelection={this.handleSelection}
|
handleSelection={this.handleSelection}
|
||||||
|
defaultSelection={this.props.channelName}
|
||||||
VIEW={VIEW}
|
VIEW={VIEW}
|
||||||
LOGOUT={LOGOUT}
|
LOGOUT={LOGOUT}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<a id="nav-bar-login-link" className="nav-bar-link link--nav" href="/login">Channel</a>
|
<NavLink id="nav-bar-login-link" className="nav-bar-link link--nav" activeClassName="link--nav-active" to="/login">Channel</NavLink>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,4 +83,4 @@ class NavBar extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default NavBar;
|
export default withRouter(NavBar);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { withRouter } from 'react-router-dom';
|
||||||
import Dropzone from 'containers/Dropzone';
|
import Dropzone from 'containers/Dropzone';
|
||||||
import PublishTitleInput from 'containers/PublishTitleInput';
|
import PublishTitleInput from 'containers/PublishTitleInput';
|
||||||
import PublishUrlInput from 'containers/PublishUrlInput';
|
import PublishUrlInput from 'containers/PublishUrlInput';
|
||||||
|
@ -10,9 +11,7 @@ import * as publishStates from 'constants/publish_claim_states';
|
||||||
class PublishForm extends React.Component {
|
class PublishForm extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.validateChannelSelection = this.validateChannelSelection.bind(this);
|
// this.makePublishRequest = this.makePublishRequest.bind(this);
|
||||||
this.validatePublishParams = this.validatePublishParams.bind(this);
|
|
||||||
this.makePublishRequest = this.makePublishRequest.bind(this);
|
|
||||||
this.publish = this.publish.bind(this);
|
this.publish = this.publish.bind(this);
|
||||||
}
|
}
|
||||||
validateChannelSelection () {
|
validateChannelSelection () {
|
||||||
|
@ -49,37 +48,33 @@ class PublishForm extends React.Component {
|
||||||
}
|
}
|
||||||
makePublishRequest (file, metadata) {
|
makePublishRequest (file, metadata) {
|
||||||
console.log('making publish request');
|
console.log('making publish request');
|
||||||
const uri = '/api/claim-publish';
|
const uri = '/api/claim/publish';
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
const fd = this.appendDataToFormData(file, metadata);
|
const fd = this.appendDataToFormData(file, metadata);
|
||||||
const that = this;
|
xhr.upload.addEventListener('loadstart', () => {
|
||||||
xhr.upload.addEventListener('loadstart', function () {
|
this.props.onPublishStatusChange(publishStates.LOAD_START, 'upload started');
|
||||||
that.props.onPublishStatusChange(publishStates.LOAD_START, 'upload started');
|
|
||||||
});
|
});
|
||||||
xhr.upload.addEventListener('progress', function (e) {
|
xhr.upload.addEventListener('progress', (e) => {
|
||||||
if (e.lengthComputable) {
|
if (e.lengthComputable) {
|
||||||
const percentage = Math.round((e.loaded * 100) / e.total);
|
const percentage = Math.round((e.loaded * 100) / e.total);
|
||||||
console.log('progress:', percentage);
|
console.log('progress:', percentage);
|
||||||
that.props.onPublishStatusChange(publishStates.LOADING, `${percentage}%`);
|
this.props.onPublishStatusChange(publishStates.LOADING, `${percentage}%`);
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
xhr.upload.addEventListener('load', function () {
|
xhr.upload.addEventListener('load', () => {
|
||||||
console.log('loaded 100%');
|
console.log('loaded 100%');
|
||||||
that.props.onPublishStatusChange(publishStates.PUBLISHING, null);
|
this.props.onPublishStatusChange(publishStates.PUBLISHING, null);
|
||||||
}, false);
|
}, false);
|
||||||
xhr.open('POST', uri, true);
|
xhr.open('POST', uri, true);
|
||||||
xhr.onreadystatechange = function () {
|
xhr.onreadystatechange = () => {
|
||||||
if (xhr.readyState === 4) {
|
if (xhr.readyState === 4) {
|
||||||
console.log('publish response:', xhr.response);
|
const response = JSON.parse(xhr.response);
|
||||||
if (xhr.status === 200) {
|
console.log('publish response:', response);
|
||||||
console.log('publish complete!');
|
if ((xhr.status === 200) && response.success) {
|
||||||
const url = JSON.parse(xhr.response).message.url;
|
this.props.history.push(`/${response.data.claimId}/${response.data.name}`);
|
||||||
that.props.onPublishStatusChange(publishStates.SUCCESS, url);
|
this.props.onPublishStatusChange(publishStates.SUCCESS, response.data.url);
|
||||||
window.location = url;
|
|
||||||
} else if (xhr.status === 502) {
|
|
||||||
that.props.onPublishStatusChange(publishStates.FAILED, 'Spee.ch was not able to get a response from the LBRY network.');
|
|
||||||
} else {
|
} else {
|
||||||
that.props.onPublishStatusChange(publishStates.FAILED, JSON.parse(xhr.response).message);
|
this.props.onPublishStatusChange(publishStates.FAILED, response.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -107,7 +102,6 @@ class PublishForm extends React.Component {
|
||||||
fd.append('file', file);
|
fd.append('file', file);
|
||||||
for (var key in metadata) {
|
for (var key in metadata) {
|
||||||
if (metadata.hasOwnProperty(key)) {
|
if (metadata.hasOwnProperty(key)) {
|
||||||
console.log('adding form data', key, metadata[key]);
|
|
||||||
fd.append(key, metadata[key]);
|
fd.append(key, metadata[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,21 +110,20 @@ class PublishForm extends React.Component {
|
||||||
publish () {
|
publish () {
|
||||||
console.log('publishing file');
|
console.log('publishing file');
|
||||||
// publish the asset
|
// publish the asset
|
||||||
const that = this;
|
|
||||||
this.validateChannelSelection()
|
this.validateChannelSelection()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return that.validatePublishParams();
|
return this.validatePublishParams();
|
||||||
})
|
})
|
||||||
Not really a comment on this PR but it might be worth looking into Not really a comment on this PR but it might be worth looking into `fetch` instead of dealing with `xhr`
Cool. Yeah, I replaced most xhr requests with fetch in the app. I kept this one for the publish request because I wanted to set event listeners on the request and wasn't sure if I could do that with fetch. I'll look into that. Cool. Yeah, I replaced most xhr requests with fetch in the app. I kept this one for the publish request because I wanted to set event listeners on the request and wasn't sure if I could do that with fetch. I'll look into that.
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
const metadata = that.createMetadata();
|
const metadata = this.createMetadata();
|
||||||
// publish the claim
|
// publish the claim
|
||||||
return that.makePublishRequest(that.props.file, metadata);
|
return this.makePublishRequest(this.props.file, metadata);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
that.props.onPublishStatusChange('publish request made');
|
this.props.onPublishStatusChange('publish request made');
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
that.props.onPublishSubmitError(error.message);
|
this.props.onPublishSubmitError(error.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
@ -176,4 +169,4 @@ class PublishForm extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PublishForm;
|
export default withRouter(PublishForm);
|
||||||
|
|
|
@ -65,7 +65,7 @@ class PublishMetadataInputs extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<a className="label link--primary" id="publish-details-toggle" href="#" onClick={this.toggleShowInputs}>{this.props.showMetadataInputs ? '[less]' : '[more]'}</a>
|
<button className="button--secondary" onClick={this.toggleShowInputs}>{this.props.showMetadataInputs ? 'less' : 'more'}</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@ class PublishThumbnailInput extends React.Component {
|
||||||
thumbnailInput : '',
|
thumbnailInput : '',
|
||||||
}
|
}
|
||||||
this.handleInput = this.handleInput.bind(this);
|
this.handleInput = this.handleInput.bind(this);
|
||||||
this.urlIsAnImage = this.urlIsAnImage.bind(this);
|
|
||||||
this.testImage = this.testImage.bind(this);
|
|
||||||
this.updateVideoThumb = this.updateVideoThumb.bind(this);
|
this.updateVideoThumb = this.updateVideoThumb.bind(this);
|
||||||
}
|
}
|
||||||
handleInput (event) {
|
handleInput (event) {
|
||||||
|
@ -38,22 +36,21 @@ class PublishThumbnailInput extends React.Component {
|
||||||
}
|
}
|
||||||
updateVideoThumb (event) {
|
updateVideoThumb (event) {
|
||||||
const imageUrl = event.target.value;
|
const imageUrl = event.target.value;
|
||||||
const that = this;
|
|
||||||
if (this.urlIsAnImage(imageUrl)) {
|
if (this.urlIsAnImage(imageUrl)) {
|
||||||
this.testImage(imageUrl, 3000)
|
this.testImage(imageUrl, 3000)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('thumbnail is a valid image');
|
console.log('thumbnail is a valid image');
|
||||||
that.props.onThumbnailChange('thumbnail', imageUrl);
|
this.props.onThumbnailChange('thumbnail', imageUrl);
|
||||||
that.setState({thumbnailError: null});
|
this.setState({thumbnailError: null});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log('encountered an error loading thumbnail image url:', error);
|
console.log('encountered an error loading thumbnail image url:', error);
|
||||||
that.props.onThumbnailChange('thumbnail', null);
|
this.props.onThumbnailChange('thumbnail', null);
|
||||||
that.setState({thumbnailError: 'That is an invalid image url'});
|
this.setState({thumbnailError: 'That is an invalid image url'});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
that.props.onThumbnailChange('thumbnail', null);
|
this.props.onThumbnailChange('thumbnail', null);
|
||||||
that.setState({thumbnailError: null});
|
this.setState({thumbnailError: null});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -6,9 +6,6 @@ class PublishUrlInput extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.handleInput = this.handleInput.bind(this);
|
this.handleInput = this.handleInput.bind(this);
|
||||||
this.cleanseInput = this.cleanseInput.bind(this);
|
|
||||||
this.setClaimNameFromFileName = this.setClaimNameFromFileName.bind(this);
|
|
||||||
this.checkClaimIsAvailable = this.checkClaimIsAvailable.bind(this);
|
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
if (!this.props.claim || this.props.claim === '') {
|
if (!this.props.claim || this.props.claim === '') {
|
||||||
|
@ -40,18 +37,17 @@ class PublishUrlInput extends React.Component {
|
||||||
this.props.onClaimChange(cleanClaimName);
|
this.props.onClaimChange(cleanClaimName);
|
||||||
}
|
}
|
||||||
checkClaimIsAvailable (claim) {
|
checkClaimIsAvailable (claim) {
|
||||||
const that = this;
|
request(`/api/claim/availability/${claim}`)
|
||||||
request(`/api/claim-is-available/${claim}`)
|
|
||||||
.then(isAvailable => {
|
.then(isAvailable => {
|
||||||
// console.log('checkClaimIsAvailable request response:', isAvailable);
|
// console.log('checkClaimIsAvailable request response:', isAvailable);
|
||||||
if (isAvailable) {
|
if (isAvailable) {
|
||||||
that.props.onUrlError(null);
|
this.props.onUrlError(null);
|
||||||
} else {
|
} else {
|
||||||
that.props.onUrlError('That url has already been claimed');
|
this.props.onUrlError('That url has already been claimed');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
that.props.onUrlError(error.message);
|
this.props.onUrlError(error.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
|
16
react/containers/ShowPage/index.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { handleShowPageUri } from 'actions/show';
|
||||||
|
import View from './view';
|
||||||
|
|
||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
|
return {
|
||||||
|
error : show.request.error,
|
||||||
|
requestType: show.request.type,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = {
|
||||||
|
handleShowPageUri,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(View);
|
38
react/containers/ShowPage/view.jsx
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ErrorPage from 'components/ErrorPage';
|
||||||
|
import ShowAssetLite from 'components/ShowAssetLite';
|
||||||
|
import ShowAssetDetails from 'components/ShowAssetDetails';
|
||||||
|
import ShowChannel from 'components/ShowChannel';
|
||||||
|
|
||||||
|
import { CHANNEL, ASSET_LITE, ASSET_DETAILS } from 'constants/show_request_types';
|
||||||
|
|
||||||
|
class ShowPage extends React.Component {
|
||||||
|
componentDidMount () {
|
||||||
|
this.props.handleShowPageUri(this.props.match.params);
|
||||||
|
}
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (nextProps.match.params !== this.props.match.params) {
|
||||||
|
this.props.handleShowPageUri(nextProps.match.params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
const { error, requestType } = this.props;
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<ErrorPage error={error}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
switch (requestType) {
|
||||||
|
case CHANNEL:
|
||||||
|
return <ShowChannel />;
|
||||||
|
case ASSET_LITE:
|
||||||
|
return <ShowAssetLite />;
|
||||||
|
case ASSET_DETAILS:
|
||||||
|
return <ShowAssetDetails />;
|
||||||
|
default:
|
||||||
|
return <p>loading...</p>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShowPage;
|
24
react/index.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { render } from 'react-dom';
|
||||||
|
import { createStore, applyMiddleware, compose } from 'redux';
|
||||||
|
import Reducer from 'reducers';
|
||||||
|
import createSagaMiddleware from 'redux-saga';
|
||||||
|
import rootSaga from 'sagas';
|
||||||
|
import Root from './root';
|
||||||
|
|
||||||
|
const sagaMiddleware = createSagaMiddleware();
|
||||||
|
const middleware = applyMiddleware(sagaMiddleware);
|
||||||
|
|
||||||
|
const enhancer = window.__REDUX_DEVTOOLS_EXTENSION__ ? compose(middleware, window.__REDUX_DEVTOOLS_EXTENSION__()) : middleware;
|
||||||
|
|
||||||
|
let store = createStore(
|
||||||
|
Reducer,
|
||||||
|
enhancer,
|
||||||
|
);
|
||||||
|
|
||||||
|
sagaMiddleware.run(rootSaga);
|
||||||
|
|
||||||
|
render(
|
||||||
|
<Root store={store} />,
|
||||||
|
document.getElementById('react-app')
|
||||||
|
);
|
|
@ -8,19 +8,11 @@ const initialState = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
Reducers describe how the application's state changes in response to actions
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default function (state = initialState, action) {
|
export default function (state = initialState, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case actions.CHANNEL_UPDATE:
|
case actions.CHANNEL_UPDATE:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
loggedInChannel: {
|
loggedInChannel: action.data,
|
||||||
name : action.name,
|
|
||||||
shortId: action.shortId,
|
|
||||||
longId : action.longId,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { combineReducers } from 'redux';
|
import { combineReducers } from 'redux';
|
||||||
import PublishReducer from 'reducers/publish';
|
import PublishReducer from 'reducers/publish';
|
||||||
import ChannelReducer from 'reducers/channel';
|
import ChannelReducer from 'reducers/channel';
|
||||||
|
import ShowReducer from 'reducers/show';
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
channel: ChannelReducer,
|
channel: ChannelReducer,
|
||||||
publish: PublishReducer,
|
publish: PublishReducer,
|
||||||
|
show : ShowReducer,
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,27 +26,23 @@ const initialState = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
Reducers describe how the application's state changes in response to actions
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default function (state = initialState, action) {
|
export default function (state = initialState, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case actions.FILE_SELECTED:
|
case actions.FILE_SELECTED:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
file: action.file,
|
file: action.data,
|
||||||
});
|
});
|
||||||
case actions.FILE_CLEAR:
|
case actions.FILE_CLEAR:
|
||||||
return initialState;
|
return initialState;
|
||||||
case actions.METADATA_UPDATE:
|
case actions.METADATA_UPDATE:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
metadata: Object.assign({}, state.metadata, {
|
metadata: Object.assign({}, state.metadata, {
|
||||||
[action.name]: action.value,
|
[action.data.name]: action.data.value,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
case actions.CLAIM_UPDATE:
|
case actions.CLAIM_UPDATE:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
claim: action.value,
|
claim: action.data,
|
||||||
});
|
});
|
||||||
case actions.SET_PUBLISH_IN_CHANNEL:
|
case actions.SET_PUBLISH_IN_CHANNEL:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
|
@ -54,24 +50,21 @@ export default function (state = initialState, action) {
|
||||||
});
|
});
|
||||||
case actions.PUBLISH_STATUS_UPDATE:
|
case actions.PUBLISH_STATUS_UPDATE:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
status: Object.assign({}, state.status, {
|
status: action.data,
|
||||||
status : action.status,
|
|
||||||
message: action.message,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
case actions.ERROR_UPDATE:
|
case actions.ERROR_UPDATE:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
error: Object.assign({}, state.error, {
|
error: Object.assign({}, state.error, {
|
||||||
[action.name]: action.value,
|
[action.data.name]: action.data.value,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
case actions.SELECTED_CHANNEL_UPDATE:
|
case actions.SELECTED_CHANNEL_UPDATE:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
selectedChannel: action.value,
|
selectedChannel: action.data,
|
||||||
});
|
});
|
||||||
case actions.TOGGLE_METADATA_INPUTS:
|
case actions.TOGGLE_METADATA_INPUTS:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
showMetadataInputs: action.value,
|
showMetadataInputs: action.data,
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|
96
react/reducers/show.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
import * as actions from 'constants/show_action_types';
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
import { LOCAL_CHECK, ERROR } from 'constants/asset_display_states';
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
const initialState = {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
request: {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
error: null,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
type : null,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
id : null,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
requestList : {},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
channelList : {},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
assetList : {},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
displayAsset: {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
error : null,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
status: LOCAL_CHECK,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
};
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
export default function (state = initialState, action) {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
switch (action.type) {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
// handle request
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.REQUEST_UPDATE_ERROR:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
request: Object.assign({}, state.request, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
error: action.data,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.CHANNEL_REQUEST_NEW:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.ASSET_REQUEST_NEW:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
request: Object.assign({}, state.request, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
type: action.data.requestType,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
id : action.data.requestId,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
// store requests
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.REQUEST_LIST_ADD:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
requestList: Object.assign({}, state.requestList, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
[action.data.id]: {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
error: action.data.error,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
key : action.data.key,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
// asset data
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.ASSET_ADD:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
assetList: Object.assign({}, state.assetList, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
[action.data.id]: {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
error : action.data.error,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
name : action.data.name,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
claimId : action.data.claimId,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
shortId : action.data.shortId,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
claimData: action.data.claimData,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
// channel data
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.CHANNEL_ADD:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
channelList: Object.assign({}, state.channelList, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
[action.data.id]: {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
name : action.data.name,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
longId : action.data.longId,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
shortId : action.data.shortId,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
claimsData: action.data.claimsData,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
},
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.CHANNEL_CLAIMS_UPDATE_SUCCESS:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
channelList: Object.assign({}, state.channelList, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
[action.data.channelListId]: Object.assign({}, state.channelList[action.data.channelListId], {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
claimsData: action.data.claimsData,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
// display an asset
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.FILE_AVAILABILITY_UPDATE:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
displayAsset: Object.assign({}, state.displayAsset, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
status: action.data,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
case actions.DISPLAY_ASSET_ERROR:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return Object.assign({}, state, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
displayAsset: Object.assign({}, state.displayAsset, {
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
error : action.data,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
status: ERROR,
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}),
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
});
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
default:
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
return state;
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
|||||||
|
}
|
||||||
In the app we use a util to avoid a lot of the boiler plate with redux. It just makes it so you don't need to use a switch. I really like it. In the app we use a util to avoid a lot of the boiler plate with redux.
https://github.com/lbryio/lbry-app/blob/master/src/renderer/util/redux-utils.js
It just makes it so you don't need to use a switch. I really like it.
Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works. Hmm, I like the readability of the switch statement, but I might use this util instead. I have to look at the app and see exactly how it works.
Here is an example of it in the app Here is an example of it in the app
https://github.com/lbryio/lbry-app/blob/master/src/renderer/redux/reducers/shape_shift.js#L99
|
31
react/root.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import React from 'react';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import { Provider } from 'react-redux';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import PublishPage from 'components/PublishPage';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import AboutPage from 'components/AboutPage';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import LoginPage from 'containers/LoginPage';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import ShowPage from 'containers/ShowPage';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
import FourOhFourPage from 'components/FourOhFourPage';
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
const Root = ({ store }) => (
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Provider store={store}>
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<BrowserRouter>
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Switch>
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Route exact path="/" component={PublishPage} />
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Route exact path="/about" component={AboutPage} />
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Route exact path="/login" component={LoginPage} />
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Route exact path="/:identifier/:claim" component={ShowPage} />
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Route exact path="/:claim" component={ShowPage} />
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
<Route component={FourOhFourPage} />
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
</Switch>
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
</BrowserRouter>
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
</Provider>
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
);
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
Root.propTypes = {
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
store: PropTypes.object.isRequired,
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
};
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
|||||||
|
export default Root;
|
||||||
Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a Probably worth adding a 404 page or just redirect to the homepage if it doesn't find a route. Either with a `Redirect` component or just a route with no `path` prop.
|
33
react/sagas/file.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { call, put, takeLatest } from 'redux-saga/effects';
|
||||||
|
import * as actions from 'constants/show_action_types';
|
||||||
|
import { updateFileAvailability, updateDisplayAssetError } from 'actions/show';
|
||||||
|
import { UNAVAILABLE, AVAILABLE } from 'constants/asset_display_states';
|
||||||
|
import { checkFileAvailability, triggerClaimGet } from 'api/fileApi';
|
||||||
|
|
||||||
|
function* retrieveFile (action) {
|
||||||
|
const name = action.data.name;
|
||||||
|
const claimId = action.data.claimId;
|
||||||
|
// see if the file is available
|
||||||
|
let isAvailable;
|
||||||
|
try {
|
||||||
|
({ data: isAvailable } = yield call(checkFileAvailability, name, claimId));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(updateDisplayAssetError(error.message));
|
||||||
|
};
|
||||||
|
if (isAvailable) {
|
||||||
|
yield put(updateDisplayAssetError(null));
|
||||||
|
return yield put(updateFileAvailability(AVAILABLE));
|
||||||
|
}
|
||||||
|
yield put(updateFileAvailability(UNAVAILABLE));
|
||||||
|
// initiate get request for the file
|
||||||
|
try {
|
||||||
|
yield call(triggerClaimGet, name, claimId);
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(updateDisplayAssetError(error.message));
|
||||||
|
};
|
||||||
|
yield put(updateFileAvailability(AVAILABLE));
|
||||||
|
};
|
||||||
|
|
||||||
|
export function* watchFileIsRequested () {
|
||||||
|
yield takeLatest(actions.FILE_REQUESTED, retrieveFile);
|
||||||
|
};
|
15
react/sagas/index.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { all } from 'redux-saga/effects';
|
||||||
|
import { watchHandleShowPageUri } from './show_uri';
|
||||||
|
import { watchNewAssetRequest } from './show_asset';
|
||||||
|
import { watchNewChannelRequest, watchUpdateChannelClaims } from './show_channel';
|
||||||
|
import { watchFileIsRequested } from './file';
|
||||||
|
|
||||||
|
export default function* rootSaga () {
|
||||||
|
yield all([
|
||||||
|
watchHandleShowPageUri(),
|
||||||
|
watchNewAssetRequest(),
|
||||||
|
watchNewChannelRequest(),
|
||||||
|
watchUpdateChannelClaims(),
|
||||||
|
watchFileIsRequested(),
|
||||||
|
]);
|
||||||
|
}
|
57
react/sagas/show_asset.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import { call, put, select, takeLatest } from 'redux-saga/effects';
|
||||||
|
import * as actions from 'constants/show_action_types';
|
||||||
|
import { addRequestToRequestList, onRequestError, addAssetToAssetList } from 'actions/show';
|
||||||
|
import { getLongClaimId, getShortId, getClaimData } from 'api/assetApi';
|
||||||
|
import { selectShowState } from 'selectors/show';
|
||||||
|
|
||||||
|
function* newAssetRequest (action) {
|
||||||
|
const { requestId, name, modifier } = action.data;
|
||||||
|
const state = yield select(selectShowState);
|
||||||
|
// is this an existing request?
|
||||||
|
// If this uri is in the request list, it's already been fetched
|
||||||
|
if (state.requestList[requestId]) {
|
||||||
|
console.log('that request already exists in the request list!');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// get long id && add request to request list
|
||||||
|
console.log(`getting asset long id ${name}`);
|
||||||
|
let longId;
|
||||||
|
try {
|
||||||
|
({data: longId} = yield call(getLongClaimId, name, modifier));
|
||||||
|
} catch (error) {
|
||||||
|
console.log('error:', error);
|
||||||
|
return yield put(onRequestError(error.message));
|
||||||
|
}
|
||||||
|
const assetKey = `a#${name}#${longId}`;
|
||||||
|
yield put(addRequestToRequestList(requestId, null, assetKey));
|
||||||
|
// is this an existing asset?
|
||||||
|
// If this asset is in the asset list, it's already been fetched
|
||||||
|
if (state.assetList[assetKey]) {
|
||||||
|
console.log('that asset already exists in the asset list!');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// get short Id
|
||||||
|
console.log(`getting asset short id ${name} ${longId}`);
|
||||||
|
let shortId;
|
||||||
|
try {
|
||||||
|
({data: shortId} = yield call(getShortId, name, longId));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(onRequestError(error.message));
|
||||||
|
}
|
||||||
|
// get asset claim data
|
||||||
|
console.log(`getting asset claim data ${name} ${longId}`);
|
||||||
|
let claimData;
|
||||||
|
try {
|
||||||
|
({data: claimData} = yield call(getClaimData, name, longId));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(onRequestError(error.message));
|
||||||
|
}
|
||||||
|
// add asset to asset list
|
||||||
|
yield put(addAssetToAssetList(assetKey, null, name, longId, shortId, claimData));
|
||||||
|
// clear any errors in request error
|
||||||
|
yield put(onRequestError(null));
|
||||||
|
};
|
||||||
|
|
||||||
|
export function* watchNewAssetRequest () {
|
||||||
|
yield takeLatest(actions.ASSET_REQUEST_NEW, newAssetRequest);
|
||||||
|
};
|
64
react/sagas/show_channel.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
import {call, put, select, takeLatest} from 'redux-saga/effects';
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
import * as actions from 'constants/show_action_types';
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
import { addNewChannelToChannelList, addRequestToRequestList, onRequestError, updateChannelClaims } from 'actions/show';
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
import { getChannelClaims, getChannelData } from 'api/channelApi';
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
import { selectShowState } from 'selectors/show';
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
function* getNewChannelAndUpdateChannelList (action) {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
const { requestId, channelName, channelId } = action.data;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
const state = yield select(selectShowState);
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// is this an existing request?
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// If this uri is in the request list, it's already been fetched
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
if (state.requestList[requestId]) {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
console.log('that request already exists in the request list!');
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
return null;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// get channel long id
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
console.log('getting channel long id and short id');
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
let longId, shortId;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
try {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
({ data: {longChannelClaimId: longId, shortChannelClaimId: shortId} } = yield call(getChannelData, channelName, channelId));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
} catch (error) {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
return yield put(onRequestError(error.message));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// store the request in the channel requests list
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
const channelKey = `c#${channelName}#${longId}`;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
yield put(addRequestToRequestList(requestId, null, channelKey));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// is this an existing channel?
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// If this channel is in the channel list, it's already been fetched
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
if (state.channelList[channelKey]) {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
console.log('that channel already exists in the channel list!');
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
return null;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// get channel claims data
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
console.log('getting channel claims data');
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
let claimsData;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
try {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
({ data: claimsData } = yield call(getChannelClaims, channelName, longId, 1));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
} catch (error) {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
return yield put(onRequestError(error.message));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// store the channel data in the channel list
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
yield put(addNewChannelToChannelList(channelKey, channelName, shortId, longId, claimsData));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
// clear any request errors
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
yield put(onRequestError(null));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
export function* watchNewChannelRequest () {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
yield takeLatest(actions.CHANNEL_REQUEST_NEW, getNewChannelAndUpdateChannelList);
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
};
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
function* getNewClaimsAndUpdateChannel (action) {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
const { channelKey, name, longId, page } = action.data;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
let claimsData;
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
try {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
({ data: claimsData } = yield call(getChannelClaims, name, longId, page));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
} catch (error) {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
return yield put(onRequestError(error.message));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
yield put(updateChannelClaims(channelKey, claimsData));
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
export function* watchUpdateChannelClaims () {
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
yield takeLatest(actions.CHANNEL_CLAIMS_UPDATE_ASYNC, getNewClaimsAndUpdateChannel);
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
|||||||
|
}
|
||||||
I don't have any experience using Generally you want I don't have any experience using `redux-saga` so I might just not understand what is happening.
Generally you want `XX_SUCCESS` and `XX_FAIL` actions separated. That makes it a lot easier handling the data on the reducer.
If these aren't being used anywhere else, I don't think they need to be separated. IMO it would make these saga files easier to understand/follow, but not a big issue If these aren't being used anywhere else, I don't think they need to be separated.
IMO it would make these saga files easier to understand/follow, but not a big issue
|
60
react/sagas/show_uri.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { call, put, takeLatest } from 'redux-saga/effects';
|
||||||
|
import * as actions from 'constants/show_action_types';
|
||||||
|
import { onRequestError, onNewChannelRequest, onNewAssetRequest } from 'actions/show';
|
||||||
|
import lbryUri from 'utils/lbryUri';
|
||||||
|
|
||||||
|
function* parseAndUpdateIdentifierAndClaim (modifier, claim) {
|
||||||
|
console.log('parseAndUpdateIdentifierAndClaim');
|
||||||
|
// this is a request for an asset
|
||||||
|
// claim will be an asset claim
|
||||||
|
// the identifier could be a channel or a claim id
|
||||||
|
let isChannel, channelName, channelClaimId, claimId, claimName, extension;
|
||||||
|
try {
|
||||||
I think you need to add a state check here too. To see if that request exists. It looks like it will add the request to the list every time. I think you need to add a state check here too. To see if that request exists. It looks like it will add the request to the list every time.
|
|||||||
|
({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(modifier));
|
||||||
|
({ claimName, extension } = lbryUri.parseClaim(claim));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(onRequestError(error.message));
|
||||||
|
}
|
||||||
|
// trigger an new action to update the store
|
||||||
|
if (isChannel) {
|
||||||
|
return yield put(onNewAssetRequest(claimName, null, channelName, channelClaimId, extension));
|
||||||
|
};
|
||||||
|
yield put(onNewAssetRequest(claimName, claimId, null, null, extension));
|
||||||
|
}
|
||||||
|
function* parseAndUpdateClaimOnly (claim) {
|
||||||
|
console.log('parseAndUpdateIdentifierAndClaim');
|
||||||
|
// this could be a request for an asset or a channel page
|
||||||
|
// claim could be an asset claim or a channel claim
|
||||||
|
let isChannel, channelName, channelClaimId;
|
||||||
|
try {
|
||||||
|
({ isChannel, channelName, channelClaimId } = lbryUri.parseIdentifier(claim));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(onRequestError(error.message));
|
||||||
|
}
|
||||||
|
// trigger an new action to update the store
|
||||||
|
// return early if this request is for a channel
|
||||||
|
if (isChannel) {
|
||||||
|
return yield put(onNewChannelRequest(channelName, channelClaimId));
|
||||||
|
}
|
||||||
|
// if not for a channel, parse the claim request
|
||||||
|
let claimName, extension;
|
||||||
|
try {
|
||||||
|
({claimName, extension} = lbryUri.parseClaim(claim));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(onRequestError(error.message));
|
||||||
|
}
|
||||||
|
yield put(onNewAssetRequest(claimName, null, null, null, extension));
|
||||||
|
}
|
||||||
|
|
||||||
|
function* handleShowPageUri (action) {
|
||||||
|
console.log('handleShowPageUri');
|
||||||
|
const { identifier, claim } = action.data;
|
||||||
|
if (identifier) {
|
||||||
|
return yield call(parseAndUpdateIdentifierAndClaim, identifier, claim);
|
||||||
|
}
|
||||||
|
yield call(parseAndUpdateClaimOnly, claim);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function* watchHandleShowPageUri () {
|
||||||
|
yield takeLatest(actions.HANDLE_SHOW_URI, handleShowPageUri);
|
||||||
|
};
|
9
react/selectors/show.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export const selectAsset = (show) => {
|
||||||
|
const request = show.requestList[show.request.id];
|
||||||
|
const assetKey = request.key;
|
||||||
|
return show.assetList[assetKey];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const selectShowState = (state) => {
|
||||||
|
return state.show;
|
||||||
|
};
|
85
react/utils/lbryUri.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
module.exports = {
|
||||||
|
REGEXP_INVALID_CLAIM : /[^A-Za-z0-9-]/g,
|
||||||
|
REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,
|
||||||
|
REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,
|
||||||
|
CHANNEL_CHAR : '@',
|
||||||
|
parseIdentifier : function (identifier) {
|
||||||
|
const componentsRegex = new RegExp(
|
||||||
|
'([^:$#/]*)' + // value (stops at the first separator or end)
|
||||||
|
'([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
|
||||||
|
);
|
||||||
|
const [proto, value, modifierSeperator, modifier] = componentsRegex
|
||||||
|
.exec(identifier)
|
||||||
|
.map(match => match || null);
|
||||||
|
|
||||||
|
// Validate and process name
|
||||||
|
if (!value) {
|
||||||
|
throw new Error(`Check your URL. No channel name provided before "${modifierSeperator}"`);
|
||||||
|
}
|
||||||
|
const isChannel = value.startsWith(module.exports.CHANNEL_CHAR);
|
||||||
|
const channelName = isChannel ? value : null;
|
||||||
|
let claimId;
|
||||||
|
if (isChannel) {
|
||||||
|
if (!channelName) {
|
||||||
|
throw new Error('Check your URL. No channel name after "@".');
|
||||||
|
}
|
||||||
|
const nameBadChars = (channelName).match(module.exports.REGEXP_INVALID_CHANNEL);
|
||||||
|
if (nameBadChars) {
|
||||||
|
throw new Error(`Check your URL. Invalid characters in channel name: "${nameBadChars.join(', ')}".`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
claimId = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate and process modifier
|
||||||
|
let channelClaimId;
|
||||||
|
if (modifierSeperator) {
|
||||||
|
if (!modifier) {
|
||||||
|
throw new Error(`Check your URL. No modifier provided after separator "${modifierSeperator}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modifierSeperator === ':') {
|
||||||
|
channelClaimId = modifier;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Check your URL. The "${modifierSeperator}" modifier is not currently supported`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
isChannel,
|
||||||
|
channelName,
|
||||||
|
channelClaimId: channelClaimId || null,
|
||||||
|
claimId : claimId || null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
parseClaim: function (name) {
|
||||||
|
const componentsRegex = new RegExp(
|
||||||
|
'([^:$#/.]*)' + // name (stops at the first extension)
|
||||||
|
'([:$#.]?)([^/]*)' // extension separator, extension (stops at the first path separator or end)
|
||||||
|
);
|
||||||
|
const [proto, claimName, extensionSeperator, extension] = componentsRegex
|
||||||
|
.exec(name)
|
||||||
|
.map(match => match || null);
|
||||||
|
|
||||||
|
// Validate and process name
|
||||||
|
if (!claimName) {
|
||||||
|
throw new Error('Check your URL. No claim name provided before "."');
|
||||||
|
}
|
||||||
|
const nameBadChars = (claimName).match(module.exports.REGEXP_INVALID_CLAIM);
|
||||||
|
if (nameBadChars) {
|
||||||
|
throw new Error(`Check your URL. Invalid characters in claim name: "${nameBadChars.join(', ')}".`);
|
||||||
|
}
|
||||||
|
// Validate and process extension
|
||||||
|
if (extensionSeperator) {
|
||||||
|
if (!extension) {
|
||||||
|
throw new Error(`Check your URL. No file extension provided after separator "${extensionSeperator}".`);
|
||||||
|
}
|
||||||
|
if (extensionSeperator !== '.') {
|
||||||
|
throw new Error(`Check your URL. The "${extensionSeperator}" separator is not supported in the claim name.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
claimName,
|
||||||
|
extension: extension || null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
|
@ -13,18 +13,18 @@ function parseJSON (response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a network request came back fine, and throws an error if not
|
* Parses the status returned by a network request
|
||||||
*
|
*
|
||||||
* @param {object} response A response from a network request
|
* @param {object} response A response from a network request
|
||||||
|
* @param {object} response The parsed JSON from the network request
|
||||||
*
|
*
|
||||||
* @return {object|undefined} Returns either the response, or throws an error
|
* @return {object | undefined} Returns object with status and statusText, or undefined
|
||||||
*/
|
*/
|
||||||
function checkStatus (response) {
|
function checkStatus (response, jsonResponse) {
|
||||||
if (response.status >= 200 && response.status < 300) {
|
if (response.status >= 200 && response.status < 300) {
|
||||||
return response;
|
return jsonResponse;
|
||||||
}
|
}
|
||||||
|
const error = new Error(jsonResponse.message);
|
||||||
const error = new Error(response.statusText);
|
|
||||||
error.response = response;
|
error.response = response;
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,13 @@ function checkStatus (response) {
|
||||||
*
|
*
|
||||||
* @return {object} The response data
|
* @return {object} The response data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default function request (url, options) {
|
export default function request (url, options) {
|
||||||
return fetch(url, options)
|
return fetch(url, options)
|
||||||
.then(checkStatus)
|
.then(response => {
|
||||||
.then(parseJSON);
|
return Promise.all([response, parseJSON(response)]);
|
||||||
|
})
|
||||||
|
.then(([response, jsonResponse]) => {
|
||||||
|
return checkStatus(response, jsonResponse);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,36 +9,79 @@ const { createPublishParams, parsePublishApiRequestBody, parsePublishApiRequestF
|
||||||
const errorHandlers = require('../helpers/errorHandlers.js');
|
const errorHandlers = require('../helpers/errorHandlers.js');
|
||||||
const { sendGoogleAnalyticsTiming } = require('../helpers/statsHelpers.js');
|
const { sendGoogleAnalyticsTiming } = require('../helpers/statsHelpers.js');
|
||||||
const { authenticateIfNoUserToken } = require('../auth/authentication.js');
|
const { authenticateIfNoUserToken } = require('../auth/authentication.js');
|
||||||
|
const { getChannelData, getChannelClaims, getClaimId } = require('../controllers/serveController.js');
|
||||||
|
|
||||||
|
const NO_CHANNEL = 'NO_CHANNEL';
|
||||||
|
const NO_CLAIM = 'NO_CLAIM';
|
||||||
|
|
||||||
module.exports = (app) => {
|
module.exports = (app) => {
|
||||||
// route to run a claim_list request on the daemon
|
// route to check whether site has published to a channel
|
||||||
app.get('/api/claim-list/:name', ({ ip, originalUrl, params }, res) => {
|
app.get('/api/channel/availability/:name', ({ ip, originalUrl, params }, res) => {
|
||||||
getClaimList(params.name)
|
checkChannelAvailability(params.name)
|
||||||
.then(claimsList => {
|
|
||||||
res.status(200).json(claimsList);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
errorHandlers.handleApiError(originalUrl, ip, error, res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// route to see if asset is available locally
|
|
||||||
app.get('/api/file-is-available/:name/:claimId', ({ ip, originalUrl, params }, res) => {
|
|
||||||
const name = params.name;
|
|
||||||
const claimId = params.claimId;
|
|
||||||
let isLocalFileAvailable = false;
|
|
||||||
db.File.findOne({where: {name, claimId}})
|
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if (result) {
|
if (result === true) {
|
||||||
isLocalFileAvailable = true;
|
res.status(200).json(true);
|
||||||
|
} else {
|
||||||
|
res.status(200).json(false);
|
||||||
}
|
}
|
||||||
res.status(200).json({status: 'success', message: isLocalFileAvailable});
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
errorHandlers.handleApiError(originalUrl, ip, error, res);
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// route to get a short channel id from long channel Id
|
||||||
|
app.get('/api/channel/short-id/:longId/:name', ({ ip, originalUrl, params }, res) => {
|
||||||
|
db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name)
|
||||||
|
.then(shortId => {
|
||||||
|
res.status(200).json(shortId);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
app.get('/api/channel/data/:channelName/:channelClaimId', ({ ip, originalUrl, body, params }, res) => {
|
||||||
|
const channelName = params.channelName;
|
||||||
|
let channelClaimId = params.channelClaimId;
|
||||||
|
if (channelClaimId === 'none') channelClaimId = null;
|
||||||
|
getChannelData(channelName, channelClaimId, 0)
|
||||||
|
.then(data => {
|
||||||
|
if (data === NO_CHANNEL) {
|
||||||
|
return res.status(404).json({success: false, message: 'No matching channel was found'});
|
||||||
|
}
|
||||||
|
res.status(200).json({success: true, data});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
app.get('/api/channel/claims/:channelName/:channelClaimId/:page', ({ ip, originalUrl, body, params }, res) => {
|
||||||
|
const channelName = params.channelName;
|
||||||
|
let channelClaimId = params.channelClaimId;
|
||||||
|
if (channelClaimId === 'none') channelClaimId = null;
|
||||||
|
const page = params.page;
|
||||||
|
getChannelClaims(channelName, channelClaimId, page)
|
||||||
|
.then(data => {
|
||||||
|
if (data === NO_CHANNEL) {
|
||||||
|
return res.status(404).json({success: false, message: 'No matching channel was found'});
|
||||||
|
}
|
||||||
|
res.status(200).json({success: true, data});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// route to run a claim_list request on the daemon
|
||||||
|
app.get('/api/claim/list/:name', ({ ip, originalUrl, params }, res) => {
|
||||||
|
getClaimList(params.name)
|
||||||
|
.then(claimsList => {
|
||||||
|
res.status(200).json(claimsList);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// route to get an asset
|
// route to get an asset
|
||||||
app.get('/api/claim-get/:name/:claimId', ({ ip, originalUrl, params }, res) => {
|
app.get('/api/claim/get/:name/:claimId', ({ ip, originalUrl, params }, res) => {
|
||||||
const name = params.name;
|
const name = params.name;
|
||||||
const claimId = params.claimId;
|
const claimId = params.claimId;
|
||||||
// resolve the claim
|
// resolve the claim
|
||||||
|
@ -57,30 +100,15 @@ module.exports = (app) => {
|
||||||
return Promise.all([db.upsert(db.File, fileData, {name, claimId}, 'File'), getResult]);
|
return Promise.all([db.upsert(db.File, fileData, {name, claimId}, 'File'), getResult]);
|
||||||
})
|
})
|
||||||
.then(([ fileRecord, {message, completed} ]) => {
|
.then(([ fileRecord, {message, completed} ]) => {
|
||||||
res.status(200).json({ status: 'success', message, completed });
|
res.status(200).json({ success: true, message, completed });
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
errorHandlers.handleApiError(originalUrl, ip, error, res);
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// route to check whether this site published to a claim
|
// route to check whether this site published to a claim
|
||||||
app.get('/api/claim-is-available/:name', ({ params }, res) => {
|
app.get('/api/claim/availability/:name', ({ ip, originalUrl, params }, res) => {
|
||||||
checkClaimNameAvailability(params.name)
|
checkClaimNameAvailability(params.name)
|
||||||
.then(result => {
|
|
||||||
if (result === true) {
|
|
||||||
res.status(200).json(true);
|
|
||||||
} else {
|
|
||||||
res.status(200).json(false);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
res.status(500).json(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// route to check whether site has published to a channel
|
|
||||||
app.get('/api/channel-is-available/:name', ({ params }, res) => {
|
|
||||||
checkChannelAvailability(params.name)
|
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if (result === true) {
|
if (result === true) {
|
||||||
res.status(200).json(true);
|
res.status(200).json(true);
|
||||||
|
@ -89,21 +117,21 @@ module.exports = (app) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
res.status(500).json(error);
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// route to run a resolve request on the daemon
|
// route to run a resolve request on the daemon
|
||||||
app.get('/api/claim-resolve/:uri', ({ headers, ip, originalUrl, params }, res) => {
|
app.get('/api/claim/resolve/:name/:claimId', ({ headers, ip, originalUrl, params }, res) => {
|
||||||
resolveUri(params.uri)
|
resolveUri(`${params.name}#${params.claimId}`)
|
||||||
.then(resolvedUri => {
|
.then(resolvedUri => {
|
||||||
res.status(200).json(resolvedUri);
|
res.status(200).json(resolvedUri);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
errorHandlers.handleApiError(originalUrl, ip, error, res);
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// route to run a publish request on the daemon
|
// route to run a publish request on the daemon
|
||||||
app.post('/api/claim-publish', multipartMiddleware, ({ body, files, headers, ip, originalUrl, user }, res) => {
|
app.post('/api/claim/publish', multipartMiddleware, ({ body, files, headers, ip, originalUrl, user }, res) => {
|
||||||
logger.debug('api/claim-publish body:', body);
|
logger.debug('api/claim-publish body:', body);
|
||||||
logger.debug('api/claim-publish files:', files);
|
logger.debug('api/claim-publish files:', files);
|
||||||
// record the start time of the request and create variable for storing the action type
|
// record the start time of the request and create variable for storing the action type
|
||||||
|
@ -119,70 +147,108 @@ module.exports = (app) => {
|
||||||
({fileName, filePath, fileType} = parsePublishApiRequestFiles(files));
|
({fileName, filePath, fileType} = parsePublishApiRequestFiles(files));
|
||||||
({channelName, channelPassword} = parsePublishApiChannel(body, user));
|
({channelName, channelPassword} = parsePublishApiChannel(body, user));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.debug('publish request rejected, insufficient request parameters', error);
|
|
||||||
return res.status(400).json({success: false, message: error.message});
|
return res.status(400).json({success: false, message: error.message});
|
||||||
}
|
}
|
||||||
// check channel authorization
|
// check channel authorization
|
||||||
authenticateIfNoUserToken(channelName, channelPassword, user)
|
authenticateIfNoUserToken(channelName, channelPassword, user)
|
||||||
.then(authenticated => {
|
.then(authenticated => {
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
throw new Error('Authentication failed, you do not have access to that channel');
|
throw new Error('Authentication failed, you do not have access to that channel');
|
||||||
}
|
}
|
||||||
// make sure the claim name is available
|
// make sure the claim name is available
|
||||||
return checkClaimNameAvailability(name);
|
return checkClaimNameAvailability(name);
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error('That name is already claimed by another user.');
|
throw new Error('That name is already claimed by another user.');
|
||||||
}
|
}
|
||||||
// create publish parameters object
|
// create publish parameters object
|
||||||
return createPublishParams(filePath, name, title, description, license, nsfw, thumbnail, channelName);
|
return createPublishParams(filePath, name, title, description, license, nsfw, thumbnail, channelName);
|
||||||
})
|
})
|
||||||
.then(publishParams => {
|
.then(publishParams => {
|
||||||
// set the timing event type for reporting
|
// set the timing event type for reporting
|
||||||
timingActionType = returnPublishTimingActionType(publishParams.channel_name);
|
timingActionType = returnPublishTimingActionType(publishParams.channel_name);
|
||||||
// publish the asset
|
// publish the asset
|
||||||
return publish(publishParams, fileName, fileType);
|
return publish(publishParams, fileName, fileType);
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
message: {
|
message: 'publish completed successfully',
|
||||||
name,
|
data : {
|
||||||
url : `${site.host}/${result.claim_id}/${name}`,
|
name,
|
||||||
lbryTx: result,
|
claimId: result.claim_id,
|
||||||
},
|
url : `${site.host}/${result.claim_id}/${name}`,
|
||||||
|
lbryTx : result,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// log the publish end time
|
||||||
|
const publishEndTime = Date.now();
|
||||||
|
logger.debug('publish request completed @', publishEndTime);
|
||||||
|
sendGoogleAnalyticsTiming(timingActionType, headers, ip, originalUrl, publishStartTime, publishEndTime);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
});
|
});
|
||||||
// log the publish end time
|
|
||||||
const publishEndTime = Date.now();
|
|
||||||
logger.debug('publish request completed @', publishEndTime);
|
|
||||||
sendGoogleAnalyticsTiming(timingActionType, headers, ip, originalUrl, publishStartTime, publishEndTime);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
errorHandlers.handleApiError(originalUrl, ip, error, res);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
// route to get a short claim id from long claim Id
|
// route to get a short claim id from long claim Id
|
||||||
app.get('/api/claim-shorten-id/:longId/:name', ({ params }, res) => {
|
app.get('/api/claim/short-id/:longId/:name', ({ ip, originalUrl, body, params }, res) => {
|
||||||
db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name)
|
db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name)
|
||||||
.then(shortId => {
|
.then(shortId => {
|
||||||
res.status(200).json(shortId);
|
res.status(200).json({success: true, data: shortId});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
logger.error('api error getting short channel id', error);
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
res.status(400).json(error.message);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// route to get a short channel id from long channel Id
|
app.post('/api/claim/long-id', ({ ip, originalUrl, body, params }, res) => {
|
||||||
app.get('/api/channel-shorten-id/:longId/:name', ({ ip, originalUrl, params }, res) => {
|
logger.debug('body:', body);
|
||||||
db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name)
|
const channelName = body.channelName;
|
||||||
.then(shortId => {
|
const channelClaimId = body.channelClaimId;
|
||||||
logger.debug('sending back short channel id', shortId);
|
const claimName = body.claimName;
|
||||||
res.status(200).json(shortId);
|
const claimId = body.claimId;
|
||||||
|
getClaimId(channelName, channelClaimId, claimName, claimId)
|
||||||
|
.then(result => {
|
||||||
|
if (result === NO_CHANNEL) {
|
||||||
|
return res.status(404).json({success: false, message: 'No matching channel could be found'});
|
||||||
|
}
|
||||||
|
if (result === NO_CLAIM) {
|
||||||
|
return res.status(404).json({success: false, message: 'No matching claim id could be found'});
|
||||||
|
}
|
||||||
|
res.status(200).json({success: true, data: result});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
logger.error('api error getting short channel id', error);
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
errorHandlers.handleApiError(originalUrl, ip, error, res);
|
});
|
||||||
|
});
|
||||||
|
app.get('/api/claim/data/:claimName/:claimId', ({ ip, originalUrl, body, params }, res) => {
|
||||||
|
const claimName = params.claimName;
|
||||||
|
let claimId = params.claimId;
|
||||||
|
if (claimId === 'none') claimId = null;
|
||||||
|
db.Claim.resolveClaim(claimName, claimId)
|
||||||
|
.then(claimInfo => {
|
||||||
|
if (!claimInfo) {
|
||||||
|
return res.status(404).json({success: false, message: 'No claim could be found'});
|
||||||
|
}
|
||||||
|
res.status(200).json({success: true, data: claimInfo});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// route to see if asset is available locally
|
||||||
|
app.get('/api/file/availability/:name/:claimId', ({ ip, originalUrl, params }, res) => {
|
||||||
|
const name = params.name;
|
||||||
|
const claimId = params.claimId;
|
||||||
|
db.File.findOne({where: {name, claimId}})
|
||||||
|
.then(result => {
|
||||||
|
if (result) {
|
||||||
|
return res.status(200).json({success: true, data: true});
|
||||||
|
}
|
||||||
|
res.status(200).json({success: true, data: false});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = (app) => {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return res.status(200).json({
|
return res.status(400).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: info.message,
|
message: info.message,
|
||||||
});
|
});
|
||||||
|
@ -39,12 +39,17 @@ module.exports = (app) => {
|
||||||
});
|
});
|
||||||
})(req, res, next);
|
})(req, res, next);
|
||||||
});
|
});
|
||||||
|
// route to log out
|
||||||
|
app.get('/logout', (req, res) => {
|
||||||
|
req.logout();
|
||||||
|
res.status(200).json({success: true, message: 'you successfully logged out'});
|
||||||
|
});
|
||||||
// see if user is authenticated, and return credentials if so
|
// see if user is authenticated, and return credentials if so
|
||||||
app.get('/user', (req, res) => {
|
app.get('/user', (req, res) => {
|
||||||
if (req.user) {
|
if (req.user) {
|
||||||
res.status(200).json({success: true, message: req.user});
|
res.status(200).json({success: true, data: req.user});
|
||||||
} else {
|
} else {
|
||||||
res.status(200).json({success: false, message: 'user is not logged in'});
|
res.status(401).json({success: false, message: 'user is not logged in'});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,6 @@ module.exports = app => {
|
||||||
// a catch-all route if someone visits a page that does not exist
|
// a catch-all route if someone visits a page that does not exist
|
||||||
app.use('*', ({ originalUrl, ip }, res) => {
|
app.use('*', ({ originalUrl, ip }, res) => {
|
||||||
// send response
|
// send response
|
||||||
res.status(404).render('fourOhFour');
|
res.status(404).render('404');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,53 +1,24 @@
|
||||||
const errorHandlers = require('../helpers/errorHandlers.js');
|
|
||||||
const { getTrendingClaims, getRecentClaims } = require('../controllers/statsController.js');
|
|
||||||
const { site } = require('../config/speechConfig.js');
|
const { site } = require('../config/speechConfig.js');
|
||||||
|
|
||||||
module.exports = (app) => {
|
module.exports = (app) => {
|
||||||
// route to log out
|
|
||||||
app.get('/logout', (req, res) => {
|
|
||||||
req.logout();
|
|
||||||
res.redirect('/');
|
|
||||||
});
|
|
||||||
// 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).render('index');
|
||||||
res.status(200).redirect(`/${req.user.channelName}`);
|
|
||||||
} else {
|
|
||||||
res.status(200).render('login');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// route to show 'about' page
|
// route to show 'about' page
|
||||||
app.get('/about', (req, res) => {
|
app.get('/about', (req, res) => {
|
||||||
// get and render the content
|
res.status(200).render('index');
|
||||||
res.status(200).render('about');
|
|
||||||
});
|
});
|
||||||
// route to display a list of the trending images
|
// route to display a list of the trending images
|
||||||
app.get('/trending', (req, res) => {
|
app.get('/trending', (req, res) => {
|
||||||
res.status(301).redirect('/popular');
|
res.status(301).redirect('/popular');
|
||||||
});
|
});
|
||||||
app.get('/popular', ({ ip, originalUrl }, res) => {
|
app.get('/popular', ({ ip, originalUrl }, res) => {
|
||||||
const startDate = new Date();
|
res.status(200).render('index');
|
||||||
startDate.setDate(startDate.getDate() - 1);
|
|
||||||
const dateTime = startDate.toISOString().slice(0, 19).replace('T', ' ');
|
|
||||||
getTrendingClaims(dateTime)
|
|
||||||
.then(result => {
|
|
||||||
res.status(200).render('popular', {
|
|
||||||
trendingAssets: result,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
errorHandlers.handleRequestError(originalUrl, ip, error, res);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
// route to display a list of the trending images
|
// route to display a list of the trending images
|
||||||
app.get('/new', ({ ip, originalUrl }, res) => {
|
app.get('/new', ({ ip, originalUrl }, res) => {
|
||||||
getRecentClaims()
|
res.status(200).render('index');
|
||||||
.then(result => {
|
|
||||||
res.status(200).render('new', { newClaims: result });
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
errorHandlers.handleRequestError(originalUrl, ip, error, res);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
// route to send embedable video player (for twitter)
|
// route to send embedable video player (for twitter)
|
||||||
app.get('/embed/:claimId/:name', ({ params }, res) => {
|
app.get('/embed/:claimId/:name', ({ params }, res) => {
|
||||||
|
@ -57,9 +28,4 @@ module.exports = (app) => {
|
||||||
// get and render the content
|
// get and render the content
|
||||||
res.status(200).render('embed', { layout: 'embed', host, claimId, name });
|
res.status(200).render('embed', { layout: 'embed', host, claimId, name });
|
||||||
});
|
});
|
||||||
// route to display all free public claims at a given name
|
|
||||||
app.get('/:name/all', (req, res) => {
|
|
||||||
// get and render the content
|
|
||||||
res.status(410).send('/:name/all is no longer supported');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
const { getClaimId, getChannelViewData, getLocalFileRecord } = require('../controllers/serveController.js');
|
const { getClaimId, getLocalFileRecord } = require('../controllers/serveController.js');
|
||||||
const serveHelpers = require('../helpers/serveHelpers.js');
|
const serveHelpers = require('../helpers/serveHelpers.js');
|
||||||
const { handleRequestError } = require('../helpers/errorHandlers.js');
|
const { handleErrorResponse } = require('../helpers/errorHandlers.js');
|
||||||
const { postToStats } = require('../helpers/statsHelpers.js');
|
|
||||||
const db = require('../models');
|
|
||||||
const lbryUri = require('../helpers/lbryUri.js');
|
const lbryUri = require('../helpers/lbryUri.js');
|
||||||
|
|
||||||
const SERVE = 'SERVE';
|
const SERVE = 'SERVE';
|
||||||
const SHOW = 'SHOW';
|
const SHOW = 'SHOW';
|
||||||
const SHOWLITE = 'SHOWLITE';
|
|
||||||
const NO_CHANNEL = 'NO_CHANNEL';
|
const NO_CHANNEL = 'NO_CHANNEL';
|
||||||
const NO_CLAIM = 'NO_CLAIM';
|
const NO_CLAIM = 'NO_CLAIM';
|
||||||
const NO_FILE = 'NO_FILE';
|
const NO_FILE = 'NO_FILE';
|
||||||
|
@ -25,25 +22,6 @@ function isValidShortIdOrClaimId (input) {
|
||||||
return (isValidClaimId(input) || isValidShortId(input));
|
return (isValidClaimId(input) || isValidShortId(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendChannelInfoAndContentToClient (channelPageData, res) {
|
|
||||||
if (channelPageData === NO_CHANNEL) {
|
|
||||||
res.status(200).render('noChannel');
|
|
||||||
} else {
|
|
||||||
res.status(200).render('channel', channelPageData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showChannelPageToClient (channelName, channelClaimId, originalUrl, ip, query, res) {
|
|
||||||
// 1. retrieve the channel contents
|
|
||||||
getChannelViewData(channelName, channelClaimId, query)
|
|
||||||
.then(channelViewData => {
|
|
||||||
sendChannelInfoAndContentToClient(channelViewData, res);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
handleRequestError(originalUrl, ip, error, res);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function clientAcceptsHtml ({accept}) {
|
function clientAcceptsHtml ({accept}) {
|
||||||
return accept && accept.match(/text\/html/);
|
return accept && accept.match(/text\/html/);
|
||||||
}
|
}
|
||||||
|
@ -58,55 +36,29 @@ function clientWantsAsset ({accept, range}) {
|
||||||
return imageIsWanted || videoIsWanted;
|
return imageIsWanted || videoIsWanted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function determineResponseType (isServeRequest, headers) {
|
function determineResponseType (hasFileExtension, headers) {
|
||||||
let responseType;
|
let responseType;
|
||||||
if (isServeRequest) {
|
if (hasFileExtension) {
|
||||||
responseType = SERVE;
|
responseType = SERVE; // assume a serve request if file extension is present
|
||||||
if (clientAcceptsHtml(headers)) { // this is in case a serve request comes from a browser
|
if (clientAcceptsHtml(headers)) { // if the request comes from a browser, change it to a show request
|
||||||
responseType = SHOWLITE;
|
responseType = SHOW;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
responseType = SHOW;
|
responseType = SHOW;
|
||||||
if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) { // this is in case someone embeds a show url
|
if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) { // this is in case someone embeds a show url
|
||||||
logger.debug('Show request came from browser and wants an image/video; changing response to serve.');
|
logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');
|
||||||
responseType = SERVE;
|
responseType = SERVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return responseType;
|
return responseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAssetToClient (claimId, name, res) {
|
|
||||||
return Promise
|
|
||||||
.all([db.Claim.resolveClaim(name, claimId), db.Claim.getShortClaimIdFromLongClaimId(claimId, name)])
|
|
||||||
.then(([claimInfo, shortClaimId]) => {
|
|
||||||
// logger.debug('claimInfo:', claimInfo);
|
|
||||||
// logger.debug('shortClaimId:', shortClaimId);
|
|
||||||
return serveHelpers.showFile(claimInfo, shortClaimId, res);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
throw error;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function showLiteAssetToClient (claimId, name, res) {
|
|
||||||
return Promise
|
|
||||||
.all([db.Claim.resolveClaim(name, claimId), db.Claim.getShortClaimIdFromLongClaimId(claimId, name)])
|
|
||||||
.then(([claimInfo, shortClaimId]) => {
|
|
||||||
// logger.debug('claimInfo:', claimInfo);
|
|
||||||
// logger.debug('shortClaimId:', shortClaimId);
|
|
||||||
return serveHelpers.showFileLite(claimInfo, shortClaimId, res);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
throw error;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function serveAssetToClient (claimId, name, res) {
|
function serveAssetToClient (claimId, name, res) {
|
||||||
return getLocalFileRecord(claimId, name)
|
return getLocalFileRecord(claimId, name)
|
||||||
.then(fileInfo => {
|
.then(fileInfo => {
|
||||||
// logger.debug('fileInfo:', fileInfo);
|
// logger.debug('fileInfo:', fileInfo);
|
||||||
if (fileInfo === NO_FILE) {
|
if (fileInfo === NO_FILE) {
|
||||||
return res.status(307).redirect(`/api/claim-get/${name}/${claimId}`);
|
return res.status(307).redirect(`/api/claim/get/${name}/${claimId}`);
|
||||||
}
|
}
|
||||||
return serveHelpers.serveFile(fileInfo, claimId, name, res);
|
return serveHelpers.serveFile(fileInfo, claimId, name, res);
|
||||||
})
|
})
|
||||||
|
@ -115,19 +67,6 @@ function serveAssetToClient (claimId, name, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showOrServeAsset (responseType, claimId, claimName, res) {
|
|
||||||
switch (responseType) {
|
|
||||||
case SHOW:
|
|
||||||
return showAssetToClient(claimId, claimName, res);
|
|
||||||
case SHOWLITE:
|
|
||||||
return showLiteAssetToClient(claimId, claimName, res);
|
|
||||||
case SERVE:
|
|
||||||
return serveAssetToClient(claimId, claimName, res);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function flipClaimNameAndIdForBackwardsCompatibility (identifier, name) {
|
function flipClaimNameAndIdForBackwardsCompatibility (identifier, name) {
|
||||||
// this is a patch for backwards compatability with '/name/claim_id' url format
|
// this is a patch for backwards compatability with '/name/claim_id' url format
|
||||||
if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {
|
if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {
|
||||||
|
@ -147,70 +86,87 @@ function logRequestData (responseType, claimName, channelName, claimId) {
|
||||||
|
|
||||||
module.exports = (app) => {
|
module.exports = (app) => {
|
||||||
// route to serve a specific asset using the channel or claim id
|
// route to serve a specific asset using the channel or claim id
|
||||||
app.get('/:identifier/:name', ({ headers, ip, originalUrl, params }, res) => {
|
app.get('/:identifier/:claim', ({ headers, ip, originalUrl, params }, res) => {
|
||||||
let isChannel, channelName, channelClaimId, claimId, claimName, isServeRequest;
|
// decide if this is a show request
|
||||||
|
let hasFileExtension;
|
||||||
|
try {
|
||||||
|
({ hasFileExtension } = lbryUri.parseModifier(params.claim));
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(400).json({success: false, message: error.message});
|
||||||
|
}
|
||||||
|
let responseType = determineResponseType(hasFileExtension, headers);
|
||||||
|
if (responseType !== SERVE) {
|
||||||
|
return res.status(200).render('index');
|
||||||
|
}
|
||||||
|
// parse the claim
|
||||||
|
let claimName;
|
||||||
|
try {
|
||||||
|
({ claimName } = lbryUri.parseClaim(params.claim));
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(400).json({success: false, message: error.message});
|
||||||
|
}
|
||||||
|
// parse the identifier
|
||||||
|
let isChannel, channelName, channelClaimId, claimId;
|
||||||
try {
|
try {
|
||||||
({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(params.identifier));
|
({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(params.identifier));
|
||||||
({ claimName, isServeRequest } = lbryUri.parseName(params.name));
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return handleRequestError(originalUrl, ip, error, res);
|
return res.status(400).json({success: false, message: error.message});
|
||||||
}
|
}
|
||||||
if (!isChannel) {
|
if (!isChannel) {
|
||||||
[claimId, claimName] = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);
|
[claimId, claimName] = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);
|
||||||
}
|
}
|
||||||
let responseType = determineResponseType(isServeRequest, headers);
|
|
||||||
// log the request data for debugging
|
// log the request data for debugging
|
||||||
logRequestData(responseType, claimName, channelName, claimId);
|
logRequestData(responseType, claimName, channelName, claimId);
|
||||||
// get the claim Id and then serve/show the asset
|
// get the claim Id and then serve the asset
|
||||||
getClaimId(channelName, channelClaimId, claimName, claimId)
|
getClaimId(channelName, channelClaimId, claimName, claimId)
|
||||||
.then(fullClaimId => {
|
.then(fullClaimId => {
|
||||||
if (fullClaimId === NO_CLAIM) {
|
if (fullClaimId === NO_CLAIM) {
|
||||||
return res.status(200).render('noClaim');
|
return res.status(404).json({success: false, message: 'no claim id could be found'});
|
||||||
} else if (fullClaimId === NO_CHANNEL) {
|
} else if (fullClaimId === NO_CHANNEL) {
|
||||||
return res.status(200).render('noChannel');
|
return res.status(404).json({success: false, message: 'no channel id could be found'});
|
||||||
}
|
}
|
||||||
showOrServeAsset(responseType, fullClaimId, claimName, res);
|
serveAssetToClient(fullClaimId, claimName, res);
|
||||||
postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
|
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
handleRequestError(originalUrl, ip, error, res);
|
handleErrorResponse(originalUrl, ip, error, res);
|
||||||
});
|
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
// route to serve the winning asset at a claim or a channel page
|
// route to serve the winning asset at a claim or a channel page
|
||||||
app.get('/:identifier', ({ headers, ip, originalUrl, params, query }, res) => {
|
app.get('/:claim', ({ headers, ip, originalUrl, params, query }, res) => {
|
||||||
let isChannel, channelName, channelClaimId;
|
// decide if this is a show request
|
||||||
|
let hasFileExtension;
|
||||||
try {
|
try {
|
||||||
({ isChannel, channelName, channelClaimId } = lbryUri.parseIdentifier(params.identifier));
|
({ hasFileExtension } = lbryUri.parseModifier(params.claim));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return handleRequestError(originalUrl, ip, error, res);
|
return res.status(400).json({success: false, message: error.message});
|
||||||
}
|
}
|
||||||
if (isChannel) {
|
let responseType = determineResponseType(hasFileExtension, headers);
|
||||||
// log the request data for debugging
|
if (responseType !== SERVE) {
|
||||||
logRequestData(null, null, channelName, null);
|
return res.status(200).render('index');
|
||||||
// handle showing the channel page
|
|
||||||
showChannelPageToClient(channelName, channelClaimId, originalUrl, ip, query, res);
|
|
||||||
} else {
|
|
||||||
let claimName, isServeRequest;
|
|
||||||
try {
|
|
||||||
({claimName, isServeRequest} = lbryUri.parseName(params.identifier));
|
|
||||||
} catch (error) {
|
|
||||||
return handleRequestError(originalUrl, ip, error, res);
|
|
||||||
}
|
|
||||||
let responseType = determineResponseType(isServeRequest, headers);
|
|
||||||
// log the request data for debugging
|
|
||||||
logRequestData(responseType, claimName, null, null);
|
|
||||||
// get the claim Id and then serve/show the asset
|
|
||||||
getClaimId(null, null, claimName, null)
|
|
||||||
.then(fullClaimId => {
|
|
||||||
if (fullClaimId === NO_CLAIM) {
|
|
||||||
return res.status(200).render('noClaim');
|
|
||||||
}
|
|
||||||
showOrServeAsset(responseType, fullClaimId, claimName, res);
|
|
||||||
postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
handleRequestError(originalUrl, ip, error, res);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
// parse the claim
|
||||||
|
let claimName;
|
||||||
|
try {
|
||||||
|
({claimName} = lbryUri.parseClaim(params.claim));
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(400).json({success: false, message: error.message});
|
||||||
|
}
|
||||||
|
// log the request data for debugging
|
||||||
|
logRequestData(responseType, claimName, null, null);
|
||||||
|
// get the claim Id and then serve the asset
|
||||||
|
getClaimId(null, null, claimName, null)
|
||||||
|
.then(fullClaimId => {
|
||||||
|
if (fullClaimId === NO_CLAIM) {
|
||||||
|
return res.status(404).json({success: false, message: 'no claim id could be found'});
|
||||||
|
}
|
||||||
|
serveAssetToClient(fullClaimId, claimName, res);
|
||||||
|
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
handleErrorResponse(originalUrl, ip, error, res);
|
||||||
|
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// load dependencies
|
// load dependencies
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
const db = require('../models/index'); // require our models for syncing
|
const db = require('../models'); // require our models for syncing
|
||||||
// configure logging
|
// configure logging
|
||||||
const config = require('../config/speechConfig.js');
|
const config = require('../config/speechConfig.js');
|
||||||
const { logLevel } = config.logging;
|
const { logLevel } = config.logging;
|
||||||
|
|
|
@ -84,8 +84,28 @@ describe('end-to-end', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('channel data request from client', function () {
|
||||||
|
const url = '/@test';
|
||||||
|
const urlWithShortClaimId = '/@test:3';
|
||||||
|
const urlWithMediumClaimId = '/@test:3b5bc6b6819172c6';
|
||||||
|
const urlWithLongClaimId = '/@test:3b5bc6b6819172c6e2f3f90aa855b14a956b4a82';
|
||||||
|
|
||||||
|
describe(url, function () {
|
||||||
|
it('should pass the tests I write here');
|
||||||
|
});
|
||||||
|
describe(urlWithShortClaimId, function () {
|
||||||
|
it('should pass the tests I write here');
|
||||||
|
});
|
||||||
|
describe(urlWithMediumClaimId, function () {
|
||||||
|
it('should pass the tests I write here');
|
||||||
|
});
|
||||||
|
describe(urlWithLongClaimId, function () {
|
||||||
|
it('should pass the tests I write here');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('publish requests', function () {
|
describe('publish requests', function () {
|
||||||
const publishUrl = '/api/claim-publish';
|
const publishUrl = '/api/claim/publish';
|
||||||
const filePath = './test/mock-data/bird.jpeg';
|
const filePath = './test/mock-data/bird.jpeg';
|
||||||
const fileName = 'byrd.jpeg';
|
const fileName = 'byrd.jpeg';
|
||||||
const channelName = testChannel;
|
const channelName = testChannel;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{{> navBar}}
|
<div class="row row--tall flex-container--column flex-container--center-center">
|
||||||
<div class="row row--padded">
|
|
||||||
<h3>404: Not Found</h3>
|
<h3>404: Not Found</h3>
|
||||||
<p>That page does not exist. Return <a class="link--primary" href="/">home</a>.</p>
|
<p>That page does not exist. Return <a class="link--primary" href="/">home</a>.</p>
|
||||||
</div>
|
</div>
|
|
@ -1,21 +0,0 @@
|
||||||
{{> navBar}}
|
|
||||||
<div class="row row--padded">
|
|
||||||
<div class="column column--5 column--med-10 align-content-top">
|
|
||||||
<div class="column column--8 column--med-10">
|
|
||||||
<p class="pull-quote">Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.</p>
|
|
||||||
<p><a class="link--primary" target="_blank" href="https://twitter.com/spee_ch">TWITTER</a></p>
|
|
||||||
<p><a class="link--primary" target="_blank" href="https://github.com/lbryio/spee.ch">GITHUB</a></p>
|
|
||||||
<p><a class="link--primary" target="_blank" href="https://discord.gg/YjYbwhS">DISCORD CHANNEL</a></p>
|
|
||||||
<p><a class="link--primary" target="_blank" href="https://github.com/lbryio/spee.ch/blob/master/README.md">DOCUMENTATION</a></p>
|
|
||||||
</div>
|
|
||||||
</div><div class="column column--5 column--med-10 align-content-top">
|
|
||||||
<div class="column column--8 column--med-10">
|
|
||||||
<p>Spee.ch is a media-hosting site that reads from and publishes content to the <a class="link--primary" 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>If you have an idea for your own spee.ch-like site on top of LBRY, fork our <a class="link--primary" 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 class="link--primary" href="https://discord.gg/YjYbwhS">discord channel</a> or solve one of our <a class="link--primary" href="https://github.com/lbryio/spee.ch/issues">github issues</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
|
@ -1,55 +0,0 @@
|
||||||
{{> navBar}}
|
|
||||||
<div class="row row--padded">
|
|
||||||
<div class="row">
|
|
||||||
{{#ifConditional this.totalPages '===' 0}}
|
|
||||||
<p>There is no content in {{this.channelName}}:{{this.longChannelClaimId}} yet. Upload some!</p>
|
|
||||||
{{/ifConditional}}
|
|
||||||
{{#ifConditional this.totalPages '>=' 1}}
|
|
||||||
<p>Below are the contents for {{this.channelName}}:{{this.longChannelClaimId}}</p>
|
|
||||||
<div class="grid">
|
|
||||||
{{#each this.claims}}
|
|
||||||
{{> gridItem}}
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
{{/ifConditional}}
|
|
||||||
{{#ifConditional this.totalPages '>' 1}}
|
|
||||||
<div class="row">
|
|
||||||
<div class="column column--3 align-content--left">
|
|
||||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p=1">First [1]</a>
|
|
||||||
</div><div class="column column--4 align-content-center">
|
|
||||||
{{#if this.previousPage}}
|
|
||||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p={{this.previousPage}}">Previous</a>
|
|
||||||
{{else}}
|
|
||||||
<a disabled>Previous</a>
|
|
||||||
{{/if}}
|
|
||||||
|
|
|
||||||
{{#if this.nextPage}}
|
|
||||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p={{this.nextPage}}">Next</a>
|
|
||||||
{{else}}
|
|
||||||
<a disabled>Next</a>
|
|
||||||
{{/if}}
|
|
||||||
</div><div class="column column--3 align-content-right">
|
|
||||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p={{this.totalPages}}">Last [{{this.totalPages}}]</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/ifConditional}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="/assets/vendors/masonry/masonry.pkgd.min.js"></script>
|
|
||||||
<script src="/assets/vendors/imagesloaded/imagesloaded.pkgd.min.js"></script>
|
|
||||||
<script>
|
|
||||||
// init masonry with element
|
|
||||||
var grid = document.querySelector('.grid');
|
|
||||||
var msnry;
|
|
||||||
|
|
||||||
imagesLoaded( grid, function() {
|
|
||||||
msnry = new Masonry( grid, {
|
|
||||||
itemSelector: '.grid-item',
|
|
||||||
columnWidth: 3,
|
|
||||||
percentPosition: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
|
@ -1,6 +1,5 @@
|
||||||
<div id="react-nav-bar"></div>
|
|
||||||
<div class="row row--tall flex-container--column">
|
<div class="row row--tall flex-container--column">
|
||||||
<div id="react-publish-tool" class="row row--padded row--tall flex-container--column">
|
<div id="react-app" class="row row--tall flex-container--column">
|
||||||
<div class="row row--padded row--tall flex-container--column flex-container--center-center">
|
<div class="row row--padded row--tall flex-container--column flex-container--center-center">
|
||||||
<p>loading...</p>
|
<p>loading...</p>
|
||||||
{{> progressBar}}
|
{{> progressBar}}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
|
||||||
<head>
|
|
||||||
{{ placeCommonHeaderTags }}
|
|
||||||
<meta name="twitter:card" content="summary" />
|
|
||||||
<meta name="twitter:site" content="@spee_ch" />
|
|
||||||
<meta property="og:title" content="{{this.channelName}} on Spee.ch" />
|
|
||||||
<meta property="og:site_name" content="Spee.ch" />
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
<meta property="og:image" content="https://spee.ch/assets/img/Speech_Logo_Main@OG-02.jpg" />
|
|
||||||
<meta property="og:url" content="http://spee.ch/{{this.channelName}}:{{this.longChannelId}}" />
|
|
||||||
<meta property="og:description" content="View images and videos from {{this.channelName}}" />
|
|
||||||
<!--google font-->
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">
|
|
||||||
<!-- google analytics -->
|
|
||||||
{{ googleAnalytics }}
|
|
||||||
</head>
|
|
||||||
<body id="channel-body">
|
|
||||||
<script src="/assets/js/generalFunctions.js"></script>
|
|
||||||
{{{ body }}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -16,8 +16,6 @@
|
||||||
{{ googleAnalytics }}
|
{{ googleAnalytics }}
|
||||||
</head>
|
</head>
|
||||||
<body id="main-body">
|
<body id="main-body">
|
||||||
<script src="/assets/js/generalFunctions.js"></script>
|
|
||||||
<script src="/assets/js/validationFunctions.js"></script>
|
|
||||||
{{{ body }}}
|
{{{ body }}}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
|
|
||||||
<head>
|
|
||||||
{{ placeCommonHeaderTags }}
|
|
||||||
<meta property="fb:app_id" content="1371961932852223">
|
|
||||||
{{#unless claimInfo.nsfw}}
|
|
||||||
{{{addTwitterCard claimInfo }}}
|
|
||||||
{{{addOpenGraph claimInfo }}}
|
|
||||||
{{/unless}}
|
|
||||||
<!--google font-->
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">
|
|
||||||
<!-- google analytics -->
|
|
||||||
{{ googleAnalytics }}
|
|
||||||
</head>
|
|
||||||
<body id="show-body">
|
|
||||||
<script src="/assets/js/generalFunctions.js"></script>
|
|
||||||
<script src="/assets/js/assetConstructor.js"></script>
|
|
||||||
{{{ body }}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
{{> navBar}}
|
|
||||||
<div class="row row--padded">
|
|
||||||
<div class="column column--5 column--med-10 align-content-top">
|
|
||||||
<div class="column column--8 column--med-10">
|
|
||||||
<p>Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends. You can create 1 channel, or 100, so whether you're <a class="link--primary" target="_blank" href="/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8">documenting important events</a>, or making a public repository for <a class="link--primary" target="_blank" href="/@catGifs">cat gifs</a> (password: '1234'), try creating a channel for it!</p>
|
|
||||||
</div>
|
|
||||||
</div><div class="column column--5 column--med-10 align-content-top">
|
|
||||||
<div class="column column--8 column--med-10">
|
|
||||||
<h3 class="h3--no-bottom">Log in to an existing channel:</h3>
|
|
||||||
{{>channelLoginForm}}
|
|
||||||
<h3 class="h3--no-bottom">Create a brand new channel:</h3>
|
|
||||||
{{>channelCreationForm}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
{{> navBar}}
|
|
||||||
<div class="row row--padded">
|
|
||||||
<h3>No Channel</h3>
|
|
||||||
<p>There are no published channels matching your url</p>
|
|
||||||
<p>If you think this message is an error, contact us in the <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY Discord!</a></p>
|
|
||||||
</div>
|
|
|
@ -1,6 +0,0 @@
|
||||||
{{> navBar}}
|
|
||||||
<div class="row row--padded">
|
|
||||||
<h3>No Claims</h3>
|
|
||||||
<p>There are no free assets at that claim. You should publish one at <a class="link--primary" 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>
|
|
|
@ -1,36 +0,0 @@
|
||||||
<div id="asset-display-component">
|
|
||||||
<div id="asset-status">
|
|
||||||
<div id="searching-message" hidden="true">
|
|
||||||
<p>Sit tight, we're searching the LBRY blockchain for your asset!</p>
|
|
||||||
{{> progressBar}}
|
|
||||||
<p>Curious what magic is happening here? <a class="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>
|
|
||||||
</div>
|
|
||||||
<div id="failure-message" hidden="true">
|
|
||||||
<p>Unfortunately, we couldn't download your asset from LBRY. You can help us out by sharing the below error message in the <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY discord</a>.</p>
|
|
||||||
<i><p id="error-message"></p></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="asset-holder" hidden="true">
|
|
||||||
{{#ifConditional claimInfo.contentType '===' 'video/mp4'}}
|
|
||||||
{{> video}}
|
|
||||||
{{else}}
|
|
||||||
{{> image}}
|
|
||||||
{{/ifConditional}}
|
|
||||||
<div>
|
|
||||||
<a id="asset-boilerpate" class="link--primary fine-print" href="/{{claimInfo.claimId}}/{{claimInfo.name}}">hosted via Spee<h</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
const asset = new Asset();
|
|
||||||
asset.data['src'] = '/{{claimInfo.claimId}}/{{claimInfo.name}}.{{claimInfo.fileExt}}';
|
|
||||||
asset.data['claimName'] = '{{claimInfo.name}}';
|
|
||||||
asset.data['claimId'] = '{{claimInfo.claimId}}';
|
|
||||||
asset.data['fileExt'] = '{{claimInfo.fileExt}}';
|
|
||||||
asset.data['contentType'] = '{{claimInfo.contentType}}';
|
|
||||||
console.log('asset data:', asset.data);
|
|
||||||
asset.checkFileAndRenderAsset();
|
|
||||||
|
|
||||||
</script>
|
|
|
@ -1,134 +0,0 @@
|
||||||
{{#if claimInfo.channelName}}
|
|
||||||
<div class="row row--padded row--wide row--no-top">
|
|
||||||
<div class="column column--2 column--med-10">
|
|
||||||
<span class="text">Channel:</span>
|
|
||||||
</div><div class="column column--8 column--med-10">
|
|
||||||
<span class="text"><a href="/{{claimInfo.channelName}}:{{claimInfo.certificateId}}">{{claimInfo.channelName}}</a></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if claimInfo.description}}
|
|
||||||
<div class="row row--padded row--wide row--no-top">
|
|
||||||
<span class="text">{{claimInfo.description}}</span>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<div class="row row--padded row--wide row--no-top">
|
|
||||||
<div id="show-short-link">
|
|
||||||
<div class="column column--2 column--med-10">
|
|
||||||
<a class="link--primary" href="/{{shortId}}/{{claimInfo.name}}.{{claimInfo.fileExt}}"><span class="text">Link:</span></a>
|
|
||||||
</div><div class="column column--8 column--med-10">
|
|
||||||
<div class="row row--short row--wide">
|
|
||||||
<div class="column column--7">
|
|
||||||
<div class="input-error" id="input-error-copy-short-link" hidden="true"></div>
|
|
||||||
<input type="text" id="short-link" class="input-disabled input-text--full-width" readonly spellcheck="false" value="{{claimInfo.host}}/{{shortId}}/{{claimInfo.name}}.{{claimInfo.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>
|
|
||||||
</div>
|
|
||||||
<div id="show-embed-code">
|
|
||||||
<div class="column column--2 column--med-10">
|
|
||||||
<span class="text">Embed:</span>
|
|
||||||
</div><div class="column column--8 column--med-10">
|
|
||||||
<div class="row row--short row--wide">
|
|
||||||
<div class="column column--7">
|
|
||||||
<div class="input-error" id="input-error-copy-embed-text" hidden="true"></div>
|
|
||||||
{{#ifConditional claimInfo.contentType '===' '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 poster="{{claimInfo.thumbnail}}" src="{{claimInfo.host}}/{{claimInfo.claimId}}/{{claimInfo.name}}.{{claimInfo.fileExt}}"/></video>'/>
|
|
||||||
{{else}}
|
|
||||||
<input type="text" id="embed-text" class="input-disabled input-text--full-width" readonly onclick="select()" spellcheck="false" value='<img src="{{claimInfo.host}}/{{claimInfo.claimId}}/{{claimInfo.name}}.{{claimInfo.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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="show-share-buttons">
|
|
||||||
<div class="row row--padded row--wide row--no-top">
|
|
||||||
<div class="column column--2 column--med-10">
|
|
||||||
<span class="text">Share:</span>
|
|
||||||
</div><div class="column column--7 column--med-10">
|
|
||||||
<div class="row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap">
|
|
||||||
<a class="link--primary" target="_blank" href="https://twitter.com/intent/tweet?text={{claimInfo.host}}/{{shortId}}/{{claimInfo.name}}">twitter</a>
|
|
||||||
<a class="link--primary" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u={{claimInfo.host}}/{{shortId}}/{{claimInfo.name}}">facebook</a>
|
|
||||||
<a class="link--primary" target="_blank" href="http://tumblr.com/widgets/share/tool?canonicalUrl={{claimInfo.host}}/{{shortId}}/{{claimInfo.name}}">tumblr</a>
|
|
||||||
<a class="link--primary" target="_blank" href="https://www.reddit.com/submit?url={{claimInfo.host}}/{{shortId}}/{{claimInfo.name}}&title={{claimInfo.name}}">reddit</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div id="show-details" class="row--padded row--wide row--no-top" hidden="true">
|
|
||||||
<div id="show-claim-name">
|
|
||||||
<div class="column column--2 column--med-10">
|
|
||||||
<span class="text">Claim Name:</span>
|
|
||||||
</div><div class="column column--8 column--med-10">
|
|
||||||
{{claimInfo.name}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="show-claim-id">
|
|
||||||
<div class="column column--2 column--med-10">
|
|
||||||
<span class="text">Claim Id:</span>
|
|
||||||
</div><div class="column column--8 column--med-10">
|
|
||||||
{{claimInfo.claimId}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="show-claim-id">
|
|
||||||
<div class="column column--2 column--med-10">
|
|
||||||
<span class="text">File Type:</span>
|
|
||||||
</div><div class="column column--8 column--med-10">
|
|
||||||
{{#if claimInfo.contentType}}
|
|
||||||
{{claimInfo.contentType}}
|
|
||||||
{{else}}
|
|
||||||
unknown
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="show-claim-id">
|
|
||||||
<div class="column column--10">
|
|
||||||
<a target="_blank" href="https://lbry.io/dmca">Report</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row row--wide">
|
|
||||||
<a class="text link--primary" id="show-details-toggle" href="#" onclick="toggleSection(event)" data-status="closed">[more]</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function toggleSection(event){
|
|
||||||
event.preventDefault();
|
|
||||||
var dataSet = event.target.dataset;
|
|
||||||
var status = dataSet.status;
|
|
||||||
var toggle = document.getElementById("show-details-toggle");
|
|
||||||
var details = document.getElementById("show-details");
|
|
||||||
if (status === "closed") {
|
|
||||||
details.hidden = false;
|
|
||||||
toggle.innerText = "[less]";
|
|
||||||
toggle.dataset.status = "open";
|
|
||||||
} else {
|
|
||||||
details.hidden = true;
|
|
||||||
toggle.innerText = "[more]";
|
|
||||||
toggle.dataset.status = "closed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
validationFunctions.showError(errorElement, 'Oops, unable to copy');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,39 +0,0 @@
|
||||||
<form id="publish-channel-form">
|
|
||||||
<p id="input-error-channel-name" class="info-message-placeholder info-message--failure"></p>
|
|
||||||
<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 class="input-text--primary flex-container--row flex-container--left-bottom">
|
|
||||||
<span>@</span>
|
|
||||||
<input type="text" name="new-channel-name" id="new-channel-name" class="input-text" placeholder="exampleChannelName" value="" oninput="validationFunctions.checkChannelName(event.target.value)">
|
|
||||||
<span id="input-success-channel-name" class="info-message--success"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<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 class="input-text--primary">
|
|
||||||
<input type="password" name="new-channel-password" id="new-channel-password" class="input-text" placeholder="" value="" >
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row row--wide">
|
|
||||||
<button class="button--primary" onclick="publishNewChannel(event)">Create Channel</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="channel-publish-in-progress" hidden="true">
|
|
||||||
<p>Creating your new channel. This may take a few seconds...</p>
|
|
||||||
{{> progressBar}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="channel-publish-done" hidden="true">
|
|
||||||
<p>Your channel has been successfully created!</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="/assets/js/createChannelFunctions.js"></script>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<form id="channel-login-form">
|
|
||||||
<p id="login-error-display-element" class="info-message-placeholder info-message--failure"></p>
|
|
||||||
<div class="row row--wide row--short">
|
|
||||||
<div class="column column--3 column--sml-10">
|
|
||||||
<label class="label" for="channel-login-name-input">Name:</label>
|
|
||||||
</div><div class="column column--6 column--sml-10">
|
|
||||||
<div class="input-text--primary flex-container--row flex-container--left-bottom">
|
|
||||||
<span>@</span>
|
|
||||||
<input type="text" id="channel-login-name-input" class="input-text" placeholder="" value="">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row--wide row--short">
|
|
||||||
<div class="column column--3 column--sml-10">
|
|
||||||
<label class="label" for="channel-login-password-input" >Password:</label>
|
|
||||||
</div><div class="column column--6 column--sml-10">
|
|
||||||
<div class="input-text--primary">
|
|
||||||
<input type="password" id="channel-login-password-input" class="input-text" placeholder="" value="">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row row--wide">
|
|
||||||
<button class="button--primary" onclick="loginToChannel(event)">Authenticate</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script src="/assets/js/loginFunctions.js"></script>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<div class='row row--wide'>
|
|
||||||
<div class="column column--3 align-content-top">
|
|
||||||
<a href="{{this.showUrlLong}}">
|
|
||||||
{{#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}}
|
|
||||||
</a>
|
|
||||||
</div><div class="column column--7 align-content-top">
|
|
||||||
<p>{{this.title}}</p>
|
|
||||||
<a class="link--primary" href="{{this.showUrlShort}}">spee.ch{{this.showUrlShort}}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
Why changing to 200?