Archived
Merge branch 'master' of https://bitbucket.org/sco44/tecnologiabanana
This commit is contained in:
@@ -26,4 +26,3 @@ yarn-error.log*
|
||||
.idea/
|
||||
.vs/
|
||||
db.json
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig
|
||||
'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig'
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"videos": [
|
||||
{
|
||||
"id": "cu3K1njbYqs",
|
||||
"timesWatched": 1,
|
||||
"lastWatched": "2018-12-02T20:43:18.202Z"
|
||||
},
|
||||
{
|
||||
"id": "PoSbnAFvqfA",
|
||||
"timesWatched": 1,
|
||||
"lastWatched": "2018-12-02T20:43:24.851Z"
|
||||
},
|
||||
{
|
||||
"id": "rzeLynj1GYM",
|
||||
"timesWatched": 2,
|
||||
"lastWatched": "2018-12-02T20:43:45.916Z"
|
||||
},
|
||||
{
|
||||
"id": "0J2QdDbelmY",
|
||||
"timesWatched": 2,
|
||||
"lastWatched": "2019-01-09T15:11:09.976Z"
|
||||
},
|
||||
{
|
||||
"id": "unRjK82bDLw",
|
||||
"timesWatched": 2,
|
||||
"lastWatched": "2018-12-02T20:49:50.769Z"
|
||||
},
|
||||
{
|
||||
"id": "g2N0TkfrQhY",
|
||||
"timesWatched": 1,
|
||||
"lastWatched": "2018-12-02T20:52:07.780Z"
|
||||
},
|
||||
{
|
||||
"id": "EM4vblG6BVQ",
|
||||
"timesWatched": 1,
|
||||
"lastWatched": "2018-12-02T20:52:43.282Z"
|
||||
},
|
||||
{
|
||||
"id": "tPwqOWK6EFw",
|
||||
"timesWatched": 1,
|
||||
"lastWatched": "2018-12-02T20:53:26.049Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
process.env['NODE_ENV'] = 'production';
|
||||
const express = require('express');
|
||||
const compression = require('compression')
|
||||
const bodyParser = require('body-parser');
|
||||
const low = require('lowdb');
|
||||
const lodashId = require('lodash-id');
|
||||
const FileAsync = require('lowdb/adapters/FileAsync');
|
||||
const app = express(); // app is an instance of express
|
||||
|
||||
app.use(compression()); // enables gzip compression
|
||||
app.use(bodyParser.urlencoded({ extended: false })) // parse application/x-www-form-urlencoded
|
||||
app.use(bodyParser.json()) // parse application/json
|
||||
|
||||
|
||||
// Create database instance and start server
|
||||
// const adapter = new FileAsync(__dirname + '/db.json');
|
||||
low(new FileAsync(__dirname + '/db.json')) // production
|
||||
.then(db => {
|
||||
db._.mixin(lodashId);
|
||||
// DATABASE ROUTES
|
||||
|
||||
// ==============
|
||||
|
||||
app.post('/test', (req, res) => {
|
||||
// "reason": {
|
||||
// "fitali": req.body.reason.toString() === "fvitali" ? 1:0,
|
||||
// "": req.body.reason.toString() === "" ? 1:0,
|
||||
// "": req.body.reason.toString() === "" ? 1:0,
|
||||
// }
|
||||
// try {
|
||||
// let test = table.updateById(req.body.id, { })
|
||||
// }
|
||||
// catch(e) {
|
||||
// }
|
||||
res.send(req.body);
|
||||
});
|
||||
|
||||
// ==============
|
||||
|
||||
// GET /globpop
|
||||
app.get('/globpop', (req, res) => {
|
||||
req.query.id ? res.send(req.query.id) : res.status(400).send('Bad Request');
|
||||
});
|
||||
|
||||
// OPTIONS /videotrack
|
||||
app.options('/videotrack', (req, res) => {
|
||||
res.set({
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
'Access-Control-Max-Age': 600
|
||||
})
|
||||
res.status(200).end();
|
||||
})
|
||||
|
||||
// GET /videotrack
|
||||
app.get('/videotrack', (req, res) => {
|
||||
const videos = db.get('videos');
|
||||
req.query.id ? res.send(videos.getById(req.query.id).value()) : res.send(videos.value())
|
||||
});
|
||||
|
||||
// POST /videotrack
|
||||
app.post('/videotrack', (req, res) => {
|
||||
const videos = db.get('videos');
|
||||
const row = videos.getById(req.body.id);
|
||||
if (row.value()) {
|
||||
row
|
||||
.update('timesWatched', (n) => ++n)
|
||||
.update('lastWatched', () => new Date().toISOString())
|
||||
.write()
|
||||
.then(output => res.send(output))
|
||||
} else {
|
||||
let newRow = {
|
||||
"id": req.body.id.toString(),
|
||||
"timesWatched": 1,
|
||||
"lastWatched": new Date().toISOString(),
|
||||
}
|
||||
videos.push(newRow).last().write().then(output => res.send(output))
|
||||
}
|
||||
});
|
||||
|
||||
// Set db default values
|
||||
return db.defaults({ videos: [] }).write();
|
||||
})
|
||||
.then(() => {
|
||||
app.listen(8000, () => console.log('listen on 8000')); // bind to port 8000 as required from specs
|
||||
});
|
||||
+32
-21
@@ -1,5 +1,5 @@
|
||||
process.env['NODE_ENV'] = 'production';
|
||||
process.env.APIKEY = 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig';
|
||||
//'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' = 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig';
|
||||
const express = require('express');
|
||||
const compression = require('compression')
|
||||
const bodyParser = require('body-parser');
|
||||
@@ -14,7 +14,7 @@ app.use(bodyParser.json()) // parse application/json
|
||||
|
||||
|
||||
app.get('/a', (req, res) => {
|
||||
res.send(process.env);
|
||||
res.send(process.env);
|
||||
|
||||
});
|
||||
|
||||
@@ -26,14 +26,14 @@ low(new FileAsync(__dirname + '/db.json')) // production
|
||||
db._.mixin(lodashId);
|
||||
// DATABASE ROUTES
|
||||
|
||||
// ==============
|
||||
// ==============
|
||||
|
||||
app.post('/test',(req,res)=>{
|
||||
// "reason": {
|
||||
// "fitali": req.body.reason.toString() === "fvitali" ? 1:0,
|
||||
// "": req.body.reason.toString() === "" ? 1:0,
|
||||
// "": req.body.reason.toString() === "" ? 1:0,
|
||||
// }
|
||||
app.post('/test', (req, res) => {
|
||||
// "reason": {
|
||||
// "fitali": req.body.reason.toString() === "fvitali" ? 1:0,
|
||||
// "": req.body.reason.toString() === "" ? 1:0,
|
||||
// "": req.body.reason.toString() === "" ? 1:0,
|
||||
// }
|
||||
// try {
|
||||
// let test = table.updateById(req.body.id, { })
|
||||
// }
|
||||
@@ -42,29 +42,40 @@ low(new FileAsync(__dirname + '/db.json')) // production
|
||||
res.send(req.body);
|
||||
});
|
||||
|
||||
// ==============
|
||||
// ==============
|
||||
|
||||
// GET /videotrack/:id?
|
||||
// GET /globpop
|
||||
app.get('/globpop', (req, res) => {
|
||||
req.query.id ? res.send(req.query.id):res.status(400).send('Bad Request');
|
||||
req.query.id ? res.send(req.query.id) : res.status(400).send('Bad Request');
|
||||
});
|
||||
|
||||
// GET /videotrack/:id?
|
||||
app.get('/videotrack/:id?', (req, res) => {
|
||||
// OPTIONS /videotrack
|
||||
app.options('/videotrack', (req, res) => {
|
||||
res.set({
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
'Access-Control-Max-Age': 600
|
||||
})
|
||||
res.status(200).end();
|
||||
})
|
||||
|
||||
// GET /videotrack
|
||||
app.get('/videotrack', (req, res) => {
|
||||
const videos = db.get('videos');
|
||||
req.params.id ? res.send(videos.getById(req.params.id).value()) : res.send(videos.value())
|
||||
req.query.id ? res.send(videos.getById(req.query.id).value()) : res.send(videos.value())
|
||||
});
|
||||
|
||||
// POST /videotrack
|
||||
app.post('/videotrack', (req, res) => {
|
||||
const videos = db.get('videos');
|
||||
const videos = db.get('videos');
|
||||
const row = videos.getById(req.body.id);
|
||||
if(row.value()) {
|
||||
if (row.value()) {
|
||||
row
|
||||
.update('timesWatched',(n) => ++n)
|
||||
.update('lastWatched',() => new Date().toISOString())
|
||||
.write()
|
||||
.then(output => res.send(output))
|
||||
.update('timesWatched', (n) => ++n)
|
||||
.update('lastWatched', () => new Date().toISOString())
|
||||
.write()
|
||||
.then(output => res.send(output))
|
||||
} else {
|
||||
let newRow = {
|
||||
"id": req.body.id.toString(),
|
||||
|
||||
Generated
+21
-7
@@ -5879,11 +5879,13 @@
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -5896,15 +5898,18 @@
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -6007,7 +6012,8 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -6017,6 +6023,7 @@
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -6029,17 +6036,20 @@
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -6056,6 +6066,7 @@
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -6128,7 +6139,8 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -6138,6 +6150,7 @@
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -6243,6 +6256,7 @@
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hazetv-alfatube-1",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@c0b41/ytclear": "^1.0.0",
|
||||
|
||||
+30
-29
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Route, Switch, withRouter, matchPath } from 'react-router-dom';
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import { Row, Col, Button, Collapse } from 'react-bootstrap';
|
||||
import TopBar from './TopBar';
|
||||
import VideoPlayer from './VideoPlayer';
|
||||
@@ -20,52 +19,53 @@ class App extends React.Component {
|
||||
videoId: localStorage['lastId']
|
||||
};
|
||||
|
||||
// componentDidMount(){
|
||||
// componentDidMount() {
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
// componentDidUpdate(prevProps, prevState) {
|
||||
// componentDidUpdate(prevProps, prevState) {
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
let idMatch = matchPath(nextProps.location.pathname, {
|
||||
path: "/video/:id",
|
||||
exact: true,
|
||||
strict: false
|
||||
});
|
||||
if(idMatch && idMatch.params.id !== prevState.videoId){
|
||||
localStorage.setItem('lastId', idMatch.params.id)
|
||||
return {videoId: idMatch.params.id };
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
let idMatch = matchPath(nextProps.location.pathname, {
|
||||
path: "/video/:id",
|
||||
exact: true,
|
||||
strict: false
|
||||
});
|
||||
if (idMatch && idMatch.params.id !== prevState.videoId) {
|
||||
localStorage.setItem('lastId', idMatch.params.id)
|
||||
return { videoId: idMatch.params.id };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ReactHeight className="row" onHeightReady={height => { this.setState({ navHeight: height }); }}>
|
||||
<Row id="top">
|
||||
<TopBar />
|
||||
</ReactHeight>
|
||||
<ReactHeight onHeightReady={height => this.setState({ blackbgHeight: height })} className="row upperSection p-2 px-5" >
|
||||
</Row>
|
||||
<Row className="upperSection">
|
||||
<Col
|
||||
xs="12"
|
||||
lg={this.state.isInfoToggled ? { span: 6, offset: 0, order: 2 } : { span: 7, offset: 1, order: 2 }}
|
||||
className="align-content-center pt-2 p-1 pr-2">
|
||||
<ReactHeight onHeightReady={height => this.setState({ playerHeight: height })}>
|
||||
<VideoPlayer videoId={this.state.videoId}/>
|
||||
<ReactHeight onHeightReady={height => { this.setState({ playerHeight: height }) }}>
|
||||
<VideoPlayer videoId={this.state.videoId} />
|
||||
</ReactHeight>
|
||||
</Col>
|
||||
<Col
|
||||
xs="12"
|
||||
lg={this.state.isInfoToggled ? { span: 5, order: 1 } : { span: 3, order: 1 }}
|
||||
className="p-0 p-sm-0"
|
||||
style={{ 'overflow': "auto", 'max-height': this.state.playerHeight }} >
|
||||
<div class="d-flex justify-content-center">
|
||||
className="p-0 p-xs-0"
|
||||
style={window.innerWidth < 992 ? { 'overflow': "auto", 'display': 'fixed', 'maxHeight': this.state.playerHeight * 1.4 + 'px' } : { 'overflow': "auto", 'maxHeight': `${this.state.playerHeight}px` }}>
|
||||
{/* true = style for xs ;; false = style for lg */}
|
||||
<div className="d-flex justify-content-center">
|
||||
<Button
|
||||
variant="outline-light"
|
||||
onClick={() => this.setState({ isInfoToggled: !this.state.isInfoToggled })}
|
||||
onClick={() => this.setState({ isInfoToggled: !this.state.isInfoToggled, dirtyBg: true })}
|
||||
className="pt-1 "
|
||||
aria-controls="infovideo-collapse"
|
||||
aria-expanded={this.state.isInfoToggled}>
|
||||
@@ -74,15 +74,16 @@ static getDerivedStateFromProps(nextProps, prevState) {
|
||||
</div>
|
||||
<Collapse in={this.state.isInfoToggled}>
|
||||
<div className="pt-1" id="infovideo-collapse">
|
||||
<VideoInfo videoId={this.state.videoId} />
|
||||
<Route render={(props) => <VideoInfo {...props} key={this.state.videoId} videoId={this.state.videoId} />} />
|
||||
</div>
|
||||
</Collapse>
|
||||
</Col>
|
||||
</ReactHeight>
|
||||
<Row style={{ "max-height": `calc(98vh - ${this.state.blackbgHeight}px - ${this.state.navHeight}px)` }} className='mt-1 downSection'>
|
||||
</Row>
|
||||
<Row style={{ "maxHeight": `calc(98vh - ${this.state.playerHeight}px - 46px)` }} className='mt-1 downSection'>
|
||||
<Switch>
|
||||
<Route exact path='/' component={VideoList} />
|
||||
<Route path={["/video/:id", "/search/:query"]} component={Suggestion} />
|
||||
<Route path={"/video/:id"} component={Suggestion} />
|
||||
<Route path={"/search/:query"} component={Suggestion} />
|
||||
<Route render={() => <div>URL not found</div>} />
|
||||
</Switch>
|
||||
</Row>
|
||||
|
||||
+24
-95
@@ -1,15 +1,12 @@
|
||||
import React from 'react';
|
||||
import Wikipedia from './areainfo/Wikipedia';
|
||||
import { Tabs, Tab } from 'react-bootstrap';
|
||||
import {Link, withRouter} from 'react-router-dom';
|
||||
import { Card, Tabs, Tab } from 'react-bootstrap';
|
||||
import {Link} from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import Linkify from "react-linkify";
|
||||
import Card from "react-bootstrap/lib/Card";
|
||||
import moment from 'moment';
|
||||
import momentDurationFormat from 'moment-duration-format'; //eslint-disable-line no-unused-vars
|
||||
import './css/VideoInfo.scss';
|
||||
|
||||
|
||||
const ytclear = require('@c0b41/ytclear');
|
||||
|
||||
class VideoInfo extends React.Component {
|
||||
@@ -31,88 +28,26 @@ class VideoInfo extends React.Component {
|
||||
return moment(a, moment.ISO_8601).format('ddd, DD/MM/YYYY hh:mm:ss');
|
||||
}
|
||||
|
||||
isArtistOrTitle(a){
|
||||
// switch(parseInt(b)){
|
||||
// case 1:
|
||||
|
||||
// break;
|
||||
// case 2:
|
||||
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
axios.all([
|
||||
axios.get("https://musicbrainz.org/ws/2/work", {
|
||||
params: {
|
||||
query: `work:${a[0]} AND artist:${a[1]}`,
|
||||
//artist: a[1],
|
||||
fmt: "json",
|
||||
limit: 1,
|
||||
inc: "aliases"
|
||||
}}),
|
||||
axios.get("https://musicbrainz.org/ws/2/work", {
|
||||
params: {
|
||||
query: `work:${a[1]} AND artist:${a[0]}`,
|
||||
// artist: a[0],
|
||||
fmt: "json",
|
||||
limit: 1,
|
||||
inc: "aliases"
|
||||
}})
|
||||
])
|
||||
.then(axios.spread((response1, response2) => {
|
||||
console.log(response1.data, response2.data);
|
||||
axios.all([
|
||||
axios.get(`https://musicbrainz.org/ws/2/work/${response1.data.works[0].id}`,{
|
||||
params:{
|
||||
fmt:'json',
|
||||
limit:1,
|
||||
inc: 'aliases'
|
||||
}
|
||||
}),
|
||||
axios.get(`https://musicbrainz.org/ws/2/work/${response2.data.works[0].id}`,{
|
||||
params:{
|
||||
fmt:'json',
|
||||
limit:1,
|
||||
inc: 'recording-rels'
|
||||
}
|
||||
}),
|
||||
]).then(axios.spread((responseA1,responseA2)=>{
|
||||
console.log(responseA1.data, responseA2.data);
|
||||
|
||||
}))
|
||||
}),
|
||||
error => { }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
getInfoComments() {
|
||||
return axios.all([
|
||||
axios.get('https://www.googleapis.com/youtube/v3/videos', { //Richiesta per tutte le info sul video
|
||||
params: {
|
||||
'part': 'snippet,contentDetails,statistics,topicDetails',
|
||||
'id': this.state.videoId,
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production
|
||||
'id': this.props.videoId,
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production
|
||||
}
|
||||
}), axios.get('https://www.googleapis.com/youtube/v3/commentThreads', { //Richiesta per ottenere i commenti del video
|
||||
params: {
|
||||
'part': 'snippet',
|
||||
'videoId': this.state.videoId,
|
||||
'videoId': this.props.videoId,
|
||||
'order': 'relevance',
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production
|
||||
}
|
||||
})])
|
||||
.then(axios.spread((videosResponse, commentThreadResponse) => {
|
||||
this.isArtistOrTitle(ytclear(videosResponse.data.items[0].snippet.title).split('-'));
|
||||
this.setState({
|
||||
VideoDetails: videosResponse.data.items[0],
|
||||
comments: commentThreadResponse.data.items,
|
||||
others: {
|
||||
artist: null,
|
||||
title: videosResponse.data.items[0].snippet.title
|
||||
},
|
||||
isLoaded: true
|
||||
});
|
||||
}), error => {
|
||||
@@ -124,19 +59,16 @@ class VideoInfo extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if(nextProps.videoId !== prevState.videoId)
|
||||
return { videoId: nextProps.videoId };
|
||||
return null;
|
||||
}
|
||||
// static getDerivedStateFromProps(nextProps, prevState) {
|
||||
|
||||
// }
|
||||
componentDidMount() {
|
||||
this.getInfoComments();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
if(prevState.videoId !== this.state.videoId)
|
||||
this.getInfoComments();
|
||||
}
|
||||
// componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
|
||||
// }
|
||||
|
||||
// shouldComponentUpdate(nextProps, nextState) {
|
||||
// }
|
||||
@@ -157,7 +89,7 @@ class VideoInfo extends React.Component {
|
||||
} else {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<span class="h5 text-white">{VideoDetails.snippet.title}</span>
|
||||
<span className="h5 text-white">{VideoDetails.snippet.title}</span>
|
||||
<Tabs defaultActiveKey="video" id="tabs">
|
||||
<Tab className="text-white" eventKey="video" title="Video">
|
||||
<p>
|
||||
@@ -166,11 +98,9 @@ class VideoInfo extends React.Component {
|
||||
<b>Channel name: </b>{VideoDetails.snippet.channelTitle}<br />
|
||||
<b>Description: </b><Linkify>{VideoDetails.snippet.description}</Linkify><br />
|
||||
<b>Tags: </b>{VideoDetails.snippet.tags ?
|
||||
VideoDetails.snippet.tags.map(tag => (<Link
|
||||
to={{
|
||||
pathname: '/search/' + tag,
|
||||
}}
|
||||
> {tag} </Link>)) : ""}
|
||||
VideoDetails.snippet.tags.map((tag,i) =>
|
||||
( <span><Link key={i} to={{pathname: '/search/' + tag}}>{tag}</Link>{" "}</span> ))
|
||||
: ""}
|
||||
</p>
|
||||
</Tab>
|
||||
<Tab className="text-white" eventKey="techinfo" title="Tecnical Informations">
|
||||
@@ -203,13 +133,16 @@ class VideoInfo extends React.Component {
|
||||
})}
|
||||
</Tab>
|
||||
<Tab className="text-white" eventKey="tweet" title="Tweet">
|
||||
/* Insert code here */
|
||||
{/* Insert code here */}
|
||||
</Tab>
|
||||
<Tab className="text-white" eventKey="wikipedia" title="Wikipedia">
|
||||
<Wikipedia
|
||||
title={this.state.others.title}
|
||||
artist={this.state.others.artist}
|
||||
videoId={this.state.videoId}
|
||||
title={'undefined' !== typeof this.props.location.state ? this.props.location.state.title: undefined}
|
||||
title2={ytclear(this.state.VideoDetails.snippet.title).split('-')[1]}
|
||||
artist={'undefined' !== typeof this.props.location.state ? this.props.location.state.artist: undefined}
|
||||
artist2={ytclear(this.state.VideoDetails.snippet.title).split('-')[0]}
|
||||
key={this.props.videoId}
|
||||
videoId={this.props.videoId}
|
||||
/>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -217,10 +150,6 @@ class VideoInfo extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
VideoInfo.propTypes = {
|
||||
|
||||
};
|
||||
|
||||
export default withRouter(VideoInfo);
|
||||
export default VideoInfo;
|
||||
|
||||
+33
-32
@@ -2,26 +2,28 @@ import React from 'react';
|
||||
import { Col, ListGroup, Card, CardDeck } from 'react-bootstrap'; // eslint-disable-line no-unused-vars
|
||||
import axios from 'axios'; // eslint-disable-line no-unused-vars
|
||||
import { Link } from 'react-router-dom'; // eslint-disable-line no-unused-vars
|
||||
import './css/VideoList.css';
|
||||
/*eslint no-console: ["error", { allow: ["warn", "error", "info"] }] */
|
||||
|
||||
class VideoList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
state = {
|
||||
error: null,
|
||||
isLoaded: false,
|
||||
items: [],
|
||||
headers: null
|
||||
};
|
||||
this.getThumbnails = this.getThumbnails.bind(this);
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
localStorage['fixedVideoList'] ?
|
||||
this.setState({
|
||||
items: this.shuffleArray(JSON.parse(localStorage.getItem('fixedVideoList'))),
|
||||
isLoaded: true
|
||||
}) :
|
||||
axios.get('http://site1825.tw.cs.unibo.it/video.json').then(
|
||||
response => {
|
||||
this.shuffleArray(response.data);
|
||||
this.getThumbnails(response.data);
|
||||
this.getThumbnails(response.data)
|
||||
.then(videoList => localStorage.setItem('fixedVideoList',JSON.stringify(videoList)));
|
||||
},
|
||||
// Note: it's important to handle errors here
|
||||
// instead of a catch() block so that we don't swallow
|
||||
@@ -33,21 +35,21 @@ class VideoList extends React.Component {
|
||||
error
|
||||
});
|
||||
}
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
// METODI
|
||||
getThumbnails(videoItems) {
|
||||
let idToLookFor = videoItems.map(item => item.videoID);
|
||||
let finalChunk = (videoItems.length % 50) + 100;
|
||||
axios
|
||||
return axios
|
||||
.all([
|
||||
// chain 3 parallel get
|
||||
axios.get('https://www.googleapis.com/youtube/v3/videos', {
|
||||
params: {
|
||||
part: 'snippet',
|
||||
id: idToLookFor.slice(0, 50).toString(),
|
||||
key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // process.env.APIKEY in production
|
||||
key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production
|
||||
fields: 'items(id,snippet/thumbnails/medium)'
|
||||
}
|
||||
}),
|
||||
@@ -56,7 +58,7 @@ class VideoList extends React.Component {
|
||||
params: {
|
||||
part: 'snippet',
|
||||
id: idToLookFor.slice(50, 100).toString(),
|
||||
key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // process.env.APIKEY in production
|
||||
key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production
|
||||
fields: 'items(id,snippet/thumbnails/medium)'
|
||||
}
|
||||
}),
|
||||
@@ -65,46 +67,45 @@ class VideoList extends React.Component {
|
||||
params: {
|
||||
part: 'snippet',
|
||||
id: idToLookFor.slice(100, finalChunk).toString(),
|
||||
key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // process.env.APIKEY in production
|
||||
key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig', // 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' in production
|
||||
fields: 'items(id,snippet/thumbnails/medium)'
|
||||
}
|
||||
})
|
||||
])
|
||||
.then(
|
||||
axios.spread((res1, res2, res3) => {
|
||||
let allres = [].concat(
|
||||
res1.data.items,
|
||||
res2.data.items,
|
||||
res3.data.items
|
||||
);
|
||||
allres.map(resCurrentValue => {
|
||||
[...res1.data.items,...res2.data.items,...res3.data.items]
|
||||
.map(resCurrentValue =>
|
||||
Object.defineProperty(
|
||||
videoItems.find(videoItem => {
|
||||
return videoItem.videoID === resCurrentValue.id;
|
||||
}),
|
||||
'thumbnail',
|
||||
{ value: resCurrentValue.snippet.thumbnails.medium.url }
|
||||
);
|
||||
});
|
||||
{ value: resCurrentValue.snippet.thumbnails.medium.url,
|
||||
enumerable: true }
|
||||
)
|
||||
);
|
||||
this.setState({
|
||||
isLoaded: true,
|
||||
items: videoItems
|
||||
});
|
||||
return new Promise((resolve, reject) => resolve(videoItems))
|
||||
})
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
shuffleArray(videoarray) {
|
||||
for (let i = videoarray.length - 1; i > 0; i--) {
|
||||
shuffleArray(videoArray) {
|
||||
for (let i = videoArray.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[videoarray[i], videoarray[j]] = [videoarray[j], videoarray[i]]; // eslint-disable-line no-param-reassign
|
||||
[videoArray[i], videoArray[j]] = [videoArray[j], videoArray[i]]; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
return videoArray
|
||||
// Durstenfeld shuffle.
|
||||
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
|
||||
}
|
||||
|
||||
render() {
|
||||
const { error, isLoaded, items, headers } = this.state;
|
||||
const { error, isLoaded, items } = this.state;
|
||||
if (error) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -126,12 +127,12 @@ class VideoList extends React.Component {
|
||||
<Col key={item.videoID} lg={{ span: 3 }} md="6">
|
||||
<Card className="my-1 carta">
|
||||
<Link to={{
|
||||
pathname: '/video/' + item.videoID,
|
||||
state: {
|
||||
artist: item.artist,
|
||||
title: item.title
|
||||
}
|
||||
}}
|
||||
pathname: '/video/' + item.videoID,
|
||||
state: {
|
||||
artist: item.artist,
|
||||
title: item.title
|
||||
}
|
||||
}}
|
||||
>
|
||||
{/* {item.artist} - {item.title} {item.videoID} {item.category} */}
|
||||
<Card.Img
|
||||
|
||||
+2
-2
@@ -86,12 +86,12 @@ class VideoPlayer extends React.Component {
|
||||
videoIdWatched => {
|
||||
// post request to local db
|
||||
axios
|
||||
.post('http://localhost:8000/videotrack', {
|
||||
.post('http://site1854.tw.cs.unibo.it/videotrack', {
|
||||
id: videoIdWatched.toString()
|
||||
})
|
||||
.then(
|
||||
response => console.info(response.data),
|
||||
error => console.info(error, videoIdWatched.toString())
|
||||
error => console.error(error, videoIdWatched.toString())
|
||||
);
|
||||
// local storage logic for recent reccomender//tmp è il video che devo inserire sulla lista
|
||||
let tmp = JSON.parse(localStorage.getItem('lastWatched'))
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Row, Col, Button, Collapse } from 'react-bootstrap';
|
||||
import { Row } from 'react-bootstrap';
|
||||
import { Switch, Route } from 'react-router';
|
||||
import Random from '../reccomenders/Random';
|
||||
import Related from '../reccomenders/Related';
|
||||
import Search from '../reccomenders/Search';
|
||||
import fvitali from '../reccomenders/fvitali';
|
||||
import popGlobaleAssoluta from '../reccomenders/popGlobaleAssoluta';
|
||||
import Recent from '../reccomenders/Recent';
|
||||
|
||||
// and so on..
|
||||
|
||||
@@ -40,6 +41,8 @@ class Suggestion extends Component {
|
||||
<Route path='/search/:query' component={Search} />
|
||||
<Route path='/video/:id/random' component={Random} />
|
||||
<Route path='/video/:id/popGlobalAssoluta' component={popGlobaleAssoluta} />
|
||||
<Route path='/video/:id/recent' component={Recent} />
|
||||
|
||||
{/* lasciare questo per ultimo */}
|
||||
<Route component={Related} />
|
||||
</Switch>
|
||||
|
||||
+51
-45
@@ -17,7 +17,9 @@ class Wikipedia extends Component {
|
||||
isWikiLoaded: false,
|
||||
isWDataLoaded: false,
|
||||
isMBLoaded: false,
|
||||
isLoaded: false
|
||||
isLoaded: false,
|
||||
wikidatakeys: null,
|
||||
wikipediakeys: null
|
||||
};
|
||||
|
||||
ISO_8601toYYYY(a) {
|
||||
@@ -50,21 +52,39 @@ class Wikipedia extends Component {
|
||||
wikipediakeys: Object.keys(wikipediaRes[0].general),
|
||||
isWikiLoaded: true
|
||||
}))
|
||||
else{ console.info('called here')
|
||||
this.findWikiPage();}
|
||||
|
||||
}, error => console.error(error))
|
||||
// .then(() => {
|
||||
// console.log(this.state.wikidata)
|
||||
// .then(() => console.log(this.state.wikipedia));
|
||||
// });
|
||||
}
|
||||
|
||||
findWikiPage = () => {
|
||||
let wikiquery = `${'undefined' === typeof this.props.title ? this.props.title2.trim() : this.props.title.trim()} (${'undefined' === typeof this.props.artist ? this.props.artist2.trim() : this.props.artist.trim()} song)`;
|
||||
console.info(wikiquery)
|
||||
return wikijs()
|
||||
.find(wikiquery)
|
||||
.then(res => {
|
||||
console.info(res,'a');
|
||||
return Promise.all([res.fullInfo(), res.summary()]);
|
||||
}) // find by props.title (props.artist song)
|
||||
.then(wikipediaRes => this.setState({
|
||||
wikipedia: {
|
||||
"desc": wikipediaRes[1],
|
||||
"info": wikipediaRes[0].general
|
||||
},
|
||||
wikipediakeys: Object.keys(wikipediaRes[0].general),
|
||||
isWikiLoaded: true
|
||||
}))
|
||||
}
|
||||
|
||||
wrapper() {
|
||||
const musicbrainzBaseUrl = "https://musicbrainz.org/ws/2"; // more readable
|
||||
return axios.get(wdk.getReverseClaims('P1651', this.state.props.videoId)) // P1651 is youtube_video_id property
|
||||
return axios.get(wdk.getReverseClaims('P1651', this.props.videoId)) // P1651 is youtube_video_id property
|
||||
.then(wikidataP1651Res => {
|
||||
if (wikidataP1651Res.data.results.bindings.length) { // got a match
|
||||
this.getWikidataPage(wdk.simplify.sparqlResults(wikidataP1651Res.data))// set in state wikidata
|
||||
.then(() => {
|
||||
if (this.state.wikidata.claims.P435) {
|
||||
if (this.state.wikidata.claims.P435) { // p435 == musicbrainzWorkId
|
||||
axios.get(`${musicbrainzBaseUrl}/work/${this.state.wikidata.claims.P435[0].mainsnak.datavalue.value}`, { // get musicbrainz info
|
||||
params: {
|
||||
'inc': 'artist-rels url-rels',
|
||||
@@ -75,7 +95,7 @@ class Wikipedia extends Component {
|
||||
}).then(
|
||||
musicbrainzRes1 =>
|
||||
this.setState({ musicbrainz: musicbrainzRes1.data, isMBLoaded: true })
|
||||
);
|
||||
);
|
||||
}
|
||||
else {//oof P435 not found in wikidata
|
||||
axios.get(`${musicbrainzBaseUrl}/work`, { // search on mb by wikidata title
|
||||
@@ -97,7 +117,7 @@ class Wikipedia extends Component {
|
||||
.then(
|
||||
(musicbrainzWorkRes2) =>
|
||||
this.setState({ musicbrainz: musicbrainzWorkRes2.data, isMBLoaded: true })
|
||||
);
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -105,7 +125,7 @@ class Wikipedia extends Component {
|
||||
else { //oof
|
||||
axios.get(`${musicbrainzBaseUrl}/work`, {
|
||||
params: {
|
||||
'query': this.state.props.title.trim(),
|
||||
'query': 'undefined' === typeof this.props.title ? this.props.title2 : this.props.title,
|
||||
'limit': 1,
|
||||
'offset': 0,
|
||||
'fmt': 'json'
|
||||
@@ -122,44 +142,31 @@ class Wikipedia extends Component {
|
||||
})
|
||||
]).then(
|
||||
axios.spread((wikidataP435Res, musicbrainzWorkRes) => {
|
||||
this.setState({ musicbrainz: musicbrainzWorkRes.data, isMBLoaded: true });
|
||||
this.setState({
|
||||
musicbrainz: musicbrainzWorkRes.data,
|
||||
isMBLoaded: true
|
||||
});
|
||||
if (wikidataP435Res.data.results.bindings.length) // found a match
|
||||
this.getWikidataPage(wdk.simplify.sparqlResults(wikidataP435Res.data)); // set the result in the state
|
||||
else if (musicbrainzWorkRes.data.relations.find(currentRel => currentRel.type === "wikidata")) { // found wikidata on music brainz
|
||||
let a = musicbrainzWorkRes.data.relations.find(currentRel => currentRel.type === "wikidata");
|
||||
let wikidataUrl = musicbrainzWorkRes.data.relations.find(currentRel => currentRel.type === "wikidata");
|
||||
let wikidataEntityRegEx = new RegExp("[^/]+$"); // match last part of url https://regex101.com/r/0wCQHY/1
|
||||
this.getWikidataPage(wikidataEntityRegEx.exec(a.url.resource)) //.then(() => this.setState({ isWikiLoaded: true }));
|
||||
this.getWikidataPage(wikidataEntityRegEx.exec(wikidataUrl.url.resource)) //.then(() => this.setState({ isWikiLoaded: true }));
|
||||
}
|
||||
else { // oof
|
||||
wikijs().find(this.state.props.title).then(data => console.log('asd', data)) // find by props.title
|
||||
this.findWikiPage()
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
return new Promise((resolve, reject) => resolve('ok'));
|
||||
});
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (prevState.props.videoId !== nextProps.videoId)
|
||||
return {
|
||||
props: {
|
||||
videoId: nextProps.videoId,
|
||||
artist: nextProps.artist,
|
||||
title: nextProps.title
|
||||
},
|
||||
isWikiLoaded: false,
|
||||
isWDataLoaded: false,
|
||||
isMBLoaded: false,
|
||||
isLoaded: false
|
||||
};
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
this.wrapper().then(()=>this.setState({isLoaded: true}));
|
||||
this.wrapper().then(() => this.setState({ isLoaded: true }));
|
||||
}
|
||||
|
||||
|
||||
@@ -167,10 +174,9 @@ class Wikipedia extends Component {
|
||||
|
||||
// }
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (prevState.props.videoId !== this.state.props.videoId)
|
||||
this.wrapper().then(()=>this.setState({isLoaded: true}));
|
||||
}
|
||||
// componentDidUpdate(prevProps, prevState) {
|
||||
|
||||
// }
|
||||
|
||||
// componentWillUnmount() {
|
||||
|
||||
@@ -185,19 +191,19 @@ class Wikipedia extends Component {
|
||||
return <React.Fragment>Loading...</React.Fragment>;
|
||||
} else {
|
||||
return (
|
||||
<Table striped bordered hover size="sm">
|
||||
<Table bordered variant="dark" hover size="sm">
|
||||
<tbody>
|
||||
{ isWikiLoaded &&
|
||||
{isWikiLoaded &&
|
||||
this.state.wikipediakeys.map(key => (
|
||||
<tr>
|
||||
<tr key={key}>
|
||||
<td>{key}</td>
|
||||
<td>{wikipedia.info[key].toLocaleString()}</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
{ isWDataLoaded &&
|
||||
{isWDataLoaded &&
|
||||
this.state.wikidatakeys.map(key => (
|
||||
<tr>
|
||||
<tr key={key}>
|
||||
<td>{`${key} - ${wikidata.claims[key][0].mainsnak.datatype}`}</td>
|
||||
<td>{
|
||||
typeof wikidata.claims[key][0].mainsnak.datavalue.value === "string" ?
|
||||
@@ -211,15 +217,15 @@ class Wikipedia extends Component {
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
{ isMBLoaded &&
|
||||
musicbrainz.relations.map(relation => {
|
||||
{isMBLoaded &&
|
||||
musicbrainz.relations.map((relation, i) => {
|
||||
if (relation["target-type"] === "artist")
|
||||
return (<tr>
|
||||
return (<tr key={i}>
|
||||
<td>{relation.type}</td>
|
||||
<td>{relation.artist.name}</td>
|
||||
</tr>);
|
||||
else if (relation["target-type"] === "url")
|
||||
return (<tr>
|
||||
return (<tr key={i}>
|
||||
<td>{relation.type}</td>
|
||||
<td><a href={relation.url.resource}>{relation.type}</a></td>
|
||||
</tr>)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.upperSection{
|
||||
background-color:#000000;
|
||||
display: fixed;
|
||||
}
|
||||
|
||||
.downSection{
|
||||
|
||||
+3
-1
@@ -1,3 +1,4 @@
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import 'react-app-polyfill/ie9';
|
||||
//import '@babel/polyfill';
|
||||
import React from 'react';
|
||||
@@ -5,8 +6,9 @@ import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
import registerServiceWorker from './registerServiceWorker';
|
||||
import { HashRouter, BrowserRouter } from 'react-router-dom'; // eslint-disable-line
|
||||
|
||||
localStorage['lastWatched'] ? function (){}() : localStorage.setItem('lastWatched', JSON.stringify([]))
|
||||
localStorage['lastId'] ? function (){}() : localStorage.setItem('lastId','0J2QdDbelmY')
|
||||
|
||||
ReactDOM.render(<HashRouter><App /></HashRouter>, document.getElementById('root'));
|
||||
ReactDOM.render(<BrowserRouter><App /></BrowserRouter>, document.getElementById('root'));
|
||||
registerServiceWorker();
|
||||
|
||||
@@ -31,7 +31,7 @@ class RecommenderRandom extends Component{
|
||||
'type' : 'video', //che contiene tutti i generi di musica
|
||||
'maxResults': '21',
|
||||
'pageToken' : pageToken,
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig'
|
||||
}
|
||||
}).then(
|
||||
response => {
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
//http://site1825.tw.cs.unibo.it/TW/globpop fvitali
|
||||
//http://site1825.tw.cs.unibo.it/video.json originale videolist
|
||||
|
||||
import React from 'react';
|
||||
import { Col, ListGroup, Card, CardDeck } from 'react-bootstrap'; // eslint-disable-line no-unused-vars
|
||||
import axios from 'axios'; // eslint-disable-line no-unused-vars
|
||||
import { Link } from 'react-router-dom'; // eslint-disable-line no-unused-vars
|
||||
/*eslint no-console: ["error", { allow: ["warn", "error", "info"] }] */
|
||||
import moment from "moment";
|
||||
|
||||
class Recent extends React.Component {
|
||||
state = {
|
||||
error: null,
|
||||
isLoaded: false,
|
||||
items: [],
|
||||
headers: null
|
||||
};
|
||||
|
||||
ISO_8601parse(a) {
|
||||
return moment(a, moment.ISO_8601).format('ddd, DD/MM/YYYY hh:mm:ss');
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// axios.get('http://site1825.tw.cs.unibo.it/TW/globpop', {
|
||||
// 'params':{
|
||||
// 'id':this.props.id
|
||||
// }
|
||||
// }).then(
|
||||
// response => {
|
||||
// //this.shuffleArray(response.data);
|
||||
// console.info ('a',response.data);
|
||||
this.getThumbnailsNames(JSON.parse(localStorage.getItem('lastWatched')));
|
||||
// console.info(response.data.recommended);
|
||||
// // this.setState({
|
||||
// // isLoaded: true,
|
||||
// // items:response.data.recommended,
|
||||
// // });
|
||||
|
||||
// },
|
||||
// // Note: it's important to handle errors here
|
||||
// // instead of a catch() block so that we don't swallow
|
||||
// // exceptions from actual bugs in components.
|
||||
// error => {
|
||||
// console.error(error);
|
||||
// this.setState({
|
||||
// isLoaded: true,
|
||||
// error
|
||||
// });
|
||||
// }
|
||||
// );
|
||||
}
|
||||
|
||||
// METODI
|
||||
getThumbnailsNames(recentVideoList) {
|
||||
let idToLookFor = recentVideoList.map(item => item.id);
|
||||
axios.get('https://www.googleapis.com/youtube/v3/videos', {
|
||||
params: {
|
||||
part: 'snippet',
|
||||
id: idToLookFor.toString(),
|
||||
key: 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig',
|
||||
fields: 'items(id,snippet/thumbnails/medium,snippet/title)'
|
||||
}
|
||||
})
|
||||
|
||||
.then(
|
||||
res1 => {
|
||||
res1.data.items.map(resCurrentValue =>
|
||||
Object.defineProperties(
|
||||
recentVideoList.find(videoItem => {
|
||||
return videoItem.id === resCurrentValue.id;
|
||||
}),
|
||||
{
|
||||
'thumbnail':
|
||||
{ value: resCurrentValue.snippet.thumbnails.medium.url },
|
||||
'name':
|
||||
{ value: resCurrentValue.snippet.title }
|
||||
})
|
||||
);
|
||||
this.setState({
|
||||
isLoaded: true,
|
||||
items: recentVideoList
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*shuffleArray(videoarray) {
|
||||
for (let i = videoarray.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[videoarray[i], videoarray[j]] = [videoarray[j], videoarray[i]]; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
// Durstenfeld shuffle.
|
||||
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
|
||||
}*/
|
||||
|
||||
render() {
|
||||
const recentVideoList = JSON.parse(localStorage.getItem('lastWatched'))
|
||||
const { error, isLoaded, items } = this.state;
|
||||
if (error) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
Error: {error.message} -- Cannot get {error.config.url}
|
||||
</React.Fragment>
|
||||
);
|
||||
} else if (!isLoaded) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Col>
|
||||
<p className="text-center">Loading...</p>
|
||||
</Col>
|
||||
</React.Fragment>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{items.map(item => (
|
||||
<Col md="4">
|
||||
<Card key={item.id}>
|
||||
<Link
|
||||
to={{
|
||||
pathname: '/video/' + item.id,
|
||||
}}
|
||||
>
|
||||
<Card.Img
|
||||
src={item.thumbnail}
|
||||
alt={'Thumbnail of ' + item.name}
|
||||
/>
|
||||
<Card.ImgOverlay>
|
||||
<Card.Title className="bg-dark d-inline text-white">
|
||||
{item.name}<br />
|
||||
{item.lastSelected}
|
||||
</Card.Title>
|
||||
</Card.ImgOverlay>
|
||||
</Link>
|
||||
</Card>
|
||||
|
||||
</Col>))}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default Recent;
|
||||
@@ -33,7 +33,7 @@ class Related extends Component {
|
||||
'relatedToVideoId' : this.state.videoId,
|
||||
'type' : 'video',
|
||||
'maxResults' : '21',
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig' // process.env.APIKEY in production
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig'
|
||||
}
|
||||
}).then(
|
||||
response => {
|
||||
|
||||
+87
-33
@@ -1,21 +1,45 @@
|
||||
import React from 'react';
|
||||
import axios from 'axios';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Card, Col } from 'react-bootstrap';
|
||||
|
||||
class Search extends React.Component {
|
||||
|
||||
state = {
|
||||
query: '',
|
||||
isLoaded: false,
|
||||
error: null,
|
||||
res: null
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (nextProps.match.params.query !== prevState.query)
|
||||
return { query: nextProps.match.params.query };
|
||||
return null;
|
||||
}
|
||||
// static getDerivedStateFromProps(nextProps, prevState) {
|
||||
// if (nextProps.match.params.query !== prevState.query)
|
||||
// return { query: nextProps.match.params.query };
|
||||
// return null;
|
||||
// }
|
||||
|
||||
componentDidMount() {
|
||||
console.log('called didmo');
|
||||
if (new RegExp("[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]").test(this.props.match.params.query.toString()))
|
||||
axios.get('https://www.googleapis.com/youtube/v3/videos', {
|
||||
params: {
|
||||
'part': 'id',
|
||||
'id': this.props.match.params.query,
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig',
|
||||
'field': 'pageInfo/resultsPerPage'
|
||||
}
|
||||
}).then(
|
||||
res => {
|
||||
res.data.pageInfo.resultsPerPage ?
|
||||
this.props.history.push('/video/' + this.props.match.params.query) :
|
||||
this.youtubeSearch()
|
||||
},
|
||||
error => {
|
||||
console.error(error)
|
||||
}
|
||||
)
|
||||
else
|
||||
this.youtubeSearch();
|
||||
}
|
||||
|
||||
// shouldComponentUpdate(nextProps, nextState) {
|
||||
@@ -24,26 +48,30 @@ class Search extends React.Component {
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
console.log('called didup');
|
||||
if(new RegExp("[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]").test(this.state.query.toString()))
|
||||
axios.get('https://www.googleapis.com/youtube/v3/videos',{
|
||||
params: {
|
||||
'part':'id',
|
||||
'id': this.state.query,
|
||||
'key': process.env.APIKEY ? process.env.APIKEY : 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig',
|
||||
'field': 'pageInfo/resultsPerPage'
|
||||
}
|
||||
}).then(
|
||||
res => {
|
||||
res.data.pageInfo.resultsPerPage ?
|
||||
this.props.history.push('/video/' + this.state.query) :
|
||||
this.youtubeSearch()
|
||||
},
|
||||
error => {
|
||||
console.error(error)
|
||||
}
|
||||
)
|
||||
else
|
||||
this.youtubeSearch();
|
||||
if (prevProps.match.params.query !== this.props.match.params.query)
|
||||
if (new RegExp("[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]").test(this.props.match.params.query.toString()))
|
||||
axios.get('https://www.googleapis.com/youtube/v3/videos', {
|
||||
params: {
|
||||
'part': 'id',
|
||||
'id': this.props.match.params.query,
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig',
|
||||
'field': 'pageInfo/resultsPerPage'
|
||||
}
|
||||
}).then(
|
||||
res => {
|
||||
res.data.pageInfo.resultsPerPage ?
|
||||
this.props.history.push('/video/' + this.props.match.params.query) :
|
||||
this.youtubeSearch()
|
||||
},
|
||||
error => {
|
||||
console.error(error)
|
||||
this.setState({
|
||||
error
|
||||
})
|
||||
}
|
||||
)
|
||||
else
|
||||
this.youtubeSearch();
|
||||
}
|
||||
|
||||
// componentWillUnmount() {
|
||||
@@ -54,18 +82,19 @@ class Search extends React.Component {
|
||||
return axios.get('https://www.googleapis.com/youtube/v3/search', {
|
||||
params: {
|
||||
'part': 'snippet',
|
||||
'q': this.state.query,
|
||||
'q': this.props.match.params.query,
|
||||
'videoEmbeddable': 'true',
|
||||
'type': 'video',
|
||||
'maxResults': 30,
|
||||
'topicId': '/m/04rlf, /m/02jjt',
|
||||
'key': process.env.APIKEY ? process.env.APIKEY : 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig'
|
||||
'key': 'AIzaSyA21Odw9UdfiOJnxvA_eDfOW0OxuUfHKig'
|
||||
}
|
||||
}).then(
|
||||
res => {
|
||||
console.log(res.data);
|
||||
this.setState({
|
||||
res: res.data
|
||||
res: res.data,
|
||||
isLoaded: true
|
||||
})
|
||||
},
|
||||
error => { console.error(error) }
|
||||
@@ -73,11 +102,36 @@ class Search extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<span>{this.state.query} keyword</span>
|
||||
</div>
|
||||
);
|
||||
if (this.state.error) {
|
||||
return <React.Fragment>Error: {this.state.error.message}</React.Fragment>;
|
||||
} else if (!this.state.isLoaded) {
|
||||
return <React.Fragment>Loading...</React.Fragment>;
|
||||
} else {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{this.state.res.items.map(item => (<Col key={item.id.videoId} md="4">
|
||||
<Card>
|
||||
<Link
|
||||
to={{
|
||||
pathname: '/video/' + item.id.videoId,
|
||||
}}
|
||||
>
|
||||
<Card.Img
|
||||
src={item.snippet.thumbnails.medium.url}
|
||||
alt={'Thumbnail of ' + item.snippet.title}
|
||||
/>
|
||||
<Card.ImgOverlay>
|
||||
<Card.Title className="bg-dark d-inline text-white">
|
||||
{item.snippet.title}
|
||||
</Card.Title>
|
||||
</Card.ImgOverlay>
|
||||
</Link>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class fvitali extends React.Component {
|
||||
|
||||
.then(
|
||||
res1 => {
|
||||
res1.data.items.map(resCurrentValue => {
|
||||
res1.data.items.map(resCurrentValue =>
|
||||
Object.defineProperties(
|
||||
reccomended.find(videoItem => {
|
||||
return videoItem.videoID === resCurrentValue.id;
|
||||
@@ -74,8 +74,8 @@ class fvitali extends React.Component {
|
||||
{ value: resCurrentValue.snippet.thumbnails.medium.url },
|
||||
'name':
|
||||
{value: resCurrentValue.snippet.title}
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
this.setState({
|
||||
isLoaded: true,
|
||||
items: reccomended
|
||||
@@ -95,8 +95,7 @@ class fvitali extends React.Component {
|
||||
}*/
|
||||
|
||||
render() {
|
||||
const ISO_8601parse = this.ISO_8601parse;
|
||||
const { error, isLoaded, items, headers } = this.state;
|
||||
const { error, isLoaded, items } = this.state;
|
||||
if (error) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -115,7 +114,7 @@ class fvitali extends React.Component {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{items.map(item=>( <Col md="4">
|
||||
<Card>
|
||||
<Card key={item.videoID}>
|
||||
<Link
|
||||
to={{
|
||||
pathname: '/video/' + item.videoID,
|
||||
|
||||
Reference in New Issue
Block a user