Add an Apply button to the Web UI when running as a Win32 Service (#700)
This commit is contained in:
parent
5980e520b9
commit
65574a02d4
7 changed files with 153 additions and 10 deletions
|
|
@ -494,6 +494,7 @@ void getConfig(resp_https_t response, req_https_t request) {
|
|||
|
||||
outputTree.put("status", "true");
|
||||
outputTree.put("platform", SUNSHINE_PLATFORM);
|
||||
outputTree.put("restart_supported", platf::restart_supported());
|
||||
|
||||
auto vars = config::parse_config(read_file(config::sunshine.config_file.c_str()));
|
||||
|
||||
|
|
@ -537,6 +538,37 @@ void saveConfig(resp_https_t response, req_https_t request) {
|
|||
}
|
||||
}
|
||||
|
||||
void restart(resp_https_t response, req_https_t request) {
|
||||
if(!authenticate(response, request)) return;
|
||||
|
||||
print_req(request);
|
||||
|
||||
std::stringstream ss;
|
||||
std::stringstream configStream;
|
||||
ss << request->content.rdbuf();
|
||||
pt::ptree outputTree;
|
||||
auto g = util::fail_guard([&]() {
|
||||
std::ostringstream data;
|
||||
|
||||
pt::write_json(data, outputTree);
|
||||
response->write(data.str());
|
||||
});
|
||||
|
||||
if(!platf::restart_supported()) {
|
||||
outputTree.put("status", false);
|
||||
outputTree.put("error", "Restart is not currently supported on this platform");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!platf::restart()) {
|
||||
outputTree.put("status", false);
|
||||
outputTree.put("error", "Restart failed");
|
||||
return;
|
||||
}
|
||||
|
||||
outputTree.put("status", true);
|
||||
}
|
||||
|
||||
void savePassword(resp_https_t response, req_https_t request) {
|
||||
if(!config::sunshine.username.empty() && !authenticate(response, request)) return;
|
||||
|
||||
|
|
@ -678,6 +710,7 @@ void start() {
|
|||
server.resource["^/api/apps$"]["POST"] = saveApp;
|
||||
server.resource["^/api/config$"]["GET"] = getConfig;
|
||||
server.resource["^/api/config$"]["POST"] = saveConfig;
|
||||
server.resource["^/api/restart$"]["POST"] = restart;
|
||||
server.resource["^/api/password$"]["POST"] = savePassword;
|
||||
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
|
||||
server.resource["^/api/clients/unpair$"]["POST"] = unpairAll;
|
||||
|
|
|
|||
|
|
@ -318,6 +318,9 @@ void adjust_thread_priority(thread_priority_e priority);
|
|||
void streaming_will_start();
|
||||
void streaming_will_stop();
|
||||
|
||||
bool restart_supported();
|
||||
bool restart();
|
||||
|
||||
input_t input();
|
||||
void move_mouse(input_t &input, int deltaX, int deltaY);
|
||||
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y);
|
||||
|
|
|
|||
|
|
@ -165,6 +165,16 @@ void streaming_will_stop() {
|
|||
// Nothing to do
|
||||
}
|
||||
|
||||
bool restart_supported() {
|
||||
// Restart not supported yet
|
||||
return false;
|
||||
}
|
||||
|
||||
bool restart() {
|
||||
// Restart not supported yet
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace source {
|
||||
enum source_e : std::size_t {
|
||||
#ifdef SUNSHINE_BUILD_CUDA
|
||||
|
|
|
|||
|
|
@ -143,6 +143,16 @@ void streaming_will_stop() {
|
|||
// Nothing to do
|
||||
}
|
||||
|
||||
bool restart_supported() {
|
||||
// Restart not supported yet
|
||||
return false;
|
||||
}
|
||||
|
||||
bool restart() {
|
||||
// Restart not supported yet
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace platf
|
||||
|
||||
namespace dyn {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <csignal>
|
||||
#include <filesystem>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
|
@ -522,4 +523,16 @@ void streaming_will_stop() {
|
|||
DwmEnableMMCSS(false);
|
||||
}
|
||||
|
||||
bool restart_supported() {
|
||||
// Restart is supported if we're running from the service
|
||||
return (GetConsoleWindow() == NULL);
|
||||
}
|
||||
|
||||
bool restart() {
|
||||
// Raise SIGINT to trigger the graceful exit logic. The service will
|
||||
// restart us in a few seconds.
|
||||
std::raise(SIGINT);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace platf
|
||||
|
|
@ -765,11 +765,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-success my-4" v-if="success">
|
||||
<b>Success!</b> Restart Sunshine to apply changes
|
||||
<div class="alert alert-success my-4" v-if="saved && restart_supported">
|
||||
<b>Success!</b> Click 'Apply' to restart Sunshine and apply changes. This will terminate any running sessions.
|
||||
</div>
|
||||
<div class="alert alert-success my-4" v-if="saved && !restart_supported">
|
||||
<b>Success!</b> Restart Sunshine to apply changes.
|
||||
</div>
|
||||
<div class="alert alert-success my-4" v-if="restarted">
|
||||
<b>Success!</b> Sunshine is restarting to apply changes.
|
||||
</div>
|
||||
<div class="mb-3 buttons">
|
||||
<button class="btn btn-primary" @click="save">Save</button>
|
||||
<button class="btn btn-success" @click="apply" v-if="saved && restart_supported && !restarted">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -779,7 +786,9 @@
|
|||
data() {
|
||||
return {
|
||||
platform: "",
|
||||
success: false,
|
||||
restart_supported: false,
|
||||
saved: false,
|
||||
restarted: false,
|
||||
config: null,
|
||||
fps: [],
|
||||
resolutions: [],
|
||||
|
|
@ -836,6 +845,7 @@
|
|||
.then((r) => {
|
||||
this.config = r;
|
||||
this.platform = this.config.platform;
|
||||
this.restart_supported = (this.config.restart_supported === "true");
|
||||
|
||||
var app = document.getElementById("app");
|
||||
if (this.platform == "windows") {
|
||||
|
|
@ -856,6 +866,7 @@
|
|||
|
||||
delete this.config.status;
|
||||
delete this.config.platform;
|
||||
delete this.config.restart_supported;
|
||||
//Populate default values if not present in config
|
||||
this.config.key_rightalt_to_key_win =
|
||||
this.config.key_rightalt_to_key_win || "disabled";
|
||||
|
|
@ -895,8 +906,7 @@
|
|||
});
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
this.success = false;
|
||||
serialize() {
|
||||
let nl = this.config === "windows" ? "\r\n" : "\n";
|
||||
this.config.resolutions =
|
||||
"[" +
|
||||
|
|
@ -906,12 +916,31 @@
|
|||
nl +
|
||||
"]";
|
||||
this.config.fps = JSON.stringify(this.fps);
|
||||
|
||||
},
|
||||
save() {
|
||||
this.saved = this.restarted = false;
|
||||
this.serialize();
|
||||
fetch("/api/config", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(this.config),
|
||||
}).then((r) => {
|
||||
if (r.status == 200) this.success = true;
|
||||
if (r.status == 200) this.saved = true;
|
||||
});
|
||||
},
|
||||
apply() {
|
||||
this.saved = this.restarted = false;
|
||||
this.serialize();
|
||||
fetch("/api/config", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(this.config),
|
||||
}).then((r) => {
|
||||
if (r.status == 200) {
|
||||
fetch("/api/restart", {
|
||||
method: "POST",
|
||||
}).then((r) => {
|
||||
if (r.status == 200) this.restarted = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
<br />
|
||||
<p>
|
||||
If Moonlight complains about an app currently running, force closing the
|
||||
app should fix the issue
|
||||
app should fix the issue.
|
||||
</p>
|
||||
<div class="alert alert-success" v-if="closeAppStatus === true">
|
||||
Application Closed Successfuly!
|
||||
Application Closed Successfully!
|
||||
</div>
|
||||
<div class="alert alert-danger" v-if="closeAppStatus === false">
|
||||
Error while closing Appplication
|
||||
|
|
@ -22,6 +22,28 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Restart Sunshine-->
|
||||
<div class="card p-2 my-4" v-if="restartSupported">
|
||||
<div class="card-body">
|
||||
<h2>Restart Sunshine</h2>
|
||||
<br />
|
||||
<p>
|
||||
If Sunshine isn't working properly, you can try restarting it.
|
||||
This will terminate any running sessions.
|
||||
</p>
|
||||
<div class="alert alert-success" v-if="restartStatus === true">
|
||||
Sunshine is restarting
|
||||
</div>
|
||||
<div class="alert alert-danger" v-if="restartStatus === false">
|
||||
Error restarting Sunshine
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-warning" :disabled="restartPressed" @click="restart">
|
||||
Restart Sunshine
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Unpair all Clients-->
|
||||
<div class="card p-2 my-4">
|
||||
<div class="card-body">
|
||||
|
|
@ -68,6 +90,9 @@
|
|||
closeAppStatus: null,
|
||||
unpairAllPressed: false,
|
||||
unpairAllStatus: null,
|
||||
restartSupported: false,
|
||||
restartPressed: false,
|
||||
restartStatus: null,
|
||||
logs: 'Loading...',
|
||||
logFilter: null,
|
||||
logInterval: null,
|
||||
|
|
@ -86,6 +111,11 @@
|
|||
this.refreshLogs();
|
||||
}, 5000);
|
||||
this.refreshLogs();
|
||||
fetch("/api/config")
|
||||
.then((r) => r.json())
|
||||
.then((r) => {
|
||||
this.restartSupported = (r.restart_supported === "true");
|
||||
});
|
||||
},
|
||||
beforeDestroy(){
|
||||
clearInterval(this.logInterval);
|
||||
|
|
@ -124,7 +154,22 @@
|
|||
},
|
||||
copyLogs(){
|
||||
navigator.clipboard.writeText(this.actualLogs);
|
||||
}
|
||||
},
|
||||
restart() {
|
||||
this.restartPressed = true;
|
||||
fetch("/api/restart", {
|
||||
method: "POST",
|
||||
}).then((r) => {
|
||||
this.restartPressed = false;
|
||||
|
||||
// We won't get a response in the success case
|
||||
this.restartStatus = r.status.toString() !== "false";
|
||||
|
||||
setTimeout(() => {
|
||||
this.restartStatus = null;
|
||||
}, 5000);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue