diff --git a/packages/components/src/api/ApiConfig.ts b/packages/components/src/api/ApiConfig.ts
index ba6b99b566..fc2703cc89 100644
--- a/packages/components/src/api/ApiConfig.ts
+++ b/packages/components/src/api/ApiConfig.ts
@@ -102,6 +102,10 @@ class ApiConfig {
return `${this.getScheme()}://${this.getNewApiHost()}/tts/list`;
}
+ getPendingTtsJobCount(): string {
+ return `${this.getScheme()}://${this.getNewApiHost()}/tts/queue_length`;
+ }
+
viewTtsModel(modelSlug: string): string {
return `${this.getScheme()}://${this.getNewApiHost()}/tts/model/${modelSlug}`;
}
diff --git a/packages/components/src/api/tts/GetPendingTtsJobCount.ts b/packages/components/src/api/tts/GetPendingTtsJobCount.ts
new file mode 100644
index 0000000000..c786adbe49
--- /dev/null
+++ b/packages/components/src/api/tts/GetPendingTtsJobCount.ts
@@ -0,0 +1,45 @@
+import { ApiConfig } from "../ApiConfig";
+
+export interface GetPendingTtsJobCountSuccessResponse {
+ success: boolean,
+ pending_job_count: number,
+ cache_time: Date,
+}
+
+export interface GetPendingTtsJobCountErrorResponse {
+}
+
+export type GetPendingTtsJobCountResponse = GetPendingTtsJobCountSuccessResponse | GetPendingTtsJobCountErrorResponse;
+
+export function GetPendingTtsJobCountIsOk(response: GetPendingTtsJobCountResponse): response is GetPendingTtsJobCountSuccessResponse {
+ return response.hasOwnProperty('pending_job_count');
+}
+
+export function GetPendingTtsJobCountIsErr(response: GetPendingTtsJobCountResponse): response is GetPendingTtsJobCountErrorResponse {
+ return !response.hasOwnProperty('pending_job_count');
+}
+
+export async function GetPendingTtsJobCount() : Promise {
+ const endpoint = new ApiConfig().getPendingTtsJobCount();
+
+ return fetch(endpoint, {
+ method: 'GET',
+ credentials: 'include',
+ headers: {
+ 'Accept': 'application/json',
+ },
+ })
+ .then(res => res.json())
+ .then(res => {
+ if (res && 'success' in res && res['success']) {
+ // NB: Timestamps aren't converted to Date objects on their own!
+ res['cache_time'] = new Date(res['cache_time']);
+ return res;
+ } else {
+ return { success : false };
+ }
+ })
+ .catch(e => {
+ return { success : false };
+ });
+}
diff --git a/packages/fakeyou/src/v2/view/NewTopNavFc.tsx b/packages/fakeyou/src/v2/view/NewTopNavFc.tsx
index 202ff68fdd..7e21c293ba 100644
--- a/packages/fakeyou/src/v2/view/NewTopNavFc.tsx
+++ b/packages/fakeyou/src/v2/view/NewTopNavFc.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useEffect, useState } from "react";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import { Link, useHistory } from "react-router-dom";
import { MigrationTopNavSession } from "../../migration/MigrationTopNav_Session";
@@ -23,6 +23,7 @@ import { t } from "i18next";
import { USE_REFRESH } from "../../Refresh";
import { Logout } from "@storyteller/components/src/api/session/Logout";
import { Gravatar } from "@storyteller/components/src/elements/Gravatar";
+import { GetPendingTtsJobCount, GetPendingTtsJobCountIsOk, GetPendingTtsJobCountSuccessResponse } from "@storyteller/components/src/api/tts/GetPendingTtsJobCount";
interface Props {
sessionWrapper: SessionWrapper;
@@ -40,6 +41,29 @@ function NewTopNavFc(props: Props) {
myDataLink = `/profile/${username}`;
}
+ // NB: The responses from the "job count" endpoint are cached in a distributed manner.
+ // We use the timestamp as a vector clock to know when to update our view.
+ const [pendingTtsJobs, setPendingTtsJobs] = useState({
+ success: true,
+ pending_job_count: 0,
+ cache_time: new Date(0), // NB: Epoch
+ });
+
+ useEffect(() => {
+ const fetch = async () => {
+ const response = await GetPendingTtsJobCount();
+ if (GetPendingTtsJobCountIsOk(response)) {
+ console.log(response);
+ if (response.cache_time.getTime() > pendingTtsJobs.cache_time.getTime()) {
+ setPendingTtsJobs(response);
+ }
+ }
+ };
+ const interval = setInterval(async () => fetch(), 15000);
+ fetch();
+ return () => clearInterval(interval);
+ }, [pendingTtsJobs]);
+
const [mobileHamburgerIsActive, setMobileHamburgerIsActive] =
useState(false);
@@ -326,7 +350,7 @@ function NewTopNavFc(props: Props) {
Online Users: 1,204
*/}
- TTS Queued: 48
+ TTS Queued: {pendingTtsJobs.pending_job_count}