Merge branch 'SouthRidge_video_app'

This commit is contained in:
Nikola Metulev 2016-12-05 21:08:52 -08:00
Родитель 3cf6cbdb16 62211ea1b2
Коммит ef4dcae7eb
75 изменённых файлов: 3129 добавлений и 0 удалений

33
apps/video/README.md Normal file
Просмотреть файл

@ -0,0 +1,33 @@
# South Ridge Video (video app)
[![SouthRidge](http://imgur.com/3lSmSJd.png)](https://www.youtube.com/watch?v=6kv3qyCdc1E)
South Ridge Video, an open source video app developed as a hosted web application built with React.js, and hosted on a web server. South Ridge can easily be converted to a UWP application that takes advantage of native platform capabilities and can be distributed through the Windows Store as any other UWP app.
Read the [full blog post](https://blogs.windows.com/buildingapps/2016/09/30/uwp-hosted-web-app-on-xbox-one-app-dev-on-xbox-series) or visit the [App Dev on Xbox landing page](http://aka.ms/xboxappdev) for more videos and blogs.
## Setup
The app is hosted at [http://southridge.azurewebsites.net](http://southridge.azurewebsites.net) for this example but you can deploy it yourself to any backend you choose. Once the app is hosted, all you need is the url to create app packages.
1. Use [manifoldJS](http://manifoldjs.com/) from the command line on any platform npm is supported, or through the [web](http://manifoldjs.com/generator). In this example, we are using the npm generator from the command line.
*install manifoldjs*
```
npm install -g manifoldjs
```
*generate package*
```
manifoldjs http://southridge.azurewebsites.net/
```
2. To deploy the package to the Xbox, first make sure your Xbox is in [Dev Mode](https://msdn.microsoft.com/en-us/windows/uwp/xbox-apps/devkit-activation). You can then use the [Windows Device Portal (WDP)](https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal) through a web browser to configure and manage the Xbox. [Follow these steps to enable WDP on your Xbox](https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal-xbox?f=255&MSPPError=-2147217396). Launch WDP in your favourite browser and navigate to the Apps tab.
3. Under the *Install app* section, click on *Browse* next to *pick a loose folder*
4. Navigate to the *windows10* folder from the packages you generated with manifoldJS and select the *manifest* folder
5. Click the *Go* button to upload the loose files and install the app. Once this is complete, you will be able to find and launch the app on your Xbox
6. Enjoy!

Просмотреть файл

@ -0,0 +1,377 @@
/*this is phone size */
@media screen and (min-width:300px) and (max-width:799px) {
@-ms-viewport {
width: 360px;
}
.movieListing .movieSection{
padding: 12px 0 12px 16px;
}
/*player part */
#page .playMovie {
padding: 72px 16px 12px 16px;
flex-wrap: wrap;
}
#page #videoContainer{
xwidth: 100%;
}
#page .movieText{
margin-left: 0px;
}
#page .movieText h2{
margin: 12px 0;
}
.movieTextWrapper{
height: 100px;
overflow: scroll;
}
#page .lowerDetailsWrapper{
flex-wrap: wrap;
}
#page .additionalDetailWrapper{
margin: 12px 16px;
}
#page .additionalDetailWrapper .detailBlock{
margin-bottom: 16px;
}
#page .additionalDetailWrapper h4{
margin-bottom: 12px;
}
#page .moviePlayer{
width: 100%;
height: 100%;
}
#page .overArrow {
display: none;
}
#page .movieBox{
width: 198px;
height: 100px;
}
#page .movieBoxContainer{
margin-top: 4px;
}
.logoBox .logo { display: none}
.controls button {
width: 120px;
height: 32px;
}
#page .controls h1{
font-size: 24px;
}
#page .logoBox {
padding: 40px 16px;
}
#page .topSection{
height: 424px;
}
#page .heroBox{
height: 296px;
padding: 64px 16px;
}
}
/*end phone size */
/*this is tablet size */
@media screen and (min-width:800px) and (max-width:1279px) {
@-ms-viewport {
width: 1024px;
}
.movieListing .movieSection{
padding-right: 126px;
}
#page .topSection{
height: 424px;
}
#page .heroBox{
height: 296px;
}
#page .moviePlayer{
height: 260px;
width: 520px;
}
}
/*end tablet size */
/*this is Xbox size */
@media screen and (min-width:1280px) and (max-width:1365px){
@-ms-viewport {
width: 1280px;
}
.movieListing .movieSection{
padding-right: 0;
}
#page .overArrow {
display: none;
}
body{
xmargin:-400px;
}
}
/*end Xbox size */
/*this is the desktoop size */
@media screen and (min-width:1366px) {
@-ms-viewport {
width: 1366px;
}
.movieListing .movieSection{
padding-right: 146px;
}
}
/*END desktoop size */
body{
background-color: #1F213A;
color: white;
font-family: 'SegoeUIMonoW01-Regular', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
touch-action: pan-y;
-ms-overflow-style: none;
overflow-x:hidden;
}
.logoBox{
position: absolute;
width:100%;
padding: 64px;
display: flex;
z-index: 11;
}
.logoBox div{
margin-right: 40px;
}
.logoBox .logo{
margin-right: 68px;
height: 56px;
margin-top: -30px;
}
#page {
display: flex;
flex-direction: column;
flex-wrap: nowrap ;
align-items: stretch;
align-content: space-between;
}
.topSection{
height: 564px;
margin-bottom:0em;
background: linear-gradient(to bottom, rgba(65,102,97,0) 0%,rgba(65,102,97,0) 32%,rgba(65,102,97,1) 99%,rgba(65,102,97,1) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
}
.heroBox {
height: 436px;
padding: 64px;
opacity:.7;
background-image:url('http://adx.metulev.com/video/Images/Clean/Large/FeaturedImage_2x1_Image04.jpg');
background-size: cover;
background-position: center;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.movieListing{
display: flex;
justify-content: center;
flex-direction: column;
}
.movieBoxContainer{
margin:16px 16px 0 0;
font-size: 12px;
}
.movieBox {
width: 276px;
height: 140px;
background-color:#32474F;
margin-bottom: 8px;
flex-shrink:0;
background-size: cover;
border: 0;
display: block;
padding:0;
}
.movieBox:focus span, .movieBox:active span{
width: 100%;
height: 100%;
background-image: url('/images/play.png');
background-size: cover;
display: inline-block;
background-position: center center;
opacity: .5;
margin:0;
padding:0;
}
.heroBox .controls{
width:29em;
margin-bottom:30px;
}
.controls h1{
margin-bottom:20px;
font-size: 34px;
}
.controls span{
font-size: 1.2em;
}
.bottomSection{
flex-grow: 1;
xheight:100%;
xpadding: 40px 68px;
}
.movieSection{
overflow:hidden;
padding: 40px 68px;
position: relative;
}
.movieSection .list{
display: flex;
flex-direction: row;
overflow-x: scroll;
overflow-y:hidden;
xwidth:2000px;
justify-content: left;
margin-top:8px;
}
.movieSection h4{
font-size: 15px;
}
.movieSection:nth-of-type(2), .movieSection:nth-of-type(5) {
background-color:#283444;
}
.movieSection:nth-of-type(4){
background-color:#2f404b;
}
.movieSection:nth-of-type(2) .movieBoxContainer:first-child .movieBox, .movieSection:nth-of-type(5) .movieBoxContainer:first-child .movieBox{
width: 568px;
height: 320px;
}
.movieSection:nth-of-type(2) .list, .movieSection:nth-of-type(5) .list{
flex-direction: column;
max-height:450px;
flex-wrap: wrap;
align-content: flex-start;
}
.movieBoxContainer:last-child { padding-right: 200px;}
.playMovie {
padding-bottom: 44px;
padding-top: 140px;
padding: 140px 100px 44px 64px;
xheight: 25em;
display: flex;
}
.moviePlayer{
height:380px;
width:760px;
background-color: black;
flex-shrink:0;
background-size: contain;
}
.movieText {
margin: 0 0 0 56px;
font-size: 12px;
}
.movieText h2{
margin-bottom:24px;
}
.movieText p {
margin-bottom: 20px;
xtext-align: justify;
}
.movieText .playInfo {
text-align: left;
}
.controls button{
font-family: 'SegoeMDL2';
}
.controls button:focus{
outline: none;
background-color: #32474F;
}
.additionalDetailWrapper{
margin:40px 64px;
}
.additionalDetailWrapper h4{
font-size: 15px;
margin-bottom: 24px;
}
.additionalDetailWrapper .lowerDetailsWrapper {
display: flex;
flex-flow: row;
line-height: 20px;
font-size: 12px;
}
.detailBlock {
margin-right: 84px;
width: 230px;
}
.overArrow{
position: absolute;
top: 48%;
right:24px;
border: 0;
font-size: 18px;
}
*webkit scroll bars */
::-webkit-scrollbar {
width: 12px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,405 @@
var data = [
{section:"recently released", id:"A", movies:[
{title:"Movie 1", id:1, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image09.jpg"},
{title:"Movie 1", id:2, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image14.jpg"},
{title:"Movie 1", id:3, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image19.jpg"},
{title:"Movie 1", id:4, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image26.jpg"},
{title:"Movie 1", id:5, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image21.jpg"},
{title:"Movie 1", id:6, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image29.jpg"},
{title:"Movie 1", id:7, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image39.jpg"},
{title:"Movie 1", id:8, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image27.jpg"},
{title:"Movie 1", id:9, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image15.jpg"},
{title:"Movie 1", id:10, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image11.jpg"},
]},
{section:"Adventures", id:"B",movies:[
{title:"Movie 1", id:11, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image06.jpg"},
{title:"Movie 1", id:12, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image40.jpg"},
{title:"Movie 1", id:13, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image32.jpg"},
{title:"Movie 1", id:14, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image28.jpg"},
{title:"Movie 1", id:15, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image49.jpg"},
{title:"Movie 1", id:16, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeaturedImage_2x1_Image03.jpg"},
{title:"Movie 1", id:17, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image10.jpg"},
{title:"Movie 1", id:18, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image19.jpg"},
{title:"Movie 1", id:19, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image22.jpg"},
{title:"Movie 1", id:20, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image09.jpg"}
]},
{section:"People",id:"C", movies:[
{title:"Movie 1", id:21, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image13.jpg"},
{title:"Movie l", id:22, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image16.jpg"},
{title:"Movie k", id:23, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image17.jpg"},
{title:"Movie l", id:24, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image22.jpg"},
{title:"Movie k", id:25, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image07.jpg"},
{title:"Movie a", id:26, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image19.jpg"},
{title:"Movie b", id:27, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image14.jpg"},
{title:"Movie c", id:28, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image08.jpg"},
{title:"Movie d", id:29, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image28.jpg"},
{title:"Movie e", id:30, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image27.jpg"}
]},
{section:"The Great Outdoors",id:"D", movies:[
{title:"Movie k", id:31, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image48.jpg"},
{title:"Movie l", id:32, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image34.jpg"},
{title:"Movie k", id:33, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image22.jpg"},
{title:"Movie l", id:34, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image08.jpg"},
{title:"Movie k", id:35, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image18.jpg"},
{title:"Movie a", id:36, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image25.jpg"},
{title:"Movie b", id:37, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image26.jpg"},
{title:"Movie c", id:38, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image09.jpg"},
{title:"Movie d", id:39, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image27.jpg"},
{title:"Movie e", id:40, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image28.jpg"}
]},
{section:"Kids",id:"E", movies:[
{title:"Movie k", id:41, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image37.jpg"},
{title:"Movie l", id:42, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image45.jpg"},
{title:"Movie k", id:43, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image12.jpg"},
{title:"Movie l", id:44, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image59.jpg"},
{title:"Movie k", id:45, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image24.jpg"},
{title:"Movie a", id:46, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image13.jpg"},
{title:"Movie b", id:47, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image21.jpg"},
{title:"Movie c", id:48, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image22.jpg"},
{title:"Movie d", id:49, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image23.jpg"},
{title:"Movie e", id:50, imgUrl:"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image24.jpg"}
]}
]
//custom events
var loadMoviePage = new CustomEvent('loadMoviePage');
var playMovieFullScreen = new CustomEvent('playMovieFullScreen');
var currentPlayObj = {title:'Galaxy Explorer', imgUrl:'http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image04.jpg'};
var initStateObj = { state: "frontPage" };
history.pushState(initStateObj, "page 2", "#frontPage");
var loadMovieState = function(a){
var stateObj = { state: "playMovie" };
history.pushState(stateObj, "page 2", "#playMovie");
document.dispatchEvent(loadMoviePage)
};
var HeroBox = React.createClass({
handleClick() {
currentPlayObj = this.props;
loadMovieState()
},
handleFocus(){
// window.scrollTo(0,0)
//console.log('should be focusing top')
 $("html, body").animate({ scrollTop: 0 }, 300);
},
render: function() {
return (
<div className="heroBox">
<div className="controls">
<h1>Galaxy Adorer</h1>
<button onFocus={this.handleFocus} onClick={this.handleClick} ><span className="arrow-right"></span></button>
</div>
</div>
);
}
});
var MovieBox = React.createClass({
handleClick: function() {
currentPlayObj = this.props.data;
loadMovieState()
},
render: function(){
var makeId = "m"+this.props.id
return(
<div className="movieBoxContainer">
<button className="movieBox" id={makeId} data-tv-focus-right={this.props.focusData} title={this.props.title} onClick={this.handleClick} style={{backgroundImage: 'url('+this.props.imgUrl+')'}}><span></span></button>
{this.props.title}
</div>
)
}
});
var MovieSection = React.createClass({
handleClick(e){
var maxPos = $(e.currentTarget).siblings()[1].scrollWidth-$( e.currentTarget).siblings()[1].clientWidth;
var curPos = $(e.currentTarget).siblings()[1].scrollLeft;
var distance = $( e.currentTarget).siblings()[1].clientWidth-200;
if(curPos >= maxPos) distance = (curPos+distance)*-1;
 $(e.currentTarget).siblings().animate({ scrollLeft: curPos+distance }, 600);
},
render: function(){
var i =0;
var leng = this.props.data.length;
var movieSectionNodes = this.props.data.map(function(data) {
i++;
if(leng == i){
leng = leng-1;
var pin = "#m"+(data.id-leng);
console.log("leng", leng);
console.log('data.id', data.id)
return (
<MovieBox id={data.id} key={data.id} title={data.title} data={data} imgUrl={data.imgUrl} focusData={pin}/>
);
}else{
return (
<MovieBox id={data.id} key={data.id} title={data.title} data={data} imgUrl={data.imgUrl} />
);
}
});
return(
<div className="movieSection" id={this.props.id}>
<h4>{this.props.section}</h4>
<div className="list">
{movieSectionNodes}
</div>
<button onClick={this.handleClick} className="overArrow"></button>
</div>
)
}
});
var MovieListing = React.createClass({
render: function() {
var num = 0;
var movieSectionNodes = this.props.data.map(function(data) {
return (
<MovieSection title={data.title} key={data.id} section={data.section} data={data.movies} />
);
});
return (
<div className="movieListing">
{movieSectionNodes}
</div>
);
}
});
class MoviePlayer extends React.Component {
constructor() {
super();
};
componentDidMount(){
initializePlayer()
}
render(){
return(
<div id="videoContainer" className="moviePlayer">
<video id="myVideo" controls="true" width="100%" height="100%" autoPlay>
<source src="http://video.ch9.ms/ch9/2f52/44b36f3c-0822-40b1-9926-6771225a2f52/mjsNapol01_high.mp4" type="video/mp4"></source>
</video>
<div id="videoControls" className="controls">
<div className="col span-12 center-content">
<input id="seekSlider" type="range" min="0" max="100" defaultValue="0" step="1" />
</div>
<div className="col span-12 center-content">
<div className="col span-6 left-controls">
<span id="curTimeText">0:00:00</span>
</div>
<div className="col span-6 right-controls">
<span id="remTimeText">-0:00:00</span>
</div>
</div>
<div className="col span-12 center-controls">
<button id="closeCaptionBtn" className="iconfont">&#xEC15;</button>
<button id="aspRatioBtn" className="iconfont">&#xE799;</button>
<button id="playPauseBtn" className="iconfont">&#xE769;</button>
<button id="volumeBtn" className="iconfont">&#xE15D;</button>
<button id="fullscreenBtn" className="iconfont">&#xE1D9;</button>
</div>
</div>
<div id="volumeModal">
<button id="muteBtn" className="iconfont">&#xE15D;</button>
<input id="volumeSlider" className="iconfont" type="range" min="0" max="100" defaultValue="100" step="1" />
</div>
</div>
)}
};
var PlayMovie = React.createClass({
render: function(){
//<div className="moviePlayer" style={{backgroundImage: 'url('+this.props.data.imgUrl+')'}}></div>
return(
<div className="playMovie">
<MoviePlayer />
<div className="movieText">
<h2>{this.props.data.title}</h2>
<div className="movieTextWrapper">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum ipsum sit amet porta faucibus. Cras ullamcorper a odio non rutrum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum ipsum sit amet porta faucibus. Quisque a diam id tellus placerat euismod.</p>
<p className="playInfo">2008 | 1 hr 51 min</p>
</div>
</div>
</div>
)
}
});
var PlayMovieDetails = React.createClass({
render:function(){
// console.log('movie obj', this.props)
return(
<div className="movieText">
<h2>{this.props.data.title}</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum ipsum sit amet porta faucibus. Quisque a diam id tellus placerat euismod. Cras ullamcorper a odio non rutrum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum ipsum sit amet porta faucibus. Quisque a diam id tellus placerat euismod.</p>
</div>
)
}
});
var PlayMoveAdditional = React.createClass({
render: function(){
return(
<div className="additionalDetailWrapper">
<h4>Additional Details</h4>
<div className="lowerDetailsWrapper">
<div className="detailBlock">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum ipsum sit amet porta faucibus</div>
<div className="detailBlock">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec fermentum ipsum sit amet porta faucibus</div>
</div>
</div>
)
}
})
class TopSection extends React.Component {
constructor() {
super();
this.state = {
viewer: 'frontPage'
};
};
componentDidMount(){
var that = this;
window.addEventListener('popstate', function(e){
var stateObj = e.state;
window.scrollTo(0, 0);
that.setState({viewer: stateObj.state});
});
document.addEventListener('loadMoviePage', function(){
that.setState({viewer: 'playMovie'});
// console.log(currentPlayObj)
})
}
render() {
if (this.state.viewer === 'frontPage'){
return(
<div className="topSection" >
<HeroBox title={"Galaxy Explorer"} id={0} imgUrl={"http://adx.azureedge.net/Images/Clean/Small/FeatureImage_2x1_Image04.jpg"} />
</div>
)
}else{
return(
<div className="topSection" >
<PlayMovie data={currentPlayObj} />
</div>
)}
}};
class BottomSection extends React.Component {
constructor() {
super();
this.state = {
viewer: 'frontPage'
};
};
componentDidMount(){
var that = this;
window.addEventListener('popstate', function(e){
var stateObj = e.state;
window.scrollTo(0, 0);
that.setState({viewer: stateObj.state});
});
document.addEventListener('loadMoviePage', function(){
window.scrollTo(0, 0);
that.setState({viewer: 'playMovie'});
})
}
render() {
if (this.state.viewer === 'frontPage'){
return(
<div className="bottomSection" >
<MovieListing data={this.props.data} />
</div>
)
}else{
return(
<div className="bottomSection">
<PlayMoveAdditional data={currentPlayObj} />
</div>
)}
}};
var LogoBox = React.createClass({
render: function() {
return (
<div className="logoBox">
<img src="http://adx.metulev.com/video/Logo/Logo_NoText.png" className="logo" />
<div>Film</div>
<div>Broadcast</div>
<div>Commercials</div>
<img src="" className="search" />
</div>
)
}
});
var PageWrapper = React.createClass({
render: function() {
return (
<div className="pageWrapper">
<LogoBox />
<div className="topSection">
<TopSection />
</div>
<BottomSection data={this.props.data} />
</div>
);
}
});
ReactDOM.render(
<PageWrapper data={data} />,
document.getElementById('page')
);

Двоичные данные
apps/video/SouthRidgeVideo/images/android-launchericon-144-144.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/android-launchericon-192-192.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.6 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/android-launchericon-48-48.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 864 B

Двоичные данные
apps/video/SouthRidgeVideo/images/android-launchericon-512-512.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/android-launchericon-72-72.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/android-launchericon-96-96.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 864 B

Двоичные данные
apps/video/SouthRidgeVideo/images/chrome-favicon-16-16.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 286 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-general-128-128.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-general-16-16.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 286 B

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-general-256-256.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.4 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-general-32-32.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 556 B

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-general-48-48.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 864 B

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-general-64-64.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-general-90-90.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-marketplace-128-128.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/firefox-marketplace-512-512.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/hero1.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 686 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-appicon-1024-1024.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 38 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-appicon-120-120.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-appicon-152-152.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-appicon-180-180.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.2 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-appicon-76-76.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-1024-768.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 37 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-1242-2208.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 56 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-1334-750.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 52 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-1536-2048.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 76 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-2048-1536.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 115 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-2208-1242.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 121 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-640-1136.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 22 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-640-960.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 21 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-750-1334.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/ios-launchimage-768-1024.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/play.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-smallsquare-24-24.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 427 B

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-smallsquare-30-30.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 513 B

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-smallsquare-42-42.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 702 B

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-smallsquare-54-54.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 976 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 32 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 23 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-splashscreen-620-300.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 15 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-splashscreen-868-420.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 23 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-squarelogo-120-120.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-squarelogo-150-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.4 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-squarelogo-210-210.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-squarelogo-270-270.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.9 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-storelogo-50-50.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 887 B

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-storelogo-70-70.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windows-storelogo-90-90.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windowsphone-appicon-106-106.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windowsphone-appicon-44-44.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 772 B

Двоичные данные
apps/video/SouthRidgeVideo/images/windowsphone-appicon-62-62.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.9 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windowsphone-smalltile-71-71.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windowsphone-smalltile-99-99.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
apps/video/SouthRidgeVideo/images/windowsphone-storelogo-50-50.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 887 B

Двоичные данные
apps/video/SouthRidgeVideo/images/windowsphone-storelogo-70-70.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Просмотреть файл

@ -0,0 +1,232 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>South Ridge Video</title>
<link href="manifest.json" rel="manifest">
<link href="//db.onlinewebfonts.com/c/88bdc70ec292cc29451932f9875b378a?family=SegoeUIMonoW01-Regular" rel="stylesheet" type="text/css"/> <link href="reset.css" rel="stylesheet" type="text/css" />
<link href="app.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="style.css">
<script>
if(window.Windows && window.Windows.UI && window.Windows.UI.ViewManagement){
var applicationView = Windows.UI.ViewManagement.ApplicationView.getForCurrentView();
applicationView.setDesiredBoundsMode(Windows.UI.ViewManagement.ApplicationViewBoundsMode.useCoreWindow);
}
</script>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
<div id="page"></div>
<script type="text/babel" src="frontpage.js"></script>
<script src="directionalnavigation-1.0.0.0.js"></script>
<script>
TVJS.DirectionalNavigation.focusableSelectors.push(".movieBox") ;
TVJS.DirectionalNavigation.focusableSelectors.push(".controls .iconfont") ;
// We set up two boundaries. This means that if the focused element is not at least 200 pixels from
// the edge of the screen, then we will scroll the viewport so that it is.
var leftBoundaryToTriggerScrollIntoView = 200;
var rightBoundaryToTriggerScrollIntoView = document.body.offsetWidth - 200;
var topBoundaryToTriggerScrollIntoView = 100
var bottomBoundaryToTriggerScrollIntoView = document.body.offsetHeight - 100;
var scrollableList = document.body;
var bodyScroll = document.body
// Adjust the left and right boundaries if the window is resized.
function handleWindowResize() {
leftBoundaryToTriggerScrollIntoView = 200;
rightBoundaryToTriggerScrollIntoView = document.body.offsetWidth - 200;
topBoundaryToTriggerScrollIntoView = 100
bottomBoundaryToTriggerScrollIntoView = document.body.offsetHeight - 100;
};
window.addEventListener("resize", handleWindowResize, false);
// This function handles the core logic for scrolling content into view.
function handleFocusChanging(ev) {
// console.log(ev)
scrollableList = ev.detail.nextFocusElement.parentNode.parentNode;
// console.log('scrollableList', scrollableList)
var keyCode = ev.detail.keyCode;
var nextFocusElement = ev.detail.nextFocusElement;
if (nextFocusElement) {
var nextFocusElementRect = nextFocusElement.getBoundingClientRect();
var newScrollLeft = -1;
var xScrollPos = 20;
var yScrollPos = 20;
switch (keyCode) {
case 37: // Left arrow
case 205: // Gamepad DPad left
case 214: // Gamepad left thumbstick left:
// Figure out if focus is about to move past the left boundary and we
// need to scroll the next element into view.
if (nextFocusElementRect.left < leftBoundaryToTriggerScrollIntoView) {
// If yes, figure out how much to move scroll the viewport.
var xScrollAmount = -1 * (leftBoundaryToTriggerScrollIntoView - nextFocusElementRect.left);
newScrollLeft = Math.max(0, scrollableList.scrollLeft + xScrollAmount);
// console.log('nextFocusElementRect.left', nextFocusElementRect.left)
// console.log('leftBoundaryToTriggerScrollIntoView', leftBoundaryToTriggerScrollIntoView);
console.log('newScrollLeft', newScrollLeft)
scrollableList.scrollLeft = newScrollLeft;
}
break;
case 39: // Right arrow
case 206: // Gamepad DPad right
case 213: // Gamepad left thumbstick right
// Figure out if focus is about to move past the right boundary and we
// need to scroll the next element into view.
if (nextFocusElementRect.right > rightBoundaryToTriggerScrollIntoView) {
// If yes, figure out how much to move scroll the viewport.
var xScrollAmount = nextFocusElementRect.right - rightBoundaryToTriggerScrollIntoView;
xScrollPos = Math.max(0, scrollableList.scrollLeft + xScrollAmount);
// console.log('nextFocusElementRect.right', nextFocusElementRect.right)
// console.log('rightBoundaryToTriggerScrollIntoView', rightBoundaryToTriggerScrollIntoView);
console.log('xScrollPos', xScrollPos)
scrollableList.scrollLeft = xScrollPos;
}
break;
case 38: // up arrow
case 203: // Gamepad DPad up
case 211: // Gamepad left thumbstick up
// Figure out if focus is about to move past the right boundary and we
// need to scroll the next element into view.
if (nextFocusElementRect.top < topBoundaryToTriggerScrollIntoView) {
// If yes, figure out how much to move scroll the viewport.
var yScrollAmount = nextFocusElementRect.top - topBoundaryToTriggerScrollIntoView;
yScrollPos = Math.max(0, bodyScroll.scrollTop + yScrollAmount);
// console.log('nextFocusElementRect.right', nextFocusElementRect.right)
// console.log('rightBoundaryToTriggerScrollIntoView', rightBoundaryToTriggerScrollIntoView);
console.log('yScrollPos', yScrollPos)
bodyScroll.scrollTop = yScrollPos; //scrollTo??????????????
}
break;
case 40: // down arrow
case 204: // Gamepad DPad down
case 212: // Gamepad left thumbstick down
// Figure out if focus is about to move past the right boundary and we
// need to scroll the next element into view.
bottomBoundaryToTriggerScrollIntoView = window.innerHeight -100;
if (nextFocusElementRect.bottom > bottomBoundaryToTriggerScrollIntoView) {
// If yes, figure out how much to move scroll the viewport.
console.log('nextFocusElementRect.bottom', nextFocusElementRect.bottom)
var yScrollAmount = bottomBoundaryToTriggerScrollIntoView - nextFocusElementRect.bottom;
yScrollPos = Math.max(0, bodyScroll.scrollTop - yScrollAmount);
// console.log('nextFocusElementRect.right', nextFocusElementRect.right)
// console.log('rightBoundaryToTriggerScrollIntoView', rightBoundaryToTriggerScrollIntoView);
console.log('yScrollPos', yScrollPos)
bodyScroll.scrollTop = yScrollPos; //scrollTo??????????????
}
break;
default:
break;
}
requestAnimationFrame(function () {
if (nextFocusElement) {
nextFocusElement.focus();
}
});
}
};
// Listen to the focuschanging event. This event will fire right before focus is about to change
// allowing us to scroll content into view if needed.
TVJS.DirectionalNavigation.addEventListener("focuschanging", handleFocusChanging, false);
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.js"></script>
<script src="videoPlayer.js"></script>
<script>
$('.overArrow').click(function(){
 $(".list").animate({ scrollRight: 900 }, 600);
 return false;
});
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,263 @@
{
"start_url": "http://southridge.azurewebsites.net",
"short_name": "SouthRidge",
"display": "fullscreen",
"orientation": "landscape",
"name": "South Ridge Video",
"scope":"/",
"mjs_access_whitelist": [
{
"url": "https://southridge.azurewebsites.net",
"apiAccess": "all"
},
{
"url": "http://southridge.azurewebsites.net",
"apiAccess": "all"
}
],
"theme_color":"#2F404B",
"icons": [
{
"src": "images/windows-smallsquare-24-24.png",
"sizes": "24x24"
},
{
"src": "images/windows-smallsquare-30-30.png",
"sizes": "30x30"
},
{
"src": "images/windows-splashscreen-1240-600.png",
"sizes": "1240x600"
},
{
"src": "images/windows-smallsquare-42-42.png",
"sizes": "42x42"
},
{
"src": "images/windows-smallsquare-54-54.png",
"sizes": "54x54"
},
{
"src": "images/windows-splashscreen-1116-540.png",
"sizes": "1116x540"
},
{
"src": "images/windows-splashscreen-868-420.png",
"sizes": "868x420"
},
{
"src": "images/windows-splashscreen-620-300.png",
"sizes": "620x300"
},
{
"src": "images/windows-squarelogo-270-270.png",
"sizes": "270x270"
},
{
"src": "images/windows-squarelogo-210-210.png",
"sizes": "210x210"
},
{
"src": "images/windows-squarelogo-150-150.png",
"sizes": "150x150"
},
{
"src": "images/windows-squarelogo-120-120.png",
"sizes": "120x120"
},
{
"src": "images/windows-storelogo-90-90.png",
"sizes": "90x90"
},
{
"src": "images/windows-storelogo-70-70.png",
"sizes": "70x70"
},
{
"src": "images/windows-storelogo-50-50.png",
"sizes": "50x50"
},
{
"src": "images/windowsphone-appicon-106-106.png",
"sizes": "106x106"
},
{
"src": "images/windowsphone-appicon-62-62.png",
"sizes": "62x62"
},
{
"src": "images/windowsphone-appicon-44-44.png",
"sizes": "44x44"
},
{
"src": "images/windowsphone-mediumtile-360-360.png",
"sizes": "360x360"
},
{
"src": "images/windowsphone-mediumtile-210-210.png",
"sizes": "210x210"
},
{
"src": "images/windowsphone-mediumtile-150-150.png",
"sizes": "150x150"
},
{
"src": "images/windowsphone-smalltile-170-170.png",
"sizes": "170x170"
},
{
"src": "images/windowsphone-smalltile-99-99.png",
"sizes": "99x99"
},
{
"src": "images/windowsphone-smalltile-71-71.png",
"sizes": "71x71"
},
{
"src": "images/windowsphone-storelogo-120-120.png",
"sizes": "120x120"
},
{
"src": "images/windowsphone-storelogo-70-70.png",
"sizes": "70x70"
},
{
"src": "images/windowsphone-storelogo-50-50.png",
"sizes": "50x50"
},
{
"src": "images/android-launchericon-512-512.png",
"sizes": "512x512"
},
{
"src": "images/android-launchericon-192-192.png",
"sizes": "192x192"
},
{
"src": "images/android-launchericon-144-144.png",
"sizes": "144x144"
},
{
"src": "images/android-launchericon-96-96.png",
"sizes": "96x96"
},
{
"src": "images/android-launchericon-72-72.png",
"sizes": "72x72"
},
{
"src": "images/android-launchericon-48-48.png",
"sizes": "48x48"
},
{
"src": "images/ios-appicon-1024-1024.png",
"sizes": "1024x1024"
},
{
"src": "images/ios-appicon-180-180.png",
"sizes": "180x180"
},
{
"src": "images/ios-appicon-152-152.png",
"sizes": "152x152"
},
{
"src": "images/ios-appicon-120-120.png",
"sizes": "120x120"
},
{
"src": "images/ios-appicon-76-76.png",
"sizes": "76x76"
},
{
"src": "images/ios-launchimage-750-1334.png",
"sizes": "750x1334"
},
{
"src": "images/ios-launchimage-1334-750.png",
"sizes": "1334x750"
},
{
"src": "images/ios-launchimage-1242-2208.png",
"sizes": "1242x2208"
},
{
"src": "images/ios-launchimage-2208-1242.png",
"sizes": "2208x1242"
},
{
"src": "images/ios-launchimage-640-960.png",
"sizes": "640x960"
},
{
"src": "images/ios-launchimage-640-1136.png",
"sizes": "640x1136"
},
{
"src": "images/ios-launchimage-1536-2048.png",
"sizes": "1536x2048"
},
{
"src": "images/ios-launchimage-2048-1536.png",
"sizes": "2048x1536"
},
{
"src": "images/ios-launchimage-768-1024.png",
"sizes": "768x1024"
},
{
"src": "images/ios-launchimage-1024-768.png",
"sizes": "1024x768"
},
{
"src": "images/chrome-extensionmanagementpage-48-48.png",
"sizes": "48x48"
},
{
"src": "images/chrome-favicon-16-16.png",
"sizes": "16x16"
},
{
"src": "images/chrome-installprocess-128-128.png",
"sizes": "128x128"
},
{
"src": "images/firefox-marketplace-512-512.png",
"sizes": "512x512"
},
{
"src": "images/firefox-marketplace-128-128.png",
"sizes": "128x128"
},
{
"src": "images/firefox-general-256-256.png",
"sizes": "256x256"
},
{
"src": "images/firefox-general-128-128.png",
"sizes": "128x128"
},
{
"src": "images/firefox-general-90-90.png",
"sizes": "90x90"
},
{
"src": "images/firefox-general-64-64.png",
"sizes": "64x64"
},
{
"src": "images/firefox-general-48-48.png",
"sizes": "48x48"
},
{
"src": "images/firefox-general-32-32.png",
"sizes": "32x32"
},
{
"src": "images/firefox-general-16-16.png",
"sizes": "16x16"
}
]
}

Просмотреть файл

@ -0,0 +1,54 @@
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
h1, h2, h3 { font-size: 24px;}
p {line-height: 1.25em; margin-bottom: 1.5em;}
button{ background: none;
border:2px solid white;
xpadding: .5em; color: white;
width: 164px;
text-align: center;
height: 36px;}

Двоичные данные
apps/video/SouthRidgeVideo/segmdl2.ttf Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,257 @@
div#videoContainer{
xwidth: 100%;
background:#000;
margin:0px;
position: relative;
bottom: 0%;
left: 0%;
right: 0%;
}
div#myVideo {
z-index: 1;
position: absolute;
}
video.scale2{
-moz-transform:scale(1.5);
-webkit-transform:scale(1.5);
-o-transform:scale(1.5);
-ms-transform:scale(1.5);
transform:scale(1.5);
}
@font-face {
font-family: 'SegoeMDL2';
src: url("segmdl2.ttf") format("truetype");
}
#videoContainer .controls {
background: #000;
position: absolute;
width: inherit;
height: 40%;
bottom: 0%;
z-index: 2147483647; /*fix this*/
}
.left-controls {
text-align: left;
color: white;
float: left;
margin-top: 0;
margin-left: 2%;
}
.center-controls {
text-align: center;
margin-bottom: 30px;
margin: 3%;
}
.center-controls button{
height: auto;
width: auto;
}
.right-controls {
text-align: right;
color: white;
float: right;
margin-top: 0;
margin-right: 2%;
}
.iconfont {
font-family: 'SegoeMDL2';
font-size: 25px;
background: none;
color: white;
border: none;
}
.center-content {
text-align: center;
margin: auto;
}
input#seekSlider {
text-align: center;
width: 97%;
margin: 2% 1%;
}
input#volumeSlider {
width: 100px;
}
button.iconfont {
background: black;
padding: 8px;
}
button.iconfont:hover {
background: #95a5a6;
}
button.iconfont:active {
background: #7f8c8d;
}
button.iconfont:focus {
outline: none;
}
div#volumeModal {
display: none;
padding: 5px;
z-index: 2147483700;
width: initial;
background: #000;
border-style: solid;
border-color: #BDC3C7;
border-width: 2px;
}
/*This removes on Chrome only. How do I get rid of it on Edge?*/
video::-webkit-media-controls-enclosure {
display:none !important;
}
/*======================= Range Slider*/
/*Chrome*/
input[type=range] {
-webkit-appearance: none;
margin: 10px 0;
width: 100%;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 11px;
cursor: pointer;
background: #BDC3C7;
border-radius: 20px;
border: 0px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
border: 2px solid #3498DB;
height: 26px;
width: 26px;
border-radius: 15px;
background: #FFFFFF;
cursor: pointer;
-webkit-appearance: none;
margin-top: -8.5px;
}
input[type=range]:hover::-webkit-slider-thumb {
background: #3498db;
}
input[type=range]:active::-webkit-slider-thumb {
background: #2980b9;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #BDC3C7;
}
/*FireFox*/
input[type=range]::-moz-range-track {
width: 100%;
height: 11px;
cursor: pointer;
background: #BDC3C7;
border-radius: 20px;
border: 0px solid #010101;
}
input[type=range]::-moz-range-thumb {
box-shadow: 0px 0px 0px #000031;
border: 2px solid #3498DB;
height: 26px;
width: 26px;
border-radius: 15px;
background: #FFFFFF;
cursor: pointer;
}
/*MS*/
input[type=range]::-ms-track {
width: 100%;
height: 3px;
padding: 5px;
cursor: pointer;
background: transparent;
border-color: transparent;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #16a085;
border-radius: 40px;
}
input[type=range]::-ms-fill-upper {
background: #BDC3C7;
border-radius: 40px;
}
input[type=range]::-ms-thumb {
border: 2px solid #16a085;
height: 20px;
width: 20px;
border-radius: 15px;
background: #000;
cursor: pointer;
margin-top: 0px;
}
input[type=range]:hover::-ms-thumb {
background: #bdc3c7;
}
input[type=range]:active::-ms-thumb {
background: #16a085;
}
/*========================*/
/* fullscreen */
html:-ms-fullscreen {
width:100%;
}
:-webkit-full-screen {
background-color:transparent;
}
/* hide controls on fullscreen with WebKit */
div[datafullscreen=true] video::-webkit-media-controls {
display:none !important;
}
div[datafullscreen=true] {
max-width:100%;
width:100%;
margin:0;
padding:0;
}
div[datafullscreen=true] video {
height:auto;
}
div[datafullscreen=true] .controls {
width:100%;
position:absolute;
bottom:0%;
left:0%;
right:0%;
height:inherit;
z-index:2147483647;
}

Просмотреть файл

@ -0,0 +1,177 @@
<!--
# The MIT License (MIT)
#
# Copyright (c) 2016 Microsoft. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-->
<!DOCTYPE html>
<html>
<head>
<title>Scroll into view</title>
<script src="directionalnavigation-1.0.0.0.js"></script>
<style>
body {
background-color: rgb(16, 16, 16);
color: rgb(235, 235, 235);
font-family: "Segoe UI";
font-size: 18pt;
}
button {
background-color: rgba(235, 235, 235, 0.1);
border: 4px solid rgb(16, 16, 16);
color: rgb(235, 235, 235);
outline: none;
padding: 16px;
height: 364px;
width: 208px;
font-size: 18pt;
}
button:focus {
background-color: rgb(16, 124, 16);
border-color: rgba(235, 235, 235, 1);
}
.scrolling-list {
overflow-x: scroll;
height: 400px;
}
.viewport {
width: 7000px;
}
</style>
</head>
<body>
<h1>Scroll into view</h1>
<div id="scrolling-list" class="scrolling-list">
<div id="viewport" class="viewport">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>7</button>
<button>8</button>
<button>9</button>
<button>10</button>
<button>11</button>
<button>12</button>
<button>13</button>
<button>14</button>
<button>15</button>
<button>16</button>
<button>17</button>
<button>18</button>
<button>19</button>
<button>20</button>
<button>21</button>
<button>22</button>
<button>23</button>
<button>24</button>
<button>25</button>
<button>26</button>
<button>27</button>
<button>28</button>
<button>29</button>
<button>30</button>
</div>
</div>
<script>
// This sample demonstrates how to use the focuschanging event to scroll elements into view so that
// the currently focused element is never on the edge of the screen.
// We set up two boundaries. This means that if the focused element is not at least 200 pixels from
// the edge of the screen, then we will scroll the viewport so that it is.
var leftBoundaryToTriggerScrollIntoView = 200;
var rightBoundaryToTriggerScrollIntoView = document.body.offsetWidth - 200;
var scrollableList = document.getElementById("scrolling-list");
// Adjust the left and right boundaries if the window is resized.
function handleWindowResize() {
leftBoundaryToTriggerScrollIntoView = 200;
rightBoundaryToTriggerScrollIntoView = document.body.offsetWidth - 200;
};
window.addEventListener("resize", handleWindowResize, false);
// This function handles the core logic for scrolling content into view.
function handleFocusChanging(ev) {
var keyCode = ev.detail.keyCode;
var nextFocusElement = ev.detail.nextFocusElement;
if (nextFocusElement) {
var nextFocusElementRect = nextFocusElement.getBoundingClientRect();
var newScrollLeft = -1;
switch (keyCode) {
case 37: // Left arrow
case 205: // Gamepad DPad left
case 214: // Gamepad left thumbstick left:
// Figure out if focus is about to move past the left boundary and we
// need to scroll the next element into view.
if (nextFocusElementRect.left < leftBoundaryToTriggerScrollIntoView) {
// If yes, figure out how much to move scroll the viewport.
var xScrollAmount = -2 * (leftBoundaryToTriggerScrollIntoView - nextFocusElementRect.left);
newScrollLeft = Math.max(0, scrollableList.scrollLeft + xScrollAmount);
}
break;
case 39: // Right arrow
case 206: // Gamepad DPad right
case 213: // Gamepad left thumbstick right
// Figure out if focus is about to move past the right boundary and we
// need to scroll the next element into view.
if (nextFocusElementRect.right > rightBoundaryToTriggerScrollIntoView) {
// If yes, figure out how much to move scroll the viewport.
var xScrollAmount = nextFocusElementRect.right - rightBoundaryToTriggerScrollIntoView;
var xScrollPos = Math.max(0, scrollableList.scrollLeft + xScrollAmount);
}
break;
default:
break;
}
if (newScrollLeft) {
// Note: If running on Edge or Internet Explorer 11 or higher, we could use the msZoomTo API
// to do an animated scroll. For other browsers, you can use CSS transitions.
scrollableList.scrollLeft = xScrollPos;
ev.preventDefault();
// Focus is an expensive operation so it's good to let any processing from scrolling into
// view finish first.
requestAnimationFrame(function () {
setTimeout(function () {
if (nextFocusElement) {
nextFocusElement.focus();
}
});
});
}
}
};
// Listen to the focuschanging event. This event will fire right before focus is about to change
// allowing us to scroll content into view if needed.
TVJS.DirectionalNavigation.addEventListener("focuschanging", handleFocusChanging, false);
var initialFocus = document.querySelector("button");
initialFocus.focus();
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,36 @@
var NewText = React.createClass({
render: function() {
return (
<h1>This is new test</h1>
)
}
});
class LikeButton extends React.Component {
constructor() {
super();
this.state = {
liked: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({liked: !this.state.liked});
}
render() {
const text = this.state.liked ? 'liked' : 'haven\'t liked';
return (
<div onClick={this.handleClick}>
You {text} this. Click to toggle.
<NewText />
</div>
)
}
}
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);

Просмотреть файл

@ -0,0 +1,274 @@
var vid,
videoContainer,
videoControls,
controlsTimer,
playPauseBtn,
seekSlider,
curTimeText,
remTimeText,
aspRatioBtn,
volumeBtn,
volumeModal,
muteBtn,
volumeSlider,
fullscreenBtn,
systemMediaControls;
var timer = 4000; //milliseconds for fade timer
function initializePlayer(){
//Set high level references
vid = document.getElementById("myVideo");
videoContainer = document.getElementById("videoContainer");
videoControls = document.getElementById("videoControls");
//replace native video controls with custom
vid.controls = false;
videoControls.style.display = 'block';
controlsTimer = setTimeout(function() {
$('#videoControls').fadeOut('slow');
$('#volumeModal').fadeOut('slow');
}, timer);
//define button references
playPauseBtn = document.getElementById("playPauseBtn");
seekSlider = document.getElementById("seekSlider");
curTimeText = document.getElementById("curTimeText");
remTimeText = document.getElementById("remTimeText");
aspRatioBtn = document.getElementById("aspRatioBtn");
volumeBtn = document.getElementById("volumeBtn");
volumeModal = document.getElementById("volumeModal");
muteBtn = document.getElementById("muteBtn");
volumeSlider = document.getElementById("volumeSlider");
fullscreenBtn = document.getElementById("fullscreenBtn");
//event listeners for buttons
vid.addEventListener("mouseover",showControls,false);
videoControls.addEventListener("mouseover",controlTimerReset,false);
document.body.addEventListener("keydown",showControls,false);
playPauseBtn.addEventListener("click",playPause,false);
seekSlider.addEventListener("change",vidSeek,false);
vid.addEventListener("timeupdate",seekTimeUpdate,false);
//volume button & modal handlers
volumeBtn.addEventListener("click",toggleVolumeModal,false);
muteBtn.addEventListener("click",vidMute,false);
volumeSlider.addEventListener("change",setVolume,false);
window.addEventListener("click",focusOffModal,false);
fullscreenBtn.addEventListener("click",toggleFullscreen,false);
//Add SMTC support
if (typeof Windows !== 'undefined') {
systemMediaControls = Windows.Media.SystemMediaTransportControls.getForCurrentView();
systemMediaControls.addEventListener("buttonpressed", systemMediaControlsButtonPressed, false);
systemMediaControls.isPlayEnabled = true;
systemMediaControls.isPauseEnabled = true;
systemMediaControls.isStopEnabled = true;
systemMediaControls.playbackStatus = Windows.Media.MediaPlaybackStatus.closed;
//Hookup SMTC functions
vid.addEventListener("pause", mediaPaused);
vid.addEventListener("playing", mediaPlaying);
vid.addEventListener("ended", mediaEnded);
}
}
//SMTC functions
function playMedia() {
var media = document.getElementById("myVideo");
media.play();
}
function pauseMedia() {
var media = document.getElementById("myVideo");
media.pause();
}
function stopMedia() {
var media = document.getElementById("myVideo");
media.pause();
media.currentTime = 0;
}
function systemMediaControlsButtonPressed(eventIn) {
var mediaButton = Windows.Media.SystemMediaTransportControlsButton;
switch (eventIn.button) {
case mediaButton.play:
playMedia();
break;
case mediaButton.pause:
pauseMedia();
break;
case mediaButton.stop:
stopMedia();
break;
}
}
function mediaPlaying() {
// Update the SystemMediaTransportControl state.
systemMediaControls.playbackStatus = Windows.Media.MediaPlaybackStatus.playing;
}
function mediaPaused() {
// Update the SystemMediaTransportControl state.
systemMediaControls.playbackStatus = Windows.Media.MediaPlaybackStatus.paused;
}
function mediaEnded() {
// Update the SystemMediaTransportControl state.
systemMediaControls.playbackStatus = Windows.Media.MediaPlaybackStatus.stopped;
}
//window.onload = initializePlayer;
function showControls(event) {
//show controller
$('#videoControls').fadeIn('slow');
//reset timer
controlTimerReset(event);
}
function controlTimerReset(event) {
//reset timer
window.clearTimeout(controlsTimer);
//restart timeout
controlsTimer = setTimeout(function() {
$('#videoControls').fadeOut('slow');
$('#volumeModal').fadeOut('slow');
}, timer);
}
function playPause(event){
if(vid.paused){
vid.play();
playPauseBtn.innerHTML = "&#xE769;";
} else {
vid.pause();
playPauseBtn.innerHTML = "&#xE768;";
}
}
function vidSeek() {
var seekto = vid.duration * (seekSlider.value / 100);
vid.currentTime = seekto;
}
function seekTimeUpdate() {
var newTime = vid.currentTime * (100 / vid.duration);
seekSlider.value = newTime;
var curHours = Math.floor(vid.currentTime / 3600);
var curMins = Math.floor((vid.currentTime - curHours * 3600) / 60);
var curSecs = Math.floor(vid.currentTime - curHours * 3600 - curMins * 60);
remTime = vid.duration - vid.currentTime;
var remHours = Math.floor(remTime / 3600);
var remMins = Math.floor((remTime - remHours * 3600) / 60);
var remSecs = Math.floor(remTime - remHours * 3600 - remMins * 60);
if (curSecs < 10) { curSecs = "0" + curSecs; }
if (curMins < 10) { curMins = "0" + curMins; }
if (curHours < 10) { curHours = "0" + curHours; }
if (remSecs < 10) { remSecs = "0" + remSecs; }
if (remMins < 10) { remMins = "0" + remMins; }
if (remHours < 10) { remHours = "0" + remHours; }
curTimeText.innerHTML = curHours + ":" + curMins + ":" + curSecs;
remTimeText.innerHTML = "-" + remHours + ":" + remMins + ":" + remSecs;
if (vid.ended) {
playPauseBtn.innerHTML = "&#xE768;";
remTimeText.innerHTML = "-00:00:00";
}
}
function vidMute() {
if(vid.muted){
vid.muted = false;
muteBtn.innerHTML = "&#xE15D";
volumeBtn.innerHTML = "&#xE15D";
} else {
vid.muted = true;
muteBtn.innerHTML = "&#xE74F";
volumeBtn.innerHTML = "&#xE74F";
}
}
function setVolume() {
vid.volume = volumeSlider.value / 100;
if(vid.muted){
vid.muted = false;
muteBtn.innerHTML = "&#xE15D";
volumeBtn.innerHTML = "&#xE15D";
}
}
var setFullscreenData = function(state) {
videoContainer.setAttribute('datafullscreen', !!state);
}
function toggleFullscreen(){
var state = !!(document.fullScreen || document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement);
if(state) { //is in fullscreen --> need to exit FS
if(document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen){
document.mozCancelFullScreen();
}
fullscreenBtn.innerHTML = "&#xE1D9;";
setFullscreenData(false);
} else { //not in fullscreen --> need to enter FS
if (vid.requestFullscreen) {
vid.requestFullScreen();
} else if (vid.webkitRequestFullscreen) {
vid.webkitRequestFullscreen();
} else if (vid.mozRequestFullscreen) {
vid.mozRequestFullScreen();
}
fullscreenBtn.innerHTML = "&#xE1D8;";
setFullscreenData(true);
}
}
function toggleVolumeModal() {
if (volumeModal.style.display == "block") { //if its open, close it
$("#volumeModal").fadeOut('slow');
} else { //if its closed, open it
renderVolumeModal();
}
}
function renderVolumeModal() {
//just to rerender in case sizing changes -- wont need to do this after focus out is there.
volumeModal.style.display = "none";
$("#volumeModal").fadeIn('slow');
volumeModal.style.display = "block";
volumeModal.style.position = "absolute";
var coords = $("#volumeBtn").offset();
coords.top = coords.top - volumeModal.offsetHeight - 5;
coords.left = coords.left - (volumeModal.offsetWidth - volumeBtn.offsetWidth) / 2;
$("#volumeModal").offset(coords);
}
function focusOffModal(event) {
if (volumeModal.style.display == "block"
&& event.target != volumeModal
&& event.target != volumeBtn
&& event.target != muteBtn
&& event.target != volumeSlider) { //if its open, close it
$("#volumeModal").fadeOut('slow');
}
}

Просмотреть файл

@ -0,0 +1,16 @@
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<staticContent>
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<remove fileExtension=".json"/>
<mimeMap fileExtension=".json" mimeType="application/manifest+json"/>
<mimeMap fileExtension=".webapp" mimeType="application/manifest+json"/>
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
</staticContent>
</system.webServer>
</configuration>