100%
diff --git a/services/webui/src/app/index.ts b/services/webui/src/app/index.ts
index ac104bd..6e106e2 100644
--- a/services/webui/src/app/index.ts
+++ b/services/webui/src/app/index.ts
@@ -3,7 +3,7 @@ import router from "./routes";
import store from "./store";
import App from './App.vue'
import "./styles/index.css";
-import "./websocket";
+import * as livewire from "./livewire";
/**
* Create the Vue application
@@ -13,6 +13,11 @@ app.use(router);
app.use(store);
app.mount("#app");
+/**
+ * Start livewire services
+ */
+livewire.updateMoviesInStore();
+
/**
* Dropdown menus
*/
diff --git a/services/webui/src/app/livewire.ts b/services/webui/src/app/livewire.ts
new file mode 100644
index 0000000..a144ab7
--- /dev/null
+++ b/services/webui/src/app/livewire.ts
@@ -0,0 +1,55 @@
+import store from "./store";
+import { sleep } from "./util";
+import websocket from "./websocket";
+
+/**
+ * Regularly update movies in the store
+ */
+export async function updateMoviesInStore() {
+ const THROTTLE = 500;
+ let lastUpdateTime = 0;
+
+ // Cache movie ticket IDs
+ let ticketIds: number[] = [];
+ let updateCachedTicketIds = () => {
+ ticketIds = Object.keys(store.state.movieTickets).map(parseInt);
+ console.log("Ticket cache updated");
+ };
+ updateCachedTicketIds();
+
+ // Listen for movie list updates
+ let onMoviesUpdated: (() => void)|null = null;
+ store.watch(state => state.movieTickets, () => {
+ updateCachedTicketIds();
+ if (onMoviesUpdated !== null) {
+ onMoviesUpdated();
+ }
+ }, { deep: true });
+
+ while (true) {
+ // Throttle the udpates
+ await sleep(THROTTLE - (Date.now() - lastUpdateTime));
+ lastUpdateTime = Date.now();
+
+ // Wait until there are movies in the list before updating
+ if (ticketIds.length == 0) {
+ await new Promise
(resolve => onMoviesUpdated = resolve);
+ }
+
+ // Get the progress of all movie tickets
+ console.log("Updating movies", ticketIds.length);
+ try {
+ let result = await websocket.movieProgress(ticketIds);
+ for (let ticketId of Object.keys(result)) {
+ let tmdbId = store.state.movieTickets[ticketId];
+ if (tmdbId === undefined || store.state.movies[ticketId]) {
+ continue;
+ }
+ store.state.movies[tmdbId].movie.plexLink = result[ticketId].plexLink ?? null;
+ store.state.movies[tmdbId].movie.progress = result[ticketId].progress ?? null;
+ }
+ } catch(e) {
+ console.error("Failed to update movies!", e);
+ }
+ }
+}
diff --git a/services/webui/src/app/util.ts b/services/webui/src/app/util.ts
index 5860e9f..c864a64 100644
--- a/services/webui/src/app/util.ts
+++ b/services/webui/src/app/util.ts
@@ -49,3 +49,10 @@ export function getAverageRgb(imgEl: HTMLImageElement) {
return rgb;
}
+
+/**
+ * Sleep for the provided number of milliseconds
+ */
+export function sleep(ms: number) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
diff --git a/services/webui/src/app/websocket.ts b/services/webui/src/app/websocket.ts
index 4232a44..2386c4d 100644
--- a/services/webui/src/app/websocket.ts
+++ b/services/webui/src/app/websocket.ts
@@ -1,4 +1,5 @@
import { WebSocketClient as WSClient } from "@autoplex/websocket-client";
+import { IMovieProgressResponse, WebSocketMethod } from "@autoplex-api/request";
import store, { Action } from "./store";
class WebSocketClient extends WSClient
@@ -23,6 +24,15 @@ class WebSocketClient extends WSClient
protected forgetJwt() {
store.dispatch(Action.AuthForget, undefined);
}
+
+ // Public Interface ----------------------------------------------------------------------------
+
+ /**
+ * Get the progress of the given movies
+ */
+ public async movieProgress(ticketIds: number[]) {
+ return await this.request(WebSocketMethod.TicketProgress, ticketIds);
+ }
}
-export default new WebSocketClient("ws://localhost:3250/");
+export default new WebSocketClient(`ws://${document.domain}:3250/`);
diff --git a/services/webui/tsconfig.json b/services/webui/tsconfig.json
index 99aedf3..0667856 100644
--- a/services/webui/tsconfig.json
+++ b/services/webui/tsconfig.json
@@ -4,7 +4,7 @@
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
- "target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
+ // "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
// "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
diff --git a/services/webui/tsconfig.server.json b/services/webui/tsconfig.server.json
index 7a537a4..cc23631 100644
--- a/services/webui/tsconfig.server.json
+++ b/services/webui/tsconfig.server.json
@@ -1,8 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
- "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
- "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"outDir": "dist/server", /* Redirect output structure to the directory. */
"sourceRoot": "src/server" /* Specify the location where debugger should locate TypeScript files instead of source locations. */
},