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

initialized the enchancement of the client side developer experience #44

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,7 @@ dmypy.json
# SSL certificate files
*.pem
*.key


# Node.js
node_modules/
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ git checkout -b your_username/fix_name

Make the changes, test them locally, and them commit. Make sure to comply with the linters.

## Setup the client-side code build
zt4ff marked this conversation as resolved.
Show resolved Hide resolved
```
yarn install
yarn run build
```

## Starting development server

```
Expand Down
28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "remote-play",
"devDependencies": {
"@types/hammerjs": "^2.0.41",
"@webpack-cli/generators": "^2.5.0",
"css-loader": "^6.7.1",
"prettier": "^2.7.1",
"sass": "^1.55.0",
"sass-loader": "^13.0.2",
"style-loader": "^3.3.1",
"ts-loader": "^9.4.1",
"tsc": "^2.0.4",
"typescript": "^4.8.4",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"scripts": {
"build": "webpack --mode=production --node-env=production",
zt4ff marked this conversation as resolved.
Show resolved Hide resolved
"build:dev": "webpack --mode=development",
"build:prod": "webpack --mode=production --node-env=production",
"watch": "webpack --watch"
},
"dependencies": {
"hammerjs": "^2.0.8"
},
"version": "1.0.0",
"description": "Remote-Play uses pyautogui to press keyboard shortcuts to control your media. It uses fastapi to serve a minimal UI to your mobile device."
}
105 changes: 68 additions & 37 deletions static/index.js → src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
if (location.protocol === 'https:') {
import * as Hammer from "hammerjs";

import "./style.scss";

let ws: WebSocket;

if (location.protocol === "https:") {
ws = new WebSocket(`wss://${window.location.host}/ws`);
} else {
ws = new WebSocket(`ws://${window.location.host}/ws`);
}

const start = { x: 0, y: 0 };
const appThemeLocalKey = "darkModeLocal";

function callEndpoint(endpoint) {
function callEndpoint(endpoint: string) {
const xhr = new XMLHttpRequest();
xhr.open("get", endpoint, true);
xhr.setRequestHeader(
Expand All @@ -16,13 +23,13 @@ function callEndpoint(endpoint) {
xhr.send();
}

function touchStart(ev) {
function touchStart(ev: TouchEvent) {
ev.preventDefault();
start.x = ev.changedTouches[0].clientX;
start.y = ev.changedTouches[0].clientY;
}

function touchMove(ev) {
function touchMove(ev: TouchEvent) {
ev.preventDefault();
const offsetX = ev.changedTouches[0].clientX - start.x;
const offsetY = ev.changedTouches[0].clientY - start.y;
Expand All @@ -34,50 +41,62 @@ function touchMove(ev) {
}

function configureDisplayTheme() {
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
const prefersDarkScheme = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;

// if first time, then set theme based on system preference
if (localStorage.getItem(appThemeLocalKey) === null) {
if (prefersDarkScheme) {
localStorage.setItem(appThemeLocalKey, "dark");
}
else {
} else {
localStorage.setItem(appThemeLocalKey, "light");
}
}
// set theme based on local storage
if (localStorage.getItem(appThemeLocalKey) == "dark") {
document.documentElement.classList.toggle("dark", true);
document.getElementById("darkMode").checked = true;
}
else {
(document.getElementById("darkMode") as HTMLInputElement).checked = true;
} else {
document.documentElement.classList.toggle("dark", false);
document.getElementById("darkMode").checked = false;
(document.getElementById("darkMode") as HTMLInputElement).checked = false;
}
}

document.addEventListener("DOMContentLoaded", event => {
document.getElementById("touchpad").addEventListener("touchstart", touchStart);
document.getElementById("touchpad").addEventListener("touchmove", touchMove);
const hammer = new Hammer.Manager(document.getElementById("touchpad"));
const vscrollHammer = new Hammer.Manager(document.getElementById("vscrollpad"));
const hscrollHammer = new Hammer.Manager(document.getElementById("hscrollpad"));
document.addEventListener("DOMContentLoaded", (event) => {
(document.getElementById("touchpad") as HTMLElement).addEventListener(
"touchstart",
touchStart
);
(document.getElementById("touchpad") as HTMLElement).addEventListener(
"touchmove",
touchMove
);
const hammer = new Hammer.Manager(
document.getElementById("touchpad") as HTMLElement
);
const vscrollHammer = new Hammer.Manager(
document.getElementById("vscrollpad") as HTMLElement
);
const hscrollHammer = new Hammer.Manager(
document.getElementById("hscrollpad") as HTMLElement
);

var singleTap = new Hammer.Tap({
event: "tap",
taps: 1
taps: 1,
});
var doubleTap = new Hammer.Tap({
event: "doubletap",
taps: 2
taps: 2,
});

hammer.add([doubleTap, singleTap]);
hammer.on("tap", ev => {
hammer.on("tap", (ev) => {
// left mouse button click
ws.send(JSON.stringify({ type: "tap" }));
});
hammer.on("doubletap", ev => {
hammer.on("doubletap", (ev) => {
// right mouse button click
ws.send(JSON.stringify({ type: "doubletap" }));
});
Expand All @@ -87,52 +106,64 @@ document.addEventListener("DOMContentLoaded", event => {

var scrolly = new Hammer.Pan({
event: "vscroll",
threshhold: 50,
direction: Hammer.DIRECTION_VERTICAL
threshold: 50,
direction: Hammer.DIRECTION_VERTICAL,
});
var scrollx = new Hammer.Pan({
event: "hscroll",
threshhold: 50,
direction: Hammer.DIRECTION_HORIZONTAL
threshold: 50,
direction: Hammer.DIRECTION_HORIZONTAL,
});

vscrollHammer.add(scrolly);
hscrollHammer.add(scrollx);

vscrollHammer.on("vscroll", ev => {
vscrollHammer.on("vscroll", (ev) => {
// scroll vertically
if (ev.direction == 8) { // direction = up
if (ev.direction == 8) {
// direction = up
ws.send(JSON.stringify({ type: "scrolly", y: "up" }));
}
if (ev.direction == 16) { // direction = down
if (ev.direction == 16) {
// direction = down
ws.send(JSON.stringify({ type: "scrolly", y: "down" }));
}
});

hscrollHammer.on("hscroll", ev => {
hscrollHammer.on("hscroll", (ev) => {
// scroll horizontally
if (ev.direction == 2) { //direction = left
if (ev.direction == 2) {
//direction = left
ws.send(JSON.stringify({ type: "scrollx", x: "left" }));
}
if (ev.direction == 4) { // direction = right
if (ev.direction == 4) {
// direction = right
ws.send(JSON.stringify({ type: "scrollx", x: "right" }));
}
});

var darkSwitch = document.querySelector('input[name=darkMode]');
const darkSwitch = document.querySelector("input[name=darkMode]");

darkSwitch.addEventListener('change', function (_event) {
darkSwitch?.addEventListener("change", function (_event) {
// toggles darkmode when user taps switch
if (localStorage.getItem(appThemeLocalKey) == "dark") {
document.documentElement.classList.toggle("dark", false);
document.getElementById("darkMode").checked = false;
(document.getElementById("darkMode") as HTMLInputElement).checked = false;
localStorage.setItem(appThemeLocalKey, "light");
}
else if (localStorage.getItem(appThemeLocalKey) == "light") {
} else if (localStorage.getItem(appThemeLocalKey) == "light") {
document.documentElement.classList.toggle("dark", true);
document.getElementById("darkMode").checked = true;
(document.getElementById("darkMode") as HTMLInputElement).checked = true;
localStorage.setItem(appThemeLocalKey, "dark");
}
});
configureDisplayTheme();
});

// moved the callEndPoiny function that is being run from the index markup file
document
.querySelectorAll("main.container button")
.forEach((button: HTMLButtonElement) => {
button.addEventListener("click", (event) => {
callEndpoint(`/${(event.target as HTMLButtonElement).name}`);
});
});
Loading