mirror of
https://github.com/moonlight-stream/moonlight-chrome.git
synced 2025-08-17 16:46:31 +00:00
Merge pull request #77 from abdallahsoliman/master
more polishes to grid-UI
This commit is contained in:
commit
6ccf313761
@ -34,15 +34,20 @@
|
|||||||
<option value="30">30 FPS</option>
|
<option value="30">30 FPS</option>
|
||||||
<option value="60">60 FPS</option>
|
<option value="60">60 FPS</option>
|
||||||
</select>
|
</select>
|
||||||
<output id='bitrateField'>10 Mbps</output>
|
|
||||||
</div>
|
</div>
|
||||||
|
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="remoteAudioEnabledSwitch" id="remoteAudioEnabledSwitchContainer">
|
||||||
|
<input type="checkbox" id="remoteAudioEnabledSwitch" class="mdl-switch__input" checked>
|
||||||
|
<span class="mdl-switch__label">Remote audio off/on</span>
|
||||||
|
</label>
|
||||||
|
<output id='bitrateField'>10 Mbps</output>
|
||||||
<input id="bitrateSlider" class="mdl-slider mdl-js-slider" type="range" min="0" max="100" step="0.5" value="10">
|
<input id="bitrateSlider" class="mdl-slider mdl-js-slider" type="range" min="0" max="100" step="0.5" value="10">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="hostSettings">
|
<div id="hostSettings">
|
||||||
<div class="mdl-grid" id='host-grid'>
|
<div class="mdl-grid" id='host-grid'>
|
||||||
<div class='mdl-cell mdl-cell--3-col' id='addHostCell'>
|
<div class='mdl-cell mdl-cell--3-col host-cell mdl-button mdl-js-button mdl-js-ripple-effect' id='addHostCell'>
|
||||||
<img src="static/res/ic_add_circle_white_24px.svg" id='addHostIcon'></img>
|
<img src="static/res/ic_add_circle_white_24px.svg" id='addHostIcon'></img>
|
||||||
|
Add Host
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,36 +1,3 @@
|
|||||||
@font-face {
|
|
||||||
font-family: 'Material Icons';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
src: local('Material Icons'),
|
|
||||||
local('MaterialIcons-Regular'),
|
|
||||||
url('../fonts/MaterialIcons-Regular.woff') format('woff'),
|
|
||||||
}
|
|
||||||
.material-icons {
|
|
||||||
font-family: 'Material Icons';
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 24px; /* Preferred icon size */
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1;
|
|
||||||
text-transform: none;
|
|
||||||
letter-spacing: normal;
|
|
||||||
word-wrap: normal;
|
|
||||||
white-space: nowrap;
|
|
||||||
direction: ltr;
|
|
||||||
|
|
||||||
/* Support for all WebKit browsers. */
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
/* Support for Safari and Chrome. */
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
|
|
||||||
/* Support for Firefox. */
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
|
|
||||||
/* Support for IE. */
|
|
||||||
font-feature-settings: 'liga';
|
|
||||||
}
|
|
||||||
|
|
||||||
.mdl-layout__header-row {
|
.mdl-layout__header-row {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
@ -46,21 +13,14 @@
|
|||||||
color:#fff;
|
color:#fff;
|
||||||
padding:25px;
|
padding:25px;
|
||||||
}
|
}
|
||||||
#addHostIcon {
|
|
||||||
width:64px;
|
|
||||||
height:64px;
|
|
||||||
margin:auto;
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
#backIcon {
|
#backIcon {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
}
|
}
|
||||||
#addHostCell {
|
#backIcon:hover {
|
||||||
padding-top:3px;
|
cursor: pointer;
|
||||||
padding-bottom:3px;
|
|
||||||
}
|
}
|
||||||
.mdl-dialog {
|
.mdl-dialog {
|
||||||
border: none;
|
border: none;
|
||||||
@ -173,6 +133,12 @@ main {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
-webkit-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.34);
|
||||||
|
-moz-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.34);
|
||||||
|
box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.34);
|
||||||
|
}
|
||||||
|
.box-art:hover {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.current-game {
|
.current-game {
|
||||||
border: 3px solid green;
|
border: 3px solid green;
|
||||||
@ -184,3 +150,27 @@ main {
|
|||||||
color: #000;
|
color: #000;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
.host-cell {
|
||||||
|
display: inline-block;
|
||||||
|
width: 150px !important;
|
||||||
|
height: 150px !important;
|
||||||
|
background-color: #000;
|
||||||
|
-webkit-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.34);
|
||||||
|
-moz-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.34);
|
||||||
|
box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.34);
|
||||||
|
-webkit-border-radius: 10px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.host-cell:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
.host-cell:hover img {
|
||||||
|
-webkit-filter: invert(100%);
|
||||||
|
filter: invert(100%);
|
||||||
|
}
|
||||||
|
.host-cell img {
|
||||||
|
width: 80px;;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
var host = "";
|
// CURRENT ISSUE: host is not being saved. or it may have not been saved, and my state is screwed up.
|
||||||
|
// if (given host not in hosts) hosts.append(given host);
|
||||||
|
|
||||||
|
var _host = "";
|
||||||
var hosts = [];
|
var hosts = [];
|
||||||
var pairingCert;
|
var pairingCert;
|
||||||
var myUniqueid;
|
var myUniqueid;
|
||||||
@ -13,6 +16,7 @@ function attachListeners() {
|
|||||||
$('#selectFramerate').on('change', saveFramerate);
|
$('#selectFramerate').on('change', saveFramerate);
|
||||||
$('#bitrateSlider').on('input', updateBitrateField); // input occurs every notch you slide
|
$('#bitrateSlider').on('input', updateBitrateField); // input occurs every notch you slide
|
||||||
$('#bitrateSlider').on('change', saveBitrate); // change occurs once the mouse lets go.
|
$('#bitrateSlider').on('change', saveBitrate); // change occurs once the mouse lets go.
|
||||||
|
$("#remoteAudioEnabledSwitch").on('click', saveRemoteAudio);
|
||||||
$('#hostChosen').on('click', hostChosen);
|
$('#hostChosen').on('click', hostChosen);
|
||||||
$('#addHostCell').on('click', addHost);
|
$('#addHostCell').on('click', addHost);
|
||||||
$('#cancelAddHost').on('click', cancelAddHost);
|
$('#cancelAddHost').on('click', cancelAddHost);
|
||||||
@ -149,14 +153,19 @@ function pairTo(host, onSuccess, onFailure) {
|
|||||||
function hostChosen(sourceEvent) {
|
function hostChosen(sourceEvent) {
|
||||||
|
|
||||||
if(sourceEvent && sourceEvent.srcElement) {
|
if(sourceEvent && sourceEvent.srcElement) {
|
||||||
console.log('parsing host from grid element.');
|
if (sourceEvent.srcElement.innerText == "") {
|
||||||
host = sourceEvent.srcElement.innerText;
|
console.log('user clicked image. we gotta hack to parse out the host.');
|
||||||
|
host = sourceEvent.currentTarget.childNodes[1].textContent;
|
||||||
|
} else {
|
||||||
|
console.log('parsing host from grid element.');
|
||||||
|
host = sourceEvent.srcElement.innerText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
api = new NvHTTP(host, myUniqueid);
|
api = new NvHTTP(host, myUniqueid);
|
||||||
api.refreshServerInfo().then(function (ret) {
|
api.refreshServerInfo().then(function (ret) {
|
||||||
if(!api.paired) {
|
if(!api.paired) {
|
||||||
pairTo(host, function(){ showApps(); }, function(){});
|
pairTo(host, function(){ showApps(); saveHosts(); }, function(){});
|
||||||
} else {
|
} else {
|
||||||
showApps();
|
showApps();
|
||||||
}
|
}
|
||||||
@ -178,15 +187,15 @@ function cancelAddHost() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addHostToGrid(host) {
|
function addHostToGrid(host) {
|
||||||
if(hosts.indexOf(host) < 0) { // we don't have this host in our list. add it, and save it.
|
var cell = document.createElement('div');
|
||||||
var cell = document.createElement('div');
|
cell.className += 'mdl-cell mdl-cell--3-col host-cell mdl-button mdl-js-button mdl-js-ripple-effect';
|
||||||
cell.className += 'mdl-cell mdl-cell--3-col';
|
cell.id = 'hostgrid-' + host;
|
||||||
cell.id = 'hostgrid-' + host;
|
cell.innerHTML = host;
|
||||||
cell.innerHTML = host;
|
$(cell).prepend($("<img>", {src: "static/res/ic_desktop_windows_white_24px.svg"}));
|
||||||
$('#host-grid').append(cell);
|
$('#host-grid').append(cell);
|
||||||
cell.onclick = hostChosen;
|
cell.onclick = hostChosen;
|
||||||
|
if(hosts.indexOf(host) < 0) {
|
||||||
hosts.push(host);
|
hosts.push(host);
|
||||||
saveHosts();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +205,7 @@ function continueAddHost() {
|
|||||||
pairTo(inputHost,
|
pairTo(inputHost,
|
||||||
function() {
|
function() {
|
||||||
addHostToGrid(inputHost);
|
addHostToGrid(inputHost);
|
||||||
|
saveHosts();
|
||||||
document.querySelector('#addHostDialog').close();
|
document.querySelector('#addHostDialog').close();
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
@ -218,6 +228,25 @@ function pairingPopupCanceled() {
|
|||||||
document.querySelector('#pairingDialog').close();
|
document.querySelector('#pairingDialog').close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// puts the CSS style for current app on the app that's currently running
|
||||||
|
// and puts the CSS style for non-current app apps that aren't running
|
||||||
|
// this requires a hot-off-the-host `api`, and the appId we're going to stylize
|
||||||
|
// the function was made like this so that we can remove duplicated code, but
|
||||||
|
// not do N*N stylizations of the box art, or make the code not flow very well
|
||||||
|
function stylizeBoxArt(freshApi, appIdToStylize) {
|
||||||
|
if (freshApi.currentGame === appIdToStylize){ // stylize the currently running game
|
||||||
|
// destylize it, if it has the not-current-game style
|
||||||
|
if ($('#game-'+ appIdToStylize).hasClass("not-current-game")) $('#game-'+ appIdToStylize).removeClass("not-current-game");
|
||||||
|
// add the current-game style
|
||||||
|
$('#game-'+ appIdToStylize).addClass("current-game");
|
||||||
|
} else {
|
||||||
|
// destylize it, if it has the current-game style
|
||||||
|
if ($('#game-'+ appIdToStylize).hasClass("current-game")) $('#game-'+ appIdToStylize).removeClass("current-game");
|
||||||
|
// add the not-current-game style
|
||||||
|
$('#game-'+ appIdToStylize).addClass('not-current-game');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// show the app list
|
// show the app list
|
||||||
function showApps() {
|
function showApps() {
|
||||||
if(!api || !api.paired) { // safety checking. shouldn't happen.
|
if(!api || !api.paired) { // safety checking. shouldn't happen.
|
||||||
@ -231,21 +260,13 @@ function showApps() {
|
|||||||
api.getAppList().then(function (appList) {
|
api.getAppList().then(function (appList) {
|
||||||
appList.forEach(function (app) {
|
appList.forEach(function (app) {
|
||||||
api.getBoxArt(app.id).then(function (resolvedPromise) {
|
api.getBoxArt(app.id).then(function (resolvedPromise) {
|
||||||
|
// put the box art into the image holder
|
||||||
var imageBlob = new Blob([resolvedPromise], {type: "image/png"});
|
var imageBlob = new Blob([resolvedPromise], {type: "image/png"});
|
||||||
$("#game-grid").append($("<div>", {html:$("<img \>", {src: URL.createObjectURL(imageBlob), id: 'game-'+app.id, name: app.title }), class: 'box-art mdl-cell mdl-cell--3-col'}).append($("<span>", {html: app.title, class:"game-title"})));
|
$("#game-grid").append($("<div>", {html:$("<img \>", {src: URL.createObjectURL(imageBlob), id: 'game-'+app.id, name: app.title }), class: 'box-art mdl-cell mdl-cell--3-col'}).append($("<span>", {html: app.title, class:"game-title"})));
|
||||||
$('#game-'+app.id).on('click', startGame);
|
$('#game-'+app.id).on('click', startGame);
|
||||||
|
|
||||||
if (api.currentGame === app.id){ // stylize the currently running game
|
// apply CSS stylization to indicate whether the app is active
|
||||||
// destylize it, if it has the not-current-game style
|
stylizeBoxArt(api, app.id);
|
||||||
if ($('#game-'+ app.id).hasClass("not-current-game")) $('#game-'+ app.id).removeClass("not-current-game");
|
|
||||||
// add the current-game style
|
|
||||||
$('#game-'+ app.id).addClass("current-game");
|
|
||||||
} else {
|
|
||||||
// destylize it, if it has the current-game style
|
|
||||||
if ($('#game-'+ app.id).hasClass("current-game")) $('#game-'+ app.id).removeClass("current-game");
|
|
||||||
// add the not-current-game style
|
|
||||||
$('#game-'+ app.id).addClass('not-current-game');
|
|
||||||
}
|
|
||||||
|
|
||||||
}, function (failedPromise) {
|
}, function (failedPromise) {
|
||||||
console.log('Error! Failed to retrieve box art for app ID: ' + app.id + '. Returned value was: ' + failedPromise)
|
console.log('Error! Failed to retrieve box art for app ID: ' + app.id + '. Returned value was: ' + failedPromise)
|
||||||
@ -349,6 +370,8 @@ function startGame(sourceEvent) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remote_audio_enabled = $("#remoteAudioEnabledSwitch").parent().hasClass('is-checked') ? 1 : 0;
|
||||||
|
|
||||||
api.launchApp(appID,
|
api.launchApp(appID,
|
||||||
streamWidth + "x" + streamHeight + "x" + frameRate,
|
streamWidth + "x" + streamHeight + "x" + frameRate,
|
||||||
1, // Allow GFE to optimize game settings
|
1, // Allow GFE to optimize game settings
|
||||||
@ -477,6 +500,14 @@ function saveBitrate() {
|
|||||||
storeData('bitrate', $('#bitrateSlider').val(), null);
|
storeData('bitrate', $('#bitrateSlider').val(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveRemoteAudio() {
|
||||||
|
console.log('saving remote audio state');
|
||||||
|
// problem: when off, and the app is just starting, a tick to the switch doesn't always toggle it
|
||||||
|
// second problem: this callback is called immediately after clicking, so the HTML class `is-checked` isn't toggled yet
|
||||||
|
// to solve the second problem, we invert the boolean. This has worked in all cases I've tried, except for the first case
|
||||||
|
storeData('remoteAudio', !$("#remoteAudioEnabledSwitch").parent().hasClass('is-checked'), null);
|
||||||
|
}
|
||||||
|
|
||||||
function updateDefaultBitrate() {
|
function updateDefaultBitrate() {
|
||||||
var res = $('#selectResolution').val();
|
var res = $('#selectResolution').val();
|
||||||
var frameRate = $('#selectFramerate').val();
|
var frameRate = $('#selectFramerate').val();
|
||||||
@ -514,6 +545,16 @@ function onWindowLoad(){
|
|||||||
chrome.storage.sync.get('resolution', function(previousValue) {
|
chrome.storage.sync.get('resolution', function(previousValue) {
|
||||||
$('#selectResolution').val(previousValue.resolution != null ? previousValue.resolution : '1280:720');
|
$('#selectResolution').val(previousValue.resolution != null ? previousValue.resolution : '1280:720');
|
||||||
});
|
});
|
||||||
|
chrome.storage.sync.get('remoteAudio', function(previousValue) {
|
||||||
|
if(previousValue.remoteAudio == null) {
|
||||||
|
document.querySelector('#remoteAudioEnabledSwitchContainer').MaterialSwitch.off();
|
||||||
|
return;
|
||||||
|
} else if(previousValue.remoteAudio == false) {
|
||||||
|
document.querySelector('#remoteAudioEnabledSwitchContainer').MaterialSwitch.off();
|
||||||
|
} else {
|
||||||
|
document.querySelector('#remoteAudioEnabledSwitchContainer').MaterialSwitch.on();
|
||||||
|
}
|
||||||
|
});
|
||||||
// load stored framerate prefs
|
// load stored framerate prefs
|
||||||
chrome.storage.sync.get('frameRate', function(previousValue) {
|
chrome.storage.sync.get('frameRate', function(previousValue) {
|
||||||
$('#selectFramerate').val(previousValue.frameRate != null ? previousValue.frameRate : '60');
|
$('#selectFramerate').val(previousValue.frameRate != null ? previousValue.frameRate : '60');
|
||||||
@ -522,12 +563,7 @@ function onWindowLoad(){
|
|||||||
chrome.storage.sync.get('hosts', function(previousValue) {
|
chrome.storage.sync.get('hosts', function(previousValue) {
|
||||||
hosts = previousValue.hosts != null ? previousValue.hosts : [];
|
hosts = previousValue.hosts != null ? previousValue.hosts : [];
|
||||||
for(var i = 0; i < hosts.length; i++) { // programmatically add each new host.
|
for(var i = 0; i < hosts.length; i++) { // programmatically add each new host.
|
||||||
var cell = document.createElement('div');
|
addHostToGrid(hosts[i]);
|
||||||
cell.className += 'mdl-cell mdl-cell--3-col';
|
|
||||||
cell.id = 'hostgrid-' + hosts[i];
|
|
||||||
cell.innerHTML = hosts[i];
|
|
||||||
$('#host-grid').append(cell);
|
|
||||||
cell.onclick = hostChosen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -22,10 +22,17 @@ function handleMessage(msg) {
|
|||||||
console.log(msg.data);
|
console.log(msg.data);
|
||||||
if(msg.data === 'streamTerminated') { // if it's a recognized event, notify the appropriate function
|
if(msg.data === 'streamTerminated') { // if it's a recognized event, notify the appropriate function
|
||||||
$('#loadingSpinner').css('display', 'none'); // This is a fallback for RTSP handshake failing, which immediately terminates the stream.
|
$('#loadingSpinner').css('display', 'none'); // This is a fallback for RTSP handshake failing, which immediately terminates the stream.
|
||||||
api.refreshServerInfo().then(function (ret) {
|
|
||||||
|
api.refreshServerInfo().then(function (ret) { // refresh the serverinfo to acknowledge the currently running app
|
||||||
|
api.getAppList().then(function (appList) {
|
||||||
|
appList.forEach(function (app) {
|
||||||
|
stylizeBoxArt(api, app.id); // and reapply stylization to indicate what's currently running
|
||||||
|
});
|
||||||
|
});
|
||||||
showApps();
|
showApps();
|
||||||
chrome.app.window.current().restore();
|
chrome.app.window.current().restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
} else if(msg.data === 'Connection Established') {
|
} else if(msg.data === 'Connection Established') {
|
||||||
$('#loadingSpinner').css('display', 'none');
|
$('#loadingSpinner').css('display', 'none');
|
||||||
} else if(msg.data.indexOf('ProgressMsg: ') === 0) {
|
} else if(msg.data.indexOf('ProgressMsg: ') === 0) {
|
||||||
|
@ -41,6 +41,12 @@ function NvHTTP(address, clientUid) {
|
|||||||
this._baseUrlHttps = 'https://' + address + ':47984';
|
this._baseUrlHttps = 'https://' + address + ':47984';
|
||||||
this._baseUrlHttp = 'http://' + address + ':47989';
|
this._baseUrlHttp = 'http://' + address + ':47989';
|
||||||
this._memCachedBoxArtArray = {};
|
this._memCachedBoxArtArray = {};
|
||||||
|
|
||||||
|
this.serverUid = '';
|
||||||
|
this.GfeVersion = '';
|
||||||
|
this.supportedDisplayModes = {}; // key: y-resolution:x-resolution, value: array of supported framerates (only ever seen 30 or 60, here)
|
||||||
|
this.gputype = '';
|
||||||
|
this.numofapps = 0;
|
||||||
_self = this;
|
_self = this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,7 +84,7 @@ NvHTTP.prototype = {
|
|||||||
_parseServerInfo: function(xmlStr) {
|
_parseServerInfo: function(xmlStr) {
|
||||||
$xml = _self._parseXML(xmlStr);
|
$xml = _self._parseXML(xmlStr);
|
||||||
$root = $xml.find('root');
|
$root = $xml.find('root');
|
||||||
|
|
||||||
if($root.attr("status_code") != 200) {
|
if($root.attr("status_code") != 200) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -86,7 +92,24 @@ NvHTTP.prototype = {
|
|||||||
_self.paired = $root.find("PairStatus").text().trim() == 1;
|
_self.paired = $root.find("PairStatus").text().trim() == 1;
|
||||||
_self.currentGame = parseInt($root.find("currentgame").text().trim(), 10);
|
_self.currentGame = parseInt($root.find("currentgame").text().trim(), 10);
|
||||||
_self.serverMajorVersion = parseInt($root.find("appversion").text().trim().substring(0, 1), 10);
|
_self.serverMajorVersion = parseInt($root.find("appversion").text().trim().substring(0, 1), 10);
|
||||||
|
_self.serverUid = $root.find('uniqueid').text().trim();
|
||||||
|
_self.GfeVersion = $root.find('GfeVersion').text().trim();
|
||||||
|
_self.gputype = $root.find('gputype').text().trim();
|
||||||
|
_self.numofapps = $root.find('numofapps').text().trim();
|
||||||
|
// now for the hard part: parsing the supported streaming
|
||||||
|
$root.find('DisplayMode').each(function(index, value) { // for each resolution:FPS object
|
||||||
|
var yres = parseInt($(value).find('Height').text());
|
||||||
|
var xres = parseInt($(value).find('Width').text());
|
||||||
|
var fps = parseInt($(value).find('RefreshRate').text());
|
||||||
|
if(!_self.supportedDisplayModes[yres + ':' + xres]) {
|
||||||
|
_self.supportedDisplayModes[yres + ':' + xres] = [];
|
||||||
|
}
|
||||||
|
if(!_self.supportedDisplayModes[yres + ':' + xres].includes(fps)) {
|
||||||
|
_self.supportedDisplayModes[yres + ':' + xres].push(fps);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// GFE 2.8 started keeping currentgame set to the last game played. As a result, it no longer
|
// GFE 2.8 started keeping currentgame set to the last game played. As a result, it no longer
|
||||||
// has the semantics that its name would indicate. To contain the effects of this change as much
|
// has the semantics that its name would indicate. To contain the effects of this change as much
|
||||||
// as possible, we'll force the current game to zero if the server isn't in a streaming session.
|
// as possible, we'll force the current game to zero if the server isn't in a streaming session.
|
||||||
|
4
static/res/ic_desktop_windows_white_24px.svg
Normal file
4
static/res/ic_desktop_windows_white_24px.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
|
<path d="M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v2H8v2h8v-2h-2v-2h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H3V4h18v12z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 274 B |
Loading…
x
Reference in New Issue
Block a user