Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweaks to the Web interface #108

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
17 changes: 14 additions & 3 deletions assets/web/clients.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
<div id="content" class="container">
<h1>Clients</h1>
</div>
<main role="main">
<div class="container-parent bg-light">
<div class="container py-3">
<h1 class="mb-0">Clients</h1>
</div>
</div>
<div class="container-parent">
<div class="container py-3">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi, perspiciatis possimus cupiditate repellat
ducimus, accusantium, voluptatem recusandae ipsa non commodi aliquam fugit reprehenderit nostrum soluta
tenetur molestias corporis quia! Debitis!</p>
</div>
</div>
</main>
3 changes: 3 additions & 0 deletions assets/web/footer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
</body>

</html>
12 changes: 6 additions & 6 deletions assets/web/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sunshine</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected].0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected].0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected].2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected].2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>

<body>
Expand Down
18 changes: 11 additions & 7 deletions assets/web/index.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<div id="content" class="container">
<div class="row">
<div class="col-md-6 py-4" style="margin: 0 auto;">
<h1>Hello, Sunshine!</h1>
<p>Sunshine is a Gamestream host for Moonlight</p>
<a href="https://github.com/loki-47-6F-64/sunshine">Official GitHub Repository</a>
<main role="main">
<div class="container-parent">
<div class="container py-3">
<div class="row justify-content-center">
<div class="col-md-6">
<h1>Hello, Sunshine!</h1>
<p>Sunshine is a Gamestream host for Moonlight</p>
<p><a href="https://github.com/loki-47-6F-64/sunshine">Official GitHub Repository</a></p>
</div>
</div>
</div>
</div>
</div>
</main>
178 changes: 98 additions & 80 deletions assets/web/password.html
Original file line number Diff line number Diff line change
@@ -1,97 +1,115 @@
<div id="app" class="container">
<h1 class="my-4">Password Change</h1>
<form @submit.prevent="save">
<div class="card d-flex p-4 flex-row">
<div class="col-md-6 px-4">
<h4>Current Credentials</h4>
<div class="mb-3">
<label for="currentUsername" class="form-label">Username</label>
<input required type="text" class="form-control" id="currentUsername" v-model="passwordData.currentUsername">
<div class="form-text">&nbsp;</div>
</div>
<div class="mb-3">
<label for="currentPassword" class="form-label">Password</label>
<input autocomplete="current-password" type="password" class="form-control" id="currentPassword" v-model="passwordData.currentPassword">
</div>
</div>
<div class="col-md-6 px-4">
<h4>New Credentials</h4>
<div class="mb-3">
<label for="newUsername" class="form-label">New Username</label>
<input type="text" class="form-control" id="newUsername" v-model="passwordData.newUsername">
<div class="form-text">If not specified, the username will not change
<main role="main" id="app">
<div class="container-parent bg-light">
<div class="container py-3">
<h1>Update credentials</h1>
<p class="mb-0">Update the credentials used to connect to this web interface, including the username and
password.</p>
</div>
</div>
<div class="container-parent">
<div class="container py-3">
<form action="#" @submit.prevent="save">
<div class="row">
<div class="col-12">
<div class="alert alert-danger" role="alert" v-if="error">
<b>An error has occured</b>. Here's what the server sent back: {{error}}.
</div>
<div class="alert alert-success" role="alert" v-if="success">
<b>Credentials have been updated</b>, your browser should reload and ask you for the new
credentials.
</div>
</div>
<div class="col-md-6">
<h2>Current credentials</h2>
<p>You need to enter your current credentials to change them, you need to enter both the
username and password.</p>
<div class="mb-3">
<label for="currentUsername" class="form-label">Current username</label>
<input type="text" class="form-control" id="currentUsername" autocomplete="username"
required v-model="passwordData.currentUsername">
</div>
<div class="mb-3">
<label for="currentPassword" class="form-label">Current password</label>
<input type="password" class="form-control" id="currentPassword"
autocomplete="current-password" required v-model="passwordData.currentPassword">
</div>
</div>
<div class="col-md-6">
<h2>New credentials</h2>
<p>Enter the new credentials you want to use, if you just want to change the password you can
leave the username field empty.</p>
<div class="mb-3">
<label for="newUsername" class="form-label">New username</label>
<input type="text" class="form-control" id="newUsername" v-model="passwordData.newUsername">
</div>
<div class="mb-3">
<label for="newPassword" class="form-label">New password</label>
<input type="password" class="form-control" id="newPassword" autocomplete="new-password"
required v-model="passwordData.newPassword">
</div>
<div class="mb-3">
<label for="confirmNewPassword" class="form-label">New password (confirm)</label>
<input type="password" class="form-control" id="confirmNewPassword"
autocomplete="new-password" required v-model="passwordData.confirmNewPassword">
</div>
</div>
<div class="col-12">
<button type="submit" id="submitButton" class="btn w-100 btn-primary"
v-bind:disabled="isLoading">Update credentials</button>
</div>
</div>
<div class="mb-3">
<label for="newPassword" class="form-label">Password</label>
<input autocomplete="new-password" required type="password" class="form-control" id="newPassword" v-model="passwordData.newPassword">
</div>
<div class="mb-3">
<label for="confirmNewPassword" class="form-label">Confirm Password</label>
<input autocomplete="new-password" required type="password" class="form-control" id="confirmNewPassword" v-model="passwordData.confirmNewPassword">
</div>
</div>
</div>
<div class="alert alert-danger" v-if="error"><b>Error: </b>{{error}}</div>
<div class="alert alert-success" v-if="success"><b>Success! </b>This page will reload soon, your browser will ask you for the new credentials</div>
<div class="mb-3 buttons">
<button class="btn btn-primary">Save</button>
</form>
</div>
</form>
</div>
</div>
</main>

<script>
new Vue({
el: '#app',
el: "#app",
data() {
return {
error: null,
success: false,
isLoading: false,
passwordData: {
currentUsername: '',
currentPassword: '',
newUsername: '',
newPassword: '',
confirmNewPassword: ''
}
}
currentUsername: "",
currentPassword: "",
newUsername: "",
newPassword: "",
confirmNewPassword: "",
},
};
},
methods: {
save() {
this.error = null;
this.isLoading = true;
fetch("/api/password", {
method: "POST",
body: JSON.stringify(this.passwordData)
}).then((r) => {
if (r.status == 200){
r.json().then((rj) => {
if(rj.status.toString() === "true"){
this.success = true;
setTimeout(()=>{
document.location.reload();
},5000);
} else {
this.error = rj.error;
}
})
}
else {
this.error = "Internal Server Error"
}
});
}
}
})
</script>

<style>
.config-page {
padding: 1em;
border: 1px solid #dee2e6;
border-top: none;
}

.buttons {
padding: 1em 0;
}
</style>
body: JSON.stringify(this.passwordData),
})
.then((r) => {
this.isLoading = false;
if (r.status == 200) {
r.json().then((rj) => {
if (rj.status.toString() === "true") {
this.success = true;
setTimeout(() => {
document.location.reload();
}, 5000);
} else {
this.error = rj.error;
}
});
} else {
this.error = "Internal Server Error";
}
})
.catch((err) => {
this.isLoading = false;
console.error(err);
});
},
},
});
</script>
87 changes: 60 additions & 27 deletions assets/web/pin.html
Original file line number Diff line number Diff line change
@@ -1,31 +1,64 @@

<div id="content" class="container">
<h1 class="my-4">PIN Pairing</h1>
<form action="" class="form d-flex flex-column align-items-center" id="form">
<div class="card flex-column d-flex p-4 mb-4">
<input type="number" placeholder="PIN" id="pin-input" class="form-control my-4">
<button class="btn btn-primary">Send</button>
</div>
<div class="alert alert-warning">
<b>Warning!</b> Make sure you have access to the client you are pairing with.<br>
This software can give total control to your computer, so be careful!
<main role="main">
<div class="container-parent bg-light">
<div class="container py-3">
<h1>Pair a new device</h1>
<p class="mb-0">Allow a new client to connect to this computer by entering the PIN code given by Moonlight here.
</p>
</div>
</div>
<div class="container-parent">
<div class="container py-3">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="alert alert-warning" role="alert">
<strong>Warning!</strong> Make sure you have access to the client you are pairing with.<br /> This software
can give total control to your computer, so be careful!
</div>
<form action="#" id="form">
<div class="mb-3">
<label for="input" class="form-label">PIN code</label>
<input type="text" class="form-control form-control-lg" id="input" name="pin" placeholder="1234"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making this a type="number" can help on mobile keyboard, since it will show only the numbers on smartphones

minlength="4" maxlength="4" required />
<div class="valid-feedback">Pairing successful! Please check Moonlight to continue!</div>
<div class="invalid-feedback">The given PIN code doesn't match, please check that it's typed correctly.
</div>
</div>
<button type="submit" id="submit" class="btn w-100 btn-primary">Pair new device</button>
</form>
</div>
<div id="status"></div>
</form>
</div>
</div>
</div>
</div>
</main>

<script>
document.querySelector("#form").addEventListener("submit", (e) => {
e.preventDefault();
let pin = document.querySelector("#pin-input").value;
document.querySelector("#status").innerHTML = "";
let b = JSON.stringify({pin: pin});
fetch("/api/pin",{method: "POST",body: b}).then((response) => response.json()).then((response)=>{
if(response.status){
document.querySelector("#status").innerHTML = `<div class="alert alert-success" role="alert">Success! Please check Moonlight to continue</div>`;
} else {
document.querySelector("#status").innerHTML = `<div class="alert alert-danger" role="alert">PIN does not match, please check if it's typed correctly</div>`;
}
})
})
/** @type HTMLFormElement */
const formElement = document.querySelector("form#form");
/** @type HTMLInputElement */
const input = formElement.querySelector("input#input");
/** @type HTMLButtonElement */
const submit = formElement.querySelector("button#submit");

formElement.addEventListener("submit", (e) => {
e.preventDefault();
submit.disabled = true;
// TODO: Check for empty or null values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required on PIN should be enough IIRC

const body = JSON.stringify({ pin: input.value });
fetch("/api/pin", { method: "POST", body })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove both is-valid and is-invalid before fetching? This way the feedback does not stay on screen while making multiple calls

.then((response) => response.json())
.then((response) => {
submit.disabled = false;
if (response.status === "true") {
input.classList.add("is-valid");
input.classList.remove("is-invalid");
} else {
input.classList.add("is-invalid");
input.classList.remove("is-valid");
}
})
.catch((err) => {
submit.disabled = false;
console.error(err);
});
});
</script>
Loading